Merge commit 'e3b31a037dcdef9cd3a101d40ca505e40221cbb6'

* commit 'e3b31a037dcdef9cd3a101d40ca505e40221cbb6':
  drm/rockchip: tve: add .loader_protect() support for tve
  drm/rockchip: tve: add support to enable/disable tve/vdac clks dynamically for rk3528
  drm/rockchip: tve: add clk error check for rk3528
  clk: rockchip: rk3506: Remove frac parent clk for dclk vop

Change-Id: I66aebfb8c695fef76471247982007d05bdcf7b9e
This commit is contained in:
Tao Huang
2024-08-26 19:54:34 +08:00
2 changed files with 135 additions and 39 deletions

View File

@@ -136,8 +136,8 @@ PNAME(mclk_sai_asrc_parents_p) = { "xin24m_gate", "clk_int_voice_matrix0", "cl
PNAME(lrck_asrc_parents_p) = { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm",
"sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" };
PNAME(cclk_src_sdmmc_parents_p) = { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
PNAME(dclk_vop_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1",
"clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
PNAME(dclk_vop_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk",
"dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" };
PNAME(dbclk_gpio0_parents_p) = { "xin24m", "clk_rc", "clk_32k_pmu" };
PNAME(clk_pmu_hp_timer_parents_p) = { "xin24m", "gpll_div_100m", "clk_core_pvtpll" };
PNAME(clk_ref_out_parents_p) = { "xin24m", "gpll", "v0pll", "v1pll" };

View File

@@ -368,6 +368,13 @@ static int cvbs_set_disable(struct rockchip_tve *tve)
return ret;
}
dac_enable(tve, false);
clk_disable_unprepare(tve->dclk_4x);
clk_disable_unprepare(tve->dclk);
clk_disable_unprepare(tve->pclk_vdac);
clk_disable_unprepare(tve->hclk);
clk_disable_unprepare(tve->aclk);
tve->enable = 0;
return 0;
@@ -398,12 +405,56 @@ static int cvbs_set_enable(struct rockchip_tve *tve)
dev_err(tve->dev, "failed to get pm runtime: %d\n", ret);
return ret;
}
ret = clk_prepare_enable(tve->aclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve aclk: %d\n", ret);
goto err_pm_put;
}
ret = clk_prepare_enable(tve->hclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve hclk: %d\n", ret);
goto err_disable_aclk;
}
ret = clk_prepare_enable(tve->pclk_vdac);
if (ret) {
dev_err(tve->dev, "Cannot enable vdac pclk: %d\n", ret);
goto err_disable_hclk;
}
ret = clk_prepare_enable(tve->dclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve dclk: %d\n", ret);
goto err_disable_pclk;
}
ret = clk_prepare_enable(tve->dclk_4x);
if (ret) {
dev_err(tve->dev, "Cannot enable tve dclk_4x: %d\n", ret);
goto err_disable_dclk;
}
tve_set_mode(tve);
msleep(1000);
dac_enable(tve, true);
tve->enable = 1;
return 0;
err_disable_dclk:
clk_disable_unprepare(tve->dclk);
err_disable_pclk:
clk_disable_unprepare(tve->pclk_vdac);
err_disable_hclk:
clk_disable_unprepare(tve->hclk);
err_disable_aclk:
clk_disable_unprepare(tve->aclk);
err_pm_put:
pm_runtime_put_sync(tve->dev);
return ret;
}
static void rockchip_tve_encoder_enable(struct drm_encoder *encoder)
@@ -435,15 +486,17 @@ static void rockchip_tve_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct rockchip_tve *tve = encoder_to_tve(encoder);
u32 tv_format;
dev_dbg(tve->dev, "encoder mode set:%s\n", adjusted_mode->name);
if (adjusted_mode->vdisplay == 576)
tve->tv_format = TVOUT_CVBS_PAL;
tv_format = TVOUT_CVBS_PAL;
else
tve->tv_format = TVOUT_CVBS_NTSC;
tv_format = TVOUT_CVBS_NTSC;
if (tve->enable) {
if (tve->enable && tve->tv_format != tv_format) {
tve->tv_format = tv_format;
dac_enable(tve, false);
msleep(200);
@@ -490,6 +543,81 @@ rockchip_tve_encoder_atomic_check(struct drm_encoder *encoder,
return 0;
}
static int rockchip_tve_encoder_loader_protect(struct drm_encoder *encoder, bool on)
{
struct rockchip_tve *tve = encoder_to_tve(encoder);
int ret;
if (on) {
ret = pm_runtime_get_sync(tve->dev);
if (ret < 0) {
dev_err(tve->dev, "failed to get pm runtime: %d\n", ret);
return ret;
}
ret = clk_prepare_enable(tve->aclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve aclk: %d\n", ret);
goto err_pm_put;
}
ret = clk_prepare_enable(tve->hclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve hclk: %d\n", ret);
goto err_disable_aclk;
}
ret = clk_prepare_enable(tve->pclk_vdac);
if (ret) {
dev_err(tve->dev, "Cannot enable vdac pclk: %d\n", ret);
goto err_disable_hclk;
}
ret = clk_prepare_enable(tve->dclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve dclk: %d\n", ret);
goto err_disable_pclk;
}
ret = clk_prepare_enable(tve->dclk_4x);
if (ret) {
dev_err(tve->dev, "Cannot enable tve dclk_4x: %d\n", ret);
goto err_disable_dclk;
}
tve->enable = 1;
} else {
ret = pm_runtime_put(tve->dev);
if (ret < 0) {
dev_err(tve->dev, "failed to put pm runtime: %d\n", ret);
return ret;
}
clk_disable_unprepare(tve->dclk_4x);
clk_disable_unprepare(tve->dclk);
clk_disable_unprepare(tve->pclk_vdac);
clk_disable_unprepare(tve->hclk);
clk_disable_unprepare(tve->aclk);
tve->enable = 0;
}
return 0;
err_disable_dclk:
clk_disable_unprepare(tve->dclk);
err_disable_pclk:
clk_disable_unprepare(tve->pclk_vdac);
err_disable_hclk:
clk_disable_unprepare(tve->hclk);
err_disable_aclk:
clk_disable_unprepare(tve->aclk);
err_pm_put:
pm_runtime_put_sync(tve->dev);
return ret;
}
static const struct drm_connector_helper_funcs
rockchip_tve_connector_helper_funcs = {
.mode_valid = rockchip_tve_mode_valid,
@@ -888,12 +1016,6 @@ static int rockchip_tve_bind(struct device *dev, struct device *master,
dev_err(tve->dev, "Unable to get tve aclk\n");
return PTR_ERR(tve->aclk);
}
ret = clk_prepare_enable(tve->aclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve aclk: %d\n", ret);
return ret;
}
} else if (tve->soc_type == SOC_RK3528) {
tve->hclk = devm_clk_get(tve->dev, "hclk");
if (IS_ERR(tve->hclk)) {
@@ -901,48 +1023,24 @@ static int rockchip_tve_bind(struct device *dev, struct device *master,
return PTR_ERR(tve->hclk);
}
ret = clk_prepare_enable(tve->hclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve hclk: %d\n", ret);
return ret;
}
tve->pclk_vdac = devm_clk_get(tve->dev, "pclk_vdac");
if (IS_ERR(tve->pclk_vdac)) {
dev_err(tve->dev, "Unable to get vdac pclk\n");
return PTR_ERR(tve->pclk_vdac);
}
ret = clk_prepare_enable(tve->pclk_vdac);
if (ret) {
dev_err(tve->dev, "Cannot enable vdac pclk: %d\n", ret);
return ret;
}
tve->dclk = devm_clk_get(tve->dev, "dclk");
if (IS_ERR(tve->dclk)) {
dev_err(tve->dev, "Unable to get tve dclk\n");
return PTR_ERR(tve->dclk);
}
ret = clk_prepare_enable(tve->dclk);
if (ret) {
dev_err(tve->dev, "Cannot enable tve dclk: %d\n", ret);
return ret;
}
if (tve->upsample_mode == DCLK_UPSAMPLEx4) {
tve->dclk_4x = devm_clk_get(tve->dev, "dclk_4x");
if (IS_ERR(tve->dclk_4x)) {
dev_err(tve->dev, "Unable to get tve dclk_4x\n");
return PTR_ERR(tve->dclk_4x);
}
ret = clk_prepare_enable(tve->dclk_4x);
if (ret) {
dev_err(tve->dev, "Cannot enable tve dclk_4x: %d\n", ret);
return ret;
}
}
}
@@ -960,7 +1058,7 @@ static int rockchip_tve_bind(struct device *dev, struct device *master,
DRM_MODE_ENCODER_TVDAC, NULL);
if (ret < 0) {
dev_err(tve->dev, "failed to initialize encoder with drm\n");
goto err_disable_aclk;
return ret;
}
drm_encoder_helper_add(encoder, &rockchip_tve_encoder_helper_funcs);
@@ -985,6 +1083,7 @@ static int rockchip_tve_bind(struct device *dev, struct device *master,
}
tve->sub_dev.connector = &tve->connector;
tve->sub_dev.of_node = tve->dev->of_node;
tve->sub_dev.loader_protect = rockchip_tve_encoder_loader_protect;
rockchip_drm_register_sub_dev(&tve->sub_dev);
pm_runtime_enable(dev);
@@ -997,9 +1096,6 @@ err_free_connector:
drm_connector_cleanup(connector);
err_free_encoder:
drm_encoder_cleanup(encoder);
err_disable_aclk:
if (tve->soc_type == SOC_RK3036)
clk_disable_unprepare(tve->aclk);
return ret;
}