Lines Matching +full:flip +full:- +full:vertical

1 // SPDX-License-Identifier: GPL-2.0+
61 /* -----------------------------------------------------------------------------
67 const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode; in rzg2l_du_crtc_set_display_timing()
68 unsigned long mode_clock = mode->clock * 1000; in rzg2l_du_crtc_set_display_timing()
70 struct rzg2l_du_device *rcdu = rcrtc->dev; in rzg2l_du_crtc_set_display_timing()
72 clk_prepare_enable(rcrtc->rzg2l_clocks.dclk); in rzg2l_du_crtc_set_display_timing()
73 clk_set_rate(rcrtc->rzg2l_clocks.dclk, mode_clock); in rzg2l_du_crtc_set_display_timing()
76 | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DU_DITR0_VSPOL : 0) in rzg2l_du_crtc_set_display_timing()
77 | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DU_DITR0_HSPOL : 0)); in rzg2l_du_crtc_set_display_timing()
79 ditr1 = DU_DITR1_VSA(mode->vsync_end - mode->vsync_start) in rzg2l_du_crtc_set_display_timing()
80 | DU_DITR1_VACTIVE(mode->vdisplay); in rzg2l_du_crtc_set_display_timing()
82 ditr2 = DU_DITR2_VBP(mode->vtotal - mode->vsync_end) in rzg2l_du_crtc_set_display_timing()
83 | DU_DITR2_VFP(mode->vsync_start - mode->vdisplay); in rzg2l_du_crtc_set_display_timing()
85 ditr3 = DU_DITR3_HSA(mode->hsync_end - mode->hsync_start) in rzg2l_du_crtc_set_display_timing()
86 | DU_DITR3_HACTIVE(mode->hdisplay); in rzg2l_du_crtc_set_display_timing()
88 ditr4 = DU_DITR4_HBP(mode->htotal - mode->hsync_end) in rzg2l_du_crtc_set_display_timing()
89 | DU_DITR4_HFP(mode->hsync_start - mode->hdisplay); in rzg2l_du_crtc_set_display_timing()
93 writel(ditr0, rcdu->mmio + DU_DITR0); in rzg2l_du_crtc_set_display_timing()
94 writel(ditr1, rcdu->mmio + DU_DITR1); in rzg2l_du_crtc_set_display_timing()
95 writel(ditr2, rcdu->mmio + DU_DITR2); in rzg2l_du_crtc_set_display_timing()
96 writel(ditr3, rcdu->mmio + DU_DITR3); in rzg2l_du_crtc_set_display_timing()
97 writel(ditr4, rcdu->mmio + DU_DITR4); in rzg2l_du_crtc_set_display_timing()
98 writel(pbcr0, rcdu->mmio + DU_PBCR0); in rzg2l_du_crtc_set_display_timing()
101 writel(DU_MCR1_PB_AUTOCLR, rcdu->mmio + DU_MCR1); in rzg2l_du_crtc_set_display_timing()
104 /* -----------------------------------------------------------------------------
105 * Page Flip
111 struct drm_device *dev = rcrtc->crtc.dev; in rzg2l_du_crtc_finish_page_flip()
114 spin_lock_irqsave(&dev->event_lock, flags); in rzg2l_du_crtc_finish_page_flip()
115 event = rcrtc->event; in rzg2l_du_crtc_finish_page_flip()
116 rcrtc->event = NULL; in rzg2l_du_crtc_finish_page_flip()
117 spin_unlock_irqrestore(&dev->event_lock, flags); in rzg2l_du_crtc_finish_page_flip()
122 spin_lock_irqsave(&dev->event_lock, flags); in rzg2l_du_crtc_finish_page_flip()
123 drm_crtc_send_vblank_event(&rcrtc->crtc, event); in rzg2l_du_crtc_finish_page_flip()
124 wake_up(&rcrtc->flip_wait); in rzg2l_du_crtc_finish_page_flip()
125 spin_unlock_irqrestore(&dev->event_lock, flags); in rzg2l_du_crtc_finish_page_flip()
127 drm_crtc_vblank_put(&rcrtc->crtc); in rzg2l_du_crtc_finish_page_flip()
132 struct drm_device *dev = rcrtc->crtc.dev; in rzg2l_du_crtc_page_flip_pending()
136 spin_lock_irqsave(&dev->event_lock, flags); in rzg2l_du_crtc_page_flip_pending()
137 pending = rcrtc->event; in rzg2l_du_crtc_page_flip_pending()
138 spin_unlock_irqrestore(&dev->event_lock, flags); in rzg2l_du_crtc_page_flip_pending()
145 struct rzg2l_du_device *rcdu = rcrtc->dev; in rzg2l_du_crtc_wait_page_flip()
147 if (wait_event_timeout(rcrtc->flip_wait, in rzg2l_du_crtc_wait_page_flip()
152 dev_warn(rcdu->dev, "page flip timeout\n"); in rzg2l_du_crtc_wait_page_flip()
157 /* -----------------------------------------------------------------------------
169 /* Turn vertical blanking interrupt reporting on. */ in rzg2l_du_crtc_setup()
170 drm_crtc_vblank_on(&rcrtc->crtc); in rzg2l_du_crtc_setup()
178 * Guard against double-get, as the function is called from both the in rzg2l_du_crtc_get()
181 if (rcrtc->initialized) in rzg2l_du_crtc_get()
184 ret = clk_prepare_enable(rcrtc->rzg2l_clocks.aclk); in rzg2l_du_crtc_get()
188 ret = clk_prepare_enable(rcrtc->rzg2l_clocks.pclk); in rzg2l_du_crtc_get()
192 ret = reset_control_deassert(rcrtc->rstc); in rzg2l_du_crtc_get()
197 rcrtc->initialized = true; in rzg2l_du_crtc_get()
202 clk_disable_unprepare(rcrtc->rzg2l_clocks.pclk); in rzg2l_du_crtc_get()
204 clk_disable_unprepare(rcrtc->rzg2l_clocks.aclk); in rzg2l_du_crtc_get()
210 clk_disable_unprepare(rcrtc->rzg2l_clocks.dclk); in rzg2l_du_crtc_put()
211 reset_control_assert(rcrtc->rstc); in rzg2l_du_crtc_put()
212 clk_disable_unprepare(rcrtc->rzg2l_clocks.pclk); in rzg2l_du_crtc_put()
213 clk_disable_unprepare(rcrtc->rzg2l_clocks.aclk); in rzg2l_du_crtc_put()
215 rcrtc->initialized = false; in rzg2l_du_crtc_put()
220 struct rzg2l_du_crtc_state *rstate = to_rzg2l_crtc_state(rcrtc->crtc.state); in rzg2l_du_start_stop()
221 struct rzg2l_du_device *rcdu = rcrtc->dev; in rzg2l_du_start_stop()
224 if (rstate->outputs & BIT(RZG2L_DU_OUTPUT_DPAD0)) in rzg2l_du_start_stop()
227 writel(start ? val : 0, rcdu->mmio + DU_MCR0); in rzg2l_du_start_stop()
237 struct drm_crtc *crtc = &rcrtc->crtc; in rzg2l_du_crtc_stop()
240 * Disable vertical blanking interrupt reporting. We first need to wait in rzg2l_du_crtc_stop()
241 * for page flip completion before stopping the CRTC as userspace in rzg2l_du_crtc_stop()
253 /* -----------------------------------------------------------------------------
275 spin_lock_irq(&crtc->dev->event_lock); in rzg2l_du_crtc_atomic_disable()
276 if (crtc->state->event) { in rzg2l_du_crtc_atomic_disable()
277 drm_crtc_send_vblank_event(crtc, crtc->state->event); in rzg2l_du_crtc_atomic_disable()
278 crtc->state->event = NULL; in rzg2l_du_crtc_atomic_disable()
280 spin_unlock_irq(&crtc->dev->event_lock); in rzg2l_du_crtc_atomic_disable()
287 struct drm_device *dev = rcrtc->crtc.dev; in rzg2l_du_crtc_atomic_flush()
290 WARN_ON(!crtc->state->enable); in rzg2l_du_crtc_atomic_flush()
292 if (crtc->state->event) { in rzg2l_du_crtc_atomic_flush()
295 spin_lock_irqsave(&dev->event_lock, flags); in rzg2l_du_crtc_atomic_flush()
296 rcrtc->event = crtc->state->event; in rzg2l_du_crtc_atomic_flush()
297 crtc->state->event = NULL; in rzg2l_du_crtc_atomic_flush()
298 spin_unlock_irqrestore(&dev->event_lock, flags); in rzg2l_du_crtc_atomic_flush()
316 if (WARN_ON(!crtc->state)) in rzg2l_du_crtc_atomic_duplicate_state()
319 state = to_rzg2l_crtc_state(crtc->state); in rzg2l_du_crtc_atomic_duplicate_state()
324 __drm_atomic_helper_crtc_duplicate_state(crtc, &copy->state); in rzg2l_du_crtc_atomic_duplicate_state()
326 return &copy->state; in rzg2l_du_crtc_atomic_duplicate_state()
340 if (crtc->state) { in rzg2l_du_crtc_reset()
341 rzg2l_du_crtc_atomic_destroy_state(crtc, crtc->state); in rzg2l_du_crtc_reset()
342 crtc->state = NULL; in rzg2l_du_crtc_reset()
349 __drm_atomic_helper_crtc_reset(crtc, &state->state); in rzg2l_du_crtc_reset()
356 rcrtc->vblank_enable = true; in rzg2l_du_crtc_enable_vblank()
365 rcrtc->vblank_enable = false; in rzg2l_du_crtc_disable_vblank()
378 /* -----------------------------------------------------------------------------
384 struct rzg2l_du_crtc *rcrtc = &rcdu->crtcs[0]; in rzg2l_du_crtc_create()
385 struct drm_crtc *crtc = &rcrtc->crtc; in rzg2l_du_crtc_create()
389 rcrtc->rstc = devm_reset_control_get_shared(rcdu->dev, NULL); in rzg2l_du_crtc_create()
390 if (IS_ERR(rcrtc->rstc)) { in rzg2l_du_crtc_create()
391 dev_err(rcdu->dev, "can't get cpg reset\n"); in rzg2l_du_crtc_create()
392 return PTR_ERR(rcrtc->rstc); in rzg2l_du_crtc_create()
395 rcrtc->rzg2l_clocks.aclk = devm_clk_get(rcdu->dev, "aclk"); in rzg2l_du_crtc_create()
396 if (IS_ERR(rcrtc->rzg2l_clocks.aclk)) { in rzg2l_du_crtc_create()
397 dev_err(rcdu->dev, "no axi clock for DU\n"); in rzg2l_du_crtc_create()
398 return PTR_ERR(rcrtc->rzg2l_clocks.aclk); in rzg2l_du_crtc_create()
401 rcrtc->rzg2l_clocks.pclk = devm_clk_get(rcdu->dev, "pclk"); in rzg2l_du_crtc_create()
402 if (IS_ERR(rcrtc->rzg2l_clocks.pclk)) { in rzg2l_du_crtc_create()
403 dev_err(rcdu->dev, "no peripheral clock for DU\n"); in rzg2l_du_crtc_create()
404 return PTR_ERR(rcrtc->rzg2l_clocks.pclk); in rzg2l_du_crtc_create()
407 rcrtc->rzg2l_clocks.dclk = devm_clk_get(rcdu->dev, "vclk"); in rzg2l_du_crtc_create()
408 if (IS_ERR(rcrtc->rzg2l_clocks.dclk)) { in rzg2l_du_crtc_create()
409 dev_err(rcdu->dev, "no video clock for DU\n"); in rzg2l_du_crtc_create()
410 return PTR_ERR(rcrtc->rzg2l_clocks.dclk); in rzg2l_du_crtc_create()
413 init_waitqueue_head(&rcrtc->flip_wait); in rzg2l_du_crtc_create()
414 rcrtc->dev = rcdu; in rzg2l_du_crtc_create()
416 primary = rzg2l_du_vsp_get_drm_plane(rcrtc, rcrtc->vsp_pipe); in rzg2l_du_crtc_create()
420 ret = drmm_crtc_init_with_planes(&rcdu->ddev, crtc, primary, NULL, in rzg2l_du_crtc_create()