* [PATCH v4 01/14] dt-bindings: display: ti,am65x-dss: Add AM62P DSS
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 02/14] drm/tidss: Add helper to identify the AM65x OLDI video port Tomi Valkeinen
` (12 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
TI's AM62P, J722S and AM67A SoCs contain same implementation of the
display subsystem (DSS). There are two instances of the DSS (DSS0 and
DSS1), each with two video ports (VP) and two video planes.
Additionally the SoCs contain two OLDI TXes (OLDI0 and OLDI1), a MIPI
DSI TX and a MIPI DPI output path.
DSS0 supports:
- VP0: OLDI0 in single-link mode, or OLDI0 and OLDI1 in dual-link or
clone mode.
- VP1: DPI
DSS1 supports:
- VP0: OLDI1 in single-link mode, or DPI
- VP1: DPI or DSI
The DSI is only connected to VP1 of DSS1, but OLDI and DPI are shared
between the DSS instances. Thus only a single VP can output to DPI, and
a single VP can use an OLDI block. Note that in single-link
configuration OLDI0 can be used by DSS0, and at the same time OLDI1 can
be used by DSS1.
The DSS IP itself is compatible with older SoCs. While we could use
"ti,am625-dss" compatible string, we add a new one "ti,am62p-dss" to be
on the safe side in case the driver needs to do something special for
the dual-DSS case in the future.
Original patch by Swamil Jain <s-jain1@ti.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
.../bindings/display/ti/ti,am65x-dss.yaml | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index db7d3d216b64..5ddee18b4982 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -28,11 +28,38 @@ description: |
On AM62A7, the first VP is tied off in the SoC, and the second VP is routed to
external MIPI DPI pins.
+ AM62P SoC contains two instances of the DSS:
+ On AM62P DSS0, the first VP is connected to two OLDI TX instances (the second
+ TX shared with DSS1), the second VP to external MIPI DPI pins (shared with
+ DSS1).
+ On AM62P DSS1, the first VP is connected either to the second OLDI TX, or
+ external MIPI DPI pins. The second VP is connected to either the external MIPI
+ DPI pins or a Cadence DSI TX.
+
+ An important note about OLDIs on AM62P:
+
+ There are two OLDI hardware blocks. Each OLDI has certain configuration that
+ has to be done before it can be used. The OLDI blocks get this configuration
+ directly from the DSS block, via DSS registers. However, as a single OLDI
+ block can be used either with DSS0 or DSS1, the source for the configuration
+ changes according to a mux. This mux is set according to the OLDI
+ configuration registers in DSS0. Thus the OLDI control paths change at
+ runtime, and it is not obvious how to structure this in the DT bindings.
+
+ The solution used here is that each DSS node contains the OLDI nodes that can
+ be used with that DSS. Thus the DSS0 node has two OLDI child nodes, OLDI0 and
+ OLDI1, and the DSS1 node has one OLDI child node, OLDI1, so three OLDI DT
+ nodes in total. The two OLDI1 nodes thus refer to the same piece of hardware,
+ and they cannot be used at the same time. The selection which OLDI nodes to
+ use are chosen in the board dts files, so assuming the dts files are correct,
+ no resource conflict can happen.
+
properties:
compatible:
enum:
- ti,am625-dss
- ti,am62a7-dss
+ - ti,am62p-dss
- ti,am65x-dss
reg:
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 02/14] drm/tidss: Add helper to identify the AM65x OLDI video port
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 01/14] dt-bindings: display: ti,am65x-dss: Add AM62P DSS Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 03/14] drm/tidss: Stop using vp_bus_type for directly connected panels Tomi Valkeinen
` (11 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
On AM65x the OLDI TX is modeled as a part of the DSS, not as a separate
bridge as the newer SoCs do, and is fed by the first video port. To
handle the AM65x OLDI, we check for it in multiple places using the
feat's vp_bus_type.
However, vp_bus_type is problematic concept and should be removed, so
this commit adds a helper function to check for the AM65x OLDI by
looking at the DSS subrevision and videoport number.
No functional change.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_dispc.c | 8 ++++----
drivers/gpu/drm/tidss/tidss_dispc.h | 7 +++++++
drivers/gpu/drm/tidss/tidss_kms.c | 2 +-
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
index e516f493d6d9..efdabf046d64 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -1034,7 +1034,7 @@ int dispc_vp_bus_check(struct dispc_device *dispc, u32 hw_videoport,
return -EINVAL;
}
- if (dispc->feat->vp_bus_type[hw_videoport] != DISPC_VP_OLDI_AM65X &&
+ if (!dispc_vp_is_am65x_oldi(dispc->feat, hw_videoport) &&
fmt->is_oldi_fmt) {
drm_dbg(dev, "%s: %s is not OLDI-port\n",
__func__, dispc->feat->vp_name[hw_videoport]);
@@ -1143,7 +1143,7 @@ void dispc_vp_prepare(struct dispc_device *dispc, u32 hw_videoport,
if (WARN_ON(!fmt))
return;
- if (dispc->feat->vp_bus_type[hw_videoport] == DISPC_VP_OLDI_AM65X) {
+ if (dispc_vp_is_am65x_oldi(dispc->feat, hw_videoport)) {
dispc_am65x_oldi_tx_power(dispc, true);
dispc_enable_am65x_oldi(dispc, hw_videoport, fmt);
@@ -1186,7 +1186,7 @@ void dispc_vp_prepare(struct dispc_device *dispc, u32 hw_videoport,
align = true;
/* always use DE_HIGH for OLDI */
- if (dispc->feat->vp_bus_type[hw_videoport] == DISPC_VP_OLDI_AM65X)
+ if (dispc_vp_is_am65x_oldi(dispc->feat, hw_videoport))
ieo = false;
dispc_vp_write(dispc, hw_videoport, DISPC_VP_POL_FREQ,
@@ -1229,7 +1229,7 @@ void dispc_vp_unprepare(struct dispc_device *dispc, u32 hw_videoport)
VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 0,
DISPC_VP_CONTROL_DPIENABLE_MASK);
- if (dispc->feat->vp_bus_type[hw_videoport] == DISPC_VP_OLDI_AM65X) {
+ if (dispc_vp_is_am65x_oldi(dispc->feat, hw_videoport)) {
dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, 0);
dispc_am65x_oldi_tx_power(dispc, false);
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h
index df3daccf3f31..3dff391d3fec 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc.h
@@ -96,6 +96,13 @@ struct dispc_features {
bool has_vp_control_dpienable;
};
+/* On AM65x the OLDI TX is a part of the DSS, on the first video port */
+static inline bool dispc_vp_is_am65x_oldi(const struct dispc_features *feat,
+ u32 hw_videoport)
+{
+ return feat->subrev == DISPC_AM65X && hw_videoport == 0;
+}
+
extern const struct dispc_features dispc_k2g_feats;
extern const struct dispc_features dispc_am625_feats;
extern const struct dispc_features dispc_am62a7_feats;
diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c
index eefe2221bdde..e55e7532e2f7 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.c
+++ b/drivers/gpu/drm/tidss/tidss_kms.c
@@ -175,7 +175,7 @@ static bool tidss_is_dpi_output(struct tidss_device *tidss, u32 hw_videoport,
* for the OLDI TX on AM65x, we cannot detect this from the DT data, and
* have to special-case it here.
*/
- if (tidss->feat->subrev == DISPC_AM65X && hw_videoport == 0)
+ if (dispc_vp_is_am65x_oldi(tidss->feat, hw_videoport))
return false;
if (!bridge)
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 03/14] drm/tidss: Stop using vp_bus_type for directly connected panels
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 01/14] dt-bindings: display: ti,am65x-dss: Add AM62P DSS Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 02/14] drm/tidss: Add helper to identify the AM65x OLDI video port Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 04/14] drm/tidss: Drop the tied off video port check from mode validation Tomi Valkeinen
` (10 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
When a panel is connected directly to a video port,
tidss_dispc_modeset_init() sets the encoder and connector types using
the 'vp_bus_type' feat. DISPC_VP_DPI selects DPI and DISPC_VP_OLDI_AM65X
selects LVDS. Any other type triggers a WARN and fails the probe.
vp_bus_type is problematic and is going to be removed. Change
tidss_dispc_modeset_init() to use dispc_vp_is_am65x_oldi() for detecting
the OLDI case, and default to DPI.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_kms.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c
index e55e7532e2f7..8b9c5fa96e47 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.c
+++ b/drivers/gpu/drm/tidss/tidss_kms.c
@@ -232,19 +232,12 @@ static int tidss_dispc_modeset_init(struct tidss_device *tidss)
dev_dbg(dev, "Setting up panel for port %d\n", i);
- switch (feat->vp_bus_type[i]) {
- case DISPC_VP_OLDI_AM65X:
+ if (dispc_vp_is_am65x_oldi(feat, i)) {
enc_type = DRM_MODE_ENCODER_LVDS;
conn_type = DRM_MODE_CONNECTOR_LVDS;
- break;
- case DISPC_VP_DPI:
+ } else {
enc_type = DRM_MODE_ENCODER_DPI;
conn_type = DRM_MODE_CONNECTOR_DPI;
- break;
- default:
- WARN_ON(1);
- ret = -EINVAL;
- goto put_panel;
}
if (panel->connector_type != conn_type) {
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 04/14] drm/tidss: Drop the tied off video port check from mode validation
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (2 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 03/14] drm/tidss: Stop using vp_bus_type for directly connected panels Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 05/14] drm/tidss: Remove the unused vp_bus_type feat Tomi Valkeinen
` (9 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
dispc_vp_mode_valid() WARNs and rejects every mode on a video port that
is marked as DISPC_VP_TIED_OFF in the 'vp_bus_type' feat.
The check is redundant, as nothing in the DT will be connected to the
tied off VP, and thus the driver can never do a mode_valid call for it.
Remove the check, and rely on the DT to be correct.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_dispc.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
index efdabf046d64..8c537280faf5 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -1342,12 +1342,6 @@ enum drm_mode_status dispc_vp_mode_valid(struct dispc_device *dispc,
const struct drm_display_mode *mode)
{
u32 hsw, hfp, hbp, vsw, vfp, vbp;
- enum dispc_vp_bus_type bus_type;
-
- bus_type = dispc->feat->vp_bus_type[hw_videoport];
-
- if (WARN_ON(bus_type == DISPC_VP_TIED_OFF))
- return MODE_BAD;
if (mode->hdisplay > 4096)
return MODE_BAD;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 05/14] drm/tidss: Remove the unused vp_bus_type feat
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (3 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 04/14] drm/tidss: Drop the tied off video port check from mode validation Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 06/14] drm/tidss: oldi: Drop unnecessary forward declaration Tomi Valkeinen
` (8 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
Nothing reads the 'vp_bus_type' feat any more, and can be removed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_dispc.c | 9 ---------
drivers/gpu/drm/tidss/tidss_dispc.h | 9 ---------
2 files changed, 18 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
index 8c537280faf5..028cf78df3fe 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -90,7 +90,6 @@ const struct dispc_features dispc_k2g_feats = {
.vp_name = { "vp1" },
.ovr_name = { "ovr1" },
.vpclk_name = { "vp1" },
- .vp_bus_type = { DISPC_VP_DPI },
.vp_feat = { .color = {
.has_ctm = true,
@@ -167,7 +166,6 @@ const struct dispc_features dispc_am65x_feats = {
.vp_name = { "vp1", "vp2" },
.ovr_name = { "ovr1", "ovr2" },
.vpclk_name = { "vp1", "vp2" },
- .vp_bus_type = { DISPC_VP_OLDI_AM65X, DISPC_VP_DPI },
.vp_feat = { .color = {
.has_ctm = true,
@@ -262,9 +260,6 @@ const struct dispc_features dispc_j721e_feats = {
.vp_name = { "vp1", "vp2", "vp3", "vp4" },
.ovr_name = { "ovr1", "ovr2", "ovr3", "ovr4" },
.vpclk_name = { "vp1", "vp2", "vp3", "vp4" },
- /* Currently hard coded VP routing (see dispc_initial_config()) */
- .vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI,
- DISPC_VP_INTERNAL, DISPC_VP_DPI, },
.vp_feat = { .color = {
.has_ctm = true,
.gamma_size = 1024,
@@ -328,7 +323,6 @@ const struct dispc_features dispc_am625_feats = {
.vp_name = { "vp1", "vp2" },
.ovr_name = { "ovr1", "ovr2" },
.vpclk_name = { "vp1", "vp2" },
- .vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI },
.vp_feat = { .color = {
.has_ctm = true,
@@ -384,8 +378,6 @@ const struct dispc_features dispc_am62a7_feats = {
.vp_name = { "vp1", "vp2" },
.ovr_name = { "ovr1", "ovr2" },
.vpclk_name = { "vp1", "vp2" },
- /* VP1 of the DSS in AM62A7 SoC is tied off internally */
- .vp_bus_type = { DISPC_VP_TIED_OFF, DISPC_VP_DPI },
.vp_feat = { .color = {
.has_ctm = true,
@@ -422,7 +414,6 @@ const struct dispc_features dispc_am62l_feats = {
.vp_name = { "vp1" },
.ovr_name = { "ovr1" },
.vpclk_name = { "vp1" },
- .vp_bus_type = { DISPC_VP_DPI },
.vp_feat = { .color = {
.has_ctm = true,
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h
index 3dff391d3fec..ebaf559d56e5 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc.h
@@ -59,14 +59,6 @@ struct dispc_errata {
bool i2000; /* DSS Does Not Support YUV Pixel Data Formats */
};
-enum dispc_vp_bus_type {
- DISPC_VP_DPI, /* DPI output */
- DISPC_VP_OLDI_AM65X, /* OLDI (LVDS) output for AM65x DSS */
- DISPC_VP_INTERNAL, /* SoC internal routing */
- DISPC_VP_TIED_OFF, /* Tied off / Unavailable */
- DISPC_VP_MAX_BUS_TYPE,
-};
-
enum dispc_dss_subrevision {
DISPC_K2G,
DISPC_AM625,
@@ -87,7 +79,6 @@ struct dispc_features {
const char *vp_name[TIDSS_MAX_PORTS]; /* Should match dt reg names */
const char *ovr_name[TIDSS_MAX_PORTS]; /* Should match dt reg names */
const char *vpclk_name[TIDSS_MAX_PORTS]; /* Should match dt clk names */
- const enum dispc_vp_bus_type vp_bus_type[TIDSS_MAX_PORTS];
struct tidss_vp_feat vp_feat;
u32 num_vids;
struct dispc_vid_info vid_info[TIDSS_MAX_PLANES];
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 06/14] drm/tidss: oldi: Drop unnecessary forward declaration
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (4 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 05/14] drm/tidss: Remove the unused vp_bus_type feat Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 07/14] drm/tidss: oldi: Fix wrong return value from tidss_oldi_mode_valid() Tomi Valkeinen
` (7 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
Nothing needs "struct tidss_oldi" in tidss_oldi.h, so drop the forward
declaration.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_oldi.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.h b/drivers/gpu/drm/tidss/tidss_oldi.h
index a361e6dbfce3..ef9597fe5409 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.h
+++ b/drivers/gpu/drm/tidss/tidss_oldi.h
@@ -10,8 +10,6 @@
#include "tidss_drv.h"
-struct tidss_oldi;
-
/* OLDI PORTS */
#define OLDI_INPUT_PORT 0
#define OLDI_OUTPUT_PORT 1
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 07/14] drm/tidss: oldi: Fix wrong return value from tidss_oldi_mode_valid()
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (5 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 06/14] drm/tidss: oldi: Drop unnecessary forward declaration Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 08/14] drm/tidss: oldi: Fix serial clock reference leak Tomi Valkeinen
` (6 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
tidss_oldi_mode_valid() returns 'enum drm_mode_status', but the current
code returns -EINVAL or 0.
Fix it to return proper enum values.
Fixes: 86db652fc22f ("drm/tidss: Move OLDI mode validation to OLDI bridge mode_valid hook")
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_oldi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c
index 82b059f85244..ae27ebc7306e 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.c
+++ b/drivers/gpu/drm/tidss/tidss_oldi.c
@@ -346,9 +346,9 @@ tidss_oldi_mode_valid(struct drm_bridge *bridge,
* we use the same 5% check here.
*/
if (dispc_pclk_diff(mode->clock * 7 * 1000, round_clock) > 5)
- return -EINVAL;
+ return MODE_CLOCK_RANGE;
- return 0;
+ return MODE_OK;
}
static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = {
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 08/14] drm/tidss: oldi: Fix serial clock reference leak
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (6 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 07/14] drm/tidss: oldi: Fix wrong return value from tidss_oldi_mode_valid() Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 09/14] drm/tidss: oldi: Fix cleanup on a failed init Tomi Valkeinen
` (5 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
tidss_oldi_init() gets the OLDI serial clock with of_clk_get_by_name()
and never puts it. A clock reference leaks each time tidss unbinds, and
each time its probe fails or defers after the OLDI setup.
Get the clock with devm_get_clk_from_child() instead.
Fixes: 7246e0929945 ("drm/tidss: Add OLDI bridge support")
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_oldi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c
index ae27ebc7306e..506507e83112 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.c
+++ b/drivers/gpu/drm/tidss/tidss_oldi.c
@@ -609,7 +609,8 @@ int tidss_oldi_init(struct tidss_device *tidss)
goto err_put_node;
}
- oldi->serial = of_clk_get_by_name(child, "serial");
+ oldi->serial = devm_get_clk_from_child(tidss->dev, child,
+ "serial");
if (IS_ERR(oldi->serial)) {
ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial),
"OLDI%u: Failed to get serial clock.\n",
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 09/14] drm/tidss: oldi: Fix cleanup on a failed init
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (7 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 08/14] drm/tidss: oldi: Fix serial clock reference leak Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 10/14] drm/tidss: oldi: Move the setup of one OLDI TX to its own function Tomi Valkeinen
` (4 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
tidss_oldi_init() registers a bridge for each OLDI TX in turn. If a later
OLDI TX fails, the bridges registered for the earlier ones are not
removed.
Fix this by calling tidss_oldi_deinit() in the error path.
Fixes: 7246e0929945 ("drm/tidss: Add OLDI bridge support")
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_oldi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c
index 506507e83112..7344d86e1f13 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.c
+++ b/drivers/gpu/drm/tidss/tidss_oldi.c
@@ -638,5 +638,6 @@ int tidss_oldi_init(struct tidss_device *tidss)
err_put_node:
of_node_put(child);
of_node_put(oldi_parent);
+ tidss_oldi_deinit(tidss);
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 10/14] drm/tidss: oldi: Move the setup of one OLDI TX to its own function
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (8 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 09/14] drm/tidss: oldi: Fix cleanup on a failed init Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 11/14] drm/tidss: oldi: Add power domain support Tomi Valkeinen
` (3 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
tidss_oldi_init() sets up each OLDI TX inside its loop over the OLDI TX
nodes, which is not a few lines of code and indents quite deeply. Clean
up the code by separating the setup of a single OLDI TX into its own
function.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_oldi.c | 264 +++++++++++++++++++------------------
1 file changed, 138 insertions(+), 126 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c
index 7344d86e1f13..5552c1c51074 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.c
+++ b/drivers/gpu/drm/tidss/tidss_oldi.c
@@ -479,155 +479,167 @@ void tidss_oldi_deinit(struct tidss_device *tidss)
}
}
-int tidss_oldi_init(struct tidss_device *tidss)
+static int tidss_oldi_init_one(struct tidss_device *tidss,
+ struct device_node *oldi_tx)
{
struct tidss_oldi *oldi;
- struct device_node *child;
struct drm_bridge *bridge;
u32 parent_vp, oldi_instance;
int companion_instance = -1;
enum tidss_oldi_link_type link_type = OLDI_MODE_UNSUPPORTED;
- struct device_node *oldi_parent;
- int ret = 0;
-
- tidss->num_oldis = 0;
-
- oldi_parent = of_get_child_by_name(tidss->dev->of_node, "oldi-transmitters");
- if (!oldi_parent)
- /* Return gracefully */
- return 0;
+ int ret;
- for_each_available_child_of_node(oldi_parent, child) {
- ret = get_parent_dss_vp(child, &parent_vp);
- if (ret) {
- if (ret == -ENODEV) {
- /*
- * ENODEV means that this particular OLDI node
- * is not connected with the DSS, which is not
- * a harmful case. There could be another OLDI
- * which may still be connected.
- * Continue to search for that.
- */
- continue;
- }
- goto err_put_node;
+ ret = get_parent_dss_vp(oldi_tx, &parent_vp);
+ if (ret) {
+ if (ret == -ENODEV) {
+ /*
+ * ENODEV means that this particular OLDI node
+ * is not connected with the DSS, which is not
+ * a harmful case. There could be another OLDI
+ * which may still be connected.
+ * Continue to search for that.
+ */
+ return 0;
}
+ return ret;
+ }
- ret = of_property_read_u32(child, "reg", &oldi_instance);
- if (ret)
- goto err_put_node;
+ ret = of_property_read_u32(oldi_tx, "reg", &oldi_instance);
+ if (ret)
+ return ret;
+ /*
+ * Now that it's confirmed that OLDI is connected with DSS,
+ * let's continue getting the OLDI sinks ahead and other OLDI
+ * properties.
+ */
+ bridge = devm_drm_of_get_bridge(tidss->dev, oldi_tx,
+ OLDI_OUTPUT_PORT, 0);
+ if (IS_ERR(bridge)) {
/*
- * Now that it's confirmed that OLDI is connected with DSS,
- * let's continue getting the OLDI sinks ahead and other OLDI
- * properties.
+ * Either there was no OLDI sink in the devicetree, or
+ * the OLDI sink has not been added yet. In any case,
+ * return.
+ * We don't want to have an OLDI node connected to DSS
+ * but not to any sink.
*/
- bridge = devm_drm_of_get_bridge(tidss->dev, child,
- OLDI_OUTPUT_PORT, 0);
- if (IS_ERR(bridge)) {
- /*
- * Either there was no OLDI sink in the devicetree, or
- * the OLDI sink has not been added yet. In any case,
- * return.
- * We don't want to have an OLDI node connected to DSS
- * but not to any sink.
- */
- ret = dev_err_probe(tidss->dev, PTR_ERR(bridge),
- "no panel/bridge for OLDI%u.\n",
+ ret = dev_err_probe(tidss->dev, PTR_ERR(bridge),
+ "no panel/bridge for OLDI%u.\n",
+ oldi_instance);
+ return ret;
+ }
+
+ link_type = get_oldi_mode(oldi_tx, &companion_instance);
+ if (link_type == OLDI_MODE_UNSUPPORTED) {
+ ret = dev_err_probe(tidss->dev, -EINVAL,
+ "OLDI%u: Unsupported OLDI connection.\n",
+ oldi_instance);
+ return ret;
+ } else if ((link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) ||
+ (link_type == OLDI_MODE_CLONE_SINGLE_LINK)) {
+ /*
+ * The OLDI driver cannot support OLDI clone mode
+ * properly at present.
+ * The clone mode requires 2 working encoder-bridge
+ * pipelines, generating from the same crtc. The DRM
+ * framework does not support this at present. If
+ * there were to be, say, 2 OLDI sink bridges each
+ * connected to an OLDI TXes, they couldn't both be
+ * supported simultaneously.
+ * This driver still has some code pertaining to OLDI
+ * clone mode configuration in DSS hardware for future,
+ * when there is a better infrastructure in the DRM
+ * framework to support 2 encoder-bridge pipelines
+ * simultaneously.
+ * Till that time, this driver shall error out if it
+ * detects a clone mode configuration.
+ */
+ ret = dev_err_probe(tidss->dev, -EOPNOTSUPP,
+ "The OLDI driver does not support Clone Mode at present.\n");
+ return ret;
+ } else if (link_type == OLDI_MODE_SECONDARY_DUAL_LINK) {
+ /*
+ * This is the secondary OLDI node, which serves as a
+ * companion to the primary OLDI, when it is configured
+ * for the dual-link mode. Since the primary OLDI will
+ * be a part of bridge chain, no need to put this one
+ * too. Continue onto the next OLDI node.
+ */
+ return 0;
+ }
+
+ oldi = devm_drm_bridge_alloc(tidss->dev, struct tidss_oldi, bridge,
+ &tidss_oldi_bridge_funcs);
+ if (IS_ERR(oldi)) {
+ ret = PTR_ERR(oldi);
+ return ret;
+ }
+
+ oldi->parent_vp = parent_vp;
+ oldi->oldi_instance = oldi_instance;
+ oldi->companion_instance = companion_instance;
+ oldi->link_type = link_type;
+ oldi->dev = tidss->dev;
+ oldi->next_bridge = bridge;
+
+ /*
+ * Only the primary OLDI needs to reference the io-ctrl system
+ * registers, and the serial clock.
+ * We don't require a check for secondary OLDI in dual-link mode
+ * because the driver will not create a drm_bridge instance.
+ * But the driver will need to create a drm_bridge instance,
+ * for secondary OLDI in clone mode (once it is supported).
+ */
+ if (link_type != OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) {
+ oldi->io_ctrl = syscon_regmap_lookup_by_phandle(oldi_tx,
+ "ti,oldi-io-ctrl");
+ if (IS_ERR(oldi->io_ctrl)) {
+ ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->io_ctrl),
+ "OLDI%u: syscon_regmap_lookup_by_phandle failed.\n",
oldi_instance);
- goto err_put_node;
+ return ret;
}
- link_type = get_oldi_mode(child, &companion_instance);
- if (link_type == OLDI_MODE_UNSUPPORTED) {
- ret = dev_err_probe(tidss->dev, -EINVAL,
- "OLDI%u: Unsupported OLDI connection.\n",
+ oldi->serial = devm_get_clk_from_child(tidss->dev, oldi_tx,
+ "serial");
+ if (IS_ERR(oldi->serial)) {
+ ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial),
+ "OLDI%u: Failed to get serial clock.\n",
oldi_instance);
- goto err_put_node;
- } else if ((link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) ||
- (link_type == OLDI_MODE_CLONE_SINGLE_LINK)) {
- /*
- * The OLDI driver cannot support OLDI clone mode
- * properly at present.
- * The clone mode requires 2 working encoder-bridge
- * pipelines, generating from the same crtc. The DRM
- * framework does not support this at present. If
- * there were to be, say, 2 OLDI sink bridges each
- * connected to an OLDI TXes, they couldn't both be
- * supported simultaneously.
- * This driver still has some code pertaining to OLDI
- * clone mode configuration in DSS hardware for future,
- * when there is a better infrastructure in the DRM
- * framework to support 2 encoder-bridge pipelines
- * simultaneously.
- * Till that time, this driver shall error out if it
- * detects a clone mode configuration.
- */
- ret = dev_err_probe(tidss->dev, -EOPNOTSUPP,
- "The OLDI driver does not support Clone Mode at present.\n");
- goto err_put_node;
- } else if (link_type == OLDI_MODE_SECONDARY_DUAL_LINK) {
- /*
- * This is the secondary OLDI node, which serves as a
- * companion to the primary OLDI, when it is configured
- * for the dual-link mode. Since the primary OLDI will
- * be a part of bridge chain, no need to put this one
- * too. Continue onto the next OLDI node.
- */
- continue;
+ return ret;
}
+ }
- oldi = devm_drm_bridge_alloc(tidss->dev, struct tidss_oldi, bridge,
- &tidss_oldi_bridge_funcs);
- if (IS_ERR(oldi)) {
- ret = PTR_ERR(oldi);
- goto err_put_node;
- }
+ /* Register the bridge. */
+ oldi->bridge.of_node = oldi_tx;
+ oldi->bridge.driver_private = oldi;
- oldi->parent_vp = parent_vp;
- oldi->oldi_instance = oldi_instance;
- oldi->companion_instance = companion_instance;
- oldi->link_type = link_type;
- oldi->dev = tidss->dev;
- oldi->next_bridge = bridge;
+ tidss->oldis[tidss->num_oldis++] = oldi;
+ tidss->is_ext_vp_clk[oldi->parent_vp] = true;
+ oldi->tidss = tidss;
- /*
- * Only the primary OLDI needs to reference the io-ctrl system
- * registers, and the serial clock.
- * We don't require a check for secondary OLDI in dual-link mode
- * because the driver will not create a drm_bridge instance.
- * But the driver will need to create a drm_bridge instance,
- * for secondary OLDI in clone mode (once it is supported).
- */
- if (link_type != OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) {
- oldi->io_ctrl = syscon_regmap_lookup_by_phandle(child,
- "ti,oldi-io-ctrl");
- if (IS_ERR(oldi->io_ctrl)) {
- ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->io_ctrl),
- "OLDI%u: syscon_regmap_lookup_by_phandle failed.\n",
- oldi_instance);
- goto err_put_node;
- }
-
- oldi->serial = devm_get_clk_from_child(tidss->dev, child,
- "serial");
- if (IS_ERR(oldi->serial)) {
- ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial),
- "OLDI%u: Failed to get serial clock.\n",
- oldi_instance);
- goto err_put_node;
- }
- }
+ drm_bridge_add(&oldi->bridge);
+
+ return 0;
+}
+
+int tidss_oldi_init(struct tidss_device *tidss)
+{
+ struct device_node *child;
+ struct device_node *oldi_parent;
+ int ret = 0;
- /* Register the bridge. */
- oldi->bridge.of_node = child;
- oldi->bridge.driver_private = oldi;
+ tidss->num_oldis = 0;
- tidss->oldis[tidss->num_oldis++] = oldi;
- tidss->is_ext_vp_clk[oldi->parent_vp] = true;
- oldi->tidss = tidss;
+ oldi_parent = of_get_child_by_name(tidss->dev->of_node, "oldi-transmitters");
+ if (!oldi_parent)
+ /* Return gracefully */
+ return 0;
- drm_bridge_add(&oldi->bridge);
+ for_each_available_child_of_node(oldi_parent, child) {
+ ret = tidss_oldi_init_one(tidss, child);
+ if (ret)
+ goto err_put_node;
}
of_node_put(child);
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 11/14] drm/tidss: oldi: Add power domain support
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (9 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 10/14] drm/tidss: oldi: Move the setup of one OLDI TX to its own function Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 12/14] drm/tidss: Add support for AM62P display subsystem Tomi Valkeinen
` (2 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
The OLDI TXes on AM62P and J722S have power domains of their own,
described in the DT, unlike the earlier SoCs. The OLDI TX nodes are not
real devices, so the driver core does not attach these power domains,
and nothing in the core turns them on.
Add support to attach the PDs with dev_pm_domain_attach_by_node(), and
manage the power state of the returned virtual devices with runtime PM
functions.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_oldi.c | 88 ++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c
index 5552c1c51074..df2326db3302 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.c
+++ b/drivers/gpu/drm/tidss/tidss_oldi.c
@@ -10,6 +10,8 @@
#include <linux/of_graph.h>
#include <linux/mfd/syscon.h>
#include <linux/media-bus-format.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <drm/drm_atomic_helper.h>
@@ -35,6 +37,12 @@ struct tidss_oldi {
struct clk *serial;
struct regmap *io_ctrl;
+
+ /*
+ * The power domains of this OLDI TX and, in dual-link mode, of its
+ * companion. NULL for an OLDI TX without a power domain of its own.
+ */
+ struct device *pd_devs[2];
};
struct oldi_bus_format {
@@ -238,6 +246,22 @@ static int tidss_oldi_atomic_check(struct drm_bridge *bridge,
return 0;
}
+static void tidss_oldi_power_get(struct tidss_oldi *oldi)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(oldi->pd_devs); i++) {
+ if (oldi->pd_devs[i])
+ WARN_ON(pm_runtime_get_sync(oldi->pd_devs[i]) < 0);
+ }
+}
+
+static void tidss_oldi_power_put(struct tidss_oldi *oldi)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(oldi->pd_devs); i++) {
+ if (oldi->pd_devs[i])
+ pm_runtime_put(oldi->pd_devs[i]);
+ }
+}
+
static void tidss_oldi_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_atomic_commit *state)
{
@@ -251,6 +275,8 @@ static void tidss_oldi_atomic_pre_enable(struct drm_bridge *bridge,
if (oldi->link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK)
return;
+ tidss_oldi_power_get(oldi);
+
connector = drm_atomic_get_new_connector_for_encoder(state,
bridge->encoder);
if (WARN_ON(!connector))
@@ -296,6 +322,8 @@ static void tidss_oldi_atomic_post_disable(struct drm_bridge *bridge,
/* Clear OLDI Config */
tidss_disable_oldi(oldi->tidss, oldi->parent_vp);
+
+ tidss_oldi_power_put(oldi);
}
#define MAX_INPUT_SEL_FORMATS 1
@@ -468,6 +496,60 @@ static int get_parent_dss_vp(struct device_node *oldi_tx, u32 *parent_vp)
return -ENODEV;
}
+static void tidss_oldi_detach_pd(void *data)
+{
+ struct device *pd_dev = data;
+
+ dev_pm_domain_detach(pd_dev, true);
+}
+
+static struct device *tidss_oldi_create_pd_dev(struct tidss_device *tidss,
+ struct device_node *oldi_tx)
+{
+ struct device *dev;
+ int ret;
+
+ dev = dev_pm_domain_attach_by_node(tidss->dev, oldi_tx, 0);
+ if (IS_ERR_OR_NULL(dev))
+ return dev;
+
+ ret = devm_add_action_or_reset(tidss->dev, tidss_oldi_detach_pd, dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return dev;
+}
+
+static int tidss_oldi_create_pd_devs(struct tidss_device *tidss,
+ struct tidss_oldi *oldi,
+ struct device_node *oldi_tx)
+{
+ struct device_node *companion;
+ struct device *pd_dev;
+
+ pd_dev = tidss_oldi_create_pd_dev(tidss, oldi_tx);
+ if (IS_ERR(pd_dev))
+ return PTR_ERR(pd_dev);
+
+ oldi->pd_devs[0] = pd_dev;
+
+ if (oldi->companion_instance < 0)
+ return 0;
+
+ companion = of_parse_phandle(oldi_tx, "ti,companion-oldi", 0);
+ if (!companion)
+ return -EINVAL;
+
+ pd_dev = tidss_oldi_create_pd_dev(tidss, companion);
+ of_node_put(companion);
+ if (IS_ERR(pd_dev))
+ return PTR_ERR(pd_dev);
+
+ oldi->pd_devs[1] = pd_dev;
+
+ return 0;
+}
+
void tidss_oldi_deinit(struct tidss_device *tidss)
{
for (int i = 0; i < tidss->num_oldis; i++) {
@@ -610,6 +692,12 @@ static int tidss_oldi_init_one(struct tidss_device *tidss,
}
}
+ ret = tidss_oldi_create_pd_devs(tidss, oldi, oldi_tx);
+ if (ret)
+ return dev_err_probe(tidss->dev, ret,
+ "OLDI%u: Failed to set up the power domains.\n",
+ oldi_instance);
+
/* Register the bridge. */
oldi->bridge.of_node = oldi_tx;
oldi->bridge.driver_private = oldi;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 12/14] drm/tidss: Add support for AM62P display subsystem
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (10 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 11/14] drm/tidss: oldi: Add power domain support Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:18 ` [PATCH v4 13/14] arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS Tomi Valkeinen
2026-10-29 10:19 ` [PATCH v4 14/14] arm64: dts: ti: beagley-ai: Enable HDMI display and audio Tomi Valkeinen
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
From: Swamil Jain <s-jain1@ti.com>
The DSS controller on TI's AM62P SoC features two instances of the TI
DSS. Each DSS instance supports two video ports, similar to the DSS
controller found on the TI AM62X SoC. This allows three independent
video streams to be supported: OLDI, DPI, and DSI.
Since the DSS instances on AM62P are architecturally similar to those
on the AM62X DSS controller, the existing dispc_am625_feats
configuration can be reused for the AM62P DSS support.
This commit adds the necessary device tree compatibility entry for
"ti,am62p-dss" in the tidss driver, pointing to dispc_am625_feats,
thereby enabling DSS support on AM62P devices.
Signed-off-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 44b0b009c29a..8e3cbfb5ef87 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -240,6 +240,7 @@ static const struct of_device_id tidss_of_table[] = {
{ .compatible = "ti,am625-dss", .data = &dispc_am625_feats, },
{ .compatible = "ti,am62a7-dss", .data = &dispc_am62a7_feats, },
{ .compatible = "ti,am62l-dss", .data = &dispc_am62l_feats, },
+ { .compatible = "ti,am62p-dss", .data = &dispc_am625_feats, },
{ .compatible = "ti,am65x-dss", .data = &dispc_am65x_feats, },
{ .compatible = "ti,j721e-dss", .data = &dispc_j721e_feats, },
{ }
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 13/14] arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (11 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 12/14] drm/tidss: Add support for AM62P display subsystem Tomi Valkeinen
@ 2026-10-29 10:18 ` Tomi Valkeinen
2026-10-29 10:28 ` sashiko-bot
2026-10-29 10:19 ` [PATCH v4 14/14] arm64: dts: ti: beagley-ai: Enable HDMI display and audio Tomi Valkeinen
13 siblings, 1 reply; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen, Jayesh Choudhary, Aradhya Bhatia
From: Jayesh Choudhary <j-choudhary@ti.com>
TI's AM62P and J722S SoCs support 2 display subsystems (DSS), DSS0 and
DSS1, each with two video ports (VP) and two video planes. The outputs
from the DSS VPs can be routed to two OLDI TXes (OLDI0, OLDI1), a DSI
TX, or parallel DPI output.
DSS0 supports:
- VP0: OLDI0 in single-link mode or OLDI0 and OLDI1 in dual-link or
clone mode.
- VP1: DPI
DSS1 supports:
- VP0: OLDI1 in single-link mode, or DPI
- VP1: DPI or DSI
The DSI is only connected to VP1 of DSS1, but OLDI and DPI are shared
between the DSS instances. Thus only a single VP can output to DPI, and
a single VP can use an OLDI block. Note that in single-link
configuration OLDI0 can be used by DSS0, and at the same time OLDI1 can
be used by DSS1.
Add the necessary nodes to k3-am62p-j722s-common-main.dtsi, including
DSS0, DSS1, OLDI0, OLDI1, DPHY and DSI.
An important note about OLDIs:
We have two OLDI hardware blocks. Each OLDI has certain configuration
that has to be done before it can be used. The OLDI blocks get this
configuration directly from the DSS block, via DSS registers. However,
as a single OLDI block can be used either with DSS0 or DSS1, the
source for the configuration changes according to (probably, this is
unclear) a DSS related clock mux.
So, afaics, when thinking about Linux device hierarchy wrt. control
busses, OLDI blocks are children of DSS blocks, and they reside in a
special DSS bus. And the OLDI parent changes according to the mux. As
far as I know, there is no way we can represent this in the DT.
Thus the solution used here (and in the driver) is that each DSS node
contains the OLDI nodes that can be used with that DSS. Thus the DSS0
node has two child nodes, OLDI0 and OLDI1, and the DSS1 node has one
child node, OLDI1. The OLDI1 nodes thus refer to the same piece of
hardware, and they cannot be used at the same time. The selection which
OLDI nodes to use are chosen in the board dts files, so assuming the dts
files are correct, no resource conflict can happen.
This is not a very nice solution, but the hardware doesn't make it easy
to have a clean solution, and, most importantly, this works.
Signed-off-by: Aradhya Bhatia <a-bhatia1@ti.com>
Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
Signed-off-by: Swamil Jain <s-jain1@ti.com>
[tomi.valkeinen: various fixes and improvements]
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
.../boot/dts/ti/k3-am62p-j722s-common-main.dtsi | 110 +++++++++++++++++++++
arch/arm64/boot/dts/ti/k3-am62p.dtsi | 16 +++
arch/arm64/boot/dts/ti/k3-j722s.dtsi | 16 +++
3 files changed, 142 insertions(+)
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
index f130c7cb998d..ae8db1bccadd 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
@@ -64,6 +64,11 @@ audio_refclk1: clock-controller@82e4 {
#clock-cells = <0>;
};
+ dss_oldi_io_ctrl: oldi-io-controller@8600 {
+ compatible = "ti,am625-dss-oldi-io-ctrl", "syscon";
+ reg = <0x8600 0x200>;
+ };
+
phy_gmii_sel: phy@4044 {
compatible = "ti,am654-phy-gmii-sel";
reg = <0x4044 0x8>;
@@ -1111,6 +1116,63 @@ dphy0: phy@30110000 {
status = "disabled";
};
+ dphy_tx0: phy@301c0000 {
+ compatible = "ti,j721e-dphy";
+ reg = <0x0 0x301c0000 0x0 0x1000>;
+ clocks = <&k3_clks 238 16>, <&k3_clks 238 1>;
+ clock-names = "psm", "pll_ref";
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 238 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 238 1>;
+ assigned-clock-parents = <&k3_clks 238 2>;
+ assigned-clock-rates = <25000000>;
+ status = "disabled";
+ };
+
+ dss0: dss@30200000 {
+ compatible = "ti,am62p-dss";
+ reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+ <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+ <0x00 0x30206000 0x00 0x1000>, /* vid */
+ <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+ <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
+ <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
+ <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI */
+ <0x00 0x30201000 0x00 0x1000>; /* common1 */
+ reg-names = "common", "vidl1", "vid",
+ "ovr1", "ovr2", "vp1", "vp2", "common1";
+ power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>; /* DSS0 */
+ clocks = <&k3_clks 186 6>,
+ <&dss0_vp1_clk>,
+ <&k3_clks 186 2>;
+ clock-names = "fck", "vp1", "vp2";
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ oldi-transmitters {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dss0_oldi0: oldi@0 {
+ reg = <0>;
+ clocks = <&k3_clks 186 0>;
+ clock-names = "serial";
+ ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+ power-domains = <&k3_pds 243 TI_SCI_PD_EXCLUSIVE>; /* OLDI0_VD */
+ status = "disabled";
+ };
+
+ dss0_oldi1: oldi@1 {
+ reg = <1>;
+ clocks = <&k3_clks 186 0>;
+ clock-names = "serial";
+ ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+ power-domains = <&k3_pds 244 TI_SCI_PD_EXCLUSIVE>; /* OLDI1_VD */
+ status = "disabled";
+ };
+ };
+ };
+
vpu: video-codec@30210000 {
compatible = "ti,j721s2-wave521c", "cnm,wave521c";
reg = <0x00 0x30210000 0x00 0x10000>;
@@ -1119,6 +1181,54 @@ vpu: video-codec@30210000 {
power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
};
+ dss1: dss@30220000 {
+ compatible = "ti,am62p-dss";
+ reg = <0x00 0x30220000 0x00 0x1000>, /* common */
+ <0x00 0x30222000 0x00 0x1000>, /* vidl1 */
+ <0x00 0x30226000 0x00 0x1000>, /* vid */
+ <0x00 0x30227000 0x00 0x1000>, /* ovr1 */
+ <0x00 0x30228000 0x00 0x1000>, /* ovr2 */
+ <0x00 0x3022a000 0x00 0x1000>, /* vp1: Used for DPI/OLDI */
+ <0x00 0x3022b000 0x00 0x1000>, /* vp2: Used for DPI/DSI */
+ <0x00 0x30221000 0x00 0x1000>; /* common1 */
+ reg-names = "common", "vidl1", "vid",
+ "ovr1", "ovr2", "vp1", "vp2", "common1";
+ power-domains = <&k3_pds 232 TI_SCI_PD_EXCLUSIVE>; /* DSS1 */
+ clocks = <&k3_clks 232 8>,
+ <&dss1_vp1_clk>,
+ <&k3_clks 232 4>;
+ clock-names = "fck", "vp1", "vp2";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ oldi-transmitters {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dss1_oldi1: oldi@1 {
+ reg = <1>;
+ clocks = <&k3_clks 232 0>;
+ clock-names = "serial";
+ ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+ power-domains = <&k3_pds 244 TI_SCI_PD_EXCLUSIVE>; /* OLDI1_VD */
+ status = "disabled";
+ };
+ };
+ };
+
+ dsi0: dsi@30500000 {
+ compatible = "ti,j721e-dsi";
+ reg = <0x0 0x30500000 0x0 0x100000>, <0x0 0x30270000 0x0 0x100>;
+ clocks = <&k3_clks 231 2>, <&k3_clks 231 5>;
+ clock-names = "dsi_p_clk", "dsi_sys_clk";
+ power-domains = <&k3_pds 231 TI_SCI_PD_EXCLUSIVE>;
+ interrupt-parent = <&gic500>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&dphy_tx0>;
+ phy-names = "dphy";
+ status = "disabled";
+ };
+
hsm: remoteproc@43c00000 {
compatible = "ti,hsm-m4fss";
/* contiguous regions but instantiated separately in HW */
diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
index 9d6266d6ddb8..074dc44ec049 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -144,6 +144,22 @@ cbass_wakeup: bus@b00000 {
};
};
+ dss0_vp1_clk: clock-divider-oldi-dss0 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 186 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
+ dss1_vp1_clk: clock-divider-oldi-dss1 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 232 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
#include "k3-am62p-j722s-common-thermal.dtsi"
};
diff --git a/arch/arm64/boot/dts/ti/k3-j722s.dtsi b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
index ca10c6904b69..dd04accfc518 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
@@ -228,6 +228,22 @@ cbass_wakeup: bus@b00000 {
};
};
+ dss0_vp1_clk: clock-divider-oldi-dss0 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 186 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
+ dss1_vp1_clk: clock-divider-oldi-dss1 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 232 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
#include "k3-am62p-j722s-common-thermal.dtsi"
};
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v4 13/14] arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS
2026-10-29 10:18 ` [PATCH v4 13/14] arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS Tomi Valkeinen
@ 2026-10-29 10:28 ` sashiko-bot
0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-10-29 10:28 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: devicetree, dri-devel, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] arm64: dts: ti: missing cbass_main ranges for DSS1, DSI0, and DPHY on AM62P
--
commit c11e92d40644178d0a46e3ee6a4f0ebbf85859f3
Author: Jayesh Choudhary <j-choudhary@ti.com>
arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS
This commit adds device tree nodes for DSS0, DSS1, OLDI0, OLDI1, DPHY, and
DSI to the shared k3-am62p-j722s-common-main.dtsi file along with the fixed
factor OLDI pixel clock dividers in k3-am62p.dtsi and k3-j722s.dtsi.
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
> index f130c7cb998d7..ae8db1bccadd5 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
[ ... ]
> @@ -1111,6 +1116,63 @@ dphy0: phy@30110000 {
> status = "disabled";
> };
>
> + dphy_tx0: phy@301c0000 {
> + compatible = "ti,j721e-dphy";
> + reg = <0x0 0x301c0000 0x0 0x1000>;
[ ... ]
> + };
[ ... ]
> @@ -1119,6 +1181,54 @@ vpu: video-codec@30210000 {
> power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
> };
>
> + dss1: dss@30220000 {
> + compatible = "ti,am62p-dss";
> + reg = <0x00 0x30220000 0x00 0x1000>, /* common */
> + <0x00 0x30222000 0x00 0x1000>, /* vidl1 */
> + <0x00 0x30226000 0x00 0x1000>, /* vid */
> + <0x00 0x30227000 0x00 0x1000>, /* ovr1 */
> + <0x00 0x30228000 0x00 0x1000>, /* ovr2 */
> + <0x00 0x3022a000 0x00 0x1000>, /* vp1: Used for DPI/OLDI */
> + <0x00 0x3022b000 0x00 0x1000>, /* vp2: Used for DPI/DSI */
> + <0x00 0x30221000 0x00 0x1000>; /* common1 */
[ ... ]
> + };
> +
> + dsi0: dsi@30500000 {
> + compatible = "ti,j721e-dsi";
> + reg = <0x0 0x30500000 0x0 0x100000>, <0x0 0x30270000 0x0 0x100>;
[Severity: High]
Are the cbass_main bus ranges in arch/arm64/boot/dts/ti/k3-am62p.dtsi
missing entries for dphy_tx0, dss1, and dsi0?
The nodes dphy_tx0 (0x301c0000), dss1 (0x30220000), and dsi0 (0x30500000
and 0x30270000) are added under cbass_main in
arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi.
While arch/arm64/boot/dts/ti/k3-j722s.dtsi defines ranges in cbass_main
for all of these regions:
<0x00 0x301c0000 0x00 0x301c0000 0x00 0x00001000>, /* DPHY-TX */
<0x00 0x30101000 0x00 0x30101000 0x00 0x00080100>, /* CSI window */
<0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
<0x00 0x30210000 0x00 0x30210000 0x00 0x00010000>, /* VPU */
<0x00 0x30220000 0x00 0x30220000 0x00 0x00010000>, /* DSS1 */
<0x00 0x30270000 0x00 0x30270000 0x00 0x00010000>, /* DSI-base1 */
<0x00 0x30500000 0x00 0x30500000 0x00 0x00100000>, /* DSI-base2 */
arch/arm64/boot/dts/ti/k3-am62p.dtsi only has the range for DSS0
(0x30200000) and VPU (0x30210000) in cbass_main:
<0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */
<0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */
<0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
<0x00 0x30210000 0x00 0x30210000 0x00 0x00010000>, /* VPU */
<0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
When dphy_tx0, dss1, or dsi0 is enabled on an AM62P board, address
translation via of_device_alloc() -> of_address_to_resource() ->
of_translate_address() -> of_translate_one() will fail to find a matching
range in cbass_main, trigger a WARN_ON(rc) in of_device_alloc(), and cause
driver probe to fail when mapping the memory resources.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029-beagley-ai-display-v4-0-dc7f2b532478@ideasonboard.com?part=13
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 14/14] arm64: dts: ti: beagley-ai: Enable HDMI display and audio
2026-10-29 10:18 [PATCH v4 00/14] drm/tidss: Add BeagleY-AI display support (and some more) Tomi Valkeinen
` (12 preceding siblings ...)
2026-10-29 10:18 ` [PATCH v4 13/14] arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS Tomi Valkeinen
@ 2026-10-29 10:19 ` Tomi Valkeinen
13 siblings, 0 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2026-10-29 10:19 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen, Andrew Davis
From: Andrew Davis <afd@ti.com>
Enable HDMI support for BeagleY-AI platform. The display controller used is
TIDSS and the HDMI bridge used is IT66122.
Based on DT by: Robert Nelson <robertcnelson@gmail.com>
Signed-off-by: Andrew Davis <afd@ti.com>
Signed-off-by: Swamil Jain <s-jain1@ti.com>
[tomi.valkeinen: cosmetic fixes]
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts | 180 +++++++++++++++++++++++++
1 file changed, 180 insertions(+)
diff --git a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
index 8b4b3b80a29d..be3f5349345f 100644
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
@@ -159,6 +159,34 @@ dsi_csi_mux: mux-controller {
/* state = SEL + 2*OE : 0 = DSI0, 1 = CSI1, 2,3 = off */
idle-state = <2>;
};
+
+ hdmi0: connector-hdmi {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "d";
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&it66122_out>;
+ };
+ };
+ };
+
+ sound0: sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "it66122 HDMI";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&hdmi_dailink_master>;
+ simple-audio-card,frame-master = <&hdmi_dailink_master>;
+
+ hdmi_dailink_master: simple-audio-card,cpu {
+ sound-dai = <&mcasp1>;
+ system-clock-direction-out;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&it66122>;
+ };
+ };
};
&main_pmx0 {
@@ -205,6 +233,13 @@ J722S_IOPAD(0x0240, PIN_INPUT, 7) /* (B24) MMC1_SDCD.GPIO1_48 */
bootph-all;
};
+ main_i2c1_pins_default: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (C24) I2C1_SCL */
+ J722S_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (A22) I2C1_SDA */
+ >;
+ };
+
mdio_pins_default: mdio-default-pins {
pinctrl-single,pins = <
J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */
@@ -254,6 +289,47 @@ vdd_3v3_sd_pins_default: vdd-3v3-sd-default-pins {
J722S_IOPAD(0x0254, PIN_OUTPUT, 7) /* (E25) USB0_DRVVBUS.GPIO1_50 */
>;
};
+
+ dss1_pins_default: dss1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0100, PIN_OUTPUT, 0) /* (AB23) VOUT0_VSYNC */
+ J722S_IOPAD(0x00f8, PIN_OUTPUT, 0) /* (AB24) VOUT0_HSYNC */
+ J722S_IOPAD(0x0104, PIN_OUTPUT, 0) /* (AC26) VOUT0_PCLK */
+ J722S_IOPAD(0x00fc, PIN_OUTPUT, 0) /* (AC27) VOUT0_DE */
+ J722S_IOPAD(0x00b8, PIN_OUTPUT, 0) /* (W27) VOUT0_DATA0 */
+ J722S_IOPAD(0x00bc, PIN_OUTPUT, 0) /* (W25) VOUT0_DATA1 */
+ J722S_IOPAD(0x00c0, PIN_OUTPUT, 0) /* (W24) VOUT0_DATA2 */
+ J722S_IOPAD(0x00c4, PIN_OUTPUT, 0) /* (W23) VOUT0_DATA3 */
+ J722S_IOPAD(0x00c8, PIN_OUTPUT, 0) /* (W22) VOUT0_DATA4 */
+ J722S_IOPAD(0x00cc, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA5 */
+ J722S_IOPAD(0x00d0, PIN_OUTPUT, 0) /* (Y26) VOUT0_DATA6 */
+ J722S_IOPAD(0x00d4, PIN_OUTPUT, 0) /* (Y27) VOUT0_DATA7 */
+ J722S_IOPAD(0x00d8, PIN_OUTPUT, 0) /* (AA24) VOUT0_DATA8 */
+ J722S_IOPAD(0x00dc, PIN_OUTPUT, 0) /* (AA27) VOUT0_DATA9 */
+ J722S_IOPAD(0x00e0, PIN_OUTPUT, 0) /* (AA25) VOUT0_DATA10 */
+ J722S_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (AB25) VOUT0_DATA11 */
+ J722S_IOPAD(0x00e8, PIN_OUTPUT, 0) /* (AA23) VOUT0_DATA12 */
+ J722S_IOPAD(0x00ec, PIN_OUTPUT, 0) /* (AA22) VOUT0_DATA13 */
+ J722S_IOPAD(0x00f0, PIN_OUTPUT, 0) /* (AB26) VOUT0_DATA14 */
+ J722S_IOPAD(0x00f4, PIN_OUTPUT, 0) /* (AB27) VOUT0_DATA15 */
+ J722S_IOPAD(0x005c, PIN_OUTPUT, 1) /* (AC25) GPMC0_AD8.VOUT0_DATA16 */
+ J722S_IOPAD(0x0060, PIN_OUTPUT, 1) /* (U26) GPMC0_AD9.VOUT0_DATA17 */
+ J722S_IOPAD(0x0064, PIN_OUTPUT, 1) /* (V27) GPMC0_AD10.VOUT0_DATA18 */
+ J722S_IOPAD(0x0068, PIN_OUTPUT, 1) /* (V25) GPMC0_AD11.VOUT0_DATA19 */
+ J722S_IOPAD(0x006c, PIN_OUTPUT, 1) /* (V26) GPMC0_AD12.VOUT0_DATA20 */
+ J722S_IOPAD(0x0070, PIN_OUTPUT, 1) /* (V24) GPMC0_AD13.VOUT0_DATA21 */
+ J722S_IOPAD(0x0074, PIN_OUTPUT, 1) /* (V22) GPMC0_AD14.VOUT0_DATA22 */
+ J722S_IOPAD(0x0078, PIN_OUTPUT, 1) /* (V23) GPMC0_AD15.VOUT0_DATA23 */
+ >;
+ };
+
+ main_mcasp1_pins_default: main-mcasp1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0090, PIN_INPUT, 2) /* (P27) GPMC0_BE0n_CLE.MCASP1_ACLKX */
+ J722S_IOPAD(0x0098, PIN_INPUT, 2) /* (V21) GPMC0_WAIT0.MCASP1_AFSX */
+ J722S_IOPAD(0x008c, PIN_OUTPUT, 2) /* (N23) GPMC0_WEn.MCASP1_AXR0 */
+ >;
+ };
};
&cpsw3g {
@@ -334,6 +410,13 @@ J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 0) /* (C6) WKUP_I2C1_SDA */
>;
bootph-all;
};
+
+ hdmi_gpio_pins_default: hdmi-gpio-default-pins {
+ pinctrl-single,pins = <
+ J722S_MCU_IOPAD(0x0038, PIN_INPUT_PULLUP | PIN_DEBOUNCE_CONF6, 7) /* (D8) MCU_MCAN0_RX.MCU_GPIO0_14 HDMI_INTn */
+ J722S_MCU_IOPAD(0x0034, PIN_OUTPUT_PULLUP, 7) /* (B2) MCU_MCAN0_TX.MCU_GPIO0_13 HDMI_RSTn */
+ >;
+ };
};
&wkup_uart0 {
@@ -435,6 +518,54 @@ rtc: rtc@68 {
};
};
+&main_i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ clock-frequency = <400000>;
+
+ it66122: bridge-hdmi@4c {
+ compatible = "ite,it66122";
+ reg = <0x4c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_gpio_pins_default>;
+ vcn33-supply = <&vdd_3v3>;
+ vcn18-supply = <&buck2_reg>;
+ vrf12-supply = <&ldo2_reg>;
+ reset-gpios = <&mcu_gpio0 13 GPIO_ACTIVE_LOW>;
+ interrupt-parent = <&mcu_gpio0>;
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+ #sound-dai-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * HDMI can be serviced with 3 potential VPs -
+ * (DSS0 VP1 / DSS1 VP0 / DSS1 VP1).
+ * For now, we will service it with DSS1 VP0.
+ */
+ port@0 {
+ reg = <0>;
+
+ it66122_in: endpoint {
+ bus-width = <24>;
+ remote-endpoint = <&dss1_dpi0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ it66122_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
+};
+
&sdhci1 {
/* SD/MMC */
vmmc-supply = <&vdd_mmc1>;
@@ -467,4 +598,53 @@ &main_i2c2 {
status = "disabled";
};
+&dss1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss1_pins_default>;
+
+ clocks = <&k3_clks 232 8>,
+ <&k3_clks 232 0>,
+ <&k3_clks 232 4>;
+
+ assigned-clocks = <&k3_clks 241 0>, /* DSS1-VP0 */
+ <&k3_clks 240 0>, /* DSS1-VP1 */
+ <&k3_clks 245 0>; /* DPI Output */
+
+ assigned-clock-parents = <&k3_clks 241 2>, /* PLL 17 HDMI */
+ <&k3_clks 240 1>, /* PLL 18 DSI */
+ <&k3_clks 245 2>; /* DSS1-DPI0 */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* DSS1-VP0: DPI/HDMI Output */
+ port@0 {
+ reg = <0>;
+
+ dss1_dpi0_out: endpoint {
+ remote-endpoint = <&it66122_in>;
+ };
+ };
+ };
+};
+
+&mcasp1 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp1_pins_default>;
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
+
#include "k3-j722s-ti-ipc-firmware.dtsi"
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread