drm/mediatek: include dma-mapping header
[linux-2.6-microblaze.git] / drivers / gpu / drm / mediatek / mtk_drm_drv.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015 MediaTek Inc.
4  * Author: YT SHEN <yt.shen@mediatek.com>
5  */
6
7 #include <drm/drmP.h>
8 #include <drm/drm_atomic.h>
9 #include <drm/drm_atomic_helper.h>
10 #include <drm/drm_fb_helper.h>
11 #include <drm/drm_gem.h>
12 #include <drm/drm_gem_cma_helper.h>
13 #include <drm/drm_of.h>
14 #include <drm/drm_probe_helper.h>
15 #include <linux/component.h>
16 #include <linux/iommu.h>
17 #include <linux/of_address.h>
18 #include <linux/of_platform.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/dma-mapping.h>
21
22 #include "mtk_drm_crtc.h"
23 #include "mtk_drm_ddp.h"
24 #include "mtk_drm_ddp_comp.h"
25 #include "mtk_drm_drv.h"
26 #include "mtk_drm_fb.h"
27 #include "mtk_drm_gem.h"
28
29 #define DRIVER_NAME "mediatek"
30 #define DRIVER_DESC "Mediatek SoC DRM"
31 #define DRIVER_DATE "20150513"
32 #define DRIVER_MAJOR 1
33 #define DRIVER_MINOR 0
34
35 static void mtk_atomic_schedule(struct mtk_drm_private *private,
36                                 struct drm_atomic_state *state)
37 {
38         private->commit.state = state;
39         schedule_work(&private->commit.work);
40 }
41
42 static void mtk_atomic_wait_for_fences(struct drm_atomic_state *state)
43 {
44         struct drm_plane *plane;
45         struct drm_plane_state *new_plane_state;
46         int i;
47
48         for_each_new_plane_in_state(state, plane, new_plane_state, i)
49                 mtk_fb_wait(new_plane_state->fb);
50 }
51
52 static void mtk_atomic_complete(struct mtk_drm_private *private,
53                                 struct drm_atomic_state *state)
54 {
55         struct drm_device *drm = private->drm;
56
57         mtk_atomic_wait_for_fences(state);
58
59         /*
60          * Mediatek drm supports runtime PM, so plane registers cannot be
61          * written when their crtc is disabled.
62          *
63          * The comment for drm_atomic_helper_commit states:
64          *     For drivers supporting runtime PM the recommended sequence is
65          *
66          *     drm_atomic_helper_commit_modeset_disables(dev, state);
67          *     drm_atomic_helper_commit_modeset_enables(dev, state);
68          *     drm_atomic_helper_commit_planes(dev, state,
69          *                                     DRM_PLANE_COMMIT_ACTIVE_ONLY);
70          *
71          * See the kerneldoc entries for these three functions for more details.
72          */
73         drm_atomic_helper_commit_modeset_disables(drm, state);
74         drm_atomic_helper_commit_modeset_enables(drm, state);
75         drm_atomic_helper_commit_planes(drm, state,
76                                         DRM_PLANE_COMMIT_ACTIVE_ONLY);
77
78         drm_atomic_helper_wait_for_vblanks(drm, state);
79
80         drm_atomic_helper_cleanup_planes(drm, state);
81         drm_atomic_state_put(state);
82 }
83
84 static void mtk_atomic_work(struct work_struct *work)
85 {
86         struct mtk_drm_private *private = container_of(work,
87                         struct mtk_drm_private, commit.work);
88
89         mtk_atomic_complete(private, private->commit.state);
90 }
91
92 static int mtk_atomic_commit(struct drm_device *drm,
93                              struct drm_atomic_state *state,
94                              bool async)
95 {
96         struct mtk_drm_private *private = drm->dev_private;
97         int ret;
98
99         ret = drm_atomic_helper_prepare_planes(drm, state);
100         if (ret)
101                 return ret;
102
103         mutex_lock(&private->commit.lock);
104         flush_work(&private->commit.work);
105
106         ret = drm_atomic_helper_swap_state(state, true);
107         if (ret) {
108                 mutex_unlock(&private->commit.lock);
109                 drm_atomic_helper_cleanup_planes(drm, state);
110                 return ret;
111         }
112
113         drm_atomic_state_get(state);
114         if (async)
115                 mtk_atomic_schedule(private, state);
116         else
117                 mtk_atomic_complete(private, state);
118
119         mutex_unlock(&private->commit.lock);
120
121         return 0;
122 }
123
124 static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
125         .fb_create = mtk_drm_mode_fb_create,
126         .atomic_check = drm_atomic_helper_check,
127         .atomic_commit = mtk_atomic_commit,
128 };
129
130 static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = {
131         DDP_COMPONENT_OVL0,
132         DDP_COMPONENT_RDMA0,
133         DDP_COMPONENT_COLOR0,
134         DDP_COMPONENT_BLS,
135         DDP_COMPONENT_DSI0,
136 };
137
138 static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = {
139         DDP_COMPONENT_RDMA1,
140         DDP_COMPONENT_DPI0,
141 };
142
143 static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = {
144         DDP_COMPONENT_OVL0,
145         DDP_COMPONENT_COLOR0,
146         DDP_COMPONENT_AAL0,
147         DDP_COMPONENT_OD0,
148         DDP_COMPONENT_RDMA0,
149         DDP_COMPONENT_DPI0,
150         DDP_COMPONENT_PWM0,
151 };
152
153 static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = {
154         DDP_COMPONENT_OVL1,
155         DDP_COMPONENT_COLOR1,
156         DDP_COMPONENT_AAL1,
157         DDP_COMPONENT_OD1,
158         DDP_COMPONENT_RDMA1,
159         DDP_COMPONENT_DPI1,
160         DDP_COMPONENT_PWM1,
161 };
162
163 static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = {
164         DDP_COMPONENT_RDMA2,
165         DDP_COMPONENT_DSI3,
166         DDP_COMPONENT_PWM2,
167 };
168
169 static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
170         DDP_COMPONENT_OVL0,
171         DDP_COMPONENT_COLOR0,
172         DDP_COMPONENT_AAL0,
173         DDP_COMPONENT_OD0,
174         DDP_COMPONENT_RDMA0,
175         DDP_COMPONENT_UFOE,
176         DDP_COMPONENT_DSI0,
177         DDP_COMPONENT_PWM0,
178 };
179
180 static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = {
181         DDP_COMPONENT_OVL1,
182         DDP_COMPONENT_COLOR1,
183         DDP_COMPONENT_GAMMA,
184         DDP_COMPONENT_RDMA1,
185         DDP_COMPONENT_DPI0,
186 };
187
188 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
189         .main_path = mt2701_mtk_ddp_main,
190         .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
191         .ext_path = mt2701_mtk_ddp_ext,
192         .ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
193         .shadow_register = true,
194 };
195
196 static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
197         .main_path = mt2712_mtk_ddp_main,
198         .main_len = ARRAY_SIZE(mt2712_mtk_ddp_main),
199         .ext_path = mt2712_mtk_ddp_ext,
200         .ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
201         .third_path = mt2712_mtk_ddp_third,
202         .third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
203 };
204
205 static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
206         .main_path = mt8173_mtk_ddp_main,
207         .main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
208         .ext_path = mt8173_mtk_ddp_ext,
209         .ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
210 };
211
212 static int mtk_drm_kms_init(struct drm_device *drm)
213 {
214         struct mtk_drm_private *private = drm->dev_private;
215         struct platform_device *pdev;
216         struct device_node *np;
217         struct device *dma_dev;
218         int ret;
219
220         if (!iommu_present(&platform_bus_type))
221                 return -EPROBE_DEFER;
222
223         pdev = of_find_device_by_node(private->mutex_node);
224         if (!pdev) {
225                 dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
226                         private->mutex_node);
227                 of_node_put(private->mutex_node);
228                 return -EPROBE_DEFER;
229         }
230         private->mutex_dev = &pdev->dev;
231
232         drm_mode_config_init(drm);
233
234         drm->mode_config.min_width = 64;
235         drm->mode_config.min_height = 64;
236
237         /*
238          * set max width and height as default value(4096x4096).
239          * this value would be used to check framebuffer size limitation
240          * at drm_mode_addfb().
241          */
242         drm->mode_config.max_width = 4096;
243         drm->mode_config.max_height = 4096;
244         drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
245
246         ret = component_bind_all(drm->dev, drm);
247         if (ret)
248                 goto err_config_cleanup;
249
250         /*
251          * We currently support two fixed data streams, each optional,
252          * and each statically assigned to a crtc:
253          * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
254          */
255         ret = mtk_drm_crtc_create(drm, private->data->main_path,
256                                   private->data->main_len);
257         if (ret < 0)
258                 goto err_component_unbind;
259         /* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
260         ret = mtk_drm_crtc_create(drm, private->data->ext_path,
261                                   private->data->ext_len);
262         if (ret < 0)
263                 goto err_component_unbind;
264
265         ret = mtk_drm_crtc_create(drm, private->data->third_path,
266                                   private->data->third_len);
267         if (ret < 0)
268                 goto err_component_unbind;
269
270         /* Use OVL device for all DMA memory allocations */
271         np = private->comp_node[private->data->main_path[0]] ?:
272              private->comp_node[private->data->ext_path[0]];
273         pdev = of_find_device_by_node(np);
274         if (!pdev) {
275                 ret = -ENODEV;
276                 dev_err(drm->dev, "Need at least one OVL device\n");
277                 goto err_component_unbind;
278         }
279
280         dma_dev = &pdev->dev;
281         private->dma_dev = dma_dev;
282
283         /*
284          * Configure the DMA segment size to make sure we get contiguous IOVA
285          * when importing PRIME buffers.
286          */
287         if (!dma_dev->dma_parms) {
288                 private->dma_parms_allocated = true;
289                 dma_dev->dma_parms =
290                         devm_kzalloc(drm->dev, sizeof(*dma_dev->dma_parms),
291                                      GFP_KERNEL);
292         }
293         if (!dma_dev->dma_parms) {
294                 ret = -ENOMEM;
295                 goto err_component_unbind;
296         }
297
298         ret = dma_set_max_seg_size(dma_dev, (unsigned int)DMA_BIT_MASK(32));
299         if (ret) {
300                 dev_err(dma_dev, "Failed to set DMA segment size\n");
301                 goto err_unset_dma_parms;
302         }
303
304         /*
305          * We don't use the drm_irq_install() helpers provided by the DRM
306          * core, so we need to set this manually in order to allow the
307          * DRM_IOCTL_WAIT_VBLANK to operate correctly.
308          */
309         drm->irq_enabled = true;
310         ret = drm_vblank_init(drm, MAX_CRTC);
311         if (ret < 0)
312                 goto err_unset_dma_parms;
313
314         drm_kms_helper_poll_init(drm);
315         drm_mode_config_reset(drm);
316
317         return 0;
318
319 err_unset_dma_parms:
320         if (private->dma_parms_allocated)
321                 dma_dev->dma_parms = NULL;
322 err_component_unbind:
323         component_unbind_all(drm->dev, drm);
324 err_config_cleanup:
325         drm_mode_config_cleanup(drm);
326
327         return ret;
328 }
329
330 static void mtk_drm_kms_deinit(struct drm_device *drm)
331 {
332         struct mtk_drm_private *private = drm->dev_private;
333
334         drm_kms_helper_poll_fini(drm);
335         drm_atomic_helper_shutdown(drm);
336
337         if (private->dma_parms_allocated)
338                 private->dma_dev->dma_parms = NULL;
339
340         component_unbind_all(drm->dev, drm);
341         drm_mode_config_cleanup(drm);
342 }
343
344 static const struct file_operations mtk_drm_fops = {
345         .owner = THIS_MODULE,
346         .open = drm_open,
347         .release = drm_release,
348         .unlocked_ioctl = drm_ioctl,
349         .mmap = mtk_drm_gem_mmap,
350         .poll = drm_poll,
351         .read = drm_read,
352         .compat_ioctl = drm_compat_ioctl,
353 };
354
355 /*
356  * We need to override this because the device used to import the memory is
357  * not dev->dev, as drm_gem_prime_import() expects.
358  */
359 struct drm_gem_object *mtk_drm_gem_prime_import(struct drm_device *dev,
360                                                 struct dma_buf *dma_buf)
361 {
362         struct mtk_drm_private *private = dev->dev_private;
363
364         return drm_gem_prime_import_dev(dev, dma_buf, private->dma_dev);
365 }
366
367 static struct drm_driver mtk_drm_driver = {
368         .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
369                            DRIVER_ATOMIC,
370
371         .gem_free_object_unlocked = mtk_drm_gem_free_object,
372         .gem_vm_ops = &drm_gem_cma_vm_ops,
373         .dumb_create = mtk_drm_gem_dumb_create,
374
375         .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
376         .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
377         .gem_prime_export = drm_gem_prime_export,
378         .gem_prime_import = mtk_drm_gem_prime_import,
379         .gem_prime_get_sg_table = mtk_gem_prime_get_sg_table,
380         .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
381         .gem_prime_mmap = mtk_drm_gem_mmap_buf,
382         .gem_prime_vmap = mtk_drm_gem_prime_vmap,
383         .gem_prime_vunmap = mtk_drm_gem_prime_vunmap,
384         .fops = &mtk_drm_fops,
385
386         .name = DRIVER_NAME,
387         .desc = DRIVER_DESC,
388         .date = DRIVER_DATE,
389         .major = DRIVER_MAJOR,
390         .minor = DRIVER_MINOR,
391 };
392
393 static int compare_of(struct device *dev, void *data)
394 {
395         return dev->of_node == data;
396 }
397
398 static int mtk_drm_bind(struct device *dev)
399 {
400         struct mtk_drm_private *private = dev_get_drvdata(dev);
401         struct drm_device *drm;
402         int ret;
403
404         drm = drm_dev_alloc(&mtk_drm_driver, dev);
405         if (IS_ERR(drm))
406                 return PTR_ERR(drm);
407
408         drm->dev_private = private;
409         private->drm = drm;
410
411         ret = mtk_drm_kms_init(drm);
412         if (ret < 0)
413                 goto err_free;
414
415         ret = drm_dev_register(drm, 0);
416         if (ret < 0)
417                 goto err_deinit;
418
419         ret = drm_fbdev_generic_setup(drm, 32);
420         if (ret)
421                 DRM_ERROR("Failed to initialize fbdev: %d\n", ret);
422
423         return 0;
424
425 err_deinit:
426         mtk_drm_kms_deinit(drm);
427 err_free:
428         drm_dev_put(drm);
429         return ret;
430 }
431
432 static void mtk_drm_unbind(struct device *dev)
433 {
434         struct mtk_drm_private *private = dev_get_drvdata(dev);
435
436         drm_dev_unregister(private->drm);
437         mtk_drm_kms_deinit(private->drm);
438         drm_dev_put(private->drm);
439         private->num_pipes = 0;
440         private->drm = NULL;
441 }
442
443 static const struct component_master_ops mtk_drm_ops = {
444         .bind           = mtk_drm_bind,
445         .unbind         = mtk_drm_unbind,
446 };
447
448 static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
449         { .compatible = "mediatek,mt2701-disp-ovl",
450           .data = (void *)MTK_DISP_OVL },
451         { .compatible = "mediatek,mt8173-disp-ovl",
452           .data = (void *)MTK_DISP_OVL },
453         { .compatible = "mediatek,mt2701-disp-rdma",
454           .data = (void *)MTK_DISP_RDMA },
455         { .compatible = "mediatek,mt8173-disp-rdma",
456           .data = (void *)MTK_DISP_RDMA },
457         { .compatible = "mediatek,mt8173-disp-wdma",
458           .data = (void *)MTK_DISP_WDMA },
459         { .compatible = "mediatek,mt2701-disp-color",
460           .data = (void *)MTK_DISP_COLOR },
461         { .compatible = "mediatek,mt8173-disp-color",
462           .data = (void *)MTK_DISP_COLOR },
463         { .compatible = "mediatek,mt8173-disp-aal",
464           .data = (void *)MTK_DISP_AAL},
465         { .compatible = "mediatek,mt8173-disp-gamma",
466           .data = (void *)MTK_DISP_GAMMA, },
467         { .compatible = "mediatek,mt8173-disp-ufoe",
468           .data = (void *)MTK_DISP_UFOE },
469         { .compatible = "mediatek,mt2701-dsi",
470           .data = (void *)MTK_DSI },
471         { .compatible = "mediatek,mt8173-dsi",
472           .data = (void *)MTK_DSI },
473         { .compatible = "mediatek,mt2701-dpi",
474           .data = (void *)MTK_DPI },
475         { .compatible = "mediatek,mt8173-dpi",
476           .data = (void *)MTK_DPI },
477         { .compatible = "mediatek,mt2701-disp-mutex",
478           .data = (void *)MTK_DISP_MUTEX },
479         { .compatible = "mediatek,mt2712-disp-mutex",
480           .data = (void *)MTK_DISP_MUTEX },
481         { .compatible = "mediatek,mt8173-disp-mutex",
482           .data = (void *)MTK_DISP_MUTEX },
483         { .compatible = "mediatek,mt2701-disp-pwm",
484           .data = (void *)MTK_DISP_BLS },
485         { .compatible = "mediatek,mt8173-disp-pwm",
486           .data = (void *)MTK_DISP_PWM },
487         { .compatible = "mediatek,mt8173-disp-od",
488           .data = (void *)MTK_DISP_OD },
489         { }
490 };
491
492 static int mtk_drm_probe(struct platform_device *pdev)
493 {
494         struct device *dev = &pdev->dev;
495         struct mtk_drm_private *private;
496         struct resource *mem;
497         struct device_node *node;
498         struct component_match *match = NULL;
499         int ret;
500         int i;
501
502         private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
503         if (!private)
504                 return -ENOMEM;
505
506         mutex_init(&private->commit.lock);
507         INIT_WORK(&private->commit.work, mtk_atomic_work);
508         private->data = of_device_get_match_data(dev);
509
510         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
511         private->config_regs = devm_ioremap_resource(dev, mem);
512         if (IS_ERR(private->config_regs)) {
513                 ret = PTR_ERR(private->config_regs);
514                 dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n",
515                         ret);
516                 return ret;
517         }
518
519         /* Iterate over sibling DISP function blocks */
520         for_each_child_of_node(dev->of_node->parent, node) {
521                 const struct of_device_id *of_id;
522                 enum mtk_ddp_comp_type comp_type;
523                 int comp_id;
524
525                 of_id = of_match_node(mtk_ddp_comp_dt_ids, node);
526                 if (!of_id)
527                         continue;
528
529                 if (!of_device_is_available(node)) {
530                         dev_dbg(dev, "Skipping disabled component %pOF\n",
531                                 node);
532                         continue;
533                 }
534
535                 comp_type = (enum mtk_ddp_comp_type)of_id->data;
536
537                 if (comp_type == MTK_DISP_MUTEX) {
538                         private->mutex_node = of_node_get(node);
539                         continue;
540                 }
541
542                 comp_id = mtk_ddp_comp_get_id(node, comp_type);
543                 if (comp_id < 0) {
544                         dev_warn(dev, "Skipping unknown component %pOF\n",
545                                  node);
546                         continue;
547                 }
548
549                 private->comp_node[comp_id] = of_node_get(node);
550
551                 /*
552                  * Currently only the COLOR, OVL, RDMA, DSI, and DPI blocks have
553                  * separate component platform drivers and initialize their own
554                  * DDP component structure. The others are initialized here.
555                  */
556                 if (comp_type == MTK_DISP_COLOR ||
557                     comp_type == MTK_DISP_OVL ||
558                     comp_type == MTK_DISP_RDMA ||
559                     comp_type == MTK_DSI ||
560                     comp_type == MTK_DPI) {
561                         dev_info(dev, "Adding component match for %pOF\n",
562                                  node);
563                         drm_of_component_match_add(dev, &match, compare_of,
564                                                    node);
565                 } else {
566                         struct mtk_ddp_comp *comp;
567
568                         comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
569                         if (!comp) {
570                                 ret = -ENOMEM;
571                                 of_node_put(node);
572                                 goto err_node;
573                         }
574
575                         ret = mtk_ddp_comp_init(dev, node, comp, comp_id, NULL);
576                         if (ret) {
577                                 of_node_put(node);
578                                 goto err_node;
579                         }
580
581                         private->ddp_comp[comp_id] = comp;
582                 }
583         }
584
585         if (!private->mutex_node) {
586                 dev_err(dev, "Failed to find disp-mutex node\n");
587                 ret = -ENODEV;
588                 goto err_node;
589         }
590
591         pm_runtime_enable(dev);
592
593         platform_set_drvdata(pdev, private);
594
595         ret = component_master_add_with_match(dev, &mtk_drm_ops, match);
596         if (ret)
597                 goto err_pm;
598
599         return 0;
600
601 err_pm:
602         pm_runtime_disable(dev);
603 err_node:
604         of_node_put(private->mutex_node);
605         for (i = 0; i < DDP_COMPONENT_ID_MAX; i++)
606                 of_node_put(private->comp_node[i]);
607         return ret;
608 }
609
610 static int mtk_drm_remove(struct platform_device *pdev)
611 {
612         struct mtk_drm_private *private = platform_get_drvdata(pdev);
613         int i;
614
615         component_master_del(&pdev->dev, &mtk_drm_ops);
616         pm_runtime_disable(&pdev->dev);
617         of_node_put(private->mutex_node);
618         for (i = 0; i < DDP_COMPONENT_ID_MAX; i++)
619                 of_node_put(private->comp_node[i]);
620
621         return 0;
622 }
623
624 #ifdef CONFIG_PM_SLEEP
625 static int mtk_drm_sys_suspend(struct device *dev)
626 {
627         struct mtk_drm_private *private = dev_get_drvdata(dev);
628         struct drm_device *drm = private->drm;
629         int ret;
630
631         ret = drm_mode_config_helper_suspend(drm);
632         DRM_DEBUG_DRIVER("mtk_drm_sys_suspend\n");
633
634         return ret;
635 }
636
637 static int mtk_drm_sys_resume(struct device *dev)
638 {
639         struct mtk_drm_private *private = dev_get_drvdata(dev);
640         struct drm_device *drm = private->drm;
641         int ret;
642
643         ret = drm_mode_config_helper_resume(drm);
644         DRM_DEBUG_DRIVER("mtk_drm_sys_resume\n");
645
646         return ret;
647 }
648 #endif
649
650 static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, mtk_drm_sys_suspend,
651                          mtk_drm_sys_resume);
652
653 static const struct of_device_id mtk_drm_of_ids[] = {
654         { .compatible = "mediatek,mt2701-mmsys",
655           .data = &mt2701_mmsys_driver_data},
656         { .compatible = "mediatek,mt2712-mmsys",
657           .data = &mt2712_mmsys_driver_data},
658         { .compatible = "mediatek,mt8173-mmsys",
659           .data = &mt8173_mmsys_driver_data},
660         { }
661 };
662
663 static struct platform_driver mtk_drm_platform_driver = {
664         .probe  = mtk_drm_probe,
665         .remove = mtk_drm_remove,
666         .driver = {
667                 .name   = "mediatek-drm",
668                 .of_match_table = mtk_drm_of_ids,
669                 .pm     = &mtk_drm_pm_ops,
670         },
671 };
672
673 static struct platform_driver * const mtk_drm_drivers[] = {
674         &mtk_ddp_driver,
675         &mtk_disp_color_driver,
676         &mtk_disp_ovl_driver,
677         &mtk_disp_rdma_driver,
678         &mtk_dpi_driver,
679         &mtk_drm_platform_driver,
680         &mtk_dsi_driver,
681         &mtk_mipi_tx_driver,
682 };
683
684 static int __init mtk_drm_init(void)
685 {
686         return platform_register_drivers(mtk_drm_drivers,
687                                          ARRAY_SIZE(mtk_drm_drivers));
688 }
689
690 static void __exit mtk_drm_exit(void)
691 {
692         platform_unregister_drivers(mtk_drm_drivers,
693                                     ARRAY_SIZE(mtk_drm_drivers));
694 }
695
696 module_init(mtk_drm_init);
697 module_exit(mtk_drm_exit);
698
699 MODULE_AUTHOR("YT SHEN <yt.shen@mediatek.com>");
700 MODULE_DESCRIPTION("Mediatek SoC DRM driver");
701 MODULE_LICENSE("GPL v2");