5c0c9bd743406a2e6e4bcb8c62ef70b246061271
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / gpu / drm / sprd / sprd_drm_drv.c
1 /*
2  * Copyright (c) 2014 Spreadtrum Communications, Inc.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include "drmP.h"
16 #include "drm.h"
17
18 #include <drm/sprd_drm.h>
19 #ifdef CONFIG_OF
20 #include <linux/of_irq.h>
21 #endif
22
23 #include "sprd_drm_drv.h"
24 #include "sprd_drm_gem.h"
25 #ifdef CONFIG_DRM_SPRD_DMABUF
26 #include "sprd_drm_dmabuf.h"
27 #endif
28 #include "sprd_drm_irq.h"
29 #include "sprd_drm_ipp.h"
30
31 #include <video/ion_sprd.h>
32 #include "sprdfb.h"
33 #include <soc/sprd/cpuidle.h>
34
35 #define DRIVER_NAME     "sprd"
36 #define DRIVER_DESC     "SPRD SoC DRM"
37 #define DRIVER_DATE     "2014"
38 #define DRIVER_MAJOR    1
39 #define DRIVER_MINOR    0
40
41 #define VBLANK_OFF_DELAY        500
42
43 struct sprd_drm_gem_info_data {
44         struct drm_file *filp;
45         struct seq_file *m;
46 };
47
48 static int sprd_drm_gem_one_info(int id, void *ptr, void *data)
49 {
50         struct drm_gem_object *obj = (struct drm_gem_object *)ptr;
51         struct sprd_drm_gem_info_data *gem_info_data = data;
52         struct pid *pid = gem_info_data->filp->pid;
53         struct drm_sprd_file_private *file_priv =
54                         gem_info_data->filp->driver_priv;
55         struct sprd_drm_gem_obj *sprd_gem;
56         struct sprd_drm_gem_buf *buf;
57
58         if (!obj) {
59                 DRM_ERROR("failed to get drm_gem_object\n");
60                 return -EFAULT;
61         }
62
63         drm_gem_object_reference(obj);
64
65         sprd_gem = to_sprd_gem_obj(obj);
66         buf = sprd_gem->buffer;
67
68         seq_printf(gem_info_data->m,
69                         "%5d\t%5d\t%4d\t%4d\t\t%4d\t0x%08lx\t0x%x\t%4d\t%4d\t\t"
70                         "%4d\t\t0x%p\t%6d\n",
71                                 pid_nr(pid),
72                                 file_priv->tgid,
73                                 id,
74                                 atomic_read(&obj->refcount.refcount) - 1,
75                                 atomic_read(&obj->handle_count),
76                                 sprd_gem->size,
77                                 sprd_gem->flags,
78                                 buf->pfnmap,
79                                 obj->export_dma_buf ? 1 : 0,
80                                 obj->import_attach ? 1 : 0,
81                                 obj,
82                                 obj->name);
83
84         drm_gem_object_unreference(obj);
85
86         return 0;
87 }
88
89 static int sprd_drm_gem_info(struct seq_file *m, void *data)
90 {
91         struct drm_info_node *node = (struct drm_info_node *)m->private;
92         struct drm_device *drm_dev = node->minor->dev;
93         struct sprd_drm_gem_info_data gem_info_data;
94
95         gem_info_data.m = m;
96         seq_puts(gem_info_data.m,
97                         "pid\ttgid\thandle\trefcount\thcount\tsize\t\tflags\t"
98                         "pfnmap\texport_to_fd\timport_from_fd\tobj_addr\t"
99                         "name\n");
100         mutex_lock(&drm_dev->struct_mutex);
101
102         list_for_each_entry(gem_info_data.filp, &drm_dev->filelist, lhead) {
103                 spin_lock(&gem_info_data.filp->table_lock);
104                 idr_for_each(&gem_info_data.filp->object_idr,
105                         sprd_drm_gem_one_info, &gem_info_data);
106                 spin_unlock(&gem_info_data.filp->table_lock);
107         }
108
109         mutex_unlock(&drm_dev->struct_mutex);
110
111         return 0;
112 }
113
114 static struct drm_info_list sprd_drm_debugfs_list[] = {
115         {"gem_info", sprd_drm_gem_info, DRIVER_GEM},
116 };
117 #define SPRD_DRM_DEBUGFS_ENTRIES ARRAY_SIZE(sprd_drm_debugfs_list)
118
119 static struct notifier_block sprd_drm_cpu_idle_notifier = {
120         .notifier_call = sprd_drm_cpuidle_notify,
121 };
122
123 static DEVICE_ATTR(vblank_freq, S_IRUGO | S_IWUSR, sprd_drm_vblank_freq_show,
124                                 sprd_drm_vblank_freq_store);
125
126 static struct attribute *sprd_drm_vblank_freq_attrs[] = {
127         &dev_attr_vblank_freq.attr,
128         NULL,
129 };
130
131 struct attribute_group sprd_drm_vblank_freq_attrs_group = {
132         .attrs = sprd_drm_vblank_freq_attrs,
133 };
134
135 static int sprd_drm_load(struct drm_device *dev, unsigned long flags)
136 {
137         struct sprd_drm_private *private;
138         struct platform_device *pdev;
139 #ifdef CONFIG_OF
140         struct resource *res;
141 #endif
142         struct drm_minor *minor;
143 #ifdef CONFIG_DRM_DPMS_IOCTL
144         struct sprd_drm_dpms_work *dpms_work;
145 #endif
146         int ret;
147
148         minor = dev->primary;
149
150         DRM_DEBUG_DRIVER("%s\n", __FILE__);
151
152         pdev = dev->driver->kdriver.platform_device;
153         if (!pdev) {
154                 DRM_ERROR("failed to get platform device.\n");
155                 return -EFAULT;
156         }
157
158         private = devm_kzalloc(&pdev->dev, sizeof(*private), GFP_KERNEL);
159         if (!private) {
160                 DRM_ERROR("failed to alloc dev private data.\n");
161                 return -ENOMEM;
162         }
163
164         INIT_LIST_HEAD(&private->pageflip_event_list);
165         dev->dev_private = (void *)private;
166
167         private->sprd_drm_ion_client = sprd_ion_client_create("drm");
168         if (!private->sprd_drm_ion_client) {
169                 DRM_ERROR("Unable to create ION client\n");
170                 return -ENOMEM;
171         }
172
173 #ifdef CONFIG_OF
174         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sprdfb");
175         if (!res) {
176                 DRM_ERROR("failed to get DISPC base address\n");
177                 return -ENOMEM;
178         }
179
180         private->reg_size = resource_size(res);
181         private->regs = devm_ioremap(&pdev->dev, res->start,
182                                         private->reg_size);
183         if (unlikely(!private->regs)) {
184                 DRM_ERROR("failed to map DISPC base\n");
185                 return -ENOMEM;
186         }
187
188         private->irq = platform_get_irq_byname(pdev, "sprd_drm_irq");
189 #else
190         private->irq = platform_get_irq(pdev, 1);
191 #endif
192         if (private->irq <= 0)
193                 DRM_ERROR("interrupt not registered\n");
194
195         private->drm_dev = dev;
196
197         private->nb_ctrl.notifier_call = sprd_drm_notifier_ctrl;
198         if (sprdfb_nb_register(&private->nb_ctrl))
199                 pr_err("could not register sprd_fb notify callback\n");
200
201         /* init workqueue for fake vsync */
202         INIT_WORK(&private->fake_vbl_work,
203                         sprd_drm_fake_vblank_handler);
204         private->fake_vbl_hz = VBLANK_DEF_HZ;
205         private->vbl_itv_us = (unsigned long int)(VBLANK_INTERVAL(VBLANK_DEF_HZ));
206         ret = sysfs_create_group(&dev->dev->kobj, &sprd_drm_vblank_freq_attrs_group);
207         if (ret)
208                 pr_err("sysfs group creation failed, ret = %d\n", ret);
209
210         drm_mode_config_init(dev);
211         ret = drm_vblank_init(dev, MAX_CRTC);
212         if (ret)
213                 goto err;
214
215         /*
216          * probe sub drivers such as display controller and hdmi driver,
217          * that were registered at probe() of platform driver
218          * to the sub driver and create encoder and connector for them.
219          */
220         ret = sprd_drm_device_register(dev);
221         if (ret)
222                 goto err_vblank;
223
224         dev->vblank_disable_allowed = 1;
225         drm_vblank_offdelay = VBLANK_OFF_DELAY;
226         minor = dev->primary;
227         ret = drm_debugfs_create_files(sprd_drm_debugfs_list,
228                         SPRD_DRM_DEBUGFS_ENTRIES,
229                         minor->debugfs_root, minor);
230         if (ret)
231                 DRM_DEBUG_DRIVER("failed to create sprd-drm debugfs.\n");
232
233 #ifdef CONFIG_DRM_DPMS_IOCTL
234         dpms_work = kzalloc(sizeof(*dpms_work), GFP_KERNEL);
235         if (!dpms_work) {
236                 DRM_ERROR("failed to alloc dpms_work.\n");
237                 goto err_unreg;
238         }
239
240         dpms_work->private = private;
241         private->dpms_work = dpms_work;
242         INIT_WORK((struct work_struct *)private->dpms_work,
243                 sprd_drm_dpms_work_ops);
244
245         init_completion(&private->dpms_comp);
246         mutex_init(&private->dpms_lock);
247 #endif
248
249         if (register_sc_cpuidle_notifier(&sprd_drm_cpu_idle_notifier))
250                 DRM_ERROR("failed to setup light sleep notifier\n");
251
252         return 0;
253
254 #ifdef CONFIG_DRM_DPMS_IOCTL
255 err_unreg:
256         sprd_drm_device_unregister(dev);
257 #endif
258 err_vblank:
259         drm_vblank_cleanup(dev);
260 err:
261         drm_mode_config_cleanup(dev);
262         kfree(private);
263
264         return ret;
265 }
266
267 static int sprd_drm_unload(struct drm_device *dev)
268 {
269         struct sprd_drm_private *private =
270                 (struct sprd_drm_private *)dev->dev_private;
271
272         DRM_DEBUG_DRIVER("%s\n", __FILE__);
273
274         if (unregister_sc_cpuidle_notifier(&sprd_drm_cpu_idle_notifier))
275                 DRM_ERROR("failed to unset light sleep notifier\n");
276
277 #ifdef CONFIG_DRM_DPMS_IOCTL
278         kfree(private->dpms_work);
279 #endif
280
281         sprdfb_nb_unregister(&private->nb_ctrl);
282
283 #ifdef CONFIG_DRM_SPRD_KMS
284         sprd_drm_fbdev_fini(dev);
285 #endif
286         sprd_drm_device_unregister(dev);
287         drm_vblank_cleanup(dev);
288 #ifdef CONFIG_DRM_SPRD_KMS
289         drm_kms_helper_poll_fini(dev);
290 #endif
291         drm_mode_config_cleanup(dev);
292         kfree(private);
293
294         private = NULL;
295
296         drm_debugfs_remove_files(sprd_drm_debugfs_list,
297                 SPRD_DRM_DEBUGFS_ENTRIES, dev->primary);
298
299         return 0;
300 }
301
302 static int sprd_drm_open(struct drm_device *dev, struct drm_file *file)
303 {
304         struct drm_sprd_file_private *file_priv;
305
306         DRM_DEBUG_DRIVER("%s\n", __FILE__);
307
308         file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
309         if (!file_priv)
310                 return -ENOMEM;
311
312         file_priv->tgid = task_tgid_nr(current);
313         file->driver_priv = file_priv;
314
315         return sprd_drm_subdrv_open(dev, file);
316 }
317
318 static void sprd_drm_preclose(struct drm_device *dev,
319                                         struct drm_file *file)
320 {
321         struct sprd_drm_private *private = dev->dev_private;
322         struct drm_pending_vblank_event *e, *t;
323         unsigned long flags;
324
325         DRM_DEBUG_DRIVER("%s\n", __FILE__);
326
327         /* release events of current file */
328         spin_lock_irqsave(&dev->event_lock, flags);
329         list_for_each_entry_safe(e, t, &private->pageflip_event_list,
330                         base.link) {
331                 if (e->base.file_priv == file) {
332                         list_del(&e->base.link);
333                         e->base.destroy(&e->base);
334                 }
335         }
336         spin_unlock_irqrestore(&dev->event_lock, flags);
337
338         sprd_drm_subdrv_close(dev, file);
339 }
340
341 static void sprd_drm_postclose(struct drm_device *dev, struct drm_file *file)
342 {
343         DRM_DEBUG_DRIVER("%s\n", __FILE__);
344
345         if (!file->driver_priv)
346                 return;
347
348         kfree(file->driver_priv);
349         file->driver_priv = NULL;
350 }
351
352 static void sprd_drm_lastclose(struct drm_device *dev)
353 {
354         DRM_DEBUG_DRIVER("%s\n", __FILE__);
355 }
356
357 static void
358 sprd_drm_irq_preinstall(struct drm_device *dev)
359 {
360         DRM_DEBUG("%s %d\n", __func__, __LINE__);
361         dev->irq_enabled = 0;
362         return;
363 }
364
365 static int
366 sprd_drm_irq_postinstall(struct drm_device *dev)
367 {
368         struct sprd_drm_private *private = dev->dev_private;
369         int i;
370
371         DRM_DEBUG("%s %d\n", __func__, __LINE__);
372
373         for (i = 0; i < MAX_CRTC; i++)
374                 atomic_set(&private->vbl_trg_cnt[i], 0);
375
376         dev->irq_enabled = 1;
377         return 0;
378 }
379
380 static void
381 sprd_drm_irq_uninstall(struct drm_device *dev)
382 {
383         struct sprd_drm_private *private = dev->dev_private;
384         int i;
385
386         DRM_DEBUG("%s %d\n", __func__, __LINE__);
387
388         for (i = 0; i < MAX_CRTC; i++)
389                 atomic_set(&private->vbl_trg_cnt[i], 0);
390
391         dev->irq_enabled = 0;
392         return;
393 }
394
395 #ifdef CONFIG_DRM_DPMS_IOCTL
396 static BLOCKING_NOTIFIER_HEAD(sprd_drm_nb_list);
397
398 int sprd_drm_nb_register(struct notifier_block *nb)
399 {
400         return blocking_notifier_chain_register(
401                 &sprd_drm_nb_list, nb);
402 }
403
404 int sprd_drm_nb_unregister(struct notifier_block *nb)
405 {
406         return blocking_notifier_chain_unregister(
407                 &sprd_drm_nb_list, nb);
408 }
409
410 int sprd_drm_nb_send_event(unsigned long val, void *v)
411 {
412         return blocking_notifier_call_chain(
413                 &sprd_drm_nb_list, val, v);
414 }
415
416 void sprd_drm_free_dpms_event(struct drm_pending_event *event)
417 {
418         DRM_INFO("%s:base[0x%x]\n", "free_dpms_evt", (int)event);
419
420         kfree(event);
421 }
422
423 void *sprd_drm_get_dpms_event(struct sprd_drm_private *private,
424                 struct drm_file *file_priv, struct drm_control_dpms *req)
425 {
426         struct drm_device *dev = private->drm_dev;
427         struct drm_sprd_send_dpms_event *e = NULL;
428         unsigned long flags;
429
430         e = kzalloc(sizeof(*e), GFP_KERNEL);
431         if (!e) {
432                 DRM_ERROR("failed to allocate event.\n");
433                 spin_lock_irqsave(&dev->event_lock, flags);
434                 file_priv->event_space += sizeof(e->event);
435                 spin_unlock_irqrestore(&dev->event_lock, flags);
436                 goto out;
437         }
438
439         e->event.base.type = DRM_DPMS_EVENT;
440         e->event.base.length = sizeof(e->event);
441         e->event.crtc_id = req->crtc_id;
442         e->event.dpms = req->dpms;
443         e->event.user_data = req->user_data;
444
445         e->base.event = &e->event.base;
446         e->base.file_priv = file_priv;
447         e->base.destroy =  sprd_drm_free_dpms_event;
448
449         DRM_INFO("%s:base[0x%x]dpms[%d]data[0x%x]\n",
450                 "get_dpms_evt", (int)&e->base, e->event.dpms,
451                 (int)e->event.user_data);
452
453 out:
454         return e;
455 }
456
457 static void sprd_drm_control_dpms(enum drm_crtc_id crtc_id,
458                                         int mode)
459 {
460         struct sprd_drm_nb_event event;
461
462         DRM_INFO("%s:crtc_id[%d]mode[%d]\n", __func__, crtc_id, mode);
463
464         event.index = crtc_id;
465         event.data = (void *)mode;
466
467         sprd_drm_nb_send_event(SPRD_DRM_DPMS_CTRL, (void *)&event);
468
469         DRM_INFO("%s:crtc_id[%d]mode[%d]done\n", __func__, crtc_id, mode);
470
471         return;
472 }
473
474 void sprd_drm_put_dpms_event(struct sprd_drm_private *private,
475                 struct drm_sprd_send_dpms_event *e)
476 {
477         struct drm_device *dev = private->drm_dev;
478         unsigned long flags;
479
480         DRM_INFO("%s:base[0x%x]dpms[%d]data[0x%x]\n",
481                 "put_dpms_evt", (int)&e->base, e->event.dpms,
482                 (int)e->event.user_data);
483
484         spin_lock_irqsave(&dev->event_lock, flags);
485         list_add_tail(&e->base.link, &e->base.file_priv->event_list);
486         wake_up_interruptible(&e->base.file_priv->event_wait);
487         spin_unlock_irqrestore(&dev->event_lock, flags);
488
489         return;
490 }
491
492 void sprd_drm_dpms_work_ops(struct work_struct *work)
493 {
494         struct sprd_drm_dpms_work *dpms_work =
495                 (struct sprd_drm_dpms_work *)work;
496         struct drm_sprd_send_dpms_event *e = dpms_work->event;
497         struct sprd_drm_private *private = dpms_work->private;
498
499         mutex_lock(&private->dpms_lock);
500
501         DRM_INFO("%s:base[0x%x]con_id[%d]dpms[%d]data[0x%x]\n",
502                 "dpms_work", (int)&e->base, e->event.crtc_id,
503                 e->event.dpms, (int)e->event.user_data);
504
505         sprd_drm_control_dpms(e->event.crtc_id, e->event.dpms);
506
507         sprd_drm_put_dpms_event(private, e);
508
509         complete_all(&private->dpms_comp);
510
511         DRM_INFO("%s:base[0x%x]dpms[%d]done\n", "dpms_work",
512                 (int)&e->base, e->event.dpms);
513
514         mutex_unlock(&private->dpms_lock);
515
516         return;
517 }
518
519 int sprd_drm_handle_dpms(struct sprd_drm_private *private,
520                 struct drm_control_dpms *req, struct drm_file *file)
521 {
522         int ret = 0;
523
524         if (req->type == DPMS_EVENT_DRIVEN) {
525                 struct sprd_drm_dpms_work *dpms_work;
526                 struct drm_sprd_send_dpms_event *e =
527                         sprd_drm_get_dpms_event(private, file, req);
528
529                 if (!e) {
530                         ret = -ENOMEM;
531                         goto out;
532                 }
533
534                 if (completion_done(&private->dpms_comp))
535                         INIT_COMPLETION(private->dpms_comp);
536
537                 dpms_work = private->dpms_work;
538                 dpms_work->event = e;
539                 schedule_work((struct work_struct *)dpms_work);
540         } else
541                 sprd_drm_control_dpms(req->crtc_id, req->dpms);
542
543 out:
544         return ret;
545 }
546
547 int sprd_drm_dpms_ioctl(struct drm_device *dev,
548                                                 void *data,
549                                                 struct drm_file *file)
550 {
551         struct drm_control_dpms *req = data;
552         struct sprd_drm_private *private = dev->dev_private;
553         int ret = 0;
554
555         DRM_INFO("[%s][%d][%s]\n", __func__, req->dpms,
556                 req->type ? "ASYNC" : "SYNC");
557
558         ret = sprd_drm_handle_dpms(private, req, file);
559
560 out:
561         DRM_INFO("[%s][%d][%s]ret[%d]\n", __func__, req->dpms,
562                 req->type ? "ASYNC" : "SYNC", ret);
563
564         return ret;
565 }
566 #endif
567
568 static const struct vm_operations_struct sprd_drm_gem_vm_ops = {
569         .fault = sprd_drm_gem_fault,
570         .open = drm_gem_vm_open,
571         .close = drm_gem_vm_close,
572 };
573
574 static struct drm_ioctl_desc sprd_ioctls[] = {
575         DRM_IOCTL_DEF_DRV(SPRD_GEM_CREATE, sprd_drm_gem_create_ioctl,
576                         DRM_UNLOCKED | DRM_AUTH),
577         DRM_IOCTL_DEF_DRV(SPRD_GEM_MAP_OFFSET,
578                         sprd_drm_gem_map_offset_ioctl, DRM_UNLOCKED |
579                         DRM_AUTH),
580         DRM_IOCTL_DEF_DRV(SPRD_GEM_MMAP,
581                         sprd_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
582         DRM_IOCTL_DEF_DRV(SPRD_GEM_MMAP_IOMMU,
583                         sprd_drm_gem_mmap_iommu_ioctl, DRM_UNLOCKED | DRM_AUTH),
584         DRM_IOCTL_DEF_DRV(SPRD_GEM_UNMAP_IOMMU, sprd_drm_gem_unmap_iommu_ioctl,
585                         DRM_UNLOCKED | DRM_AUTH),
586         DRM_IOCTL_DEF_DRV(SPRD_GEM_GET,
587                         sprd_drm_gem_get_ioctl, DRM_UNLOCKED),
588         DRM_IOCTL_DEF_DRV(SPRD_GEM_LOCK_HANDLE,
589                         sprd_gem_lock_handle_ioctl, DRM_UNLOCKED),
590         DRM_IOCTL_DEF_DRV(SPRD_GEM_UNLOCK_HANDLE,
591                         sprd_gem_unlock_handle_ioctl, DRM_UNLOCKED),
592         DRM_IOCTL_DEF_DRV(SPRD_GEM_CACHE_OP,
593                         sprd_gem_cache_op_ioctl, DRM_UNLOCKED),
594         DRM_IOCTL_DEF_DRV(SPRD_GEM_INDEX_CREATE, sprd_drm_gem_create_index_ioctl,
595                         DRM_UNLOCKED | DRM_AUTH),
596 #ifdef CONFIG_DRM_SPRD_IPP
597         DRM_IOCTL_DEF_DRV(SPRD_IPP_GET_PROPERTY,
598                         sprd_drm_ipp_get_property, DRM_UNLOCKED | DRM_AUTH),
599         DRM_IOCTL_DEF_DRV(SPRD_IPP_SET_PROPERTY,
600                         sprd_drm_ipp_set_property, DRM_UNLOCKED | DRM_AUTH),
601         DRM_IOCTL_DEF_DRV(SPRD_IPP_QUEUE_BUF,
602                         sprd_drm_ipp_queue_buf, DRM_UNLOCKED | DRM_AUTH),
603         DRM_IOCTL_DEF_DRV(SPRD_IPP_CMD_CTRL,
604                         sprd_drm_ipp_cmd_ctrl, DRM_UNLOCKED | DRM_AUTH),
605 #endif
606 #ifdef CONFIG_DRM_DPMS_IOCTL
607         DRM_IOCTL_DEF_DRV(DPMS_CONTROL,
608                         sprd_drm_dpms_ioctl, DRM_UNLOCKED | DRM_AUTH),
609 #endif
610 };
611
612 static const struct file_operations sprd_drm_driver_fops = {
613         .owner          = THIS_MODULE,
614         .open           = drm_open,
615         .mmap           = sprd_drm_gem_mmap,
616         .poll           = drm_poll,
617         .read           = drm_read,
618         .unlocked_ioctl = drm_ioctl,
619         .release        = drm_release,
620 };
621
622 static struct drm_driver sprd_drm_driver = {
623         .driver_features        = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
624                                         DRIVER_GEM | DRIVER_PRIME,
625         .load                   = sprd_drm_load,
626         .unload                 = sprd_drm_unload,
627         .open                   = sprd_drm_open,
628         .preclose               = sprd_drm_preclose,
629         .lastclose              = sprd_drm_lastclose,
630         .postclose              = sprd_drm_postclose,
631         .get_vblank_counter     = sprd_drm_get_vblank_counter,
632         .prepare_vblank         = sprd_prepare_vblank,
633         .enable_vblank          = sprd_enable_vblank,
634         .disable_vblank         = sprd_disable_vblank,
635         .gem_init_object        = sprd_drm_gem_init_object,
636         .gem_free_object        = sprd_drm_gem_free_object,
637         .gem_vm_ops             = &sprd_drm_gem_vm_ops,
638         .dumb_create            = sprd_drm_gem_dumb_create,
639         .dumb_map_offset        = sprd_drm_gem_dumb_map_offset,
640         .dumb_destroy           = sprd_drm_gem_dumb_destroy,
641         .prime_handle_to_fd     = sprd_drm_gem_prime_handle_to_fd,
642         .prime_fd_to_handle     = sprd_drm_gem_prime_fd_to_handle,
643 #ifdef CONFIG_DRM_SPRD_DMABUF
644         .gem_prime_export       = sprd_dmabuf_prime_export,
645         .gem_prime_import       = sprd_dmabuf_prime_import,
646 #endif
647         .ioctls                 = sprd_ioctls,
648         .fops                   = &sprd_drm_driver_fops,
649         .irq_handler            = sprd_drm_irq_handler,
650         .irq_preinstall         = sprd_drm_irq_preinstall,
651         .irq_postinstall        = sprd_drm_irq_postinstall,
652         .irq_uninstall          = sprd_drm_irq_uninstall,
653         .name   = DRIVER_NAME,
654         .desc   = DRIVER_DESC,
655         .date   = DRIVER_DATE,
656         .major  = DRIVER_MAJOR,
657         .minor  = DRIVER_MINOR,
658 };
659
660 static int sprd_drm_platform_probe(struct platform_device *pdev)
661 {
662         DRM_DEBUG_DRIVER("%s\n", __FILE__);
663
664         sprd_drm_driver.num_ioctls = DRM_ARRAY_SIZE(sprd_ioctls);
665         sprd_drm_driver.kdriver.platform_device = pdev;
666
667         return drm_platform_init(&sprd_drm_driver, pdev);
668 }
669
670 static int sprd_drm_platform_remove(struct platform_device *pdev)
671 {
672         DRM_DEBUG_DRIVER("%s\n", __FILE__);
673
674         drm_platform_exit(&sprd_drm_driver, pdev);
675
676         return 0;
677 }
678
679 #ifdef CONFIG_OF
680 static const struct of_device_id sprd_drm_dt_match[] = {
681         { .compatible = "sprd,sprd_drm",},
682         {}
683 };
684 MODULE_DEVICE_TABLE(of, sprd_drm_dt_match);
685 #endif
686
687 static struct platform_driver sprd_drm_platform_driver = {
688         .probe          = sprd_drm_platform_probe,
689         .remove         = sprd_drm_platform_remove,
690         .driver         = {
691                 .owner  = THIS_MODULE,
692                 .name   = "sprd-drm",
693 #ifdef CONFIG_OF
694                 .of_match_table = of_match_ptr(sprd_drm_dt_match),
695 #endif
696         },
697 };
698
699 static int __init sprd_drm_init(void)
700 {
701         int ret;
702
703         DRM_DEBUG_DRIVER("%s\n", __FILE__);
704
705 #ifdef CONFIG_DRM_SPRD_GSP
706         ret = platform_driver_register(&gsp_driver);
707         if (ret < 0)
708                 goto out_gsp;
709 #endif
710
711 #ifdef CONFIG_DRM_SPRD_IPP
712         ret = platform_driver_register(&ipp_driver);
713         if (ret < 0)
714                 goto out_ipp;
715 #endif
716
717         ret = platform_driver_register(&sprd_drm_platform_driver);
718         if (ret < 0)
719                 goto out_drm;
720
721         return 0;
722
723 out_drm:
724 #ifdef CONFIG_DRM_SPRD_IPP
725         platform_driver_unregister(&ipp_driver);
726 out_ipp:
727 #endif
728
729 #ifdef CONFIG_DRM_SPRD_GSP
730         platform_driver_unregister(&gsp_driver);
731 out_gsp:
732 #endif
733
734         return ret;
735 }
736
737 static void __exit sprd_drm_exit(void)
738 {
739         DRM_DEBUG_DRIVER("%s\n", __FILE__);
740
741         platform_driver_unregister(&sprd_drm_platform_driver);
742
743 #ifdef CONFIG_DRM_SPRD_IPP
744         platform_driver_unregister(&ipp_driver);
745 #endif
746
747 #ifdef CONFIG_DRM_SPRD_GSP
748         platform_driver_unregister(&gsp_driver);
749 #endif
750 }
751
752 //module_init(sprd_drm_init);
753 late_initcall(sprd_drm_init);
754 module_exit(sprd_drm_exit);
755
756 MODULE_AUTHOR("frank.dong@spreadtrum.com");
757 MODULE_DESCRIPTION("Spreadtrum SoC DRM Driver");
758 MODULE_LICENSE("GPL");