drm/rockchip: dw_hdmi: Enable rk3588 clks before write/read hdmitx regs

Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
Change-Id: I42ac9cd48e4c959d6f0990f606f0758575c9f796
This commit is contained in:
Algea Cao
2021-11-22 17:23:57 +08:00
committed by Tao Huang
parent 6b3a481369
commit 582ab904e7
2 changed files with 84 additions and 81 deletions

View File

@@ -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

View File

@@ -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 = {