2 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
3 * Author: Rob Clark <rob@ti.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <drm/drm_atomic.h>
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_crtc.h>
21 #include <drm/drm_mode.h>
22 #include <drm/drm_plane_helper.h>
23 #include <linux/math64.h>
27 #define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
29 struct omap_crtc_state
{
31 struct drm_crtc_state base
;
32 /* Shadow values for legacy userspace support. */
33 unsigned int rotation
;
37 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
43 struct omap_drm_pipeline
*pipe
;
44 enum omap_channel channel
;
48 bool ignore_digit_sync_lost
;
52 wait_queue_head_t pending_wait
;
53 struct drm_pending_vblank_event
*event
;
56 /* -----------------------------------------------------------------------------
60 struct videomode
*omap_crtc_timings(struct drm_crtc
*crtc
)
62 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
63 return &omap_crtc
->vm
;
66 enum omap_channel
omap_crtc_channel(struct drm_crtc
*crtc
)
68 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
69 return omap_crtc
->channel
;
72 static bool omap_crtc_is_pending(struct drm_crtc
*crtc
)
74 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
78 spin_lock_irqsave(&crtc
->dev
->event_lock
, flags
);
79 pending
= omap_crtc
->pending
;
80 spin_unlock_irqrestore(&crtc
->dev
->event_lock
, flags
);
85 int omap_crtc_wait_pending(struct drm_crtc
*crtc
)
87 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
90 * Timeout is set to a "sufficiently" high value, which should cover
91 * a single frame refresh even on slower displays.
93 return wait_event_timeout(omap_crtc
->pending_wait
,
94 !omap_crtc_is_pending(crtc
),
95 msecs_to_jiffies(250));
98 /* -----------------------------------------------------------------------------
99 * DSS Manager Functions
103 * Manager-ops, callbacks from output when they need to configure
104 * the upstream part of the video pipe.
106 * Most of these we can ignore until we add support for command-mode
107 * panels.. for video-mode the crtc-helpers already do an adequate
108 * job of sequencing the setup of the video pipe in the proper order
111 /* we can probably ignore these until we support command-mode panels: */
112 static void omap_crtc_dss_start_update(struct omap_drm_private
*priv
,
113 enum omap_channel channel
)
117 /* Called only from the encoder enable/disable and suspend/resume handlers. */
118 static void omap_crtc_set_enabled(struct drm_crtc
*crtc
, bool enable
)
120 struct drm_device
*dev
= crtc
->dev
;
121 struct omap_drm_private
*priv
= dev
->dev_private
;
122 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
123 enum omap_channel channel
= omap_crtc
->channel
;
124 struct omap_irq_wait
*wait
;
125 u32 framedone_irq
, vsync_irq
;
128 if (WARN_ON(omap_crtc
->enabled
== enable
))
131 if (omap_crtc
->pipe
->output
->output_type
== OMAP_DISPLAY_TYPE_HDMI
) {
132 priv
->dispc_ops
->mgr_enable(priv
->dispc
, channel
, enable
);
133 omap_crtc
->enabled
= enable
;
137 if (omap_crtc
->channel
== OMAP_DSS_CHANNEL_DIGIT
) {
139 * Digit output produces some sync lost interrupts during the
140 * first frame when enabling, so we need to ignore those.
142 omap_crtc
->ignore_digit_sync_lost
= true;
145 framedone_irq
= priv
->dispc_ops
->mgr_get_framedone_irq(priv
->dispc
,
147 vsync_irq
= priv
->dispc_ops
->mgr_get_vsync_irq(priv
->dispc
, channel
);
150 wait
= omap_irq_wait_init(dev
, vsync_irq
, 1);
153 * When we disable the digit output, we need to wait for
154 * FRAMEDONE to know that DISPC has finished with the output.
156 * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
157 * that case we need to use vsync interrupt, and wait for both
158 * even and odd frames.
162 wait
= omap_irq_wait_init(dev
, framedone_irq
, 1);
164 wait
= omap_irq_wait_init(dev
, vsync_irq
, 2);
167 priv
->dispc_ops
->mgr_enable(priv
->dispc
, channel
, enable
);
168 omap_crtc
->enabled
= enable
;
170 ret
= omap_irq_wait(dev
, wait
, msecs_to_jiffies(100));
172 dev_err(dev
->dev
, "%s: timeout waiting for %s\n",
173 omap_crtc
->name
, enable
? "enable" : "disable");
176 if (omap_crtc
->channel
== OMAP_DSS_CHANNEL_DIGIT
) {
177 omap_crtc
->ignore_digit_sync_lost
= false;
178 /* make sure the irq handler sees the value above */
184 static int omap_crtc_dss_enable(struct omap_drm_private
*priv
,
185 enum omap_channel channel
)
187 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
188 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
190 priv
->dispc_ops
->mgr_set_timings(priv
->dispc
, omap_crtc
->channel
,
192 omap_crtc_set_enabled(&omap_crtc
->base
, true);
197 static void omap_crtc_dss_disable(struct omap_drm_private
*priv
,
198 enum omap_channel channel
)
200 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
201 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
203 omap_crtc_set_enabled(&omap_crtc
->base
, false);
206 static void omap_crtc_dss_set_timings(struct omap_drm_private
*priv
,
207 enum omap_channel channel
,
208 const struct videomode
*vm
)
210 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
211 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
213 DBG("%s", omap_crtc
->name
);
217 static void omap_crtc_dss_set_lcd_config(struct omap_drm_private
*priv
,
218 enum omap_channel channel
,
219 const struct dss_lcd_mgr_config
*config
)
221 struct drm_crtc
*crtc
= priv
->channels
[channel
]->crtc
;
222 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
224 DBG("%s", omap_crtc
->name
);
225 priv
->dispc_ops
->mgr_set_lcd_config(priv
->dispc
, omap_crtc
->channel
,
229 static int omap_crtc_dss_register_framedone(
230 struct omap_drm_private
*priv
, enum omap_channel channel
,
231 void (*handler
)(void *), void *data
)
236 static void omap_crtc_dss_unregister_framedone(
237 struct omap_drm_private
*priv
, enum omap_channel channel
,
238 void (*handler
)(void *), void *data
)
242 static const struct dss_mgr_ops mgr_ops
= {
243 .start_update
= omap_crtc_dss_start_update
,
244 .enable
= omap_crtc_dss_enable
,
245 .disable
= omap_crtc_dss_disable
,
246 .set_timings
= omap_crtc_dss_set_timings
,
247 .set_lcd_config
= omap_crtc_dss_set_lcd_config
,
248 .register_framedone_handler
= omap_crtc_dss_register_framedone
,
249 .unregister_framedone_handler
= omap_crtc_dss_unregister_framedone
,
252 /* -----------------------------------------------------------------------------
253 * Setup, Flush and Page Flip
256 void omap_crtc_error_irq(struct drm_crtc
*crtc
, u32 irqstatus
)
258 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
260 if (omap_crtc
->ignore_digit_sync_lost
) {
261 irqstatus
&= ~DISPC_IRQ_SYNC_LOST_DIGIT
;
266 DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc
->name
, irqstatus
);
269 void omap_crtc_vblank_irq(struct drm_crtc
*crtc
)
271 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
272 struct drm_device
*dev
= omap_crtc
->base
.dev
;
273 struct omap_drm_private
*priv
= dev
->dev_private
;
276 spin_lock(&crtc
->dev
->event_lock
);
278 * If the dispc is busy we're racing the flush operation. Try again on
279 * the next vblank interrupt.
281 if (priv
->dispc_ops
->mgr_go_busy(priv
->dispc
, omap_crtc
->channel
)) {
282 spin_unlock(&crtc
->dev
->event_lock
);
286 /* Send the vblank event if one has been requested. */
287 if (omap_crtc
->event
) {
288 drm_crtc_send_vblank_event(crtc
, omap_crtc
->event
);
289 omap_crtc
->event
= NULL
;
292 pending
= omap_crtc
->pending
;
293 omap_crtc
->pending
= false;
294 spin_unlock(&crtc
->dev
->event_lock
);
297 drm_crtc_vblank_put(crtc
);
299 /* Wake up omap_atomic_complete. */
300 wake_up(&omap_crtc
->pending_wait
);
302 DBG("%s: apply done", omap_crtc
->name
);
305 static void omap_crtc_write_crtc_properties(struct drm_crtc
*crtc
)
307 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
308 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
309 struct omap_overlay_manager_info info
;
311 memset(&info
, 0, sizeof(info
));
313 info
.default_color
= 0x000000;
314 info
.trans_enabled
= false;
315 info
.partial_alpha_enabled
= false;
316 info
.cpr_enable
= false;
318 priv
->dispc_ops
->mgr_setup(priv
->dispc
, omap_crtc
->channel
, &info
);
321 /* -----------------------------------------------------------------------------
325 static void omap_crtc_destroy(struct drm_crtc
*crtc
)
327 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
329 DBG("%s", omap_crtc
->name
);
331 drm_crtc_cleanup(crtc
);
336 static void omap_crtc_arm_event(struct drm_crtc
*crtc
)
338 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
340 WARN_ON(omap_crtc
->pending
);
341 omap_crtc
->pending
= true;
343 if (crtc
->state
->event
) {
344 omap_crtc
->event
= crtc
->state
->event
;
345 crtc
->state
->event
= NULL
;
349 static void omap_crtc_atomic_enable(struct drm_crtc
*crtc
,
350 struct drm_crtc_state
*old_state
)
352 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
353 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
356 DBG("%s", omap_crtc
->name
);
358 priv
->dispc_ops
->runtime_get(priv
->dispc
);
360 spin_lock_irq(&crtc
->dev
->event_lock
);
361 drm_crtc_vblank_on(crtc
);
362 ret
= drm_crtc_vblank_get(crtc
);
365 omap_crtc_arm_event(crtc
);
366 spin_unlock_irq(&crtc
->dev
->event_lock
);
369 static void omap_crtc_atomic_disable(struct drm_crtc
*crtc
,
370 struct drm_crtc_state
*old_state
)
372 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
373 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
375 DBG("%s", omap_crtc
->name
);
377 spin_lock_irq(&crtc
->dev
->event_lock
);
378 if (crtc
->state
->event
) {
379 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
380 crtc
->state
->event
= NULL
;
382 spin_unlock_irq(&crtc
->dev
->event_lock
);
384 drm_crtc_vblank_off(crtc
);
386 priv
->dispc_ops
->runtime_put(priv
->dispc
);
389 static enum drm_mode_status
omap_crtc_mode_valid(struct drm_crtc
*crtc
,
390 const struct drm_display_mode
*mode
)
392 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
394 /* Check for bandwidth limit */
395 if (priv
->max_bandwidth
) {
397 * Estimation for the bandwidth need of a given mode with one
399 * bandwidth = resolution * 32bpp * (pclk / (vtotal * htotal))
402 * The interlaced mode is taken into account by using the
403 * pixelclock in the calculation.
405 * The equation is rearranged for 64bit arithmetic.
407 uint64_t bandwidth
= mode
->clock
* 1000;
408 unsigned int bpp
= 4;
410 bandwidth
= bandwidth
* mode
->hdisplay
* mode
->vdisplay
* bpp
;
411 bandwidth
= div_u64(bandwidth
, mode
->htotal
* mode
->vtotal
);
414 * Reject modes which would need more bandwidth if used with one
415 * full resolution plane (most common use case).
417 if (priv
->max_bandwidth
< bandwidth
)
424 static void omap_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
426 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
427 struct drm_display_mode
*mode
= &crtc
->state
->adjusted_mode
;
429 DBG("%s: set mode: " DRM_MODE_FMT
,
430 omap_crtc
->name
, DRM_MODE_ARG(mode
));
432 drm_display_mode_to_videomode(mode
, &omap_crtc
->vm
);
435 static int omap_crtc_atomic_check(struct drm_crtc
*crtc
,
436 struct drm_crtc_state
*state
)
438 struct drm_plane_state
*pri_state
;
440 if (state
->color_mgmt_changed
&& state
->gamma_lut
) {
441 unsigned int length
= state
->gamma_lut
->length
/
442 sizeof(struct drm_color_lut
);
448 pri_state
= drm_atomic_get_new_plane_state(state
->state
, crtc
->primary
);
450 struct omap_crtc_state
*omap_crtc_state
=
451 to_omap_crtc_state(state
);
453 /* Mirror new values for zpos and rotation in omap_crtc_state */
454 omap_crtc_state
->zpos
= pri_state
->zpos
;
455 omap_crtc_state
->rotation
= pri_state
->rotation
;
461 static void omap_crtc_atomic_begin(struct drm_crtc
*crtc
,
462 struct drm_crtc_state
*old_crtc_state
)
466 static void omap_crtc_atomic_flush(struct drm_crtc
*crtc
,
467 struct drm_crtc_state
*old_crtc_state
)
469 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
470 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
473 if (crtc
->state
->color_mgmt_changed
) {
474 struct drm_color_lut
*lut
= NULL
;
475 unsigned int length
= 0;
477 if (crtc
->state
->gamma_lut
) {
478 lut
= (struct drm_color_lut
*)
479 crtc
->state
->gamma_lut
->data
;
480 length
= crtc
->state
->gamma_lut
->length
/
483 priv
->dispc_ops
->mgr_set_gamma(priv
->dispc
, omap_crtc
->channel
,
487 omap_crtc_write_crtc_properties(crtc
);
489 /* Only flush the CRTC if it is currently enabled. */
490 if (!omap_crtc
->enabled
)
493 DBG("%s: GO", omap_crtc
->name
);
495 ret
= drm_crtc_vblank_get(crtc
);
498 spin_lock_irq(&crtc
->dev
->event_lock
);
499 priv
->dispc_ops
->mgr_go(priv
->dispc
, omap_crtc
->channel
);
500 omap_crtc_arm_event(crtc
);
501 spin_unlock_irq(&crtc
->dev
->event_lock
);
504 static int omap_crtc_atomic_set_property(struct drm_crtc
*crtc
,
505 struct drm_crtc_state
*state
,
506 struct drm_property
*property
,
509 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
510 struct drm_plane_state
*plane_state
;
513 * Delegate property set to the primary plane. Get the plane state and
514 * set the property directly, the shadow copy will be assigned in the
515 * omap_crtc_atomic_check callback. This way updates to plane state will
516 * always be mirrored in the crtc state correctly.
518 plane_state
= drm_atomic_get_plane_state(state
->state
, crtc
->primary
);
519 if (IS_ERR(plane_state
))
520 return PTR_ERR(plane_state
);
522 if (property
== crtc
->primary
->rotation_property
)
523 plane_state
->rotation
= val
;
524 else if (property
== priv
->zorder_prop
)
525 plane_state
->zpos
= val
;
532 static int omap_crtc_atomic_get_property(struct drm_crtc
*crtc
,
533 const struct drm_crtc_state
*state
,
534 struct drm_property
*property
,
537 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
538 struct omap_crtc_state
*omap_state
= to_omap_crtc_state(state
);
540 if (property
== crtc
->primary
->rotation_property
)
541 *val
= omap_state
->rotation
;
542 else if (property
== priv
->zorder_prop
)
543 *val
= omap_state
->zpos
;
550 static void omap_crtc_reset(struct drm_crtc
*crtc
)
553 __drm_atomic_helper_crtc_destroy_state(crtc
->state
);
556 crtc
->state
= kzalloc(sizeof(struct omap_crtc_state
), GFP_KERNEL
);
559 crtc
->state
->crtc
= crtc
;
562 static struct drm_crtc_state
*
563 omap_crtc_duplicate_state(struct drm_crtc
*crtc
)
565 struct omap_crtc_state
*state
, *current_state
;
567 if (WARN_ON(!crtc
->state
))
570 current_state
= to_omap_crtc_state(crtc
->state
);
572 state
= kmalloc(sizeof(*state
), GFP_KERNEL
);
576 __drm_atomic_helper_crtc_duplicate_state(crtc
, &state
->base
);
578 state
->zpos
= current_state
->zpos
;
579 state
->rotation
= current_state
->rotation
;
584 static const struct drm_crtc_funcs omap_crtc_funcs
= {
585 .reset
= omap_crtc_reset
,
586 .set_config
= drm_atomic_helper_set_config
,
587 .destroy
= omap_crtc_destroy
,
588 .page_flip
= drm_atomic_helper_page_flip
,
589 .gamma_set
= drm_atomic_helper_legacy_gamma_set
,
590 .atomic_duplicate_state
= omap_crtc_duplicate_state
,
591 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
592 .atomic_set_property
= omap_crtc_atomic_set_property
,
593 .atomic_get_property
= omap_crtc_atomic_get_property
,
594 .enable_vblank
= omap_irq_enable_vblank
,
595 .disable_vblank
= omap_irq_disable_vblank
,
598 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs
= {
599 .mode_set_nofb
= omap_crtc_mode_set_nofb
,
600 .atomic_check
= omap_crtc_atomic_check
,
601 .atomic_begin
= omap_crtc_atomic_begin
,
602 .atomic_flush
= omap_crtc_atomic_flush
,
603 .atomic_enable
= omap_crtc_atomic_enable
,
604 .atomic_disable
= omap_crtc_atomic_disable
,
605 .mode_valid
= omap_crtc_mode_valid
,
608 /* -----------------------------------------------------------------------------
612 static const char *channel_names
[] = {
613 [OMAP_DSS_CHANNEL_LCD
] = "lcd",
614 [OMAP_DSS_CHANNEL_DIGIT
] = "tv",
615 [OMAP_DSS_CHANNEL_LCD2
] = "lcd2",
616 [OMAP_DSS_CHANNEL_LCD3
] = "lcd3",
619 void omap_crtc_pre_init(struct omap_drm_private
*priv
)
621 dss_install_mgr_ops(priv
->dss
, &mgr_ops
, priv
);
624 void omap_crtc_pre_uninit(struct omap_drm_private
*priv
)
626 dss_uninstall_mgr_ops(priv
->dss
);
629 /* initialize crtc */
630 struct drm_crtc
*omap_crtc_init(struct drm_device
*dev
,
631 struct omap_drm_pipeline
*pipe
,
632 struct drm_plane
*plane
)
634 struct omap_drm_private
*priv
= dev
->dev_private
;
635 struct drm_crtc
*crtc
= NULL
;
636 struct omap_crtc
*omap_crtc
;
637 enum omap_channel channel
;
640 channel
= pipe
->output
->dispc_channel
;
642 DBG("%s", channel_names
[channel
]);
644 omap_crtc
= kzalloc(sizeof(*omap_crtc
), GFP_KERNEL
);
646 return ERR_PTR(-ENOMEM
);
648 crtc
= &omap_crtc
->base
;
650 init_waitqueue_head(&omap_crtc
->pending_wait
);
652 omap_crtc
->pipe
= pipe
;
653 omap_crtc
->channel
= channel
;
654 omap_crtc
->name
= channel_names
[channel
];
656 ret
= drm_crtc_init_with_planes(dev
, crtc
, plane
, NULL
,
657 &omap_crtc_funcs
, NULL
);
659 dev_err(dev
->dev
, "%s(): could not init crtc for: %s\n",
660 __func__
, pipe
->display
->name
);
665 drm_crtc_helper_add(crtc
, &omap_crtc_helper_funcs
);
667 /* The dispc API adapts to what ever size, but the HW supports
668 * 256 element gamma table for LCDs and 1024 element table for
669 * OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
670 * tables so lets use that. Size of HW gamma table can be
671 * extracted with dispc_mgr_gamma_size(). If it returns 0
672 * gamma table is not supprted.
674 if (priv
->dispc_ops
->mgr_gamma_size(priv
->dispc
, channel
)) {
675 unsigned int gamma_lut_size
= 256;
677 drm_crtc_enable_color_mgmt(crtc
, 0, false, gamma_lut_size
);
678 drm_mode_crtc_set_gamma_size(crtc
, gamma_lut_size
);
681 omap_plane_install_properties(crtc
->primary
, &crtc
->base
);