drm/exynos: Consolidate suspend/resume
[cascardo/linux.git] / drivers / gpu / drm / exynos / exynos_drm_drv.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
3  * Authors:
4  *      Inki Dae <inki.dae@samsung.com>
5  *      Joonyoung Shim <jy0922.shim@samsung.com>
6  *      Seung-Woo Kim <sw0312.kim@samsung.com>
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27
28 #include "drmP.h"
29 #include "drm.h"
30 #include "drm_crtc_helper.h"
31
32 #include <drm/exynos_drm.h>
33
34 #include "exynos_drm_drv.h"
35 #include "exynos_drm_crtc.h"
36 #include "exynos_drm_encoder.h"
37 #include "exynos_drm_fbdev.h"
38 #include "exynos_drm_fb.h"
39 #include "exynos_drm_gem.h"
40 #include "exynos_drm_plane.h"
41 #include "exynos_drm_vidi.h"
42 #include "exynos_drm_dmabuf.h"
43 #include "exynos_drm_display.h"
44
45 #define DRIVER_NAME     "exynos"
46 #define DRIVER_DESC     "Samsung SoC DRM"
47 #define DRIVER_DATE     "20110530"
48 #define DRIVER_MAJOR    1
49 #define DRIVER_MINOR    0
50
51 #define VBLANK_OFF_DELAY        50000
52
53 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
54 {
55         struct exynos_drm_private *private;
56         int ret;
57         int nr;
58
59         DRM_DEBUG_DRIVER("%s\n", __FILE__);
60
61         private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
62         if (!private) {
63                 DRM_ERROR("failed to allocate private\n");
64                 return -ENOMEM;
65         }
66
67 #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
68         if (kds_callback_init(&private->kds_cb, 1,
69                               exynos_drm_kds_callback) < 0) {
70                 DRM_ERROR("kds alloc queue failed.\n");
71                 ret = -ENOMEM;
72                 goto err_kds;
73         }
74         if (kds_callback_init(&private->kds_cb_rm_fb, 0,
75                               exynos_drm_kds_callback_rm_fb) < 0) {
76                 DRM_ERROR("kds alloc queue failed.\n");
77                 ret = -ENOMEM;
78                 goto err_kds_rm_fb;
79         }
80 #endif
81
82         DRM_INIT_WAITQUEUE(&private->wait_vsync_queue);
83         atomic_set(&private->wait_vsync_event, 0);
84
85         dev->dev_private = (void *)private;
86
87         drm_mode_config_init(dev);
88
89         /* init kms poll for handling hpd */
90         drm_kms_helper_poll_init(dev);
91
92         exynos_drm_mode_config_init(dev);
93
94         /*
95          * EXYNOS4 is enough to have two CRTCs and each crtc would be used
96          * without dependency of hardware.
97          */
98         for (nr = 0; nr < MAX_CRTC; nr++) {
99                 ret = exynos_drm_crtc_create(dev, nr);
100                 if (ret)
101                         goto err_crtc;
102         }
103
104         for (nr = 0; nr < MAX_PLANE; nr++) {
105                 ret = exynos_plane_init(dev, nr);
106                 if (ret)
107                         goto err_crtc;
108         }
109
110         ret = drm_vblank_init(dev, MAX_CRTC);
111         if (ret)
112                 goto err_crtc;
113
114         /*
115          * probe sub drivers such as display controller and hdmi driver,
116          * that were registered at probe() of platform driver
117          * to the sub driver and create encoder and connector for them.
118          */
119         ret = exynos_drm_device_register(dev);
120         if (ret)
121                 goto err_vblank;
122
123         /* setup possible_clones. */
124         exynos_drm_encoder_setup(dev);
125
126         /*
127          * create and configure fb helper and also exynos specific
128          * fbdev object.
129          */
130         ret = exynos_drm_fbdev_init(dev);
131         if (ret) {
132                 DRM_ERROR("failed to initialize drm fbdev\n");
133                 goto err_drm_device;
134         }
135
136         drm_vblank_offdelay = VBLANK_OFF_DELAY;
137
138         return 0;
139
140 err_drm_device:
141         exynos_drm_device_unregister(dev);
142 err_vblank:
143         drm_vblank_cleanup(dev);
144 err_crtc:
145         drm_mode_config_cleanup(dev);
146 #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
147         kds_callback_term(&private->kds_cb_rm_fb);
148 err_kds_rm_fb:
149         kds_callback_term(&private->kds_cb);
150 err_kds:
151 #endif
152         kfree(private);
153
154         return ret;
155 }
156
157 static int exynos_drm_unload(struct drm_device *dev)
158 {
159         struct exynos_drm_private *private = dev->dev_private;
160
161         DRM_DEBUG_DRIVER("%s\n", __FILE__);
162
163         exynos_drm_fbdev_fini(dev);
164         exynos_drm_device_unregister(dev);
165         drm_vblank_cleanup(dev);
166         drm_kms_helper_poll_fini(dev);
167         drm_mode_config_cleanup(dev);
168 #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
169         kds_callback_term(&private->kds_cb);
170 #endif
171         kfree(private);
172
173         dev->dev_private = NULL;
174
175         return 0;
176 }
177
178 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
179 {
180         DRM_DEBUG_DRIVER("%s\n", __FILE__);
181
182         return exynos_drm_subdrv_open(dev, file);
183 }
184
185 static void exynos_drm_preclose(struct drm_device *dev,
186                                         struct drm_file *file)
187 {
188         DRM_DEBUG_DRIVER("%s\n", __FILE__);
189
190         exynos_drm_subdrv_close(dev, file);
191 }
192
193 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
194 {
195         DRM_DEBUG_DRIVER("%s\n", __FILE__);
196
197         if (!file->driver_priv)
198                 return;
199
200         kfree(file->driver_priv);
201         file->driver_priv = NULL;
202 }
203
204 static void exynos_drm_lastclose(struct drm_device *dev)
205 {
206         DRM_DEBUG_DRIVER("%s\n", __FILE__);
207
208         exynos_drm_fbdev_restore_mode(dev);
209 }
210
211 static struct vm_operations_struct exynos_drm_gem_vm_ops = {
212         .fault = exynos_drm_gem_fault,
213         .open = drm_gem_vm_open,
214         .close = drm_gem_vm_close,
215 };
216
217 static struct drm_ioctl_desc exynos_ioctls[] = {
218         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
219                         DRM_UNLOCKED | DRM_AUTH),
220         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP_OFFSET,
221                         exynos_drm_gem_map_offset_ioctl, DRM_UNLOCKED |
222                         DRM_AUTH),
223         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP,
224                         exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
225         DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
226                         DRM_UNLOCKED | DRM_AUTH),
227         DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
228                         vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),
229 };
230
231 static const struct file_operations exynos_drm_driver_fops = {
232         .owner          = THIS_MODULE,
233         .open           = drm_open,
234         .mmap           = exynos_drm_gem_mmap,
235         .poll           = drm_poll,
236         .read           = drm_read,
237         .unlocked_ioctl = drm_ioctl,
238         .release        = drm_release,
239 };
240
241 static struct drm_driver exynos_drm_driver = {
242         .driver_features        = DRIVER_HAVE_IRQ | DRIVER_BUS_PLATFORM |
243                                   DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
244         .load                   = exynos_drm_load,
245         .unload                 = exynos_drm_unload,
246         .open                   = exynos_drm_open,
247         .preclose               = exynos_drm_preclose,
248         .lastclose              = exynos_drm_lastclose,
249         .postclose              = exynos_drm_postclose,
250         .get_vblank_counter     = drm_vblank_count,
251         .enable_vblank          = exynos_drm_crtc_enable_vblank,
252         .disable_vblank         = exynos_drm_crtc_disable_vblank,
253         .gem_init_object        = exynos_drm_gem_init_object,
254         .gem_free_object        = exynos_drm_gem_free_object,
255         .gem_vm_ops             = &exynos_drm_gem_vm_ops,
256         .dumb_create            = exynos_drm_gem_dumb_create,
257         .dumb_map_offset        = exynos_drm_gem_dumb_map_offset,
258         .dumb_destroy           = exynos_drm_gem_dumb_destroy,
259         .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
260         .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
261         .gem_prime_export       = exynos_dmabuf_prime_export,
262         .gem_prime_import       = exynos_dmabuf_prime_import,
263         .ioctls                 = exynos_ioctls,
264         .fops                   = &exynos_drm_driver_fops,
265         .name   = DRIVER_NAME,
266         .desc   = DRIVER_DESC,
267         .date   = DRIVER_DATE,
268         .major  = DRIVER_MAJOR,
269         .minor  = DRIVER_MINOR,
270 };
271
272 #ifdef CONFIG_EXYNOS_IOMMU
273 static int iommu_init(struct platform_device *pdev)
274 {
275         /* DRM device expects a IOMMU mapping to be already
276          * created in FIMD. Else this function should
277          * throw an error.
278          */
279         if (exynos_drm_common_mapping==NULL) {
280                 printk(KERN_ERR "exynos drm common mapping is invalid\n");
281                 return -1;
282         }
283
284         /*
285          * The ordering in Makefile warrants that this is initialized after
286          * FIMD, so only just ensure that it works as expected and we are
287          * reusing the mapping originally created in exynos_drm_fimd.c.
288          */
289         WARN_ON(!exynos_drm_common_mapping);
290         if (!s5p_create_iommu_mapping(&pdev->dev, 0,
291                                 0, 0, exynos_drm_common_mapping)) {
292                 printk(KERN_ERR "failed to create IOMMU mapping\n");
293                 return -1;
294         }
295
296         return 0;
297 }
298
299 static void iommu_deinit(struct platform_device *pdev)
300 {
301         /* detach the device and mapping */
302         s5p_destroy_iommu_mapping(&pdev->dev);
303         DRM_DEBUG("released the IOMMU mapping\n");
304
305         return;
306 }
307 #endif
308
309 static int exynos_drm_platform_probe(struct platform_device *pdev)
310 {
311         struct device *dev = &pdev->dev;
312
313         DRM_DEBUG_DRIVER("%s\n", __FILE__);
314
315 #ifdef CONFIG_EXYNOS_IOMMU
316         if (iommu_init(pdev)) {
317                 DRM_ERROR("failed to initialize IOMMU\n");
318                 return -ENODEV;
319         }
320 #endif
321
322         exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls);
323
324         pm_runtime_enable(dev);
325         pm_runtime_get_sync(dev);
326
327         return drm_platform_init(&exynos_drm_driver, pdev);
328 }
329
330 static int __devexit exynos_drm_platform_remove(struct platform_device *pdev)
331 {
332         struct device *dev = &pdev->dev;
333
334         DRM_DEBUG_DRIVER("%s\n", __FILE__);
335
336         pm_runtime_disable(dev);
337
338         drm_platform_exit(&exynos_drm_driver, pdev);
339
340 #ifdef CONFIG_EXYNOS_IOMMU
341         iommu_deinit(pdev);
342 #endif
343         return 0;
344 }
345
346 /* TODO (seanpaul): Once we remove platform drivers, we'll be calling the
347  * various panel/controller init functions directly. These init functions will
348  * return to us the ops and context, so we can get rid of these attach
349  * functions. Once the attach functions are gone, we can move this array of
350  * display pointers into the drm device's platform data.
351  *
352  * For now, we'll use a global to keep track of things.
353  */
354 static struct exynos_drm_display *displays[EXYNOS_DRM_DISPLAY_NUM_DISPLAYS];
355
356 void exynos_display_attach_panel(enum exynos_drm_display_type type,
357                 struct exynos_panel_ops *ops, void *ctx)
358 {
359         int i;
360         for (i = 0; i < EXYNOS_DRM_DISPLAY_NUM_DISPLAYS; i++) {
361                 if (displays[i]->display_type == type) {
362                         displays[i]->panel_ctx = ctx;
363                         displays[i]->panel_ops = ops;
364                         return;
365                 }
366         }
367 }
368
369 void exynos_display_attach_controller(enum exynos_drm_display_type type,
370                 struct exynos_controller_ops *ops, void *ctx)
371 {
372         int i;
373         for (i = 0; i < EXYNOS_DRM_DISPLAY_NUM_DISPLAYS; i++) {
374                 if (displays[i]->display_type == type) {
375                         displays[i]->controller_ctx = ctx;
376                         displays[i]->controller_ops = ops;
377                         return;
378                 }
379         }
380 }
381
382 static int display_subdrv_probe(struct drm_device *drm_dev,
383                 struct exynos_drm_subdrv *subdrv)
384 {
385         struct exynos_drm_display *display = subdrv->display;
386         int ret;
387
388         if (!display->controller_ops || !display->panel_ops)
389                 return -EINVAL;
390
391         if (display->controller_ops->subdrv_probe) {
392                 ret = display->controller_ops->subdrv_probe(
393                                 display->controller_ctx, drm_dev);
394                 if (ret)
395                         return ret;
396         }
397
398         if (display->panel_ops->subdrv_probe) {
399                 ret = display->panel_ops->subdrv_probe(display->panel_ctx,
400                                 drm_dev);
401                 if (ret)
402                         return ret;
403         }
404
405         return 0;
406 }
407
408 int exynos_display_init(struct exynos_drm_display *display,
409                 enum exynos_drm_display_type type)
410 {
411         struct exynos_drm_subdrv *subdrv;
412
413         subdrv = kzalloc(sizeof(*subdrv), GFP_KERNEL);
414         if (!subdrv) {
415                 DRM_ERROR("Failed to allocate display subdrv\n");
416                 return -ENOMEM;
417         }
418
419         display->display_type = type;
420         display->pipe = -1;
421         display->subdrv = subdrv;
422
423         subdrv->probe = display_subdrv_probe;
424         subdrv->display = display;
425         exynos_drm_subdrv_register(subdrv);
426
427         return 0;
428 }
429
430 void exynos_display_remove(struct exynos_drm_display *display)
431 {
432         if (display->subdrv) {
433                 exynos_drm_subdrv_unregister(display->subdrv);
434                 kfree(display->subdrv);
435         }
436 }
437
438 static int exynos_drm_resume_displays(void)
439 {
440         int i;
441
442         for (i = 0; i < EXYNOS_DRM_DISPLAY_NUM_DISPLAYS; i++) {
443                 struct exynos_drm_display *display = displays[i];
444                 struct drm_encoder *encoder = display->subdrv->encoder;
445
446                 if (!encoder)
447                         continue;
448
449                 exynos_drm_encoder_dpms(encoder, display->suspend_dpms);
450         }
451         return 0;
452 }
453
454 static int exynos_drm_suspend_displays(void)
455 {
456         int i;
457
458         for (i = 0; i < EXYNOS_DRM_DISPLAY_NUM_DISPLAYS; i++) {
459                 struct exynos_drm_display *display = displays[i];
460                 struct drm_encoder *encoder = display->subdrv->encoder;
461
462                 if (!encoder)
463                         continue;
464
465                 display->suspend_dpms = exynos_drm_encoder_get_dpms(encoder);
466                 exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
467         }
468         return 0;
469 }
470
471 #ifdef CONFIG_PM_SLEEP
472 static int exynos_drm_suspend(struct device *dev)
473 {
474         if (pm_runtime_suspended(dev))
475                 return 0;
476
477         return exynos_drm_suspend_displays();
478 }
479
480 static int exynos_drm_resume(struct device *dev)
481 {
482         if (pm_runtime_suspended(dev))
483                 return 0;
484
485         return exynos_drm_resume_displays();
486 }
487 #endif
488
489 #ifdef CONFIG_PM_RUNTIME
490 static int exynos_drm_runtime_resume(struct device *dev)
491 {
492         return exynos_drm_resume_displays();
493 }
494
495 static int exynos_drm_runtime_suspend(struct device *dev)
496 {
497         return exynos_drm_suspend_displays();
498 }
499 #endif
500
501 static const struct dev_pm_ops drm_pm_ops = {
502         SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_suspend, exynos_drm_resume)
503         SET_RUNTIME_PM_OPS(exynos_drm_runtime_suspend,
504                         exynos_drm_runtime_resume, NULL)
505 };
506
507 static struct platform_driver exynos_drm_platform_driver = {
508         .probe          = exynos_drm_platform_probe,
509         .remove         = __devexit_p(exynos_drm_platform_remove),
510         .driver         = {
511                 .owner  = THIS_MODULE,
512                 .name   = "exynos-drm",
513                 .pm     = &drm_pm_ops,
514         },
515 };
516
517 static int __init exynos_drm_init(void)
518 {
519         int ret, i;
520
521         DRM_DEBUG_DRIVER("%s\n", __FILE__);
522
523         for (i = 0; i < EXYNOS_DRM_DISPLAY_NUM_DISPLAYS; i++) {
524                 displays[i] = kzalloc(sizeof(*displays[i]), GFP_KERNEL);
525                 if (!displays[i]) {
526                         ret = -ENOMEM;
527                         goto out_display;
528                 }
529
530                 ret = exynos_display_init(displays[i], i);
531                 if (ret)
532                         goto out_display;
533         }
534
535 #ifdef CONFIG_DRM_EXYNOS_FIMD
536         ret = platform_driver_register(&fimd_driver);
537         if (ret < 0)
538                 goto out_fimd;
539 #endif
540
541 #ifdef CONFIG_DRM_EXYNOS_DP
542         ret = platform_driver_register(&dp_driver);
543         if (ret < 0)
544                 goto out_dp_driver;
545 #endif
546
547 #ifdef CONFIG_DRM_EXYNOS_HDMI
548         ret = platform_driver_register(&hdmi_driver);
549         if (ret < 0)
550                 goto out_hdmi;
551         ret = platform_driver_register(&mixer_driver);
552         if (ret < 0)
553                 goto out_mixer;
554 #endif
555
556 #ifdef CONFIG_DRM_EXYNOS_VIDI
557         ret = platform_driver_register(&vidi_driver);
558         if (ret < 0)
559                 goto out_vidi;
560 #endif
561
562         ret = platform_driver_register(&exynos_drm_platform_driver);
563         if (ret < 0)
564                 goto out;
565
566         return 0;
567
568 out:
569 #ifdef CONFIG_DRM_EXYNOS_VIDI
570 out_vidi:
571         platform_driver_unregister(&vidi_driver);
572 #endif
573
574 #ifdef CONFIG_DRM_EXYNOS_HDMI
575         platform_driver_unregister(&mixer_driver);
576 out_mixer:
577         platform_driver_unregister(&hdmi_driver);
578 out_hdmi:
579 #endif
580
581         platform_driver_unregister(&dp_driver);
582 out_dp_driver:
583 #ifdef CONFIG_DRM_EXYNOS_FIMD
584         platform_driver_unregister(&fimd_driver);
585 out_fimd:
586 #endif
587 out_display:
588         for (i = 0; i < EXYNOS_DRM_DISPLAY_NUM_DISPLAYS; i++) {
589                 if (!displays[i])
590                         continue;
591
592                 exynos_display_remove(displays[i]);
593                 kfree(displays[i]);
594         }
595         return ret;
596 }
597
598 static void __exit exynos_drm_exit(void)
599 {
600         int i;
601
602         DRM_DEBUG_DRIVER("%s\n", __FILE__);
603
604         platform_driver_unregister(&exynos_drm_platform_driver);
605
606 #ifdef CONFIG_DRM_EXYNOS_HDMI
607         platform_driver_unregister(&mixer_driver);
608         platform_driver_unregister(&hdmi_driver);
609 #endif
610
611 #ifdef CONFIG_DRM_EXYNOS_VIDI
612         platform_driver_unregister(&vidi_driver);
613 #endif
614
615         platform_driver_unregister(&dp_driver);
616 #ifdef CONFIG_DRM_EXYNOS_FIMD
617         platform_driver_unregister(&fimd_driver);
618 #endif
619
620         for (i = 0; i < EXYNOS_DRM_DISPLAY_NUM_DISPLAYS; i++) {
621                 if (!displays[i])
622                         continue;
623
624                 exynos_display_remove(displays[i]);
625                 kfree(displays[i]);
626         }
627 }
628
629 module_init(exynos_drm_init);
630 module_exit(exynos_drm_exit);
631
632 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
633 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
634 MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
635 MODULE_DESCRIPTION("Samsung SoC DRM Driver");
636 MODULE_LICENSE("GPL");