From 582ab904e7c021d153e6383bd0d6946fdf9994aa Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Mon, 22 Nov 2021 17:23:57 +0800 Subject: [PATCH] drm/rockchip: dw_hdmi: Enable rk3588 clks before write/read hdmitx regs Signed-off-by: Algea Cao Change-Id: I42ac9cd48e4c959d6f0990f606f0758575c9f796 --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 79 +++--------------- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 86 +++++++++++++++++--- 2 files changed, 84 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 71fde3b23faa..7cc41314bcb1 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -230,10 +230,6 @@ struct dw_hdmi_qp { int avp_irq; int earc_irq; - struct clk *pclk; - struct clk *earc_clk; - struct clk *ref_clk; - u8 edid[HDMI_EDID_LEN]; struct { @@ -2062,48 +2058,9 @@ __dw_hdmi_probe(struct platform_device *pdev, hdmi->regm = plat_data->regm; } - hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); - if (IS_ERR(hdmi->pclk)) { - ret = PTR_ERR(hdmi->pclk); - dev_err(hdmi->dev, "Unable to get HDMI pclk: %d\n", ret); - goto err_res; - } - - ret = clk_prepare_enable(hdmi->pclk); - if (ret) { - dev_err(hdmi->dev, "Cannot enable HDMI pclk: %d\n", ret); - goto err_res; - } - - hdmi->earc_clk = devm_clk_get(hdmi->dev, "earc"); - if (IS_ERR(hdmi->earc_clk)) { - ret = PTR_ERR(hdmi->earc_clk); - dev_err(hdmi->dev, "Unable to get HDMI earc_clk: %d\n", ret); - goto err_pclk; - } - - ret = clk_prepare_enable(hdmi->earc_clk); - if (ret) { - dev_err(hdmi->dev, "Cannot enable HDMI earc_clk: %d\n", ret); - goto err_pclk; - } - - hdmi->ref_clk = devm_clk_get(hdmi->dev, "ref"); - if (IS_ERR(hdmi->ref_clk)) { - ret = PTR_ERR(hdmi->ref_clk); - dev_err(hdmi->dev, "Unable to get HDMI ref_clk: %d\n", ret); - goto err_earc; - } - - ret = clk_prepare_enable(hdmi->ref_clk); - if (ret) { - dev_err(hdmi->dev, "Cannot enable HDMI ref_clk: %d\n", ret); - goto err_earc; - } - ret = dw_hdmi_detect_phy(hdmi); if (ret < 0) - goto err_ref; + goto err_res; hdmi_writel(hdmi, 0, MAINUNIT_0_INT_MASK_N); hdmi_writel(hdmi, 0, MAINUNIT_1_INT_MASK_N); @@ -2112,7 +2069,7 @@ __dw_hdmi_probe(struct platform_device *pdev, irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = irq; - goto err_ref; + goto err_res; } hdmi->avp_irq = irq; @@ -2121,12 +2078,12 @@ __dw_hdmi_probe(struct platform_device *pdev, dw_hdmi_qp_avp_irq, IRQF_SHARED, dev_name(dev), hdmi); if (ret) - goto err_ref; + goto err_res; irq = platform_get_irq(pdev, 2); if (irq < 0) { ret = irq; - goto err_pclk; + goto err_res; } hdmi->earc_irq = irq; @@ -2135,12 +2092,12 @@ __dw_hdmi_probe(struct platform_device *pdev, dw_hdmi_qp_earc_irq, IRQF_SHARED, dev_name(dev), hdmi); if (ret) - goto err_ref; + goto err_res; irq = platform_get_irq(pdev, 3); if (irq < 0) { ret = irq; - goto err_ref; + goto err_res; } hdmi->main_irq = irq; @@ -2148,7 +2105,7 @@ __dw_hdmi_probe(struct platform_device *pdev, dw_hdmi_qp_main_hardirq, NULL, IRQF_SHARED, dev_name(dev), hdmi); if (ret) - goto err_ref; + goto err_res; hdmi_init_clk_regenerator(hdmi); @@ -2201,13 +2158,13 @@ __dw_hdmi_probe(struct platform_device *pdev, if (IS_ERR(hdmi->extcon)) { dev_err(hdmi->dev, "allocate extcon failed\n"); ret = PTR_ERR(hdmi->extcon); - goto err_ref; + goto err_res; } ret = devm_extcon_dev_register(hdmi->dev, hdmi->extcon); if (ret) { dev_err(hdmi->dev, "failed to register extcon: %d\n", ret); - goto err_ref; + goto err_res; } ret = extcon_set_property_capability(hdmi->extcon, EXTCON_DISP_HDMI, @@ -2215,7 +2172,7 @@ __dw_hdmi_probe(struct platform_device *pdev, if (ret) { dev_err(hdmi->dev, "failed to set USB property capability: %d\n", ret); - goto err_ref; + goto err_res; } /* Reset HDMI DDC I2C master controller and mute I2CM interrupts */ @@ -2231,18 +2188,6 @@ __dw_hdmi_probe(struct platform_device *pdev, return hdmi; -err_ref: - clk_disable_unprepare(hdmi->ref_clk); -err_earc: - clk_disable_unprepare(hdmi->earc_clk); -err_pclk: - if (hdmi->i2c) { - i2c_del_adapter(&hdmi->i2c->adap); - hdmi->ddc = NULL; - } - - clk_disable_unprepare(hdmi->pclk); - err_res: if (hdmi->i2c) i2c_del_adapter(&hdmi->i2c->adap); @@ -2271,10 +2216,6 @@ static void __dw_hdmi_remove(struct dw_hdmi_qp *hdmi) if (hdmi->bridge.encoder) hdmi->bridge.encoder->funcs->destroy(hdmi->bridge.encoder); - clk_disable_unprepare(hdmi->ref_clk); - clk_disable_unprepare(hdmi->earc_clk); - clk_disable_unprepare(hdmi->pclk); - if (hdmi->i2c) i2c_del_adapter(&hdmi->i2c->adap); else diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 87349b98ceeb..4ef7bf1f71cb 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -164,8 +164,12 @@ struct rockchip_hdmi { struct clk *phyref_clk; struct clk *grf_clk; struct clk *hclk_vio; + struct clk *hclk_vo1; struct clk *hclk_vop; struct clk *hpd_clk; + struct clk *pclk; + struct clk *earc_clk; + struct clk *hdmitx_ref; struct dw_hdmi *hdmi; struct dw_hdmi_qp *hdmi_qp; @@ -1438,6 +1442,34 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) return PTR_ERR(hdmi->hpd_clk); } + hdmi->hclk_vo1 = devm_clk_get_optional(hdmi->dev, "hclk_vo1"); + if (IS_ERR(hdmi->hclk_vo1)) { + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hclk_vo1), + "failed to get hclk_vo1 clock\n"); + return PTR_ERR(hdmi->hclk_vo1); + } + + hdmi->earc_clk = devm_clk_get_optional(hdmi->dev, "earc"); + if (IS_ERR(hdmi->earc_clk)) { + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->earc_clk), + "failed to get earc_clk clock\n"); + return PTR_ERR(hdmi->earc_clk); + } + + hdmi->hdmitx_ref = devm_clk_get_optional(hdmi->dev, "hdmitx_ref"); + if (IS_ERR(hdmi->hdmitx_ref)) { + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hdmitx_ref), + "failed to get hdmitx_ref clock\n"); + return PTR_ERR(hdmi->hdmitx_ref); + } + + hdmi->pclk = devm_clk_get_optional(hdmi->dev, "pclk"); + if (IS_ERR(hdmi->pclk)) { + dev_err_probe(hdmi->dev, PTR_ERR(hdmi->pclk), + "failed to get pclk clock\n"); + return PTR_ERR(hdmi->pclk); + } + hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable", GPIOD_OUT_HIGH); if (IS_ERR(hdmi->enable_gpio)) { @@ -1592,9 +1624,8 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) if (hdmi->phy) phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width); - if (!hdmi->is_hdmi_qp) - clk_set_rate(hdmi->phyref_clk, - crtc->state->adjusted_mode.crtc_clock * 1000); + clk_set_rate(hdmi->phyref_clk, + crtc->state->adjusted_mode.crtc_clock * 1000); if (hdmi->chip_data->lcdsel_grf_reg < 0) return; @@ -2475,8 +2506,7 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder, { struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); - if (!hdmi->is_hdmi_qp) - clk_set_rate(hdmi->phyref_clk, adj->crtc_clock * 1000); + clk_set_rate(hdmi->phyref_clk, adj->crtc_clock * 1000); } static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = { @@ -2909,6 +2939,37 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, return ret; } + ret = clk_prepare_enable(hdmi->hpd_clk); + if (ret) { + dev_err(hdmi->dev, "Failed to enable HDMI hpd_clk: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(hdmi->hclk_vo1); + if (ret) { + dev_err(hdmi->dev, "Failed to enable HDMI hclk_vo1: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(hdmi->earc_clk); + if (ret) { + dev_err(hdmi->dev, "Failed to enable HDMI earc_clk: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(hdmi->hdmitx_ref); + if (ret) { + dev_err(hdmi->dev, "Failed to enable HDMI hdmitx_ref: %d\n", + ret); + return ret; + } + + ret = clk_prepare_enable(hdmi->pclk); + if (ret) { + dev_err(hdmi->dev, "Failed to enable HDMI pclk: %d\n", ret); + return ret; + } + if (hdmi->chip_data->ddc_en_reg == RK3568_GRF_VO_CON1) { regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1, HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK | @@ -2970,13 +3031,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, return ret; } - ret = clk_prepare_enable(hdmi->hpd_clk); - if (ret) { - dev_err(hdmi->dev, "Failed to enable HDMI hpd_clk: %d\n", - ret); - return ret; - } - val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK) | HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK); regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); @@ -3040,6 +3094,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, clk_disable_unprepare(hdmi->phyref_clk); clk_disable_unprepare(hdmi->hclk_vop); clk_disable_unprepare(hdmi->hpd_clk); + clk_disable_unprepare(hdmi->hclk_vo1); + clk_disable_unprepare(hdmi->earc_clk); + clk_disable_unprepare(hdmi->hdmitx_ref); + clk_disable_unprepare(hdmi->pclk); } if (plat_data->connector) { @@ -3066,6 +3124,10 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, clk_disable_unprepare(hdmi->phyref_clk); clk_disable_unprepare(hdmi->hclk_vop); clk_disable_unprepare(hdmi->hpd_clk); + clk_disable_unprepare(hdmi->hclk_vo1); + clk_disable_unprepare(hdmi->earc_clk); + clk_disable_unprepare(hdmi->hdmitx_ref); + clk_disable_unprepare(hdmi->pclk); } static const struct component_ops dw_hdmi_rockchip_ops = {