]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/rockchip: dw_hdmi_qp: Add platform ctrl callback
authorAndy Yan <andy.yan@rock-chips.com>
Tue, 31 Dec 2024 09:44:17 +0000 (17:44 +0800)
committerHeiko Stuebner <heiko@sntech.de>
Mon, 6 Jan 2025 15:26:18 +0000 (16:26 +0100)
There are some control bits for IO and interrupts status scattered
across different GRF on differt SOC.
Add platform callback for this IO setting and interrupts status
handling.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20241231094425.253398-2-andyshrk@163.com
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c

index e498767a0a667dd3ede2403c2987d369b9ba4831..4c82b8400b41c2c3681d27bf539ee1fade84defb 100644 (file)
@@ -62,6 +62,12 @@ struct rockchip_hdmi_qp {
        int port_id;
 };
 
+struct rockchip_hdmi_qp_ctrl_ops {
+       void (*io_init)(struct rockchip_hdmi_qp *hdmi);
+       irqreturn_t (*irq_callback)(int irq, void *dev_id);
+       irqreturn_t (*hardirq_callback)(int irq, void *dev_id);
+};
+
 static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder)
 {
        struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
@@ -226,9 +232,44 @@ static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+static void dw_hdmi_qp_rk3588_io_init(struct rockchip_hdmi_qp *hdmi)
+{
+       u32 val;
+
+       val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
+             HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
+             HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
+             HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
+       regmap_write(hdmi->vo_regmap,
+                    hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
+                    val);
+
+       val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, RK3588_SET_HPD_PATH_MASK);
+       regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
+
+       if (hdmi->port_id)
+               val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL, RK3588_HDMI1_GRANT_SEL);
+       else
+               val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, RK3588_HDMI0_GRANT_SEL);
+       regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
+
+       if (hdmi->port_id)
+               val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK);
+       else
+               val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
+       regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
+}
+
+static const struct rockchip_hdmi_qp_ctrl_ops rk3588_hdmi_ctrl_ops = {
+       .io_init                = dw_hdmi_qp_rk3588_io_init,
+       .irq_callback           = dw_hdmi_qp_rk3588_irq,
+       .hardirq_callback       = dw_hdmi_qp_rk3588_hardirq,
+};
+
 struct rockchip_hdmi_qp_cfg {
        unsigned int num_ports;
        unsigned int port_ids[MAX_HDMI_PORT_NUM];
+       const struct rockchip_hdmi_qp_ctrl_ops *ctrl_ops;
        const struct dw_hdmi_qp_phy_ops *phy_ops;
 };
 
@@ -238,6 +279,7 @@ static const struct rockchip_hdmi_qp_cfg rk3588_hdmi_cfg = {
                0xfde80000,
                0xfdea0000,
        },
+       .ctrl_ops = &rk3588_hdmi_ctrl_ops,
        .phy_ops = &rk3588_hdmi_phy_ops,
 };
 
@@ -261,7 +303,6 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
        struct resource *res;
        struct clk_bulk_data *clks;
        int ret, irq, i;
-       u32 val;
 
        if (!pdev->dev.of_node)
                return -ENODEV;
@@ -278,6 +319,12 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
        if (!cfg)
                return -ENODEV;
 
+       if (!cfg->ctrl_ops || !cfg->ctrl_ops->io_init ||
+           !cfg->ctrl_ops->irq_callback || !cfg->ctrl_ops->hardirq_callback) {
+               dev_err(dev, "Missing platform ctrl ops\n");
+               return -ENODEV;
+       }
+
        hdmi->dev = &pdev->dev;
        hdmi->port_id = -ENODEV;
 
@@ -357,31 +404,7 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
                return ret;
        }
 
-       val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
-             HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
-             HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
-             HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
-       regmap_write(hdmi->vo_regmap,
-                    hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
-                    val);
-
-       val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
-                           RK3588_SET_HPD_PATH_MASK);
-       regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
-
-       if (hdmi->port_id)
-               val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
-                                   RK3588_HDMI1_GRANT_SEL);
-       else
-               val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
-                                   RK3588_HDMI0_GRANT_SEL);
-       regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
-
-       if (hdmi->port_id)
-               val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK);
-       else
-               val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
-       regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
+       cfg->ctrl_ops->io_init(hdmi);
 
        INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_qp_rk3588_hpd_work);
 
@@ -394,8 +417,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
                return irq;
 
        ret = devm_request_threaded_irq(hdmi->dev, irq,
-                                       dw_hdmi_qp_rk3588_hardirq,
-                                       dw_hdmi_qp_rk3588_irq,
+                                       cfg->ctrl_ops->hardirq_callback,
+                                       cfg->ctrl_ops->irq_callback,
                                        IRQF_SHARED, "dw-hdmi-qp-hpd",
                                        hdmi);
        if (ret)