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_crtc_state
*state
)
90 struct drm_device
*ddev
= crtc
->dev
;
91 struct tidss_device
*tidss
= to_tidss(ddev
);
92 struct dispc_device
*dispc
= tidss
->dispc
;
93 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
94 u32 hw_videoport
= tcrtc
->hw_videoport
;
95 const struct drm_display_mode
*mode
;
96 enum drm_mode_status ok
;
98 dev_dbg(ddev
->dev
, "%s\n", __func__
);
103 mode
= &state
->adjusted_mode
;
105 ok
= dispc_vp_mode_valid(dispc
, hw_videoport
, mode
);
107 dev_dbg(ddev
->dev
, "%s: bad mode: %ux%u pclk %u kHz\n",
108 __func__
, mode
->hdisplay
, mode
->vdisplay
, mode
->clock
);
112 return dispc_vp_bus_check(dispc
, hw_videoport
, state
);
116 * This needs all affected planes to be present in the atomic
117 * state. The untouched planes are added to the state in
118 * tidss_atomic_check().
120 static void tidss_crtc_position_planes(struct tidss_device
*tidss
,
121 struct drm_crtc
*crtc
,
122 struct drm_crtc_state
*old_state
,
125 struct drm_atomic_state
*ostate
= old_state
->state
;
126 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
127 struct drm_crtc_state
*cstate
= crtc
->state
;
130 if (!newmodeset
&& !cstate
->zpos_changed
&&
131 !to_tidss_crtc_state(cstate
)->plane_pos_changed
)
134 for (layer
= 0; layer
< tidss
->feat
->num_planes
; layer
++) {
135 struct drm_plane_state
*pstate
;
136 struct drm_plane
*plane
;
137 bool layer_active
= false;
140 for_each_new_plane_in_state(ostate
, plane
, pstate
, i
) {
141 if (pstate
->crtc
!= crtc
|| !pstate
->visible
)
144 if (pstate
->normalized_zpos
== layer
) {
151 struct tidss_plane
*tplane
= to_tidss_plane(plane
);
153 dispc_ovr_set_plane(tidss
->dispc
, tplane
->hw_plane_id
,
155 pstate
->crtc_x
, pstate
->crtc_y
,
158 dispc_ovr_enable_layer(tidss
->dispc
, tcrtc
->hw_videoport
, layer
,
163 static void tidss_crtc_atomic_flush(struct drm_crtc
*crtc
,
164 struct drm_crtc_state
*old_crtc_state
)
166 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
167 struct drm_device
*ddev
= crtc
->dev
;
168 struct tidss_device
*tidss
= to_tidss(ddev
);
172 "%s: %s enabled %d, needs modeset %d, event %p\n", __func__
,
173 crtc
->name
, drm_atomic_crtc_needs_modeset(crtc
->state
),
174 crtc
->state
->enable
, crtc
->state
->event
);
176 /* There is nothing to do if CRTC is not going to be enabled. */
177 if (!crtc
->state
->enable
)
181 * Flush CRTC changes with go bit only if new modeset is not
182 * coming, so CRTC is enabled trough out the commit.
184 if (drm_atomic_crtc_needs_modeset(crtc
->state
))
187 /* If the GO bit is stuck we better quit here. */
188 if (WARN_ON(dispc_vp_go_busy(tidss
->dispc
, tcrtc
->hw_videoport
)))
191 /* We should have event if CRTC is enabled through out this commit. */
192 if (WARN_ON(!crtc
->state
->event
))
195 /* Write vp properties to HW if needed. */
196 dispc_vp_setup(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
, false);
198 /* Update plane positions if needed. */
199 tidss_crtc_position_planes(tidss
, crtc
, old_crtc_state
, false);
201 WARN_ON(drm_crtc_vblank_get(crtc
) != 0);
203 spin_lock_irqsave(&ddev
->event_lock
, flags
);
204 dispc_vp_go(tidss
->dispc
, tcrtc
->hw_videoport
);
206 WARN_ON(tcrtc
->event
);
208 tcrtc
->event
= crtc
->state
->event
;
209 crtc
->state
->event
= NULL
;
211 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
214 static void tidss_crtc_atomic_enable(struct drm_crtc
*crtc
,
215 struct drm_crtc_state
*old_state
)
217 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
218 struct drm_device
*ddev
= crtc
->dev
;
219 struct tidss_device
*tidss
= to_tidss(ddev
);
220 const struct drm_display_mode
*mode
= &crtc
->state
->adjusted_mode
;
224 dev_dbg(ddev
->dev
, "%s, event %p\n", __func__
, crtc
->state
->event
);
226 tidss_runtime_get(tidss
);
228 r
= dispc_vp_set_clk_rate(tidss
->dispc
, tcrtc
->hw_videoport
,
233 r
= dispc_vp_enable_clk(tidss
->dispc
, tcrtc
->hw_videoport
);
237 dispc_vp_setup(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
, true);
238 tidss_crtc_position_planes(tidss
, crtc
, old_state
, true);
240 /* Turn vertical blanking interrupt reporting on. */
241 drm_crtc_vblank_on(crtc
);
243 dispc_vp_prepare(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
);
245 dispc_vp_enable(tidss
->dispc
, tcrtc
->hw_videoport
, crtc
->state
);
247 spin_lock_irqsave(&ddev
->event_lock
, flags
);
249 if (crtc
->state
->event
) {
250 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
251 crtc
->state
->event
= NULL
;
254 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
257 static void tidss_crtc_atomic_disable(struct drm_crtc
*crtc
,
258 struct drm_crtc_state
*old_state
)
260 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
261 struct drm_device
*ddev
= crtc
->dev
;
262 struct tidss_device
*tidss
= to_tidss(ddev
);
265 dev_dbg(ddev
->dev
, "%s, event %p\n", __func__
, crtc
->state
->event
);
267 reinit_completion(&tcrtc
->framedone_completion
);
269 dispc_vp_disable(tidss
->dispc
, tcrtc
->hw_videoport
);
271 if (!wait_for_completion_timeout(&tcrtc
->framedone_completion
,
272 msecs_to_jiffies(500)))
273 dev_err(tidss
->dev
, "Timeout waiting for framedone on crtc %d",
274 tcrtc
->hw_videoport
);
276 dispc_vp_unprepare(tidss
->dispc
, tcrtc
->hw_videoport
);
278 spin_lock_irqsave(&ddev
->event_lock
, flags
);
279 if (crtc
->state
->event
) {
280 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
281 crtc
->state
->event
= NULL
;
283 spin_unlock_irqrestore(&ddev
->event_lock
, flags
);
285 drm_crtc_vblank_off(crtc
);
287 dispc_vp_disable_clk(tidss
->dispc
, tcrtc
->hw_videoport
);
289 tidss_runtime_put(tidss
);
293 enum drm_mode_status
tidss_crtc_mode_valid(struct drm_crtc
*crtc
,
294 const struct drm_display_mode
*mode
)
296 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
297 struct drm_device
*ddev
= crtc
->dev
;
298 struct tidss_device
*tidss
= to_tidss(ddev
);
300 return dispc_vp_mode_valid(tidss
->dispc
, tcrtc
->hw_videoport
, mode
);
303 static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs
= {
304 .atomic_check
= tidss_crtc_atomic_check
,
305 .atomic_flush
= tidss_crtc_atomic_flush
,
306 .atomic_enable
= tidss_crtc_atomic_enable
,
307 .atomic_disable
= tidss_crtc_atomic_disable
,
309 .mode_valid
= tidss_crtc_mode_valid
,
314 static int tidss_crtc_enable_vblank(struct drm_crtc
*crtc
)
316 struct drm_device
*ddev
= crtc
->dev
;
317 struct tidss_device
*tidss
= to_tidss(ddev
);
319 dev_dbg(ddev
->dev
, "%s\n", __func__
);
321 tidss_runtime_get(tidss
);
323 tidss_irq_enable_vblank(crtc
);
328 static void tidss_crtc_disable_vblank(struct drm_crtc
*crtc
)
330 struct drm_device
*ddev
= crtc
->dev
;
331 struct tidss_device
*tidss
= to_tidss(ddev
);
333 dev_dbg(ddev
->dev
, "%s\n", __func__
);
335 tidss_irq_disable_vblank(crtc
);
337 tidss_runtime_put(tidss
);
340 static void tidss_crtc_reset(struct drm_crtc
*crtc
)
342 struct tidss_crtc_state
*tcrtc
;
345 __drm_atomic_helper_crtc_destroy_state(crtc
->state
);
349 tcrtc
= kzalloc(sizeof(*tcrtc
), GFP_KERNEL
);
355 __drm_atomic_helper_crtc_reset(crtc
, &tcrtc
->base
);
358 static struct drm_crtc_state
*tidss_crtc_duplicate_state(struct drm_crtc
*crtc
)
360 struct tidss_crtc_state
*state
, *current_state
;
362 if (WARN_ON(!crtc
->state
))
365 current_state
= to_tidss_crtc_state(crtc
->state
);
367 state
= kmalloc(sizeof(*state
), GFP_KERNEL
);
371 __drm_atomic_helper_crtc_duplicate_state(crtc
, &state
->base
);
373 state
->plane_pos_changed
= false;
375 state
->bus_format
= current_state
->bus_format
;
376 state
->bus_flags
= current_state
->bus_flags
;
381 static void tidss_crtc_destroy(struct drm_crtc
*crtc
)
383 struct tidss_crtc
*tcrtc
= to_tidss_crtc(crtc
);
385 drm_crtc_cleanup(crtc
);
389 static const struct drm_crtc_funcs tidss_crtc_funcs
= {
390 .reset
= tidss_crtc_reset
,
391 .destroy
= tidss_crtc_destroy
,
392 .set_config
= drm_atomic_helper_set_config
,
393 .page_flip
= drm_atomic_helper_page_flip
,
394 .atomic_duplicate_state
= tidss_crtc_duplicate_state
,
395 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
396 .enable_vblank
= tidss_crtc_enable_vblank
,
397 .disable_vblank
= tidss_crtc_disable_vblank
,
400 struct tidss_crtc
*tidss_crtc_create(struct tidss_device
*tidss
,
402 struct drm_plane
*primary
)
404 struct tidss_crtc
*tcrtc
;
405 struct drm_crtc
*crtc
;
406 unsigned int gamma_lut_size
= 0;
407 bool has_ctm
= tidss
->feat
->vp_feat
.color
.has_ctm
;
410 tcrtc
= kzalloc(sizeof(*tcrtc
), GFP_KERNEL
);
412 return ERR_PTR(-ENOMEM
);
414 tcrtc
->hw_videoport
= hw_videoport
;
415 init_completion(&tcrtc
->framedone_completion
);
419 ret
= drm_crtc_init_with_planes(&tidss
->ddev
, crtc
, primary
,
420 NULL
, &tidss_crtc_funcs
, NULL
);
426 drm_crtc_helper_add(crtc
, &tidss_crtc_helper_funcs
);
429 * The dispc gamma functions adapt to what ever size we ask
430 * from it no matter what HW supports. X-server assumes 256
431 * element gamma tables so lets use that.
433 if (tidss
->feat
->vp_feat
.color
.gamma_size
)
434 gamma_lut_size
= 256;
436 drm_crtc_enable_color_mgmt(crtc
, 0, has_ctm
, gamma_lut_size
);
438 drm_mode_crtc_set_gamma_size(crtc
, gamma_lut_size
);