Lines Matching +full:burst +full:- +full:wrap
1 // SPDX-License-Identifier: GPL-2.0-only
29 #include "regs-decon5433.h"
99 val = (val & mask) | (readl(ctx->addr + reg) & ~mask); in decon_set_bits()
100 writel(val, ctx->addr + reg); in decon_set_bits()
105 struct decon_context *ctx = crtc->ctx; in decon_enable_vblank()
109 if (crtc->i80_mode) in decon_enable_vblank()
114 writel(val, ctx->addr + DECON_VIDINTCON0); in decon_enable_vblank()
116 enable_irq(ctx->irq); in decon_enable_vblank()
117 if (!(ctx->out_type & I80_HW_TRG)) in decon_enable_vblank()
118 enable_irq(ctx->te_irq); in decon_enable_vblank()
125 struct decon_context *ctx = crtc->ctx; in decon_disable_vblank()
127 if (!(ctx->out_type & I80_HW_TRG)) in decon_disable_vblank()
128 disable_irq_nosync(ctx->te_irq); in decon_disable_vblank()
129 disable_irq_nosync(ctx->irq); in decon_disable_vblank()
131 writel(0, ctx->addr + DECON_VIDINTCON0); in decon_disable_vblank()
143 frm = readl(ctx->addr + DECON_CRFMID); in decon_get_frame_count()
145 status = readl(ctx->addr + DECON_VIDCON1); in decon_get_frame_count()
147 frm = readl(ctx->addr + DECON_CRFMID); in decon_get_frame_count()
148 } while (frm != pfrm && --cnt); in decon_get_frame_count()
158 if (!(ctx->crtc->i80_mode)) in decon_get_frame_count()
159 --frm; in decon_get_frame_count()
162 --frm; in decon_get_frame_count()
167 --frm; in decon_get_frame_count()
178 if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG)) in decon_setup_trigger()
181 if (!(ctx->out_type & I80_HW_TRG)) { in decon_setup_trigger()
184 ctx->addr + DECON_TRIGCON); in decon_setup_trigger()
189 | TRIGCON_HWTRIGEN, ctx->addr + DECON_TRIGCON); in decon_setup_trigger()
191 if (regmap_update_bits(ctx->sysreg, DSD_CFG_MUX, in decon_setup_trigger()
193 DRM_DEV_ERROR(ctx->dev, "Cannot update sysreg.\n"); in decon_setup_trigger()
198 struct decon_context *ctx = crtc->ctx; in decon_commit()
199 struct drm_display_mode *m = &crtc->base.mode; in decon_commit()
203 if (ctx->out_type & IFTYPE_HDMI) { in decon_commit()
204 m->crtc_hsync_start = m->crtc_hdisplay + 10; in decon_commit()
205 m->crtc_hsync_end = m->crtc_htotal - 92; in decon_commit()
206 m->crtc_vsync_start = m->crtc_vdisplay + 1; in decon_commit()
207 m->crtc_vsync_end = m->crtc_vsync_start + 1; in decon_commit()
208 if (m->flags & DRM_MODE_FLAG_INTERLACE) in decon_commit()
218 if (crtc->i80_mode) { in decon_commit()
224 writel(val, ctx->addr + DECON_VIDOUTCON0); in decon_commit()
227 val = VIDTCON2_LINEVAL(m->vdisplay / 2 - 1) | in decon_commit()
228 VIDTCON2_HOZVAL(m->hdisplay - 1); in decon_commit()
230 val = VIDTCON2_LINEVAL(m->vdisplay - 1) | in decon_commit()
231 VIDTCON2_HOZVAL(m->hdisplay - 1); in decon_commit()
232 writel(val, ctx->addr + DECON_VIDTCON2); in decon_commit()
234 if (!crtc->i80_mode) { in decon_commit()
235 int vbp = m->crtc_vtotal - m->crtc_vsync_end; in decon_commit()
236 int vfp = m->crtc_vsync_start - m->crtc_vdisplay; in decon_commit()
239 vbp = vbp / 2 - 1; in decon_commit()
240 val = VIDTCON00_VBPD_F(vbp - 1) | VIDTCON00_VFPD_F(vfp - 1); in decon_commit()
241 writel(val, ctx->addr + DECON_VIDTCON00); in decon_commit()
244 m->crtc_vsync_end - m->crtc_vsync_start - 1); in decon_commit()
245 writel(val, ctx->addr + DECON_VIDTCON01); in decon_commit()
248 m->crtc_htotal - m->crtc_hsync_end - 1) | in decon_commit()
250 m->crtc_hsync_start - m->crtc_hdisplay - 1); in decon_commit()
251 writel(val, ctx->addr + DECON_VIDTCON10); in decon_commit()
254 m->crtc_hsync_end - m->crtc_hsync_start - 1); in decon_commit()
255 writel(val, ctx->addr + DECON_VIDTCON11); in decon_commit()
322 struct exynos_drm_plane *plane = &ctx->planes[win]; in decon_win_set_pixfmt()
324 to_exynos_plane_state(plane->base.state); in decon_win_set_pixfmt()
325 unsigned int alpha = state->base.alpha; in decon_win_set_pixfmt()
329 if (fb->format->has_alpha) in decon_win_set_pixfmt()
330 pixel_alpha = state->base.pixel_blend_mode; in decon_win_set_pixfmt()
334 val = readl(ctx->addr + DECON_WINCONx(win)); in decon_win_set_pixfmt()
337 switch (fb->format->format) { in decon_win_set_pixfmt()
361 DRM_DEV_DEBUG_KMS(ctx->dev, "cpp = %u\n", fb->format->cpp[0]); in decon_win_set_pixfmt()
364 * In case of exynos, setting dma-burst to 16Word causes permanent in decon_win_set_pixfmt()
365 * tearing for very small buffers, e.g. cursor buffer. Burst Mode in decon_win_set_pixfmt()
371 if (fb->width < MIN_FB_WIDTH_FOR_16WORD_BURST) { in decon_win_set_pixfmt()
391 struct decon_context *ctx = crtc->ctx; in decon_atomic_begin()
396 #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
404 to_exynos_plane_state(plane->base.state); in decon_update_plane()
405 struct decon_context *ctx = crtc->ctx; in decon_update_plane()
406 struct drm_framebuffer *fb = state->base.fb; in decon_update_plane()
407 unsigned int win = plane->index; in decon_update_plane()
408 unsigned int cpp = fb->format->cpp[0]; in decon_update_plane()
409 unsigned int pitch = fb->pitches[0]; in decon_update_plane()
413 if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) { in decon_update_plane()
414 val = COORDINATE_X(state->crtc.x) | in decon_update_plane()
415 COORDINATE_Y(state->crtc.y / 2); in decon_update_plane()
416 writel(val, ctx->addr + DECON_VIDOSDxA(win)); in decon_update_plane()
418 val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) | in decon_update_plane()
419 COORDINATE_Y((state->crtc.y + state->crtc.h) / 2 - 1); in decon_update_plane()
420 writel(val, ctx->addr + DECON_VIDOSDxB(win)); in decon_update_plane()
422 val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y); in decon_update_plane()
423 writel(val, ctx->addr + DECON_VIDOSDxA(win)); in decon_update_plane()
425 val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) | in decon_update_plane()
426 COORDINATE_Y(state->crtc.y + state->crtc.h - 1); in decon_update_plane()
427 writel(val, ctx->addr + DECON_VIDOSDxB(win)); in decon_update_plane()
432 writel(val, ctx->addr + DECON_VIDOSDxC(win)); in decon_update_plane()
436 writel(val, ctx->addr + DECON_VIDOSDxD(win)); in decon_update_plane()
438 writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win)); in decon_update_plane()
440 val = dma_addr + pitch * state->src.h; in decon_update_plane()
441 writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); in decon_update_plane()
443 if (!(ctx->out_type & IFTYPE_HDMI)) in decon_update_plane()
444 val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14) in decon_update_plane()
445 | BIT_VAL(state->crtc.w * cpp, 13, 0); in decon_update_plane()
447 val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15) in decon_update_plane()
448 | BIT_VAL(state->crtc.w * cpp, 14, 0); in decon_update_plane()
449 writel(val, ctx->addr + DECON_VIDW0xADD2(win)); in decon_update_plane()
460 struct decon_context *ctx = crtc->ctx; in decon_disable_plane()
461 unsigned int win = plane->index; in decon_disable_plane()
468 struct decon_context *ctx = crtc->ctx; in decon_atomic_flush()
471 spin_lock_irqsave(&ctx->vblank_lock, flags); in decon_atomic_flush()
477 ctx->frame_id = decon_get_frame_count(ctx, true); in decon_atomic_flush()
481 spin_unlock_irqrestore(&ctx->vblank_lock, flags); in decon_atomic_flush()
490 writel(0, ctx->addr + DECON_VIDCON0); in decon_swreset()
491 readl_poll_timeout(ctx->addr + DECON_VIDCON0, val, in decon_swreset()
494 writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0); in decon_swreset()
495 ret = readl_poll_timeout(ctx->addr + DECON_VIDCON0, val, in decon_swreset()
500 spin_lock_irqsave(&ctx->vblank_lock, flags); in decon_swreset()
501 ctx->frame_id = 0; in decon_swreset()
502 spin_unlock_irqrestore(&ctx->vblank_lock, flags); in decon_swreset()
504 if (!(ctx->out_type & IFTYPE_HDMI)) in decon_swreset()
507 writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0); in decon_swreset()
510 writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1); in decon_swreset()
512 ctx->addr + DECON_CRCCTRL); in decon_swreset()
517 struct decon_context *ctx = crtc->ctx; in decon_atomic_enable()
520 ret = pm_runtime_resume_and_get(ctx->dev); in decon_atomic_enable()
522 DRM_DEV_ERROR(ctx->dev, "failed to enable DECON device.\n"); in decon_atomic_enable()
530 decon_commit(ctx->crtc); in decon_atomic_enable()
535 struct decon_context *ctx = crtc->ctx; in decon_atomic_disable()
538 if (!(ctx->out_type & I80_HW_TRG)) in decon_atomic_disable()
539 synchronize_irq(ctx->te_irq); in decon_atomic_disable()
540 synchronize_irq(ctx->irq); in decon_atomic_disable()
547 for (i = ctx->first_win; i < WINDOWS_NR; i++) in decon_atomic_disable()
548 decon_disable_plane(crtc, &ctx->planes[i]); in decon_atomic_disable()
554 pm_runtime_put_sync(ctx->dev); in decon_atomic_disable()
568 struct decon_context *ctx = crtc->ctx; in decon_clear_channels()
572 ret = clk_prepare_enable(ctx->clks[i]); in decon_clear_channels()
588 while (--i >= 0) in decon_clear_channels()
589 clk_disable_unprepare(ctx->clks[i]); in decon_clear_channels()
595 struct decon_context *ctx = crtc->ctx; in decon_mode_valid()
597 ctx->irq = crtc->i80_mode ? ctx->irq_lcd_sys : ctx->irq_vsync; in decon_mode_valid()
599 if (ctx->irq) in decon_mode_valid()
602 dev_info(ctx->dev, "Sink requires %s mode, but appropriate interrupt is not provided.\n", in decon_mode_valid()
603 crtc->i80_mode ? "command" : "video"); in decon_mode_valid()
629 ctx->drm_dev = drm_dev; in decon_bind()
631 for (win = ctx->first_win; win < WINDOWS_NR; win++) { in decon_bind()
632 ctx->configs[win].pixel_formats = decon_formats; in decon_bind()
633 ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); in decon_bind()
634 ctx->configs[win].zpos = win - ctx->first_win; in decon_bind()
635 ctx->configs[win].type = decon_win_types[win]; in decon_bind()
636 ctx->configs[win].capabilities = capabilities[win]; in decon_bind()
638 ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, in decon_bind()
639 &ctx->configs[win]); in decon_bind()
644 exynos_plane = &ctx->planes[PRIMARY_WIN]; in decon_bind()
645 out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI in decon_bind()
647 ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, in decon_bind()
649 if (IS_ERR(ctx->crtc)) in decon_bind()
650 return PTR_ERR(ctx->crtc); in decon_bind()
652 decon_clear_channels(ctx->crtc); in decon_bind()
654 return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); in decon_bind()
661 decon_atomic_disable(ctx->crtc); in decon_unbind()
664 exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); in decon_unbind()
676 spin_lock(&ctx->vblank_lock); in decon_handle_vblank()
680 if (frm != ctx->frame_id) { in decon_handle_vblank()
681 /* handle only if incremented, take care of wrap-around */ in decon_handle_vblank()
682 if ((s32)(frm - ctx->frame_id) > 0) in decon_handle_vblank()
683 drm_crtc_handle_vblank(&ctx->crtc->base); in decon_handle_vblank()
684 ctx->frame_id = frm; in decon_handle_vblank()
687 spin_unlock(&ctx->vblank_lock); in decon_handle_vblank()
695 val = readl(ctx->addr + DECON_VIDINTCON1); in decon_irq_handler()
699 writel(val, ctx->addr + DECON_VIDINTCON1); in decon_irq_handler()
700 if (ctx->out_type & IFTYPE_HDMI) { in decon_irq_handler()
701 val = readl(ctx->addr + DECON_VIDOUTCON0); in decon_irq_handler()
718 while (--i >= 0) in exynos5433_decon_suspend()
719 clk_disable_unprepare(ctx->clks[i]); in exynos5433_decon_suspend()
730 ret = clk_prepare_enable(ctx->clks[i]); in exynos5433_decon_resume()
738 while (--i >= 0) in exynos5433_decon_resume()
739 clk_disable_unprepare(ctx->clks[i]); in exynos5433_decon_resume()
750 .compatible = "samsung,exynos5433-decon",
754 .compatible = "samsung,exynos5433-decon-tv",
764 struct platform_device *pdev = to_platform_device(ctx->dev); in decon_conf_irq()
769 case -EPROBE_DEFER: in decon_conf_irq()
771 case -ENODATA: in decon_conf_irq()
772 case -ENXIO: in decon_conf_irq()
775 dev_err(ctx->dev, "IRQ %s get failed, %d\n", name, irq); in decon_conf_irq()
779 ret = devm_request_irq(ctx->dev, irq, handler, in decon_conf_irq()
782 dev_err(ctx->dev, "IRQ %s request failed\n", name); in decon_conf_irq()
791 struct device *dev = &pdev->dev; in exynos5433_decon_probe()
798 return -ENOMEM; in exynos5433_decon_probe()
800 ctx->dev = dev; in exynos5433_decon_probe()
801 ctx->out_type = (unsigned long)of_device_get_match_data(dev); in exynos5433_decon_probe()
802 spin_lock_init(&ctx->vblank_lock); in exynos5433_decon_probe()
804 if (ctx->out_type & IFTYPE_HDMI) in exynos5433_decon_probe()
805 ctx->first_win = 1; in exynos5433_decon_probe()
810 clk = devm_clk_get(ctx->dev, decon_clks_name[i]); in exynos5433_decon_probe()
814 ctx->clks[i] = clk; in exynos5433_decon_probe()
817 ctx->addr = devm_platform_ioremap_resource(pdev, 0); in exynos5433_decon_probe()
818 if (IS_ERR(ctx->addr)) in exynos5433_decon_probe()
819 return PTR_ERR(ctx->addr); in exynos5433_decon_probe()
824 ctx->irq_vsync = ret; in exynos5433_decon_probe()
829 ctx->irq_lcd_sys = ret; in exynos5433_decon_probe()
836 ctx->te_irq = ret; in exynos5433_decon_probe()
837 ctx->out_type &= ~I80_HW_TRG; in exynos5433_decon_probe()
840 if (ctx->out_type & I80_HW_TRG) { in exynos5433_decon_probe()
841 ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, in exynos5433_decon_probe()
842 "samsung,disp-sysreg"); in exynos5433_decon_probe()
843 if (IS_ERR(ctx->sysreg)) { in exynos5433_decon_probe()
845 return PTR_ERR(ctx->sysreg); in exynos5433_decon_probe()
867 pm_runtime_disable(&pdev->dev); in exynos5433_decon_remove()
869 component_del(&pdev->dev, &decon_component_ops); in exynos5433_decon_remove()
876 .name = "exynos5433-decon",