1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
4 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
7 #include <drm/drm_atomic.h>
8 #include <drm/drm_atomic_helper.h>
9 #include <drm/drm_crtc.h>
10 #include <drm/drm_crtc_helper.h>
11 #include <drm/drm_fb_cma_helper.h>
12 #include <drm/drm_gem_cma_helper.h>
13 #include <drm/drm_plane_helper.h>
14 #include <drm/drm_vblank.h>
16 #include "tidss_crtc.h"
17 #include "tidss_dispc.h"
18 #include "tidss_drv.h"
19 #include "tidss_irq.h"
20 #include "tidss_plane.h"
22 /* Page flip and frame done IRQs */
24 static void tidss_crtc_finish_page_flip(struct tidss_crtc
*tcrtc
)
26 struct drm_device
*ddev
= tcrtc
->crtc
.dev
;
27 struct tidss_device
*tidss
= to_tidss(ddev
);
28 struct drm_pending_vblank_event
*event
;
32 spin_lock_irqsave(&ddev
->event_lock
, flags
);
35 * New settings are taken into use at VFP, and GO bit is cleared at
36 * the same time. This happens before the vertical blank interrupt.
37 * So there is a small change that the driver sets GO bit after VFP, but
38 * before vblank, and we have to check for that case here.
40 busy
= dispc_vp_go_busy(tidss
->dispc
, tcrtc
->hw_videoport
);
42 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
50 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
54 drm_crtc_send_vblank_event(&tcrtc
->crtc
, event
);
56 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
58 drm_crtc_vblank_put(&tcrtc
->crtc
);
61 void tidss_crtc_vblank_irq(struct drm_crtc
*crtc
)
63 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
65 drm_crtc_handle_vblank(crtc
);
67 tidss_crtc_finish_page_flip(tcrtc
);
70 void tidss_crtc_framedone_irq(struct drm_crtc
*crtc
)
72 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
74 complete(&tcrtc
->framedone_completion
);
77 void tidss_crtc_error_irq(struct drm_crtc
*crtc
, u64 irqstatus
)
79 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
81 dev_err_ratelimited(crtc
->dev
->dev
, "CRTC%u SYNC LOST: (irq %llx)\n",
82 tcrtc
->hw_videoport
, irqstatus
);
85 /* drm_crtc_helper_funcs */
87 static int tidss_crtc_atomic_check(struct drm_crtc
*crtc
,
88 struct drm_atomic_state
*state
)
90 struct drm_crtc_state
*crtc_state
= drm_atomic_get_new_crtc_state(state
,
92 struct drm_device
*ddev
= crtc
->dev
;
93 struct tidss_device
*tidss
= to_tidss(ddev
);
94 struct dispc_device
*dispc
= tidss
->dispc
;
95 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
96 u32 hw_videoport
= tcrtc
->hw_videoport
;
97 const struct drm_display_mode
*mode
;
98 enum drm_mode_status ok
;
100 dev_dbg(ddev
->dev
, "%s\n", __func__
);
102 if (!crtc_state
->enable
)
105 mode
= &crtc_state
->adjusted_mode
;
107 ok
= dispc_vp_mode_valid(dispc
, hw_videoport
, mode
);
109 dev_dbg(ddev
->dev
, "%s: bad mode: %ux%u pclk %u kHz\n",
110 __func__
, mode
->hdisplay
, mode
->vdisplay
, mode
->clock
);
114 return dispc_vp_bus_check(dispc
, hw_videoport
, crtc_state
);
118 * This needs all affected planes to be present in the atomic
119 * state. The untouched planes are added to the state in
120 * tidss_atomic_check().
122 static void tidss_crtc_position_planes(struct tidss_device
*tidss
,
123 struct drm_crtc
*crtc
,
124 struct drm_crtc_state
*old_state
,
127 struct drm_atomic_state
*ostate
= old_state
->state
;
128 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
129 struct drm_crtc_state
*cstate
= crtc
->state
;
132 if (!newmodeset
&& !cstate
->zpos_changed
&&
133 !to_tidss_crtc_state(cstate
)->plane_pos_changed
)
136 for (layer
= 0; layer
< tidss
->feat
->num_planes
; layer
++) {
137 struct drm_plane_state
*pstate
;
138 struct drm_plane
*plane
;
139 bool layer_active
= false;
142 for_each_new_plane_in_state(ostate
, plane
, pstate
, i
) {
143 if (pstate
->crtc
!= crtc
|| !pstate
->visible
)
146 if (pstate
->normalized_zpos
== layer
) {
153 struct tidss_plane
*tplane
= to_tidss_plane(plane
);
155 dispc_ovr_set_plane(tidss
->dispc
, tplane
->hw_plane_id
,
157 pstate
->crtc_x
, pstate
->crtc_y
,
160 dispc_ovr_enable_layer(tidss
->dispc
, tcrtc
->hw_videoport
, layer
,
165 static void tidss_crtc_atomic_flush(struct drm_crtc
*crtc
,
166 struct drm_atomic_state
*state
)
168 struct drm_crtc_state
*old_crtc_state
= drm_atomic_get_old_crtc_state(state
,
170 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
171 struct drm_device
*ddev
= crtc
->dev
;
172 struct tidss_device
*tidss
= to_tidss(ddev
);
176 "%s: %s enabled %d, needs modeset %d, event %p\n", __func__
,
177 crtc
->name
, drm_atomic_crtc_needs_modeset(crtc
->state
),
178 crtc
->state
->enable
, crtc
->state
->event
);
180 /* There is nothing to do if CRTC is not going to be enabled. */
181 if (!crtc
->state
->enable
)
185 * Flush CRTC changes with go bit only if new modeset is not
186 * coming, so CRTC is enabled trough out the commit.
188 if (drm_atomic_crtc_needs_modeset(crtc
->state
))
191 /* If the GO bit is stuck we better quit here. */
192 if (WARN_ON(dispc_vp_go_busy(tidss
->dispc
, tcrtc
->hw_videoport
)))
195 /* We should have event if CRTC is enabled through out this commit. */
196 if (WARN_ON(!crtc
->state
->event
))
199 /* Write vp properties to HW if needed. */
200 dispc_vp_setup(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
, false);
202 /* Update plane positions if needed. */
203 tidss_crtc_position_planes(tidss
, crtc
, old_crtc_state
, false);
205 WARN_ON(drm_crtc_vblank_get(crtc
) != 0);
207 spin_lock_irqsave(&ddev
->event_lock
, flags
);
208 dispc_vp_go(tidss
->dispc
, tcrtc
->hw_videoport
);
210 WARN_ON(tcrtc
->event
);
212 tcrtc
->event
= crtc
->state
->event
;
213 crtc
->state
->event
= NULL
;
215 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
218 static void tidss_crtc_atomic_enable(struct drm_crtc
*crtc
,
219 struct drm_atomic_state
*state
)
221 struct drm_crtc_state
*old_state
= drm_atomic_get_old_crtc_state(state
,
223 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
224 struct drm_device
*ddev
= crtc
->dev
;
225 struct tidss_device
*tidss
= to_tidss(ddev
);
226 const struct drm_display_mode
*mode
= &crtc
->state
->adjusted_mode
;
230 dev_dbg(ddev
->dev
, "%s, event %p\n", __func__
, crtc
->state
->event
);
232 tidss_runtime_get(tidss
);
234 r
= dispc_vp_set_clk_rate(tidss
->dispc
, tcrtc
->hw_videoport
,
239 r
= dispc_vp_enable_clk(tidss
->dispc
, tcrtc
->hw_videoport
);
243 dispc_vp_setup(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
, true);
244 tidss_crtc_position_planes(tidss
, crtc
, old_state
, true);
246 /* Turn vertical blanking interrupt reporting on. */
247 drm_crtc_vblank_on(crtc
);
249 dispc_vp_prepare(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
);
251 dispc_vp_enable(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
);
253 spin_lock_irqsave(&ddev
->event_lock
, flags
);
255 if (crtc
->state
->event
) {
256 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
257 crtc
->state
->event
= NULL
;
260 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
263 static void tidss_crtc_atomic_disable(struct drm_crtc
*crtc
,
264 struct drm_atomic_state
*state
)
266 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
267 struct drm_device
*ddev
= crtc
->dev
;
268 struct tidss_device
*tidss
= to_tidss(ddev
);
271 dev_dbg(ddev
->dev
, "%s, event %p\n", __func__
, crtc
->state
->event
);
273 reinit_completion(&tcrtc
->framedone_completion
);
275 dispc_vp_disable(tidss
->dispc
, tcrtc
->hw_videoport
);
277 if (!wait_for_completion_timeout(&tcrtc
->framedone_completion
,
278 msecs_to_jiffies(500)))
279 dev_err(tidss
->dev
, "Timeout waiting for framedone on crtc %d",
280 tcrtc
->hw_videoport
);
282 dispc_vp_unprepare(tidss
->dispc
, tcrtc
->hw_videoport
);
284 spin_lock_irqsave(&ddev
->event_lock
, flags
);
285 if (crtc
->state
->event
) {
286 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
287 crtc
->state
->event
= NULL
;
289 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
291 drm_crtc_vblank_off(crtc
);
293 dispc_vp_disable_clk(tidss
->dispc
, tcrtc
->hw_videoport
);
295 tidss_runtime_put(tidss
);
299 enum drm_mode_status
tidss_crtc_mode_valid(struct drm_crtc
*crtc
,
300 const struct drm_display_mode
*mode
)
302 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
303 struct drm_device
*ddev
= crtc
->dev
;
304 struct tidss_device
*tidss
= to_tidss(ddev
);
306 return dispc_vp_mode_valid(tidss
->dispc
, tcrtc
->hw_videoport
, mode
);
309 static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs
= {
310 .atomic_check
= tidss_crtc_atomic_check
,
311 .atomic_flush
= tidss_crtc_atomic_flush
,
312 .atomic_enable
= tidss_crtc_atomic_enable
,
313 .atomic_disable
= tidss_crtc_atomic_disable
,
315 .mode_valid
= tidss_crtc_mode_valid
,
320 static int tidss_crtc_enable_vblank(struct drm_crtc
*crtc
)
322 struct drm_device
*ddev
= crtc
->dev
;
323 struct tidss_device
*tidss
= to_tidss(ddev
);
325 dev_dbg(ddev
->dev
, "%s\n", __func__
);
327 tidss_runtime_get(tidss
);
329 tidss_irq_enable_vblank(crtc
);
334 static void tidss_crtc_disable_vblank(struct drm_crtc
*crtc
)
336 struct drm_device
*ddev
= crtc
->dev
;
337 struct tidss_device
*tidss
= to_tidss(ddev
);
339 dev_dbg(ddev
->dev
, "%s\n", __func__
);
341 tidss_irq_disable_vblank(crtc
);
343 tidss_runtime_put(tidss
);
346 static void tidss_crtc_reset(struct drm_crtc
*crtc
)
348 struct tidss_crtc_state
*tcrtc
;
351 __drm_atomic_helper_crtc_destroy_state(crtc
->state
);
355 tcrtc
= kzalloc(sizeof(*tcrtc
), GFP_KERNEL
);
361 __drm_atomic_helper_crtc_reset(crtc
, &tcrtc
->base
);
364 static struct drm_crtc_state
*tidss_crtc_duplicate_state(struct drm_crtc
*crtc
)
366 struct tidss_crtc_state
*state
, *current_state
;
368 if (WARN_ON(!crtc
->state
))
371 current_state
= to_tidss_crtc_state(crtc
->state
);
373 state
= kmalloc(sizeof(*state
), GFP_KERNEL
);
377 __drm_atomic_helper_crtc_duplicate_state(crtc
, &state
->base
);
379 state
->plane_pos_changed
= false;
381 state
->bus_format
= current_state
->bus_format
;
382 state
->bus_flags
= current_state
->bus_flags
;
387 static void tidss_crtc_destroy(struct drm_crtc
*crtc
)
389 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
391 drm_crtc_cleanup(crtc
);
395 static const struct drm_crtc_funcs tidss_crtc_funcs
= {
396 .reset
= tidss_crtc_reset
,
397 .destroy
= tidss_crtc_destroy
,
398 .set_config
= drm_atomic_helper_set_config
,
399 .page_flip
= drm_atomic_helper_page_flip
,
400 .atomic_duplicate_state
= tidss_crtc_duplicate_state
,
401 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
402 .enable_vblank
= tidss_crtc_enable_vblank
,
403 .disable_vblank
= tidss_crtc_disable_vblank
,
406 struct tidss_crtc
*tidss_crtc_create(struct tidss_device
*tidss
,
408 struct drm_plane
*primary
)
410 struct tidss_crtc
*tcrtc
;
411 struct drm_crtc
*crtc
;
412 unsigned int gamma_lut_size
= 0;
413 bool has_ctm
= tidss
->feat
->vp_feat
.color
.has_ctm
;
416 tcrtc
= kzalloc(sizeof(*tcrtc
), GFP_KERNEL
);
418 return ERR_PTR(-ENOMEM
);
420 tcrtc
->hw_videoport
= hw_videoport
;
421 init_completion(&tcrtc
->framedone_completion
);
425 ret
= drm_crtc_init_with_planes(&tidss
->ddev
, crtc
, primary
,
426 NULL
, &tidss_crtc_funcs
, NULL
);
432 drm_crtc_helper_add(crtc
, &tidss_crtc_helper_funcs
);
435 * The dispc gamma functions adapt to what ever size we ask
436 * from it no matter what HW supports. X-server assumes 256
437 * element gamma tables so lets use that.
439 if (tidss
->feat
->vp_feat
.color
.gamma_size
)
440 gamma_lut_size
= 256;
442 drm_crtc_enable_color_mgmt(crtc
, 0, has_ctm
, gamma_lut_size
);
444 drm_mode_crtc_set_gamma_size(crtc
, gamma_lut_size
);