Lines Matching +full:exynos7 +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0-or-later
10 #include <linux/clk.h>
30 #include "regs-decon7.h"
65 struct clk *pclk;
66 struct clk *aclk;
67 struct clk *eclk;
68 struct clk *vclk;
82 .compatible = "samsung,exynos7-decon",
86 .compatible = "samsung,exynos7870-decon",
111 * decon_shadow_protect_win() - disable updating values from shadow registers at vsync
121 unsigned int shift = ctx->data->shadowcon_win_protect_shift; in decon_shadow_protect_win()
125 val = readl(ctx->regs + SHADOWCON); in decon_shadow_protect_win()
130 writel(val, ctx->regs + SHADOWCON); in decon_shadow_protect_win()
135 if (ctx->suspended) in decon_wait_for_vblank()
138 atomic_set(&ctx->wait_vsync_event, 1); in decon_wait_for_vblank()
144 if (!wait_event_timeout(ctx->wait_vsync_queue, in decon_wait_for_vblank()
145 !atomic_read(&ctx->wait_vsync_event), in decon_wait_for_vblank()
147 DRM_DEV_DEBUG_KMS(ctx->dev, "vblank wait timed out.\n"); in decon_wait_for_vblank()
157 val = readl(ctx->regs + WINCON(win)); in decon_clear_channels()
163 writel(val, ctx->regs + WINCON(win)); in decon_clear_channels()
170 val = readl(ctx->regs + DECON_UPDATE); in decon_clear_channels()
172 writel(val, ctx->regs + DECON_UPDATE); in decon_clear_channels()
182 ctx->drm_dev = drm_dev; in decon_ctx_initialize()
186 return exynos_drm_register_dma(drm_dev, ctx->dev, &ctx->dma_priv); in decon_ctx_initialize()
192 exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); in decon_ctx_remove()
198 unsigned long ideal_clk = mode->clock * 1000; in decon_calc_clkdiv()
202 clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->vclk), ideal_clk); in decon_calc_clkdiv()
209 struct decon_context *ctx = crtc->ctx; in decon_commit()
210 struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; in decon_commit()
213 if (ctx->suspended) in decon_commit()
217 if (mode->htotal == 0 || mode->vtotal == 0) in decon_commit()
220 if (!ctx->i80_if) { in decon_commit()
223 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; in decon_commit()
224 vbpd = mode->crtc_vtotal - mode->crtc_vsync_end; in decon_commit()
225 vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay; in decon_commit()
227 val = VIDTCON0_VBPD(vbpd - 1) | VIDTCON0_VFPD(vfpd - 1); in decon_commit()
228 writel(val, ctx->regs + VIDTCON0); in decon_commit()
230 val = VIDTCON1_VSPW(vsync_len - 1); in decon_commit()
231 writel(val, ctx->regs + VIDTCON1); in decon_commit()
234 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; in decon_commit()
235 hbpd = mode->crtc_htotal - mode->crtc_hsync_end; in decon_commit()
236 hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay; in decon_commit()
239 val = VIDTCON2_HBPD(hbpd - 1) | VIDTCON2_HFPD(hfpd - 1); in decon_commit()
240 writel(val, ctx->regs + VIDTCON2); in decon_commit()
242 val = VIDTCON3_HSPW(hsync_len - 1); in decon_commit()
243 writel(val, ctx->regs + VIDTCON3); in decon_commit()
247 val = VIDTCON4_LINEVAL(mode->vdisplay - 1) | in decon_commit()
248 VIDTCON4_HOZVAL(mode->hdisplay - 1); in decon_commit()
249 writel(val, ctx->regs + VIDTCON4); in decon_commit()
251 writel(mode->vdisplay - 1, ctx->regs + LINECNT_OP_THRESHOLD); in decon_commit()
258 writel(val, ctx->regs + VIDCON0); in decon_commit()
262 val = VCLKCON1_CLKVAL_NUM_VCLK(clkdiv - 1); in decon_commit()
263 writel(val, ctx->regs + VCLKCON1); in decon_commit()
264 writel(val, ctx->regs + VCLKCON2); in decon_commit()
267 val = readl(ctx->regs + DECON_UPDATE); in decon_commit()
269 writel(val, ctx->regs + DECON_UPDATE); in decon_commit()
274 struct decon_context *ctx = crtc->ctx; in decon_enable_vblank()
277 if (ctx->suspended) in decon_enable_vblank()
278 return -EPERM; in decon_enable_vblank()
280 if (!test_and_set_bit(0, &ctx->irq_flags)) { in decon_enable_vblank()
281 val = readl(ctx->regs + VIDINTCON0); in decon_enable_vblank()
285 if (!ctx->i80_if) { in decon_enable_vblank()
291 writel(val, ctx->regs + VIDINTCON0); in decon_enable_vblank()
299 struct decon_context *ctx = crtc->ctx; in decon_disable_vblank()
302 if (ctx->suspended) in decon_disable_vblank()
305 if (test_and_clear_bit(0, &ctx->irq_flags)) { in decon_disable_vblank()
306 val = readl(ctx->regs + VIDINTCON0); in decon_disable_vblank()
309 if (!ctx->i80_if) in decon_disable_vblank()
312 writel(val, ctx->regs + VIDINTCON0); in decon_disable_vblank()
321 unsigned int shift = ctx->data->wincon_burstlen_shift; in decon_win_set_pixfmt()
323 val = readl(ctx->regs + WINCON(win)); in decon_win_set_pixfmt()
326 switch (fb->format->format) { in decon_win_set_pixfmt()
370 DRM_DEV_DEBUG_KMS(ctx->dev, "cpp = %d\n", fb->format->cpp[0]); in decon_win_set_pixfmt()
373 * In case of exynos, setting dma-burst to 16Word causes permanent in decon_win_set_pixfmt()
380 padding = (fb->pitches[0] / fb->format->cpp[0]) - fb->width; in decon_win_set_pixfmt()
381 if (fb->width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) { in decon_win_set_pixfmt()
386 writel(val, ctx->regs + WINCON(win)); in decon_win_set_pixfmt()
398 writel(keycon0, ctx->regs + WKEYCON0_BASE(win)); in decon_win_set_colkey()
399 writel(keycon1, ctx->regs + WKEYCON1_BASE(win)); in decon_win_set_colkey()
404 struct decon_context *ctx = crtc->ctx; in decon_atomic_begin()
407 if (ctx->suspended) in decon_atomic_begin()
418 to_exynos_plane_state(plane->base.state); in decon_update_plane()
419 struct decon_context *ctx = crtc->ctx; in decon_update_plane()
420 struct drm_framebuffer *fb = state->base.fb; in decon_update_plane()
425 unsigned int win = plane->index; in decon_update_plane()
426 unsigned int cpp = fb->format->cpp[0]; in decon_update_plane()
427 unsigned int pitch = fb->pitches[0]; in decon_update_plane()
428 unsigned int vidw_addr0_base = ctx->data->vidw_buf_start_base; in decon_update_plane()
430 if (ctx->suspended) in decon_update_plane()
445 writel(val, ctx->regs + VIDW_BUF_START(vidw_addr0_base, win)); in decon_update_plane()
447 padding = (pitch / cpp) - fb->width; in decon_update_plane()
450 writel(fb->width + padding, ctx->regs + VIDW_WHOLE_X(win)); in decon_update_plane()
451 writel(fb->height, ctx->regs + VIDW_WHOLE_Y(win)); in decon_update_plane()
454 writel(state->src.x, ctx->regs + VIDW_OFFSET_X(win)); in decon_update_plane()
455 writel(state->src.y, ctx->regs + VIDW_OFFSET_Y(win)); in decon_update_plane()
457 DRM_DEV_DEBUG_KMS(ctx->dev, "start addr = 0x%lx\n", in decon_update_plane()
459 DRM_DEV_DEBUG_KMS(ctx->dev, "ovl_width = %d, ovl_height = %d\n", in decon_update_plane()
460 state->crtc.w, state->crtc.h); in decon_update_plane()
462 val = VIDOSDxA_TOPLEFT_X(state->crtc.x) | in decon_update_plane()
463 VIDOSDxA_TOPLEFT_Y(state->crtc.y); in decon_update_plane()
464 writel(val, ctx->regs + VIDOSD_A(win)); in decon_update_plane()
466 last_x = state->crtc.x + state->crtc.w; in decon_update_plane()
468 last_x--; in decon_update_plane()
469 last_y = state->crtc.y + state->crtc.h; in decon_update_plane()
471 last_y--; in decon_update_plane()
475 writel(val, ctx->regs + VIDOSD_B(win)); in decon_update_plane()
477 DRM_DEV_DEBUG_KMS(ctx->dev, "osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", in decon_update_plane()
478 state->crtc.x, state->crtc.y, last_x, last_y); in decon_update_plane()
485 writel(alpha, ctx->regs + VIDOSD_C(win)); in decon_update_plane()
491 writel(alpha, ctx->regs + VIDOSD_D(win)); in decon_update_plane()
500 val = readl(ctx->regs + WINCON(win)); in decon_update_plane()
503 writel(val, ctx->regs + WINCON(win)); in decon_update_plane()
508 val = readl(ctx->regs + DECON_UPDATE); in decon_update_plane()
510 writel(val, ctx->regs + DECON_UPDATE); in decon_update_plane()
516 struct decon_context *ctx = crtc->ctx; in decon_disable_plane()
517 unsigned int win = plane->index; in decon_disable_plane()
520 if (ctx->suspended) in decon_disable_plane()
527 val = readl(ctx->regs + WINCON(win)); in decon_disable_plane()
529 writel(val, ctx->regs + WINCON(win)); in decon_disable_plane()
531 val = readl(ctx->regs + DECON_UPDATE); in decon_disable_plane()
533 writel(val, ctx->regs + DECON_UPDATE); in decon_disable_plane()
538 struct decon_context *ctx = crtc->ctx; in decon_atomic_flush()
541 if (ctx->suspended) in decon_atomic_flush()
553 writel(VIDCON0_SWRESET, ctx->regs + VIDCON0); in decon_init()
556 if (!ctx->i80_if) in decon_init()
558 writel(val, ctx->regs + VIDOUTCON0); in decon_init()
560 writel(VCLKCON0_CLKVALUP | VCLKCON0_VCLKFREE, ctx->regs + VCLKCON0); in decon_init()
562 if (!ctx->i80_if) in decon_init()
563 writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0)); in decon_init()
568 struct decon_context *ctx = crtc->ctx; in decon_atomic_enable()
571 if (!ctx->suspended) in decon_atomic_enable()
574 ret = pm_runtime_resume_and_get(ctx->dev); in decon_atomic_enable()
576 DRM_DEV_ERROR(ctx->dev, "failed to enable DECON device.\n"); in decon_atomic_enable()
583 if (test_and_clear_bit(0, &ctx->irq_flags)) in decon_atomic_enable()
584 decon_enable_vblank(ctx->crtc); in decon_atomic_enable()
586 decon_commit(ctx->crtc); in decon_atomic_enable()
588 ctx->suspended = false; in decon_atomic_enable()
593 struct decon_context *ctx = crtc->ctx; in decon_atomic_disable()
596 if (ctx->suspended) in decon_atomic_disable()
605 decon_disable_plane(crtc, &ctx->planes[i]); in decon_atomic_disable()
607 pm_runtime_put_sync(ctx->dev); in decon_atomic_disable()
609 ctx->suspended = true; in decon_atomic_disable()
629 val = readl(ctx->regs + VIDINTCON1); in decon_irq_handler()
631 clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME; in decon_irq_handler()
633 writel(clear_bit, ctx->regs + VIDINTCON1); in decon_irq_handler()
636 if (!ctx->drm_dev) in decon_irq_handler()
639 if (!ctx->i80_if) { in decon_irq_handler()
640 drm_crtc_handle_vblank(&ctx->crtc->base); in decon_irq_handler()
643 if (atomic_read(&ctx->wait_vsync_event)) { in decon_irq_handler()
644 atomic_set(&ctx->wait_vsync_event, 0); in decon_irq_handler()
645 wake_up(&ctx->wait_vsync_queue); in decon_irq_handler()
667 ctx->configs[i].pixel_formats = decon_formats; in decon_bind()
668 ctx->configs[i].num_pixel_formats = ARRAY_SIZE(decon_formats); in decon_bind()
669 ctx->configs[i].zpos = i; in decon_bind()
670 ctx->configs[i].type = decon_win_types[i]; in decon_bind()
672 ret = exynos_plane_init(drm_dev, &ctx->planes[i], i, in decon_bind()
673 &ctx->configs[i]); in decon_bind()
678 exynos_plane = &ctx->planes[DEFAULT_WIN]; in decon_bind()
679 ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, in decon_bind()
681 if (IS_ERR(ctx->crtc)) { in decon_bind()
683 return PTR_ERR(ctx->crtc); in decon_bind()
686 if (ctx->encoder) in decon_bind()
687 exynos_dpi_bind(drm_dev, ctx->encoder); in decon_bind()
698 decon_atomic_disable(ctx->crtc); in decon_unbind()
700 if (ctx->encoder) in decon_unbind()
701 exynos_dpi_remove(ctx->encoder); in decon_unbind()
713 struct device *dev = &pdev->dev; in decon_probe()
718 if (!dev->of_node) in decon_probe()
719 return -ENODEV; in decon_probe()
723 return -ENOMEM; in decon_probe()
725 ctx->dev = dev; in decon_probe()
726 ctx->suspended = true; in decon_probe()
727 ctx->data = of_device_get_match_data(dev); in decon_probe()
729 i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings"); in decon_probe()
731 ctx->i80_if = true; in decon_probe()
734 ctx->regs = of_iomap(dev->of_node, 0); in decon_probe()
735 if (!ctx->regs) in decon_probe()
736 return -ENOMEM; in decon_probe()
738 ctx->pclk = devm_clk_get(dev, "pclk_decon0"); in decon_probe()
739 if (IS_ERR(ctx->pclk)) { in decon_probe()
741 ret = PTR_ERR(ctx->pclk); in decon_probe()
745 ctx->aclk = devm_clk_get(dev, "aclk_decon0"); in decon_probe()
746 if (IS_ERR(ctx->aclk)) { in decon_probe()
748 ret = PTR_ERR(ctx->aclk); in decon_probe()
752 ctx->eclk = devm_clk_get(dev, "decon0_eclk"); in decon_probe()
753 if (IS_ERR(ctx->eclk)) { in decon_probe()
755 ret = PTR_ERR(ctx->eclk); in decon_probe()
759 ctx->vclk = devm_clk_get(dev, "decon0_vclk"); in decon_probe()
760 if (IS_ERR(ctx->vclk)) { in decon_probe()
762 ret = PTR_ERR(ctx->vclk); in decon_probe()
766 ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync"); in decon_probe()
776 init_waitqueue_head(&ctx->wait_vsync_queue); in decon_probe()
777 atomic_set(&ctx->wait_vsync_event, 0); in decon_probe()
781 ctx->encoder = exynos_dpi_probe(dev); in decon_probe()
782 if (IS_ERR(ctx->encoder)) { in decon_probe()
783 ret = PTR_ERR(ctx->encoder); in decon_probe()
799 iounmap(ctx->regs); in decon_probe()
806 struct decon_context *ctx = dev_get_drvdata(&pdev->dev); in decon_remove()
808 pm_runtime_disable(&pdev->dev); in decon_remove()
810 iounmap(ctx->regs); in decon_remove()
812 component_del(&pdev->dev, &decon_component_ops); in decon_remove()
819 clk_disable_unprepare(ctx->vclk); in exynos7_decon_suspend()
820 clk_disable_unprepare(ctx->eclk); in exynos7_decon_suspend()
821 clk_disable_unprepare(ctx->aclk); in exynos7_decon_suspend()
822 clk_disable_unprepare(ctx->pclk); in exynos7_decon_suspend()
832 ret = clk_prepare_enable(ctx->pclk); in exynos7_decon_resume()
839 ret = clk_prepare_enable(ctx->aclk); in exynos7_decon_resume()
846 ret = clk_prepare_enable(ctx->eclk); in exynos7_decon_resume()
853 ret = clk_prepare_enable(ctx->vclk); in exynos7_decon_resume()
863 clk_disable_unprepare(ctx->eclk); in exynos7_decon_resume()
865 clk_disable_unprepare(ctx->aclk); in exynos7_decon_resume()
867 clk_disable_unprepare(ctx->pclk); in exynos7_decon_resume()
879 .name = "exynos-decon",