1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
4 * Author: Rob Clark <rob@ti.com>
7 #include <linux/math64.h>
9 #include <drm/drm_atomic.h>
10 #include <drm/drm_atomic_helper.h>
11 #include <drm/drm_crtc.h>
12 #include <drm/drm_mode.h>
13 #include <drm/drm_plane_helper.h>
14 #include <drm/drm_vblank.h>
18 #define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
20 struct omap_crtc_state
{
22 struct drm_crtc_state base
;
23 /* Shadow values for legacy userspace support. */
24 unsigned int rotation
;
26 bool manually_updated
;
29 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
35 struct omap_drm_pipeline
*pipe
;
36 enum omap_channel channel
;
40 bool ignore_digit_sync_lost
;
44 wait_queue_head_t pending_wait
;
45 struct drm_pending_vblank_event
*event
;
46 struct delayed_work update_work
;
48 void (*framedone_handler
)(void *);
49 void *framedone_handler_data
;
52 /* -----------------------------------------------------------------------------
56 struct videomode
*omap_crtc_timings(struct drm_crtc
*crtc
)
58 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
59 return &omap_crtc
->vm
;
62 enum omap_channel
omap_crtc_channel(struct drm_crtc
*crtc
)
64 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
65 return omap_crtc
->channel
;
68 static bool omap_crtc_is_pending(struct drm_crtc
*crtc
)
70 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
74 spin_lock_irqsave(&crtc
->dev
->event_lock
, flags
);
75 pending
= omap_crtc
->pending
;
76 spin_unlock_irqrestore(&crtc
->dev
->event_lock
, flags
);
81 int omap_crtc_wait_pending(struct drm_crtc
*crtc
)
83 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
86 * Timeout is set to a "sufficiently" high value, which should cover
87 * a single frame refresh even on slower displays.
89 return wait_event_timeout(omap_crtc
->pending_wait
,
90 !omap_crtc_is_pending(crtc
),
91 msecs_to_jiffies(250));
94 /* -----------------------------------------------------------------------------
95 * DSS Manager Functions
99 * Manager-ops, callbacks from output when they need to configure
100 * the upstream part of the video pipe.
103 static void omap_crtc_dss_start_update(struct omap_drm_private
*priv
,
104 enum omap_channel channel
)
106 priv
->dispc_ops
->mgr_enable(priv
->dispc
, channel
, true);
109 /* Called only from the encoder enable/disable and suspend/resume handlers. */
110 static void omap_crtc_set_enabled(struct drm_crtc
*crtc
, bool enable
)
112 struct omap_crtc_state
*omap_state
= to_omap_crtc_state(crtc
->state
);
113 struct drm_device
*dev
= crtc
->dev
;
114 struct omap_drm_private
*priv
= dev
->dev_private
;
115 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
116 enum omap_channel channel
= omap_crtc
->channel
;
117 struct omap_irq_wait
*wait
;
118 u32 framedone_irq
, vsync_irq
;
121 if (WARN_ON(omap_crtc
->enabled
== enable
))
124 if (omap_state
->manually_updated
) {
125 omap_irq_enable_framedone(crtc
, enable
);
126 omap_crtc
->enabled
= enable
;
130 if (omap_crtc
->pipe
->output
->type
== OMAP_DISPLAY_TYPE_HDMI
) {
131 priv
->dispc_ops
->mgr_enable(priv
->dispc
, channel
, enable
);
132 omap_crtc
->enabled
= enable
;
136 if (omap_crtc
->channel
== OMAP_DSS_CHANNEL_DIGIT
) {
138 * Digit output produces some sync lost interrupts during the
139 * first frame when enabling, so we need to ignore those.
141 omap_crtc
->ignore_digit_sync_lost
= true;
144 framedone_irq
= priv
->dispc_ops
->mgr_get_framedone_irq(priv
->dispc
,
146 vsync_irq
= priv
->dispc_ops
->mgr_get_vsync_irq(priv
->dispc
, channel
);
149 wait
= omap_irq_wait_init(dev
, vsync_irq
, 1);
152 * When we disable the digit output, we need to wait for
153 * FRAMEDONE to know that DISPC has finished with the output.
155 * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
156 * that case we need to use vsync interrupt, and wait for both
157 * even and odd frames.
161 wait
= omap_irq_wait_init(dev
, framedone_irq
, 1);
163 wait
= omap_irq_wait_init(dev
, vsync_irq
, 2);
166 priv
->dispc_ops
->mgr_enable(priv
->dispc
, channel
, enable
);
167 omap_crtc
->enabled
= enable
;
169 ret
= omap_irq_wait(dev
, wait
, msecs_to_jiffies(100));
171 dev_err(dev
->dev
, "%s: timeout waiting for %s\n",
172 omap_crtc
->name
, enable
? "enable" : "disable");
175 if (omap_crtc
->channel
== OMAP_DSS_CHANNEL_DIGIT
) {
176 omap_crtc
->ignore_digit_sync_lost
= false;
177 /* make sure the irq handler sees the value above */
183 static int omap_crtc_dss_enable(struct omap_drm_private
*priv
,
184 enum omap_channel channel
)
186 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
187 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
189 priv
->dispc_ops
->mgr_set_timings(priv
->dispc
, omap_crtc
->channel
,
191 omap_crtc_set_enabled(&omap_crtc
->base
, true);
196 static void omap_crtc_dss_disable(struct omap_drm_private
*priv
,
197 enum omap_channel channel
)
199 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
200 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
202 omap_crtc_set_enabled(&omap_crtc
->base
, false);
205 static void omap_crtc_dss_set_timings(struct omap_drm_private
*priv
,
206 enum omap_channel channel
,
207 const struct videomode
*vm
)
209 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
210 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
212 DBG("%s", omap_crtc
->name
);
216 static void omap_crtc_dss_set_lcd_config(struct omap_drm_private
*priv
,
217 enum omap_channel channel
,
218 const struct dss_lcd_mgr_config
*config
)
220 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
221 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
223 DBG("%s", omap_crtc
->name
);
224 priv
->dispc_ops
->mgr_set_lcd_config(priv
->dispc
, omap_crtc
->channel
,
228 static int omap_crtc_dss_register_framedone(
229 struct omap_drm_private
*priv
, enum omap_channel channel
,
230 void (*handler
)(void *), void *data
)
232 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
233 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
234 struct drm_device
*dev
= omap_crtc
->base
.dev
;
236 if (omap_crtc
->framedone_handler
)
239 dev_dbg(dev
->dev
, "register framedone %s", omap_crtc
->name
);
241 omap_crtc
->framedone_handler
= handler
;
242 omap_crtc
->framedone_handler_data
= data
;
247 static void omap_crtc_dss_unregister_framedone(
248 struct omap_drm_private
*priv
, enum omap_channel channel
,
249 void (*handler
)(void *), void *data
)
251 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
252 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
253 struct drm_device
*dev
= omap_crtc
->base
.dev
;
255 dev_dbg(dev
->dev
, "unregister framedone %s", omap_crtc
->name
);
257 WARN_ON(omap_crtc
->framedone_handler
!= handler
);
258 WARN_ON(omap_crtc
->framedone_handler_data
!= data
);
260 omap_crtc
->framedone_handler
= NULL
;
261 omap_crtc
->framedone_handler_data
= NULL
;
264 static const struct dss_mgr_ops mgr_ops
= {
265 .start_update
= omap_crtc_dss_start_update
,
266 .enable
= omap_crtc_dss_enable
,
267 .disable
= omap_crtc_dss_disable
,
268 .set_timings
= omap_crtc_dss_set_timings
,
269 .set_lcd_config
= omap_crtc_dss_set_lcd_config
,
270 .register_framedone_handler
= omap_crtc_dss_register_framedone
,
271 .unregister_framedone_handler
= omap_crtc_dss_unregister_framedone
,
274 /* -----------------------------------------------------------------------------
275 * Setup, Flush and Page Flip
278 void omap_crtc_error_irq(struct drm_crtc
*crtc
, u32 irqstatus
)
280 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
282 if (omap_crtc
->ignore_digit_sync_lost
) {
283 irqstatus
&= ~DISPC_IRQ_SYNC_LOST_DIGIT
;
288 DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc
->name
, irqstatus
);
291 void omap_crtc_vblank_irq(struct drm_crtc
*crtc
)
293 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
294 struct drm_device
*dev
= omap_crtc
->base
.dev
;
295 struct omap_drm_private
*priv
= dev
->dev_private
;
298 spin_lock(&crtc
->dev
->event_lock
);
300 * If the dispc is busy we're racing the flush operation. Try again on
301 * the next vblank interrupt.
303 if (priv
->dispc_ops
->mgr_go_busy(priv
->dispc
, omap_crtc
->channel
)) {
304 spin_unlock(&crtc
->dev
->event_lock
);
308 /* Send the vblank event if one has been requested. */
309 if (omap_crtc
->event
) {
310 drm_crtc_send_vblank_event(crtc
, omap_crtc
->event
);
311 omap_crtc
->event
= NULL
;
314 pending
= omap_crtc
->pending
;
315 omap_crtc
->pending
= false;
316 spin_unlock(&crtc
->dev
->event_lock
);
319 drm_crtc_vblank_put(crtc
);
321 /* Wake up omap_atomic_complete. */
322 wake_up(&omap_crtc
->pending_wait
);
324 DBG("%s: apply done", omap_crtc
->name
);
327 void omap_crtc_framedone_irq(struct drm_crtc
*crtc
, uint32_t irqstatus
)
329 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
331 if (!omap_crtc
->framedone_handler
)
334 omap_crtc
->framedone_handler(omap_crtc
->framedone_handler_data
);
336 spin_lock(&crtc
->dev
->event_lock
);
337 /* Send the vblank event if one has been requested. */
338 if (omap_crtc
->event
) {
339 drm_crtc_send_vblank_event(crtc
, omap_crtc
->event
);
340 omap_crtc
->event
= NULL
;
342 omap_crtc
->pending
= false;
343 spin_unlock(&crtc
->dev
->event_lock
);
345 /* Wake up omap_atomic_complete. */
346 wake_up(&omap_crtc
->pending_wait
);
349 void omap_crtc_flush(struct drm_crtc
*crtc
)
351 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
352 struct omap_crtc_state
*omap_state
= to_omap_crtc_state(crtc
->state
);
354 if (!omap_state
->manually_updated
)
357 if (!delayed_work_pending(&omap_crtc
->update_work
))
358 schedule_delayed_work(&omap_crtc
->update_work
, 0);
361 static void omap_crtc_manual_display_update(struct work_struct
*data
)
363 struct omap_crtc
*omap_crtc
=
364 container_of(data
, struct omap_crtc
, update_work
.work
);
365 struct drm_display_mode
*mode
= &omap_crtc
->pipe
->crtc
->mode
;
366 struct omap_dss_device
*dssdev
= omap_crtc
->pipe
->output
->next
;
367 struct drm_device
*dev
= omap_crtc
->base
.dev
;
368 const struct omap_dss_driver
*dssdrv
;
372 dev_err_once(dev
->dev
, "missing display dssdev!");
376 dssdrv
= dssdev
->driver
;
377 if (!dssdrv
|| !dssdrv
->update
) {
378 dev_err_once(dev
->dev
, "missing or incorrect dssdrv!");
383 dssdrv
->sync(dssdev
);
385 ret
= dssdrv
->update(dssdev
, 0, 0, mode
->hdisplay
, mode
->vdisplay
);
387 spin_lock_irq(&dev
->event_lock
);
388 omap_crtc
->pending
= false;
389 spin_unlock_irq(&dev
->event_lock
);
390 wake_up(&omap_crtc
->pending_wait
);
394 static void omap_crtc_write_crtc_properties(struct drm_crtc
*crtc
)
396 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
397 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
398 struct omap_overlay_manager_info info
;
400 memset(&info
, 0, sizeof(info
));
402 info
.default_color
= 0x000000;
403 info
.trans_enabled
= false;
404 info
.partial_alpha_enabled
= false;
405 info
.cpr_enable
= false;
407 priv
->dispc_ops
->mgr_setup(priv
->dispc
, omap_crtc
->channel
, &info
);
410 /* -----------------------------------------------------------------------------
414 static void omap_crtc_destroy(struct drm_crtc
*crtc
)
416 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
418 DBG("%s", omap_crtc
->name
);
420 drm_crtc_cleanup(crtc
);
425 static void omap_crtc_arm_event(struct drm_crtc
*crtc
)
427 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
429 WARN_ON(omap_crtc
->pending
);
430 omap_crtc
->pending
= true;
432 if (crtc
->state
->event
) {
433 omap_crtc
->event
= crtc
->state
->event
;
434 crtc
->state
->event
= NULL
;
438 static void omap_crtc_atomic_enable(struct drm_crtc
*crtc
,
439 struct drm_crtc_state
*old_state
)
441 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
442 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
443 struct omap_crtc_state
*omap_state
= to_omap_crtc_state(crtc
->state
);
446 DBG("%s", omap_crtc
->name
);
448 priv
->dispc_ops
->runtime_get(priv
->dispc
);
450 /* manual updated display will not trigger vsync irq */
451 if (omap_state
->manually_updated
)
454 spin_lock_irq(&crtc
->dev
->event_lock
);
455 drm_crtc_vblank_on(crtc
);
456 ret
= drm_crtc_vblank_get(crtc
);
459 omap_crtc_arm_event(crtc
);
460 spin_unlock_irq(&crtc
->dev
->event_lock
);
463 static void omap_crtc_atomic_disable(struct drm_crtc
*crtc
,
464 struct drm_crtc_state
*old_state
)
466 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
467 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
468 struct drm_device
*dev
= crtc
->dev
;
470 DBG("%s", omap_crtc
->name
);
472 spin_lock_irq(&crtc
->dev
->event_lock
);
473 if (crtc
->state
->event
) {
474 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
475 crtc
->state
->event
= NULL
;
477 spin_unlock_irq(&crtc
->dev
->event_lock
);
479 cancel_delayed_work(&omap_crtc
->update_work
);
481 if (!omap_crtc_wait_pending(crtc
))
482 dev_warn(dev
->dev
, "manual display update did not finish!");
484 drm_crtc_vblank_off(crtc
);
486 priv
->dispc_ops
->runtime_put(priv
->dispc
);
489 static enum drm_mode_status
omap_crtc_mode_valid(struct drm_crtc
*crtc
,
490 const struct drm_display_mode
*mode
)
492 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
493 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
494 struct videomode vm
= {0};
497 drm_display_mode_to_videomode(mode
, &vm
);
500 * DSI might not call this, since the supplied mode is not a
501 * valid DISPC mode. DSI will calculate and configure the
502 * proper DISPC mode later.
504 if (omap_crtc
->pipe
->output
->next
== NULL
||
505 omap_crtc
->pipe
->output
->next
->type
!= OMAP_DISPLAY_TYPE_DSI
) {
506 r
= priv
->dispc_ops
->mgr_check_timings(priv
->dispc
,
513 /* Check for bandwidth limit */
514 if (priv
->max_bandwidth
) {
516 * Estimation for the bandwidth need of a given mode with one
518 * bandwidth = resolution * 32bpp * (pclk / (vtotal * htotal))
521 * The interlaced mode is taken into account by using the
522 * pixelclock in the calculation.
524 * The equation is rearranged for 64bit arithmetic.
526 uint64_t bandwidth
= mode
->clock
* 1000;
527 unsigned int bpp
= 4;
529 bandwidth
= bandwidth
* mode
->hdisplay
* mode
->vdisplay
* bpp
;
530 bandwidth
= div_u64(bandwidth
, mode
->htotal
* mode
->vtotal
);
533 * Reject modes which would need more bandwidth if used with one
534 * full resolution plane (most common use case).
536 if (priv
->max_bandwidth
< bandwidth
)
543 static void omap_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
545 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
546 struct drm_display_mode
*mode
= &crtc
->state
->adjusted_mode
;
548 DBG("%s: set mode: " DRM_MODE_FMT
,
549 omap_crtc
->name
, DRM_MODE_ARG(mode
));
551 drm_display_mode_to_videomode(mode
, &omap_crtc
->vm
);
554 static bool omap_crtc_is_manually_updated(struct drm_crtc
*crtc
)
556 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
557 struct omap_dss_device
*display
= omap_crtc
->pipe
->output
->next
;
562 if (display
->caps
& OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE
) {
563 DBG("detected manually updated display!");
570 static int omap_crtc_atomic_check(struct drm_crtc
*crtc
,
571 struct drm_crtc_state
*state
)
573 struct drm_plane_state
*pri_state
;
575 if (state
->color_mgmt_changed
&& state
->gamma_lut
) {
576 unsigned int length
= state
->gamma_lut
->length
/
577 sizeof(struct drm_color_lut
);
583 pri_state
= drm_atomic_get_new_plane_state(state
->state
, crtc
->primary
);
585 struct omap_crtc_state
*omap_crtc_state
=
586 to_omap_crtc_state(state
);
588 /* Mirror new values for zpos and rotation in omap_crtc_state */
589 omap_crtc_state
->zpos
= pri_state
->zpos
;
590 omap_crtc_state
->rotation
= pri_state
->rotation
;
592 /* Check if this CRTC is for a manually updated display */
593 omap_crtc_state
->manually_updated
= omap_crtc_is_manually_updated(crtc
);
599 static void omap_crtc_atomic_begin(struct drm_crtc
*crtc
,
600 struct drm_crtc_state
*old_crtc_state
)
604 static void omap_crtc_atomic_flush(struct drm_crtc
*crtc
,
605 struct drm_crtc_state
*old_crtc_state
)
607 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
608 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
609 struct omap_crtc_state
*omap_crtc_state
= to_omap_crtc_state(crtc
->state
);
612 if (crtc
->state
->color_mgmt_changed
) {
613 struct drm_color_lut
*lut
= NULL
;
614 unsigned int length
= 0;
616 if (crtc
->state
->gamma_lut
) {
617 lut
= (struct drm_color_lut
*)
618 crtc
->state
->gamma_lut
->data
;
619 length
= crtc
->state
->gamma_lut
->length
/
622 priv
->dispc_ops
->mgr_set_gamma(priv
->dispc
, omap_crtc
->channel
,
626 omap_crtc_write_crtc_properties(crtc
);
628 /* Only flush the CRTC if it is currently enabled. */
629 if (!omap_crtc
->enabled
)
632 DBG("%s: GO", omap_crtc
->name
);
634 if (omap_crtc_state
->manually_updated
) {
635 /* send new image for page flips and modeset changes */
636 spin_lock_irq(&crtc
->dev
->event_lock
);
637 omap_crtc_flush(crtc
);
638 omap_crtc_arm_event(crtc
);
639 spin_unlock_irq(&crtc
->dev
->event_lock
);
643 ret
= drm_crtc_vblank_get(crtc
);
646 spin_lock_irq(&crtc
->dev
->event_lock
);
647 priv
->dispc_ops
->mgr_go(priv
->dispc
, omap_crtc
->channel
);
648 omap_crtc_arm_event(crtc
);
649 spin_unlock_irq(&crtc
->dev
->event_lock
);
652 static int omap_crtc_atomic_set_property(struct drm_crtc
*crtc
,
653 struct drm_crtc_state
*state
,
654 struct drm_property
*property
,
657 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
658 struct drm_plane_state
*plane_state
;
661 * Delegate property set to the primary plane. Get the plane state and
662 * set the property directly, the shadow copy will be assigned in the
663 * omap_crtc_atomic_check callback. This way updates to plane state will
664 * always be mirrored in the crtc state correctly.
666 plane_state
= drm_atomic_get_plane_state(state
->state
, crtc
->primary
);
667 if (IS_ERR(plane_state
))
668 return PTR_ERR(plane_state
);
670 if (property
== crtc
->primary
->rotation_property
)
671 plane_state
->rotation
= val
;
672 else if (property
== priv
->zorder_prop
)
673 plane_state
->zpos
= val
;
680 static int omap_crtc_atomic_get_property(struct drm_crtc
*crtc
,
681 const struct drm_crtc_state
*state
,
682 struct drm_property
*property
,
685 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
686 struct omap_crtc_state
*omap_state
= to_omap_crtc_state(state
);
688 if (property
== crtc
->primary
->rotation_property
)
689 *val
= omap_state
->rotation
;
690 else if (property
== priv
->zorder_prop
)
691 *val
= omap_state
->zpos
;
698 static void omap_crtc_reset(struct drm_crtc
*crtc
)
701 __drm_atomic_helper_crtc_destroy_state(crtc
->state
);
704 crtc
->state
= kzalloc(sizeof(struct omap_crtc_state
), GFP_KERNEL
);
707 crtc
->state
->crtc
= crtc
;
710 static struct drm_crtc_state
*
711 omap_crtc_duplicate_state(struct drm_crtc
*crtc
)
713 struct omap_crtc_state
*state
, *current_state
;
715 if (WARN_ON(!crtc
->state
))
718 current_state
= to_omap_crtc_state(crtc
->state
);
720 state
= kmalloc(sizeof(*state
), GFP_KERNEL
);
724 __drm_atomic_helper_crtc_duplicate_state(crtc
, &state
->base
);
726 state
->zpos
= current_state
->zpos
;
727 state
->rotation
= current_state
->rotation
;
728 state
->manually_updated
= current_state
->manually_updated
;
733 static const struct drm_crtc_funcs omap_crtc_funcs
= {
734 .reset
= omap_crtc_reset
,
735 .set_config
= drm_atomic_helper_set_config
,
736 .destroy
= omap_crtc_destroy
,
737 .page_flip
= drm_atomic_helper_page_flip
,
738 .gamma_set
= drm_atomic_helper_legacy_gamma_set
,
739 .atomic_duplicate_state
= omap_crtc_duplicate_state
,
740 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
741 .atomic_set_property
= omap_crtc_atomic_set_property
,
742 .atomic_get_property
= omap_crtc_atomic_get_property
,
743 .enable_vblank
= omap_irq_enable_vblank
,
744 .disable_vblank
= omap_irq_disable_vblank
,
747 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs
= {
748 .mode_set_nofb
= omap_crtc_mode_set_nofb
,
749 .atomic_check
= omap_crtc_atomic_check
,
750 .atomic_begin
= omap_crtc_atomic_begin
,
751 .atomic_flush
= omap_crtc_atomic_flush
,
752 .atomic_enable
= omap_crtc_atomic_enable
,
753 .atomic_disable
= omap_crtc_atomic_disable
,
754 .mode_valid
= omap_crtc_mode_valid
,
757 /* -----------------------------------------------------------------------------
761 static const char *channel_names
[] = {
762 [OMAP_DSS_CHANNEL_LCD
] = "lcd",
763 [OMAP_DSS_CHANNEL_DIGIT
] = "tv",
764 [OMAP_DSS_CHANNEL_LCD2
] = "lcd2",
765 [OMAP_DSS_CHANNEL_LCD3
] = "lcd3",
768 void omap_crtc_pre_init(struct omap_drm_private
*priv
)
770 dss_install_mgr_ops(priv
->dss
, &mgr_ops
, priv
);
773 void omap_crtc_pre_uninit(struct omap_drm_private
*priv
)
775 dss_uninstall_mgr_ops(priv
->dss
);
778 /* initialize crtc */
779 struct drm_crtc
*omap_crtc_init(struct drm_device
*dev
,
780 struct omap_drm_pipeline
*pipe
,
781 struct drm_plane
*plane
)
783 struct omap_drm_private
*priv
= dev
->dev_private
;
784 struct drm_crtc
*crtc
= NULL
;
785 struct omap_crtc
*omap_crtc
;
786 enum omap_channel channel
;
789 channel
= pipe
->output
->dispc_channel
;
791 DBG("%s", channel_names
[channel
]);
793 omap_crtc
= kzalloc(sizeof(*omap_crtc
), GFP_KERNEL
);
795 return ERR_PTR(-ENOMEM
);
797 crtc
= &omap_crtc
->base
;
799 init_waitqueue_head(&omap_crtc
->pending_wait
);
801 omap_crtc
->pipe
= pipe
;
802 omap_crtc
->channel
= channel
;
803 omap_crtc
->name
= channel_names
[channel
];
806 * We want to refresh manually updated displays from dirty callback,
807 * which is called quite often (e.g. for each drawn line). This will
808 * be used to do the display update asynchronously to avoid blocking
809 * the rendering process and merges multiple dirty calls into one
810 * update if they arrive very fast. We also call this function for
811 * atomic display updates (e.g. for page flips), which means we do
812 * not need extra locking. Atomic updates should be synchronous, but
813 * need to wait for the framedone interrupt anyways.
815 INIT_DELAYED_WORK(&omap_crtc
->update_work
,
816 omap_crtc_manual_display_update
);
818 ret
= drm_crtc_init_with_planes(dev
, crtc
, plane
, NULL
,
819 &omap_crtc_funcs
, NULL
);
821 dev_err(dev
->dev
, "%s(): could not init crtc for: %s\n",
822 __func__
, pipe
->output
->name
);
827 drm_crtc_helper_add(crtc
, &omap_crtc_helper_funcs
);
829 /* The dispc API adapts to what ever size, but the HW supports
830 * 256 element gamma table for LCDs and 1024 element table for
831 * OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
832 * tables so lets use that. Size of HW gamma table can be
833 * extracted with dispc_mgr_gamma_size(). If it returns 0
834 * gamma table is not supprted.
836 if (priv
->dispc_ops
->mgr_gamma_size(priv
->dispc
, channel
)) {
837 unsigned int gamma_lut_size
= 256;
839 drm_crtc_enable_color_mgmt(crtc
, 0, false, gamma_lut_size
);
840 drm_mode_crtc_set_gamma_size(crtc
, gamma_lut_size
);
843 omap_plane_install_properties(crtc
->primary
, &crtc
->base
);