On 2015년 08월 20일 11:33, Hyungwon Hwang wrote: > Each CRTC's atomic_{begin/flush} must stop/start the update of shadow > registers to active register in the functions. This patch achieves these > purpose by moving the setting of protection bits to those functions from > {fimd/decon}_update_plane. Hyungwon, Gustavo already posted atomic_begin/flush support. However, he didn't consider decon drivers. Can you post only atomic_begin/flush support for decon drivers? Thanks, Inki Dae > > Signed-off-by: Hyungwon Hwang <human.hwang@xxxxxxxxxxx> > --- > drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 47 +++++++++++++++++------- > drivers/gpu/drm/exynos/exynos7_drm_decon.c | 47 ++++++++++++++++-------- > drivers/gpu/drm/exynos/exynos_drm_fimd.c | 51 ++++++++++++++++++--------- > 3 files changed, 103 insertions(+), 42 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c > index 484e312..fef0333 100644 > --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c > +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c > @@ -31,6 +31,7 @@ struct decon_context { > struct drm_device *drm_dev; > struct exynos_drm_crtc *crtc; > struct exynos_drm_plane planes[WINDOWS_NR]; > + unsigned int updated_plane; > void __iomem *addr; > struct clk *clks[6]; > unsigned int default_win; > @@ -204,17 +205,17 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, > writel(val, ctx->addr + DECON_WINCONx(win)); > } > > -static void decon_shadow_protect_win(struct decon_context *ctx, int win, > - bool protect) > +static void decon_shadow_protect_win(struct decon_context *ctx, > + unsigned int win_bits, bool protect) > { > u32 val; > > val = readl(ctx->addr + DECON_SHADOWCON); > > if (protect) > - val |= SHADOWCON_Wx_PROTECT(win); > + val |= win_bits; > else > - val &= ~SHADOWCON_Wx_PROTECT(win); > + val &= ~win_bits; > > writel(val, ctx->addr + DECON_SHADOWCON); > } > @@ -232,8 +233,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, > if (ctx->suspended) > return; > > - decon_shadow_protect_win(ctx, win, true); > - > val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y); > writel(val, ctx->addr + DECON_VIDOSDxA(win)); > > @@ -265,15 +264,12 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, > val |= WINCONx_ENWIN_F; > writel(val, ctx->addr + DECON_WINCONx(win)); > > - decon_shadow_protect_win(ctx, win, false); > - > /* standalone update */ > val = readl(ctx->addr + DECON_UPDATE); > val |= STANDALONE_UPDATE_F; > writel(val, ctx->addr + DECON_UPDATE); > > - if (ctx->i80_if) > - atomic_set(&ctx->win_updated, 1); > + ctx->updated_plane |= SHADOWCON_Wx_PROTECT(win); > } > > static void decon_disable_plane(struct exynos_drm_crtc *crtc, > @@ -286,14 +282,14 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, > if (ctx->suspended) > return; > > - decon_shadow_protect_win(ctx, win, true); > + decon_shadow_protect_win(ctx, SHADOWCON_Wx_PROTECT(win), true); > > /* window disable */ > val = readl(ctx->addr + DECON_WINCONx(win)); > val &= ~WINCONx_ENWIN_F; > writel(val, ctx->addr + DECON_WINCONx(win)); > > - decon_shadow_protect_win(ctx, win, false); > + decon_shadow_protect_win(ctx, SHADOWCON_Wx_PROTECT(win), false); > > /* standalone update */ > val = readl(ctx->addr + DECON_UPDATE); > @@ -405,6 +401,31 @@ void decon_te_irq_handler(struct exynos_drm_crtc *crtc) > drm_crtc_handle_vblank(&ctx->crtc->base); > } > > +static void decon_begin(struct exynos_drm_crtc *crtc) > +{ > + struct decon_context *ctx = crtc->ctx; > + int i; > + unsigned int val = 0; > + > + for (i = 0; i < WINDOWS_NR; i++) > + val |= SHADOWCON_Wx_PROTECT(i); > + > + /* protect windows */ > + decon_shadow_protect_win(ctx, val, true); > +} > + > +static void decon_flush(struct exynos_drm_crtc *crtc) > +{ > + struct decon_context *ctx = crtc->ctx; > + > + if (ctx->updated_plane) { > + decon_shadow_protect_win(ctx, ctx->updated_plane, false); > + > + if (ctx->i80_if) > + atomic_set(&ctx->win_updated, 1); > + } > +} > + > static void decon_clear_channels(struct exynos_drm_crtc *crtc) > { > struct decon_context *ctx = crtc->ctx; > @@ -458,6 +479,8 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = { > .update_plane = decon_update_plane, > .disable_plane = decon_disable_plane, > .te_handler = decon_te_irq_handler, > + .atomic_begin = decon_begin, > + .atomic_flush = decon_flush, > }; > > static int decon_bind(struct device *dev, struct device *master, void *data) > diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c > index 0792654..c81de86 100644 > --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c > +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c > @@ -47,6 +47,7 @@ struct decon_context { > struct drm_device *drm_dev; > struct exynos_drm_crtc *crtc; > struct exynos_drm_plane planes[WINDOWS_NR]; > + unsigned int updated_plane; > struct clk *pclk; > struct clk *aclk; > struct clk *eclk; > @@ -369,17 +370,15 @@ static void decon_win_set_colkey(struct decon_context *ctx, unsigned int win) > * @protect: 1 to protect (disable updates) > */ > static void decon_shadow_protect_win(struct decon_context *ctx, > - unsigned int win, bool protect) > + unsigned int win_bits, bool protect) > { > - u32 bits, val; > - > - bits = SHADOWCON_WINx_PROTECT(win); > + u32 val; > > val = readl(ctx->regs + SHADOWCON); > if (protect) > - val |= bits; > + val |= win_bits; > else > - val &= ~bits; > + val &= ~win_bits; > writel(val, ctx->regs + SHADOWCON); > } > > @@ -410,9 +409,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, > * is set. > */ > > - /* protect windows */ > - decon_shadow_protect_win(ctx, win, true); > - > /* buffer start address */ > val = (unsigned long)plane->dma_addr[0]; > writel(val, ctx->regs + VIDW_BUF_START(win)); > @@ -484,12 +480,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, > val |= WINCONx_ENWIN; > writel(val, ctx->regs + WINCON(win)); > > - /* Enable DMA channel and unprotect windows */ > - decon_shadow_protect_win(ctx, win, false); > - > val = readl(ctx->regs + DECON_UPDATE); > val |= DECON_UPDATE_STANDALONE_F; > writel(val, ctx->regs + DECON_UPDATE); > + > + ctx->updated_plane |= SHADOWCON_WINx_PROTECT(win); > } > > static void decon_disable_plane(struct exynos_drm_crtc *crtc, > @@ -503,7 +498,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, > return; > > /* protect windows */ > - decon_shadow_protect_win(ctx, win, true); > + decon_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), true); > > /* wincon */ > val = readl(ctx->regs + WINCON(win)); > @@ -511,7 +506,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, > writel(val, ctx->regs + WINCON(win)); > > /* unprotect windows */ > - decon_shadow_protect_win(ctx, win, false); > + decon_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), false); > > val = readl(ctx->regs + DECON_UPDATE); > val |= DECON_UPDATE_STANDALONE_F; > @@ -606,6 +601,28 @@ static void decon_disable(struct exynos_drm_crtc *crtc) > ctx->suspended = true; > } > > +static void decon_begin(struct exynos_drm_crtc *crtc) > +{ > + struct decon_context *ctx = crtc->ctx; > + int i; > + unsigned int val = 0; > + > + for (i = 0; i < WINDOWS_NR; i++) > + val |= SHADOWCON_WINx_PROTECT(i); > + > + /* protect windows */ > + decon_shadow_protect_win(ctx, val, true); > +} > + > +static void decon_flush(struct exynos_drm_crtc *crtc) > +{ > + struct decon_context *ctx = crtc->ctx; > + > + if (ctx->updated_plane) > + decon_shadow_protect_win(ctx, ctx->updated_plane, false); > +} > + > + > static const struct exynos_drm_crtc_ops decon_crtc_ops = { > .enable = decon_enable, > .disable = decon_disable, > @@ -616,6 +633,8 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = { > .wait_for_vblank = decon_wait_for_vblank, > .update_plane = decon_update_plane, > .disable_plane = decon_disable_plane, > + .atomic_begin = decon_begin, > + .atomic_flush = decon_flush, > }; > > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > index 5def6bc..0b41bb2 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > @@ -149,6 +149,7 @@ struct fimd_context { > struct drm_device *drm_dev; > struct exynos_drm_crtc *crtc; > struct exynos_drm_plane planes[WINDOWS_NR]; > + unsigned int updated_plane; > struct clk *bus_clk; > struct clk *lcd_clk; > void __iomem *regs; > @@ -587,23 +588,22 @@ static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win) > * @protect: 1 to protect (disable updates) > */ > static void fimd_shadow_protect_win(struct fimd_context *ctx, > - unsigned int win, bool protect) > + unsigned int win_bits, bool protect) > { > - u32 reg, bits, val; > + u32 reg, val; > > if (ctx->driver_data->has_shadowcon) { > reg = SHADOWCON; > - bits = SHADOWCON_WINx_PROTECT(win); > } else { > reg = PRTCON; > - bits = PRTCON_PROTECT; > + win_bits = PRTCON_PROTECT; > } > > val = readl(ctx->regs + reg); > if (protect) > - val |= bits; > + val |= win_bits; > else > - val &= ~bits; > + val &= ~win_bits; > writel(val, ctx->regs + reg); > } > > @@ -632,10 +632,6 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, > * is set. > */ > > - /* protect windows */ > - fimd_shadow_protect_win(ctx, win, true); > - > - > offset = plane->src_x * bpp; > offset += plane->src_y * pitch; > > @@ -707,11 +703,32 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, > if (ctx->driver_data->has_shadowcon) > fimd_enable_shadow_channel_path(ctx, win, true); > > - /* Enable DMA channel and unprotect windows */ > - fimd_shadow_protect_win(ctx, win, false); > + ctx->updated_plane |= SHADOWCON_WINx_PROTECT(win); > +} > + > +static void fimd_begin(struct exynos_drm_crtc *crtc) > +{ > + struct fimd_context *ctx = crtc->ctx; > + int i; > + unsigned int val = 0; > + > + for (i = 0; i < WINDOWS_NR; i++) > + val |= SHADOWCON_WINx_PROTECT(i); > > - if (ctx->i80_if) > - atomic_set(&ctx->win_updated, 1); > + /* protect windows */ > + fimd_shadow_protect_win(ctx, val, true); > +} > + > +static void fimd_flush(struct exynos_drm_crtc *crtc) > +{ > + struct fimd_context *ctx = crtc->ctx; > + > + if (ctx->updated_plane) { > + fimd_shadow_protect_win(ctx, ctx->updated_plane, false); > + > + if (ctx->i80_if) > + atomic_set(&ctx->win_updated, 1); > + } > } > > static void fimd_disable_plane(struct exynos_drm_crtc *crtc, > @@ -724,7 +741,7 @@ static void fimd_disable_plane(struct exynos_drm_crtc *crtc, > return; > > /* protect windows */ > - fimd_shadow_protect_win(ctx, win, true); > + fimd_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), true); > > fimd_enable_video_output(ctx, win, false); > > @@ -732,7 +749,7 @@ static void fimd_disable_plane(struct exynos_drm_crtc *crtc, > fimd_enable_shadow_channel_path(ctx, win, false); > > /* unprotect windows */ > - fimd_shadow_protect_win(ctx, win, false); > + fimd_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), false); > } > > static void fimd_enable(struct exynos_drm_crtc *crtc) > @@ -879,6 +896,8 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = { > .disable_plane = fimd_disable_plane, > .te_handler = fimd_te_handler, > .clock_enable = fimd_dp_clock_enable, > + .atomic_begin = fimd_begin, > + .atomic_flush = fimd_flush, > }; > > static irqreturn_t fimd_irq_handler(int irq, void *dev_id) > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel