drm/exynos: remove chained calls to enable
With atomic modesetting all the control for CRTC, Planes, Encoders and Connectors should come from DRM core, so the driver is not allowed to enable or disable planes from inside the crtc_enable()/disable() call. But it needs to disable planes with crtc_disable in exynos driver internally. Because crtc is disabled before plane is disabled, it means plane_disable just returns without any register changes, then we cannot be sure setting register to disable plane when crtc is disable. This patch removes this chainned calls to enable plane from exynos hw drivers code letting only DRM core touch planes except to disable plane. Also it leads eliminable enabled and resume of struct exynos_drm_plane. Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
ba4b77c485
commit
c329f667ba
|
@ -410,11 +410,8 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
|
||||||
plane = &ctx->planes[win];
|
plane = &ctx->planes[win];
|
||||||
|
|
||||||
/* If suspended, enable this on resume */
|
if (ctx->suspended)
|
||||||
if (ctx->suspended) {
|
|
||||||
plane->resume = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SHADOWCON/PRTCON register is used for enabling timing.
|
* SHADOWCON/PRTCON register is used for enabling timing.
|
||||||
|
@ -506,8 +503,6 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
val = readl(ctx->regs + DECON_UPDATE);
|
val = readl(ctx->regs + DECON_UPDATE);
|
||||||
val |= DECON_UPDATE_STANDALONE_F;
|
val |= DECON_UPDATE_STANDALONE_F;
|
||||||
writel(val, ctx->regs + DECON_UPDATE);
|
writel(val, ctx->regs + DECON_UPDATE);
|
||||||
|
|
||||||
plane->enabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
@ -521,11 +516,8 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
|
||||||
plane = &ctx->planes[win];
|
plane = &ctx->planes[win];
|
||||||
|
|
||||||
if (ctx->suspended) {
|
if (ctx->suspended)
|
||||||
/* do not resume this window*/
|
|
||||||
plane->resume = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* protect windows */
|
/* protect windows */
|
||||||
decon_shadow_protect_win(ctx, win, true);
|
decon_shadow_protect_win(ctx, win, true);
|
||||||
|
@ -541,49 +533,6 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
val = readl(ctx->regs + DECON_UPDATE);
|
val = readl(ctx->regs + DECON_UPDATE);
|
||||||
val |= DECON_UPDATE_STANDALONE_F;
|
val |= DECON_UPDATE_STANDALONE_F;
|
||||||
writel(val, ctx->regs + DECON_UPDATE);
|
writel(val, ctx->regs + DECON_UPDATE);
|
||||||
|
|
||||||
plane->enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decon_window_suspend(struct decon_context *ctx)
|
|
||||||
{
|
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < WINDOWS_NR; i++) {
|
|
||||||
plane = &ctx->planes[i];
|
|
||||||
plane->resume = plane->enabled;
|
|
||||||
if (plane->enabled)
|
|
||||||
decon_win_disable(ctx->crtc, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decon_window_resume(struct decon_context *ctx)
|
|
||||||
{
|
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < WINDOWS_NR; i++) {
|
|
||||||
plane = &ctx->planes[i];
|
|
||||||
plane->enabled = plane->resume;
|
|
||||||
plane->resume = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decon_apply(struct decon_context *ctx)
|
|
||||||
{
|
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < WINDOWS_NR; i++) {
|
|
||||||
plane = &ctx->planes[i];
|
|
||||||
if (plane->enabled)
|
|
||||||
decon_win_commit(ctx->crtc, i);
|
|
||||||
else
|
|
||||||
decon_win_disable(ctx->crtc, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
decon_commit(ctx->crtc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decon_init(struct decon_context *ctx)
|
static void decon_init(struct decon_context *ctx)
|
||||||
|
@ -645,14 +594,13 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
|
||||||
if (test_and_clear_bit(0, &ctx->irq_flags))
|
if (test_and_clear_bit(0, &ctx->irq_flags))
|
||||||
decon_enable_vblank(ctx->crtc);
|
decon_enable_vblank(ctx->crtc);
|
||||||
|
|
||||||
decon_window_resume(ctx);
|
decon_commit(ctx->crtc);
|
||||||
|
|
||||||
decon_apply(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decon_disable(struct exynos_drm_crtc *crtc)
|
static void decon_disable(struct exynos_drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct decon_context *ctx = crtc->ctx;
|
struct decon_context *ctx = crtc->ctx;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (ctx->suspended)
|
if (ctx->suspended)
|
||||||
return;
|
return;
|
||||||
|
@ -662,7 +610,8 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
|
||||||
* suspend that connector. Otherwise we might try to scan from
|
* suspend that connector. Otherwise we might try to scan from
|
||||||
* a destroyed buffer later.
|
* a destroyed buffer later.
|
||||||
*/
|
*/
|
||||||
decon_window_suspend(ctx);
|
for (i = 0; i < WINDOWS_NR; i++)
|
||||||
|
decon_win_disable(crtc, i);
|
||||||
|
|
||||||
clk_disable_unprepare(ctx->vclk);
|
clk_disable_unprepare(ctx->vclk);
|
||||||
clk_disable_unprepare(ctx->eclk);
|
clk_disable_unprepare(ctx->eclk);
|
||||||
|
|
|
@ -64,8 +64,6 @@ enum exynos_drm_output_type {
|
||||||
* @dma_addr: array of bus(accessed by dma) address to the memory region
|
* @dma_addr: array of bus(accessed by dma) address to the memory region
|
||||||
* allocated for a overlay.
|
* allocated for a overlay.
|
||||||
* @zpos: order of overlay layer(z position).
|
* @zpos: order of overlay layer(z position).
|
||||||
* @enabled: enabled or not.
|
|
||||||
* @resume: to resume or not.
|
|
||||||
*
|
*
|
||||||
* this structure is common to exynos SoC and its contents would be copied
|
* this structure is common to exynos SoC and its contents would be copied
|
||||||
* to hardware specific overlay info.
|
* to hardware specific overlay info.
|
||||||
|
@ -94,9 +92,6 @@ struct exynos_drm_plane {
|
||||||
uint32_t pixel_format;
|
uint32_t pixel_format;
|
||||||
dma_addr_t dma_addr[MAX_FB_BUFFER];
|
dma_addr_t dma_addr[MAX_FB_BUFFER];
|
||||||
unsigned int zpos;
|
unsigned int zpos;
|
||||||
|
|
||||||
bool enabled:1;
|
|
||||||
bool resume:1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -634,11 +634,8 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
|
||||||
plane = &ctx->planes[win];
|
plane = &ctx->planes[win];
|
||||||
|
|
||||||
/* If suspended, enable this on resume */
|
if (ctx->suspended)
|
||||||
if (ctx->suspended) {
|
|
||||||
plane->resume = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SHADOWCON/PRTCON register is used for enabling timing.
|
* SHADOWCON/PRTCON register is used for enabling timing.
|
||||||
|
@ -728,8 +725,6 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
/* Enable DMA channel and unprotect windows */
|
/* Enable DMA channel and unprotect windows */
|
||||||
fimd_shadow_protect_win(ctx, win, false);
|
fimd_shadow_protect_win(ctx, win, false);
|
||||||
|
|
||||||
plane->enabled = true;
|
|
||||||
|
|
||||||
if (ctx->i80_if)
|
if (ctx->i80_if)
|
||||||
atomic_set(&ctx->win_updated, 1);
|
atomic_set(&ctx->win_updated, 1);
|
||||||
}
|
}
|
||||||
|
@ -744,11 +739,8 @@ static void fimd_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
|
||||||
plane = &ctx->planes[win];
|
plane = &ctx->planes[win];
|
||||||
|
|
||||||
if (ctx->suspended) {
|
if (ctx->suspended)
|
||||||
/* do not resume this window*/
|
|
||||||
plane->resume = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* protect windows */
|
/* protect windows */
|
||||||
fimd_shadow_protect_win(ctx, win, true);
|
fimd_shadow_protect_win(ctx, win, true);
|
||||||
|
@ -760,49 +752,6 @@ static void fimd_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
|
||||||
/* unprotect windows */
|
/* unprotect windows */
|
||||||
fimd_shadow_protect_win(ctx, win, false);
|
fimd_shadow_protect_win(ctx, win, false);
|
||||||
|
|
||||||
plane->enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fimd_window_suspend(struct fimd_context *ctx)
|
|
||||||
{
|
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < WINDOWS_NR; i++) {
|
|
||||||
plane = &ctx->planes[i];
|
|
||||||
plane->resume = plane->enabled;
|
|
||||||
if (plane->enabled)
|
|
||||||
fimd_win_disable(ctx->crtc, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fimd_window_resume(struct fimd_context *ctx)
|
|
||||||
{
|
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < WINDOWS_NR; i++) {
|
|
||||||
plane = &ctx->planes[i];
|
|
||||||
plane->enabled = plane->resume;
|
|
||||||
plane->resume = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fimd_apply(struct fimd_context *ctx)
|
|
||||||
{
|
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < WINDOWS_NR; i++) {
|
|
||||||
plane = &ctx->planes[i];
|
|
||||||
if (plane->enabled)
|
|
||||||
fimd_win_commit(ctx->crtc, i);
|
|
||||||
else
|
|
||||||
fimd_win_disable(ctx->crtc, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
fimd_commit(ctx->crtc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fimd_enable(struct exynos_drm_crtc *crtc)
|
static void fimd_enable(struct exynos_drm_crtc *crtc)
|
||||||
|
@ -833,14 +782,13 @@ static void fimd_enable(struct exynos_drm_crtc *crtc)
|
||||||
if (test_and_clear_bit(0, &ctx->irq_flags))
|
if (test_and_clear_bit(0, &ctx->irq_flags))
|
||||||
fimd_enable_vblank(ctx->crtc);
|
fimd_enable_vblank(ctx->crtc);
|
||||||
|
|
||||||
fimd_window_resume(ctx);
|
fimd_commit(ctx->crtc);
|
||||||
|
|
||||||
fimd_apply(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fimd_disable(struct exynos_drm_crtc *crtc)
|
static void fimd_disable(struct exynos_drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct fimd_context *ctx = crtc->ctx;
|
struct fimd_context *ctx = crtc->ctx;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (ctx->suspended)
|
if (ctx->suspended)
|
||||||
return;
|
return;
|
||||||
|
@ -850,7 +798,8 @@ static void fimd_disable(struct exynos_drm_crtc *crtc)
|
||||||
* suspend that connector. Otherwise we might try to scan from
|
* suspend that connector. Otherwise we might try to scan from
|
||||||
* a destroyed buffer later.
|
* a destroyed buffer later.
|
||||||
*/
|
*/
|
||||||
fimd_window_suspend(ctx);
|
for (i = 0; i < WINDOWS_NR; i++)
|
||||||
|
fimd_win_disable(crtc, i);
|
||||||
|
|
||||||
clk_disable_unprepare(ctx->lcd_clk);
|
clk_disable_unprepare(ctx->lcd_clk);
|
||||||
clk_disable_unprepare(ctx->bus_clk);
|
clk_disable_unprepare(ctx->bus_clk);
|
||||||
|
|
|
@ -131,33 +131,15 @@ static void vidi_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
|
||||||
plane = &ctx->planes[win];
|
plane = &ctx->planes[win];
|
||||||
|
|
||||||
plane->enabled = true;
|
|
||||||
|
|
||||||
DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr);
|
DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr);
|
||||||
|
|
||||||
if (ctx->vblank_on)
|
if (ctx->vblank_on)
|
||||||
schedule_work(&ctx->work);
|
schedule_work(&ctx->work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vidi_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
|
||||||
{
|
|
||||||
struct vidi_context *ctx = crtc->ctx;
|
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
|
|
||||||
if (win < 0 || win >= WINDOWS_NR)
|
|
||||||
return;
|
|
||||||
|
|
||||||
plane = &ctx->planes[win];
|
|
||||||
plane->enabled = false;
|
|
||||||
|
|
||||||
/* TODO. */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vidi_enable(struct exynos_drm_crtc *crtc)
|
static void vidi_enable(struct exynos_drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct vidi_context *ctx = crtc->ctx;
|
struct vidi_context *ctx = crtc->ctx;
|
||||||
struct exynos_drm_plane *plane;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
mutex_lock(&ctx->lock);
|
mutex_lock(&ctx->lock);
|
||||||
|
|
||||||
|
@ -167,12 +149,6 @@ static void vidi_enable(struct exynos_drm_crtc *crtc)
|
||||||
if (test_and_clear_bit(0, &ctx->irq_flags))
|
if (test_and_clear_bit(0, &ctx->irq_flags))
|
||||||
vidi_enable_vblank(ctx->crtc);
|
vidi_enable_vblank(ctx->crtc);
|
||||||
|
|
||||||
for (i = 0; i < WINDOWS_NR; i++) {
|
|
||||||
plane = &ctx->planes[i];
|
|
||||||
if (plane->enabled)
|
|
||||||
vidi_win_commit(ctx->crtc, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&ctx->lock);
|
mutex_unlock(&ctx->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +180,6 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
|
||||||
.enable_vblank = vidi_enable_vblank,
|
.enable_vblank = vidi_enable_vblank,
|
||||||
.disable_vblank = vidi_disable_vblank,
|
.disable_vblank = vidi_disable_vblank,
|
||||||
.win_commit = vidi_win_commit,
|
.win_commit = vidi_win_commit,
|
||||||
.win_disable = vidi_win_disable,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vidi_fake_vblank_handler(struct work_struct *work)
|
static void vidi_fake_vblank_handler(struct work_struct *work)
|
||||||
|
|
|
@ -937,8 +937,6 @@ static void mixer_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
vp_video_buffer(mixer_ctx, win);
|
vp_video_buffer(mixer_ctx, win);
|
||||||
else
|
else
|
||||||
mixer_graph_buffer(mixer_ctx, win);
|
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)
|
static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
@ -952,7 +950,6 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
mutex_lock(&mixer_ctx->mixer_mutex);
|
mutex_lock(&mixer_ctx->mixer_mutex);
|
||||||
if (!mixer_ctx->powered) {
|
if (!mixer_ctx->powered) {
|
||||||
mutex_unlock(&mixer_ctx->mixer_mutex);
|
mutex_unlock(&mixer_ctx->mixer_mutex);
|
||||||
mixer_ctx->planes[win].resume = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mutex_unlock(&mixer_ctx->mixer_mutex);
|
mutex_unlock(&mixer_ctx->mixer_mutex);
|
||||||
|
@ -964,8 +961,6 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
|
||||||
|
|
||||||
mixer_vsync_set_update(mixer_ctx, true);
|
mixer_vsync_set_update(mixer_ctx, true);
|
||||||
spin_unlock_irqrestore(&res->reg_slock, flags);
|
spin_unlock_irqrestore(&res->reg_slock, flags);
|
||||||
|
|
||||||
mixer_ctx->planes[win].enabled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
|
static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
|
||||||
|
@ -1000,32 +995,6 @@ static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
|
||||||
drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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_enable(struct exynos_drm_crtc *crtc)
|
static void mixer_enable(struct exynos_drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct mixer_context *ctx = crtc->ctx;
|
struct mixer_context *ctx = crtc->ctx;
|
||||||
|
@ -1078,14 +1047,13 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
|
||||||
|
|
||||||
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
|
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
|
||||||
mixer_win_reset(ctx);
|
mixer_win_reset(ctx);
|
||||||
|
|
||||||
mixer_window_resume(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_disable(struct exynos_drm_crtc *crtc)
|
static void mixer_disable(struct exynos_drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct mixer_context *ctx = crtc->ctx;
|
struct mixer_context *ctx = crtc->ctx;
|
||||||
struct mixer_resources *res = &ctx->mixer_res;
|
struct mixer_resources *res = &ctx->mixer_res;
|
||||||
|
int i;
|
||||||
|
|
||||||
mutex_lock(&ctx->mixer_mutex);
|
mutex_lock(&ctx->mixer_mutex);
|
||||||
if (!ctx->powered) {
|
if (!ctx->powered) {
|
||||||
|
@ -1096,7 +1064,9 @@ static void mixer_disable(struct exynos_drm_crtc *crtc)
|
||||||
|
|
||||||
mixer_stop(ctx);
|
mixer_stop(ctx);
|
||||||
mixer_regs_dump(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);
|
ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue