• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 struct platform_device *exynos_drm_pdev;
42 
43 static DEFINE_MUTEX(drm_component_lock);
44 static LIST_HEAD(drm_component_list);
45 
46 struct component_dev {
47 	struct list_head list;
48 	struct device *crtc_dev;
49 	struct device *conn_dev;
50 	enum exynos_drm_output_type out_type;
51 	unsigned int dev_type_flag;
52 };
53 
exynos_drm_load(struct drm_device * dev,unsigned long flags)54 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
55 {
56 	struct exynos_drm_private *private;
57 	int ret;
58 	int nr;
59 
60 	private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
61 	if (!private)
62 		return -ENOMEM;
63 
64 	INIT_LIST_HEAD(&private->pageflip_event_list);
65 	dev_set_drvdata(dev->dev, dev);
66 	dev->dev_private = (void *)private;
67 
68 	/*
69 	 * create mapping to manage iommu table and set a pointer to iommu
70 	 * mapping structure to iommu_mapping of private data.
71 	 * also this iommu_mapping can be used to check if iommu is supported
72 	 * or not.
73 	 */
74 	ret = drm_create_iommu_mapping(dev);
75 	if (ret < 0) {
76 		DRM_ERROR("failed to create iommu mapping.\n");
77 		goto err_free_private;
78 	}
79 
80 	drm_mode_config_init(dev);
81 
82 	exynos_drm_mode_config_init(dev);
83 
84 	for (nr = 0; nr < MAX_PLANE; nr++) {
85 		struct drm_plane *plane;
86 		unsigned long possible_crtcs = (1 << MAX_CRTC) - 1;
87 
88 		plane = exynos_plane_init(dev, possible_crtcs,
89 					  DRM_PLANE_TYPE_OVERLAY);
90 		if (!IS_ERR(plane))
91 			continue;
92 
93 		ret = PTR_ERR(plane);
94 		goto err_mode_config_cleanup;
95 	}
96 
97 	/* setup possible_clones. */
98 	exynos_drm_encoder_setup(dev);
99 
100 	platform_set_drvdata(dev->platformdev, dev);
101 
102 	/* Try to bind all sub drivers. */
103 	ret = component_bind_all(dev->dev, dev);
104 	if (ret)
105 		goto err_mode_config_cleanup;
106 
107 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
108 	if (ret)
109 		goto err_unbind_all;
110 
111 	/* Probe non kms sub drivers and virtual display driver. */
112 	ret = exynos_drm_device_subdrv_probe(dev);
113 	if (ret)
114 		goto err_cleanup_vblank;
115 
116 	/*
117 	 * enable drm irq mode.
118 	 * - with irq_enabled = true, we can use the vblank feature.
119 	 *
120 	 * P.S. note that we wouldn't use drm irq handler but
121 	 *	just specific driver own one instead because
122 	 *	drm framework supports only one irq handler.
123 	 */
124 	dev->irq_enabled = true;
125 
126 	/*
127 	 * with vblank_disable_allowed = true, vblank interrupt will be disabled
128 	 * by drm timer once a current process gives up ownership of
129 	 * vblank event.(after drm_vblank_put function is called)
130 	 */
131 	dev->vblank_disable_allowed = true;
132 
133 	/* init kms poll for handling hpd */
134 	drm_kms_helper_poll_init(dev);
135 
136 	/* force connectors detection */
137 	drm_helper_hpd_irq_event(dev);
138 
139 	return 0;
140 
141 err_cleanup_vblank:
142 	drm_vblank_cleanup(dev);
143 err_unbind_all:
144 	component_unbind_all(dev->dev, dev);
145 err_mode_config_cleanup:
146 	drm_mode_config_cleanup(dev);
147 	drm_release_iommu_mapping(dev);
148 err_free_private:
149 	kfree(private);
150 
151 	return ret;
152 }
153 
exynos_drm_unload(struct drm_device * dev)154 static int exynos_drm_unload(struct drm_device *dev)
155 {
156 	exynos_drm_device_subdrv_remove(dev);
157 
158 	exynos_drm_fbdev_fini(dev);
159 	drm_kms_helper_poll_fini(dev);
160 
161 	drm_vblank_cleanup(dev);
162 	component_unbind_all(dev->dev, dev);
163 	drm_mode_config_cleanup(dev);
164 	drm_release_iommu_mapping(dev);
165 
166 	kfree(dev->dev_private);
167 	dev->dev_private = NULL;
168 
169 	return 0;
170 }
171 
exynos_drm_suspend(struct drm_device * dev,pm_message_t state)172 static int exynos_drm_suspend(struct drm_device *dev, pm_message_t state)
173 {
174 	struct drm_connector *connector;
175 
176 	drm_modeset_lock_all(dev);
177 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
178 		int old_dpms = connector->dpms;
179 
180 		if (connector->funcs->dpms)
181 			connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF);
182 
183 		/* Set the old mode back to the connector for resume */
184 		connector->dpms = old_dpms;
185 	}
186 	drm_modeset_unlock_all(dev);
187 
188 	return 0;
189 }
190 
exynos_drm_resume(struct drm_device * dev)191 static int exynos_drm_resume(struct drm_device *dev)
192 {
193 	struct drm_connector *connector;
194 
195 	drm_modeset_lock_all(dev);
196 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
197 		if (connector->funcs->dpms) {
198 			int dpms = connector->dpms;
199 
200 			connector->dpms = DRM_MODE_DPMS_OFF;
201 			connector->funcs->dpms(connector, dpms);
202 		}
203 	}
204 	drm_modeset_unlock_all(dev);
205 
206 	drm_helper_resume_force_mode(dev);
207 
208 	return 0;
209 }
210 
exynos_drm_open(struct drm_device * dev,struct drm_file * file)211 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
212 {
213 	struct drm_exynos_file_private *file_priv;
214 	int ret;
215 
216 	file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
217 	if (!file_priv)
218 		return -ENOMEM;
219 
220 	file->driver_priv = file_priv;
221 
222 	ret = exynos_drm_subdrv_open(dev, file);
223 	if (ret)
224 		goto err_file_priv_free;
225 
226 	return ret;
227 
228 err_file_priv_free:
229 	kfree(file_priv);
230 	file->driver_priv = NULL;
231 	return ret;
232 }
233 
exynos_drm_preclose(struct drm_device * dev,struct drm_file * file)234 static void exynos_drm_preclose(struct drm_device *dev,
235 					struct drm_file *file)
236 {
237 	exynos_drm_subdrv_close(dev, file);
238 }
239 
exynos_drm_postclose(struct drm_device * dev,struct drm_file * file)240 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
241 {
242 	struct exynos_drm_private *private = dev->dev_private;
243 	struct drm_pending_vblank_event *v, *vt;
244 	struct drm_pending_event *e, *et;
245 	unsigned long flags;
246 
247 	if (!file->driver_priv)
248 		return;
249 
250 	/* Release all events not unhandled by page flip handler. */
251 	spin_lock_irqsave(&dev->event_lock, flags);
252 	list_for_each_entry_safe(v, vt, &private->pageflip_event_list,
253 			base.link) {
254 		if (v->base.file_priv == file) {
255 			list_del(&v->base.link);
256 			drm_vblank_put(dev, v->pipe);
257 			v->base.destroy(&v->base);
258 		}
259 	}
260 
261 	/* Release all events handled by page flip handler but not freed. */
262 	list_for_each_entry_safe(e, et, &file->event_list, link) {
263 		list_del(&e->link);
264 		e->destroy(e);
265 	}
266 	spin_unlock_irqrestore(&dev->event_lock, flags);
267 
268 	kfree(file->driver_priv);
269 	file->driver_priv = NULL;
270 }
271 
exynos_drm_lastclose(struct drm_device * dev)272 static void exynos_drm_lastclose(struct drm_device *dev)
273 {
274 	exynos_drm_fbdev_restore_mode(dev);
275 }
276 
277 static const struct vm_operations_struct exynos_drm_gem_vm_ops = {
278 	.fault = exynos_drm_gem_fault,
279 	.open = drm_gem_vm_open,
280 	.close = drm_gem_vm_close,
281 };
282 
283 static const struct drm_ioctl_desc exynos_ioctls[] = {
284 	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
285 			DRM_UNLOCKED | DRM_AUTH),
286 	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET,
287 			exynos_drm_gem_get_ioctl, DRM_UNLOCKED),
288 	DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
289 			vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),
290 	DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
291 			exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
292 	DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST,
293 			exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH),
294 	DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC,
295 			exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH),
296 	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_PROPERTY,
297 			exynos_drm_ipp_get_property, DRM_UNLOCKED | DRM_AUTH),
298 	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_SET_PROPERTY,
299 			exynos_drm_ipp_set_property, DRM_UNLOCKED | DRM_AUTH),
300 	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_QUEUE_BUF,
301 			exynos_drm_ipp_queue_buf, DRM_UNLOCKED | DRM_AUTH),
302 	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_CMD_CTRL,
303 			exynos_drm_ipp_cmd_ctrl, DRM_UNLOCKED | DRM_AUTH),
304 };
305 
306 static const struct file_operations exynos_drm_driver_fops = {
307 	.owner		= THIS_MODULE,
308 	.open		= drm_open,
309 	.mmap		= exynos_drm_gem_mmap,
310 	.poll		= drm_poll,
311 	.read		= drm_read,
312 	.unlocked_ioctl	= drm_ioctl,
313 #ifdef CONFIG_COMPAT
314 	.compat_ioctl = drm_compat_ioctl,
315 #endif
316 	.release	= drm_release,
317 };
318 
319 static struct drm_driver exynos_drm_driver = {
320 	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
321 	.load			= exynos_drm_load,
322 	.unload			= exynos_drm_unload,
323 	.suspend		= exynos_drm_suspend,
324 	.resume			= exynos_drm_resume,
325 	.open			= exynos_drm_open,
326 	.preclose		= exynos_drm_preclose,
327 	.lastclose		= exynos_drm_lastclose,
328 	.postclose		= exynos_drm_postclose,
329 	.set_busid		= drm_platform_set_busid,
330 	.get_vblank_counter	= drm_vblank_count,
331 	.enable_vblank		= exynos_drm_crtc_enable_vblank,
332 	.disable_vblank		= exynos_drm_crtc_disable_vblank,
333 	.gem_free_object	= exynos_drm_gem_free_object,
334 	.gem_vm_ops		= &exynos_drm_gem_vm_ops,
335 	.dumb_create		= exynos_drm_gem_dumb_create,
336 	.dumb_map_offset	= exynos_drm_gem_dumb_map_offset,
337 	.dumb_destroy		= drm_gem_dumb_destroy,
338 	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
339 	.prime_fd_to_handle	= drm_gem_prime_fd_to_handle,
340 	.gem_prime_export	= exynos_dmabuf_prime_export,
341 	.gem_prime_import	= exynos_dmabuf_prime_import,
342 	.ioctls			= exynos_ioctls,
343 	.num_ioctls		= ARRAY_SIZE(exynos_ioctls),
344 	.fops			= &exynos_drm_driver_fops,
345 	.name	= DRIVER_NAME,
346 	.desc	= DRIVER_DESC,
347 	.date	= DRIVER_DATE,
348 	.major	= DRIVER_MAJOR,
349 	.minor	= DRIVER_MINOR,
350 };
351 
352 #ifdef CONFIG_PM_SLEEP
exynos_drm_sys_suspend(struct device * dev)353 static int exynos_drm_sys_suspend(struct device *dev)
354 {
355 	struct drm_device *drm_dev = dev_get_drvdata(dev);
356 	pm_message_t message;
357 
358 	if (pm_runtime_suspended(dev) || !drm_dev)
359 		return 0;
360 
361 	message.event = PM_EVENT_SUSPEND;
362 	return exynos_drm_suspend(drm_dev, message);
363 }
364 
exynos_drm_sys_resume(struct device * dev)365 static int exynos_drm_sys_resume(struct device *dev)
366 {
367 	struct drm_device *drm_dev = dev_get_drvdata(dev);
368 
369 	if (pm_runtime_suspended(dev) || !drm_dev)
370 		return 0;
371 
372 	return exynos_drm_resume(drm_dev);
373 }
374 #endif
375 
376 static const struct dev_pm_ops exynos_drm_pm_ops = {
377 	SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume)
378 };
379 
exynos_drm_component_add(struct device * dev,enum exynos_drm_device_type dev_type,enum exynos_drm_output_type out_type)380 int exynos_drm_component_add(struct device *dev,
381 				enum exynos_drm_device_type dev_type,
382 				enum exynos_drm_output_type out_type)
383 {
384 	struct component_dev *cdev;
385 
386 	if (dev_type != EXYNOS_DEVICE_TYPE_CRTC &&
387 			dev_type != EXYNOS_DEVICE_TYPE_CONNECTOR) {
388 		DRM_ERROR("invalid device type.\n");
389 		return -EINVAL;
390 	}
391 
392 	mutex_lock(&drm_component_lock);
393 
394 	/*
395 	 * Make sure to check if there is a component which has two device
396 	 * objects, for connector and for encoder/connector.
397 	 * It should make sure that crtc and encoder/connector drivers are
398 	 * ready before exynos drm core binds them.
399 	 */
400 	list_for_each_entry(cdev, &drm_component_list, list) {
401 		if (cdev->out_type == out_type) {
402 			/*
403 			 * If crtc and encoder/connector device objects are
404 			 * added already just return.
405 			 */
406 			if (cdev->dev_type_flag == (EXYNOS_DEVICE_TYPE_CRTC |
407 						EXYNOS_DEVICE_TYPE_CONNECTOR)) {
408 				mutex_unlock(&drm_component_lock);
409 				return 0;
410 			}
411 
412 			if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
413 				cdev->crtc_dev = dev;
414 				cdev->dev_type_flag |= dev_type;
415 			}
416 
417 			if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
418 				cdev->conn_dev = dev;
419 				cdev->dev_type_flag |= dev_type;
420 			}
421 
422 			mutex_unlock(&drm_component_lock);
423 			return 0;
424 		}
425 	}
426 
427 	mutex_unlock(&drm_component_lock);
428 
429 	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
430 	if (!cdev)
431 		return -ENOMEM;
432 
433 	if (dev_type == EXYNOS_DEVICE_TYPE_CRTC)
434 		cdev->crtc_dev = dev;
435 	if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR)
436 		cdev->conn_dev = dev;
437 
438 	cdev->out_type = out_type;
439 	cdev->dev_type_flag = dev_type;
440 
441 	mutex_lock(&drm_component_lock);
442 	list_add_tail(&cdev->list, &drm_component_list);
443 	mutex_unlock(&drm_component_lock);
444 
445 	return 0;
446 }
447 
exynos_drm_component_del(struct device * dev,enum exynos_drm_device_type dev_type)448 void exynos_drm_component_del(struct device *dev,
449 				enum exynos_drm_device_type dev_type)
450 {
451 	struct component_dev *cdev, *next;
452 
453 	mutex_lock(&drm_component_lock);
454 
455 	list_for_each_entry_safe(cdev, next, &drm_component_list, list) {
456 		if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
457 			if (cdev->crtc_dev == dev) {
458 				cdev->crtc_dev = NULL;
459 				cdev->dev_type_flag &= ~dev_type;
460 			}
461 		}
462 
463 		if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
464 			if (cdev->conn_dev == dev) {
465 				cdev->conn_dev = NULL;
466 				cdev->dev_type_flag &= ~dev_type;
467 			}
468 		}
469 
470 		/*
471 		 * Release cdev object only in case that both of crtc and
472 		 * encoder/connector device objects are NULL.
473 		 */
474 		if (!cdev->crtc_dev && !cdev->conn_dev) {
475 			list_del(&cdev->list);
476 			kfree(cdev);
477 		}
478 
479 		break;
480 	}
481 
482 	mutex_unlock(&drm_component_lock);
483 }
484 
compare_dev(struct device * dev,void * data)485 static int compare_dev(struct device *dev, void *data)
486 {
487 	return dev == (struct device *)data;
488 }
489 
exynos_drm_match_add(struct device * dev)490 static struct component_match *exynos_drm_match_add(struct device *dev)
491 {
492 	struct component_match *match = NULL;
493 	struct component_dev *cdev;
494 	unsigned int attach_cnt = 0;
495 
496 	mutex_lock(&drm_component_lock);
497 
498 	/* Do not retry to probe if there is no any kms driver regitered. */
499 	if (list_empty(&drm_component_list)) {
500 		mutex_unlock(&drm_component_lock);
501 		return ERR_PTR(-ENODEV);
502 	}
503 
504 	list_for_each_entry(cdev, &drm_component_list, list) {
505 		/*
506 		 * Add components to master only in case that crtc and
507 		 * encoder/connector device objects exist.
508 		 */
509 		if (!cdev->crtc_dev || !cdev->conn_dev)
510 			continue;
511 
512 		attach_cnt++;
513 
514 		mutex_unlock(&drm_component_lock);
515 
516 		/*
517 		 * fimd and dpi modules have same device object so add
518 		 * only crtc device object in this case.
519 		 */
520 		if (cdev->crtc_dev == cdev->conn_dev) {
521 			component_match_add(dev, &match, compare_dev,
522 						cdev->crtc_dev);
523 			goto out_lock;
524 		}
525 
526 		/*
527 		 * Do not chage below call order.
528 		 * crtc device first should be added to master because
529 		 * connector/encoder need pipe number of crtc when they
530 		 * are created.
531 		 */
532 		component_match_add(dev, &match, compare_dev, cdev->crtc_dev);
533 		component_match_add(dev, &match, compare_dev, cdev->conn_dev);
534 
535 out_lock:
536 		mutex_lock(&drm_component_lock);
537 	}
538 
539 	mutex_unlock(&drm_component_lock);
540 
541 	return attach_cnt ? match : ERR_PTR(-EPROBE_DEFER);
542 }
543 
exynos_drm_bind(struct device * dev)544 static int exynos_drm_bind(struct device *dev)
545 {
546 	return drm_platform_init(&exynos_drm_driver, to_platform_device(dev));
547 }
548 
exynos_drm_unbind(struct device * dev)549 static void exynos_drm_unbind(struct device *dev)
550 {
551 	drm_put_dev(dev_get_drvdata(dev));
552 }
553 
554 static const struct component_master_ops exynos_drm_ops = {
555 	.bind		= exynos_drm_bind,
556 	.unbind		= exynos_drm_unbind,
557 };
558 
exynos_drm_platform_probe(struct platform_device * pdev)559 static int exynos_drm_platform_probe(struct platform_device *pdev)
560 {
561 	struct component_match *match;
562 	int ret;
563 
564 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
565 	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
566 
567 #ifdef CONFIG_DRM_EXYNOS_FIMD
568 	ret = platform_driver_register(&fimd_driver);
569 	if (ret < 0)
570 		return ret;
571 #endif
572 
573 #ifdef CONFIG_DRM_EXYNOS_DP
574 	ret = platform_driver_register(&dp_driver);
575 	if (ret < 0)
576 		goto err_unregister_fimd_drv;
577 #endif
578 
579 #ifdef CONFIG_DRM_EXYNOS_DSI
580 	ret = platform_driver_register(&dsi_driver);
581 	if (ret < 0)
582 		goto err_unregister_dp_drv;
583 #endif
584 
585 #ifdef CONFIG_DRM_EXYNOS_HDMI
586 	ret = platform_driver_register(&mixer_driver);
587 	if (ret < 0)
588 		goto err_unregister_dsi_drv;
589 	ret = platform_driver_register(&hdmi_driver);
590 	if (ret < 0)
591 		goto err_unregister_mixer_drv;
592 #endif
593 
594 	match = exynos_drm_match_add(&pdev->dev);
595 	if (IS_ERR(match)) {
596 		ret = PTR_ERR(match);
597 		goto err_unregister_hdmi_drv;
598 	}
599 
600 	ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
601 						match);
602 	if (ret < 0)
603 		goto err_unregister_hdmi_drv;
604 
605 #ifdef CONFIG_DRM_EXYNOS_G2D
606 	ret = platform_driver_register(&g2d_driver);
607 	if (ret < 0)
608 		goto err_del_component_master;
609 #endif
610 
611 #ifdef CONFIG_DRM_EXYNOS_FIMC
612 	ret = platform_driver_register(&fimc_driver);
613 	if (ret < 0)
614 		goto err_unregister_g2d_drv;
615 #endif
616 
617 #ifdef CONFIG_DRM_EXYNOS_ROTATOR
618 	ret = platform_driver_register(&rotator_driver);
619 	if (ret < 0)
620 		goto err_unregister_fimc_drv;
621 #endif
622 
623 #ifdef CONFIG_DRM_EXYNOS_GSC
624 	ret = platform_driver_register(&gsc_driver);
625 	if (ret < 0)
626 		goto err_unregister_rotator_drv;
627 #endif
628 
629 #ifdef CONFIG_DRM_EXYNOS_IPP
630 	ret = platform_driver_register(&ipp_driver);
631 	if (ret < 0)
632 		goto err_unregister_gsc_drv;
633 
634 	ret = exynos_platform_device_ipp_register();
635 	if (ret < 0)
636 		goto err_unregister_ipp_drv;
637 #endif
638 
639 	return ret;
640 
641 #ifdef CONFIG_DRM_EXYNOS_IPP
642 err_unregister_ipp_drv:
643 	platform_driver_unregister(&ipp_driver);
644 err_unregister_gsc_drv:
645 #endif
646 
647 #ifdef CONFIG_DRM_EXYNOS_GSC
648 	platform_driver_unregister(&gsc_driver);
649 err_unregister_rotator_drv:
650 #endif
651 
652 #ifdef CONFIG_DRM_EXYNOS_ROTATOR
653 	platform_driver_unregister(&rotator_driver);
654 err_unregister_fimc_drv:
655 #endif
656 
657 #ifdef CONFIG_DRM_EXYNOS_FIMC
658 	platform_driver_unregister(&fimc_driver);
659 err_unregister_g2d_drv:
660 #endif
661 
662 #ifdef CONFIG_DRM_EXYNOS_G2D
663 	platform_driver_unregister(&g2d_driver);
664 err_del_component_master:
665 #endif
666 	component_master_del(&pdev->dev, &exynos_drm_ops);
667 
668 err_unregister_hdmi_drv:
669 #ifdef CONFIG_DRM_EXYNOS_HDMI
670 	platform_driver_unregister(&hdmi_driver);
671 err_unregister_mixer_drv:
672 	platform_driver_unregister(&mixer_driver);
673 err_unregister_dsi_drv:
674 #endif
675 
676 #ifdef CONFIG_DRM_EXYNOS_DSI
677 	platform_driver_unregister(&dsi_driver);
678 err_unregister_dp_drv:
679 #endif
680 
681 #ifdef CONFIG_DRM_EXYNOS_DP
682 	platform_driver_unregister(&dp_driver);
683 err_unregister_fimd_drv:
684 #endif
685 
686 #ifdef CONFIG_DRM_EXYNOS_FIMD
687 	platform_driver_unregister(&fimd_driver);
688 #endif
689 	return ret;
690 }
691 
exynos_drm_platform_remove(struct platform_device * pdev)692 static int exynos_drm_platform_remove(struct platform_device *pdev)
693 {
694 #ifdef CONFIG_DRM_EXYNOS_IPP
695 	exynos_platform_device_ipp_unregister();
696 	platform_driver_unregister(&ipp_driver);
697 #endif
698 
699 #ifdef CONFIG_DRM_EXYNOS_GSC
700 	platform_driver_unregister(&gsc_driver);
701 #endif
702 
703 #ifdef CONFIG_DRM_EXYNOS_ROTATOR
704 	platform_driver_unregister(&rotator_driver);
705 #endif
706 
707 #ifdef CONFIG_DRM_EXYNOS_FIMC
708 	platform_driver_unregister(&fimc_driver);
709 #endif
710 
711 #ifdef CONFIG_DRM_EXYNOS_G2D
712 	platform_driver_unregister(&g2d_driver);
713 #endif
714 
715 #ifdef CONFIG_DRM_EXYNOS_HDMI
716 	platform_driver_unregister(&mixer_driver);
717 	platform_driver_unregister(&hdmi_driver);
718 #endif
719 
720 #ifdef CONFIG_DRM_EXYNOS_FIMD
721 	platform_driver_unregister(&fimd_driver);
722 #endif
723 
724 #ifdef CONFIG_DRM_EXYNOS_DSI
725 	platform_driver_unregister(&dsi_driver);
726 #endif
727 
728 #ifdef CONFIG_DRM_EXYNOS_DP
729 	platform_driver_unregister(&dp_driver);
730 #endif
731 	component_master_del(&pdev->dev, &exynos_drm_ops);
732 	return 0;
733 }
734 
735 static struct platform_driver exynos_drm_platform_driver = {
736 	.probe	= exynos_drm_platform_probe,
737 	.remove	= exynos_drm_platform_remove,
738 	.driver	= {
739 		.owner	= THIS_MODULE,
740 		.name	= "exynos-drm",
741 		.pm	= &exynos_drm_pm_ops,
742 	},
743 };
744 
exynos_drm_init(void)745 static int exynos_drm_init(void)
746 {
747 	int ret;
748 
749 	/*
750 	 * Register device object only in case of Exynos SoC.
751 	 *
752 	 * Below codes resolves temporarily infinite loop issue incurred
753 	 * by Exynos drm driver when using multi-platform kernel.
754 	 * So these codes will be replaced with more generic way later.
755 	 */
756 	if (!of_machine_is_compatible("samsung,exynos3") &&
757 			!of_machine_is_compatible("samsung,exynos4") &&
758 			!of_machine_is_compatible("samsung,exynos5"))
759 		return -ENODEV;
760 
761 	exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
762 								NULL, 0);
763 	if (IS_ERR(exynos_drm_pdev))
764 		return PTR_ERR(exynos_drm_pdev);
765 
766 #ifdef CONFIG_DRM_EXYNOS_VIDI
767 	ret = exynos_drm_probe_vidi();
768 	if (ret < 0)
769 		goto err_unregister_pd;
770 #endif
771 
772 	ret = platform_driver_register(&exynos_drm_platform_driver);
773 	if (ret)
774 		goto err_remove_vidi;
775 
776 	return 0;
777 
778 err_remove_vidi:
779 #ifdef CONFIG_DRM_EXYNOS_VIDI
780 	exynos_drm_remove_vidi();
781 
782 err_unregister_pd:
783 #endif
784 	platform_device_unregister(exynos_drm_pdev);
785 
786 	return ret;
787 }
788 
exynos_drm_exit(void)789 static void exynos_drm_exit(void)
790 {
791 	platform_driver_unregister(&exynos_drm_platform_driver);
792 #ifdef CONFIG_DRM_EXYNOS_VIDI
793 	exynos_drm_remove_vidi();
794 #endif
795 	platform_device_unregister(exynos_drm_pdev);
796 }
797 
798 module_init(exynos_drm_init);
799 module_exit(exynos_drm_exit);
800 
801 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
802 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
803 MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
804 MODULE_DESCRIPTION("Samsung SoC DRM Driver");
805 MODULE_LICENSE("GPL");
806