mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
drm/rockchip: tve: add .loader_protect() support for tve
If logo display enabled, the rockchip_tve_encoder_loader_protect() helps to set the tve enable/disable status and call pm_runtime_get_sync()/pm_runtime_put(), which allows for the continuation of the display state from the U-Boot stage. In addition, fix the check of tve mode setting in .mode_set() to avoid display flashing, which caused by the off/on switch of dac. Change-Id: I6f1fcaf05cb6e362ce375e447c566fb5356c5380 Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
This commit is contained in:
@@ -486,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);
|
||||
|
||||
@@ -541,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,
|
||||
@@ -1006,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);
|
||||
|
||||
Reference in New Issue
Block a user