* [PATCH v2 01/20] dt-bindings: display: tilcdc: Convert to DT schema
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-16 6:01 ` Krzysztof Kozlowski
2025-12-11 16:38 ` [PATCH v2 02/20] dt-bindings: display: tilcdc: Mark panel binding as deprecated Kory Maincent (TI.com)
` (18 subsequent siblings)
19 siblings, 1 reply; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Convert the device tree binding documentation for tilcdc
from plain text to DT binding schema.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
.../devicetree/bindings/display/tilcdc/tilcdc.txt | 82 ------------------
.../devicetree/bindings/display/tilcdc/tilcdc.yaml | 96 ++++++++++++++++++++++
2 files changed, 96 insertions(+), 82 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
deleted file mode 100644
index 3b3d0bbfcfff4..0000000000000
--- a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-Device-Tree bindings for tilcdc DRM driver
-
-Required properties:
- - compatible: value should be one of the following:
- - "ti,am33xx-tilcdc" for AM335x based boards
- - "ti,da850-tilcdc" for DA850/AM18x/OMAP-L138 based boards
- - interrupts: the interrupt number
- - reg: base address and size of the LCDC device
-
-Recommended properties:
- - ti,hwmods: Name of the hwmod associated to the LCDC
-
-Optional properties:
- - max-bandwidth: The maximum pixels per second that the memory
- interface / lcd controller combination can sustain
- - max-width: The maximum horizontal pixel width supported by
- the lcd controller.
- - max-pixelclock: The maximum pixel clock that can be supported
- by the lcd controller in KHz.
- - blue-and-red-wiring: Recognized values "straight" or "crossed".
- This property deals with the LCDC revision 2 (found on AM335x)
- color errata [1].
- - "straight" indicates normal wiring that supports RGB565,
- BGR888, and XBGR8888 color formats.
- - "crossed" indicates wiring that has blue and red wires
- crossed. This setup supports BGR565, RGB888 and XRGB8888
- formats.
- - If the property is not present or its value is not recognized
- the legacy mode is assumed. This configuration supports RGB565,
- RGB888 and XRGB8888 formats. However, depending on wiring, the red
- and blue colors are swapped in either 16 or 24-bit color modes.
-
-Optional nodes:
-
- - port/ports: to describe a connection to an external encoder. The
- binding follows Documentation/devicetree/bindings/graph.txt and
- supports a single port with a single endpoint.
-
- - See also Documentation/devicetree/bindings/display/tilcdc/panel.txt and
- Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml for connecting
- tfp410 DVI encoder or lcd panel to lcdc
-
-[1] There is an errata about AM335x color wiring. For 16-bit color mode
- the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]),
- but for 24 bit color modes the wiring of blue and red components is
- crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is
- for Blue[3-7]. For more details see section 3.1.1 in AM335x
- Silicon Errata:
- https://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360
-
-Example:
-
- fb: fb@4830e000 {
- compatible = "ti,am33xx-tilcdc", "ti,da850-tilcdc";
- reg = <0x4830e000 0x1000>;
- interrupt-parent = <&intc>;
- interrupts = <36>;
- ti,hwmods = "lcdc";
-
- blue-and-red-wiring = "crossed";
-
- port {
- lcdc_0: endpoint {
- remote-endpoint = <&hdmi_0>;
- };
- };
- };
-
- tda19988: tda19988 {
- compatible = "nxp,tda998x";
- reg = <0x70>;
-
- pinctrl-names = "default", "off";
- pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
- pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
-
- port {
- hdmi_0: endpoint {
- remote-endpoint = <&lcdc_0>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.yaml b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.yaml
new file mode 100644
index 0000000000000..34ac1fd04d5c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tilcdc/tilcdc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI LCD Controller, found on AM335x, DA850, AM18x and OMAP-L138
+
+maintainers:
+ - Kory Maincent <kory.maincent@bootlin.com>
+
+properties:
+ compatible:
+ enum:
+ - ti,am33xx-tilcdc
+ - ti,da850-tilcdc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ port:
+ $ref: /schemas/graph.yaml#/properties/port
+
+ ti,hwmods:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ Name of the hwmod associated to the LCDC
+
+ max-bandwidth:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ The maximum pixels per second that the memory interface / lcd
+ controller combination can sustain
+
+ max-width:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ The maximum horizontal pixel width supported by the lcd controller.
+
+ max-pixelclock:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ The maximum pixel clock that can be supported by the lcd controller
+ in KHz.
+
+ blue-and-red-wiring:
+ enum: [straight, crossed]
+ description:
+ This property deals with the LCDC revision 2 (found on AM335x)
+ color errata [1].
+ - "straight" indicates normal wiring that supports RGB565,
+ BGR888, and XBGR8888 color formats.
+ - "crossed" indicates wiring that has blue and red wires
+ crossed. This setup supports BGR565, RGB888 and XRGB8888
+ formats.
+ - If the property is not present or its value is not recognized
+ the legacy mode is assumed. This configuration supports RGB565,
+ RGB888 and XRGB8888 formats. However, depending on wiring, the red
+ and blue colors are swapped in either 16 or 24-bit color modes.
+
+ [1] There is an errata about AM335x color wiring. For 16-bit color
+ mode the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]),
+ but for 24 bit color modes the wiring of blue and red components is
+ crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is
+ for Blue[3-7]. For more details see section 3.1.1 in AM335x
+ Silicon Errata
+ https://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360
+
+required:
+ - compatible
+ - interrupts
+ - reg
+ - port
+
+additionalProperties: false
+
+examples:
+ - |
+ tilcdc: tilcdc@4830e000 {
+ compatible = "ti,am33xx-tilcdc";
+ reg = <0x4830e000 0x1000>;
+ interrupt-parent = <&intc>;
+ interrupts = <36>;
+ ti,hwmods = "lcdc";
+
+ blue-and-red-wiring = "crossed";
+
+ port {
+ lcdc_0: endpoint {
+ remote-endpoint = <&hdmi_0>;
+ };
+ };
+ };
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 01/20] dt-bindings: display: tilcdc: Convert to DT schema
2025-12-11 16:38 ` [PATCH v2 01/20] dt-bindings: display: tilcdc: Convert to DT schema Kory Maincent (TI.com)
@ 2025-12-16 6:01 ` Krzysztof Kozlowski
0 siblings, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-12-16 6:01 UTC (permalink / raw)
To: Kory Maincent (TI.com)
Cc: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap
On Thu, Dec 11, 2025 at 05:38:45PM +0100, Kory Maincent (TI.com) wrote:
> diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.yaml b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.yaml
> new file mode 100644
> index 0000000000000..34ac1fd04d5c6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.yaml
Filename based on compatible, so for example ti,am33xx-tilcdc.yaml or
worse case ti,tilcdc.yaml (see writing bindings and writing schema docs)
> @@ -0,0 +1,96 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/tilcdc/tilcdc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI LCD Controller, found on AM335x, DA850, AM18x and OMAP-L138
> +
> +maintainers:
> + - Kory Maincent <kory.maincent@bootlin.com>
> +
> +properties:
> + compatible:
> + enum:
> + - ti,am33xx-tilcdc
> + - ti,da850-tilcdc
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + port:
> + $ref: /schemas/graph.yaml#/properties/port
> +
> + ti,hwmods:
> + $ref: /schemas/types.yaml#/definitions/string
> + description:
> + Name of the hwmod associated to the LCDC
> +
> + max-bandwidth:
constraints? Is '1' valid? Is INT_MAX valid as well?
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + The maximum pixels per second that the memory interface / lcd
> + controller combination can sustain
> +
> + max-width:
> + $ref: /schemas/types.yaml#/definitions/uint32
constraints?
> + description:
> + The maximum horizontal pixel width supported by the lcd controller.
> +
> + max-pixelclock:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + The maximum pixel clock that can be supported by the lcd controller
> + in KHz.
> +
> + blue-and-red-wiring:
> + enum: [straight, crossed]
> + description:
> + This property deals with the LCDC revision 2 (found on AM335x)
> + color errata [1].
> + - "straight" indicates normal wiring that supports RGB565,
> + BGR888, and XBGR8888 color formats.
> + - "crossed" indicates wiring that has blue and red wires
> + crossed. This setup supports BGR565, RGB888 and XRGB8888
> + formats.
> + - If the property is not present or its value is not recognized
> + the legacy mode is assumed. This configuration supports RGB565,
> + RGB888 and XRGB8888 formats. However, depending on wiring, the red
> + and blue colors are swapped in either 16 or 24-bit color modes.
> +
> + [1] There is an errata about AM335x color wiring. For 16-bit color
> + mode the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]),
> + but for 24 bit color modes the wiring of blue and red components is
> + crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is
> + for Blue[3-7]. For more details see section 3.1.1 in AM335x
> + Silicon Errata
> + https://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360
> +
> +required:
> + - compatible
> + - interrupts
> + - reg
> + - port
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + tilcdc: tilcdc@4830e000 {
Drop unused label. Generic node name, e.g. "display-controller" or
"lcd-controller".
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 02/20] dt-bindings: display: tilcdc: Mark panel binding as deprecated
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 01/20] dt-bindings: display: tilcdc: Convert to DT schema Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-16 6:02 ` Krzysztof Kozlowski
2025-12-11 16:38 ` [PATCH v2 03/20] drm/tilcdc: Remove simulate_vesa_sync flag Kory Maincent (TI.com)
` (17 subsequent siblings)
19 siblings, 1 reply; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Mark the ti,tilcdc,panel binding as deprecated in the documentation.
This legacy binding should no longer be used for new designs. Users
should migrate to the standard DRM panel bindings instead.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
Change in v2:
- New patch
---
Documentation/devicetree/bindings/display/tilcdc/panel.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/tilcdc/panel.txt b/Documentation/devicetree/bindings/display/tilcdc/panel.txt
index 808216310ea27..b973174d704ed 100644
--- a/Documentation/devicetree/bindings/display/tilcdc/panel.txt
+++ b/Documentation/devicetree/bindings/display/tilcdc/panel.txt
@@ -1,4 +1,5 @@
Device-Tree bindings for tilcdc DRM generic panel output driver
+This binding is deprecated and should not be used.
Required properties:
- compatible: value should be "ti,tilcdc,panel".
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 02/20] dt-bindings: display: tilcdc: Mark panel binding as deprecated
2025-12-11 16:38 ` [PATCH v2 02/20] dt-bindings: display: tilcdc: Mark panel binding as deprecated Kory Maincent (TI.com)
@ 2025-12-16 6:02 ` Krzysztof Kozlowski
0 siblings, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-12-16 6:02 UTC (permalink / raw)
To: Kory Maincent (TI.com)
Cc: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap
On Thu, Dec 11, 2025 at 05:38:46PM +0100, Kory Maincent (TI.com) wrote:
> Mark the ti,tilcdc,panel binding as deprecated in the documentation.
> This legacy binding should no longer be used for new designs. Users
> should migrate to the standard DRM panel bindings instead.
>
> Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 03/20] drm/tilcdc: Remove simulate_vesa_sync flag
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 01/20] dt-bindings: display: tilcdc: Convert to DT schema Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 02/20] dt-bindings: display: tilcdc: Mark panel binding as deprecated Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 04/20] drm/tilcdc: Add support for DRM bus flags and simplify panel config Kory Maincent (TI.com)
` (16 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The tilcdc hardware does not generate VESA-compliant sync signals. It
aligns the vertical sync (VS) on the second edge of the horizontal sync
(HS) instead of the first edge. To compensate for this hardware
behavior, the driver applies a timing adjustment in mode_fixup().
Previously, this adjustment was conditional based on the simulate_vesa_sync
flag, which was only set when using external encoders. This appears
problematic because:
1. The timing adjustment seems needed for the hardware behavior regardless
of whether an external encoder is used
2. The external encoder infrastructure is driver-specific and being
removed due to design issues
3. Boards using tilcdc without bridges (e.g., am335x-evm, am335x-evmsk)
may not be getting the necessary timing adjustments
Remove the simulate_vesa_sync flag and apply the VESA sync timing
adjustment unconditionally, ensuring consistent behavior across all
configurations. While it's unclear if the previous conditional behavior
was causing actual issues, the unconditional adjustment better reflects
the hardware's characteristics.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
Only few board currently use tilcdc not associated to a bridge like the
am335x_evm or the am335x-evmsk.
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 16 ----------------
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 --
drivers/gpu/drm/tilcdc/tilcdc_external.c | 1 -
3 files changed, 19 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 52c95131af5af..b06b1453db2dd 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -47,9 +47,6 @@ struct tilcdc_crtc {
struct drm_framebuffer *next_fb;
- /* Only set if an external encoder is connected */
- bool simulate_vesa_sync;
-
int sync_lost_count;
bool frame_intact;
struct work_struct recover_work;
@@ -642,11 +639,6 @@ static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
-
- if (!tilcdc_crtc->simulate_vesa_sync)
- return true;
-
/*
* tilcdc does not generate VESA-compliant sync but aligns
* VS on the second edge of HS instead of first edge.
@@ -866,14 +858,6 @@ void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
tilcdc_crtc->info = info;
}
-void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc,
- bool simulate_vesa_sync)
-{
- struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
-
- tilcdc_crtc->simulate_vesa_sync = simulate_vesa_sync;
-}
-
void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 58b276f82a669..3aba3a1155ba0 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -160,8 +160,6 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc);
void tilcdc_crtc_update_clk(struct drm_crtc *crtc);
void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
const struct tilcdc_panel_info *info);
-void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc,
- bool simulate_vesa_sync);
void tilcdc_crtc_shutdown(struct drm_crtc *crtc);
void tilcdc_crtc_destroy(struct drm_crtc *crtc);
int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 3b86d002ef62e..da755a411d9ff 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -80,7 +80,6 @@ int tilcdc_add_component_encoder(struct drm_device *ddev)
return -ENODEV;
/* Only tda998x is supported at the moment. */
- tilcdc_crtc_set_simulate_vesa_sync(priv->crtc, true);
tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_tda998x);
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 04/20] drm/tilcdc: Add support for DRM bus flags and simplify panel config
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (2 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 03/20] drm/tilcdc: Remove simulate_vesa_sync flag Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 05/20] drm/tilcdc: Convert legacy panel binding via DT overlay at boot time Kory Maincent (TI.com)
` (15 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Migrate CRTC mode configuration to use standard DRM bus flags in
preparation for removing the tilcdc_panel driver and its custom
tilcdc_panel_info structure.
Add support for DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE and
DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE flags to control pixel clock and sync
signal edge polarity, while maintaining backward compatibility with the
existing tilcdc panel info structure.
Simplify several hardware parameters by setting them to fixed defaults
based on common usage across existing device trees:
- DMA burst size: 16 (previously configurable via switch statement)
- AC bias frequency: 255 (previously panel-specific)
- FIFO DMA request delay: 128 (previously panel-specific)
These parameters show no variation in real-world usage, so hardcoding
them simplifies the driver without losing functionality.
Preserve FIFO threshold configurability by detecting the SoC type, as
this parameter varies between AM33xx (8) and DA850 (16) platforms.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
Change in v2:
- Use SoC type instead of devicetree parameter to set FIFO threshold
value.
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 47 +++++++++++++-----------------------
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 29 ++++++++++++++++------
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 ++
3 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index b06b1453db2dd..2309a9a0c925d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -285,27 +285,15 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
/* Configure the Burst Size and fifo threshold of DMA: */
reg = tilcdc_read(dev, LCDC_DMA_CTRL_REG) & ~0x00000770;
- switch (info->dma_burst_sz) {
- case 1:
- reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_1);
- break;
- case 2:
- reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_2);
- break;
- case 4:
- reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_4);
- break;
- case 8:
- reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_8);
- break;
- case 16:
- reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_16);
- break;
- default:
- dev_err(dev->dev, "invalid burst size\n");
- return;
+ /* Use 16 bit DMA burst size by default */
+ reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_16);
+ if (priv->fifo_th) {
+ int fifo_th_val = ilog2(priv->fifo_th) - 3;
+
+ reg |= (fifo_th_val << 8);
+ } else {
+ reg |= (info->fifo_th << 8);
}
- reg |= (info->fifo_th << 8);
tilcdc_write(dev, LCDC_DMA_CTRL_REG, reg);
/* Configure timings: */
@@ -321,8 +309,8 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
/* Set AC Bias Period and Number of Transitions per Interrupt: */
reg = tilcdc_read(dev, LCDC_RASTER_TIMING_2_REG) & ~0x000fff00;
- reg |= LCDC_AC_BIAS_FREQUENCY(info->ac_bias) |
- LCDC_AC_BIAS_TRANSITIONS_PER_INT(info->ac_bias_intrpt);
+ /* Use 255 AC Bias Pin Frequency by default */
+ reg |= LCDC_AC_BIAS_FREQUENCY(255);
/*
* subtract one from hfp, hbp, hsw because the hardware uses
@@ -392,20 +380,19 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
return;
}
}
- reg |= info->fdd << 12;
+ /* Use 128 FIFO DMA Request Delay by default */
+ reg |= 128 << 12;
tilcdc_write(dev, LCDC_RASTER_CTRL_REG, reg);
- if (info->invert_pxl_clk)
+ if (info->invert_pxl_clk ||
+ mode->flags == DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK);
else
tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK);
- if (info->sync_ctrl)
- tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
- else
- tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
-
- if (info->sync_edge)
+ tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
+ if (info->sync_edge ||
+ mode->flags == DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE)
tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
else
tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 3dcbec312bacb..60230fa9cec95 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -31,6 +31,11 @@
#include "tilcdc_panel.h"
#include "tilcdc_regs.h"
+enum {
+ AM33XX_TILCDC,
+ DA850_TILCDC,
+};
+
static LIST_HEAD(module_list);
static const u32 tilcdc_rev1_formats[] = { DRM_FORMAT_RGB565 };
@@ -192,11 +197,19 @@ static void tilcdc_fini(struct drm_device *dev)
drm_dev_put(dev);
}
+static const struct of_device_id tilcdc_of_match[] = {
+ { .compatible = "ti,am33xx-tilcdc", .data = (void *)AM33XX_TILCDC},
+ { .compatible = "ti,da850-tilcdc", .data = (void *)DA850_TILCDC},
+ { },
+};
+MODULE_DEVICE_TABLE(of, tilcdc_of_match);
+
static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
{
struct drm_device *ddev;
struct platform_device *pdev = to_platform_device(dev);
struct device_node *node = dev->of_node;
+ const struct of_device_id *of_id;
struct tilcdc_drm_private *priv;
u32 bpp = 0;
int ret;
@@ -209,6 +222,10 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
if (IS_ERR(ddev))
return PTR_ERR(ddev);
+ of_id = of_match_node(tilcdc_of_match, node);
+ if (!of_id)
+ return -ENODEV;
+
ddev->dev_private = priv;
platform_set_drvdata(pdev, ddev);
drm_mode_config_init(ddev);
@@ -309,6 +326,11 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock);
+ if ((unsigned int)of_id->data == DA850_TILCDC)
+ priv->fifo_th = 16;
+ else
+ priv->fifo_th = 8;
+
ret = tilcdc_crtc_create(ddev);
if (ret < 0) {
dev_err(dev, "failed to create crtc\n");
@@ -597,13 +619,6 @@ static void tilcdc_pdev_shutdown(struct platform_device *pdev)
drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
}
-static const struct of_device_id tilcdc_of_match[] = {
- { .compatible = "ti,am33xx-tilcdc", },
- { .compatible = "ti,da850-tilcdc", },
- { },
-};
-MODULE_DEVICE_TABLE(of, tilcdc_of_match);
-
static struct platform_driver tilcdc_platform_driver = {
.probe = tilcdc_pdev_probe,
.remove = tilcdc_pdev_remove,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 3aba3a1155ba0..79078b4ae7393 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -61,6 +61,8 @@ struct tilcdc_drm_private {
*/
uint32_t max_width;
+ u32 fifo_th;
+
/* Supported pixel formats */
const uint32_t *pixelformats;
uint32_t num_pixelformats;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 05/20] drm/tilcdc: Convert legacy panel binding via DT overlay at boot time
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (3 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 04/20] drm/tilcdc: Add support for DRM bus flags and simplify panel config Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 06/20] drm/tilcdc: Remove tilcdc panel driver Kory Maincent (TI.com)
` (14 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
To maintain backward compatibility while removing the deprecated
tilcdc_panel driver, add a tilcdc_panel_legacy subdriver that converts
the legacy "ti,tilcdc,panel" devicetree binding to the standard
panel-dpi binding at early boot.
The conversion uses an embedded device tree overlay that is applied and
modified during subsys_initcall. The process:
- Apply embedded overlay to create a panel-dpi node with placeholder
timing properties and port/endpoint connections to the LCDC
- Copy all properties from the legacy panel node to the new panel-dpi
- Copy display-timings from the legacy panel
- Convert legacy panel-info properties (invert-pxl-clk, sync-edge) to
standard display timing properties (pixelclk-active, syncclk-active)
- Disable the legacy panel by removing its compatible property to
prevent the deprecated driver from binding
The result is a standard panel-dpi node with proper endpoints and
timing properties, allowing the DRM panel infrastructure to work with
legacy devicetrees without modification.
Other legacy panel-info properties are not migrated as they consistently
use default values across all mainline devicetrees and can be hardcoded
in the tilcdc driver.
This feature is optional via CONFIG_DRM_TILCDC_PANEL_LEGACY and should
only be enabled for systems with legacy devicetrees containing
"ti,tilcdc,panel" nodes.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
Using the approach of applying an overlay and then modifying the live
device tree is the solution I found that requires no modification of the
OF core. Dealing entirely with overlay changesets would bring additional
requirements such as phandle resolution management, which is internal to
the OF framework. I intend to avoid OF core change to support this legacy
binding.
Change in v2:
- New patch.
---
drivers/gpu/drm/tilcdc/Kconfig | 14 +++
drivers/gpu/drm/tilcdc/Makefile | 2 +
drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c | 159 ++++++++++++++++++++++++
drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.dtso | 44 +++++++
4 files changed, 219 insertions(+)
diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig
index 24f9a245ba593..4dcae0a06b819 100644
--- a/drivers/gpu/drm/tilcdc/Kconfig
+++ b/drivers/gpu/drm/tilcdc/Kconfig
@@ -14,3 +14,17 @@ config DRM_TILCDC
controller, for example AM33xx in beagle-bone, DA8xx, or
OMAP-L1xx. This driver replaces the FB_DA8XX fbdev driver.
+config DRM_TILCDC_PANEL_LEGACY
+ bool "Support device tree blobs using TI LCDC Panel binding"
+ default n
+ depends on DRM_TILCDC
+ depends on OF
+ depends on BACKLIGHT_CLASS_DEVICE
+ depends on PM
+ select OF_OVERLAY
+ select DRM_PANEL_SIMPLE
+ help
+ Choose this option if you need a kernel that is compatible
+ with device tree blobs using the obsolete "ti,tilcdc,panel"
+ binding. If you find "ti,tilcdc,panel"-string from your DTB,
+ you probably need this. Otherwise you do not.
diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
index f5190477de721..6d6a08b5adf40 100644
--- a/drivers/gpu/drm/tilcdc/Makefile
+++ b/drivers/gpu/drm/tilcdc/Makefile
@@ -11,3 +11,5 @@ tilcdc-y := \
tilcdc_drv.o
obj-$(CONFIG_DRM_TILCDC) += tilcdc.o
+obj-$(CONFIG_DRM_TILCDC_PANEL_LEGACY) += tilcdc_panel_legacy.o \
+ tilcdc_panel_legacy.dtbo.o
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c b/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c
new file mode 100644
index 0000000000000..a9651dd9f9935
--- /dev/null
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Kory Maincent <kory.maincent@bootlin.com>
+ *
+ * To support the legacy "ti,tilcdc,panel" binding, the devicetree has to
+ * be transformed to the new panel-dpi binding with the endpoint associated.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/slab.h>
+
+/* Embedded dtbo symbols created by cmd_wrap_S_dtb in scripts/Makefile.lib */
+extern char __dtbo_tilcdc_panel_legacy_begin[];
+extern char __dtbo_tilcdc_panel_legacy_end[];
+
+static void __init
+tilcdc_panel_update_prop(struct device_node *node, char *name,
+ void *val, int length)
+{
+ struct property *prop;
+
+ prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+ if (!prop)
+ return;
+
+ prop->name = kstrdup(name, GFP_KERNEL);
+ prop->length = length;
+ prop->value = kmemdup(val, length, GFP_KERNEL);
+ of_update_property(node, prop);
+}
+
+static int __init tilcdc_panel_copy_props(struct device_node *old_panel,
+ struct device_node *new_panel)
+{
+ struct device_node *child, *old_timing, *new_timing, *panel_info;
+ u32 invert_pxl_clk = 0, sync_edge = 0;
+ struct property *prop;
+
+ /* Copy all panel properties to the new panel node */
+ for_each_property_of_node(old_panel, prop) {
+ if (!strncmp(prop->name, "compatible", sizeof("compatible")))
+ continue;
+
+ tilcdc_panel_update_prop(new_panel, prop->name,
+ prop->value, prop->length);
+ }
+
+ child = of_get_child_by_name(old_panel, "display-timings");
+ if (!child)
+ return -EINVAL;
+
+ /* The default display timing is the one specified as native-mode.
+ * If no native-mode is specified then the first node is assumed
+ * to be the native mode.
+ */
+ old_timing = of_parse_phandle(child, "native-mode", 0);
+ if (!old_timing) {
+ old_timing = of_get_next_child(child, NULL);
+ if (!old_timing) {
+ of_node_put(child);
+ return -EINVAL;
+ }
+ }
+ of_node_put(child);
+
+ new_timing = of_get_child_by_name(new_panel, "panel-timing");
+ if (!new_timing)
+ return -EINVAL;
+
+ /* Copy all panel timing property to the new panel node */
+ for_each_property_of_node(old_timing, prop)
+ tilcdc_panel_update_prop(new_timing, prop->name,
+ prop->value, prop->length);
+
+ panel_info = of_get_child_by_name(old_panel, "panel-info");
+ if (!panel_info)
+ return -EINVAL;
+
+ /* Looked only for these two parameter as all the other are always
+ * set to default and not related to common DRM properties.
+ */
+ of_property_read_u32(panel_info, "invert-pxl-clk", &invert_pxl_clk);
+ of_property_read_u32(panel_info, "sync-edge", &sync_edge);
+
+ if (!invert_pxl_clk)
+ tilcdc_panel_update_prop(new_timing, "pixelclk-active",
+ &(int){1}, sizeof(int));
+
+ if (!sync_edge)
+ tilcdc_panel_update_prop(new_timing, "syncclk-active",
+ &(int){1}, sizeof(int));
+
+ of_node_put(panel_info);
+ of_node_put(old_timing);
+ of_node_put(new_timing);
+ return 0;
+}
+
+static const struct of_device_id tilcdc_panel_of_match[] __initconst = {
+ { .compatible = "ti,tilcdc,panel", },
+ {},
+};
+
+static const struct of_device_id tilcdc_of_match[] __initconst = {
+ { .compatible = "ti,am33xx-tilcdc", },
+ { .compatible = "ti,da850-tilcdc", },
+ {},
+};
+
+static int __init tilcdc_panel_legacy_init(void)
+{
+ struct device_node *panel, *lcdc, *new_panel;
+ void *dtbo_start;
+ u32 dtbo_size;
+ int ovcs_id;
+ int ret;
+
+ lcdc = of_find_matching_node(NULL, tilcdc_of_match);
+ panel = of_find_matching_node(NULL, tilcdc_panel_of_match);
+
+ if (!of_device_is_available(panel) ||
+ !of_device_is_available(lcdc)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ dtbo_start = __dtbo_tilcdc_panel_legacy_begin;
+ dtbo_size = __dtbo_tilcdc_panel_legacy_end -
+ __dtbo_tilcdc_panel_legacy_begin;
+
+ ret = of_overlay_fdt_apply(dtbo_start, dtbo_size, &ovcs_id, NULL);
+ if (ret)
+ goto out;
+
+ new_panel = of_find_node_by_name(NULL, "panel-dpi");
+ if (!new_panel) {
+ ret = -ENODEV;
+ goto overlay_remove;
+ }
+
+ ret = tilcdc_panel_copy_props(panel, new_panel);
+ if (ret)
+ goto overlay_remove;
+
+ /* Remove compatible property to avoid any driver compatible match */
+ of_remove_property(panel, of_find_property(panel, "compatible",
+ NULL));
+overlay_remove:
+ of_overlay_remove(&ovcs_id);
+out:
+ of_node_put(new_panel);
+ of_node_put(panel);
+ of_node_put(lcdc);
+ return ret;
+}
+
+subsys_initcall(tilcdc_panel_legacy_init);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.dtso b/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.dtso
new file mode 100644
index 0000000000000..77f3ec9391d55
--- /dev/null
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.dtso
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * DTS overlay for converting ti,tilcdc,panel binding to new binding.
+ *
+ * Copyright (C) Kory Maincent <kory.maincent@bootlin.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ panel-dpi {
+ compatible = "panel-dpi";
+ port {
+ panel_in: endpoint@0 {
+ remote-endpoint = <&lcd_0>;
+ };
+ };
+ panel-timing {
+ clock-frequency = <0>;
+ hactive = <0>;
+ vactive = <0>;
+ hfront-porch = <0>;
+ hback-porch = <0>;
+ hsync-len = <0>;
+ vfront-porch = <0>;
+ vback-porch = <0>;
+ vsync-len = <0>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <0>;
+ syncclk-active = <0>;
+ };
+ };
+};
+
+&lcdc {
+ port {
+ lcd_0: endpoint@0 {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 06/20] drm/tilcdc: Remove tilcdc panel driver
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (4 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 05/20] drm/tilcdc: Convert legacy panel binding via DT overlay at boot time Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 07/20] drm/tilcdc: Remove component framework support Kory Maincent (TI.com)
` (13 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The tilcdc panel subdriver is a legacy, non-standard driver that has been
replaced by the standard panel-dpi driver and panel-simple infrastructure.
With the device tree bindings removed and all in-tree users migrated to
use panel-dpi, this driver no longer has any associated device tree
bindings or users. The panel-dpi driver combined with DRM bus flags
provides equivalent functionality in a standard way that is compatible
with the broader DRM panel ecosystem.
This removal eliminates 400+ lines of redundant code and completes the
migration to standard panel handling.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/Makefile | 1 -
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 -
drivers/gpu/drm/tilcdc/tilcdc_panel.c | 408 ----------------------------------
drivers/gpu/drm/tilcdc/tilcdc_panel.h | 15 --
4 files changed, 427 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
index 6d6a08b5adf40..b78204a65ce29 100644
--- a/drivers/gpu/drm/tilcdc/Makefile
+++ b/drivers/gpu/drm/tilcdc/Makefile
@@ -6,7 +6,6 @@ endif
tilcdc-y := \
tilcdc_plane.o \
tilcdc_crtc.o \
- tilcdc_panel.o \
tilcdc_external.o \
tilcdc_drv.o
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 60230fa9cec95..28f09b9c1879b 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -28,7 +28,6 @@
#include "tilcdc_drv.h"
#include "tilcdc_external.h"
-#include "tilcdc_panel.h"
#include "tilcdc_regs.h"
enum {
@@ -636,7 +635,6 @@ static int __init tilcdc_drm_init(void)
return -ENODEV;
DBG("init");
- tilcdc_panel_init();
return platform_driver_register(&tilcdc_platform_driver);
}
@@ -644,7 +642,6 @@ static void __exit tilcdc_drm_fini(void)
{
DBG("fini");
platform_driver_unregister(&tilcdc_platform_driver);
- tilcdc_panel_fini();
}
module_init(tilcdc_drm_init);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
deleted file mode 100644
index 262f290d85d91..0000000000000
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ /dev/null
@@ -1,408 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2012 Texas Instruments
- * Author: Rob Clark <robdclark@gmail.com>
- */
-
-#include <linux/backlight.h>
-#include <linux/gpio/consumer.h>
-#include <linux/platform_device.h>
-
-#include <video/display_timing.h>
-#include <video/of_display_timing.h>
-#include <video/videomode.h>
-
-#include <drm/drm_atomic_state_helper.h>
-#include <drm/drm_connector.h>
-#include <drm/drm_modeset_helper_vtables.h>
-#include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
-
-#include "tilcdc_drv.h"
-#include "tilcdc_panel.h"
-
-struct panel_module {
- struct tilcdc_module base;
- struct tilcdc_panel_info *info;
- struct display_timings *timings;
- struct backlight_device *backlight;
- struct gpio_desc *enable_gpio;
-};
-#define to_panel_module(x) container_of(x, struct panel_module, base)
-
-
-/*
- * Encoder:
- */
-
-struct panel_encoder {
- struct drm_encoder base;
- struct panel_module *mod;
-};
-#define to_panel_encoder(x) container_of(x, struct panel_encoder, base)
-
-static void panel_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct panel_encoder *panel_encoder = to_panel_encoder(encoder);
- struct backlight_device *backlight = panel_encoder->mod->backlight;
- struct gpio_desc *gpio = panel_encoder->mod->enable_gpio;
-
- if (backlight) {
- backlight->props.power = mode == DRM_MODE_DPMS_ON ?
- BACKLIGHT_POWER_ON : BACKLIGHT_POWER_OFF;
- backlight_update_status(backlight);
- }
-
- if (gpio)
- gpiod_set_value_cansleep(gpio,
- mode == DRM_MODE_DPMS_ON ? 1 : 0);
-}
-
-static void panel_encoder_prepare(struct drm_encoder *encoder)
-{
- panel_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-static void panel_encoder_commit(struct drm_encoder *encoder)
-{
- panel_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static void panel_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- /* nothing needed */
-}
-
-static const struct drm_encoder_helper_funcs panel_encoder_helper_funcs = {
- .dpms = panel_encoder_dpms,
- .prepare = panel_encoder_prepare,
- .commit = panel_encoder_commit,
- .mode_set = panel_encoder_mode_set,
-};
-
-static struct drm_encoder *panel_encoder_create(struct drm_device *dev,
- struct panel_module *mod)
-{
- struct panel_encoder *panel_encoder;
- struct drm_encoder *encoder;
- int ret;
-
- panel_encoder = devm_kzalloc(dev->dev, sizeof(*panel_encoder),
- GFP_KERNEL);
- if (!panel_encoder)
- return NULL;
-
- panel_encoder->mod = mod;
-
- encoder = &panel_encoder->base;
- encoder->possible_crtcs = 1;
-
- ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
- if (ret < 0)
- goto fail;
-
- drm_encoder_helper_add(encoder, &panel_encoder_helper_funcs);
-
- return encoder;
-
-fail:
- drm_encoder_cleanup(encoder);
- return NULL;
-}
-
-/*
- * Connector:
- */
-
-struct panel_connector {
- struct drm_connector base;
-
- struct drm_encoder *encoder; /* our connected encoder */
- struct panel_module *mod;
-};
-#define to_panel_connector(x) container_of(x, struct panel_connector, base)
-
-
-static void panel_connector_destroy(struct drm_connector *connector)
-{
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
-}
-
-static int panel_connector_get_modes(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- struct panel_connector *panel_connector = to_panel_connector(connector);
- struct display_timings *timings = panel_connector->mod->timings;
- int i;
-
- for (i = 0; i < timings->num_timings; i++) {
- struct drm_display_mode *mode;
- struct videomode vm;
-
- if (videomode_from_timings(timings, &vm, i))
- break;
-
- mode = drm_mode_create(dev);
- if (!mode)
- break;
-
- drm_display_mode_from_videomode(&vm, mode);
-
- mode->type = DRM_MODE_TYPE_DRIVER;
-
- if (timings->native_mode == i)
- mode->type |= DRM_MODE_TYPE_PREFERRED;
-
- drm_mode_set_name(mode);
- drm_mode_probed_add(connector, mode);
- }
-
- return i;
-}
-
-static struct drm_encoder *panel_connector_best_encoder(
- struct drm_connector *connector)
-{
- struct panel_connector *panel_connector = to_panel_connector(connector);
- return panel_connector->encoder;
-}
-
-static const struct drm_connector_funcs panel_connector_funcs = {
- .destroy = panel_connector_destroy,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .reset = drm_atomic_helper_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static const struct drm_connector_helper_funcs panel_connector_helper_funcs = {
- .get_modes = panel_connector_get_modes,
- .best_encoder = panel_connector_best_encoder,
-};
-
-static struct drm_connector *panel_connector_create(struct drm_device *dev,
- struct panel_module *mod, struct drm_encoder *encoder)
-{
- struct panel_connector *panel_connector;
- struct drm_connector *connector;
- int ret;
-
- panel_connector = devm_kzalloc(dev->dev, sizeof(*panel_connector),
- GFP_KERNEL);
- if (!panel_connector)
- return NULL;
-
- panel_connector->encoder = encoder;
- panel_connector->mod = mod;
-
- connector = &panel_connector->base;
-
- drm_connector_init(dev, connector, &panel_connector_funcs,
- DRM_MODE_CONNECTOR_LVDS);
- drm_connector_helper_add(connector, &panel_connector_helper_funcs);
-
- connector->interlace_allowed = 0;
- connector->doublescan_allowed = 0;
-
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret)
- goto fail;
-
- return connector;
-
-fail:
- panel_connector_destroy(connector);
- return NULL;
-}
-
-/*
- * Module:
- */
-
-static int panel_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
-{
- struct panel_module *panel_mod = to_panel_module(mod);
- struct tilcdc_drm_private *priv = dev->dev_private;
- struct drm_encoder *encoder;
- struct drm_connector *connector;
-
- encoder = panel_encoder_create(dev, panel_mod);
- if (!encoder)
- return -ENOMEM;
-
- connector = panel_connector_create(dev, panel_mod, encoder);
- if (!connector)
- return -ENOMEM;
-
- priv->encoders[priv->num_encoders++] = encoder;
- priv->connectors[priv->num_connectors++] = connector;
-
- tilcdc_crtc_set_panel_info(priv->crtc,
- to_panel_encoder(encoder)->mod->info);
-
- return 0;
-}
-
-static const struct tilcdc_module_ops panel_module_ops = {
- .modeset_init = panel_modeset_init,
-};
-
-/*
- * Device:
- */
-
-/* maybe move this somewhere common if it is needed by other outputs? */
-static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np)
-{
- struct device_node *info_np;
- struct tilcdc_panel_info *info;
- int ret = 0;
-
- if (!np) {
- pr_err("%s: no devicenode given\n", __func__);
- return NULL;
- }
-
- info_np = of_get_child_by_name(np, "panel-info");
- if (!info_np) {
- pr_err("%s: could not find panel-info node\n", __func__);
- return NULL;
- }
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- goto put_node;
-
- ret |= of_property_read_u32(info_np, "ac-bias", &info->ac_bias);
- ret |= of_property_read_u32(info_np, "ac-bias-intrpt", &info->ac_bias_intrpt);
- ret |= of_property_read_u32(info_np, "dma-burst-sz", &info->dma_burst_sz);
- ret |= of_property_read_u32(info_np, "bpp", &info->bpp);
- ret |= of_property_read_u32(info_np, "fdd", &info->fdd);
- ret |= of_property_read_u32(info_np, "sync-edge", &info->sync_edge);
- ret |= of_property_read_u32(info_np, "sync-ctrl", &info->sync_ctrl);
- ret |= of_property_read_u32(info_np, "raster-order", &info->raster_order);
- ret |= of_property_read_u32(info_np, "fifo-th", &info->fifo_th);
-
- /* optional: */
- info->tft_alt_mode = of_property_read_bool(info_np, "tft-alt-mode");
- info->invert_pxl_clk = of_property_read_bool(info_np, "invert-pxl-clk");
-
- if (ret) {
- pr_err("%s: error reading panel-info properties\n", __func__);
- kfree(info);
- info = NULL;
- }
-
-put_node:
- of_node_put(info_np);
- return info;
-}
-
-static int panel_probe(struct platform_device *pdev)
-{
- struct device_node *node = pdev->dev.of_node;
- struct backlight_device *backlight;
- struct panel_module *panel_mod;
- struct tilcdc_module *mod;
- int ret;
-
- /* bail out early if no DT data: */
- if (!node) {
- dev_err(&pdev->dev, "device-tree data is missing\n");
- return -ENXIO;
- }
-
- panel_mod = devm_kzalloc(&pdev->dev, sizeof(*panel_mod), GFP_KERNEL);
- if (!panel_mod)
- return -ENOMEM;
-
- backlight = devm_of_find_backlight(&pdev->dev);
- if (IS_ERR(backlight))
- return PTR_ERR(backlight);
- panel_mod->backlight = backlight;
-
- panel_mod->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
- GPIOD_OUT_LOW);
- if (IS_ERR(panel_mod->enable_gpio)) {
- ret = PTR_ERR(panel_mod->enable_gpio);
- dev_err(&pdev->dev, "failed to request enable GPIO\n");
- goto fail_backlight;
- }
-
- if (panel_mod->enable_gpio)
- dev_info(&pdev->dev, "found enable GPIO\n");
-
- mod = &panel_mod->base;
- pdev->dev.platform_data = mod;
-
- tilcdc_module_init(mod, "panel", &panel_module_ops);
-
- panel_mod->timings = of_get_display_timings(node);
- if (!panel_mod->timings) {
- dev_err(&pdev->dev, "could not get panel timings\n");
- ret = -EINVAL;
- goto fail_free;
- }
-
- panel_mod->info = of_get_panel_info(node);
- if (!panel_mod->info) {
- dev_err(&pdev->dev, "could not get panel info\n");
- ret = -EINVAL;
- goto fail_timings;
- }
-
- return 0;
-
-fail_timings:
- display_timings_release(panel_mod->timings);
-
-fail_free:
- tilcdc_module_cleanup(mod);
-
-fail_backlight:
- if (panel_mod->backlight)
- put_device(&panel_mod->backlight->dev);
- return ret;
-}
-
-static void panel_remove(struct platform_device *pdev)
-{
- struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
- struct panel_module *panel_mod = to_panel_module(mod);
- struct backlight_device *backlight = panel_mod->backlight;
-
- if (backlight)
- put_device(&backlight->dev);
-
- display_timings_release(panel_mod->timings);
-
- tilcdc_module_cleanup(mod);
- kfree(panel_mod->info);
-}
-
-static const struct of_device_id panel_of_match[] = {
- { .compatible = "ti,tilcdc,panel", },
- { },
-};
-
-static struct platform_driver panel_driver = {
- .probe = panel_probe,
- .remove = panel_remove,
- .driver = {
- .name = "tilcdc-panel",
- .of_match_table = panel_of_match,
- },
-};
-
-int __init tilcdc_panel_init(void)
-{
- return platform_driver_register(&panel_driver);
-}
-
-void __exit tilcdc_panel_fini(void)
-{
- platform_driver_unregister(&panel_driver);
-}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.h b/drivers/gpu/drm/tilcdc/tilcdc_panel.h
deleted file mode 100644
index 65d735d773a48..0000000000000
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012 Texas Instruments
- * Author: Rob Clark <robdclark@gmail.com>
- */
-
-#ifndef __TILCDC_PANEL_H__
-#define __TILCDC_PANEL_H__
-
-/* sub-module for generic lcd panel output */
-
-int tilcdc_panel_init(void);
-void tilcdc_panel_fini(void);
-
-#endif /* __TILCDC_PANEL_H__ */
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 07/20] drm/tilcdc: Remove component framework support
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (5 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 06/20] drm/tilcdc: Remove tilcdc panel driver Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 08/20] drm/tilcdc: Remove tilcdc_panel_info structure Kory Maincent (TI.com)
` (12 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The tilcdc driver previously used the component framework to bind
external encoder subdrivers (specifically the TDA998x HDMI encoder).
With the removal of these subdrivers in previous commits, the component
framework is no longer needed.
This commit removes all component framework infrastructure including:
- Component master operations and bind/unbind callbacks
- The is_componentized flag and conditional code paths
- tilcdc_get_external_components() and tilcdc_add_component_encoder()
- TDA998x-specific panel configuration
The driver now uses a simplified initialization path that directly
attaches external devices via the DRM bridge API, eliminating the
complexity of dual code paths for componentized vs non-componentized
configurations.
This cleanup removes approximately 140 lines of code and makes the
driver initialization flow more straightforward.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 10 ----
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 80 ++++----------------------------
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 -
drivers/gpu/drm/tilcdc/tilcdc_external.c | 65 --------------------------
drivers/gpu/drm/tilcdc/tilcdc_external.h | 3 --
5 files changed, 9 insertions(+), 150 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 2309a9a0c925d..252e5adaeb6e2 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -1021,16 +1021,6 @@ int tilcdc_crtc_create(struct drm_device *dev)
drm_crtc_helper_add(crtc, &tilcdc_crtc_helper_funcs);
- if (priv->is_componentized) {
- crtc->port = of_graph_get_port_by_id(dev->dev->of_node, 0);
- if (!crtc->port) { /* This should never happen */
- dev_err(dev->dev, "Port node not found in %pOF\n",
- dev->dev->of_node);
- ret = -EINVAL;
- goto fail;
- }
- }
-
priv->crtc = crtc;
return 0;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 28f09b9c1879b..9b3a0435a8d2d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -6,7 +6,6 @@
/* LCDC DRM driver, based on da8xx-fb */
-#include <linux/component.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
@@ -229,9 +228,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
platform_set_drvdata(pdev, ddev);
drm_mode_config_init(ddev);
- priv->is_componentized =
- tilcdc_get_external_components(dev, NULL) > 0;
-
priv->wq = alloc_ordered_workqueue("tilcdc", 0);
if (!priv->wq) {
ret = -ENOMEM;
@@ -348,42 +344,32 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
}
#endif
- if (priv->is_componentized) {
- ret = component_bind_all(dev, ddev);
- if (ret < 0)
- goto unregister_cpufreq_notif;
-
- ret = tilcdc_add_component_encoder(ddev);
- if (ret < 0)
- goto unbind_component;
- } else {
- ret = tilcdc_attach_external_device(ddev);
- if (ret)
- goto unregister_cpufreq_notif;
- }
+ ret = tilcdc_attach_external_device(ddev);
+ if (ret)
+ goto unregister_cpufreq_notif;
if (!priv->external_connector &&
((priv->num_encoders == 0) || (priv->num_connectors == 0))) {
dev_err(dev, "no encoders/connectors found\n");
ret = -EPROBE_DEFER;
- goto unbind_component;
+ goto unregister_cpufreq_notif;
}
ret = drm_vblank_init(ddev, 1);
if (ret < 0) {
dev_err(dev, "failed to initialize vblank\n");
- goto unbind_component;
+ goto unregister_cpufreq_notif;
}
ret = platform_get_irq(pdev, 0);
if (ret < 0)
- goto unbind_component;
+ goto unregister_cpufreq_notif;
priv->irq = ret;
ret = tilcdc_irq_install(ddev, priv->irq);
if (ret < 0) {
dev_err(dev, "failed to install IRQ handler\n");
- goto unbind_component;
+ goto unregister_cpufreq_notif;
}
drm_mode_config_reset(ddev);
@@ -401,9 +387,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
stop_poll:
drm_kms_helper_poll_fini(ddev);
tilcdc_irq_uninstall(ddev);
-unbind_component:
- if (priv->is_componentized)
- component_unbind_all(dev, ddev);
unregister_cpufreq_notif:
#ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier(&priv->freq_transition,
@@ -552,65 +535,20 @@ static int tilcdc_pm_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(tilcdc_pm_ops,
tilcdc_pm_suspend, tilcdc_pm_resume);
-/*
- * Platform driver:
- */
-static int tilcdc_bind(struct device *dev)
-{
- return tilcdc_init(&tilcdc_driver, dev);
-}
-
-static void tilcdc_unbind(struct device *dev)
-{
- struct drm_device *ddev = dev_get_drvdata(dev);
-
- /* Check if a subcomponent has already triggered the unloading. */
- if (!ddev->dev_private)
- return;
-
- tilcdc_fini(ddev);
- dev_set_drvdata(dev, NULL);
-}
-
-static const struct component_master_ops tilcdc_comp_ops = {
- .bind = tilcdc_bind,
- .unbind = tilcdc_unbind,
-};
-
static int tilcdc_pdev_probe(struct platform_device *pdev)
{
- struct component_match *match = NULL;
- int ret;
-
/* bail out early if no DT data: */
if (!pdev->dev.of_node) {
dev_err(&pdev->dev, "device-tree data is missing\n");
return -ENXIO;
}
- ret = tilcdc_get_external_components(&pdev->dev, &match);
- if (ret < 0)
- return ret;
- else if (ret == 0)
- return tilcdc_init(&tilcdc_driver, &pdev->dev);
- else
- return component_master_add_with_match(&pdev->dev,
- &tilcdc_comp_ops,
- match);
+ return tilcdc_init(&tilcdc_driver, &pdev->dev);
}
static void tilcdc_pdev_remove(struct platform_device *pdev)
{
- int ret;
-
- ret = tilcdc_get_external_components(&pdev->dev, NULL);
- if (ret < 0)
- dev_err(&pdev->dev, "tilcdc_get_external_components() failed (%pe)\n",
- ERR_PTR(ret));
- else if (ret == 0)
- tilcdc_fini(platform_get_drvdata(pdev));
- else
- component_master_del(&pdev->dev, &tilcdc_comp_ops);
+ tilcdc_fini(platform_get_drvdata(pdev));
}
static void tilcdc_pdev_shutdown(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 79078b4ae7393..c23b593dc61f6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -84,7 +84,6 @@ struct tilcdc_drm_private {
struct drm_encoder *external_encoder;
struct drm_connector *external_connector;
- bool is_componentized;
bool irq_enabled;
};
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index da755a411d9ff..2970c41d9c3eb 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -4,7 +4,6 @@
* Author: Jyri Sarha <jsarha@ti.com>
*/
-#include <linux/component.h>
#include <linux/of_graph.h>
#include <drm/drm_atomic_helper.h>
@@ -15,19 +14,6 @@
#include "tilcdc_drv.h"
#include "tilcdc_external.h"
-static const struct tilcdc_panel_info panel_info_tda998x = {
- .ac_bias = 255,
- .ac_bias_intrpt = 0,
- .dma_burst_sz = 16,
- .bpp = 16,
- .fdd = 0x80,
- .tft_alt_mode = 0,
- .invert_pxl_clk = 1,
- .sync_edge = 1,
- .sync_ctrl = 1,
- .raster_order = 0,
-};
-
static const struct tilcdc_panel_info panel_info_default = {
.ac_bias = 255,
.ac_bias_intrpt = 0,
@@ -57,34 +43,6 @@ struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev,
return NULL;
}
-int tilcdc_add_component_encoder(struct drm_device *ddev)
-{
- struct tilcdc_drm_private *priv = ddev->dev_private;
- struct drm_encoder *encoder = NULL, *iter;
-
- list_for_each_entry(iter, &ddev->mode_config.encoder_list, head)
- if (iter->possible_crtcs & (1 << priv->crtc->index)) {
- encoder = iter;
- break;
- }
-
- if (!encoder) {
- dev_err(ddev->dev, "%s: No suitable encoder found\n", __func__);
- return -ENODEV;
- }
-
- priv->external_connector =
- tilcdc_encoder_find_connector(ddev, encoder);
-
- if (!priv->external_connector)
- return -ENODEV;
-
- /* Only tda998x is supported at the moment. */
- tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_tda998x);
-
- return 0;
-}
-
static
int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
{
@@ -153,26 +111,3 @@ int tilcdc_attach_external_device(struct drm_device *ddev)
drm_encoder_cleanup(priv->external_encoder);
return ret;
}
-
-static int dev_match_of(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
-int tilcdc_get_external_components(struct device *dev,
- struct component_match **match)
-{
- struct device_node *node;
-
- node = of_graph_get_remote_node(dev->of_node, 0, 0);
-
- if (!of_device_is_compatible(node, "nxp,tda998x")) {
- of_node_put(node);
- return 0;
- }
-
- if (match)
- drm_of_component_match_add(dev, match, dev_match_of, node);
- of_node_put(node);
- return 1;
-}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.h b/drivers/gpu/drm/tilcdc/tilcdc_external.h
index fb4476694cd89..285a132f3035d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.h
@@ -7,8 +7,5 @@
#ifndef __TILCDC_EXTERNAL_H__
#define __TILCDC_EXTERNAL_H__
-int tilcdc_add_component_encoder(struct drm_device *dev);
-int tilcdc_get_external_components(struct device *dev,
- struct component_match **match);
int tilcdc_attach_external_device(struct drm_device *ddev);
#endif /* __TILCDC_SLAVE_H__ */
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 08/20] drm/tilcdc: Remove tilcdc_panel_info structure
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (6 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 07/20] drm/tilcdc: Remove component framework support Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 09/20] drm/tilcdc: Remove redundant #endif/#ifdef in debugfs code Kory Maincent (TI.com)
` (11 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Remove the tilcdc_panel_info structure and its associated helper
function as the structure contains only redundant or unused parameters.
Most panel configuration parameters in tilcdc_panel_info are either:
- Already represented by existing DRM mode flags (invert_pxl_clk,
sync_edge via DRM_BUS_FLAG_*), or
- Set to identical values across all instances (panel_info_default),
making them effectively constants
The removed fifo_th field is already handled by priv->fifo_th when set.
Other removed fields (tft_alt_mode, raster_order) were always set to 0
in the only instance (panel_info_default) and thus had no effect.
This simplifies the code by eliminating unnecessary abstraction while
preserving all functional behavior.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 28 +++------------------
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 42 --------------------------------
drivers/gpu/drm/tilcdc/tilcdc_external.c | 14 -----------
3 files changed, 3 insertions(+), 81 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 252e5adaeb6e2..5b8aba0765f9b 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -31,7 +31,6 @@ struct tilcdc_crtc {
struct drm_crtc base;
struct drm_plane primary;
- const struct tilcdc_panel_info *info;
struct drm_pending_vblank_event *event;
struct mutex enable_lock;
bool enabled;
@@ -272,14 +271,10 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct tilcdc_drm_private *priv = dev->dev_private;
- const struct tilcdc_panel_info *info = tilcdc_crtc->info;
uint32_t reg, hbp, hfp, hsw, vbp, vfp, vsw;
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
struct drm_framebuffer *fb = crtc->primary->state->fb;
- if (WARN_ON(!info))
- return;
-
if (WARN_ON(!fb))
return;
@@ -287,12 +282,11 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
reg = tilcdc_read(dev, LCDC_DMA_CTRL_REG) & ~0x00000770;
/* Use 16 bit DMA burst size by default */
reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_16);
+
if (priv->fifo_th) {
int fifo_th_val = ilog2(priv->fifo_th) - 3;
reg |= (fifo_th_val << 8);
- } else {
- reg |= (info->fifo_th << 8);
}
tilcdc_write(dev, LCDC_DMA_CTRL_REG, reg);
@@ -360,8 +354,6 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
LCDC_V2_TFT_24BPP_MODE | LCDC_V2_TFT_24BPP_UNPACK |
0x000ff000 /* Palette Loading Delay bits */);
reg |= LCDC_TFT_MODE; /* no monochrome/passive support */
- if (info->tft_alt_mode)
- reg |= LCDC_TFT_ALT_ENABLE;
if (priv->rev == 2) {
switch (fb->format->format) {
case DRM_FORMAT_BGR565:
@@ -384,15 +376,13 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
reg |= 128 << 12;
tilcdc_write(dev, LCDC_RASTER_CTRL_REG, reg);
- if (info->invert_pxl_clk ||
- mode->flags == DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
+ if (mode->flags == DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK);
else
tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK);
tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
- if (info->sync_edge ||
- mode->flags == DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE)
+ if (mode->flags == DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE)
tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
else
tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
@@ -407,11 +397,6 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
else
tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_VSYNC);
- if (info->raster_order)
- tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER);
- else
- tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER);
-
tilcdc_crtc_set_clk(crtc);
tilcdc_crtc_load_palette(crtc);
@@ -838,13 +823,6 @@ static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
.atomic_flush = tilcdc_crtc_atomic_flush,
};
-void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
- const struct tilcdc_panel_info *info)
-{
- struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
- tilcdc_crtc->info = info;
-}
-
void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index c23b593dc61f6..181b9d7a515b6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -114,53 +114,11 @@ void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
const struct tilcdc_module_ops *funcs);
void tilcdc_module_cleanup(struct tilcdc_module *mod);
-/* Panel config that needs to be set in the crtc, but is not coming from
- * the mode timings. The display module is expected to call
- * tilcdc_crtc_set_panel_info() to set this during modeset.
- */
-struct tilcdc_panel_info {
-
- /* AC Bias Pin Frequency */
- uint32_t ac_bias;
-
- /* AC Bias Pin Transitions per Interrupt */
- uint32_t ac_bias_intrpt;
-
- /* DMA burst size */
- uint32_t dma_burst_sz;
-
- /* Bits per pixel */
- uint32_t bpp;
-
- /* FIFO DMA Request Delay */
- uint32_t fdd;
-
- /* TFT Alternative Signal Mapping (Only for active) */
- bool tft_alt_mode;
-
- /* Invert pixel clock */
- bool invert_pxl_clk;
-
- /* Horizontal and Vertical Sync Edge: 0=rising 1=falling */
- uint32_t sync_edge;
-
- /* Horizontal and Vertical Sync: Control: 0=ignore */
- uint32_t sync_ctrl;
-
- /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */
- uint32_t raster_order;
-
- /* DMA FIFO threshold */
- uint32_t fifo_th;
-};
-
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
int tilcdc_crtc_create(struct drm_device *dev);
irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc);
void tilcdc_crtc_update_clk(struct drm_crtc *crtc);
-void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
- const struct tilcdc_panel_info *info);
void tilcdc_crtc_shutdown(struct drm_crtc *crtc);
void tilcdc_crtc_destroy(struct drm_crtc *crtc);
int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 2970c41d9c3eb..81c90c2754c6c 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -14,18 +14,6 @@
#include "tilcdc_drv.h"
#include "tilcdc_external.h"
-static const struct tilcdc_panel_info panel_info_default = {
- .ac_bias = 255,
- .ac_bias_intrpt = 0,
- .dma_burst_sz = 16,
- .bpp = 16,
- .fdd = 0x80,
- .tft_alt_mode = 0,
- .sync_edge = 0,
- .sync_ctrl = 1,
- .raster_order = 0,
-};
-
static
struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev,
struct drm_encoder *encoder)
@@ -55,8 +43,6 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
if (ret)
return ret;
- tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_default);
-
priv->external_connector =
tilcdc_encoder_find_connector(ddev, priv->external_encoder);
if (!priv->external_connector)
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 09/20] drm/tilcdc: Remove redundant #endif/#ifdef in debugfs code
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (7 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 08/20] drm/tilcdc: Remove tilcdc_panel_info structure Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 10/20] drm/tilcdc: Remove unused encoder and connector tracking arrays Kory Maincent (TI.com)
` (10 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Remove the unnecessary #endif/#ifdef CONFIG_DEBUG_FS pair that splits
the debugfs code section. This keeps all debugfs-related code within a
single preprocessor conditional block, improving code readability.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 9b3a0435a8d2d..d2aae731b72c6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -438,9 +438,6 @@ static const struct {
#undef REG
};
-#endif
-
-#ifdef CONFIG_DEBUG_FS
static int tilcdc_regs_show(struct seq_file *m, void *arg)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 10/20] drm/tilcdc: Remove unused encoder and connector tracking arrays
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (8 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 09/20] drm/tilcdc: Remove redundant #endif/#ifdef in debugfs code Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 11/20] drm/tilcdc: Rename external_encoder and external_connector to encoder and connector Kory Maincent (TI.com)
` (9 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The num_encoders/encoders and num_connectors/connectors arrays in
tilcdc_drm_private are never populated or used by the driver.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 +--
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 6 ------
2 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index d2aae731b72c6..a753cc47a59d7 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -348,8 +348,7 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
if (ret)
goto unregister_cpufreq_notif;
- if (!priv->external_connector &&
- ((priv->num_encoders == 0) || (priv->num_connectors == 0))) {
+ if (!priv->external_connector) {
dev_err(dev, "no encoders/connectors found\n");
ret = -EPROBE_DEFER;
goto unregister_cpufreq_notif;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 181b9d7a515b6..717529a331009 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -75,12 +75,6 @@ struct tilcdc_drm_private {
struct drm_crtc *crtc;
- unsigned int num_encoders;
- struct drm_encoder *encoders[8];
-
- unsigned int num_connectors;
- struct drm_connector *connectors[8];
-
struct drm_encoder *external_encoder;
struct drm_connector *external_connector;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 11/20] drm/tilcdc: Rename external_encoder and external_connector to encoder and connector
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (9 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 10/20] drm/tilcdc: Remove unused encoder and connector tracking arrays Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 12/20] drm/tilcdc: Rename tilcdc_external to tilcdc_encoder Kory Maincent (TI.com)
` (8 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Remove the "external_" prefix from encoder and connector members in the
tilcdc driver. These are internal driver structures and the "external"
naming is misleading. The simpler names better reflect that these are
the primary encoder and connector managed by this driver.
Also rename tilcdc_attach_external_device() to tilcdc_encoder_create()
for consistency and to better describe the function's purpose.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 4 ++--
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 4 ++--
drivers/gpu/drm/tilcdc/tilcdc_external.c | 24 ++++++++++++------------
drivers/gpu/drm/tilcdc/tilcdc_external.h | 2 +-
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index a753cc47a59d7..bf6cd763ecd0f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -344,11 +344,11 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
}
#endif
- ret = tilcdc_attach_external_device(ddev);
+ ret = tilcdc_encoder_create(ddev);
if (ret)
goto unregister_cpufreq_notif;
- if (!priv->external_connector) {
+ if (!priv->connector) {
dev_err(dev, "no encoders/connectors found\n");
ret = -EPROBE_DEFER;
goto unregister_cpufreq_notif;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 717529a331009..dafb00908d1d4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -75,8 +75,8 @@ struct tilcdc_drm_private {
struct drm_crtc *crtc;
- struct drm_encoder *external_encoder;
- struct drm_connector *external_connector;
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
bool irq_enabled;
};
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 81c90c2754c6c..0c18d05dc7101 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -37,21 +37,21 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
struct tilcdc_drm_private *priv = ddev->dev_private;
int ret;
- priv->external_encoder->possible_crtcs = BIT(0);
+ priv->encoder->possible_crtcs = BIT(0);
- ret = drm_bridge_attach(priv->external_encoder, bridge, NULL, 0);
+ ret = drm_bridge_attach(priv->encoder, bridge, NULL, 0);
if (ret)
return ret;
- priv->external_connector =
- tilcdc_encoder_find_connector(ddev, priv->external_encoder);
- if (!priv->external_connector)
+ priv->connector =
+ tilcdc_encoder_find_connector(ddev, priv->encoder);
+ if (!priv->connector)
return -ENODEV;
return 0;
}
-int tilcdc_attach_external_device(struct drm_device *ddev)
+int tilcdc_encoder_create(struct drm_device *ddev)
{
struct tilcdc_drm_private *priv = ddev->dev_private;
struct drm_bridge *bridge;
@@ -65,13 +65,13 @@ int tilcdc_attach_external_device(struct drm_device *ddev)
else if (ret)
return ret;
- priv->external_encoder = devm_kzalloc(ddev->dev,
- sizeof(*priv->external_encoder),
- GFP_KERNEL);
- if (!priv->external_encoder)
+ priv->encoder = devm_kzalloc(ddev->dev,
+ sizeof(*priv->encoder),
+ GFP_KERNEL);
+ if (!priv->encoder)
return -ENOMEM;
- ret = drm_simple_encoder_init(ddev, priv->external_encoder,
+ ret = drm_simple_encoder_init(ddev, priv->encoder,
DRM_MODE_ENCODER_NONE);
if (ret) {
dev_err(ddev->dev, "drm_encoder_init() failed %d\n", ret);
@@ -94,6 +94,6 @@ int tilcdc_attach_external_device(struct drm_device *ddev)
return 0;
err_encoder_cleanup:
- drm_encoder_cleanup(priv->external_encoder);
+ drm_encoder_cleanup(priv->encoder);
return ret;
}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.h b/drivers/gpu/drm/tilcdc/tilcdc_external.h
index 285a132f3035d..c8f87f59024e6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.h
@@ -7,5 +7,5 @@
#ifndef __TILCDC_EXTERNAL_H__
#define __TILCDC_EXTERNAL_H__
-int tilcdc_attach_external_device(struct drm_device *ddev);
+int tilcdc_encoder_create(struct drm_device *ddev);
#endif /* __TILCDC_SLAVE_H__ */
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 12/20] drm/tilcdc: Rename tilcdc_external to tilcdc_encoder
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (10 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 11/20] drm/tilcdc: Rename external_encoder and external_connector to encoder and connector Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 13/20] drm/tilcdc: Remove the useless module list support Kory Maincent (TI.com)
` (7 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The tilcdc_external module describes the encoder part of the tilcdc
driver. Rename it to tilcdc_encoder for better clarity and to make
the naming more consistent with DRM subsystem conventions, where
encoder-related files typically use "encoder" in their names.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/Makefile | 2 +-
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +-
drivers/gpu/drm/tilcdc/{tilcdc_external.c => tilcdc_encoder.c} | 2 +-
drivers/gpu/drm/tilcdc/{tilcdc_external.h => tilcdc_encoder.h} | 0
4 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
index b78204a65ce29..c6b484dad711a 100644
--- a/drivers/gpu/drm/tilcdc/Makefile
+++ b/drivers/gpu/drm/tilcdc/Makefile
@@ -6,7 +6,7 @@ endif
tilcdc-y := \
tilcdc_plane.o \
tilcdc_crtc.o \
- tilcdc_external.o \
+ tilcdc_encoder.o \
tilcdc_drv.o
obj-$(CONFIG_DRM_TILCDC) += tilcdc.o
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index bf6cd763ecd0f..6a08f50762af9 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -26,7 +26,7 @@
#include "tilcdc_drv.h"
-#include "tilcdc_external.h"
+#include "tilcdc_encoder.h"
#include "tilcdc_regs.h"
enum {
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
similarity index 98%
rename from drivers/gpu/drm/tilcdc/tilcdc_external.c
rename to drivers/gpu/drm/tilcdc/tilcdc_encoder.c
index 0c18d05dc7101..bca91226351dd 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
@@ -12,7 +12,7 @@
#include <drm/drm_simple_kms_helper.h>
#include "tilcdc_drv.h"
-#include "tilcdc_external.h"
+#include "tilcdc_encoder.h"
static
struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.h b/drivers/gpu/drm/tilcdc/tilcdc_encoder.h
similarity index 100%
rename from drivers/gpu/drm/tilcdc/tilcdc_external.h
rename to drivers/gpu/drm/tilcdc/tilcdc_encoder.h
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 13/20] drm/tilcdc: Remove the useless module list support
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (11 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 12/20] drm/tilcdc: Rename tilcdc_external to tilcdc_encoder Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 14/20] drm/tilcdc: Modernize driver initialization and cleanup paths Kory Maincent (TI.com)
` (6 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The tilcdc driver previously supported a sub-module system where
external display drivers (panels, encoders) could register themselves
through tilcdc_module_init() and be automatically initialized through
a module list. This infrastructure became unused after the component
framework support and panel driver was removed.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 48 +------------------------------------
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 27 ---------------------
2 files changed, 1 insertion(+), 74 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 6a08f50762af9..4630e56c3f028 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -7,7 +7,6 @@
/* LCDC DRM driver, based on da8xx-fb */
#include <linux/mod_devicetable.h>
-#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -34,8 +33,6 @@ enum {
DA850_TILCDC,
};
-static LIST_HEAD(module_list);
-
static const u32 tilcdc_rev1_formats[] = { DRM_FORMAT_RGB565 };
static const u32 tilcdc_straight_formats[] = { DRM_FORMAT_RGB565,
@@ -50,20 +47,6 @@ static const u32 tilcdc_legacy_formats[] = { DRM_FORMAT_RGB565,
DRM_FORMAT_RGB888,
DRM_FORMAT_XRGB8888 };
-void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
- const struct tilcdc_module_ops *funcs)
-{
- mod->name = name;
- mod->funcs = funcs;
- INIT_LIST_HEAD(&mod->list);
- list_add(&mod->list, &module_list);
-}
-
-void tilcdc_module_cleanup(struct tilcdc_module *mod)
-{
- list_del(&mod->list);
-}
-
static int tilcdc_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state)
{
@@ -97,12 +80,6 @@ static const struct drm_mode_config_funcs mode_config_funcs = {
static void modeset_init(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
- struct tilcdc_module *mod;
-
- list_for_each_entry(mod, &module_list, list) {
- DBG("loading module: %s", mod->name);
- mod->funcs->modeset_init(mod, dev);
- }
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
@@ -474,15 +451,9 @@ static struct drm_info_list tilcdc_debugfs_list[] = {
static void tilcdc_debugfs_init(struct drm_minor *minor)
{
- struct tilcdc_module *mod;
-
drm_debugfs_create_files(tilcdc_debugfs_list,
ARRAY_SIZE(tilcdc_debugfs_list),
minor->debugfs_root, minor);
-
- list_for_each_entry(mod, &module_list, list)
- if (mod->funcs->debugfs_init)
- mod->funcs->debugfs_init(mod, minor);
}
#endif
@@ -562,24 +533,7 @@ static struct platform_driver tilcdc_platform_driver = {
.of_match_table = tilcdc_of_match,
},
};
-
-static int __init tilcdc_drm_init(void)
-{
- if (drm_firmware_drivers_only())
- return -ENODEV;
-
- DBG("init");
- return platform_driver_register(&tilcdc_platform_driver);
-}
-
-static void __exit tilcdc_drm_fini(void)
-{
- DBG("fini");
- platform_driver_unregister(&tilcdc_platform_driver);
-}
-
-module_init(tilcdc_drm_init);
-module_exit(tilcdc_drm_fini);
+module_platform_driver(tilcdc_platform_driver);
MODULE_AUTHOR("Rob Clark <robdclark@gmail.com");
MODULE_DESCRIPTION("TI LCD Controller DRM Driver");
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index dafb00908d1d4..60e85e29b1063 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -81,33 +81,6 @@ struct tilcdc_drm_private {
bool irq_enabled;
};
-/* Sub-module for display. Since we don't know at compile time what panels
- * or display adapter(s) might be present (for ex, off chip dvi/tfp410,
- * hdmi encoder, various lcd panels), the connector/encoder(s) are split into
- * separate drivers. If they are probed and found to be present, they
- * register themselves with tilcdc_register_module().
- */
-struct tilcdc_module;
-
-struct tilcdc_module_ops {
- /* create appropriate encoders/connectors: */
- int (*modeset_init)(struct tilcdc_module *mod, struct drm_device *dev);
-#ifdef CONFIG_DEBUG_FS
- /* create debugfs nodes (can be NULL): */
- int (*debugfs_init)(struct tilcdc_module *mod, struct drm_minor *minor);
-#endif
-};
-
-struct tilcdc_module {
- const char *name;
- struct list_head list;
- const struct tilcdc_module_ops *funcs;
-};
-
-void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
- const struct tilcdc_module_ops *funcs);
-void tilcdc_module_cleanup(struct tilcdc_module *mod);
-
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
int tilcdc_crtc_create(struct drm_device *dev);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 14/20] drm/tilcdc: Modernize driver initialization and cleanup paths
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (12 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 13/20] drm/tilcdc: Remove the useless module list support Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:38 ` [PATCH v2 15/20] drm/tilcdc: Remove the use of drm_device private_data Kory Maincent (TI.com)
` (5 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Refactor the driver initialization to use modern DRM managed resource
APIs, simplifying the code.
The tilcdc_init and tilcdc_fini wrapper functions are removed since they
served no purpose after the component framework was eliminated. Their
logic is integrated directly into probe and remove.
Key changes:
- Use devm_drm_dev_alloc() instead of drm_dev_alloc().
- Use drmm_mode_config_init() instead of drm_mode_config_init().
- Align the remove path with the probe error path to ensure consistent
cleanup ordering in both success and failure cases.
- Adjust platform_set_drvdata() to store the private structure instead
of the drm_device, matching the new allocation pattern.
These changes reduce error-prone code while maintaining the same
functional behavior.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 308 ++++++++++++++++--------------------
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 +
2 files changed, 139 insertions(+), 171 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 4630e56c3f028..2cbe390a1ee54 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -139,39 +139,125 @@ static void tilcdc_irq_uninstall(struct drm_device *dev)
* DRM operations:
*/
-static void tilcdc_fini(struct drm_device *dev)
+#if defined(CONFIG_DEBUG_FS)
+static const struct {
+ const char *name;
+ uint8_t rev;
+ uint8_t save;
+ uint32_t reg;
+} registers[] = {
+#define REG(rev, save, reg) { #reg, rev, save, reg }
+ /* exists in revision 1: */
+ REG(1, false, LCDC_PID_REG),
+ REG(1, true, LCDC_CTRL_REG),
+ REG(1, false, LCDC_STAT_REG),
+ REG(1, true, LCDC_RASTER_CTRL_REG),
+ REG(1, true, LCDC_RASTER_TIMING_0_REG),
+ REG(1, true, LCDC_RASTER_TIMING_1_REG),
+ REG(1, true, LCDC_RASTER_TIMING_2_REG),
+ REG(1, true, LCDC_DMA_CTRL_REG),
+ REG(1, true, LCDC_DMA_FB_BASE_ADDR_0_REG),
+ REG(1, true, LCDC_DMA_FB_CEILING_ADDR_0_REG),
+ REG(1, true, LCDC_DMA_FB_BASE_ADDR_1_REG),
+ REG(1, true, LCDC_DMA_FB_CEILING_ADDR_1_REG),
+ /* new in revision 2: */
+ REG(2, false, LCDC_RAW_STAT_REG),
+ REG(2, false, LCDC_MASKED_STAT_REG),
+ REG(2, true, LCDC_INT_ENABLE_SET_REG),
+ REG(2, false, LCDC_INT_ENABLE_CLR_REG),
+ REG(2, false, LCDC_END_OF_INT_IND_REG),
+ REG(2, true, LCDC_CLK_ENABLE_REG),
+#undef REG
+};
+
+static int tilcdc_regs_show(struct seq_file *m, void *arg)
{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
struct tilcdc_drm_private *priv = dev->dev_private;
+ unsigned i;
-#ifdef CONFIG_CPU_FREQ
- if (priv->freq_transition.notifier_call)
- cpufreq_unregister_notifier(&priv->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
+ pm_runtime_get_sync(dev->dev);
+
+ seq_printf(m, "revision: %d\n", priv->rev);
+
+ for (i = 0; i < ARRAY_SIZE(registers); i++)
+ if (priv->rev >= registers[i].rev)
+ seq_printf(m, "%s:\t %08x\n", registers[i].name,
+ tilcdc_read(dev, registers[i].reg));
+
+ pm_runtime_put_sync(dev->dev);
+
+ return 0;
+}
+
+static int tilcdc_mm_show(struct seq_file *m, void *arg)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_printer p = drm_seq_file_printer(m);
+ drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p);
+ return 0;
+}
+
+static struct drm_info_list tilcdc_debugfs_list[] = {
+ { "regs", tilcdc_regs_show, 0, NULL },
+ { "mm", tilcdc_mm_show, 0, NULL },
+};
+
+static void tilcdc_debugfs_init(struct drm_minor *minor)
+{
+ drm_debugfs_create_files(tilcdc_debugfs_list,
+ ARRAY_SIZE(tilcdc_debugfs_list),
+ minor->debugfs_root, minor);
+}
#endif
- if (priv->crtc)
- tilcdc_crtc_shutdown(priv->crtc);
+DEFINE_DRM_GEM_DMA_FOPS(fops);
- drm_dev_unregister(dev);
+static const struct drm_driver tilcdc_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+ DRM_GEM_DMA_DRIVER_OPS,
+ DRM_FBDEV_DMA_DRIVER_OPS,
+#ifdef CONFIG_DEBUG_FS
+ .debugfs_init = tilcdc_debugfs_init,
+#endif
+ .fops = &fops,
+ .name = "tilcdc",
+ .desc = "TI LCD Controller DRM",
+ .major = 1,
+ .minor = 0,
+};
- drm_kms_helper_poll_fini(dev);
- drm_atomic_helper_shutdown(dev);
- tilcdc_irq_uninstall(dev);
- drm_mode_config_cleanup(dev);
+/*
+ * Power management:
+ */
- if (priv->clk)
- clk_put(priv->clk);
+static int tilcdc_pm_suspend(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ int ret = 0;
- if (priv->wq)
- destroy_workqueue(priv->wq);
+ ret = drm_mode_config_helper_suspend(ddev);
+
+ /* Select sleep pin state */
+ pinctrl_pm_select_sleep_state(dev);
- dev->dev_private = NULL;
+ return ret;
+}
- pm_runtime_disable(dev->dev);
+static int tilcdc_pm_resume(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
- drm_dev_put(dev);
+ /* Select default pin state */
+ pinctrl_pm_select_default_state(dev);
+ return drm_mode_config_helper_resume(ddev);
}
+static DEFINE_SIMPLE_DEV_PM_OPS(tilcdc_pm_ops,
+ tilcdc_pm_suspend, tilcdc_pm_resume);
+
static const struct of_device_id tilcdc_of_match[] = {
{ .compatible = "ti,am33xx-tilcdc", .data = (void *)AM33XX_TILCDC},
{ .compatible = "ti,da850-tilcdc", .data = (void *)DA850_TILCDC},
@@ -179,37 +265,35 @@ static const struct of_device_id tilcdc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, tilcdc_of_match);
-static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
+static int tilcdc_pdev_probe(struct platform_device *pdev)
{
- struct drm_device *ddev;
- struct platform_device *pdev = to_platform_device(dev);
- struct device_node *node = dev->of_node;
+ struct device_node *node = pdev->dev.of_node;
const struct of_device_id *of_id;
struct tilcdc_drm_private *priv;
+ struct device *dev = &pdev->dev;
+ struct drm_device *ddev;
u32 bpp = 0;
int ret;
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- ddev = drm_dev_alloc(ddrv, dev);
- if (IS_ERR(ddev))
- return PTR_ERR(ddev);
+ priv = devm_drm_dev_alloc(dev, &tilcdc_driver,
+ struct tilcdc_drm_private, ddev);
+ if (IS_ERR(priv))
+ return PTR_ERR(priv);
of_id = of_match_node(tilcdc_of_match, node);
if (!of_id)
return -ENODEV;
+ platform_set_drvdata(pdev, priv);
+ ddev = &priv->ddev;
ddev->dev_private = priv;
- platform_set_drvdata(pdev, ddev);
- drm_mode_config_init(ddev);
+ ret = drmm_mode_config_init(ddev);
+ if (ret)
+ return ret;
priv->wq = alloc_ordered_workqueue("tilcdc", 0);
- if (!priv->wq) {
- ret = -ENOMEM;
- goto put_drm;
- }
+ if (!priv->wq)
+ return -ENOMEM;
priv->mmio = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->mmio)) {
@@ -375,152 +459,34 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
clk_put(priv->clk);
free_wq:
destroy_workqueue(priv->wq);
-put_drm:
- platform_set_drvdata(pdev, NULL);
- ddev->dev_private = NULL;
- drm_dev_put(ddev);
return ret;
}
-#if defined(CONFIG_DEBUG_FS)
-static const struct {
- const char *name;
- uint8_t rev;
- uint8_t save;
- uint32_t reg;
-} registers[] = {
-#define REG(rev, save, reg) { #reg, rev, save, reg }
- /* exists in revision 1: */
- REG(1, false, LCDC_PID_REG),
- REG(1, true, LCDC_CTRL_REG),
- REG(1, false, LCDC_STAT_REG),
- REG(1, true, LCDC_RASTER_CTRL_REG),
- REG(1, true, LCDC_RASTER_TIMING_0_REG),
- REG(1, true, LCDC_RASTER_TIMING_1_REG),
- REG(1, true, LCDC_RASTER_TIMING_2_REG),
- REG(1, true, LCDC_DMA_CTRL_REG),
- REG(1, true, LCDC_DMA_FB_BASE_ADDR_0_REG),
- REG(1, true, LCDC_DMA_FB_CEILING_ADDR_0_REG),
- REG(1, true, LCDC_DMA_FB_BASE_ADDR_1_REG),
- REG(1, true, LCDC_DMA_FB_CEILING_ADDR_1_REG),
- /* new in revision 2: */
- REG(2, false, LCDC_RAW_STAT_REG),
- REG(2, false, LCDC_MASKED_STAT_REG),
- REG(2, true, LCDC_INT_ENABLE_SET_REG),
- REG(2, false, LCDC_INT_ENABLE_CLR_REG),
- REG(2, false, LCDC_END_OF_INT_IND_REG),
- REG(2, true, LCDC_CLK_ENABLE_REG),
-#undef REG
-};
-
-static int tilcdc_regs_show(struct seq_file *m, void *arg)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_device *dev = node->minor->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
- unsigned i;
-
- pm_runtime_get_sync(dev->dev);
-
- seq_printf(m, "revision: %d\n", priv->rev);
-
- for (i = 0; i < ARRAY_SIZE(registers); i++)
- if (priv->rev >= registers[i].rev)
- seq_printf(m, "%s:\t %08x\n", registers[i].name,
- tilcdc_read(dev, registers[i].reg));
-
- pm_runtime_put_sync(dev->dev);
-
- return 0;
-}
-
-static int tilcdc_mm_show(struct seq_file *m, void *arg)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_printer p = drm_seq_file_printer(m);
- drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p);
- return 0;
-}
-
-static struct drm_info_list tilcdc_debugfs_list[] = {
- { "regs", tilcdc_regs_show, 0, NULL },
- { "mm", tilcdc_mm_show, 0, NULL },
-};
-
-static void tilcdc_debugfs_init(struct drm_minor *minor)
+static void tilcdc_pdev_remove(struct platform_device *pdev)
{
- drm_debugfs_create_files(tilcdc_debugfs_list,
- ARRAY_SIZE(tilcdc_debugfs_list),
- minor->debugfs_root, minor);
-}
-#endif
-
-DEFINE_DRM_GEM_DMA_FOPS(fops);
+ struct tilcdc_drm_private *priv = platform_get_drvdata(pdev);
+ struct drm_device *ddev = &priv->ddev;
-static const struct drm_driver tilcdc_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
- DRM_GEM_DMA_DRIVER_OPS,
- DRM_FBDEV_DMA_DRIVER_OPS,
-#ifdef CONFIG_DEBUG_FS
- .debugfs_init = tilcdc_debugfs_init,
+ drm_dev_unregister(ddev);
+ drm_kms_helper_poll_fini(ddev);
+ tilcdc_irq_uninstall(ddev);
+#ifdef CONFIG_CPU_FREQ
+ cpufreq_unregister_notifier(&priv->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
#endif
- .fops = &fops,
- .name = "tilcdc",
- .desc = "TI LCD Controller DRM",
- .major = 1,
- .minor = 0,
-};
-
-/*
- * Power management:
- */
-
-static int tilcdc_pm_suspend(struct device *dev)
-{
- struct drm_device *ddev = dev_get_drvdata(dev);
- int ret = 0;
-
- ret = drm_mode_config_helper_suspend(ddev);
-
- /* Select sleep pin state */
- pinctrl_pm_select_sleep_state(dev);
-
- return ret;
-}
-
-static int tilcdc_pm_resume(struct device *dev)
-{
- struct drm_device *ddev = dev_get_drvdata(dev);
-
- /* Select default pin state */
- pinctrl_pm_select_default_state(dev);
- return drm_mode_config_helper_resume(ddev);
-}
-
-static DEFINE_SIMPLE_DEV_PM_OPS(tilcdc_pm_ops,
- tilcdc_pm_suspend, tilcdc_pm_resume);
-
-static int tilcdc_pdev_probe(struct platform_device *pdev)
-{
- /* bail out early if no DT data: */
- if (!pdev->dev.of_node) {
- dev_err(&pdev->dev, "device-tree data is missing\n");
- return -ENXIO;
- }
-
- return tilcdc_init(&tilcdc_driver, &pdev->dev);
-}
-
-static void tilcdc_pdev_remove(struct platform_device *pdev)
-{
- tilcdc_fini(platform_get_drvdata(pdev));
+ tilcdc_crtc_destroy(priv->crtc);
+ pm_runtime_disable(&pdev->dev);
+ clk_put(priv->clk);
+ destroy_workqueue(priv->wq);
}
static void tilcdc_pdev_shutdown(struct platform_device *pdev)
{
- drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
+ struct tilcdc_drm_private *priv = platform_get_drvdata(pdev);
+ struct drm_device *ddev = &priv->ddev;
+
+ drm_atomic_helper_shutdown(ddev);
}
static struct platform_driver tilcdc_platform_driver = {
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 60e85e29b1063..e3d04a3eb25b4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -48,6 +48,8 @@ struct tilcdc_drm_private {
unsigned int irq;
+ struct drm_device ddev;
+
/* don't attempt resolutions w/ higher W * H * Hz: */
uint32_t max_bandwidth;
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 15/20] drm/tilcdc: Remove the use of drm_device private_data
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (13 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 14/20] drm/tilcdc: Modernize driver initialization and cleanup paths Kory Maincent (TI.com)
@ 2025-12-11 16:38 ` Kory Maincent (TI.com)
2025-12-11 16:39 ` [PATCH v2 16/20] drm/bridge: tda998x: Remove component support Kory Maincent (TI.com)
` (4 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:38 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The DRM core documentation recommends against using dev_private:
"Instead of using this pointer it is recommended that drivers use
embed the struct &drm_device in their larger per-device structure."
This patch refactors the tilcdc driver to follow this recommendation
by embedding struct drm_device within struct tilcdc_drm_private and
replacing all dev->dev_private accesses with the ddev_to_tilcdc_priv()
helper macro that uses container_of().
This change aligns the driver with modern DRM best practices.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 28 ++++++++++++++--------------
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 11 +++++------
drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 ++
drivers/gpu/drm/tilcdc/tilcdc_encoder.c | 4 ++--
drivers/gpu/drm/tilcdc/tilcdc_plane.c | 2 +-
drivers/gpu/drm/tilcdc/tilcdc_regs.h | 8 ++++----
6 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 5b8aba0765f9b..0bd99a2efeeb4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -59,7 +59,7 @@ struct tilcdc_crtc {
static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
{
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
struct drm_gem_dma_object *gem;
dma_addr_t start, end;
u64 dma_base_and_ceiling;
@@ -94,7 +94,7 @@ static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
int ret;
reinit_completion(&tilcdc_crtc->palette_loaded);
@@ -136,7 +136,7 @@ static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
tilcdc_clear_irqstatus(dev, 0xffffffff);
@@ -153,7 +153,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
/* disable irqs that we might have enabled: */
if (priv->rev == 1) {
@@ -173,7 +173,7 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
static void reset(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
if (priv->rev != 2)
return;
@@ -198,7 +198,7 @@ static unsigned int tilcdc_pclk_diff(unsigned long rate,
static void tilcdc_crtc_set_clk(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
unsigned long clk_rate, real_pclk_rate, pclk_rate;
unsigned int clkdiv;
@@ -270,7 +270,7 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
uint32_t reg, hbp, hfp, hsw, vbp, vfp, vsw;
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
struct drm_framebuffer *fb = crtc->primary->state->fb;
@@ -557,7 +557,7 @@ static void tilcdc_crtc_recover_work(struct work_struct *work)
void tilcdc_crtc_destroy(struct drm_crtc *crtc)
{
- struct tilcdc_drm_private *priv = crtc->dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(crtc->dev);
tilcdc_crtc_shutdown(crtc);
@@ -647,7 +647,7 @@ static int tilcdc_crtc_enable_vblank(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
unsigned long flags;
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
@@ -670,7 +670,7 @@ static void tilcdc_crtc_disable_vblank(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
unsigned long flags;
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
@@ -728,7 +728,7 @@ static enum drm_mode_status
tilcdc_crtc_mode_valid(struct drm_crtc *crtc,
const struct drm_display_mode *mode)
{
- struct tilcdc_drm_private *priv = crtc->dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(crtc->dev);
unsigned int bandwidth;
uint32_t hbp, hfp, hsw, vbp, vfp, vsw;
@@ -826,7 +826,7 @@ static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
drm_modeset_lock(&crtc->mutex, NULL);
@@ -850,7 +850,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
uint32_t stat, reg;
stat = tilcdc_read_irqstatus(dev);
@@ -958,7 +958,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
int tilcdc_crtc_create(struct drm_device *dev)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
struct tilcdc_crtc *tilcdc_crtc;
struct drm_crtc *crtc;
int ret;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 2cbe390a1ee54..89afd32b52baf 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -79,7 +79,7 @@ static const struct drm_mode_config_funcs mode_config_funcs = {
static void modeset_init(struct drm_device *dev)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
@@ -105,14 +105,14 @@ static int cpufreq_transition(struct notifier_block *nb,
static irqreturn_t tilcdc_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
return tilcdc_crtc_irq(priv->crtc);
}
static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
int ret;
ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
@@ -126,7 +126,7 @@ static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
static void tilcdc_irq_uninstall(struct drm_device *dev)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
if (!priv->irq_enabled)
return;
@@ -174,7 +174,7 @@ static int tilcdc_regs_show(struct seq_file *m, void *arg)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
unsigned i;
pm_runtime_get_sync(dev->dev);
@@ -286,7 +286,6 @@ static int tilcdc_pdev_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
ddev = &priv->ddev;
- ddev->dev_private = priv;
ret = drmm_mode_config_init(ddev);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index e3d04a3eb25b4..c69e279a2539d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -85,6 +85,8 @@ struct tilcdc_drm_private {
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+#define ddev_to_tilcdc_priv(x) container_of(x, struct tilcdc_drm_private, ddev)
+
int tilcdc_crtc_create(struct drm_device *dev);
irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc);
void tilcdc_crtc_update_clk(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_encoder.c b/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
index bca91226351dd..d01e7a31a286c 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
@@ -34,7 +34,7 @@ struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev,
static
int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
{
- struct tilcdc_drm_private *priv = ddev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(ddev);
int ret;
priv->encoder->possible_crtcs = BIT(0);
@@ -53,7 +53,7 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
int tilcdc_encoder_create(struct drm_device *ddev)
{
- struct tilcdc_drm_private *priv = ddev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(ddev);
struct drm_bridge *bridge;
struct drm_panel *panel;
int ret;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
index aa72ca679598b..a77a5b22ebd96 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
@@ -101,7 +101,7 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
int tilcdc_plane_init(struct drm_device *dev,
struct drm_plane *plane)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
int ret;
ret = drm_universal_plane_init(dev, plane, 1, &tilcdc_plane_funcs,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
index f90e2dc3457cd..26ebaf1e0f70f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
@@ -113,13 +113,13 @@
static inline void tilcdc_write(struct drm_device *dev, u32 reg, u32 data)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
iowrite32(data, priv->mmio + reg);
}
static inline void tilcdc_write64(struct drm_device *dev, u32 reg, u64 data)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
volatile void __iomem *addr = priv->mmio + reg;
#if defined(iowrite64) && !defined(iowrite64_is_nonatomic)
@@ -133,7 +133,7 @@ static inline void tilcdc_write64(struct drm_device *dev, u32 reg, u64 data)
static inline u32 tilcdc_read(struct drm_device *dev, u32 reg)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
return ioread32(priv->mmio + reg);
}
@@ -156,7 +156,7 @@ static inline void tilcdc_clear(struct drm_device *dev, u32 reg, u32 mask)
/* the register to read/clear irqstatus differs between v1 and v2 of the IP */
static inline u32 tilcdc_irqstatus_reg(struct drm_device *dev)
{
- struct tilcdc_drm_private *priv = dev->dev_private;
+ struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev);
return (priv->rev == 2) ? LCDC_MASKED_STAT_REG : LCDC_STAT_REG;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 16/20] drm/bridge: tda998x: Remove component support
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (14 preceding siblings ...)
2025-12-11 16:38 ` [PATCH v2 15/20] drm/tilcdc: Remove the use of drm_device private_data Kory Maincent (TI.com)
@ 2025-12-11 16:39 ` Kory Maincent (TI.com)
2025-12-11 16:39 ` [PATCH v2 17/20] drm/bridge: tda998x: Move tda998x_create/destroy into probe and remove Kory Maincent (TI.com)
` (3 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:39 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
The tilcdc driver no longer uses the component framework to bind the
tda998x bridge driver. The component bind/unbind operations and the
encoder initialization code are now dead code and can be safely removed.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/bridge/tda998x_drv.c | 69 +-----------------------------------
1 file changed, 1 insertion(+), 68 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c
index e636459d91857..865285ba2bd8c 100644
--- a/drivers/gpu/drm/bridge/tda998x_drv.c
+++ b/drivers/gpu/drm/bridge/tda998x_drv.c
@@ -4,7 +4,6 @@
* Author: Rob Clark <robdclark@gmail.com>
*/
-#include <linux/component.h>
#include <linux/gpio/consumer.h>
#include <linux/hdmi.h>
#include <linux/i2c.h>
@@ -1963,85 +1962,19 @@ static int tda998x_create(struct device *dev)
return ret;
}
-/* DRM encoder functions */
-
-static int tda998x_encoder_init(struct device *dev, struct drm_device *drm)
-{
- struct tda998x_priv *priv = dev_get_drvdata(dev);
- u32 crtcs = 0;
- int ret;
-
- if (dev->of_node)
- crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
-
- /* If no CRTCs were found, fall back to our old behaviour */
- if (crtcs == 0) {
- dev_warn(dev, "Falling back to first CRTC\n");
- crtcs = 1 << 0;
- }
-
- priv->encoder.possible_crtcs = crtcs;
-
- ret = drm_simple_encoder_init(drm, &priv->encoder,
- DRM_MODE_ENCODER_TMDS);
- if (ret)
- goto err_encoder;
-
- ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL, 0);
- if (ret)
- goto err_bridge;
-
- return 0;
-
-err_bridge:
- drm_encoder_cleanup(&priv->encoder);
-err_encoder:
- return ret;
-}
-
-static int tda998x_bind(struct device *dev, struct device *master, void *data)
-{
- struct drm_device *drm = data;
-
- return tda998x_encoder_init(dev, drm);
-}
-
-static void tda998x_unbind(struct device *dev, struct device *master,
- void *data)
-{
- struct tda998x_priv *priv = dev_get_drvdata(dev);
-
- drm_encoder_cleanup(&priv->encoder);
-}
-
-static const struct component_ops tda998x_ops = {
- .bind = tda998x_bind,
- .unbind = tda998x_unbind,
-};
-
static int
tda998x_probe(struct i2c_client *client)
{
- int ret;
-
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_warn(&client->dev, "adapter does not support I2C\n");
return -EIO;
}
- ret = tda998x_create(&client->dev);
- if (ret)
- return ret;
-
- ret = component_add(&client->dev, &tda998x_ops);
- if (ret)
- tda998x_destroy(&client->dev);
- return ret;
+ return tda998x_create(&client->dev);
}
static void tda998x_remove(struct i2c_client *client)
{
- component_del(&client->dev, &tda998x_ops);
tda998x_destroy(&client->dev);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 17/20] drm/bridge: tda998x: Move tda998x_create/destroy into probe and remove
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (15 preceding siblings ...)
2025-12-11 16:39 ` [PATCH v2 16/20] drm/bridge: tda998x: Remove component support Kory Maincent (TI.com)
@ 2025-12-11 16:39 ` Kory Maincent (TI.com)
2025-12-11 16:39 ` [PATCH v2 18/20] drm/bridge: tda998x: Remove useless tda998x_connector_destroy wrapper Kory Maincent (TI.com)
` (2 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:39 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Now that tda998x_create and tda998x_destroy are called only in the probe
function, there is no need for separate functions.
Move the code into the tda998x_probe and tda998x_remove functions.
Rewrite the cleanup path using goto calls in probe and reorder it in the
remove function.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/bridge/tda998x_drv.c | 99 +++++++++++++++++++-----------------
1 file changed, 51 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c
index 865285ba2bd8c..4be49dd5bfc01 100644
--- a/drivers/gpu/drm/bridge/tda998x_drv.c
+++ b/drivers/gpu/drm/bridge/tda998x_drv.c
@@ -1748,38 +1748,20 @@ static int tda998x_get_audio_ports(struct tda998x_priv *priv,
return 0;
}
-static void tda998x_destroy(struct device *dev)
-{
- struct tda998x_priv *priv = dev_get_drvdata(dev);
-
- drm_bridge_remove(&priv->bridge);
-
- /* disable all IRQs and free the IRQ handler */
- cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
- reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
-
- if (priv->audio_pdev)
- platform_device_unregister(priv->audio_pdev);
-
- if (priv->hdmi->irq)
- free_irq(priv->hdmi->irq, priv);
-
- timer_delete_sync(&priv->edid_delay_timer);
- cancel_work_sync(&priv->detect_work);
-
- i2c_unregister_device(priv->cec);
-
- cec_notifier_conn_unregister(priv->cec_notify);
-}
-
-static int tda998x_create(struct device *dev)
+static int
+tda998x_probe(struct i2c_client *client)
{
- struct i2c_client *client = to_i2c_client(dev);
struct device_node *np = client->dev.of_node;
+ struct device *dev = &client->dev;
struct i2c_board_info cec_info;
struct tda998x_priv *priv;
- u32 video;
int rev_lo, rev_hi, ret;
+ u32 video;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_warn(&client->dev, "adapter does not support I2C\n");
+ return -EIO;
+ }
priv = devm_drm_bridge_alloc(dev, struct tda998x_priv, bridge, &tda998x_bridge_funcs);
if (IS_ERR(priv))
@@ -1814,13 +1796,15 @@ static int tda998x_create(struct device *dev)
rev_lo = reg_read(priv, REG_VERSION_LSB);
if (rev_lo < 0) {
dev_err(dev, "failed to read version: %d\n", rev_lo);
- return rev_lo;
+ ret = rev_lo;
+ goto cancel_work;
}
rev_hi = reg_read(priv, REG_VERSION_MSB);
if (rev_hi < 0) {
dev_err(dev, "failed to read version: %d\n", rev_hi);
- return rev_hi;
+ ret = rev_hi;
+ goto cancel_work;
}
priv->rev = rev_lo | rev_hi << 8;
@@ -1843,7 +1827,8 @@ static int tda998x_create(struct device *dev)
break;
default:
dev_err(dev, "found unsupported device: %04x\n", priv->rev);
- return -ENXIO;
+ ret = -ENXIO;
+ goto cancel_work;
}
/* after reset, enable DDC: */
@@ -1887,7 +1872,7 @@ static int tda998x_create(struct device *dev)
if (ret) {
dev_err(dev, "failed to request IRQ#%u: %d\n",
client->irq, ret);
- goto err_irq;
+ goto cancel_work;
}
/* enable HPD irq */
@@ -1897,7 +1882,7 @@ static int tda998x_create(struct device *dev)
priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
if (!priv->cec_notify) {
ret = -ENOMEM;
- goto fail;
+ goto free_irq;
}
priv->cec_glue.parent = dev;
@@ -1924,7 +1909,7 @@ static int tda998x_create(struct device *dev)
priv->cec = i2c_new_client_device(client->adapter, &cec_info);
if (IS_ERR(priv->cec)) {
ret = PTR_ERR(priv->cec);
- goto fail;
+ goto notifier_conn_unregister;
}
/* enable EDID read irq: */
@@ -1941,7 +1926,7 @@ static int tda998x_create(struct device *dev)
ret = tda998x_get_audio_ports(priv, np);
if (ret)
- goto fail;
+ goto unregister_dev;
if (priv->audio_port_enable[AUDIO_ROUTE_I2S] ||
priv->audio_port_enable[AUDIO_ROUTE_SPDIF])
@@ -1956,26 +1941,44 @@ static int tda998x_create(struct device *dev)
return 0;
-fail:
- tda998x_destroy(dev);
-err_irq:
+unregister_dev:
+ i2c_unregister_device(priv->cec);
+notifier_conn_unregister:
+ cec_notifier_conn_unregister(priv->cec_notify);
+free_irq:
+ if (client->irq) {
+ free_irq(client->irq, priv);
+ cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
+ reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
+ }
+cancel_work:
+ timer_delete_sync(&priv->edid_delay_timer);
+ cancel_work_sync(&priv->detect_work);
return ret;
}
-static int
-tda998x_probe(struct i2c_client *client)
+static void tda998x_remove(struct i2c_client *client)
{
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- dev_warn(&client->dev, "adapter does not support I2C\n");
- return -EIO;
- }
+ struct tda998x_priv *priv = dev_get_drvdata(&client->dev);
- return tda998x_create(&client->dev);
-}
+ drm_bridge_remove(&priv->bridge);
-static void tda998x_remove(struct i2c_client *client)
-{
- tda998x_destroy(&client->dev);
+ if (priv->audio_pdev)
+ platform_device_unregister(priv->audio_pdev);
+
+ i2c_unregister_device(priv->cec);
+
+ cec_notifier_conn_unregister(priv->cec_notify);
+
+ /* disable all IRQs and free the IRQ handler */
+ if (client->irq) {
+ cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
+ reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
+ free_irq(priv->hdmi->irq, priv);
+ }
+
+ timer_delete_sync(&priv->edid_delay_timer);
+ cancel_work_sync(&priv->detect_work);
}
#ifdef CONFIG_OF
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 18/20] drm/bridge: tda998x: Remove useless tda998x_connector_destroy wrapper
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (16 preceding siblings ...)
2025-12-11 16:39 ` [PATCH v2 17/20] drm/bridge: tda998x: Move tda998x_create/destroy into probe and remove Kory Maincent (TI.com)
@ 2025-12-11 16:39 ` Kory Maincent (TI.com)
2025-12-11 16:39 ` [PATCH v2 19/20] drm/bridge: tda998x: Add support for DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
2025-12-11 16:39 ` [PATCH v2 20/20] drm/tilcdc: " Kory Maincent (TI.com)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:39 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Use directly drm_connector_cleanup in the destroy ops instead of having
a custom function that does nothing more.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/bridge/tda998x_drv.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c
index 4be49dd5bfc01..43ace6ee2ca35 100644
--- a/drivers/gpu/drm/bridge/tda998x_drv.c
+++ b/drivers/gpu/drm/bridge/tda998x_drv.c
@@ -1203,16 +1203,11 @@ tda998x_connector_detect(struct drm_connector *connector, bool force)
connector_status_disconnected;
}
-static void tda998x_connector_destroy(struct drm_connector *connector)
-{
- drm_connector_cleanup(connector);
-}
-
static const struct drm_connector_funcs tda998x_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = tda998x_connector_detect,
- .destroy = tda998x_connector_destroy,
+ .destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 19/20] drm/bridge: tda998x: Add support for DRM_BRIDGE_ATTACH_NO_CONNECTOR
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (17 preceding siblings ...)
2025-12-11 16:39 ` [PATCH v2 18/20] drm/bridge: tda998x: Remove useless tda998x_connector_destroy wrapper Kory Maincent (TI.com)
@ 2025-12-11 16:39 ` Kory Maincent (TI.com)
2025-12-11 16:39 ` [PATCH v2 20/20] drm/tilcdc: " Kory Maincent (TI.com)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:39 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Add support for the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag to allow display
controller drivers to create their own connectors. This modernizes the
driver to work with the current DRM bridge framework.
The implementation includes:
- Refactoring detection and EDID reading into bridge-usable helpers
- Adding bridge operations: edid_read, detect, hpd_enable, hpd_disable
- Setting appropriate bridge ops (DRM_BRIDGE_OP_EDID, DRM_BRIDGE_OP_DETECT,
DRM_BRIDGE_OP_HPD) and connector type (HDMIA)
- Skipping connector creation when DRM_BRIDGE_ATTACH_NO_CONNECTOR is set
- Handling conditional connector cleanup in bridge_detach
The driver maintains backward compatibility by continuing to create its
own connector when the flag is not set.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/bridge/tda998x_drv.c | 96 +++++++++++++++++++++++++++++++-----
1 file changed, 85 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c
index 43ace6ee2ca35..4d78615634691 100644
--- a/drivers/gpu/drm/bridge/tda998x_drv.c
+++ b/drivers/gpu/drm/bridge/tda998x_drv.c
@@ -1193,16 +1193,22 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
/* DRM connector functions */
-static enum drm_connector_status
-tda998x_connector_detect(struct drm_connector *connector, bool force)
+static enum drm_connector_status tda998x_conn_detect(struct tda998x_priv *priv)
{
- struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
u8 val = cec_read(priv, REG_CEC_RXSHPDLEV);
return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected :
connector_status_disconnected;
}
+static enum drm_connector_status
+tda998x_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
+
+ return tda998x_conn_detect(priv);
+}
+
static const struct drm_connector_funcs tda998x_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -1276,11 +1282,10 @@ static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
return ret;
}
-static int tda998x_connector_get_modes(struct drm_connector *connector)
+static const struct drm_edid *tda998x_edid_read(struct tda998x_priv *priv,
+ struct drm_connector *connector)
{
- struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
const struct drm_edid *drm_edid;
- int n;
/*
* If we get killed while waiting for the HPD timeout, return
@@ -1298,6 +1303,16 @@ static int tda998x_connector_get_modes(struct drm_connector *connector)
if (priv->rev == TDA19988)
reg_set(priv, REG_TX4, TX4_PD_RAM);
+ return drm_edid;
+}
+
+static int tda998x_connector_get_modes(struct drm_connector *connector)
+{
+ struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
+ const struct drm_edid *drm_edid;
+ int n;
+
+ drm_edid = tda998x_edid_read(priv, connector);
drm_edid_connector_update(connector, drm_edid);
cec_notifier_set_phys_addr(priv->cec_notify,
connector->display_info.source_physical_address);
@@ -1365,10 +1380,8 @@ static int tda998x_bridge_attach(struct drm_bridge *bridge,
{
struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
- if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
- DRM_ERROR("Fix bridge driver to make connector optional!");
- return -EINVAL;
- }
+ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+ return 0;
return tda998x_connector_init(priv, bridge->dev);
}
@@ -1377,7 +1390,8 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
{
struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
- drm_connector_cleanup(&priv->connector);
+ if (priv->connector.dev)
+ drm_connector_cleanup(&priv->connector);
}
static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
@@ -1677,6 +1691,59 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
mutex_unlock(&priv->audio_mutex);
}
+static const struct drm_edid *
+tda998x_bridge_edid_read(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+ struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+ const struct drm_edid *drm_edid;
+ const struct edid *edid;
+
+ drm_edid = tda998x_edid_read(priv, connector);
+ if (!drm_edid) {
+ dev_dbg(&priv->hdmi->dev, "failed to get edid\n");
+ return NULL;
+ }
+
+ /*
+ * FIXME: This should use connector->display_info.has_audio from
+ * a path that has read the EDID and called
+ * drm_edid_connector_update().
+ */
+ edid = drm_edid_raw(drm_edid);
+
+ dev_dbg(&priv->hdmi->dev, "got edid: width[%d] x height[%d]\n",
+ edid->width_cm, edid->height_cm);
+
+ priv->sink_has_audio = drm_detect_monitor_audio(edid);
+ cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid);
+
+ return drm_edid;
+}
+
+static enum drm_connector_status
+tda998x_bridge_detect(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+ struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+ return tda998x_conn_detect(priv);
+}
+
+static void tda998x_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+ struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+ cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
+}
+
+static void tda998x_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+ struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+ cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
+}
+
static const struct drm_bridge_funcs tda998x_bridge_funcs = {
.attach = tda998x_bridge_attach,
.detach = tda998x_bridge_detach,
@@ -1684,6 +1751,10 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = {
.disable = tda998x_bridge_disable,
.mode_set = tda998x_bridge_mode_set,
.enable = tda998x_bridge_enable,
+ .edid_read = tda998x_bridge_edid_read,
+ .detect = tda998x_bridge_detect,
+ .hpd_enable = tda998x_bridge_hpd_enable,
+ .hpd_disable = tda998x_bridge_hpd_disable,
};
/* I2C driver functions */
@@ -1872,6 +1943,7 @@ tda998x_probe(struct i2c_client *client)
/* enable HPD irq */
cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
+ priv->bridge.ops = DRM_BRIDGE_OP_HPD;
}
priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
@@ -1932,6 +2004,8 @@ tda998x_probe(struct i2c_client *client)
priv->bridge.of_node = dev->of_node;
#endif
+ priv->bridge.ops |= DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
+ priv->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
drm_bridge_add(&priv->bridge);
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 20/20] drm/tilcdc: Add support for DRM_BRIDGE_ATTACH_NO_CONNECTOR
2025-12-11 16:38 [PATCH v2 00/20] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
` (18 preceding siblings ...)
2025-12-11 16:39 ` [PATCH v2 19/20] drm/bridge: tda998x: Add support for DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
@ 2025-12-11 16:39 ` Kory Maincent (TI.com)
19 siblings, 0 replies; 23+ messages in thread
From: Kory Maincent (TI.com) @ 2025-12-11 16:39 UTC (permalink / raw)
To: Jyri Sarha, Tomi Valkeinen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Russell King,
Bartosz Golaszewski, Tony Lindgren, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
Cc: Markus Schneider-Pargmann, Bajjuri Praneeth, Luca Ceresoli,
Louis Chauvet, Thomas Petazzoni, Miguel Gazquez, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, linux-omap,
Kory Maincent (TI.com)
Convert the driver to use the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag when
attaching bridges. This modernizes the driver by delegating connector
creation to the bridge subsystem through drm_bridge_connector_init()
instead of manually searching for connectors created by the bridge.
The custom tilcdc_encoder_find_connector() function is removed and
replaced with the standard drm_bridge_connector infrastructure, which
simplifies the code and aligns with current DRM bridge best practices.
This change is safe as there are now no in-tree devicetrees that
connect tilcdc to bridges which do not support the
DRM_BRIDGE_ATTACH_NO_CONNECTOR flag.
Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
drivers/gpu/drm/tilcdc/tilcdc_encoder.c | 38 ++++++++++++++-------------------
1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_encoder.c b/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
index d01e7a31a286c..11fde3a2be353 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_encoder.c
@@ -8,46 +8,40 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
#include <drm/drm_of.h>
#include <drm/drm_simple_kms_helper.h>
#include "tilcdc_drv.h"
#include "tilcdc_encoder.h"
-static
-struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev,
- struct drm_encoder *encoder)
-{
- struct drm_connector *connector;
-
- list_for_each_entry(connector, &ddev->mode_config.connector_list, head) {
- if (drm_connector_has_possible_encoder(connector, encoder))
- return connector;
- }
-
- dev_err(ddev->dev, "No connector found for %s encoder (id %d)\n",
- encoder->name, encoder->base.id);
-
- return NULL;
-}
-
static
int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
{
struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(ddev);
+ struct drm_connector *connector;
int ret;
priv->encoder->possible_crtcs = BIT(0);
- ret = drm_bridge_attach(priv->encoder, bridge, NULL, 0);
+ ret = drm_bridge_attach(priv->encoder, bridge, NULL,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret)
return ret;
- priv->connector =
- tilcdc_encoder_find_connector(ddev, priv->encoder);
- if (!priv->connector)
- return -ENODEV;
+ connector = drm_bridge_connector_init(ddev, priv->encoder);
+ if (IS_ERR(connector)) {
+ dev_err(ddev->dev, "bridge_connector create failed\n");
+ return PTR_ERR(connector);
+ }
+
+ ret = drm_connector_attach_encoder(connector, priv->encoder);
+ if (ret) {
+ dev_err(ddev->dev, "attaching encoder to connector failed\n");
+ return ret;
+ }
+ priv->connector = connector;
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread