diff options
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_vec.c')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_vec.c | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 4b843b18c006..df6adef96050 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -14,6 +14,7 @@ */ #include <drm/drm_atomic_helper.h> +#include <drm/drm_drv.h> #include <drm/drm_edid.h> #include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> @@ -225,14 +226,30 @@ static const struct debugfs_reg32 vec_regs[] = { static void vc4_vec_ntsc_mode_set(struct vc4_vec *vec) { + struct drm_device *drm = vec->connector.dev; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN); VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); + + drm_dev_exit(idx); } static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec) { + struct drm_device *drm = vec->connector.dev; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD); VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); + + drm_dev_exit(idx); } static const struct drm_display_mode ntsc_mode = { @@ -244,17 +261,33 @@ static const struct drm_display_mode ntsc_mode = { static void vc4_vec_pal_mode_set(struct vc4_vec *vec) { + struct drm_device *drm = vec->connector.dev; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); + + drm_dev_exit(idx); } static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec) { + struct drm_device *drm = vec->connector.dev; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ); VEC_WRITE(VEC_FREQ3_2, 0x223b); VEC_WRITE(VEC_FREQ1_0, 0x61d1); + + drm_dev_exit(idx); } static const struct drm_display_mode pal_mode = { @@ -344,8 +377,12 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) static void vc4_vec_encoder_disable(struct drm_encoder *encoder) { + struct drm_device *drm = encoder->dev; struct vc4_vec *vec = encoder_to_vc4_vec(encoder); - int ret; + int idx, ret; + + if (!drm_dev_enter(drm, &idx)) + return; VEC_WRITE(VEC_CFG, 0); VEC_WRITE(VEC_DAC_MISC, @@ -359,19 +396,29 @@ static void vc4_vec_encoder_disable(struct drm_encoder *encoder) ret = pm_runtime_put(&vec->pdev->dev); if (ret < 0) { DRM_ERROR("Failed to release power domain: %d\n", ret); - return; + goto err_dev_exit; } + + drm_dev_exit(idx); + return; + +err_dev_exit: + drm_dev_exit(idx); } static void vc4_vec_encoder_enable(struct drm_encoder *encoder) { + struct drm_device *drm = encoder->dev; struct vc4_vec *vec = encoder_to_vc4_vec(encoder); - int ret; + int idx, ret; + + if (!drm_dev_enter(drm, &idx)) + return; ret = pm_runtime_get_sync(&vec->pdev->dev); if (ret < 0) { DRM_ERROR("Failed to retain power domain: %d\n", ret); - return; + goto err_dev_exit; } /* @@ -384,13 +431,13 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder) ret = clk_set_rate(vec->clock, 108000000); if (ret) { DRM_ERROR("Failed to set clock rate: %d\n", ret); - return; + goto err_put_runtime_pm; } ret = clk_prepare_enable(vec->clock); if (ret) { DRM_ERROR("Failed to turn on core clock: %d\n", ret); - return; + goto err_put_runtime_pm; } /* Reset the different blocks */ @@ -426,6 +473,14 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder) VEC_WRITE(VEC_DAC_MISC, VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N); VEC_WRITE(VEC_CFG, VEC_CFG_VEC_EN); + + drm_dev_exit(idx); + return; + +err_put_runtime_pm: + pm_runtime_put(&vec->pdev->dev); +err_dev_exit: + drm_dev_exit(idx); } |