Version:  2.0.40 2.2.26 2.4.37 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2

Linux/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  * This program is free software; you can redistribute  it and/or modify it
  9  * under  the terms of  the GNU General  Public License as published by the
 10  * Free Software Foundation;  either version 2 of the  License, or (at your
 11  * option) any later version.
 12  */
 13 
 14 #include <linux/pm_runtime.h>
 15 #include <drm/drmP.h>
 16 #include <drm/drm_crtc_helper.h>
 17 
 18 #include <linux/component.h>
 19 
 20 #include <drm/exynos_drm.h>
 21 
 22 #include "exynos_drm_drv.h"
 23 #include "exynos_drm_crtc.h"
 24 #include "exynos_drm_encoder.h"
 25 #include "exynos_drm_fbdev.h"
 26 #include "exynos_drm_fb.h"
 27 #include "exynos_drm_gem.h"
 28 #include "exynos_drm_plane.h"
 29 #include "exynos_drm_vidi.h"
 30 #include "exynos_drm_dmabuf.h"
 31 #include "exynos_drm_g2d.h"
 32 #include "exynos_drm_ipp.h"
 33 #include "exynos_drm_iommu.h"
 34 
 35 #define DRIVER_NAME     "exynos"
 36 #define DRIVER_DESC     "Samsung SoC DRM"
 37 #define DRIVER_DATE     "20110530"
 38 #define DRIVER_MAJOR    1
 39 #define DRIVER_MINOR    0
 40 
 41 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 42 {
 43         struct exynos_drm_private *private;
 44         int ret;
 45 
 46         private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
 47         if (!private)
 48                 return -ENOMEM;
 49 
 50         dev_set_drvdata(dev->dev, dev);
 51         dev->dev_private = (void *)private;
 52 
 53         /*
 54          * create mapping to manage iommu table and set a pointer to iommu
 55          * mapping structure to iommu_mapping of private data.
 56          * also this iommu_mapping can be used to check if iommu is supported
 57          * or not.
 58          */
 59         ret = drm_create_iommu_mapping(dev);
 60         if (ret < 0) {
 61                 DRM_ERROR("failed to create iommu mapping.\n");
 62                 goto err_free_private;
 63         }
 64 
 65         drm_mode_config_init(dev);
 66 
 67         exynos_drm_mode_config_init(dev);
 68 
 69         /* setup possible_clones. */
 70         exynos_drm_encoder_setup(dev);
 71 
 72         platform_set_drvdata(dev->platformdev, dev);
 73 
 74         /* Try to bind all sub drivers. */
 75         ret = component_bind_all(dev->dev, dev);
 76         if (ret)
 77                 goto err_mode_config_cleanup;
 78 
 79         ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 80         if (ret)
 81                 goto err_unbind_all;
 82 
 83         /* Probe non kms sub drivers and virtual display driver. */
 84         ret = exynos_drm_device_subdrv_probe(dev);
 85         if (ret)
 86                 goto err_cleanup_vblank;
 87 
 88         drm_mode_config_reset(dev);
 89 
 90         /*
 91          * enable drm irq mode.
 92          * - with irq_enabled = true, we can use the vblank feature.
 93          *
 94          * P.S. note that we wouldn't use drm irq handler but
 95          *      just specific driver own one instead because
 96          *      drm framework supports only one irq handler.
 97          */
 98         dev->irq_enabled = true;
 99 
100         /*
101          * with vblank_disable_allowed = true, vblank interrupt will be disabled
102          * by drm timer once a current process gives up ownership of
103          * vblank event.(after drm_vblank_put function is called)
104          */
105         dev->vblank_disable_allowed = true;
106 
107         /* init kms poll for handling hpd */
108         drm_kms_helper_poll_init(dev);
109 
110         /* force connectors detection */
111         drm_helper_hpd_irq_event(dev);
112 
113         return 0;
114 
115 err_cleanup_vblank:
116         drm_vblank_cleanup(dev);
117 err_unbind_all:
118         component_unbind_all(dev->dev, dev);
119 err_mode_config_cleanup:
120         drm_mode_config_cleanup(dev);
121         drm_release_iommu_mapping(dev);
122 err_free_private:
123         kfree(private);
124 
125         return ret;
126 }
127 
128 static int exynos_drm_unload(struct drm_device *dev)
129 {
130         exynos_drm_device_subdrv_remove(dev);
131 
132         exynos_drm_fbdev_fini(dev);
133         drm_kms_helper_poll_fini(dev);
134 
135         drm_vblank_cleanup(dev);
136         component_unbind_all(dev->dev, dev);
137         drm_mode_config_cleanup(dev);
138         drm_release_iommu_mapping(dev);
139 
140         kfree(dev->dev_private);
141         dev->dev_private = NULL;
142 
143         return 0;
144 }
145 
146 static int exynos_drm_suspend(struct drm_device *dev, pm_message_t state)
147 {
148         struct drm_connector *connector;
149 
150         drm_modeset_lock_all(dev);
151         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
152                 int old_dpms = connector->dpms;
153 
154                 if (connector->funcs->dpms)
155                         connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF);
156 
157                 /* Set the old mode back to the connector for resume */
158                 connector->dpms = old_dpms;
159         }
160         drm_modeset_unlock_all(dev);
161 
162         return 0;
163 }
164 
165 static int exynos_drm_resume(struct drm_device *dev)
166 {
167         struct drm_connector *connector;
168 
169         drm_modeset_lock_all(dev);
170         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
171                 if (connector->funcs->dpms) {
172                         int dpms = connector->dpms;
173 
174                         connector->dpms = DRM_MODE_DPMS_OFF;
175                         connector->funcs->dpms(connector, dpms);
176                 }
177         }
178         drm_modeset_unlock_all(dev);
179 
180         return 0;
181 }
182 
183 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
184 {
185         struct drm_exynos_file_private *file_priv;
186         int ret;
187 
188         file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
189         if (!file_priv)
190                 return -ENOMEM;
191 
192         file->driver_priv = file_priv;
193 
194         ret = exynos_drm_subdrv_open(dev, file);
195         if (ret)
196                 goto err_file_priv_free;
197 
198         return ret;
199 
200 err_file_priv_free:
201         kfree(file_priv);
202         file->driver_priv = NULL;
203         return ret;
204 }
205 
206 static void exynos_drm_preclose(struct drm_device *dev,
207                                         struct drm_file *file)
208 {
209         exynos_drm_subdrv_close(dev, file);
210 }
211 
212 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
213 {
214         struct drm_pending_event *e, *et;
215         unsigned long flags;
216 
217         if (!file->driver_priv)
218                 return;
219 
220         spin_lock_irqsave(&dev->event_lock, flags);
221         /* Release all events handled by page flip handler but not freed. */
222         list_for_each_entry_safe(e, et, &file->event_list, link) {
223                 list_del(&e->link);
224                 e->destroy(e);
225         }
226         spin_unlock_irqrestore(&dev->event_lock, flags);
227 
228         kfree(file->driver_priv);
229         file->driver_priv = NULL;
230 }
231 
232 static void exynos_drm_lastclose(struct drm_device *dev)
233 {
234         exynos_drm_fbdev_restore_mode(dev);
235 }
236 
237 static const struct vm_operations_struct exynos_drm_gem_vm_ops = {
238         .fault = exynos_drm_gem_fault,
239         .open = drm_gem_vm_open,
240         .close = drm_gem_vm_close,
241 };
242 
243 static const struct drm_ioctl_desc exynos_ioctls[] = {
244         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
245                         DRM_UNLOCKED | DRM_AUTH),
246         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET,
247                         exynos_drm_gem_get_ioctl, DRM_UNLOCKED),
248         DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
249                         vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),
250         DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
251                         exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
252         DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST,
253                         exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH),
254         DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC,
255                         exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH),
256         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_PROPERTY,
257                         exynos_drm_ipp_get_property, DRM_UNLOCKED | DRM_AUTH),
258         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_SET_PROPERTY,
259                         exynos_drm_ipp_set_property, DRM_UNLOCKED | DRM_AUTH),
260         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_QUEUE_BUF,
261                         exynos_drm_ipp_queue_buf, DRM_UNLOCKED | DRM_AUTH),
262         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_CMD_CTRL,
263                         exynos_drm_ipp_cmd_ctrl, DRM_UNLOCKED | DRM_AUTH),
264 };
265 
266 static const struct file_operations exynos_drm_driver_fops = {
267         .owner          = THIS_MODULE,
268         .open           = drm_open,
269         .mmap           = exynos_drm_gem_mmap,
270         .poll           = drm_poll,
271         .read           = drm_read,
272         .unlocked_ioctl = drm_ioctl,
273 #ifdef CONFIG_COMPAT
274         .compat_ioctl = drm_compat_ioctl,
275 #endif
276         .release        = drm_release,
277 };
278 
279 static struct drm_driver exynos_drm_driver = {
280         .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
281         .load                   = exynos_drm_load,
282         .unload                 = exynos_drm_unload,
283         .suspend                = exynos_drm_suspend,
284         .resume                 = exynos_drm_resume,
285         .open                   = exynos_drm_open,
286         .preclose               = exynos_drm_preclose,
287         .lastclose              = exynos_drm_lastclose,
288         .postclose              = exynos_drm_postclose,
289         .set_busid              = drm_platform_set_busid,
290         .get_vblank_counter     = drm_vblank_count,
291         .enable_vblank          = exynos_drm_crtc_enable_vblank,
292         .disable_vblank         = exynos_drm_crtc_disable_vblank,
293         .gem_free_object        = exynos_drm_gem_free_object,
294         .gem_vm_ops             = &exynos_drm_gem_vm_ops,
295         .dumb_create            = exynos_drm_gem_dumb_create,
296         .dumb_map_offset        = exynos_drm_gem_dumb_map_offset,
297         .dumb_destroy           = drm_gem_dumb_destroy,
298         .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
299         .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
300         .gem_prime_export       = exynos_dmabuf_prime_export,
301         .gem_prime_import       = exynos_dmabuf_prime_import,
302         .ioctls                 = exynos_ioctls,
303         .num_ioctls             = ARRAY_SIZE(exynos_ioctls),
304         .fops                   = &exynos_drm_driver_fops,
305         .name   = DRIVER_NAME,
306         .desc   = DRIVER_DESC,
307         .date   = DRIVER_DATE,
308         .major  = DRIVER_MAJOR,
309         .minor  = DRIVER_MINOR,
310 };
311 
312 #ifdef CONFIG_PM_SLEEP
313 static int exynos_drm_sys_suspend(struct device *dev)
314 {
315         struct drm_device *drm_dev = dev_get_drvdata(dev);
316         pm_message_t message;
317 
318         if (pm_runtime_suspended(dev) || !drm_dev)
319                 return 0;
320 
321         message.event = PM_EVENT_SUSPEND;
322         return exynos_drm_suspend(drm_dev, message);
323 }
324 
325 static int exynos_drm_sys_resume(struct device *dev)
326 {
327         struct drm_device *drm_dev = dev_get_drvdata(dev);
328 
329         if (pm_runtime_suspended(dev) || !drm_dev)
330                 return 0;
331 
332         return exynos_drm_resume(drm_dev);
333 }
334 #endif
335 
336 static const struct dev_pm_ops exynos_drm_pm_ops = {
337         SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume)
338 };
339 
340 /* forward declaration */
341 static struct platform_driver exynos_drm_platform_driver;
342 
343 /*
344  * Connector drivers should not be placed before associated crtc drivers,
345  * because connector requires pipe number of its crtc during initialization.
346  */
347 static struct platform_driver *const exynos_drm_kms_drivers[] = {
348 #ifdef CONFIG_DRM_EXYNOS_VIDI
349         &vidi_driver,
350 #endif
351 #ifdef CONFIG_DRM_EXYNOS_FIMD
352         &fimd_driver,
353 #endif
354 #ifdef CONFIG_DRM_EXYNOS5433_DECON
355         &exynos5433_decon_driver,
356 #endif
357 #ifdef CONFIG_DRM_EXYNOS7_DECON
358         &decon_driver,
359 #endif
360 #ifdef CONFIG_DRM_EXYNOS_MIC
361         &mic_driver,
362 #endif
363 #ifdef CONFIG_DRM_EXYNOS_DP
364         &dp_driver,
365 #endif
366 #ifdef CONFIG_DRM_EXYNOS_DSI
367         &dsi_driver,
368 #endif
369 #ifdef CONFIG_DRM_EXYNOS_HDMI
370         &mixer_driver,
371         &hdmi_driver,
372 #endif
373 };
374 
375 static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
376 #ifdef CONFIG_DRM_EXYNOS_G2D
377         &g2d_driver,
378 #endif
379 #ifdef CONFIG_DRM_EXYNOS_FIMC
380         &fimc_driver,
381 #endif
382 #ifdef CONFIG_DRM_EXYNOS_ROTATOR
383         &rotator_driver,
384 #endif
385 #ifdef CONFIG_DRM_EXYNOS_GSC
386         &gsc_driver,
387 #endif
388 #ifdef CONFIG_DRM_EXYNOS_IPP
389         &ipp_driver,
390 #endif
391         &exynos_drm_platform_driver,
392 };
393 
394 static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
395 #ifdef CONFIG_DRM_EXYNOS_VIDI
396         &vidi_driver,
397 #endif
398 #ifdef CONFIG_DRM_EXYNOS_IPP
399         &ipp_driver,
400 #endif
401         &exynos_drm_platform_driver,
402 };
403 #define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
404 
405 static int compare_dev(struct device *dev, void *data)
406 {
407         return dev == (struct device *)data;
408 }
409 
410 static struct component_match *exynos_drm_match_add(struct device *dev)
411 {
412         struct component_match *match = NULL;
413         int i;
414 
415         for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
416                 struct device_driver *drv = &exynos_drm_kms_drivers[i]->driver;
417                 struct device *p = NULL, *d;
418 
419                 while ((d = bus_find_device(&platform_bus_type, p, drv,
420                                             (void *)platform_bus_type.match))) {
421                         put_device(p);
422                         component_match_add(dev, &match, compare_dev, d);
423                         p = d;
424                 }
425                 put_device(p);
426         }
427 
428         return match ?: ERR_PTR(-ENODEV);
429 }
430 
431 static int exynos_drm_bind(struct device *dev)
432 {
433         return drm_platform_init(&exynos_drm_driver, to_platform_device(dev));
434 }
435 
436 static void exynos_drm_unbind(struct device *dev)
437 {
438         drm_put_dev(dev_get_drvdata(dev));
439 }
440 
441 static const struct component_master_ops exynos_drm_ops = {
442         .bind           = exynos_drm_bind,
443         .unbind         = exynos_drm_unbind,
444 };
445 
446 static int exynos_drm_platform_probe(struct platform_device *pdev)
447 {
448         struct component_match *match;
449 
450         pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
451         exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
452 
453         match = exynos_drm_match_add(&pdev->dev);
454         if (IS_ERR(match))
455                 return PTR_ERR(match);
456 
457         return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
458                                                match);
459 }
460 
461 static int exynos_drm_platform_remove(struct platform_device *pdev)
462 {
463         component_master_del(&pdev->dev, &exynos_drm_ops);
464         return 0;
465 }
466 
467 static struct platform_driver exynos_drm_platform_driver = {
468         .probe  = exynos_drm_platform_probe,
469         .remove = exynos_drm_platform_remove,
470         .driver = {
471                 .name   = "exynos-drm",
472                 .pm     = &exynos_drm_pm_ops,
473         },
474 };
475 
476 static struct platform_device *exynos_drm_pdevs[PDEV_COUNT];
477 
478 static void exynos_drm_unregister_devices(void)
479 {
480         int i = PDEV_COUNT;
481 
482         while (--i >= 0) {
483                 platform_device_unregister(exynos_drm_pdevs[i]);
484                 exynos_drm_pdevs[i] = NULL;
485         }
486 }
487 
488 static int exynos_drm_register_devices(void)
489 {
490         int i;
491 
492         for (i = 0; i < PDEV_COUNT; ++i) {
493                 struct platform_driver *d = exynos_drm_drv_with_simple_dev[i];
494                 struct platform_device *pdev =
495                         platform_device_register_simple(d->driver.name, -1,
496                                                         NULL, 0);
497 
498                 if (!IS_ERR(pdev)) {
499                         exynos_drm_pdevs[i] = pdev;
500                         continue;
501                 }
502                 while (--i >= 0) {
503                         platform_device_unregister(exynos_drm_pdevs[i]);
504                         exynos_drm_pdevs[i] = NULL;
505                 }
506 
507                 return PTR_ERR(pdev);
508         }
509 
510         return 0;
511 }
512 
513 static void exynos_drm_unregister_drivers(struct platform_driver * const *drv,
514                                           int count)
515 {
516         while (--count >= 0)
517                 platform_driver_unregister(drv[count]);
518 }
519 
520 static int exynos_drm_register_drivers(struct platform_driver * const *drv,
521                                        int count)
522 {
523         int i, ret;
524 
525         for (i = 0; i < count; ++i) {
526                 ret = platform_driver_register(drv[i]);
527                 if (!ret)
528                         continue;
529 
530                 while (--i >= 0)
531                         platform_driver_unregister(drv[i]);
532 
533                 return ret;
534         }
535 
536         return 0;
537 }
538 
539 static inline int exynos_drm_register_kms_drivers(void)
540 {
541         return exynos_drm_register_drivers(exynos_drm_kms_drivers,
542                                         ARRAY_SIZE(exynos_drm_kms_drivers));
543 }
544 
545 static inline int exynos_drm_register_non_kms_drivers(void)
546 {
547         return exynos_drm_register_drivers(exynos_drm_non_kms_drivers,
548                                         ARRAY_SIZE(exynos_drm_non_kms_drivers));
549 }
550 
551 static inline void exynos_drm_unregister_kms_drivers(void)
552 {
553         exynos_drm_unregister_drivers(exynos_drm_kms_drivers,
554                                         ARRAY_SIZE(exynos_drm_kms_drivers));
555 }
556 
557 static inline void exynos_drm_unregister_non_kms_drivers(void)
558 {
559         exynos_drm_unregister_drivers(exynos_drm_non_kms_drivers,
560                                         ARRAY_SIZE(exynos_drm_non_kms_drivers));
561 }
562 
563 static int exynos_drm_init(void)
564 {
565         int ret;
566 
567         ret = exynos_drm_register_devices();
568         if (ret)
569                 return ret;
570 
571         ret = exynos_drm_register_kms_drivers();
572         if (ret)
573                 goto err_unregister_pdevs;
574 
575         ret = exynos_drm_register_non_kms_drivers();
576         if (ret)
577                 goto err_unregister_kms_drivers;
578 
579         return 0;
580 
581 err_unregister_kms_drivers:
582         exynos_drm_unregister_kms_drivers();
583 
584 err_unregister_pdevs:
585         exynos_drm_unregister_devices();
586 
587         return ret;
588 }
589 
590 static void exynos_drm_exit(void)
591 {
592         exynos_drm_unregister_non_kms_drivers();
593         exynos_drm_unregister_kms_drivers();
594         exynos_drm_unregister_devices();
595 }
596 
597 module_init(exynos_drm_init);
598 module_exit(exynos_drm_exit);
599 
600 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
601 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
602 MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
603 MODULE_DESCRIPTION("Samsung SoC DRM Driver");
604 MODULE_LICENSE("GPL");
605 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us