]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm: renesas: rz-du: mipi_dsi: Add OF data support
authorLad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Mon, 9 Jun 2025 22:56:25 +0000 (23:56 +0100)
committerBiju Das <biju.das.jz@bp.renesas.com>
Thu, 12 Jun 2025 18:42:27 +0000 (19:42 +0100)
n preparation for adding support for the Renesas RZ/V2H(P) SoC, this patch
introduces a mechanism to pass SoC-specific information via OF data in the
DSI driver. This enables the driver to adapt dynamically to various
SoC-specific requirements without hardcoding configurations.

The MIPI DSI interface on the RZ/V2H(P) SoC is nearly identical to the one
on the RZ/G2L SoC. While the LINK registers are shared between the two
SoCs, the D-PHY registers differ. Also the VCLK range differs on both these
SoCs. To accommodate these differences `struct rzg2l_mipi_dsi_hw_info` is
introduced and as now passed as OF data.

These changes lay the groundwork for the upcoming RZ/V2H(P) SoC support by
allowing SoC-specific data to be passed through OF.

Co-developed-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20250609225630.502888-5-prabhakar.mahadev-lad.rj@bp.renesas.com
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h

index b08274e5dfcff7fbad7d9a3e620d4a3733d4b7b1..85074e0c3cc4c3aa20dc898a150a266e7fc17449 100644 (file)
 
 #define RZG2L_DCS_BUF_SIZE     128 /* Maximum DCS buffer size in external memory. */
 
+struct rzg2l_mipi_dsi;
+
+struct rzg2l_mipi_dsi_hw_info {
+       int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, unsigned long hsfreq);
+       void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi);
+       u32 phy_reg_offset;
+       u32 link_reg_offset;
+       unsigned long min_dclk;
+       unsigned long max_dclk;
+};
+
 struct rzg2l_mipi_dsi {
        struct device *dev;
        void __iomem *mmio;
 
+       const struct rzg2l_mipi_dsi_hw_info *info;
+
        struct reset_control *rstc;
        struct reset_control *arstc;
        struct reset_control *prstc;
@@ -174,22 +187,22 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = {
 
 static void rzg2l_mipi_dsi_phy_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data)
 {
-       iowrite32(data, dsi->mmio + reg);
+       iowrite32(data, dsi->mmio + dsi->info->phy_reg_offset + reg);
 }
 
 static void rzg2l_mipi_dsi_link_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data)
 {
-       iowrite32(data, dsi->mmio + LINK_REG_OFFSET + reg);
+       iowrite32(data, dsi->mmio + dsi->info->link_reg_offset + reg);
 }
 
 static u32 rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
 {
-       return ioread32(dsi->mmio + reg);
+       return ioread32(dsi->mmio + dsi->info->phy_reg_offset + reg);
 }
 
 static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
 {
-       return ioread32(dsi->mmio + LINK_REG_OFFSET + reg);
+       return ioread32(dsi->mmio + dsi->info->link_reg_offset + reg);
 }
 
 /* -----------------------------------------------------------------------------
@@ -305,7 +318,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
        bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
        hsfreq = DIV_ROUND_CLOSEST_ULL(vclk_rate * bpp, dsi->lanes);
 
-       ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq);
+       ret = dsi->info->dphy_init(dsi, hsfreq);
        if (ret < 0)
                goto err_phy;
 
@@ -357,7 +370,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
        return 0;
 
 err_phy:
-       rzg2l_mipi_dsi_dphy_exit(dsi);
+       dsi->info->dphy_exit(dsi);
        pm_runtime_put(dsi->dev);
 
        return ret;
@@ -365,7 +378,7 @@ err_phy:
 
 static void rzg2l_mipi_dsi_stop(struct rzg2l_mipi_dsi *dsi)
 {
-       rzg2l_mipi_dsi_dphy_exit(dsi);
+       dsi->info->dphy_exit(dsi);
        pm_runtime_put(dsi->dev);
 }
 
@@ -615,10 +628,12 @@ rzg2l_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
                                 const struct drm_display_info *info,
                                 const struct drm_display_mode *mode)
 {
-       if (mode->clock > 148500)
+       struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge);
+
+       if (mode->clock > dsi->info->max_dclk)
                return MODE_CLOCK_HIGH;
 
-       if (mode->clock < 5803)
+       if (mode->clock < dsi->info->min_dclk)
                return MODE_CLOCK_LOW;
 
        return MODE_OK;
@@ -905,6 +920,8 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dsi);
        dsi->dev = &pdev->dev;
 
+       dsi->info = of_device_get_match_data(&pdev->dev);
+
        ret = drm_of_get_data_lanes_count_ep(dsi->dev->of_node, 1, 0, 1, 4);
        if (ret < 0)
                return dev_err_probe(dsi->dev, ret,
@@ -948,13 +965,13 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
         * mode->clock and format are not available. So initialize DPHY with
         * timing parameters for 80Mbps.
         */
-       ret = rzg2l_mipi_dsi_dphy_init(dsi, 80000000);
+       ret = dsi->info->dphy_init(dsi, 80000000);
        if (ret < 0)
                goto err_phy;
 
        txsetr = rzg2l_mipi_dsi_link_read(dsi, TXSETR);
        dsi->num_data_lanes = min(((txsetr >> 16) & 3) + 1, num_data_lanes);
-       rzg2l_mipi_dsi_dphy_exit(dsi);
+       dsi->info->dphy_exit(dsi);
        pm_runtime_put(dsi->dev);
 
        /* Initialize the DRM bridge. */
@@ -975,7 +992,7 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
        return 0;
 
 err_phy:
-       rzg2l_mipi_dsi_dphy_exit(dsi);
+       dsi->info->dphy_exit(dsi);
        pm_runtime_put(dsi->dev);
 err_pm_disable:
        pm_runtime_disable(dsi->dev);
@@ -992,8 +1009,16 @@ static void rzg2l_mipi_dsi_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
 }
 
+static const struct rzg2l_mipi_dsi_hw_info rzg2l_mipi_dsi_info = {
+       .dphy_init = rzg2l_mipi_dsi_dphy_init,
+       .dphy_exit = rzg2l_mipi_dsi_dphy_exit,
+       .link_reg_offset = 0x10000,
+       .min_dclk = 5803,
+       .max_dclk = 148500,
+};
+
 static const struct of_device_id rzg2l_mipi_dsi_of_table[] = {
-       { .compatible = "renesas,rzg2l-mipi-dsi" },
+       { .compatible = "renesas,rzg2l-mipi-dsi", .data = &rzg2l_mipi_dsi_info, },
        { /* sentinel */ }
 };
 
index 26d8a37ee635197a014f4512df0dd223e57e1773..d8082a87d874488c6bdf74bf07b45f6af4a97ae0 100644 (file)
@@ -41,8 +41,6 @@
 #define DSIDPHYTIM3_THS_ZERO(x)                ((x) << 0)
 
 /* --------------------------------------------------------*/
-/* Link Registers */
-#define LINK_REG_OFFSET                        0x10000
 
 /* Link Status Register */
 #define LINKSR                         0x10