CHROMIUM: drm/exynos: fb: exynos_drm_fb functions take an exynos_drm_fb
[cascardo/linux.git] / drivers / gpu / drm / exynos / exynos_drm_crtc.c
1 /* exynos_drm_crtc.c
2  *
3  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4  * Authors:
5  *      Inki Dae <inki.dae@samsung.com>
6  *      Joonyoung Shim <jy0922.shim@samsung.com>
7  *      Seung-Woo Kim <sw0312.kim@samsung.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the next
17  * paragraph) shall be included in all copies or substantial portions of the
18  * Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26  * OTHER DEALINGS IN THE SOFTWARE.
27  */
28
29 #include "drmP.h"
30 #include "drm_crtc_helper.h"
31
32 #include "exynos_drm_crtc.h"
33 #include "exynos_drm_drv.h"
34 #include "exynos_drm_fb.h"
35 #include "exynos_drm_encoder.h"
36 #include "exynos_drm_gem.h"
37 #include "exynos_trace.h"
38
39 static void exynos_drm_crtc_apply(struct drm_crtc *crtc)
40 {
41         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
42         struct exynos_drm_overlay *overlay = &exynos_crtc->overlay;
43
44         exynos_drm_fn_encoder(crtc, overlay,
45                         exynos_drm_encoder_crtc_mode_set);
46         exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
47                         exynos_drm_encoder_crtc_commit);
48 }
49
50 void exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
51                                struct drm_framebuffer *fb,
52                                struct drm_display_mode *mode,
53                                struct exynos_drm_crtc_pos *pos)
54 {
55         struct exynos_drm_gem_buf *buffer;
56         unsigned int actual_w;
57         unsigned int actual_h;
58         struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
59         int nr = exynos_drm_format_num_buffers(fb->pixel_format);
60         int i;
61
62         for (i = 0; i < nr; i++) {
63                 buffer = exynos_drm_fb_buffer(exynos_fb, i);
64
65                 overlay->dma_addr[i] = buffer->dma_addr;
66
67                 DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
68                                 i, (unsigned long)overlay->dma_addr[i]);
69         }
70
71         actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w);
72         actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h);
73
74         /* set drm framebuffer data. */
75         overlay->fb_x = pos->fb_x;
76         overlay->fb_y = pos->fb_y;
77         overlay->fb_width = min(pos->fb_w, actual_w);
78         overlay->fb_height = min(pos->fb_h, actual_h);
79         overlay->fb_pitch = fb->pitches[0];
80         overlay->bpp = fb->bits_per_pixel;
81         overlay->pixel_format = fb->pixel_format;
82
83         /* set overlay range to be displayed. */
84         overlay->crtc_x = pos->crtc_x;
85         overlay->crtc_y = pos->crtc_y;
86         overlay->crtc_width = actual_w;
87         overlay->crtc_height = actual_h;
88         overlay->crtc_htotal = mode->crtc_htotal;
89         overlay->crtc_hsync_len = mode->hsync_end - mode->hsync_start;
90         overlay->crtc_vtotal = mode->crtc_vtotal;
91         overlay->crtc_vsync_len = mode->vsync_end - mode->vsync_start;
92
93         /* set drm mode data. */
94         overlay->mode_width = mode->hdisplay;
95         overlay->mode_height = mode->vdisplay;
96         overlay->refresh = mode->vrefresh;
97         overlay->scan_flag = mode->flags;
98
99         DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)",
100                         overlay->crtc_x, overlay->crtc_y,
101                         overlay->crtc_width, overlay->crtc_height);
102 }
103
104 static void exynos_drm_crtc_update(struct drm_crtc *crtc,
105                                    struct drm_framebuffer *fb)
106 {
107         struct exynos_drm_crtc *exynos_crtc;
108         struct exynos_drm_overlay *overlay;
109         struct exynos_drm_crtc_pos pos;
110         struct drm_display_mode *mode = &crtc->mode;
111
112         exynos_crtc = to_exynos_crtc(crtc);
113         overlay = &exynos_crtc->overlay;
114
115         memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos));
116
117         /* it means the offset of framebuffer to be displayed. */
118         pos.fb_x = crtc->x;
119         pos.fb_y = crtc->y;
120         pos.fb_w = fb->width;
121         pos.fb_h = fb->height;
122
123         /* OSD position to be displayed. */
124         pos.crtc_x = 0;
125         pos.crtc_y = 0;
126         pos.crtc_w = fb->width - crtc->x;
127         pos.crtc_h = fb->height - crtc->y;
128
129         exynos_drm_overlay_update(overlay, fb, mode, &pos);
130 }
131
132 static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
133 {
134         struct drm_device *dev = crtc->dev;
135         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
136
137         DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
138
139         if (exynos_crtc->dpms == mode) {
140                 DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
141                 return;
142         }
143
144         mutex_lock(&dev->struct_mutex);
145
146         switch (mode) {
147         case DRM_MODE_DPMS_ON:
148                 exynos_drm_fn_encoder(crtc, &mode,
149                                 exynos_drm_encoder_crtc_dpms);
150                 exynos_crtc->dpms = mode;
151                 break;
152         case DRM_MODE_DPMS_STANDBY:
153         case DRM_MODE_DPMS_SUSPEND:
154         case DRM_MODE_DPMS_OFF:
155                 exynos_drm_fn_encoder(crtc, &mode,
156                                 exynos_drm_encoder_crtc_dpms);
157                 exynos_crtc->dpms = mode;
158                 break;
159         default:
160                 DRM_ERROR("unspecified mode %d\n", mode);
161                 break;
162         }
163
164         mutex_unlock(&dev->struct_mutex);
165 }
166
167 static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
168 {
169         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
170         struct exynos_drm_overlay *overlay = &exynos_crtc->overlay;
171         int win = overlay->zpos;
172
173         exynos_drm_fn_encoder(crtc, &win,
174                 exynos_drm_encoder_crtc_disable);
175 }
176
177 static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
178 {
179         DRM_DEBUG_KMS("%s\n", __FILE__);
180
181         /* drm framework doesn't check NULL. */
182 }
183
184 static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
185                                      struct drm_framebuffer *fb,
186                                      struct drm_pending_vblank_event *event);
187
188 static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
189 {
190         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
191         int ret;
192
193         DRM_DEBUG_KMS("%s\n", __FILE__);
194
195         /*
196          * when set_crtc is requested from user or at booting time,
197          * crtc->commit would be called without dpms call so if dpms is
198          * no power on then crtc->dpms should be called
199          * with DRM_MODE_DPMS_ON for the hardware power to be on.
200          */
201         if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) {
202                 int mode = DRM_MODE_DPMS_ON;
203
204                 /*
205                  * TODO(seanpaul): This has the nasty habit of calling the
206                  * underlying dpms/power callbacks twice on boot. This code
207                  * needs to be cleaned up so this doesn't happen.
208                  */
209
210                 /*
211                  * enable hardware(power on) to all encoders hdmi connected
212                  * to current crtc.
213                  */
214                 exynos_drm_crtc_dpms(crtc, mode);
215                 /*
216                  * enable dma to all encoders connected to current crtc and
217                  * lcd panel.
218                  */
219                 exynos_drm_fn_encoder(crtc, &mode,
220                                         exynos_drm_encoder_dpms_from_crtc);
221         }
222
223         ret = exynos_drm_crtc_page_flip(crtc, crtc->fb, NULL);
224         if (ret)
225                 DRM_ERROR("page_flip failed\n");
226 }
227
228 static bool
229 exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc,
230                             struct drm_display_mode *mode,
231                             struct drm_display_mode *adjusted_mode)
232 {
233         DRM_DEBUG_KMS("%s\n", __FILE__);
234
235         /* drm framework doesn't check NULL */
236         return true;
237 }
238
239 static int
240 exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
241                           struct drm_display_mode *adjusted_mode, int x, int y,
242                           struct drm_framebuffer *old_fb)
243 {
244         struct exynos_drm_private *dev_priv = crtc->dev->dev_private;
245         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
246         struct drm_framebuffer *fb = crtc->fb;
247         int ret;
248
249         DRM_DEBUG_KMS("%s\n", __FILE__);
250
251         if (!fb)
252                 return -EINVAL;
253
254         /*
255          * copy the mode data adjusted by mode_fixup() into crtc->mode
256          * so that hardware can be seet to proper mode.
257          */
258         memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
259
260         /* We should never timeout here. */
261         ret = wait_event_timeout(dev_priv->wait_vsync_queue,
262                                  !exynos_crtc->flip_in_flight,
263                                  DRM_HZ/20);
264         if (!ret)
265                 DRM_ERROR("Timed out waiting for flips to complete\n");
266
267         exynos_drm_crtc_update(crtc, fb);
268
269         return 0;
270 }
271
272 static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
273                                           struct drm_framebuffer *old_fb)
274 {
275         struct exynos_drm_private *dev_priv = crtc->dev->dev_private;
276         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
277         struct drm_framebuffer *fb = crtc->fb;
278         int ret;
279
280         DRM_DEBUG_KMS("%s\n", __FILE__);
281
282         if (!fb)
283                 return -EINVAL;
284
285         /* We should never timeout here. */
286         ret = wait_event_timeout(dev_priv->wait_vsync_queue,
287                                  !exynos_crtc->flip_in_flight,
288                                  DRM_HZ/20);
289         if (!ret)
290                 DRM_ERROR("Timed out waiting for flips to complete\n");
291
292
293         ret = exynos_drm_crtc_page_flip(crtc, fb, NULL);
294         if (ret)
295                 DRM_ERROR("page_flip failed\n");
296
297         return ret;
298 }
299
300 static void exynos_drm_crtc_load_lut(struct drm_crtc *crtc)
301 {
302         DRM_DEBUG_KMS("%s\n", __FILE__);
303         /* drm framework doesn't check NULL */
304 }
305
306 static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
307         .dpms           = exynos_drm_crtc_dpms,
308         .disable        = exynos_drm_crtc_disable,
309         .prepare        = exynos_drm_crtc_prepare,
310         .commit         = exynos_drm_crtc_commit,
311         .mode_fixup     = exynos_drm_crtc_mode_fixup,
312         .mode_set       = exynos_drm_crtc_mode_set,
313         .mode_set_base  = exynos_drm_crtc_mode_set_base,
314         .load_lut       = exynos_drm_crtc_load_lut,
315 };
316
317 #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
318 void exynos_drm_kds_callback(void *callback_parameter, void *callback_extra_parameter)
319 {
320         struct drm_framebuffer *fb = callback_parameter;
321         struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
322         struct drm_crtc *crtc =  exynos_fb->crtc;
323         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
324         struct drm_device *dev = crtc->dev;
325         struct kds_resource_set **pkds = callback_extra_parameter;
326         struct kds_resource_set *prev_kds;
327         struct drm_framebuffer *prev_fb;
328         unsigned long flags;
329
330         exynos_drm_crtc_update(crtc, fb);
331         exynos_drm_crtc_apply(crtc);
332
333         spin_lock_irqsave(&dev->event_lock, flags);
334         prev_kds = exynos_crtc->pending_kds;
335         prev_fb = exynos_crtc->pending_fb;
336         exynos_crtc->pending_kds = *pkds;
337         exynos_crtc->pending_fb = fb;
338         *pkds = NULL;
339         if (prev_fb)
340                 exynos_crtc->flip_in_flight--;
341         spin_unlock_irqrestore(&dev->event_lock, flags);
342
343         if (prev_fb) {
344                 DRM_ERROR("previous work detected\n");
345                 exynos_drm_fb_put(to_exynos_fb(prev_fb));
346                 if (prev_kds)
347                         kds_resource_set_release(&prev_kds);
348         } else {
349                 BUG_ON(atomic_read(&exynos_crtc->flip_pending));
350                 BUG_ON(prev_kds);
351                 atomic_set(&exynos_crtc->flip_pending, 1);
352         }
353 }
354 #endif
355
356 static void exynos_drm_crtc_flip_complete(struct drm_pending_vblank_event *e)
357 {
358         struct timeval now;
359
360         do_gettimeofday(&now);
361         e->event.sequence = 0;
362         e->event.tv_sec = now.tv_sec;
363         e->event.tv_usec = now.tv_usec;
364         list_add_tail(&e->base.link, &e->base.file_priv->event_list);
365         wake_up_interruptible(&e->base.file_priv->event_wait);
366         trace_exynos_fake_flip_complete(e->pipe);
367 }
368
369 static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
370                                      struct drm_framebuffer *fb,
371                                      struct drm_pending_vblank_event *event)
372 {
373         struct drm_device *dev = crtc->dev;
374         struct exynos_drm_private *dev_priv = dev->dev_private;
375         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
376         unsigned long flags;
377         int ret;
378 #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
379         struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
380         struct exynos_drm_gem_obj *gem_ob = (struct exynos_drm_gem_obj *)exynos_fb->exynos_gem_obj[0];
381         struct kds_resource_set **pkds;
382         struct drm_pending_vblank_event *event_to_send;
383 #endif
384         DRM_DEBUG_KMS("%s\n", __FILE__);
385
386         /*
387          * the pipe from user always is 0 so we can set pipe number
388          * of current owner to event.
389          */
390         if (event)
391                 event->pipe = exynos_crtc->pipe;
392
393         ret = drm_vblank_get(dev, exynos_crtc->pipe);
394         if (ret) {
395                 DRM_ERROR("Unable to get vblank\n");
396                 return -EINVAL;
397         }
398
399 #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
400         spin_lock_irqsave(&dev->event_lock, flags);
401         if (exynos_crtc->flip_in_flight > 1) {
402                 spin_unlock_irqrestore(&dev->event_lock, flags);
403                 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
404                 ret = -EBUSY;
405                 goto fail_max_in_flight;
406         }
407         /* Signal previous flip event. Or if none in flight signal current. */
408         if (exynos_crtc->flip_in_flight) {
409                 event_to_send = exynos_crtc->event;
410                 exynos_crtc->event = event;
411         } else {
412                 event_to_send = event;
413                 exynos_crtc->event = NULL;
414         }
415         pkds = &exynos_crtc->future_kds;
416         if (*pkds)
417                 pkds = &exynos_crtc->future_kds_extra;
418         *pkds = ERR_PTR(-EINVAL); /* Make it non-NULL */
419         exynos_crtc->flip_in_flight++;
420         spin_unlock_irqrestore(&dev->event_lock, flags);
421 #endif
422
423         mutex_lock(&dev->struct_mutex);
424
425         crtc->fb = fb;
426
427         mutex_unlock(&dev->struct_mutex);
428
429 #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
430         exynos_fb->crtc = crtc;
431         if (gem_ob->base.export_dma_buf) {
432                 struct dma_buf *buf = gem_ob->base.export_dma_buf;
433                 unsigned long shared = 0UL;
434                 struct kds_resource *res_list = get_dma_buf_kds_resource(buf);
435
436                 /*
437                  * If we don't already have a reference to the dma_buf,
438                  * grab one now. We'll release it in exynos_drm_fb_destory().
439                  */
440                 if (!exynos_fb->dma_buf) {
441                         get_dma_buf(buf);
442                         exynos_fb->dma_buf = buf;
443                 }
444                 BUG_ON(exynos_fb->dma_buf !=  buf);
445
446                 /* Waiting for the KDS resource*/
447                 ret = kds_async_waitall(pkds, KDS_FLAG_LOCKED_WAIT,
448                                         &dev_priv->kds_cb, fb, pkds, 1,
449                                         &shared, &res_list);
450                 if (ret) {
451                         DRM_ERROR("kds_async_waitall failed: %d\n", ret);
452                         goto fail_kds;
453                 }
454         } else {
455                 /*
456                  * For normal page-flip (i.e. non-modeset) we should
457                  * never be flipping a non-kds buffer.
458                  */
459                 if (event)
460                         DRM_ERROR("flipping a non-kds buffer\n");
461                 *pkds = NULL;
462                 exynos_drm_kds_callback(fb, pkds);
463         }
464
465         if (event_to_send) {
466                 spin_lock_irqsave(&dev->event_lock, flags);
467                 exynos_drm_crtc_flip_complete(event_to_send);
468                 spin_unlock_irqrestore(&dev->event_lock, flags);
469         }
470 #endif
471
472         exynos_drm_fb_get(exynos_fb);
473
474         trace_exynos_flip_request(exynos_crtc->pipe);
475
476         return 0;
477
478 fail_kds:
479         *pkds = NULL;
480         spin_lock_irqsave(&dev->event_lock, flags);
481         exynos_crtc->flip_in_flight--;
482         spin_unlock_irqrestore(&dev->event_lock, flags);
483 fail_max_in_flight:
484         drm_vblank_put(dev, exynos_crtc->pipe);
485         return ret;
486 }
487
488 void exynos_drm_crtc_finish_pageflip(struct drm_device *drm_dev, int crtc_idx)
489 {
490         struct exynos_drm_private *dev_priv = drm_dev->dev_private;
491         struct drm_crtc *crtc = dev_priv->crtc[crtc_idx];
492         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
493         struct kds_resource_set *kds;
494         struct drm_framebuffer *fb;
495         unsigned long flags;
496
497         /* set wait vsync wake up queue. */
498         DRM_WAKEUP(&dev_priv->wait_vsync_queue);
499
500         if (!atomic_cmpxchg(&exynos_crtc->flip_pending, 1, 0))
501                 return;
502
503         trace_exynos_flip_complete(crtc_idx);
504
505         spin_lock_irqsave(&drm_dev->event_lock, flags);
506         if (exynos_crtc->event) {
507                 exynos_drm_crtc_flip_complete(exynos_crtc->event);
508                 exynos_crtc->event = NULL;
509         }
510         kds = exynos_crtc->current_kds;
511         exynos_crtc->current_kds = exynos_crtc->pending_kds;
512         exynos_crtc->pending_kds = NULL;
513         fb = exynos_crtc->current_fb;
514         exynos_crtc->current_fb = exynos_crtc->pending_fb;
515         exynos_crtc->pending_fb = NULL;
516         exynos_crtc->flip_in_flight--;
517         spin_unlock_irqrestore(&drm_dev->event_lock, flags);
518
519         if (fb)
520                 exynos_drm_fb_put(to_exynos_fb(fb));
521         if (kds)
522                 kds_resource_set_release(&kds);
523
524         drm_vblank_put(drm_dev, crtc_idx);
525 }
526
527 static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
528 {
529         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
530         struct exynos_drm_private *private = crtc->dev->dev_private;
531
532         DRM_DEBUG_KMS("%s\n", __FILE__);
533
534         private->crtc[exynos_crtc->pipe] = NULL;
535
536         drm_crtc_cleanup(crtc);
537         kfree(exynos_crtc);
538 }
539
540 static struct drm_crtc_funcs exynos_crtc_funcs = {
541         .set_config     = drm_crtc_helper_set_config,
542         .page_flip      = exynos_drm_crtc_page_flip,
543         .destroy        = exynos_drm_crtc_destroy,
544 };
545
546 struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_device *dev,
547                 struct drm_crtc *crtc)
548 {
549         struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
550
551         return &exynos_crtc->overlay;
552 }
553
554 int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
555 {
556         struct exynos_drm_crtc *exynos_crtc;
557         struct exynos_drm_private *private = dev->dev_private;
558         struct drm_crtc *crtc;
559
560         DRM_DEBUG_KMS("%s\n", __FILE__);
561
562         exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
563         if (!exynos_crtc) {
564                 DRM_ERROR("failed to allocate exynos crtc\n");
565                 return -ENOMEM;
566         }
567
568         exynos_crtc->pipe = nr;
569         exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
570         exynos_crtc->overlay.zpos = DEFAULT_ZPOS;
571         crtc = &exynos_crtc->drm_crtc;
572
573         private->crtc[nr] = crtc;
574
575         drm_crtc_init(dev, crtc, &exynos_crtc_funcs);
576         drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs);
577
578         return 0;
579 }
580
581 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)
582 {
583         struct exynos_drm_private *private = dev->dev_private;
584         struct exynos_drm_crtc *exynos_crtc =
585                 to_exynos_crtc(private->crtc[crtc]);
586
587         DRM_DEBUG_KMS("%s\n", __FILE__);
588
589         if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
590                 return -EPERM;
591
592         exynos_drm_fn_encoder(private->crtc[crtc], &crtc,
593                         exynos_drm_enable_vblank);
594
595         return 0;
596 }
597
598 void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
599 {
600         struct exynos_drm_private *private = dev->dev_private;
601         struct exynos_drm_crtc *exynos_crtc =
602                 to_exynos_crtc(private->crtc[crtc]);
603
604         DRM_DEBUG_KMS("%s\n", __FILE__);
605
606         if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
607                 return;
608
609         exynos_drm_fn_encoder(private->crtc[crtc], &crtc,
610                         exynos_drm_disable_vblank);
611 }