* [PATCH v3 0/2] Support for Synaptics TDDI series panels
@ 2025-07-20 12:01 Kaustabh Chakraborty
2025-07-20 12:01 ` [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel Kaustabh Chakraborty
2025-07-20 12:01 ` [PATCH v3 2/2] drm: panel: add support for Synaptics TDDI series DSI panels Kaustabh Chakraborty
0 siblings, 2 replies; 7+ messages in thread
From: Kaustabh Chakraborty @ 2025-07-20 12:01 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jessica Zhang
Cc: dri-devel, devicetree, linux-kernel, Kaustabh Chakraborty
Synaptics' Touch and Display Driver Integration (TDDI) technology [1]
employs a single chip for both touchscreen and display capabilities.
Such designs reportedly help reducing costs and power consumption.
Although the touchscreens, which are powered by Synaptics'
Register-Mapped Interface 4 (RMI4) touch protocol via I2C or SPI have
driver support in the kernel, the MIPI DSI display panels don't.
This series introduces a rudimentary driver for controlling said display
panels, which supports TD4101 and TD4300 panels.
[1] https://www.synaptics.com/technology/display-integration
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
Changes in v3:
- fixed various dt_binding_check errors (robh's bot)
- adjusted commit description of [v2 1/2] (robh)
- utilized devm_drm_panel_alloc() and devm_regulator_bulk_get_const()
- Link to v2: https://lore.kernel.org/r/20250625-panel-synaptics-tddi-v2-0-7a62ab1d13c7@disroot.org
Changes in v2:
- fixed various dt_binding_check errors (conor)
- did s/tddi_update_brightness/tddi_update_status
- added check for panel enable in tddi_update_status()
- used backlight_get_brightness() in appropriate places
- Link to v1: https://lore.kernel.org/r/20250612-panel-synaptics-tddi-v1-0-dfb8a425f76c@disroot.org
---
Kaustabh Chakraborty (2):
dt-bindings: display: panel: document Synaptics TDDI panel
drm: panel: add support for Synaptics TDDI series DSI panels
.../display/panel/synaptics,td4300-panel.yaml | 89 +++++++
drivers/gpu/drm/panel/Kconfig | 11 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-synaptics-tddi.c | 289 +++++++++++++++++++++
4 files changed, 390 insertions(+)
---
base-commit: d086c886ceb9f59dea6c3a9dae7eb89e780a20c9
change-id: 20250523-panel-synaptics-tddi-0b0b3f07f814
Best regards,
--
Kaustabh Chakraborty <kauschluss@disroot.org>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel 2025-07-20 12:01 [PATCH v3 0/2] Support for Synaptics TDDI series panels Kaustabh Chakraborty @ 2025-07-20 12:01 ` Kaustabh Chakraborty 2025-07-21 7:48 ` Krzysztof Kozlowski 2025-08-03 12:02 ` Dmitry Baryshkov 2025-07-20 12:01 ` [PATCH v3 2/2] drm: panel: add support for Synaptics TDDI series DSI panels Kaustabh Chakraborty 1 sibling, 2 replies; 7+ messages in thread From: Kaustabh Chakraborty @ 2025-07-20 12:01 UTC (permalink / raw) To: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jessica Zhang Cc: dri-devel, devicetree, linux-kernel, Kaustabh Chakraborty Document the Synaptics TDDI (Touch/Display Integration) panel hardware. Along with the MIPI-DSI panel, these devices also have an in-built LED backlight device and a touchscreen, all packed together in a single chip. Also, add compatibles for supported panels - TD4101 and TD4300. Both have the '-panel' suffix so as to remove any ambiguity between the panel and touchscreen chips. Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org> --- .../display/panel/synaptics,td4300-panel.yaml | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml new file mode 100644 index 0000000000000000000000000000000000000000..152d94367130e9d80a885fe87a2da53db88e3393 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/synaptics,td4300-panel.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synaptics TDDI Display Panel Controller + +maintainers: + - Kaustabh Chakraborty <kauschluss@disroot.org> + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + enum: + - syna,td4101-panel + - syna,td4300-panel + + reg: + maxItems: 1 + + vio-supply: + description: core I/O voltage supply + + vsn-supply: + description: negative voltage supply for analog circuits + + vsp-supply: + description: positive voltage supply for analog circuits + + backlight-gpios: + maxItems: 1 + description: backlight enable GPIO + + reset-gpios: true + width-mm: true + height-mm: true + panel-timing: true + +required: + - compatible + - reg + - width-mm + - height-mm + - panel-timing + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "syna,td4300-panel"; + reg = <0>; + + vio-supply = <&panel_vio_reg>; + vsn-supply = <&panel_vsn_reg>; + vsp-supply = <&panel_vsp_reg>; + + backlight-gpios = <&gpd3 5 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpd3 4 GPIO_ACTIVE_LOW>; + + width-mm = <68>; + height-mm = <121>; + + panel-timing { + clock-frequency = <144389520>; + + hactive = <1080>; + hsync-len = <4>; + hfront-porch = <120>; + hback-porch = <32>; + + vactive = <1920>; + vsync-len = <2>; + vfront-porch = <21>; + vback-porch = <4>; + }; + }; + }; + +... -- 2.50.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel 2025-07-20 12:01 ` [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel Kaustabh Chakraborty @ 2025-07-21 7:48 ` Krzysztof Kozlowski 2025-08-03 12:02 ` Dmitry Baryshkov 1 sibling, 0 replies; 7+ messages in thread From: Krzysztof Kozlowski @ 2025-07-21 7:48 UTC (permalink / raw) To: Kaustabh Chakraborty Cc: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jessica Zhang, dri-devel, devicetree, linux-kernel On Sun, Jul 20, 2025 at 05:31:54PM +0530, Kaustabh Chakraborty wrote: > Document the Synaptics TDDI (Touch/Display Integration) panel hardware. > Along with the MIPI-DSI panel, these devices also have an in-built LED > backlight device and a touchscreen, all packed together in a single chip. > > Also, add compatibles for supported panels - TD4101 and TD4300. Both > have the '-panel' suffix so as to remove any ambiguity between the panel > and touchscreen chips. > > Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org> > --- > .../display/panel/synaptics,td4300-panel.yaml | 89 ++++++++++++++++++++++ > 1 file changed, 89 insertions(+) Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel 2025-07-20 12:01 ` [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel Kaustabh Chakraborty 2025-07-21 7:48 ` Krzysztof Kozlowski @ 2025-08-03 12:02 ` Dmitry Baryshkov 2025-08-06 15:22 ` Kaustabh Chakraborty 1 sibling, 1 reply; 7+ messages in thread From: Dmitry Baryshkov @ 2025-08-03 12:02 UTC (permalink / raw) To: Kaustabh Chakraborty Cc: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jessica Zhang, dri-devel, devicetree, linux-kernel On Sun, Jul 20, 2025 at 05:31:54PM +0530, Kaustabh Chakraborty wrote: > Document the Synaptics TDDI (Touch/Display Integration) panel hardware. > Along with the MIPI-DSI panel, these devices also have an in-built LED > backlight device and a touchscreen, all packed together in a single chip. > > Also, add compatibles for supported panels - TD4101 and TD4300. Both > have the '-panel' suffix so as to remove any ambiguity between the panel > and touchscreen chips. > > Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org> > --- > .../display/panel/synaptics,td4300-panel.yaml | 89 ++++++++++++++++++++++ > 1 file changed, 89 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml > new file mode 100644 > index 0000000000000000000000000000000000000000..152d94367130e9d80a885fe87a2da53db88e3393 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml > @@ -0,0 +1,89 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/panel/synaptics,td4300-panel.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Synaptics TDDI Display Panel Controller > + > +maintainers: > + - Kaustabh Chakraborty <kauschluss@disroot.org> > + > +allOf: > + - $ref: panel-common.yaml# > + > +properties: > + compatible: > + enum: > + - syna,td4101-panel > + - syna,td4300-panel > + > + reg: > + maxItems: 1 > + > + vio-supply: > + description: core I/O voltage supply > + > + vsn-supply: > + description: negative voltage supply for analog circuits > + > + vsp-supply: > + description: positive voltage supply for analog circuits > + > + backlight-gpios: > + maxItems: 1 > + description: backlight enable GPIO > + > + reset-gpios: true > + width-mm: true > + height-mm: true > + panel-timing: true > + > +required: > + - compatible > + - reg > + - width-mm > + - height-mm > + - panel-timing > + > +additionalProperties: false > + > +examples: > + - | > + #include <dt-bindings/gpio/gpio.h> > + > + dsi { > + #address-cells = <1>; > + #size-cells = <0>; > + > + panel@0 { > + compatible = "syna,td4300-panel"; > + reg = <0>; > + > + vio-supply = <&panel_vio_reg>; > + vsn-supply = <&panel_vsn_reg>; > + vsp-supply = <&panel_vsp_reg>; > + > + backlight-gpios = <&gpd3 5 GPIO_ACTIVE_LOW>; > + reset-gpios = <&gpd3 4 GPIO_ACTIVE_LOW>; > + > + width-mm = <68>; > + height-mm = <121>; > + > + panel-timing { Are the timings defined by the 'TD4300' name or might there be different panels with the same name but different timings? > + clock-frequency = <144389520>; > + > + hactive = <1080>; > + hsync-len = <4>; > + hfront-porch = <120>; > + hback-porch = <32>; > + > + vactive = <1920>; > + vsync-len = <2>; > + vfront-porch = <21>; > + vback-porch = <4>; > + }; > + }; > + }; > + > +... > > -- > 2.50.0 > -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel 2025-08-03 12:02 ` Dmitry Baryshkov @ 2025-08-06 15:22 ` Kaustabh Chakraborty 0 siblings, 0 replies; 7+ messages in thread From: Kaustabh Chakraborty @ 2025-08-06 15:22 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jessica Zhang, dri-devel, devicetree, linux-kernel On 2025-08-03 12:02, Dmitry Baryshkov wrote: > On Sun, Jul 20, 2025 at 05:31:54PM +0530, Kaustabh Chakraborty wrote: >> Document the Synaptics TDDI (Touch/Display Integration) panel >> hardware. >> Along with the MIPI-DSI panel, these devices also have an in-built LED >> backlight device and a touchscreen, all packed together in a single >> chip. >> >> Also, add compatibles for supported panels - TD4101 and TD4300. Both >> have the '-panel' suffix so as to remove any ambiguity between the >> panel >> and touchscreen chips. >> >> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org> >> --- >> .../display/panel/synaptics,td4300-panel.yaml | 89 >> ++++++++++++++++++++++ >> 1 file changed, 89 insertions(+) >> >> diff --git >> a/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml >> b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml >> new file mode 100644 >> index >> 0000000000000000000000000000000000000000..152d94367130e9d80a885fe87a2da53db88e3393 >> --- /dev/null >> +++ >> b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml >> @@ -0,0 +1,89 @@ >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) >> +%YAML 1.2 >> +--- >> +$id: >> http://devicetree.org/schemas/display/panel/synaptics,td4300-panel.yaml# >> +$schema: http://devicetree.org/meta-schemas/core.yaml# >> + >> +title: Synaptics TDDI Display Panel Controller >> + >> +maintainers: >> + - Kaustabh Chakraborty <kauschluss@disroot.org> >> + >> +allOf: >> + - $ref: panel-common.yaml# >> + >> +properties: >> + compatible: >> + enum: >> + - syna,td4101-panel >> + - syna,td4300-panel >> + >> + reg: >> + maxItems: 1 >> + >> + vio-supply: >> + description: core I/O voltage supply >> + >> + vsn-supply: >> + description: negative voltage supply for analog circuits >> + >> + vsp-supply: >> + description: positive voltage supply for analog circuits >> + >> + backlight-gpios: >> + maxItems: 1 >> + description: backlight enable GPIO >> + >> + reset-gpios: true >> + width-mm: true >> + height-mm: true >> + panel-timing: true >> + >> +required: >> + - compatible >> + - reg >> + - width-mm >> + - height-mm >> + - panel-timing >> + >> +additionalProperties: false >> + >> +examples: >> + - | >> + #include <dt-bindings/gpio/gpio.h> >> + >> + dsi { >> + #address-cells = <1>; >> + #size-cells = <0>; >> + >> + panel@0 { >> + compatible = "syna,td4300-panel"; >> + reg = <0>; >> + >> + vio-supply = <&panel_vio_reg>; >> + vsn-supply = <&panel_vsn_reg>; >> + vsp-supply = <&panel_vsp_reg>; >> + >> + backlight-gpios = <&gpd3 5 GPIO_ACTIVE_LOW>; >> + reset-gpios = <&gpd3 4 GPIO_ACTIVE_LOW>; >> + >> + width-mm = <68>; >> + height-mm = <121>; >> + >> + panel-timing { > > Are the timings defined by the 'TD4300' name or might there be > different > panels with the same name but different timings? Yes, if I recall correctly, the same panel was used by some Huawei phones with different panel timings. So this is just future-proofing. > >> + clock-frequency = <144389520>; >> + >> + hactive = <1080>; >> + hsync-len = <4>; >> + hfront-porch = <120>; >> + hback-porch = <32>; >> + >> + vactive = <1920>; >> + vsync-len = <2>; >> + vfront-porch = <21>; >> + vback-porch = <4>; >> + }; >> + }; >> + }; >> + >> +... >> >> -- >> 2.50.0 >> > > -- > With best wishes > Dmitry ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 2/2] drm: panel: add support for Synaptics TDDI series DSI panels 2025-07-20 12:01 [PATCH v3 0/2] Support for Synaptics TDDI series panels Kaustabh Chakraborty 2025-07-20 12:01 ` [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel Kaustabh Chakraborty @ 2025-07-20 12:01 ` Kaustabh Chakraborty 2025-08-03 12:04 ` Dmitry Baryshkov 1 sibling, 1 reply; 7+ messages in thread From: Kaustabh Chakraborty @ 2025-07-20 12:01 UTC (permalink / raw) To: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jessica Zhang Cc: dri-devel, devicetree, linux-kernel, Kaustabh Chakraborty Synaptics TDDI (Touch/Display Integration) panels utilize a single chip for display and touch controllers. Implement a simple device driver for such panels, along with its built-in LED backlight controller, and add support for TD4101 and TD4300 panels in the driver. Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org> --- drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-synaptics-tddi.c | 289 +++++++++++++++++++++++++++ 3 files changed, 301 insertions(+) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 09b9f7ff9340abb708a503f7564acc46b2faaf7d..b080da939f5e3d11bf4c437ae167480d2721b41f 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -1021,6 +1021,17 @@ config DRM_PANEL_SYNAPTICS_R63353 Say Y if you want to enable support for panels based on the Synaptics R63353 controller. +config DRM_PANEL_SYNAPTICS_TDDI + tristate "Synaptics TDDI display panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for the Synaptics TDDI display + panels. There are multiple MIPI DSI panels manufactured under the TDDI + namesake, with varying resolutions and data lanes. They also have a + built-in LED backlight and a touch controller. + config DRM_PANEL_TDO_TL070WSH30 tristate "TDO TL070WSH30 DSI panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 957555b499968ebbfb55c87d2729ce88b5d48a57..a6e786e2b578e09d95de5b6430eba94c668ee4bc 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -98,6 +98,7 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o obj-$(CONFIG_DRM_PANEL_SUMMIT) += panel-summit.o obj-$(CONFIG_DRM_PANEL_SYNAPTICS_R63353) += panel-synaptics-r63353.o +obj-$(CONFIG_DRM_PANEL_SYNAPTICS_TDDI) += panel-synaptics-tddi.o obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o obj-$(CONFIG_DRM_PANEL_SONY_TD4353_JDI) += panel-sony-td4353-jdi.o obj-$(CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521) += panel-sony-tulip-truly-nt35521.o diff --git a/drivers/gpu/drm/panel/panel-synaptics-tddi.c b/drivers/gpu/drm/panel/panel-synaptics-tddi.c new file mode 100644 index 0000000000000000000000000000000000000000..1e99be8791770437ce22c482320a7c475f50019e --- /dev/null +++ b/drivers/gpu/drm/panel/panel-synaptics-tddi.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Synaptics TDDI display panel driver. + * + * Copyright (C) 2025 Kaustabh Chakraborty <kauschluss@disroot.org> + */ + +#include <linux/backlight.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> + +struct tddi_panel_data { + u8 lanes; + /* wait timings for panel enable */ + u8 delay_ms_sleep_exit; + u8 delay_ms_display_on; + /* wait timings for panel disable */ + u8 delay_ms_display_off; + u8 delay_ms_sleep_enter; +}; + +struct tddi_ctx { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct drm_display_mode mode; + struct backlight_device *backlight; + const struct tddi_panel_data *data; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + struct gpio_desc *backlight_gpio; + u32 bus_flags; + u32 width; + u32 height; +}; + +static const struct regulator_bulk_data tddi_supplies[] = { + { .supply = "vio" }, + { .supply = "vsn" }, + { .supply = "vsp" }, +}; + +static inline struct tddi_ctx *to_tddi_ctx(struct drm_panel *panel) +{ + return container_of(panel, struct tddi_ctx, panel); +} + +static int tddi_update_status(struct backlight_device *backlight) +{ + struct tddi_ctx *ctx = bl_get_data(backlight); + struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; + u8 brightness = backlight_get_brightness(backlight); + + if (!ctx->panel.enabled) + return 0; + + mipi_dsi_dcs_set_display_brightness_multi(&dsi, brightness); + + return dsi.accum_err; +} + +static int tddi_prepare(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(tddi_supplies), ctx->supplies); + if (ret < 0) { + dev_err(dev, "failed to enable regulators: %d\n", ret); + return ret; + } + + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); + + gpiod_set_value_cansleep(ctx->backlight_gpio, 0); + usleep_range(5000, 6000); + + return 0; +} + +static int tddi_unprepare(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + + gpiod_set_value_cansleep(ctx->backlight_gpio, 1); + usleep_range(5000, 6000); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + + regulator_bulk_disable(ARRAY_SIZE(tddi_supplies), ctx->supplies); + + return 0; +} + +static int tddi_enable(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; + u8 brightness = ctx->backlight->props.brightness; + + mipi_dsi_dcs_write_seq_multi(&dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x0c); + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_sleep_exit); + + /* sync the panel with the backlight's brightness level */ + mipi_dsi_dcs_set_display_brightness_multi(&dsi, brightness); + + mipi_dsi_dcs_set_display_on_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_display_on); + + return dsi.accum_err; +}; + +static int tddi_disable(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; + + mipi_dsi_dcs_set_display_off_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_display_off); + + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_sleep_enter); + + return dsi.accum_err; +} + +static int tddi_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, &ctx->mode); + if (!mode) + return -ENOMEM; + + mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + drm_mode_set_name(mode); + + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + connector->display_info.bus_flags = ctx->bus_flags; + + return 1; +} + +static const struct backlight_ops tddi_bl_ops = { + .update_status = tddi_update_status, +}; + +static const struct drm_panel_funcs tddi_drm_panel_funcs = { + .prepare = tddi_prepare, + .unprepare = tddi_unprepare, + .enable = tddi_enable, + .disable = tddi_disable, + .get_modes = tddi_get_modes, +}; + +static int tddi_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct tddi_ctx *ctx; + int ret; + + ctx = devm_drm_panel_alloc(dev, struct tddi_ctx, panel, + &tddi_drm_panel_funcs, DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ctx->data = of_device_get_match_data(dev); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(tddi_supplies), + tddi_supplies, &ctx->supplies); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get regulators\n"); + + ctx->backlight_gpio = devm_gpiod_get_optional(dev, "backlight", GPIOD_ASIS); + if (IS_ERR(ctx->backlight_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->backlight_gpio), + "failed to get backlight-gpios\n"); + + ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "failed to get reset-gpios\n"); + + ret = of_get_drm_panel_display_mode(dev->of_node, &ctx->mode, + &ctx->bus_flags); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get panel timings\n"); + + ctx->backlight = devm_backlight_device_register(dev, dev_name(dev), dev, + ctx, &tddi_bl_ops, NULL); + if (IS_ERR(ctx->backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->backlight), + "failed to register backlight device"); + + ctx->backlight->props.type = BACKLIGHT_PLATFORM; + ctx->backlight->props.brightness = 255; + ctx->backlight->props.max_brightness = 255; + + dsi->lanes = ctx->data->lanes; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_VIDEO_NO_HFP; + + ctx->panel.prepare_prev_first = true; + drm_panel_add(&ctx->panel); + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "failed to attach to DSI host\n"); + } + + return 0; +} + +static void tddi_remove(struct mipi_dsi_device *dsi) +{ + struct tddi_ctx *ctx = mipi_dsi_get_drvdata(dsi); + + drm_panel_remove(&ctx->panel); +} + +static const struct tddi_panel_data td4101_panel_data = { + .lanes = 2, + /* wait timings for panel enable */ + .delay_ms_sleep_exit = 100, + .delay_ms_display_on = 0, + /* wait timings for panel disable */ + .delay_ms_display_off = 20, + .delay_ms_sleep_enter = 90, +}; + +static const struct tddi_panel_data td4300_panel_data = { + .lanes = 4, + /* wait timings for panel enable */ + .delay_ms_sleep_exit = 100, + .delay_ms_display_on = 0, + /* wait timings for panel disable */ + .delay_ms_display_off = 0, + .delay_ms_sleep_enter = 0, +}; + +static const struct of_device_id tddi_of_device_id[] = { + { + .compatible = "syna,td4101-panel", + .data = &td4101_panel_data, + }, { + .compatible = "syna,td4300-panel", + .data = &td4300_panel_data, + }, { } +}; +MODULE_DEVICE_TABLE(of, tddi_of_device_id); + +static struct mipi_dsi_driver tddi_dsi_driver = { + .probe = tddi_probe, + .remove = tddi_remove, + .driver = { + .name = "panel-synaptics-tddi", + .of_match_table = tddi_of_device_id, + }, +}; +module_mipi_dsi_driver(tddi_dsi_driver); + +MODULE_AUTHOR("Kaustabh Chakraborty <kauschluss@disroot.org>"); +MODULE_DESCRIPTION("Synaptics TDDI Display Panel Driver"); +MODULE_LICENSE("GPL"); -- 2.50.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] drm: panel: add support for Synaptics TDDI series DSI panels 2025-07-20 12:01 ` [PATCH v3 2/2] drm: panel: add support for Synaptics TDDI series DSI panels Kaustabh Chakraborty @ 2025-08-03 12:04 ` Dmitry Baryshkov 0 siblings, 0 replies; 7+ messages in thread From: Dmitry Baryshkov @ 2025-08-03 12:04 UTC (permalink / raw) To: Kaustabh Chakraborty Cc: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jessica Zhang, dri-devel, devicetree, linux-kernel On Sun, Jul 20, 2025 at 05:31:55PM +0530, Kaustabh Chakraborty wrote: > Synaptics TDDI (Touch/Display Integration) panels utilize a single chip > for display and touch controllers. Implement a simple device driver for > such panels, along with its built-in LED backlight controller, and add > support for TD4101 and TD4300 panels in the driver. > > Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org> > --- > drivers/gpu/drm/panel/Kconfig | 11 + > drivers/gpu/drm/panel/Makefile | 1 + > drivers/gpu/drm/panel/panel-synaptics-tddi.c | 289 +++++++++++++++++++++++++++ > 3 files changed, 301 insertions(+) > > + > +static int tddi_get_modes(struct drm_panel *panel, > + struct drm_connector *connector) > +{ > + struct tddi_ctx *ctx = to_tddi_ctx(panel); > + struct drm_display_mode *mode; > + > + mode = drm_mode_duplicate(connector->dev, &ctx->mode); > + if (!mode) > + return -ENOMEM; > + > + mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; > + drm_mode_probed_add(connector, mode); > + drm_mode_set_name(mode); > + > + connector->display_info.width_mm = mode->width_mm; > + connector->display_info.height_mm = mode->height_mm; Please use drm_connector_helper_get_modes_fixed() > + connector->display_info.bus_flags = ctx->bus_flags; > + > + return 1; > +} > + > +static const struct backlight_ops tddi_bl_ops = { > + .update_status = tddi_update_status, > +}; > + > +static const struct drm_panel_funcs tddi_drm_panel_funcs = { > + .prepare = tddi_prepare, > + .unprepare = tddi_unprepare, > + .enable = tddi_enable, > + .disable = tddi_disable, > + .get_modes = tddi_get_modes, > +}; > + > +static int tddi_probe(struct mipi_dsi_device *dsi) > +{ > + struct device *dev = &dsi->dev; > + struct tddi_ctx *ctx; > + int ret; > + > + ctx = devm_drm_panel_alloc(dev, struct tddi_ctx, panel, > + &tddi_drm_panel_funcs, DRM_MODE_CONNECTOR_DSI); > + if (IS_ERR(ctx)) > + return PTR_ERR(ctx); > + > + ctx->data = of_device_get_match_data(dev); > + > + ctx->dsi = dsi; > + mipi_dsi_set_drvdata(dsi, ctx); > + > + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(tddi_supplies), > + tddi_supplies, &ctx->supplies); > + if (ret < 0) > + return dev_err_probe(dev, ret, "failed to get regulators\n"); > + > + ctx->backlight_gpio = devm_gpiod_get_optional(dev, "backlight", GPIOD_ASIS); > + if (IS_ERR(ctx->backlight_gpio)) > + return dev_err_probe(dev, PTR_ERR(ctx->backlight_gpio), > + "failed to get backlight-gpios\n"); > + > + ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); > + if (IS_ERR(ctx->reset_gpio)) > + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), > + "failed to get reset-gpios\n"); > + > + ret = of_get_drm_panel_display_mode(dev->of_node, &ctx->mode, > + &ctx->bus_flags); > + if (ret < 0) > + return dev_err_probe(dev, ret, "failed to get panel timings\n"); > + > + ctx->backlight = devm_backlight_device_register(dev, dev_name(dev), dev, > + ctx, &tddi_bl_ops, NULL); > + if (IS_ERR(ctx->backlight)) > + return dev_err_probe(dev, PTR_ERR(ctx->backlight), > + "failed to register backlight device"); > + > + ctx->backlight->props.type = BACKLIGHT_PLATFORM; > + ctx->backlight->props.brightness = 255; > + ctx->backlight->props.max_brightness = 255; Props should be set before registering the backlight > + > + dsi->lanes = ctx->data->lanes; > + dsi->format = MIPI_DSI_FMT_RGB888; > + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | > + MIPI_DSI_MODE_VIDEO_NO_HFP; > + > + ctx->panel.prepare_prev_first = true; > + drm_panel_add(&ctx->panel); > + > + ret = devm_mipi_dsi_attach(dev, dsi); > + if (ret < 0) { > + drm_panel_remove(&ctx->panel); > + return dev_err_probe(dev, ret, "failed to attach to DSI host\n"); > + } > + > + return 0; > +} > + > +static void tddi_remove(struct mipi_dsi_device *dsi) > +{ > + struct tddi_ctx *ctx = mipi_dsi_get_drvdata(dsi); > + > + drm_panel_remove(&ctx->panel); > +} > + > +static const struct tddi_panel_data td4101_panel_data = { > + .lanes = 2, > + /* wait timings for panel enable */ > + .delay_ms_sleep_exit = 100, > + .delay_ms_display_on = 0, > + /* wait timings for panel disable */ > + .delay_ms_display_off = 20, > + .delay_ms_sleep_enter = 90, > +}; > + > +static const struct tddi_panel_data td4300_panel_data = { > + .lanes = 4, > + /* wait timings for panel enable */ > + .delay_ms_sleep_exit = 100, > + .delay_ms_display_on = 0, > + /* wait timings for panel disable */ > + .delay_ms_display_off = 0, > + .delay_ms_sleep_enter = 0, > +}; > + > +static const struct of_device_id tddi_of_device_id[] = { > + { > + .compatible = "syna,td4101-panel", > + .data = &td4101_panel_data, > + }, { > + .compatible = "syna,td4300-panel", > + .data = &td4300_panel_data, > + }, { } > +}; > +MODULE_DEVICE_TABLE(of, tddi_of_device_id); > + > +static struct mipi_dsi_driver tddi_dsi_driver = { > + .probe = tddi_probe, > + .remove = tddi_remove, > + .driver = { > + .name = "panel-synaptics-tddi", > + .of_match_table = tddi_of_device_id, > + }, > +}; > +module_mipi_dsi_driver(tddi_dsi_driver); > + > +MODULE_AUTHOR("Kaustabh Chakraborty <kauschluss@disroot.org>"); > +MODULE_DESCRIPTION("Synaptics TDDI Display Panel Driver"); > +MODULE_LICENSE("GPL"); > > -- > 2.50.0 > -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-08-06 15:22 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-07-20 12:01 [PATCH v3 0/2] Support for Synaptics TDDI series panels Kaustabh Chakraborty 2025-07-20 12:01 ` [PATCH v3 1/2] dt-bindings: display: panel: document Synaptics TDDI panel Kaustabh Chakraborty 2025-07-21 7:48 ` Krzysztof Kozlowski 2025-08-03 12:02 ` Dmitry Baryshkov 2025-08-06 15:22 ` Kaustabh Chakraborty 2025-07-20 12:01 ` [PATCH v3 2/2] drm: panel: add support for Synaptics TDDI series DSI panels Kaustabh Chakraborty 2025-08-03 12:04 ` Dmitry Baryshkov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®