Merge remote-tracking branch 'drm/drm-next' into drm-misc-next
[sfrench/cifs-2.6.git] / drivers / gpu / drm / rockchip / dw_hdmi-rockchip.c
index 77d929e6f6ce5c6ebc04568af9463d99a4e54a89..cdc304d4cd02b1edcfd310e19da12b5b150f0b2f 100644 (file)
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
+#define RK3228_GRF_SOC_CON2            0x0408
+#define RK3228_HDMI_SDAIN_MSK          BIT(14)
+#define RK3228_HDMI_SCLIN_MSK          BIT(13)
+#define RK3228_GRF_SOC_CON6            0x0418
+#define RK3228_HDMI_HPD_VSEL           BIT(6)
+#define RK3228_HDMI_SDA_VSEL           BIT(5)
+#define RK3228_HDMI_SCL_VSEL           BIT(4)
+
 #define RK3288_GRF_SOC_CON6            0x025C
 #define RK3288_HDMI_LCDC_SEL           BIT(4)
 #define RK3328_GRF_SOC_CON2            0x0408
@@ -321,6 +329,25 @@ static void dw_hdmi_rockchip_genphy_disable(struct dw_hdmi *dw_hdmi, void *data)
        phy_power_off(hdmi->phy);
 }
 
+static void dw_hdmi_rk3228_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
+{
+       struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
+
+       dw_hdmi_phy_setup_hpd(dw_hdmi, data);
+
+       regmap_write(hdmi->regmap,
+               RK3228_GRF_SOC_CON6,
+               HIWORD_UPDATE(RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
+                             RK3228_HDMI_SCL_VSEL,
+                             RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
+                             RK3228_HDMI_SCL_VSEL));
+
+       regmap_write(hdmi->regmap,
+               RK3228_GRF_SOC_CON2,
+               HIWORD_UPDATE(RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK,
+                             RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK));
+}
+
 static enum drm_connector_status
 dw_hdmi_rk3328_read_hpd(struct dw_hdmi *dw_hdmi, void *data)
 {
@@ -366,6 +393,29 @@ static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
                              RK3328_HDMI_HPD_IOE));
 }
 
+static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = {
+       .init           = dw_hdmi_rockchip_genphy_init,
+       .disable        = dw_hdmi_rockchip_genphy_disable,
+       .read_hpd       = dw_hdmi_phy_read_hpd,
+       .update_hpd     = dw_hdmi_phy_update_hpd,
+       .setup_hpd      = dw_hdmi_rk3228_setup_hpd,
+};
+
+static struct rockchip_hdmi_chip_data rk3228_chip_data = {
+       .lcdsel_grf_reg = -1,
+};
+
+static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
+       .mode_valid = dw_hdmi_rockchip_mode_valid,
+       .mpll_cfg = rockchip_mpll_cfg,
+       .cur_ctr = rockchip_cur_ctr,
+       .phy_config = rockchip_phy_config,
+       .phy_data = &rk3228_chip_data,
+       .phy_ops = &rk3228_hdmi_phy_ops,
+       .phy_name = "inno_dw_hdmi_phy2",
+       .phy_force_vendor = true,
+};
+
 static struct rockchip_hdmi_chip_data rk3288_chip_data = {
        .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
        .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
@@ -418,6 +468,9 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
 };
 
 static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
+       { .compatible = "rockchip,rk3228-dw-hdmi",
+         .data = &rk3228_hdmi_drv_data
+       },
        { .compatible = "rockchip,rk3288-dw-hdmi",
          .data = &rk3288_hdmi_drv_data
        },
@@ -538,11 +591,25 @@ static int dw_hdmi_rockchip_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused dw_hdmi_rockchip_resume(struct device *dev)
+{
+       struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
+
+       dw_hdmi_resume(hdmi->hdmi);
+
+       return 0;
+}
+
+static const struct dev_pm_ops dw_hdmi_rockchip_pm = {
+       SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_rockchip_resume)
+};
+
 struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
        .probe  = dw_hdmi_rockchip_probe,
        .remove = dw_hdmi_rockchip_remove,
        .driver = {
                .name = "dwhdmi-rockchip",
+               .pm = &dw_hdmi_rockchip_pm,
                .of_match_table = dw_hdmi_rockchip_dt_ids,
        },
 };