Message ID | 20200729164554.114735-1-marex@denx.de |
---|---|
State | Changes Requested, archived |
Headers | show |
Series | [V2,1/2] dt-bindings: Add DT bindings for Toshiba TC358762 DSI-to-DPI bridge | expand |
Context | Check | Description |
---|---|---|
robh/checkpatch | success | |
robh/dt-meta-schema | success |
Hi Marek. On Wed, Jul 29, 2020 at 06:45:54PM +0200, Marek Vasut wrote: > Add very basic driver for Toshiba TC358762 DSI-to-DPI bridge, derived > from tc358764 driver and panel-raspberrypi-touchscreen. This driver is > meant to replace the panel-raspberrypi-touchscreen too, as the bridge > connection can be described in DT too. > > Signed-off-by: Marek Vasut <marex@denx.de> > To: dri-devel@lists.freedesktop.org > Cc: Eric Anholt <eric@anholt.net> > Cc: Rob Herring <robh+dt@kernel.org> > Cc: Sam Ravnborg <sam@ravnborg.org> > Cc: devicetree@vger.kernel.org > --- > V2: Switch to DRM_PANEL_BRIDGE Changes looks good. One detail below. > --- > drivers/gpu/drm/bridge/Kconfig | 8 + > drivers/gpu/drm/bridge/Makefile | 1 + > drivers/gpu/drm/bridge/tc358762.c | 280 ++++++++++++++++++++++++++++++ > 3 files changed, 289 insertions(+) > create mode 100644 drivers/gpu/drm/bridge/tc358762.c > > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig > index 43271c21d3fc..58e879852082 100644 > --- a/drivers/gpu/drm/bridge/Kconfig > +++ b/drivers/gpu/drm/bridge/Kconfig > @@ -153,6 +153,14 @@ config DRM_THINE_THC63LVD1024 > help > Thine THC63LVD1024 LVDS/parallel converter driver. > > +config DRM_TOSHIBA_TC358762 > + tristate "TC358762 DSI/DPI bridge" > + depends on OF > + select DRM_MIPI_DSI > + select DRM_PANEL_BRIDGE > + help > + Toshiba TC358762 DSI/DPI bridge driver. > + > config DRM_TOSHIBA_TC358764 > tristate "TC358764 DSI/LVDS bridge" > depends on OF > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile > index d63d4b7e4347..b341c60ee96a 100644 > --- a/drivers/gpu/drm/bridge/Makefile > +++ b/drivers/gpu/drm/bridge/Makefile > @@ -12,6 +12,7 @@ obj-$(CONFIG_DRM_SII902X) += sii902x.o > obj-$(CONFIG_DRM_SII9234) += sii9234.o > obj-$(CONFIG_DRM_SIMPLE_BRIDGE) += simple-bridge.o > obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o > +obj-$(CONFIG_DRM_TOSHIBA_TC358762) += tc358762.o > obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o > obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o > obj-$(CONFIG_DRM_TOSHIBA_TC358768) += tc358768.o > diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c > new file mode 100644 > index 000000000000..1bfdfc6affaf > --- /dev/null > +++ b/drivers/gpu/drm/bridge/tc358762.c > @@ -0,0 +1,280 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2020 Marek Vasut <marex@denx.de> > + * > + * Based on tc358764.c by > + * Andrzej Hajda <a.hajda@samsung.com> > + * Maciej Purski <m.purski@samsung.com> > + * > + * Based on rpi_touchscreen.c by > + * Eric Anholt <eric@anholt.net> > + */ > + > +#include <linux/delay.h> > +#include <linux/module.h> > +#include <linux/of_graph.h> > +#include <linux/regulator/consumer.h> > + > +#include <video/mipi_display.h> > + > +#include <drm/drm_atomic_helper.h> > +#include <drm/drm_crtc.h> > +#include <drm/drm_fb_helper.h> > +#include <drm/drm_mipi_dsi.h> > +#include <drm/drm_of.h> > +#include <drm/drm_panel.h> > +#include <drm/drm_print.h> > +#include <drm/drm_probe_helper.h> > + > +/* PPI layer registers */ > +#define PPI_STARTPPI 0x0104 /* START control bit */ > +#define PPI_LPTXTIMECNT 0x0114 /* LPTX timing signal */ > +#define PPI_D0S_ATMR 0x0144 > +#define PPI_D1S_ATMR 0x0148 > +#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */ > +#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */ > +#define PPI_START_FUNCTION 1 > + > +/* DSI layer registers */ > +#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */ > +#define DSI_LANEENABLE 0x0210 /* Enables each lane */ > +#define DSI_RX_START 1 > + > +/* LCDC/DPI Host Registers */ > +#define LCDCTRL 0x0420 > + > +/* SPI Master Registers */ > +#define SPICMR 0x0450 > +#define SPITCR 0x0454 > + > +/* System Controller Registers */ > +#define SYSCTRL 0x0464 > + > +/* System registers */ > +#define LPX_PERIOD 3 > + > +/* Lane enable PPI and DSI register bits */ > +#define LANEENABLE_CLEN BIT(0) > +#define LANEENABLE_L0EN BIT(1) > +#define LANEENABLE_L1EN BIT(2) > + > +struct tc358762 { > + struct device *dev; > + struct drm_bridge bridge; > + struct drm_connector connector; > + struct regulator *regulator; > + struct drm_bridge *panel_bridge; > + bool pre_enabled; > + int error; > +}; > + > +static int tc358762_clear_error(struct tc358762 *ctx) > +{ > + int ret = ctx->error; > + > + ctx->error = 0; > + return ret; > +} > + > +static void tc358762_write(struct tc358762 *ctx, u16 addr, u32 val) > +{ > + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); > + ssize_t ret; > + u8 data[6]; > + > + if (ctx->error) > + return; > + > + data[0] = addr; > + data[1] = addr >> 8; > + data[2] = val; > + data[3] = val >> 8; > + data[4] = val >> 16; > + data[5] = val >> 24; > + > + ret = mipi_dsi_generic_write(dsi, data, sizeof(data)); > + if (ret < 0) > + ctx->error = ret; > +} > + > +static inline struct tc358762 *bridge_to_tc358762(struct drm_bridge *bridge) > +{ > + return container_of(bridge, struct tc358762, bridge); > +} > + > +static int tc358762_init(struct tc358762 *ctx) > +{ > + tc358762_write(ctx, DSI_LANEENABLE, > + LANEENABLE_L0EN | LANEENABLE_CLEN); > + tc358762_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5); > + tc358762_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5); > + tc358762_write(ctx, PPI_D0S_ATMR, 0); > + tc358762_write(ctx, PPI_D1S_ATMR, 0); > + tc358762_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD); > + > + tc358762_write(ctx, SPICMR, 0x00); > + tc358762_write(ctx, LCDCTRL, 0x00100150); > + tc358762_write(ctx, SYSCTRL, 0x040f); > + msleep(100); > + > + tc358762_write(ctx, PPI_STARTPPI, PPI_START_FUNCTION); > + tc358762_write(ctx, DSI_STARTDSI, DSI_RX_START); > + > + msleep(100); > + > + return tc358762_clear_error(ctx); > +} > + > +static void tc358762_post_disable(struct drm_bridge *bridge) > +{ > + struct tc358762 *ctx = bridge_to_tc358762(bridge); > + int ret; > + > + /* > + * The post_disable hook might be called multiple times. > + * We want to avoid regulator imbalance below. > + */ > + if (!ctx->pre_enabled) > + return; > + > + ctx->pre_enabled = false; > + > + ret = regulator_disable(ctx->regulator); > + if (ret < 0) > + dev_err(ctx->dev, "error disabling regulators (%d)\n", ret); > +} > + > +static void tc358762_pre_enable(struct drm_bridge *bridge) > +{ > + struct tc358762 *ctx = bridge_to_tc358762(bridge); > + int ret; > + > + ret = regulator_enable(ctx->regulator); > + if (ret < 0) > + dev_err(ctx->dev, "error enabling regulators (%d)\n", ret); > + > + ret = tc358762_init(ctx); > + if (ret < 0) > + dev_err(ctx->dev, "error initializing bridge (%d)\n", ret); > + > + ctx->pre_enabled = true; > +} > + > +static int tc358762_attach(struct drm_bridge *bridge, > + enum drm_bridge_attach_flags flags) > +{ > + struct tc358762 *ctx = bridge_to_tc358762(bridge); > + > + return drm_bridge_attach(bridge->encoder, ctx->panel_bridge, > + bridge, flags); > +} > + > +static const struct drm_bridge_funcs tc358762_bridge_funcs = { > + .post_disable = tc358762_post_disable, > + .pre_enable = tc358762_pre_enable, > + .attach = tc358762_attach, > +}; > + > +static int tc358762_parse_dt(struct tc358762 *ctx) > +{ > + struct drm_bridge *panel_bridge; > + struct device *dev = ctx->dev; > + struct drm_panel *panel; > + int ret; > + > + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); > + if (ret) > + return ret; > + > + panel_bridge = devm_drm_panel_bridge_add(dev, panel); > + > + if (IS_ERR(panel_bridge)) > + return PTR_ERR(panel_bridge); > + > + ctx->panel_bridge = panel_bridge; > + > + return 0; > +} > + > +static int tc358762_configure_regulators(struct tc358762 *ctx) > +{ > + ctx->regulator = devm_regulator_get(ctx->dev, "vddc"); > + if (IS_ERR(ctx->regulator)) > + return PTR_ERR(ctx->regulator); > + > + return 0; > +} > + > +static int tc358762_probe(struct mipi_dsi_device *dsi) > +{ > + struct device *dev = &dsi->dev; > + struct tc358762 *ctx; > + int ret; > + > + ctx = devm_kzalloc(dev, sizeof(struct tc358762), GFP_KERNEL); > + if (!ctx) > + return -ENOMEM; > + > + mipi_dsi_set_drvdata(dsi, ctx); I cannot see why this is needed. If not used then delete it. With the above addressed: Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Let me know if I shall apply - but we have to wait until binding is reviewed. And preferably one extra set of eyes on this driver. Sam > + > + ctx->dev = dev; > + ctx->pre_enabled = false; > + > + /* TODO: Find out how to get dual-lane mode working */ > + dsi->lanes = 1; > + dsi->format = MIPI_DSI_FMT_RGB888; > + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | > + MIPI_DSI_MODE_LPM; > + > + ret = tc358762_parse_dt(ctx); > + if (ret < 0) > + return ret; > + > + ret = tc358762_configure_regulators(ctx); > + if (ret < 0) > + return ret; > + > + ctx->bridge.funcs = &tc358762_bridge_funcs; > + ctx->bridge.type = DRM_MODE_CONNECTOR_DPI; > + ctx->bridge.of_node = dev->of_node; > + > + drm_bridge_add(&ctx->bridge); > + > + ret = mipi_dsi_attach(dsi); > + if (ret < 0) { > + drm_bridge_remove(&ctx->bridge); > + dev_err(dev, "failed to attach dsi\n"); > + } > + > + return ret; > +} > + > +static int tc358762_remove(struct mipi_dsi_device *dsi) > +{ > + struct tc358762 *ctx = mipi_dsi_get_drvdata(dsi); > + > + mipi_dsi_detach(dsi); > + drm_bridge_remove(&ctx->bridge); > + > + return 0; > +} > + > +static const struct of_device_id tc358762_of_match[] = { > + { .compatible = "toshiba,tc358762" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, tc358762_of_match); > + > +static struct mipi_dsi_driver tc358762_driver = { > + .probe = tc358762_probe, > + .remove = tc358762_remove, > + .driver = { > + .name = "tc358762", > + .of_match_table = tc358762_of_match, > + }, > +}; > +module_mipi_dsi_driver(tc358762_driver); > + > +MODULE_AUTHOR("Marek Vasut <marex@denx.de>"); > +MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358762 DSI/DPI Bridge"); > +MODULE_LICENSE("GPL v2"); > -- > 2.27.0
Hi Marek. On Wed, Jul 29, 2020 at 06:45:53PM +0200, Marek Vasut wrote: > Add DT bindings for Toshiba TC358762 DSI-to-DPI bridge, this > one is used in the Raspberry Pi 7" touchscreen display unit. > > Signed-off-by: Marek Vasut <marex@denx.de> > To: dri-devel@lists.freedesktop.org > Cc: Eric Anholt <eric@anholt.net> > Cc: Rob Herring <robh+dt@kernel.org> > Cc: Sam Ravnborg <sam@ravnborg.org> > Cc: devicetree@vger.kernel.org > --- > V2: Fix dt_binding_check errors > --- > .../display/bridge/toshiba,tc358762.yaml | 125 ++++++++++++++++++ > 1 file changed, 125 insertions(+) > create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml > > diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml > new file mode 100644 > index 000000000000..6cd4c0d86c13 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml > @@ -0,0 +1,125 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/bridge/toshiba,tc358762.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Toshiba TC358762 MIPI DSI to MIPI DPI bridge > + > +maintainers: > + - Marek Vasut <marex@denx.de> > + > +description: | > + The TC358762 is bridge device which converts MIPI DSI to MIPI DPI. > + > +properties: > + compatible: > + enum: > + - toshiba,tc358762 > + > + reg: > + maxItems: 1 > + description: virtual channel number of a DSI peripheral > + > + vddc-supply: > + description: Regulator for 1.2V internal core power. > + > + ports: > + type: object > + > + properties: > + "#address-cells": > + const: 1 > + > + "#size-cells": > + const: 0 > + > + port@0: > + type: object > + additionalProperties: false > + > + description: | > + Video port for MIPI DSI input > + > + properties: > + reg: > + const: 0 > + > + patternProperties: Not happy with the use of "patternProperties" when there is no pattern. > + endpoint: > + type: object > + additionalProperties: false > + > + properties: > + remote-endpoint: true > + > + required: > + - reg > + > + port@1: > + type: object > + additionalProperties: false > + > + description: | > + Video port for MIPI DPI output (panel or connector). > + > + properties: > + reg: > + const: 1 > + > + patternProperties: Same here. > + endpoint: > + type: object > + additionalProperties: false > + > + properties: > + remote-endpoint: true > + > + required: > + - reg > + > + required: > + - "#address-cells" > + - "#size-cells" > + - port@0 > + - port@1 > + > +required: > + - compatible > + - reg > + - vddc-supply > + - ports > + > +additionalProperties: false > + > +examples: > + - | > + i2c1 { > + #address-cells = <1>; > + #size-cells = <0>; > + > + bridge@0 { > + reg = <0>; > + compatible = "toshiba,tc358762"; > + vddc-supply = <&vcc_1v2_reg>; > + > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port@0 { > + reg = <0>; > + bridge_in: endpoint { > + remote-endpoint = <&dsi_out>; > + }; > + }; > + > + port@1 { > + reg = <1>; > + bridge_out: endpoint { > + remote-endpoint = <&panel_in>; > + }; > + }; > + }; > + }; > + }; Add: <empty line> ... Where "..." is the end-marker (or somethig like that in yaml). > -- > 2.27.0
On 7/29/20 6:56 PM, Sam Ravnborg wrote: [...] >> +static int tc358762_probe(struct mipi_dsi_device *dsi) >> +{ >> + struct device *dev = &dsi->dev; >> + struct tc358762 *ctx; >> + int ret; >> + >> + ctx = devm_kzalloc(dev, sizeof(struct tc358762), GFP_KERNEL); >> + if (!ctx) >> + return -ENOMEM; >> + >> + mipi_dsi_set_drvdata(dsi, ctx); > I cannot see why this is needed. If not used then delete it. > With the above addressed: > Reviewed-by: Sam Ravnborg <sam@ravnborg.org> > > Let me know if I shall apply - but we have to wait until binding is > reviewed. And preferably one extra set of eyes on this driver. [...] >> +static int tc358762_remove(struct mipi_dsi_device *dsi) >> +{ >> + struct tc358762 *ctx = mipi_dsi_get_drvdata(dsi); >> + >> + mipi_dsi_detach(dsi); >> + drm_bridge_remove(&ctx->bridge); Because it's used here in the remove callback. [...]
Hi Marek. On Wed, Jul 29, 2020 at 07:02:51PM +0200, Marek Vasut wrote: > On 7/29/20 6:56 PM, Sam Ravnborg wrote: > [...] > >> +static int tc358762_probe(struct mipi_dsi_device *dsi) > >> +{ > >> + struct device *dev = &dsi->dev; > >> + struct tc358762 *ctx; > >> + int ret; > >> + > >> + ctx = devm_kzalloc(dev, sizeof(struct tc358762), GFP_KERNEL); > >> + if (!ctx) > >> + return -ENOMEM; > >> + > >> + mipi_dsi_set_drvdata(dsi, ctx); > > I cannot see why this is needed. If not used then delete it. > > With the above addressed: > > Reviewed-by: Sam Ravnborg <sam@ravnborg.org> > > > > Let me know if I shall apply - but we have to wait until binding is > > reviewed. And preferably one extra set of eyes on this driver. > > [...] > > >> +static int tc358762_remove(struct mipi_dsi_device *dsi) > >> +{ > >> + struct tc358762 *ctx = mipi_dsi_get_drvdata(dsi); > >> + > >> + mipi_dsi_detach(dsi); > >> + drm_bridge_remove(&ctx->bridge); > > Because it's used here in the remove callback. Thanks - missed that. So consider the point addressed by enlightning me. Sam
On 7/29/20 6:59 PM, Sam Ravnborg wrote: Hi, [...] >> + port@0: >> + type: object >> + additionalProperties: false >> + >> + description: | >> + Video port for MIPI DSI input >> + >> + properties: >> + reg: >> + const: 0 >> + >> + patternProperties: > Not happy with the use of "patternProperties" when there is no pattern. So how should this be changed ? [...]
On Wed, Jul 29, 2020 at 11:36:27PM +0200, Marek Vasut wrote: > On 7/29/20 6:59 PM, Sam Ravnborg wrote: > > Hi, > > [...] > >> + port@0: > >> + type: object > >> + additionalProperties: false > >> + > >> + description: | > >> + Video port for MIPI DSI input > >> + > >> + properties: > >> + reg: > >> + const: 0 > >> + > >> + patternProperties: > > Not happy with the use of "patternProperties" when there is no pattern. > > So how should this be changed ? Delete the "patternProperties" line and adjust indent on the following lines. Then this should continue to be valid syntax and validate the example. Sam
diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml new file mode 100644 index 000000000000..6cd4c0d86c13 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml @@ -0,0 +1,125 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/toshiba,tc358762.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Toshiba TC358762 MIPI DSI to MIPI DPI bridge + +maintainers: + - Marek Vasut <marex@denx.de> + +description: | + The TC358762 is bridge device which converts MIPI DSI to MIPI DPI. + +properties: + compatible: + enum: + - toshiba,tc358762 + + reg: + maxItems: 1 + description: virtual channel number of a DSI peripheral + + vddc-supply: + description: Regulator for 1.2V internal core power. + + ports: + type: object + + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + port@0: + type: object + additionalProperties: false + + description: | + Video port for MIPI DSI input + + properties: + reg: + const: 0 + + patternProperties: + endpoint: + type: object + additionalProperties: false + + properties: + remote-endpoint: true + + required: + - reg + + port@1: + type: object + additionalProperties: false + + description: | + Video port for MIPI DPI output (panel or connector). + + properties: + reg: + const: 1 + + patternProperties: + endpoint: + type: object + additionalProperties: false + + properties: + remote-endpoint: true + + required: + - reg + + required: + - "#address-cells" + - "#size-cells" + - port@0 + - port@1 + +required: + - compatible + - reg + - vddc-supply + - ports + +additionalProperties: false + +examples: + - | + i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358762"; + vddc-supply = <&vcc_1v2_reg>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + bridge_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + + port@1 { + reg = <1>; + bridge_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + }; + };
Add DT bindings for Toshiba TC358762 DSI-to-DPI bridge, this one is used in the Raspberry Pi 7" touchscreen display unit. Signed-off-by: Marek Vasut <marex@denx.de> To: dri-devel@lists.freedesktop.org Cc: Eric Anholt <eric@anholt.net> Cc: Rob Herring <robh+dt@kernel.org> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: devicetree@vger.kernel.org --- V2: Fix dt_binding_check errors --- .../display/bridge/toshiba,tc358762.yaml | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml