xref: /linux/drivers/gpu/drm/omapdrm/omap_crtc.c (revision 4745dc8abb0a0a9851c07265eea01d844886d5c8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
4  * Author: Rob Clark <rob@ti.com>
5  */
6 
7 #include <drm/drm_atomic.h>
8 #include <drm/drm_atomic_helper.h>
9 #include <drm/drm_crtc.h>
10 #include <drm/drm_mode.h>
11 #include <drm/drm_plane_helper.h>
12 #include <linux/math64.h>
13 
14 #include "omap_drv.h"
15 
16 #define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
17 
18 struct omap_crtc_state {
19 	/* Must be first. */
20 	struct drm_crtc_state base;
21 	/* Shadow values for legacy userspace support. */
22 	unsigned int rotation;
23 	unsigned int zpos;
24 };
25 
26 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
27 
28 struct omap_crtc {
29 	struct drm_crtc base;
30 
31 	const char *name;
32 	struct omap_drm_pipeline *pipe;
33 	enum omap_channel channel;
34 
35 	struct videomode vm;
36 
37 	bool ignore_digit_sync_lost;
38 
39 	bool enabled;
40 	bool pending;
41 	wait_queue_head_t pending_wait;
42 	struct drm_pending_vblank_event *event;
43 };
44 
45 /* -----------------------------------------------------------------------------
46  * Helper Functions
47  */
48 
49 struct videomode *omap_crtc_timings(struct drm_crtc *crtc)
50 {
51 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
52 	return &omap_crtc->vm;
53 }
54 
55 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
56 {
57 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
58 	return omap_crtc->channel;
59 }
60 
61 static bool omap_crtc_is_pending(struct drm_crtc *crtc)
62 {
63 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
64 	unsigned long flags;
65 	bool pending;
66 
67 	spin_lock_irqsave(&crtc->dev->event_lock, flags);
68 	pending = omap_crtc->pending;
69 	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
70 
71 	return pending;
72 }
73 
74 int omap_crtc_wait_pending(struct drm_crtc *crtc)
75 {
76 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
77 
78 	/*
79 	 * Timeout is set to a "sufficiently" high value, which should cover
80 	 * a single frame refresh even on slower displays.
81 	 */
82 	return wait_event_timeout(omap_crtc->pending_wait,
83 				  !omap_crtc_is_pending(crtc),
84 				  msecs_to_jiffies(250));
85 }
86 
87 /* -----------------------------------------------------------------------------
88  * DSS Manager Functions
89  */
90 
91 /*
92  * Manager-ops, callbacks from output when they need to configure
93  * the upstream part of the video pipe.
94  *
95  * Most of these we can ignore until we add support for command-mode
96  * panels.. for video-mode the crtc-helpers already do an adequate
97  * job of sequencing the setup of the video pipe in the proper order
98  */
99 
100 /* we can probably ignore these until we support command-mode panels: */
101 static void omap_crtc_dss_start_update(struct omap_drm_private *priv,
102 				       enum omap_channel channel)
103 {
104 }
105 
106 /* Called only from the encoder enable/disable and suspend/resume handlers. */
107 static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
108 {
109 	struct drm_device *dev = crtc->dev;
110 	struct omap_drm_private *priv = dev->dev_private;
111 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
112 	enum omap_channel channel = omap_crtc->channel;
113 	struct omap_irq_wait *wait;
114 	u32 framedone_irq, vsync_irq;
115 	int ret;
116 
117 	if (WARN_ON(omap_crtc->enabled == enable))
118 		return;
119 
120 	if (omap_crtc->pipe->output->type == OMAP_DISPLAY_TYPE_HDMI) {
121 		priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
122 		omap_crtc->enabled = enable;
123 		return;
124 	}
125 
126 	if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
127 		/*
128 		 * Digit output produces some sync lost interrupts during the
129 		 * first frame when enabling, so we need to ignore those.
130 		 */
131 		omap_crtc->ignore_digit_sync_lost = true;
132 	}
133 
134 	framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(priv->dispc,
135 							       channel);
136 	vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel);
137 
138 	if (enable) {
139 		wait = omap_irq_wait_init(dev, vsync_irq, 1);
140 	} else {
141 		/*
142 		 * When we disable the digit output, we need to wait for
143 		 * FRAMEDONE to know that DISPC has finished with the output.
144 		 *
145 		 * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
146 		 * that case we need to use vsync interrupt, and wait for both
147 		 * even and odd frames.
148 		 */
149 
150 		if (framedone_irq)
151 			wait = omap_irq_wait_init(dev, framedone_irq, 1);
152 		else
153 			wait = omap_irq_wait_init(dev, vsync_irq, 2);
154 	}
155 
156 	priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
157 	omap_crtc->enabled = enable;
158 
159 	ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
160 	if (ret) {
161 		dev_err(dev->dev, "%s: timeout waiting for %s\n",
162 				omap_crtc->name, enable ? "enable" : "disable");
163 	}
164 
165 	if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
166 		omap_crtc->ignore_digit_sync_lost = false;
167 		/* make sure the irq handler sees the value above */
168 		mb();
169 	}
170 }
171 
172 
173 static int omap_crtc_dss_enable(struct omap_drm_private *priv,
174 				enum omap_channel channel)
175 {
176 	struct drm_crtc *crtc = priv->channels[channel]->crtc;
177 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
178 
179 	priv->dispc_ops->mgr_set_timings(priv->dispc, omap_crtc->channel,
180 					 &omap_crtc->vm);
181 	omap_crtc_set_enabled(&omap_crtc->base, true);
182 
183 	return 0;
184 }
185 
186 static void omap_crtc_dss_disable(struct omap_drm_private *priv,
187 				  enum omap_channel channel)
188 {
189 	struct drm_crtc *crtc = priv->channels[channel]->crtc;
190 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
191 
192 	omap_crtc_set_enabled(&omap_crtc->base, false);
193 }
194 
195 static void omap_crtc_dss_set_timings(struct omap_drm_private *priv,
196 		enum omap_channel channel,
197 		const struct videomode *vm)
198 {
199 	struct drm_crtc *crtc = priv->channels[channel]->crtc;
200 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
201 
202 	DBG("%s", omap_crtc->name);
203 	omap_crtc->vm = *vm;
204 }
205 
206 static void omap_crtc_dss_set_lcd_config(struct omap_drm_private *priv,
207 		enum omap_channel channel,
208 		const struct dss_lcd_mgr_config *config)
209 {
210 	struct drm_crtc *crtc = priv->channels[channel]->crtc;
211 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
212 
213 	DBG("%s", omap_crtc->name);
214 	priv->dispc_ops->mgr_set_lcd_config(priv->dispc, omap_crtc->channel,
215 					    config);
216 }
217 
218 static int omap_crtc_dss_register_framedone(
219 		struct omap_drm_private *priv, enum omap_channel channel,
220 		void (*handler)(void *), void *data)
221 {
222 	return 0;
223 }
224 
225 static void omap_crtc_dss_unregister_framedone(
226 		struct omap_drm_private *priv, enum omap_channel channel,
227 		void (*handler)(void *), void *data)
228 {
229 }
230 
231 static const struct dss_mgr_ops mgr_ops = {
232 	.start_update = omap_crtc_dss_start_update,
233 	.enable = omap_crtc_dss_enable,
234 	.disable = omap_crtc_dss_disable,
235 	.set_timings = omap_crtc_dss_set_timings,
236 	.set_lcd_config = omap_crtc_dss_set_lcd_config,
237 	.register_framedone_handler = omap_crtc_dss_register_framedone,
238 	.unregister_framedone_handler = omap_crtc_dss_unregister_framedone,
239 };
240 
241 /* -----------------------------------------------------------------------------
242  * Setup, Flush and Page Flip
243  */
244 
245 void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus)
246 {
247 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
248 
249 	if (omap_crtc->ignore_digit_sync_lost) {
250 		irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
251 		if (!irqstatus)
252 			return;
253 	}
254 
255 	DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
256 }
257 
258 void omap_crtc_vblank_irq(struct drm_crtc *crtc)
259 {
260 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
261 	struct drm_device *dev = omap_crtc->base.dev;
262 	struct omap_drm_private *priv = dev->dev_private;
263 	bool pending;
264 
265 	spin_lock(&crtc->dev->event_lock);
266 	/*
267 	 * If the dispc is busy we're racing the flush operation. Try again on
268 	 * the next vblank interrupt.
269 	 */
270 	if (priv->dispc_ops->mgr_go_busy(priv->dispc, omap_crtc->channel)) {
271 		spin_unlock(&crtc->dev->event_lock);
272 		return;
273 	}
274 
275 	/* Send the vblank event if one has been requested. */
276 	if (omap_crtc->event) {
277 		drm_crtc_send_vblank_event(crtc, omap_crtc->event);
278 		omap_crtc->event = NULL;
279 	}
280 
281 	pending = omap_crtc->pending;
282 	omap_crtc->pending = false;
283 	spin_unlock(&crtc->dev->event_lock);
284 
285 	if (pending)
286 		drm_crtc_vblank_put(crtc);
287 
288 	/* Wake up omap_atomic_complete. */
289 	wake_up(&omap_crtc->pending_wait);
290 
291 	DBG("%s: apply done", omap_crtc->name);
292 }
293 
294 static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc)
295 {
296 	struct omap_drm_private *priv = crtc->dev->dev_private;
297 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
298 	struct omap_overlay_manager_info info;
299 
300 	memset(&info, 0, sizeof(info));
301 
302 	info.default_color = 0x000000;
303 	info.trans_enabled = false;
304 	info.partial_alpha_enabled = false;
305 	info.cpr_enable = false;
306 
307 	priv->dispc_ops->mgr_setup(priv->dispc, omap_crtc->channel, &info);
308 }
309 
310 /* -----------------------------------------------------------------------------
311  * CRTC Functions
312  */
313 
314 static void omap_crtc_destroy(struct drm_crtc *crtc)
315 {
316 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
317 
318 	DBG("%s", omap_crtc->name);
319 
320 	drm_crtc_cleanup(crtc);
321 
322 	kfree(omap_crtc);
323 }
324 
325 static void omap_crtc_arm_event(struct drm_crtc *crtc)
326 {
327 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
328 
329 	WARN_ON(omap_crtc->pending);
330 	omap_crtc->pending = true;
331 
332 	if (crtc->state->event) {
333 		omap_crtc->event = crtc->state->event;
334 		crtc->state->event = NULL;
335 	}
336 }
337 
338 static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
339 				    struct drm_crtc_state *old_state)
340 {
341 	struct omap_drm_private *priv = crtc->dev->dev_private;
342 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
343 	int ret;
344 
345 	DBG("%s", omap_crtc->name);
346 
347 	priv->dispc_ops->runtime_get(priv->dispc);
348 
349 	spin_lock_irq(&crtc->dev->event_lock);
350 	drm_crtc_vblank_on(crtc);
351 	ret = drm_crtc_vblank_get(crtc);
352 	WARN_ON(ret != 0);
353 
354 	omap_crtc_arm_event(crtc);
355 	spin_unlock_irq(&crtc->dev->event_lock);
356 }
357 
358 static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
359 				     struct drm_crtc_state *old_state)
360 {
361 	struct omap_drm_private *priv = crtc->dev->dev_private;
362 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
363 
364 	DBG("%s", omap_crtc->name);
365 
366 	spin_lock_irq(&crtc->dev->event_lock);
367 	if (crtc->state->event) {
368 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
369 		crtc->state->event = NULL;
370 	}
371 	spin_unlock_irq(&crtc->dev->event_lock);
372 
373 	drm_crtc_vblank_off(crtc);
374 
375 	priv->dispc_ops->runtime_put(priv->dispc);
376 }
377 
378 static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
379 					const struct drm_display_mode *mode)
380 {
381 	struct omap_drm_private *priv = crtc->dev->dev_private;
382 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
383 	struct videomode vm = {0};
384 	int r;
385 
386 	drm_display_mode_to_videomode(mode, &vm);
387 	r = priv->dispc_ops->mgr_check_timings(priv->dispc, omap_crtc->channel,
388 					       &vm);
389 	if (r)
390 		return r;
391 
392 	/* Check for bandwidth limit */
393 	if (priv->max_bandwidth) {
394 		/*
395 		 * Estimation for the bandwidth need of a given mode with one
396 		 * full screen plane:
397 		 * bandwidth = resolution * 32bpp * (pclk / (vtotal * htotal))
398 		 *					^^ Refresh rate ^^
399 		 *
400 		 * The interlaced mode is taken into account by using the
401 		 * pixelclock in the calculation.
402 		 *
403 		 * The equation is rearranged for 64bit arithmetic.
404 		 */
405 		uint64_t bandwidth = mode->clock * 1000;
406 		unsigned int bpp = 4;
407 
408 		bandwidth = bandwidth * mode->hdisplay * mode->vdisplay * bpp;
409 		bandwidth = div_u64(bandwidth, mode->htotal * mode->vtotal);
410 
411 		/*
412 		 * Reject modes which would need more bandwidth if used with one
413 		 * full resolution plane (most common use case).
414 		 */
415 		if (priv->max_bandwidth < bandwidth)
416 			return MODE_BAD;
417 	}
418 
419 	return MODE_OK;
420 }
421 
422 static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
423 {
424 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
425 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
426 
427 	DBG("%s: set mode: " DRM_MODE_FMT,
428 	    omap_crtc->name, DRM_MODE_ARG(mode));
429 
430 	drm_display_mode_to_videomode(mode, &omap_crtc->vm);
431 }
432 
433 static int omap_crtc_atomic_check(struct drm_crtc *crtc,
434 				struct drm_crtc_state *state)
435 {
436 	struct drm_plane_state *pri_state;
437 
438 	if (state->color_mgmt_changed && state->gamma_lut) {
439 		unsigned int length = state->gamma_lut->length /
440 			sizeof(struct drm_color_lut);
441 
442 		if (length < 2)
443 			return -EINVAL;
444 	}
445 
446 	pri_state = drm_atomic_get_new_plane_state(state->state, crtc->primary);
447 	if (pri_state) {
448 		struct omap_crtc_state *omap_crtc_state =
449 			to_omap_crtc_state(state);
450 
451 		/* Mirror new values for zpos and rotation in omap_crtc_state */
452 		omap_crtc_state->zpos = pri_state->zpos;
453 		omap_crtc_state->rotation = pri_state->rotation;
454 	}
455 
456 	return 0;
457 }
458 
459 static void omap_crtc_atomic_begin(struct drm_crtc *crtc,
460 				   struct drm_crtc_state *old_crtc_state)
461 {
462 }
463 
464 static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
465 				   struct drm_crtc_state *old_crtc_state)
466 {
467 	struct omap_drm_private *priv = crtc->dev->dev_private;
468 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
469 	int ret;
470 
471 	if (crtc->state->color_mgmt_changed) {
472 		struct drm_color_lut *lut = NULL;
473 		unsigned int length = 0;
474 
475 		if (crtc->state->gamma_lut) {
476 			lut = (struct drm_color_lut *)
477 				crtc->state->gamma_lut->data;
478 			length = crtc->state->gamma_lut->length /
479 				sizeof(*lut);
480 		}
481 		priv->dispc_ops->mgr_set_gamma(priv->dispc, omap_crtc->channel,
482 					       lut, length);
483 	}
484 
485 	omap_crtc_write_crtc_properties(crtc);
486 
487 	/* Only flush the CRTC if it is currently enabled. */
488 	if (!omap_crtc->enabled)
489 		return;
490 
491 	DBG("%s: GO", omap_crtc->name);
492 
493 	ret = drm_crtc_vblank_get(crtc);
494 	WARN_ON(ret != 0);
495 
496 	spin_lock_irq(&crtc->dev->event_lock);
497 	priv->dispc_ops->mgr_go(priv->dispc, omap_crtc->channel);
498 	omap_crtc_arm_event(crtc);
499 	spin_unlock_irq(&crtc->dev->event_lock);
500 }
501 
502 static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
503 					 struct drm_crtc_state *state,
504 					 struct drm_property *property,
505 					 u64 val)
506 {
507 	struct omap_drm_private *priv = crtc->dev->dev_private;
508 	struct drm_plane_state *plane_state;
509 
510 	/*
511 	 * Delegate property set to the primary plane. Get the plane state and
512 	 * set the property directly, the shadow copy will be assigned in the
513 	 * omap_crtc_atomic_check callback. This way updates to plane state will
514 	 * always be mirrored in the crtc state correctly.
515 	 */
516 	plane_state = drm_atomic_get_plane_state(state->state, crtc->primary);
517 	if (IS_ERR(plane_state))
518 		return PTR_ERR(plane_state);
519 
520 	if (property == crtc->primary->rotation_property)
521 		plane_state->rotation = val;
522 	else if (property == priv->zorder_prop)
523 		plane_state->zpos = val;
524 	else
525 		return -EINVAL;
526 
527 	return 0;
528 }
529 
530 static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
531 					 const struct drm_crtc_state *state,
532 					 struct drm_property *property,
533 					 u64 *val)
534 {
535 	struct omap_drm_private *priv = crtc->dev->dev_private;
536 	struct omap_crtc_state *omap_state = to_omap_crtc_state(state);
537 
538 	if (property == crtc->primary->rotation_property)
539 		*val = omap_state->rotation;
540 	else if (property == priv->zorder_prop)
541 		*val = omap_state->zpos;
542 	else
543 		return -EINVAL;
544 
545 	return 0;
546 }
547 
548 static void omap_crtc_reset(struct drm_crtc *crtc)
549 {
550 	if (crtc->state)
551 		__drm_atomic_helper_crtc_destroy_state(crtc->state);
552 
553 	kfree(crtc->state);
554 	crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL);
555 
556 	if (crtc->state)
557 		crtc->state->crtc = crtc;
558 }
559 
560 static struct drm_crtc_state *
561 omap_crtc_duplicate_state(struct drm_crtc *crtc)
562 {
563 	struct omap_crtc_state *state, *current_state;
564 
565 	if (WARN_ON(!crtc->state))
566 		return NULL;
567 
568 	current_state = to_omap_crtc_state(crtc->state);
569 
570 	state = kmalloc(sizeof(*state), GFP_KERNEL);
571 	if (!state)
572 		return NULL;
573 
574 	__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
575 
576 	state->zpos = current_state->zpos;
577 	state->rotation = current_state->rotation;
578 
579 	return &state->base;
580 }
581 
582 static const struct drm_crtc_funcs omap_crtc_funcs = {
583 	.reset = omap_crtc_reset,
584 	.set_config = drm_atomic_helper_set_config,
585 	.destroy = omap_crtc_destroy,
586 	.page_flip = drm_atomic_helper_page_flip,
587 	.gamma_set = drm_atomic_helper_legacy_gamma_set,
588 	.atomic_duplicate_state = omap_crtc_duplicate_state,
589 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
590 	.atomic_set_property = omap_crtc_atomic_set_property,
591 	.atomic_get_property = omap_crtc_atomic_get_property,
592 	.enable_vblank = omap_irq_enable_vblank,
593 	.disable_vblank = omap_irq_disable_vblank,
594 };
595 
596 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
597 	.mode_set_nofb = omap_crtc_mode_set_nofb,
598 	.atomic_check = omap_crtc_atomic_check,
599 	.atomic_begin = omap_crtc_atomic_begin,
600 	.atomic_flush = omap_crtc_atomic_flush,
601 	.atomic_enable = omap_crtc_atomic_enable,
602 	.atomic_disable = omap_crtc_atomic_disable,
603 	.mode_valid = omap_crtc_mode_valid,
604 };
605 
606 /* -----------------------------------------------------------------------------
607  * Init and Cleanup
608  */
609 
610 static const char *channel_names[] = {
611 	[OMAP_DSS_CHANNEL_LCD] = "lcd",
612 	[OMAP_DSS_CHANNEL_DIGIT] = "tv",
613 	[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
614 	[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
615 };
616 
617 void omap_crtc_pre_init(struct omap_drm_private *priv)
618 {
619 	dss_install_mgr_ops(priv->dss, &mgr_ops, priv);
620 }
621 
622 void omap_crtc_pre_uninit(struct omap_drm_private *priv)
623 {
624 	dss_uninstall_mgr_ops(priv->dss);
625 }
626 
627 /* initialize crtc */
628 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
629 				struct omap_drm_pipeline *pipe,
630 				struct drm_plane *plane)
631 {
632 	struct omap_drm_private *priv = dev->dev_private;
633 	struct drm_crtc *crtc = NULL;
634 	struct omap_crtc *omap_crtc;
635 	enum omap_channel channel;
636 	int ret;
637 
638 	channel = pipe->output->dispc_channel;
639 
640 	DBG("%s", channel_names[channel]);
641 
642 	omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
643 	if (!omap_crtc)
644 		return ERR_PTR(-ENOMEM);
645 
646 	crtc = &omap_crtc->base;
647 
648 	init_waitqueue_head(&omap_crtc->pending_wait);
649 
650 	omap_crtc->pipe = pipe;
651 	omap_crtc->channel = channel;
652 	omap_crtc->name = channel_names[channel];
653 
654 	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
655 					&omap_crtc_funcs, NULL);
656 	if (ret < 0) {
657 		dev_err(dev->dev, "%s(): could not init crtc for: %s\n",
658 			__func__, pipe->output->name);
659 		kfree(omap_crtc);
660 		return ERR_PTR(ret);
661 	}
662 
663 	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
664 
665 	/* The dispc API adapts to what ever size, but the HW supports
666 	 * 256 element gamma table for LCDs and 1024 element table for
667 	 * OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
668 	 * tables so lets use that. Size of HW gamma table can be
669 	 * extracted with dispc_mgr_gamma_size(). If it returns 0
670 	 * gamma table is not supprted.
671 	 */
672 	if (priv->dispc_ops->mgr_gamma_size(priv->dispc, channel)) {
673 		unsigned int gamma_lut_size = 256;
674 
675 		drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
676 		drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size);
677 	}
678 
679 	omap_plane_install_properties(crtc->primary, &crtc->base);
680 
681 	return crtc;
682 }
683