]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/omapdrm/omap_crtc.c
d61215494617d92d8f34c16f225e08421e0019ae
[linux.git] / drivers / gpu / drm / omapdrm / omap_crtc.c
1 /*
2  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
3  * Author: Rob Clark <rob@ti.com>
4  *
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.
8  *
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
12  * more details.
13  *
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/>.
16  */
17
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>
24
25 #include "omap_drv.h"
26
27 #define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
28
29 struct omap_crtc_state {
30         /* Must be first. */
31         struct drm_crtc_state base;
32         /* Shadow values for legacy userspace support. */
33         unsigned int rotation;
34         unsigned int zpos;
35         bool manually_updated;
36 };
37
38 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
39
40 struct omap_crtc {
41         struct drm_crtc base;
42
43         const char *name;
44         struct omap_drm_pipeline *pipe;
45         enum omap_channel channel;
46
47         struct videomode vm;
48
49         bool ignore_digit_sync_lost;
50
51         bool enabled;
52         bool pending;
53         wait_queue_head_t pending_wait;
54         struct drm_pending_vblank_event *event;
55         struct delayed_work update_work;
56
57         void (*framedone_handler)(void *);
58         void *framedone_handler_data;
59 };
60
61 /* -----------------------------------------------------------------------------
62  * Helper Functions
63  */
64
65 struct videomode *omap_crtc_timings(struct drm_crtc *crtc)
66 {
67         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
68         return &omap_crtc->vm;
69 }
70
71 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
72 {
73         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
74         return omap_crtc->channel;
75 }
76
77 static bool omap_crtc_is_pending(struct drm_crtc *crtc)
78 {
79         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
80         unsigned long flags;
81         bool pending;
82
83         spin_lock_irqsave(&crtc->dev->event_lock, flags);
84         pending = omap_crtc->pending;
85         spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
86
87         return pending;
88 }
89
90 int omap_crtc_wait_pending(struct drm_crtc *crtc)
91 {
92         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
93
94         /*
95          * Timeout is set to a "sufficiently" high value, which should cover
96          * a single frame refresh even on slower displays.
97          */
98         return wait_event_timeout(omap_crtc->pending_wait,
99                                   !omap_crtc_is_pending(crtc),
100                                   msecs_to_jiffies(250));
101 }
102
103 /* -----------------------------------------------------------------------------
104  * DSS Manager Functions
105  */
106
107 /*
108  * Manager-ops, callbacks from output when they need to configure
109  * the upstream part of the video pipe.
110  */
111
112 static void omap_crtc_dss_start_update(struct omap_drm_private *priv,
113                                        enum omap_channel channel)
114 {
115         priv->dispc_ops->mgr_enable(priv->dispc, channel, true);
116 }
117
118 /* Called only from the encoder enable/disable and suspend/resume handlers. */
119 static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
120 {
121         struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
122         struct drm_device *dev = crtc->dev;
123         struct omap_drm_private *priv = dev->dev_private;
124         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
125         enum omap_channel channel = omap_crtc->channel;
126         struct omap_irq_wait *wait;
127         u32 framedone_irq, vsync_irq;
128         int ret;
129
130         if (WARN_ON(omap_crtc->enabled == enable))
131                 return;
132
133         if (omap_state->manually_updated) {
134                 omap_irq_enable_framedone(crtc, enable);
135                 omap_crtc->enabled = enable;
136                 return;
137         }
138
139         if (omap_crtc->pipe->output->type == OMAP_DISPLAY_TYPE_HDMI) {
140                 priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
141                 omap_crtc->enabled = enable;
142                 return;
143         }
144
145         if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
146                 /*
147                  * Digit output produces some sync lost interrupts during the
148                  * first frame when enabling, so we need to ignore those.
149                  */
150                 omap_crtc->ignore_digit_sync_lost = true;
151         }
152
153         framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(priv->dispc,
154                                                                channel);
155         vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel);
156
157         if (enable) {
158                 wait = omap_irq_wait_init(dev, vsync_irq, 1);
159         } else {
160                 /*
161                  * When we disable the digit output, we need to wait for
162                  * FRAMEDONE to know that DISPC has finished with the output.
163                  *
164                  * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
165                  * that case we need to use vsync interrupt, and wait for both
166                  * even and odd frames.
167                  */
168
169                 if (framedone_irq)
170                         wait = omap_irq_wait_init(dev, framedone_irq, 1);
171                 else
172                         wait = omap_irq_wait_init(dev, vsync_irq, 2);
173         }
174
175         priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
176         omap_crtc->enabled = enable;
177
178         ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
179         if (ret) {
180                 dev_err(dev->dev, "%s: timeout waiting for %s\n",
181                                 omap_crtc->name, enable ? "enable" : "disable");
182         }
183
184         if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
185                 omap_crtc->ignore_digit_sync_lost = false;
186                 /* make sure the irq handler sees the value above */
187                 mb();
188         }
189 }
190
191
192 static int omap_crtc_dss_enable(struct omap_drm_private *priv,
193                                 enum omap_channel channel)
194 {
195         struct drm_crtc *crtc = priv->channels[channel]->crtc;
196         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
197
198         priv->dispc_ops->mgr_set_timings(priv->dispc, omap_crtc->channel,
199                                          &omap_crtc->vm);
200         omap_crtc_set_enabled(&omap_crtc->base, true);
201
202         return 0;
203 }
204
205 static void omap_crtc_dss_disable(struct omap_drm_private *priv,
206                                   enum omap_channel channel)
207 {
208         struct drm_crtc *crtc = priv->channels[channel]->crtc;
209         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
210
211         omap_crtc_set_enabled(&omap_crtc->base, false);
212 }
213
214 static void omap_crtc_dss_set_timings(struct omap_drm_private *priv,
215                 enum omap_channel channel,
216                 const struct videomode *vm)
217 {
218         struct drm_crtc *crtc = priv->channels[channel]->crtc;
219         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
220
221         DBG("%s", omap_crtc->name);
222         omap_crtc->vm = *vm;
223 }
224
225 static void omap_crtc_dss_set_lcd_config(struct omap_drm_private *priv,
226                 enum omap_channel channel,
227                 const struct dss_lcd_mgr_config *config)
228 {
229         struct drm_crtc *crtc = priv->channels[channel]->crtc;
230         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
231
232         DBG("%s", omap_crtc->name);
233         priv->dispc_ops->mgr_set_lcd_config(priv->dispc, omap_crtc->channel,
234                                             config);
235 }
236
237 static int omap_crtc_dss_register_framedone(
238                 struct omap_drm_private *priv, enum omap_channel channel,
239                 void (*handler)(void *), void *data)
240 {
241         struct drm_crtc *crtc = priv->channels[channel]->crtc;
242         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
243         struct drm_device *dev = omap_crtc->base.dev;
244
245         if (omap_crtc->framedone_handler)
246                 return -EBUSY;
247
248         dev_dbg(dev->dev, "register framedone %s", omap_crtc->name);
249
250         omap_crtc->framedone_handler = handler;
251         omap_crtc->framedone_handler_data = data;
252
253         return 0;
254 }
255
256 static void omap_crtc_dss_unregister_framedone(
257                 struct omap_drm_private *priv, enum omap_channel channel,
258                 void (*handler)(void *), void *data)
259 {
260         struct drm_crtc *crtc = priv->channels[channel]->crtc;
261         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
262         struct drm_device *dev = omap_crtc->base.dev;
263
264         dev_dbg(dev->dev, "unregister framedone %s", omap_crtc->name);
265
266         WARN_ON(omap_crtc->framedone_handler != handler);
267         WARN_ON(omap_crtc->framedone_handler_data != data);
268
269         omap_crtc->framedone_handler = NULL;
270         omap_crtc->framedone_handler_data = NULL;
271 }
272
273 static const struct dss_mgr_ops mgr_ops = {
274         .start_update = omap_crtc_dss_start_update,
275         .enable = omap_crtc_dss_enable,
276         .disable = omap_crtc_dss_disable,
277         .set_timings = omap_crtc_dss_set_timings,
278         .set_lcd_config = omap_crtc_dss_set_lcd_config,
279         .register_framedone_handler = omap_crtc_dss_register_framedone,
280         .unregister_framedone_handler = omap_crtc_dss_unregister_framedone,
281 };
282
283 /* -----------------------------------------------------------------------------
284  * Setup, Flush and Page Flip
285  */
286
287 void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus)
288 {
289         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
290
291         if (omap_crtc->ignore_digit_sync_lost) {
292                 irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
293                 if (!irqstatus)
294                         return;
295         }
296
297         DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
298 }
299
300 void omap_crtc_vblank_irq(struct drm_crtc *crtc)
301 {
302         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
303         struct drm_device *dev = omap_crtc->base.dev;
304         struct omap_drm_private *priv = dev->dev_private;
305         bool pending;
306
307         spin_lock(&crtc->dev->event_lock);
308         /*
309          * If the dispc is busy we're racing the flush operation. Try again on
310          * the next vblank interrupt.
311          */
312         if (priv->dispc_ops->mgr_go_busy(priv->dispc, omap_crtc->channel)) {
313                 spin_unlock(&crtc->dev->event_lock);
314                 return;
315         }
316
317         /* Send the vblank event if one has been requested. */
318         if (omap_crtc->event) {
319                 drm_crtc_send_vblank_event(crtc, omap_crtc->event);
320                 omap_crtc->event = NULL;
321         }
322
323         pending = omap_crtc->pending;
324         omap_crtc->pending = false;
325         spin_unlock(&crtc->dev->event_lock);
326
327         if (pending)
328                 drm_crtc_vblank_put(crtc);
329
330         /* Wake up omap_atomic_complete. */
331         wake_up(&omap_crtc->pending_wait);
332
333         DBG("%s: apply done", omap_crtc->name);
334 }
335
336 void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus)
337 {
338         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
339
340         if (!omap_crtc->framedone_handler)
341                 return;
342
343         omap_crtc->framedone_handler(omap_crtc->framedone_handler_data);
344
345         spin_lock(&crtc->dev->event_lock);
346         /* Send the vblank event if one has been requested. */
347         if (omap_crtc->event) {
348                 drm_crtc_send_vblank_event(crtc, omap_crtc->event);
349                 omap_crtc->event = NULL;
350         }
351         omap_crtc->pending = false;
352         spin_unlock(&crtc->dev->event_lock);
353
354         /* Wake up omap_atomic_complete. */
355         wake_up(&omap_crtc->pending_wait);
356 }
357
358 void omap_crtc_flush(struct drm_crtc *crtc)
359 {
360         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
361         struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
362
363         if (!omap_state->manually_updated)
364                 return;
365
366         if (!delayed_work_pending(&omap_crtc->update_work))
367                 schedule_delayed_work(&omap_crtc->update_work, 0);
368 }
369
370 static void omap_crtc_manual_display_update(struct work_struct *data)
371 {
372         struct omap_crtc *omap_crtc =
373                         container_of(data, struct omap_crtc, update_work.work);
374         struct drm_display_mode *mode = &omap_crtc->pipe->crtc->mode;
375         struct omap_dss_device *dssdev = omap_crtc->pipe->output->next;
376         struct drm_device *dev = omap_crtc->base.dev;
377         const struct omap_dss_driver *dssdrv;
378         int ret;
379
380         if (!dssdev) {
381                 dev_err_once(dev->dev, "missing display dssdev!");
382                 return;
383         }
384
385         dssdrv = dssdev->driver;
386         if (!dssdrv || !dssdrv->update) {
387                 dev_err_once(dev->dev, "missing or incorrect dssdrv!");
388                 return;
389         }
390
391         if (dssdrv->sync)
392                 dssdrv->sync(dssdev);
393
394         ret = dssdrv->update(dssdev, 0, 0, mode->hdisplay, mode->vdisplay);
395         if (ret < 0) {
396                 spin_lock_irq(&dev->event_lock);
397                 omap_crtc->pending = false;
398                 spin_unlock_irq(&dev->event_lock);
399                 wake_up(&omap_crtc->pending_wait);
400         }
401 }
402
403 static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc)
404 {
405         struct omap_drm_private *priv = crtc->dev->dev_private;
406         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
407         struct omap_overlay_manager_info info;
408
409         memset(&info, 0, sizeof(info));
410
411         info.default_color = 0x000000;
412         info.trans_enabled = false;
413         info.partial_alpha_enabled = false;
414         info.cpr_enable = false;
415
416         priv->dispc_ops->mgr_setup(priv->dispc, omap_crtc->channel, &info);
417 }
418
419 /* -----------------------------------------------------------------------------
420  * CRTC Functions
421  */
422
423 static void omap_crtc_destroy(struct drm_crtc *crtc)
424 {
425         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
426
427         DBG("%s", omap_crtc->name);
428
429         drm_crtc_cleanup(crtc);
430
431         kfree(omap_crtc);
432 }
433
434 static void omap_crtc_arm_event(struct drm_crtc *crtc)
435 {
436         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
437
438         WARN_ON(omap_crtc->pending);
439         omap_crtc->pending = true;
440
441         if (crtc->state->event) {
442                 omap_crtc->event = crtc->state->event;
443                 crtc->state->event = NULL;
444         }
445 }
446
447 static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
448                                     struct drm_crtc_state *old_state)
449 {
450         struct omap_drm_private *priv = crtc->dev->dev_private;
451         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
452         struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
453         int ret;
454
455         DBG("%s", omap_crtc->name);
456
457         priv->dispc_ops->runtime_get(priv->dispc);
458
459         /* manual updated display will not trigger vsync irq */
460         if (omap_state->manually_updated)
461                 return;
462
463         spin_lock_irq(&crtc->dev->event_lock);
464         drm_crtc_vblank_on(crtc);
465         ret = drm_crtc_vblank_get(crtc);
466         WARN_ON(ret != 0);
467
468         omap_crtc_arm_event(crtc);
469         spin_unlock_irq(&crtc->dev->event_lock);
470 }
471
472 static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
473                                      struct drm_crtc_state *old_state)
474 {
475         struct omap_drm_private *priv = crtc->dev->dev_private;
476         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
477         struct drm_device *dev = crtc->dev;
478
479         DBG("%s", omap_crtc->name);
480
481         spin_lock_irq(&crtc->dev->event_lock);
482         if (crtc->state->event) {
483                 drm_crtc_send_vblank_event(crtc, crtc->state->event);
484                 crtc->state->event = NULL;
485         }
486         spin_unlock_irq(&crtc->dev->event_lock);
487
488         cancel_delayed_work(&omap_crtc->update_work);
489
490         if (!omap_crtc_wait_pending(crtc))
491                 dev_warn(dev->dev, "manual display update did not finish!");
492
493         drm_crtc_vblank_off(crtc);
494
495         priv->dispc_ops->runtime_put(priv->dispc);
496 }
497
498 static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
499                                         const struct drm_display_mode *mode)
500 {
501         struct omap_drm_private *priv = crtc->dev->dev_private;
502         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
503         struct videomode vm = {0};
504         int r;
505
506         drm_display_mode_to_videomode(mode, &vm);
507
508         /*
509          * DSI might not call this, since the supplied mode is not a
510          * valid DISPC mode. DSI will calculate and configure the
511          * proper DISPC mode later.
512          */
513         if (omap_crtc->pipe->output->next == NULL ||
514             omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) {
515                 r = priv->dispc_ops->mgr_check_timings(priv->dispc,
516                                                        omap_crtc->channel,
517                                                        &vm);
518                 if (r)
519                         return r;
520         }
521
522         /* Check for bandwidth limit */
523         if (priv->max_bandwidth) {
524                 /*
525                  * Estimation for the bandwidth need of a given mode with one
526                  * full screen plane:
527                  * bandwidth = resolution * 32bpp * (pclk / (vtotal * htotal))
528                  *                                      ^^ Refresh rate ^^
529                  *
530                  * The interlaced mode is taken into account by using the
531                  * pixelclock in the calculation.
532                  *
533                  * The equation is rearranged for 64bit arithmetic.
534                  */
535                 uint64_t bandwidth = mode->clock * 1000;
536                 unsigned int bpp = 4;
537
538                 bandwidth = bandwidth * mode->hdisplay * mode->vdisplay * bpp;
539                 bandwidth = div_u64(bandwidth, mode->htotal * mode->vtotal);
540
541                 /*
542                  * Reject modes which would need more bandwidth if used with one
543                  * full resolution plane (most common use case).
544                  */
545                 if (priv->max_bandwidth < bandwidth)
546                         return MODE_BAD;
547         }
548
549         return MODE_OK;
550 }
551
552 static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
553 {
554         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
555         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
556
557         DBG("%s: set mode: " DRM_MODE_FMT,
558             omap_crtc->name, DRM_MODE_ARG(mode));
559
560         drm_display_mode_to_videomode(mode, &omap_crtc->vm);
561 }
562
563 static bool omap_crtc_is_manually_updated(struct drm_crtc *crtc)
564 {
565         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
566         struct omap_dss_device *display = omap_crtc->pipe->output->next;
567
568         if (!display)
569                 return false;
570
571         if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
572                 DBG("detected manually updated display!");
573                 return true;
574         }
575
576         return false;
577 }
578
579 static int omap_crtc_atomic_check(struct drm_crtc *crtc,
580                                 struct drm_crtc_state *state)
581 {
582         struct drm_plane_state *pri_state;
583
584         if (state->color_mgmt_changed && state->gamma_lut) {
585                 unsigned int length = state->gamma_lut->length /
586                         sizeof(struct drm_color_lut);
587
588                 if (length < 2)
589                         return -EINVAL;
590         }
591
592         pri_state = drm_atomic_get_new_plane_state(state->state, crtc->primary);
593         if (pri_state) {
594                 struct omap_crtc_state *omap_crtc_state =
595                         to_omap_crtc_state(state);
596
597                 /* Mirror new values for zpos and rotation in omap_crtc_state */
598                 omap_crtc_state->zpos = pri_state->zpos;
599                 omap_crtc_state->rotation = pri_state->rotation;
600
601                 /* Check if this CRTC is for a manually updated display */
602                 omap_crtc_state->manually_updated = omap_crtc_is_manually_updated(crtc);
603         }
604
605         return 0;
606 }
607
608 static void omap_crtc_atomic_begin(struct drm_crtc *crtc,
609                                    struct drm_crtc_state *old_crtc_state)
610 {
611 }
612
613 static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
614                                    struct drm_crtc_state *old_crtc_state)
615 {
616         struct omap_drm_private *priv = crtc->dev->dev_private;
617         struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
618         struct omap_crtc_state *omap_crtc_state = to_omap_crtc_state(crtc->state);
619         int ret;
620
621         if (crtc->state->color_mgmt_changed) {
622                 struct drm_color_lut *lut = NULL;
623                 unsigned int length = 0;
624
625                 if (crtc->state->gamma_lut) {
626                         lut = (struct drm_color_lut *)
627                                 crtc->state->gamma_lut->data;
628                         length = crtc->state->gamma_lut->length /
629                                 sizeof(*lut);
630                 }
631                 priv->dispc_ops->mgr_set_gamma(priv->dispc, omap_crtc->channel,
632                                                lut, length);
633         }
634
635         omap_crtc_write_crtc_properties(crtc);
636
637         /* Only flush the CRTC if it is currently enabled. */
638         if (!omap_crtc->enabled)
639                 return;
640
641         DBG("%s: GO", omap_crtc->name);
642
643         if (omap_crtc_state->manually_updated) {
644                 /* send new image for page flips and modeset changes */
645                 spin_lock_irq(&crtc->dev->event_lock);
646                 omap_crtc_flush(crtc);
647                 omap_crtc_arm_event(crtc);
648                 spin_unlock_irq(&crtc->dev->event_lock);
649                 return;
650         }
651
652         ret = drm_crtc_vblank_get(crtc);
653         WARN_ON(ret != 0);
654
655         spin_lock_irq(&crtc->dev->event_lock);
656         priv->dispc_ops->mgr_go(priv->dispc, omap_crtc->channel);
657         omap_crtc_arm_event(crtc);
658         spin_unlock_irq(&crtc->dev->event_lock);
659 }
660
661 static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
662                                          struct drm_crtc_state *state,
663                                          struct drm_property *property,
664                                          u64 val)
665 {
666         struct omap_drm_private *priv = crtc->dev->dev_private;
667         struct drm_plane_state *plane_state;
668
669         /*
670          * Delegate property set to the primary plane. Get the plane state and
671          * set the property directly, the shadow copy will be assigned in the
672          * omap_crtc_atomic_check callback. This way updates to plane state will
673          * always be mirrored in the crtc state correctly.
674          */
675         plane_state = drm_atomic_get_plane_state(state->state, crtc->primary);
676         if (IS_ERR(plane_state))
677                 return PTR_ERR(plane_state);
678
679         if (property == crtc->primary->rotation_property)
680                 plane_state->rotation = val;
681         else if (property == priv->zorder_prop)
682                 plane_state->zpos = val;
683         else
684                 return -EINVAL;
685
686         return 0;
687 }
688
689 static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
690                                          const struct drm_crtc_state *state,
691                                          struct drm_property *property,
692                                          u64 *val)
693 {
694         struct omap_drm_private *priv = crtc->dev->dev_private;
695         struct omap_crtc_state *omap_state = to_omap_crtc_state(state);
696
697         if (property == crtc->primary->rotation_property)
698                 *val = omap_state->rotation;
699         else if (property == priv->zorder_prop)
700                 *val = omap_state->zpos;
701         else
702                 return -EINVAL;
703
704         return 0;
705 }
706
707 static void omap_crtc_reset(struct drm_crtc *crtc)
708 {
709         if (crtc->state)
710                 __drm_atomic_helper_crtc_destroy_state(crtc->state);
711
712         kfree(crtc->state);
713         crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL);
714
715         if (crtc->state)
716                 crtc->state->crtc = crtc;
717 }
718
719 static struct drm_crtc_state *
720 omap_crtc_duplicate_state(struct drm_crtc *crtc)
721 {
722         struct omap_crtc_state *state, *current_state;
723
724         if (WARN_ON(!crtc->state))
725                 return NULL;
726
727         current_state = to_omap_crtc_state(crtc->state);
728
729         state = kmalloc(sizeof(*state), GFP_KERNEL);
730         if (!state)
731                 return NULL;
732
733         __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
734
735         state->zpos = current_state->zpos;
736         state->rotation = current_state->rotation;
737         state->manually_updated = current_state->manually_updated;
738
739         return &state->base;
740 }
741
742 static const struct drm_crtc_funcs omap_crtc_funcs = {
743         .reset = omap_crtc_reset,
744         .set_config = drm_atomic_helper_set_config,
745         .destroy = omap_crtc_destroy,
746         .page_flip = drm_atomic_helper_page_flip,
747         .gamma_set = drm_atomic_helper_legacy_gamma_set,
748         .atomic_duplicate_state = omap_crtc_duplicate_state,
749         .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
750         .atomic_set_property = omap_crtc_atomic_set_property,
751         .atomic_get_property = omap_crtc_atomic_get_property,
752         .enable_vblank = omap_irq_enable_vblank,
753         .disable_vblank = omap_irq_disable_vblank,
754 };
755
756 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
757         .mode_set_nofb = omap_crtc_mode_set_nofb,
758         .atomic_check = omap_crtc_atomic_check,
759         .atomic_begin = omap_crtc_atomic_begin,
760         .atomic_flush = omap_crtc_atomic_flush,
761         .atomic_enable = omap_crtc_atomic_enable,
762         .atomic_disable = omap_crtc_atomic_disable,
763         .mode_valid = omap_crtc_mode_valid,
764 };
765
766 /* -----------------------------------------------------------------------------
767  * Init and Cleanup
768  */
769
770 static const char *channel_names[] = {
771         [OMAP_DSS_CHANNEL_LCD] = "lcd",
772         [OMAP_DSS_CHANNEL_DIGIT] = "tv",
773         [OMAP_DSS_CHANNEL_LCD2] = "lcd2",
774         [OMAP_DSS_CHANNEL_LCD3] = "lcd3",
775 };
776
777 void omap_crtc_pre_init(struct omap_drm_private *priv)
778 {
779         dss_install_mgr_ops(priv->dss, &mgr_ops, priv);
780 }
781
782 void omap_crtc_pre_uninit(struct omap_drm_private *priv)
783 {
784         dss_uninstall_mgr_ops(priv->dss);
785 }
786
787 /* initialize crtc */
788 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
789                                 struct omap_drm_pipeline *pipe,
790                                 struct drm_plane *plane)
791 {
792         struct omap_drm_private *priv = dev->dev_private;
793         struct drm_crtc *crtc = NULL;
794         struct omap_crtc *omap_crtc;
795         enum omap_channel channel;
796         int ret;
797
798         channel = pipe->output->dispc_channel;
799
800         DBG("%s", channel_names[channel]);
801
802         omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
803         if (!omap_crtc)
804                 return ERR_PTR(-ENOMEM);
805
806         crtc = &omap_crtc->base;
807
808         init_waitqueue_head(&omap_crtc->pending_wait);
809
810         omap_crtc->pipe = pipe;
811         omap_crtc->channel = channel;
812         omap_crtc->name = channel_names[channel];
813
814         /*
815          * We want to refresh manually updated displays from dirty callback,
816          * which is called quite often (e.g. for each drawn line). This will
817          * be used to do the display update asynchronously to avoid blocking
818          * the rendering process and merges multiple dirty calls into one
819          * update if they arrive very fast. We also call this function for
820          * atomic display updates (e.g. for page flips), which means we do
821          * not need extra locking. Atomic updates should be synchronous, but
822          * need to wait for the framedone interrupt anyways.
823          */
824         INIT_DELAYED_WORK(&omap_crtc->update_work,
825                           omap_crtc_manual_display_update);
826
827         ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
828                                         &omap_crtc_funcs, NULL);
829         if (ret < 0) {
830                 dev_err(dev->dev, "%s(): could not init crtc for: %s\n",
831                         __func__, pipe->output->name);
832                 kfree(omap_crtc);
833                 return ERR_PTR(ret);
834         }
835
836         drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
837
838         /* The dispc API adapts to what ever size, but the HW supports
839          * 256 element gamma table for LCDs and 1024 element table for
840          * OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
841          * tables so lets use that. Size of HW gamma table can be
842          * extracted with dispc_mgr_gamma_size(). If it returns 0
843          * gamma table is not supprted.
844          */
845         if (priv->dispc_ops->mgr_gamma_size(priv->dispc, channel)) {
846                 unsigned int gamma_lut_size = 256;
847
848                 drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
849                 drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size);
850         }
851
852         omap_plane_install_properties(crtc->primary, &crtc->base);
853
854         return crtc;
855 }