The DPI output pipeline in K3 SoCs contains the display subsystem (DSS)
which produces the in-SoC parallel video signal, and a DPI block which
adjusts the signal to the external MIPI DPI output.

The DSS IP has registers to configure whether the data and sync signals
are driven on rising or falling clock edge, and on some SoCs these are
automatically conveyed to the DPI block which needs that configuration
to properly output the MIPI DPI signal.

However, on some SoCs the DPI block configuration has to be done
manually, using an extra register outside the DSS, DPI0_CLK_CTRL from
MAIN_CTRL_MMR_CFG0 block, which controls the DPI block's behavior.

Add the support to get the regmap to the register via syscon, and
configure the bits before enabling the video output.

Original patch from Louis Chauvet <[email protected]>

Signed-off-by: Tomi Valkeinen <[email protected]>
---
 drivers/gpu/drm/tidss/tidss_dispc.c      | 21 +++++++++++++++++++++
 drivers/gpu/drm/tidss/tidss_dispc_regs.h |  4 ++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
b/drivers/gpu/drm/tidss/tidss_dispc.c
index c21ac3f51720..92cba069ed6c 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -467,6 +467,8 @@ struct dispc_device {
        const struct dispc_features *feat;
 
        struct clk *fclk;
+       struct regmap *syscon_dpi_io_ctrl;
+       unsigned int syscon_dpi_io_ctrl_offset;
 
        bool is_enabled;
 
@@ -1201,6 +1203,13 @@ void dispc_vp_prepare(struct dispc_device *dispc, u32 
hw_videoport,
                                  mode->crtc_hdisplay - 1) |
                       FIELD_PREP(DISPC_VP_SIZE_SCREEN_VDISPLAY_MASK,
                                  mode->crtc_vdisplay - 1));
+
+       if (dispc->vp_data[hw_videoport].dpi_output && 
dispc->syscon_dpi_io_ctrl) {
+               regmap_write(dispc->syscon_dpi_io_ctrl,
+                            dispc->syscon_dpi_io_ctrl_offset + 0x0,
+                            (!ipc ? DPI0_CLK_CTRL_DATA_CLK_INVDIS : 0) |
+                            (rf ? DPI0_CLK_CTRL_SYNC_CLK_INVDIS : 0));
+       }
 }
 
 void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport)
@@ -2989,6 +2998,18 @@ int dispc_init(struct tidss_device *tidss)
 
        dispc_init_errata(dispc);
 
+       dispc->syscon_dpi_io_ctrl =
+               syscon_regmap_lookup_by_phandle_args(tidss->dev->of_node,
+                                                    "ti,dpi-io-ctrl", 1,
+                                                    
&dispc->syscon_dpi_io_ctrl_offset);
+
+       if (PTR_ERR(dispc->syscon_dpi_io_ctrl) == -ENODEV)
+               dispc->syscon_dpi_io_ctrl = NULL;
+       else if (IS_ERR(dispc->syscon_dpi_io_ctrl))
+               return dev_err_probe(dispc->dev,
+                                    PTR_ERR(dispc->syscon_dpi_io_ctrl),
+                                    "DISPC: syscon_regmap_lookup_by_phandle 
failed.\n");
+
        dispc->fourccs = devm_kcalloc(dev, ARRAY_SIZE(dispc_color_formats),
                                      sizeof(*dispc->fourccs), GFP_KERNEL);
        if (!dispc->fourccs)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc_regs.h 
b/drivers/gpu/drm/tidss/tidss_dispc_regs.h
index 382027dddce8..4cdde24d8372 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc_regs.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc_regs.h
@@ -333,4 +333,8 @@ enum oldi_mode_reg_val { SPWG_18 = 0, JEIDA_24 = 1, SPWG_24 
= 2 };
 
 #define AM65X_OLDI_PWRDN_TX            BIT(8)
 
+/* Bits in the MAIN_CTRL_MMR_CFG0_DPI0_CLK_CTRL register */
+#define DPI0_CLK_CTRL_DATA_CLK_INVDIS BIT(8)
+#define DPI0_CLK_CTRL_SYNC_CLK_INVDIS BIT(9)
+
 #endif /* __TIDSS_DISPC_REGS_H */

-- 
2.43.0

Reply via email to