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_crtc_helper.h>
22 #include <drm/drm_mode.h>
23 #include <drm/drm_plane_helper.h>
24 #include <linux/math64.h>
28 #define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
30 struct omap_crtc_state
{
32 struct drm_crtc_state base
;
33 /* Shadow values for legacy userspace support. */
34 unsigned int rotation
;
38 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
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 /* ovl-mgr-id -> crtc */
112 static struct omap_crtc
*omap_crtcs
[8];
113 static struct omap_dss_device
*omap_crtc_output
[8];
115 /* we can probably ignore these until we support command-mode panels: */
116 static int omap_crtc_dss_connect(enum omap_channel channel
,
117 struct omap_dss_device
*dst
)
119 const struct dispc_ops
*dispc_ops
= dispc_get_ops();
121 if (omap_crtc_output
[channel
])
124 if ((dispc_ops
->mgr_get_supported_outputs(channel
) & dst
->id
) == 0)
127 omap_crtc_output
[channel
] = dst
;
128 dst
->dispc_channel_connected
= true;
133 static void omap_crtc_dss_disconnect(enum omap_channel channel
,
134 struct omap_dss_device
*dst
)
136 omap_crtc_output
[channel
] = NULL
;
137 dst
->dispc_channel_connected
= false;
140 static void omap_crtc_dss_start_update(enum omap_channel channel
)
144 /* Called only from the encoder enable/disable and suspend/resume handlers. */
145 static void omap_crtc_set_enabled(struct drm_crtc
*crtc
, bool enable
)
147 struct drm_device
*dev
= crtc
->dev
;
148 struct omap_drm_private
*priv
= dev
->dev_private
;
149 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
150 enum omap_channel channel
= omap_crtc
->channel
;
151 struct omap_irq_wait
*wait
;
152 u32 framedone_irq
, vsync_irq
;
155 if (WARN_ON(omap_crtc
->enabled
== enable
))
158 if (omap_crtc_output
[channel
]->output_type
== OMAP_DISPLAY_TYPE_HDMI
) {
159 priv
->dispc_ops
->mgr_enable(channel
, enable
);
160 omap_crtc
->enabled
= enable
;
164 if (omap_crtc
->channel
== OMAP_DSS_CHANNEL_DIGIT
) {
166 * Digit output produces some sync lost interrupts during the
167 * first frame when enabling, so we need to ignore those.
169 omap_crtc
->ignore_digit_sync_lost
= true;
172 framedone_irq
= priv
->dispc_ops
->mgr_get_framedone_irq(channel
);
173 vsync_irq
= priv
->dispc_ops
->mgr_get_vsync_irq(channel
);
176 wait
= omap_irq_wait_init(dev
, vsync_irq
, 1);
179 * When we disable the digit output, we need to wait for
180 * FRAMEDONE to know that DISPC has finished with the output.
182 * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
183 * that case we need to use vsync interrupt, and wait for both
184 * even and odd frames.
188 wait
= omap_irq_wait_init(dev
, framedone_irq
, 1);
190 wait
= omap_irq_wait_init(dev
, vsync_irq
, 2);
193 priv
->dispc_ops
->mgr_enable(channel
, enable
);
194 omap_crtc
->enabled
= enable
;
196 ret
= omap_irq_wait(dev
, wait
, msecs_to_jiffies(100));
198 dev_err(dev
->dev
, "%s: timeout waiting for %s\n",
199 omap_crtc
->name
, enable
? "enable" : "disable");
202 if (omap_crtc
->channel
== OMAP_DSS_CHANNEL_DIGIT
) {
203 omap_crtc
->ignore_digit_sync_lost
= false;
204 /* make sure the irq handler sees the value above */
210 static int omap_crtc_dss_enable(enum omap_channel channel
)
212 struct omap_crtc
*omap_crtc
= omap_crtcs
[channel
];
213 struct omap_drm_private
*priv
= omap_crtc
->base
.dev
->dev_private
;
215 priv
->dispc_ops
->mgr_set_timings(omap_crtc
->channel
, &omap_crtc
->vm
);
216 omap_crtc_set_enabled(&omap_crtc
->base
, true);
221 static void omap_crtc_dss_disable(enum omap_channel channel
)
223 struct omap_crtc
*omap_crtc
= omap_crtcs
[channel
];
225 omap_crtc_set_enabled(&omap_crtc
->base
, false);
228 static void omap_crtc_dss_set_timings(enum omap_channel channel
,
229 const struct videomode
*vm
)
231 struct omap_crtc
*omap_crtc
= omap_crtcs
[channel
];
232 DBG("%s", omap_crtc
->name
);
236 static void omap_crtc_dss_set_lcd_config(enum omap_channel channel
,
237 const struct dss_lcd_mgr_config
*config
)
239 struct omap_crtc
*omap_crtc
= omap_crtcs
[channel
];
240 struct omap_drm_private
*priv
= omap_crtc
->base
.dev
->dev_private
;
242 DBG("%s", omap_crtc
->name
);
243 priv
->dispc_ops
->mgr_set_lcd_config(omap_crtc
->channel
, config
);
246 static int omap_crtc_dss_register_framedone(
247 enum omap_channel channel
,
248 void (*handler
)(void *), void *data
)
253 static void omap_crtc_dss_unregister_framedone(
254 enum omap_channel channel
,
255 void (*handler
)(void *), void *data
)
259 static const struct dss_mgr_ops mgr_ops
= {
260 .connect
= omap_crtc_dss_connect
,
261 .disconnect
= omap_crtc_dss_disconnect
,
262 .start_update
= omap_crtc_dss_start_update
,
263 .enable
= omap_crtc_dss_enable
,
264 .disable
= omap_crtc_dss_disable
,
265 .set_timings
= omap_crtc_dss_set_timings
,
266 .set_lcd_config
= omap_crtc_dss_set_lcd_config
,
267 .register_framedone_handler
= omap_crtc_dss_register_framedone
,
268 .unregister_framedone_handler
= omap_crtc_dss_unregister_framedone
,
271 /* -----------------------------------------------------------------------------
272 * Setup, Flush and Page Flip
275 void omap_crtc_error_irq(struct drm_crtc
*crtc
, uint32_t irqstatus
)
277 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
279 if (omap_crtc
->ignore_digit_sync_lost
) {
280 irqstatus
&= ~DISPC_IRQ_SYNC_LOST_DIGIT
;
285 DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc
->name
, irqstatus
);
288 void omap_crtc_vblank_irq(struct drm_crtc
*crtc
)
290 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
291 struct drm_device
*dev
= omap_crtc
->base
.dev
;
292 struct omap_drm_private
*priv
= dev
->dev_private
;
295 spin_lock(&crtc
->dev
->event_lock
);
297 * If the dispc is busy we're racing the flush operation. Try again on
298 * the next vblank interrupt.
300 if (priv
->dispc_ops
->mgr_go_busy(omap_crtc
->channel
)) {
301 spin_unlock(&crtc
->dev
->event_lock
);
305 /* Send the vblank event if one has been requested. */
306 if (omap_crtc
->event
) {
307 drm_crtc_send_vblank_event(crtc
, omap_crtc
->event
);
308 omap_crtc
->event
= NULL
;
311 pending
= omap_crtc
->pending
;
312 omap_crtc
->pending
= false;
313 spin_unlock(&crtc
->dev
->event_lock
);
316 drm_crtc_vblank_put(crtc
);
318 /* Wake up omap_atomic_complete. */
319 wake_up(&omap_crtc
->pending_wait
);
321 DBG("%s: apply done", omap_crtc
->name
);
324 static void omap_crtc_write_crtc_properties(struct drm_crtc
*crtc
)
326 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
327 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
328 struct omap_overlay_manager_info info
;
330 memset(&info
, 0, sizeof(info
));
332 info
.default_color
= 0x000000;
333 info
.trans_enabled
= false;
334 info
.partial_alpha_enabled
= false;
335 info
.cpr_enable
= false;
337 priv
->dispc_ops
->mgr_setup(omap_crtc
->channel
, &info
);
340 /* -----------------------------------------------------------------------------
344 static void omap_crtc_destroy(struct drm_crtc
*crtc
)
346 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
348 DBG("%s", omap_crtc
->name
);
350 drm_crtc_cleanup(crtc
);
355 static void omap_crtc_arm_event(struct drm_crtc
*crtc
)
357 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
359 WARN_ON(omap_crtc
->pending
);
360 omap_crtc
->pending
= true;
362 if (crtc
->state
->event
) {
363 omap_crtc
->event
= crtc
->state
->event
;
364 crtc
->state
->event
= NULL
;
368 static void omap_crtc_atomic_enable(struct drm_crtc
*crtc
,
369 struct drm_crtc_state
*old_state
)
371 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
374 DBG("%s", omap_crtc
->name
);
376 spin_lock_irq(&crtc
->dev
->event_lock
);
377 drm_crtc_vblank_on(crtc
);
378 ret
= drm_crtc_vblank_get(crtc
);
381 omap_crtc_arm_event(crtc
);
382 spin_unlock_irq(&crtc
->dev
->event_lock
);
385 static void omap_crtc_atomic_disable(struct drm_crtc
*crtc
,
386 struct drm_crtc_state
*old_state
)
388 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
390 DBG("%s", omap_crtc
->name
);
392 spin_lock_irq(&crtc
->dev
->event_lock
);
393 if (crtc
->state
->event
) {
394 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
395 crtc
->state
->event
= NULL
;
397 spin_unlock_irq(&crtc
->dev
->event_lock
);
399 drm_crtc_vblank_off(crtc
);
402 static enum drm_mode_status
omap_crtc_mode_valid(struct drm_crtc
*crtc
,
403 const struct drm_display_mode
*mode
)
405 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
407 /* Check for bandwidth limit */
408 if (priv
->max_bandwidth
) {
410 * Estimation for the bandwidth need of a given mode with one
412 * bandwidth = resolution * 32bpp * (pclk / (vtotal * htotal))
415 * The interlaced mode is taken into account by using the
416 * pixelclock in the calculation.
418 * The equation is rearranged for 64bit arithmetic.
420 uint64_t bandwidth
= mode
->clock
* 1000;
421 unsigned int bpp
= 4;
423 bandwidth
= bandwidth
* mode
->hdisplay
* mode
->vdisplay
* bpp
;
424 bandwidth
= div_u64(bandwidth
, mode
->htotal
* mode
->vtotal
);
427 * Reject modes which would need more bandwidth if used with one
428 * full resolution plane (most common use case).
430 if (priv
->max_bandwidth
< bandwidth
)
437 static void omap_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
439 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
440 struct drm_display_mode
*mode
= &crtc
->state
->adjusted_mode
;
441 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
442 const u32 flags_mask
= DISPLAY_FLAGS_DE_HIGH
| DISPLAY_FLAGS_DE_LOW
|
443 DISPLAY_FLAGS_PIXDATA_POSEDGE
| DISPLAY_FLAGS_PIXDATA_NEGEDGE
|
444 DISPLAY_FLAGS_SYNC_POSEDGE
| DISPLAY_FLAGS_SYNC_NEGEDGE
;
447 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
448 omap_crtc
->name
, mode
->base
.id
, mode
->name
,
449 mode
->vrefresh
, mode
->clock
,
450 mode
->hdisplay
, mode
->hsync_start
, mode
->hsync_end
, mode
->htotal
,
451 mode
->vdisplay
, mode
->vsync_start
, mode
->vsync_end
, mode
->vtotal
,
452 mode
->type
, mode
->flags
);
454 drm_display_mode_to_videomode(mode
, &omap_crtc
->vm
);
457 * HACK: This fixes the vm flags.
458 * struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags
459 * and they get lost when converting back and forth between
460 * struct drm_display_mode and struct videomode. The hack below
461 * goes and fetches the missing flags from the panel drivers.
463 * Correct solution would be to use DRM's bus-flags, but that's not
464 * easily possible before the omapdrm's panel/encoder driver model
465 * has been changed to the DRM model.
468 for (i
= 0; i
< priv
->num_encoders
; ++i
) {
469 struct drm_encoder
*encoder
= priv
->encoders
[i
];
471 if (encoder
->crtc
== crtc
) {
472 struct omap_dss_device
*dssdev
;
474 dssdev
= omap_encoder_get_dssdev(encoder
);
477 struct videomode vm
= {0};
479 dssdev
->driver
->get_timings(dssdev
, &vm
);
481 omap_crtc
->vm
.flags
|= vm
.flags
& flags_mask
;
489 static int omap_crtc_atomic_check(struct drm_crtc
*crtc
,
490 struct drm_crtc_state
*state
)
492 struct drm_plane_state
*pri_state
;
494 if (state
->color_mgmt_changed
&& state
->gamma_lut
) {
495 uint length
= state
->gamma_lut
->length
/
496 sizeof(struct drm_color_lut
);
502 pri_state
= drm_atomic_get_new_plane_state(state
->state
, crtc
->primary
);
504 struct omap_crtc_state
*omap_crtc_state
=
505 to_omap_crtc_state(state
);
507 /* Mirror new values for zpos and rotation in omap_crtc_state */
508 omap_crtc_state
->zpos
= pri_state
->zpos
;
509 omap_crtc_state
->rotation
= pri_state
->rotation
;
515 static void omap_crtc_atomic_begin(struct drm_crtc
*crtc
,
516 struct drm_crtc_state
*old_crtc_state
)
520 static void omap_crtc_atomic_flush(struct drm_crtc
*crtc
,
521 struct drm_crtc_state
*old_crtc_state
)
523 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
524 struct omap_crtc
*omap_crtc
= to_omap_crtc(crtc
);
527 if (crtc
->state
->color_mgmt_changed
) {
528 struct drm_color_lut
*lut
= NULL
;
531 if (crtc
->state
->gamma_lut
) {
532 lut
= (struct drm_color_lut
*)
533 crtc
->state
->gamma_lut
->data
;
534 length
= crtc
->state
->gamma_lut
->length
/
537 priv
->dispc_ops
->mgr_set_gamma(omap_crtc
->channel
, lut
, length
);
540 omap_crtc_write_crtc_properties(crtc
);
542 /* Only flush the CRTC if it is currently enabled. */
543 if (!omap_crtc
->enabled
)
546 DBG("%s: GO", omap_crtc
->name
);
548 ret
= drm_crtc_vblank_get(crtc
);
551 spin_lock_irq(&crtc
->dev
->event_lock
);
552 priv
->dispc_ops
->mgr_go(omap_crtc
->channel
);
553 omap_crtc_arm_event(crtc
);
554 spin_unlock_irq(&crtc
->dev
->event_lock
);
557 static int omap_crtc_atomic_set_property(struct drm_crtc
*crtc
,
558 struct drm_crtc_state
*state
,
559 struct drm_property
*property
,
562 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
563 struct drm_plane_state
*plane_state
;
566 * Delegate property set to the primary plane. Get the plane state and
567 * set the property directly, the shadow copy will be assigned in the
568 * omap_crtc_atomic_check callback. This way updates to plane state will
569 * always be mirrored in the crtc state correctly.
571 plane_state
= drm_atomic_get_plane_state(state
->state
, crtc
->primary
);
572 if (IS_ERR(plane_state
))
573 return PTR_ERR(plane_state
);
575 if (property
== crtc
->primary
->rotation_property
)
576 plane_state
->rotation
= val
;
577 else if (property
== priv
->zorder_prop
)
578 plane_state
->zpos
= val
;
585 static int omap_crtc_atomic_get_property(struct drm_crtc
*crtc
,
586 const struct drm_crtc_state
*state
,
587 struct drm_property
*property
,
590 struct omap_drm_private
*priv
= crtc
->dev
->dev_private
;
591 struct omap_crtc_state
*omap_state
= to_omap_crtc_state(state
);
593 if (property
== crtc
->primary
->rotation_property
)
594 *val
= omap_state
->rotation
;
595 else if (property
== priv
->zorder_prop
)
596 *val
= omap_state
->zpos
;
603 static void omap_crtc_reset(struct drm_crtc
*crtc
)
606 __drm_atomic_helper_crtc_destroy_state(crtc
->state
);
609 crtc
->state
= kzalloc(sizeof(struct omap_crtc_state
), GFP_KERNEL
);
612 crtc
->state
->crtc
= crtc
;
615 static struct drm_crtc_state
*
616 omap_crtc_duplicate_state(struct drm_crtc
*crtc
)
618 struct omap_crtc_state
*state
, *current_state
;
620 if (WARN_ON(!crtc
->state
))
623 current_state
= to_omap_crtc_state(crtc
->state
);
625 state
= kmalloc(sizeof(*state
), GFP_KERNEL
);
629 __drm_atomic_helper_crtc_duplicate_state(crtc
, &state
->base
);
631 state
->zpos
= current_state
->zpos
;
632 state
->rotation
= current_state
->rotation
;
637 static const struct drm_crtc_funcs omap_crtc_funcs
= {
638 .reset
= omap_crtc_reset
,
639 .set_config
= drm_atomic_helper_set_config
,
640 .destroy
= omap_crtc_destroy
,
641 .page_flip
= drm_atomic_helper_page_flip
,
642 .gamma_set
= drm_atomic_helper_legacy_gamma_set
,
643 .atomic_duplicate_state
= omap_crtc_duplicate_state
,
644 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
645 .atomic_set_property
= omap_crtc_atomic_set_property
,
646 .atomic_get_property
= omap_crtc_atomic_get_property
,
647 .enable_vblank
= omap_irq_enable_vblank
,
648 .disable_vblank
= omap_irq_disable_vblank
,
651 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs
= {
652 .mode_set_nofb
= omap_crtc_mode_set_nofb
,
653 .atomic_check
= omap_crtc_atomic_check
,
654 .atomic_begin
= omap_crtc_atomic_begin
,
655 .atomic_flush
= omap_crtc_atomic_flush
,
656 .atomic_enable
= omap_crtc_atomic_enable
,
657 .atomic_disable
= omap_crtc_atomic_disable
,
658 .mode_valid
= omap_crtc_mode_valid
,
661 /* -----------------------------------------------------------------------------
665 static const char *channel_names
[] = {
666 [OMAP_DSS_CHANNEL_LCD
] = "lcd",
667 [OMAP_DSS_CHANNEL_DIGIT
] = "tv",
668 [OMAP_DSS_CHANNEL_LCD2
] = "lcd2",
669 [OMAP_DSS_CHANNEL_LCD3
] = "lcd3",
672 void omap_crtc_pre_init(void)
674 memset(omap_crtcs
, 0, sizeof(omap_crtcs
));
676 dss_install_mgr_ops(&mgr_ops
);
679 void omap_crtc_pre_uninit(void)
681 dss_uninstall_mgr_ops();
684 /* initialize crtc */
685 struct drm_crtc
*omap_crtc_init(struct drm_device
*dev
,
686 struct drm_plane
*plane
, struct omap_dss_device
*dssdev
)
688 struct omap_drm_private
*priv
= dev
->dev_private
;
689 struct drm_crtc
*crtc
= NULL
;
690 struct omap_crtc
*omap_crtc
;
691 enum omap_channel channel
;
692 struct omap_dss_device
*out
;
695 out
= omapdss_find_output_from_display(dssdev
);
696 channel
= out
->dispc_channel
;
697 omap_dss_put_device(out
);
699 DBG("%s", channel_names
[channel
]);
701 /* Multiple displays on same channel is not allowed */
702 if (WARN_ON(omap_crtcs
[channel
] != NULL
))
703 return ERR_PTR(-EINVAL
);
705 omap_crtc
= kzalloc(sizeof(*omap_crtc
), GFP_KERNEL
);
707 return ERR_PTR(-ENOMEM
);
709 crtc
= &omap_crtc
->base
;
711 init_waitqueue_head(&omap_crtc
->pending_wait
);
713 omap_crtc
->channel
= channel
;
714 omap_crtc
->name
= channel_names
[channel
];
716 ret
= drm_crtc_init_with_planes(dev
, crtc
, plane
, NULL
,
717 &omap_crtc_funcs
, NULL
);
719 dev_err(dev
->dev
, "%s(): could not init crtc for: %s\n",
720 __func__
, dssdev
->name
);
725 drm_crtc_helper_add(crtc
, &omap_crtc_helper_funcs
);
727 /* The dispc API adapts to what ever size, but the HW supports
728 * 256 element gamma table for LCDs and 1024 element table for
729 * OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
730 * tables so lets use that. Size of HW gamma table can be
731 * extracted with dispc_mgr_gamma_size(). If it returns 0
732 * gamma table is not supprted.
734 if (priv
->dispc_ops
->mgr_gamma_size(channel
)) {
735 uint gamma_lut_size
= 256;
737 drm_crtc_enable_color_mgmt(crtc
, 0, false, gamma_lut_size
);
738 drm_mode_crtc_set_gamma_size(crtc
, gamma_lut_size
);
741 omap_plane_install_properties(crtc
->primary
, &crtc
->base
);
743 omap_crtcs
[channel
] = omap_crtc
;