SoCs that integrate several DU channels describe the registers, clocks
and resets of each channel separately, and name them after the channel
they belong to. Introduce a table of resource names indexed by hardware
channel index, selected by the new RZG2L_DU_FEATURE_CHANNEL_RES feature
flag, and keep looking the resources up unnamed and unindexed for the
single-channel SoCs.

No functional change for the currently supported SoCs.

Signed-off-by: Tommaso Merciai <[email protected]>
---
v7->v8
 - New patch.

 drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 42 ++++++++++++++++---
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h  |  1 +
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c 
b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
index 81934fcb551b..dea6d92a7a8a 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
@@ -377,41 +377,73 @@ static const struct drm_crtc_funcs crtc_funcs_rz = {
  * Initialization
  */
 
+/*
+ * struct rzg2l_du_channel_res - Names of the resources of a DU channel
+ * @reg: reg-names entry holding the channel registers, NULL if unnamed
+ * @aclk: name of the channel main clock
+ * @pclk: name of the channel register access clock
+ * @vclk: name of the channel video clock
+ * @rst: reset-names entry of the channel reset, NULL if unnamed
+ */
+struct rzg2l_du_channel_res {
+       const char *reg;
+       const char *aclk;
+       const char *pclk;
+       const char *vclk;
+       const char *rst;
+};
+
 int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu, unsigned int swindex,
                         unsigned int hwindex)
 {
+       static const struct rzg2l_du_channel_res channel_res[] = {
+               [0] = { "du.0", "aclk", "pclk", "vclk", "resetn" },
+               [1] = { "du.1", "aclk1", "pclk1", "vclk1", "resetn1" },
+       };
+       static const struct rzg2l_du_channel_res single_channel_res = {
+               NULL, "aclk", "pclk", "vclk", NULL,
+       };
+
+       static_assert(ARRAY_SIZE(channel_res) == RZG2L_DU_MAX_CRTCS);
+
        struct platform_device *pdev = to_platform_device(rcdu->dev);
        struct rzg2l_du_crtc *rcrtc = &rcdu->crtcs[swindex];
+       const struct rzg2l_du_channel_res *res;
        struct drm_crtc *crtc = &rcrtc->crtc;
        struct drm_plane *primary;
        int ret;
 
+       res = rzg2l_du_has(rcdu, RZG2L_DU_FEATURE_CHANNEL_RES)
+           ? &channel_res[hwindex] : &single_channel_res;
+
        /* I/O resources */
-       rcrtc->mmio = devm_platform_ioremap_resource(pdev, 0);
+       rcrtc->mmio = res->reg
+                   ? devm_platform_ioremap_resource_byname(pdev, res->reg)
+                   : devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(rcrtc->mmio)) {
                dev_err(rcdu->dev, "failed to map MMIO for DU%u\n", hwindex);
                return PTR_ERR(rcrtc->mmio);
        }
 
-       rcrtc->rstc = devm_reset_control_get_optional_shared(rcdu->dev, NULL);
+       rcrtc->rstc = devm_reset_control_get_optional_shared(rcdu->dev, 
res->rst);
        if (IS_ERR(rcrtc->rstc)) {
                dev_err(rcdu->dev, "can't get cpg reset for DU%u\n", hwindex);
                return PTR_ERR(rcrtc->rstc);
        }
 
-       rcrtc->rzg2l_clocks.aclk = devm_clk_get(rcdu->dev, "aclk");
+       rcrtc->rzg2l_clocks.aclk = devm_clk_get(rcdu->dev, res->aclk);
        if (IS_ERR(rcrtc->rzg2l_clocks.aclk)) {
                dev_err(rcdu->dev, "no axi clock for DU%u\n", hwindex);
                return PTR_ERR(rcrtc->rzg2l_clocks.aclk);
        }
 
-       rcrtc->rzg2l_clocks.pclk = devm_clk_get(rcdu->dev, "pclk");
+       rcrtc->rzg2l_clocks.pclk = devm_clk_get(rcdu->dev, res->pclk);
        if (IS_ERR(rcrtc->rzg2l_clocks.pclk)) {
                dev_err(rcdu->dev, "no peripheral clock for DU%u\n", hwindex);
                return PTR_ERR(rcrtc->rzg2l_clocks.pclk);
        }
 
-       rcrtc->rzg2l_clocks.dclk = devm_clk_get(rcdu->dev, "vclk");
+       rcrtc->rzg2l_clocks.dclk = devm_clk_get(rcdu->dev, res->vclk);
        if (IS_ERR(rcrtc->rzg2l_clocks.dclk)) {
                dev_err(rcdu->dev, "no video clock for DU%u\n", hwindex);
                return PTR_ERR(rcrtc->rzg2l_clocks.dclk);
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h 
b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
index cb9ad869d66b..6e1e4222d2f4 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
@@ -21,6 +21,7 @@ struct device;
 struct drm_property;
 
 #define RZG2L_DU_FEATURE_DPIO_OE       BIT(0)  /* Has DPIO output enable 
control */
+#define RZG2L_DU_FEATURE_CHANNEL_RES   BIT(1)  /* Per-channel named reg, 
clocks and resets */
 
 enum rzg2l_du_output {
        RZG2L_DU_OUTPUT_DSI0,
-- 
2.54.0

Reply via email to