summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vc4/vc4_vec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_vec.c')
-rw-r--r--drivers/gpu/drm/vc4/vc4_vec.c67
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);
}