diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_mixer.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_mixer.c | 118 |
1 files changed, 43 insertions, 75 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 8874c1fcb3ab..cae98db33062 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -882,10 +882,12 @@ static int mixer_initialize(struct mixer_context *mixer_ctx, } } - if (!is_drm_iommu_supported(mixer_ctx->drm_dev)) - return 0; + ret = drm_iommu_attach_device_if_possible(mixer_ctx->crtc, drm_dev, + mixer_ctx->dev); + if (ret) + priv->pipe--; - return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev); + return ret; } static void mixer_ctx_remove(struct mixer_context *mixer_ctx) @@ -937,8 +939,6 @@ static void mixer_win_commit(struct exynos_drm_crtc *crtc, unsigned int win) vp_video_buffer(mixer_ctx, win); else mixer_graph_buffer(mixer_ctx, win); - - mixer_ctx->planes[win].enabled = true; } static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) @@ -952,7 +952,6 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) mutex_lock(&mixer_ctx->mixer_mutex); if (!mixer_ctx->powered) { mutex_unlock(&mixer_ctx->mixer_mutex); - mixer_ctx->planes[win].resume = false; return; } mutex_unlock(&mixer_ctx->mixer_mutex); @@ -964,8 +963,6 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) mixer_vsync_set_update(mixer_ctx, true); spin_unlock_irqrestore(&res->reg_slock, flags); - - mixer_ctx->planes[win].enabled = false; } static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) @@ -1000,36 +997,11 @@ static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe); } -static void mixer_window_suspend(struct mixer_context *ctx) -{ - struct exynos_drm_plane *plane; - int i; - - for (i = 0; i < MIXER_WIN_NR; i++) { - plane = &ctx->planes[i]; - plane->resume = plane->enabled; - mixer_win_disable(ctx->crtc, i); - } - mixer_wait_for_vblank(ctx->crtc); -} - -static void mixer_window_resume(struct mixer_context *ctx) -{ - struct exynos_drm_plane *plane; - int i; - - for (i = 0; i < MIXER_WIN_NR; i++) { - plane = &ctx->planes[i]; - plane->enabled = plane->resume; - plane->resume = false; - if (plane->enabled) - mixer_win_commit(ctx->crtc, i); - } -} - -static void mixer_poweron(struct mixer_context *ctx) +static void mixer_enable(struct exynos_drm_crtc *crtc) { + struct mixer_context *ctx = crtc->ctx; struct mixer_resources *res = &ctx->mixer_res; + int ret; mutex_lock(&ctx->mixer_mutex); if (ctx->powered) { @@ -1041,12 +1013,32 @@ static void mixer_poweron(struct mixer_context *ctx) pm_runtime_get_sync(ctx->dev); - clk_prepare_enable(res->mixer); - clk_prepare_enable(res->hdmi); + ret = clk_prepare_enable(res->mixer); + if (ret < 0) { + DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret); + return; + } + ret = clk_prepare_enable(res->hdmi); + if (ret < 0) { + DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); + return; + } if (ctx->vp_enabled) { - clk_prepare_enable(res->vp); - if (ctx->has_sclk) - clk_prepare_enable(res->sclk_mixer); + ret = clk_prepare_enable(res->vp); + if (ret < 0) { + DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n", + ret); + return; + } + if (ctx->has_sclk) { + ret = clk_prepare_enable(res->sclk_mixer); + if (ret < 0) { + DRM_ERROR("Failed to prepare_enable the " \ + "sclk_mixer clk [%d]\n", + ret); + return; + } + } } mutex_lock(&ctx->mixer_mutex); @@ -1057,13 +1049,13 @@ static void mixer_poweron(struct mixer_context *ctx) mixer_reg_write(res, MXR_INT_EN, ctx->int_en); mixer_win_reset(ctx); - - mixer_window_resume(ctx); } -static void mixer_poweroff(struct mixer_context *ctx) +static void mixer_disable(struct exynos_drm_crtc *crtc) { + struct mixer_context *ctx = crtc->ctx; struct mixer_resources *res = &ctx->mixer_res; + int i; mutex_lock(&ctx->mixer_mutex); if (!ctx->powered) { @@ -1074,7 +1066,9 @@ static void mixer_poweroff(struct mixer_context *ctx) mixer_stop(ctx); mixer_regs_dump(ctx); - mixer_window_suspend(ctx); + + for (i = 0; i < MIXER_WIN_NR; i++) + mixer_win_disable(crtc, i); ctx->int_en = mixer_reg_read(res, MXR_INT_EN); @@ -1093,23 +1087,6 @@ static void mixer_poweroff(struct mixer_context *ctx) pm_runtime_put_sync(ctx->dev); } -static void mixer_dpms(struct exynos_drm_crtc *crtc, int mode) -{ - switch (mode) { - case DRM_MODE_DPMS_ON: - mixer_poweron(crtc->ctx); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - mixer_poweroff(crtc->ctx); - break; - default: - DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); - break; - } -} - /* Only valid for Mixer version 16.0.33.0 */ int mixer_check_mode(struct drm_display_mode *mode) { @@ -1131,7 +1108,8 @@ int mixer_check_mode(struct drm_display_mode *mode) } static const struct exynos_drm_crtc_ops mixer_crtc_ops = { - .dpms = mixer_dpms, + .enable = mixer_enable, + .disable = mixer_disable, .enable_vblank = mixer_enable_vblank, .disable_vblank = mixer_disable_vblank, .wait_for_vblank = mixer_wait_for_vblank, @@ -1280,18 +1258,9 @@ static int mixer_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, - EXYNOS_DISPLAY_TYPE_HDMI); - if (ret) - return ret; - ret = component_add(&pdev->dev, &mixer_component_ops); - if (ret) { - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); - return ret; - } - - pm_runtime_enable(dev); + if (!ret) + pm_runtime_enable(dev); return ret; } @@ -1301,7 +1270,6 @@ static int mixer_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); component_del(&pdev->dev, &mixer_component_ops); - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); return 0; } |