xref: /openbmc/linux/drivers/gpu/drm/mediatek/mtk_drm_drv.c (revision ecc23d0a422a3118fcf6e4f0a46e17a6c2047b02)
11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2119f5173SCK Hu /*
3119f5173SCK Hu  * Copyright (c) 2015 MediaTek Inc.
4119f5173SCK Hu  * Author: YT SHEN <yt.shen@mediatek.com>
5119f5173SCK Hu  */
6119f5173SCK Hu 
7119f5173SCK Hu #include <linux/component.h>
8119f5173SCK Hu #include <linux/iommu.h>
99aef5867SSam Ravnborg #include <linux/module.h>
10722d4f06SRob Herring #include <linux/of.h>
11119f5173SCK Hu #include <linux/of_platform.h>
12722d4f06SRob Herring #include <linux/platform_device.h>
13119f5173SCK Hu #include <linux/pm_runtime.h>
147837951aSDave Airlie #include <linux/dma-mapping.h>
15119f5173SCK Hu 
16119f5173SCK Hu #include <drm/drm_atomic.h>
17119f5173SCK Hu #include <drm/drm_atomic_helper.h>
189aef5867SSam Ravnborg #include <drm/drm_drv.h>
198ab59da2SThomas Zimmermann #include <drm/drm_fbdev_generic.h>
20d268f42eSDaniel Vetter #include <drm/drm_fourcc.h>
21119f5173SCK Hu #include <drm/drm_gem.h>
22d268f42eSDaniel Vetter #include <drm/drm_gem_framebuffer_helper.h>
2302f60151SRob Clark #include <drm/drm_ioctl.h>
24119f5173SCK Hu #include <drm/drm_of.h>
25119f5173SCK Hu #include <drm/drm_probe_helper.h>
269aef5867SSam Ravnborg #include <drm/drm_vblank.h>
27119f5173SCK Hu 
28119f5173SCK Hu #include "mtk_drm_crtc.h"
29119f5173SCK Hu #include "mtk_drm_ddp_comp.h"
30119f5173SCK Hu #include "mtk_drm_drv.h"
31119f5173SCK Hu #include "mtk_drm_gem.h"
32119f5173SCK Hu 
33119f5173SCK Hu #define DRIVER_NAME "mediatek"
34119f5173SCK Hu #define DRIVER_DESC "Mediatek SoC DRM"
35119f5173SCK Hu #define DRIVER_DATE "20150513"
36119f5173SCK Hu #define DRIVER_MAJOR 1
37119f5173SCK Hu #define DRIVER_MINOR 0
38119f5173SCK Hu 
3960b874f6SBibby Hsieh static const struct drm_mode_config_helper_funcs mtk_drm_mode_config_helpers = {
4060b874f6SBibby Hsieh 	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
4160b874f6SBibby Hsieh };
42119f5173SCK Hu 
43d268f42eSDaniel Vetter static struct drm_framebuffer *
mtk_drm_mode_fb_create(struct drm_device * dev,struct drm_file * file,const struct drm_mode_fb_cmd2 * cmd)44d268f42eSDaniel Vetter mtk_drm_mode_fb_create(struct drm_device *dev,
45d268f42eSDaniel Vetter 		       struct drm_file *file,
46d268f42eSDaniel Vetter 		       const struct drm_mode_fb_cmd2 *cmd)
47d268f42eSDaniel Vetter {
48d268f42eSDaniel Vetter 	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
49d268f42eSDaniel Vetter 
50d268f42eSDaniel Vetter 	if (info->num_planes != 1)
51d268f42eSDaniel Vetter 		return ERR_PTR(-EINVAL);
52d268f42eSDaniel Vetter 
53d268f42eSDaniel Vetter 	return drm_gem_fb_create(dev, file, cmd);
54d268f42eSDaniel Vetter }
55d268f42eSDaniel Vetter 
56119f5173SCK Hu static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
57119f5173SCK Hu 	.fb_create = mtk_drm_mode_fb_create,
58119f5173SCK Hu 	.atomic_check = drm_atomic_helper_check,
5960b874f6SBibby Hsieh 	.atomic_commit = drm_atomic_helper_commit,
60119f5173SCK Hu };
61119f5173SCK Hu 
620d9eee91SNancy.Lin static const unsigned int mt2701_mtk_ddp_main[] = {
6384a5ead1Syt.shen@mediatek.com 	DDP_COMPONENT_OVL0,
6484a5ead1Syt.shen@mediatek.com 	DDP_COMPONENT_RDMA0,
6584a5ead1Syt.shen@mediatek.com 	DDP_COMPONENT_COLOR0,
6684a5ead1Syt.shen@mediatek.com 	DDP_COMPONENT_BLS,
6784a5ead1Syt.shen@mediatek.com 	DDP_COMPONENT_DSI0,
6884a5ead1Syt.shen@mediatek.com };
6984a5ead1Syt.shen@mediatek.com 
700d9eee91SNancy.Lin static const unsigned int mt2701_mtk_ddp_ext[] = {
7184a5ead1Syt.shen@mediatek.com 	DDP_COMPONENT_RDMA1,
7284a5ead1Syt.shen@mediatek.com 	DDP_COMPONENT_DPI0,
7384a5ead1Syt.shen@mediatek.com };
7484a5ead1Syt.shen@mediatek.com 
750d9eee91SNancy.Lin static const unsigned int mt7623_mtk_ddp_main[] = {
767bde3c0cSFrank Wunderlich 	DDP_COMPONENT_OVL0,
777bde3c0cSFrank Wunderlich 	DDP_COMPONENT_RDMA0,
787bde3c0cSFrank Wunderlich 	DDP_COMPONENT_COLOR0,
797bde3c0cSFrank Wunderlich 	DDP_COMPONENT_BLS,
807bde3c0cSFrank Wunderlich 	DDP_COMPONENT_DPI0,
817bde3c0cSFrank Wunderlich };
827bde3c0cSFrank Wunderlich 
830d9eee91SNancy.Lin static const unsigned int mt7623_mtk_ddp_ext[] = {
847bde3c0cSFrank Wunderlich 	DDP_COMPONENT_RDMA1,
857bde3c0cSFrank Wunderlich 	DDP_COMPONENT_DSI0,
867bde3c0cSFrank Wunderlich };
877bde3c0cSFrank Wunderlich 
880d9eee91SNancy.Lin static const unsigned int mt2712_mtk_ddp_main[] = {
89e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_OVL0,
90e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_COLOR0,
91e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_AAL0,
92e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_OD0,
93e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_RDMA0,
94e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_DPI0,
95e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_PWM0,
96e6ab087aSstu.hsieh@mediatek.com };
97e6ab087aSstu.hsieh@mediatek.com 
980d9eee91SNancy.Lin static const unsigned int mt2712_mtk_ddp_ext[] = {
99e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_OVL1,
100e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_COLOR1,
101e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_AAL1,
102e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_OD1,
103e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_RDMA1,
104e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_DPI1,
105e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_PWM1,
106e6ab087aSstu.hsieh@mediatek.com };
107e6ab087aSstu.hsieh@mediatek.com 
1080d9eee91SNancy.Lin static const unsigned int mt2712_mtk_ddp_third[] = {
109e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_RDMA2,
110e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_DSI3,
111e6ab087aSstu.hsieh@mediatek.com 	DDP_COMPONENT_PWM2,
112e6ab087aSstu.hsieh@mediatek.com };
113e6ab087aSstu.hsieh@mediatek.com 
1140d9eee91SNancy.Lin static unsigned int mt8167_mtk_ddp_main[] = {
11558e4c539SFabien Parent 	DDP_COMPONENT_OVL0,
11658e4c539SFabien Parent 	DDP_COMPONENT_COLOR0,
11758e4c539SFabien Parent 	DDP_COMPONENT_CCORR,
11858e4c539SFabien Parent 	DDP_COMPONENT_AAL0,
11958e4c539SFabien Parent 	DDP_COMPONENT_GAMMA,
1209c1b06a5Sjason-jh.lin 	DDP_COMPONENT_DITHER0,
12158e4c539SFabien Parent 	DDP_COMPONENT_RDMA0,
12258e4c539SFabien Parent 	DDP_COMPONENT_DSI0,
12358e4c539SFabien Parent };
12458e4c539SFabien Parent 
1250d9eee91SNancy.Lin static const unsigned int mt8173_mtk_ddp_main[] = {
126119f5173SCK Hu 	DDP_COMPONENT_OVL0,
127119f5173SCK Hu 	DDP_COMPONENT_COLOR0,
128d480bbc4Sstu.hsieh@mediatek.com 	DDP_COMPONENT_AAL0,
129df2dce4eSstu.hsieh@mediatek.com 	DDP_COMPONENT_OD0,
130119f5173SCK Hu 	DDP_COMPONENT_RDMA0,
131119f5173SCK Hu 	DDP_COMPONENT_UFOE,
132119f5173SCK Hu 	DDP_COMPONENT_DSI0,
133119f5173SCK Hu 	DDP_COMPONENT_PWM0,
134119f5173SCK Hu };
135119f5173SCK Hu 
1360d9eee91SNancy.Lin static const unsigned int mt8173_mtk_ddp_ext[] = {
137119f5173SCK Hu 	DDP_COMPONENT_OVL1,
138119f5173SCK Hu 	DDP_COMPONENT_COLOR1,
139119f5173SCK Hu 	DDP_COMPONENT_GAMMA,
140119f5173SCK Hu 	DDP_COMPONENT_RDMA1,
141119f5173SCK Hu 	DDP_COMPONENT_DPI0,
142119f5173SCK Hu };
143119f5173SCK Hu 
1440d9eee91SNancy.Lin static const unsigned int mt8183_mtk_ddp_main[] = {
145641ef9e7SYongqiang Niu 	DDP_COMPONENT_OVL0,
146641ef9e7SYongqiang Niu 	DDP_COMPONENT_OVL_2L0,
147641ef9e7SYongqiang Niu 	DDP_COMPONENT_RDMA0,
148641ef9e7SYongqiang Niu 	DDP_COMPONENT_COLOR0,
149641ef9e7SYongqiang Niu 	DDP_COMPONENT_CCORR,
150641ef9e7SYongqiang Niu 	DDP_COMPONENT_AAL0,
151641ef9e7SYongqiang Niu 	DDP_COMPONENT_GAMMA,
1529c1b06a5Sjason-jh.lin 	DDP_COMPONENT_DITHER0,
153641ef9e7SYongqiang Niu 	DDP_COMPONENT_DSI0,
154641ef9e7SYongqiang Niu };
155641ef9e7SYongqiang Niu 
1560d9eee91SNancy.Lin static const unsigned int mt8183_mtk_ddp_ext[] = {
157641ef9e7SYongqiang Niu 	DDP_COMPONENT_OVL_2L1,
158641ef9e7SYongqiang Niu 	DDP_COMPONENT_RDMA1,
159641ef9e7SYongqiang Niu 	DDP_COMPONENT_DPI0,
160641ef9e7SYongqiang Niu };
161641ef9e7SYongqiang Niu 
1620d9eee91SNancy.Lin static const unsigned int mt8186_mtk_ddp_main[] = {
163885a0d09SYongqiang Niu 	DDP_COMPONENT_OVL0,
164885a0d09SYongqiang Niu 	DDP_COMPONENT_RDMA0,
165885a0d09SYongqiang Niu 	DDP_COMPONENT_COLOR0,
166885a0d09SYongqiang Niu 	DDP_COMPONENT_CCORR,
167885a0d09SYongqiang Niu 	DDP_COMPONENT_AAL0,
168885a0d09SYongqiang Niu 	DDP_COMPONENT_GAMMA,
169885a0d09SYongqiang Niu 	DDP_COMPONENT_POSTMASK0,
1709c1b06a5Sjason-jh.lin 	DDP_COMPONENT_DITHER0,
171885a0d09SYongqiang Niu 	DDP_COMPONENT_DSI0,
172885a0d09SYongqiang Niu };
173885a0d09SYongqiang Niu 
1740d9eee91SNancy.Lin static const unsigned int mt8186_mtk_ddp_ext[] = {
175885a0d09SYongqiang Niu 	DDP_COMPONENT_OVL_2L0,
176885a0d09SYongqiang Niu 	DDP_COMPONENT_RDMA1,
177885a0d09SYongqiang Niu 	DDP_COMPONENT_DPI0,
178885a0d09SYongqiang Niu };
179885a0d09SYongqiang Niu 
18054b48080SNathan Lu static const unsigned int mt8188_mtk_ddp_main[] = {
18154b48080SNathan Lu 	DDP_COMPONENT_OVL0,
18254b48080SNathan Lu 	DDP_COMPONENT_RDMA0,
18354b48080SNathan Lu 	DDP_COMPONENT_COLOR0,
18454b48080SNathan Lu 	DDP_COMPONENT_CCORR,
18554b48080SNathan Lu 	DDP_COMPONENT_AAL0,
18654b48080SNathan Lu 	DDP_COMPONENT_GAMMA,
18754b48080SNathan Lu 	DDP_COMPONENT_POSTMASK0,
18854b48080SNathan Lu 	DDP_COMPONENT_DITHER0,
18954b48080SNathan Lu 	DDP_COMPONENT_DP_INTF0,
19054b48080SNathan Lu };
19154b48080SNathan Lu 
1920d9eee91SNancy.Lin static const unsigned int mt8192_mtk_ddp_main[] = {
19301365f54SYongqiang Niu 	DDP_COMPONENT_OVL0,
19401365f54SYongqiang Niu 	DDP_COMPONENT_OVL_2L0,
19501365f54SYongqiang Niu 	DDP_COMPONENT_RDMA0,
19601365f54SYongqiang Niu 	DDP_COMPONENT_COLOR0,
19701365f54SYongqiang Niu 	DDP_COMPONENT_CCORR,
19801365f54SYongqiang Niu 	DDP_COMPONENT_AAL0,
19901365f54SYongqiang Niu 	DDP_COMPONENT_GAMMA,
20001365f54SYongqiang Niu 	DDP_COMPONENT_POSTMASK0,
2019c1b06a5Sjason-jh.lin 	DDP_COMPONENT_DITHER0,
20201365f54SYongqiang Niu 	DDP_COMPONENT_DSI0,
20301365f54SYongqiang Niu };
20401365f54SYongqiang Niu 
2050d9eee91SNancy.Lin static const unsigned int mt8192_mtk_ddp_ext[] = {
20601365f54SYongqiang Niu 	DDP_COMPONENT_OVL_2L2,
20701365f54SYongqiang Niu 	DDP_COMPONENT_RDMA4,
20801365f54SYongqiang Niu 	DDP_COMPONENT_DPI0,
20901365f54SYongqiang Niu };
21001365f54SYongqiang Niu 
2110d9eee91SNancy.Lin static const unsigned int mt8195_mtk_ddp_main[] = {
2127266e90aSjason-jh.lin 	DDP_COMPONENT_OVL0,
2137266e90aSjason-jh.lin 	DDP_COMPONENT_RDMA0,
2147266e90aSjason-jh.lin 	DDP_COMPONENT_COLOR0,
2157266e90aSjason-jh.lin 	DDP_COMPONENT_CCORR,
2167266e90aSjason-jh.lin 	DDP_COMPONENT_AAL0,
2177266e90aSjason-jh.lin 	DDP_COMPONENT_GAMMA,
2189c1b06a5Sjason-jh.lin 	DDP_COMPONENT_DITHER0,
2197266e90aSjason-jh.lin 	DDP_COMPONENT_DSC0,
2207266e90aSjason-jh.lin 	DDP_COMPONENT_MERGE0,
2217266e90aSjason-jh.lin 	DDP_COMPONENT_DP_INTF0,
2227266e90aSjason-jh.lin };
2237266e90aSjason-jh.lin 
224012cc7ebSNancy.Lin static const unsigned int mt8195_mtk_ddp_ext[] = {
225012cc7ebSNancy.Lin 	DDP_COMPONENT_DRM_OVL_ADAPTOR,
226012cc7ebSNancy.Lin 	DDP_COMPONENT_MERGE5,
227012cc7ebSNancy.Lin 	DDP_COMPONENT_DP_INTF1,
228012cc7ebSNancy.Lin };
229012cc7ebSNancy.Lin 
23084a5ead1Syt.shen@mediatek.com static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
23184a5ead1Syt.shen@mediatek.com 	.main_path = mt2701_mtk_ddp_main,
23284a5ead1Syt.shen@mediatek.com 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
23384a5ead1Syt.shen@mediatek.com 	.ext_path = mt2701_mtk_ddp_ext,
23484a5ead1Syt.shen@mediatek.com 	.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
23584a5ead1Syt.shen@mediatek.com 	.shadow_register = true,
2361ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
23784a5ead1Syt.shen@mediatek.com };
23884a5ead1Syt.shen@mediatek.com 
2397bde3c0cSFrank Wunderlich static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
2407bde3c0cSFrank Wunderlich 	.main_path = mt7623_mtk_ddp_main,
2417bde3c0cSFrank Wunderlich 	.main_len = ARRAY_SIZE(mt7623_mtk_ddp_main),
2427bde3c0cSFrank Wunderlich 	.ext_path = mt7623_mtk_ddp_ext,
2437bde3c0cSFrank Wunderlich 	.ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
2447bde3c0cSFrank Wunderlich 	.shadow_register = true,
2451ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
2467bde3c0cSFrank Wunderlich };
2477bde3c0cSFrank Wunderlich 
248e6ab087aSstu.hsieh@mediatek.com static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
249e6ab087aSstu.hsieh@mediatek.com 	.main_path = mt2712_mtk_ddp_main,
250e6ab087aSstu.hsieh@mediatek.com 	.main_len = ARRAY_SIZE(mt2712_mtk_ddp_main),
251e6ab087aSstu.hsieh@mediatek.com 	.ext_path = mt2712_mtk_ddp_ext,
252e6ab087aSstu.hsieh@mediatek.com 	.ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
253e6ab087aSstu.hsieh@mediatek.com 	.third_path = mt2712_mtk_ddp_third,
254e6ab087aSstu.hsieh@mediatek.com 	.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
2551ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
256e6ab087aSstu.hsieh@mediatek.com };
257e6ab087aSstu.hsieh@mediatek.com 
25858e4c539SFabien Parent static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
25958e4c539SFabien Parent 	.main_path = mt8167_mtk_ddp_main,
26058e4c539SFabien Parent 	.main_len = ARRAY_SIZE(mt8167_mtk_ddp_main),
2611ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
26258e4c539SFabien Parent };
26358e4c539SFabien Parent 
264c5f228efSyt.shen@mediatek.com static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
265c5f228efSyt.shen@mediatek.com 	.main_path = mt8173_mtk_ddp_main,
266c5f228efSyt.shen@mediatek.com 	.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
267c5f228efSyt.shen@mediatek.com 	.ext_path = mt8173_mtk_ddp_ext,
268c5f228efSyt.shen@mediatek.com 	.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
2691ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
270c5f228efSyt.shen@mediatek.com };
271c5f228efSyt.shen@mediatek.com 
272641ef9e7SYongqiang Niu static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
273641ef9e7SYongqiang Niu 	.main_path = mt8183_mtk_ddp_main,
274641ef9e7SYongqiang Niu 	.main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
275641ef9e7SYongqiang Niu 	.ext_path = mt8183_mtk_ddp_ext,
276641ef9e7SYongqiang Niu 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
2771ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
278641ef9e7SYongqiang Niu };
279641ef9e7SYongqiang Niu 
280885a0d09SYongqiang Niu static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
281885a0d09SYongqiang Niu 	.main_path = mt8186_mtk_ddp_main,
282885a0d09SYongqiang Niu 	.main_len = ARRAY_SIZE(mt8186_mtk_ddp_main),
283885a0d09SYongqiang Niu 	.ext_path = mt8186_mtk_ddp_ext,
284885a0d09SYongqiang Niu 	.ext_len = ARRAY_SIZE(mt8186_mtk_ddp_ext),
2851ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
286885a0d09SYongqiang Niu };
287885a0d09SYongqiang Niu 
28854b48080SNathan Lu static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = {
28954b48080SNathan Lu 	.main_path = mt8188_mtk_ddp_main,
29054b48080SNathan Lu 	.main_len = ARRAY_SIZE(mt8188_mtk_ddp_main),
291bc46695bSJason-JH.Lin 	.mmsys_dev_num = 1,
29254b48080SNathan Lu };
29354b48080SNathan Lu 
29401365f54SYongqiang Niu static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
29501365f54SYongqiang Niu 	.main_path = mt8192_mtk_ddp_main,
29601365f54SYongqiang Niu 	.main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
29701365f54SYongqiang Niu 	.ext_path = mt8192_mtk_ddp_ext,
29801365f54SYongqiang Niu 	.ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
2991ef7ed48SNancy.Lin 	.mmsys_dev_num = 1,
30001365f54SYongqiang Niu };
30101365f54SYongqiang Niu 
3027266e90aSjason-jh.lin static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
3037266e90aSjason-jh.lin 	.main_path = mt8195_mtk_ddp_main,
3047266e90aSjason-jh.lin 	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
305012cc7ebSNancy.Lin 	.mmsys_dev_num = 2,
306012cc7ebSNancy.Lin };
307012cc7ebSNancy.Lin 
308012cc7ebSNancy.Lin static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
309012cc7ebSNancy.Lin 	.ext_path = mt8195_mtk_ddp_ext,
310012cc7ebSNancy.Lin 	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
311012cc7ebSNancy.Lin 	.mmsys_id = 1,
312012cc7ebSNancy.Lin 	.mmsys_dev_num = 2,
3137266e90aSjason-jh.lin };
3147266e90aSjason-jh.lin 
3151ef7ed48SNancy.Lin static const struct of_device_id mtk_drm_of_ids[] = {
3161ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt2701-mmsys",
3171ef7ed48SNancy.Lin 	  .data = &mt2701_mmsys_driver_data},
3181ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt7623-mmsys",
3191ef7ed48SNancy.Lin 	  .data = &mt7623_mmsys_driver_data},
3201ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt2712-mmsys",
3211ef7ed48SNancy.Lin 	  .data = &mt2712_mmsys_driver_data},
3221ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt8167-mmsys",
3231ef7ed48SNancy.Lin 	  .data = &mt8167_mmsys_driver_data},
3241ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt8173-mmsys",
3251ef7ed48SNancy.Lin 	  .data = &mt8173_mmsys_driver_data},
3261ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt8183-mmsys",
3271ef7ed48SNancy.Lin 	  .data = &mt8183_mmsys_driver_data},
3281ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt8186-mmsys",
3291ef7ed48SNancy.Lin 	  .data = &mt8186_mmsys_driver_data},
33054b48080SNathan Lu 	{ .compatible = "mediatek,mt8188-vdosys0",
33154b48080SNathan Lu 	  .data = &mt8188_vdosys0_driver_data},
3321ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt8192-mmsys",
3331ef7ed48SNancy.Lin 	  .data = &mt8192_mmsys_driver_data},
3341ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt8195-mmsys",
3351ef7ed48SNancy.Lin 	  .data = &mt8195_vdosys0_driver_data},
3361ef7ed48SNancy.Lin 	{ .compatible = "mediatek,mt8195-vdosys0",
3371ef7ed48SNancy.Lin 	  .data = &mt8195_vdosys0_driver_data},
338012cc7ebSNancy.Lin 	{ .compatible = "mediatek,mt8195-vdosys1",
339012cc7ebSNancy.Lin 	  .data = &mt8195_vdosys1_driver_data},
3401ef7ed48SNancy.Lin 	{ }
3411ef7ed48SNancy.Lin };
3421ef7ed48SNancy.Lin MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
3431ef7ed48SNancy.Lin 
mtk_drm_match(struct device * dev,void * data)3441ef7ed48SNancy.Lin static int mtk_drm_match(struct device *dev, void *data)
3451ef7ed48SNancy.Lin {
3461ef7ed48SNancy.Lin 	if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
3471ef7ed48SNancy.Lin 		return true;
3481ef7ed48SNancy.Lin 	return false;
3491ef7ed48SNancy.Lin }
3501ef7ed48SNancy.Lin 
mtk_drm_get_all_drm_priv(struct device * dev)3511ef7ed48SNancy.Lin static bool mtk_drm_get_all_drm_priv(struct device *dev)
3521ef7ed48SNancy.Lin {
3531ef7ed48SNancy.Lin 	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
3541ef7ed48SNancy.Lin 	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
3551ef7ed48SNancy.Lin 	struct device_node *phandle = dev->parent->of_node;
3561ef7ed48SNancy.Lin 	const struct of_device_id *of_id;
3571ef7ed48SNancy.Lin 	struct device_node *node;
3581ef7ed48SNancy.Lin 	struct device *drm_dev;
359d761b945SJason-JH.Lin 	unsigned int cnt = 0;
3601ef7ed48SNancy.Lin 	int i, j;
3611ef7ed48SNancy.Lin 
3621ef7ed48SNancy.Lin 	for_each_child_of_node(phandle->parent, node) {
3631ef7ed48SNancy.Lin 		struct platform_device *pdev;
3641ef7ed48SNancy.Lin 
3651ef7ed48SNancy.Lin 		of_id = of_match_node(mtk_drm_of_ids, node);
3661ef7ed48SNancy.Lin 		if (!of_id)
3671ef7ed48SNancy.Lin 			continue;
3681ef7ed48SNancy.Lin 
3691ef7ed48SNancy.Lin 		pdev = of_find_device_by_node(node);
3701ef7ed48SNancy.Lin 		if (!pdev)
3711ef7ed48SNancy.Lin 			continue;
3721ef7ed48SNancy.Lin 
3731ef7ed48SNancy.Lin 		drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
3741ef7ed48SNancy.Lin 		if (!drm_dev || !dev_get_drvdata(drm_dev))
3751ef7ed48SNancy.Lin 			continue;
3761ef7ed48SNancy.Lin 
3771ef7ed48SNancy.Lin 		all_drm_priv[cnt] = dev_get_drvdata(drm_dev);
3781ef7ed48SNancy.Lin 		if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound)
3791ef7ed48SNancy.Lin 			cnt++;
380d761b945SJason-JH.Lin 
381*a3d970f1SJavier Carrasco 		if (cnt == MAX_CRTC) {
382*a3d970f1SJavier Carrasco 			of_node_put(node);
383d761b945SJason-JH.Lin 			break;
3841ef7ed48SNancy.Lin 		}
385*a3d970f1SJavier Carrasco 	}
3861ef7ed48SNancy.Lin 
3871ef7ed48SNancy.Lin 	if (drm_priv->data->mmsys_dev_num == cnt) {
3881ef7ed48SNancy.Lin 		for (i = 0; i < cnt; i++)
3891ef7ed48SNancy.Lin 			for (j = 0; j < cnt; j++)
3901ef7ed48SNancy.Lin 				all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
3911ef7ed48SNancy.Lin 
3921ef7ed48SNancy.Lin 		return true;
3931ef7ed48SNancy.Lin 	}
3941ef7ed48SNancy.Lin 
3951ef7ed48SNancy.Lin 	return false;
3961ef7ed48SNancy.Lin }
3971ef7ed48SNancy.Lin 
mtk_drm_find_mmsys_comp(struct mtk_drm_private * private,int comp_id)3981ef7ed48SNancy.Lin static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
3991ef7ed48SNancy.Lin {
4001ef7ed48SNancy.Lin 	const struct mtk_mmsys_driver_data *drv_data = private->data;
4011ef7ed48SNancy.Lin 	int i;
4021ef7ed48SNancy.Lin 
4031ef7ed48SNancy.Lin 	if (drv_data->main_path)
4041ef7ed48SNancy.Lin 		for (i = 0; i < drv_data->main_len; i++)
4051ef7ed48SNancy.Lin 			if (drv_data->main_path[i] == comp_id)
4061ef7ed48SNancy.Lin 				return true;
4071ef7ed48SNancy.Lin 
4081ef7ed48SNancy.Lin 	if (drv_data->ext_path)
4091ef7ed48SNancy.Lin 		for (i = 0; i < drv_data->ext_len; i++)
4101ef7ed48SNancy.Lin 			if (drv_data->ext_path[i] == comp_id)
4111ef7ed48SNancy.Lin 				return true;
4121ef7ed48SNancy.Lin 
4131ef7ed48SNancy.Lin 	if (drv_data->third_path)
4141ef7ed48SNancy.Lin 		for (i = 0; i < drv_data->third_len; i++)
4151ef7ed48SNancy.Lin 			if (drv_data->third_path[i] == comp_id)
4161ef7ed48SNancy.Lin 				return true;
4171ef7ed48SNancy.Lin 
4181ef7ed48SNancy.Lin 	return false;
4191ef7ed48SNancy.Lin }
4201ef7ed48SNancy.Lin 
mtk_drm_kms_init(struct drm_device * drm)421119f5173SCK Hu static int mtk_drm_kms_init(struct drm_device *drm)
422119f5173SCK Hu {
423119f5173SCK Hu 	struct mtk_drm_private *private = drm->dev_private;
4241ef7ed48SNancy.Lin 	struct mtk_drm_private *priv_n;
4250d9eee91SNancy.Lin 	struct device *dma_dev = NULL;
42689645241SMichael Walle 	struct drm_crtc *crtc;
4271ef7ed48SNancy.Lin 	int ret, i, j;
428119f5173SCK Hu 
429c0a23916SJavier Martinez Canillas 	if (drm_firmware_drivers_only())
430c0a23916SJavier Martinez Canillas 		return -ENODEV;
431c0a23916SJavier Martinez Canillas 
43218c62222SDaniel Vetter 	ret = drmm_mode_config_init(drm);
43318c62222SDaniel Vetter 	if (ret)
4342132940fSYu Kuai 		goto put_mutex_dev;
435119f5173SCK Hu 
436119f5173SCK Hu 	drm->mode_config.min_width = 64;
437119f5173SCK Hu 	drm->mode_config.min_height = 64;
438119f5173SCK Hu 
439119f5173SCK Hu 	/*
440119f5173SCK Hu 	 * set max width and height as default value(4096x4096).
441119f5173SCK Hu 	 * this value would be used to check framebuffer size limitation
442119f5173SCK Hu 	 * at drm_mode_addfb().
443119f5173SCK Hu 	 */
444119f5173SCK Hu 	drm->mode_config.max_width = 4096;
445119f5173SCK Hu 	drm->mode_config.max_height = 4096;
446119f5173SCK Hu 	drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
44760b874f6SBibby Hsieh 	drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
448119f5173SCK Hu 
4491ef7ed48SNancy.Lin 	for (i = 0; i < private->data->mmsys_dev_num; i++) {
4501ef7ed48SNancy.Lin 		drm->dev_private = private->all_drm_private[i];
4511ef7ed48SNancy.Lin 		ret = component_bind_all(private->all_drm_private[i]->dev, drm);
452119f5173SCK Hu 		if (ret)
4532132940fSYu Kuai 			goto put_mutex_dev;
4541ef7ed48SNancy.Lin 	}
455119f5173SCK Hu 
456119f5173SCK Hu 	/*
457144d9b2eSGil Dekel 	 * Ensure internal panels are at the top of the connector list before
458144d9b2eSGil Dekel 	 * crtc creation.
459144d9b2eSGil Dekel 	 */
460144d9b2eSGil Dekel 	drm_helper_move_panel_connectors_to_head(drm);
461144d9b2eSGil Dekel 
462144d9b2eSGil Dekel 	/*
4631ef7ed48SNancy.Lin 	 * 1. We currently support two fixed data streams, each optional,
464119f5173SCK Hu 	 *    and each statically assigned to a crtc:
465119f5173SCK Hu 	 *    OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
4661ef7ed48SNancy.Lin 	 * 2. For multi mmsys architecture, crtc path data are located in
4671ef7ed48SNancy.Lin 	 *    different drm private data structures. Loop through crtc index to
4681ef7ed48SNancy.Lin 	 *    create crtc from the main path and then ext_path and finally the
4691ef7ed48SNancy.Lin 	 *    third path.
470119f5173SCK Hu 	 */
4711ef7ed48SNancy.Lin 	for (i = 0; i < MAX_CRTC; i++) {
4721ef7ed48SNancy.Lin 		for (j = 0; j < private->data->mmsys_dev_num; j++) {
4731ef7ed48SNancy.Lin 			priv_n = private->all_drm_private[j];
4741ef7ed48SNancy.Lin 
4751ef7ed48SNancy.Lin 			if (i == 0 && priv_n->data->main_len) {
4761ef7ed48SNancy.Lin 				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
4771ef7ed48SNancy.Lin 							  priv_n->data->main_len, j);
4781ef7ed48SNancy.Lin 				if (ret)
479119f5173SCK Hu 					goto err_component_unbind;
480119f5173SCK Hu 
4811ef7ed48SNancy.Lin 				continue;
4821ef7ed48SNancy.Lin 			} else if (i == 1 && priv_n->data->ext_len) {
4831ef7ed48SNancy.Lin 				ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
4841ef7ed48SNancy.Lin 							  priv_n->data->ext_len, j);
4851ef7ed48SNancy.Lin 				if (ret)
486561fad31Sstu.hsieh@mediatek.com 					goto err_component_unbind;
487561fad31Sstu.hsieh@mediatek.com 
4881ef7ed48SNancy.Lin 				continue;
4891ef7ed48SNancy.Lin 			} else if (i == 2 && priv_n->data->third_len) {
4901ef7ed48SNancy.Lin 				ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
4911ef7ed48SNancy.Lin 							  priv_n->data->third_len, j);
4921ef7ed48SNancy.Lin 				if (ret)
4931ef7ed48SNancy.Lin 					goto err_component_unbind;
4941ef7ed48SNancy.Lin 
4951ef7ed48SNancy.Lin 				continue;
4961ef7ed48SNancy.Lin 			}
4971ef7ed48SNancy.Lin 		}
4981ef7ed48SNancy.Lin 	}
4991ef7ed48SNancy.Lin 
5000d9eee91SNancy.Lin 	/* Use OVL device for all DMA memory allocations */
50189645241SMichael Walle 	crtc = drm_crtc_from_index(drm, 0);
50289645241SMichael Walle 	if (crtc)
50389645241SMichael Walle 		dma_dev = mtk_drm_crtc_dma_dev_get(crtc);
5040d9eee91SNancy.Lin 	if (!dma_dev) {
505119f5173SCK Hu 		ret = -ENODEV;
506119f5173SCK Hu 		dev_err(drm->dev, "Need at least one OVL device\n");
507119f5173SCK Hu 		goto err_component_unbind;
508119f5173SCK Hu 	}
509119f5173SCK Hu 
5101ef7ed48SNancy.Lin 	for (i = 0; i < private->data->mmsys_dev_num; i++)
5111ef7ed48SNancy.Lin 		private->all_drm_private[i]->dma_dev = dma_dev;
51207095555SAlexandre Courbot 
51307095555SAlexandre Courbot 	/*
51407095555SAlexandre Courbot 	 * Configure the DMA segment size to make sure we get contiguous IOVA
51507095555SAlexandre Courbot 	 * when importing PRIME buffers.
51607095555SAlexandre Courbot 	 */
51731855cffSRobin Murphy 	ret = dma_set_max_seg_size(dma_dev, UINT_MAX);
51807095555SAlexandre Courbot 	if (ret) {
51907095555SAlexandre Courbot 		dev_err(dma_dev, "Failed to set DMA segment size\n");
52031855cffSRobin Murphy 		goto err_component_unbind;
52107095555SAlexandre Courbot 	}
522119f5173SCK Hu 
523119f5173SCK Hu 	ret = drm_vblank_init(drm, MAX_CRTC);
524119f5173SCK Hu 	if (ret < 0)
52531855cffSRobin Murphy 		goto err_component_unbind;
526119f5173SCK Hu 
527119f5173SCK Hu 	drm_kms_helper_poll_init(drm);
528119f5173SCK Hu 	drm_mode_config_reset(drm);
529119f5173SCK Hu 
530119f5173SCK Hu 	return 0;
531119f5173SCK Hu 
532119f5173SCK Hu err_component_unbind:
5331ef7ed48SNancy.Lin 	for (i = 0; i < private->data->mmsys_dev_num; i++)
5341ef7ed48SNancy.Lin 		component_unbind_all(private->all_drm_private[i]->dev, drm);
5352132940fSYu Kuai put_mutex_dev:
5361ef7ed48SNancy.Lin 	for (i = 0; i < private->data->mmsys_dev_num; i++)
5371ef7ed48SNancy.Lin 		put_device(private->all_drm_private[i]->mutex_dev);
5381ef7ed48SNancy.Lin 
539119f5173SCK Hu 	return ret;
540119f5173SCK Hu }
541119f5173SCK Hu 
mtk_drm_kms_deinit(struct drm_device * drm)542119f5173SCK Hu static void mtk_drm_kms_deinit(struct drm_device *drm)
543119f5173SCK Hu {
544119f5173SCK Hu 	drm_kms_helper_poll_fini(drm);
545cf49b24fSHsin-Yi Wang 	drm_atomic_helper_shutdown(drm);
546119f5173SCK Hu 
547119f5173SCK Hu 	component_unbind_all(drm->dev, drm);
548119f5173SCK Hu }
549119f5173SCK Hu 
550500007ebSThomas Zimmermann DEFINE_DRM_GEM_FOPS(mtk_drm_fops);
551119f5173SCK Hu 
5524c6f3196SAlexandre Courbot /*
5534c6f3196SAlexandre Courbot  * We need to override this because the device used to import the memory is
5544c6f3196SAlexandre Courbot  * not dev->dev, as drm_gem_prime_import() expects.
5554c6f3196SAlexandre Courbot  */
mtk_drm_gem_prime_import(struct drm_device * dev,struct dma_buf * dma_buf)55636b36f91SLee Jones static struct drm_gem_object *mtk_drm_gem_prime_import(struct drm_device *dev,
5574c6f3196SAlexandre Courbot 						       struct dma_buf *dma_buf)
5584c6f3196SAlexandre Courbot {
5594c6f3196SAlexandre Courbot 	struct mtk_drm_private *private = dev->dev_private;
5604c6f3196SAlexandre Courbot 
5614c6f3196SAlexandre Courbot 	return drm_gem_prime_import_dev(dev, dma_buf, private->dma_dev);
5624c6f3196SAlexandre Courbot }
5634c6f3196SAlexandre Courbot 
56470a59dd8SDaniel Vetter static const struct drm_driver mtk_drm_driver = {
5650424fdafSDaniel Vetter 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
566119f5173SCK Hu 
567119f5173SCK Hu 	.dumb_create = mtk_drm_gem_dumb_create,
568119f5173SCK Hu 
5694c6f3196SAlexandre Courbot 	.gem_prime_import = mtk_drm_gem_prime_import,
570119f5173SCK Hu 	.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
571119f5173SCK Hu 	.fops = &mtk_drm_fops,
572119f5173SCK Hu 
573119f5173SCK Hu 	.name = DRIVER_NAME,
574119f5173SCK Hu 	.desc = DRIVER_DESC,
575119f5173SCK Hu 	.date = DRIVER_DATE,
576119f5173SCK Hu 	.major = DRIVER_MAJOR,
577119f5173SCK Hu 	.minor = DRIVER_MINOR,
578119f5173SCK Hu };
579119f5173SCK Hu 
compare_dev(struct device * dev,void * data)5800d9eee91SNancy.Lin static int compare_dev(struct device *dev, void *data)
5810d9eee91SNancy.Lin {
5820d9eee91SNancy.Lin 	return dev == (struct device *)data;
5830d9eee91SNancy.Lin }
5840d9eee91SNancy.Lin 
mtk_drm_bind(struct device * dev)585119f5173SCK Hu static int mtk_drm_bind(struct device *dev)
586119f5173SCK Hu {
587119f5173SCK Hu 	struct mtk_drm_private *private = dev_get_drvdata(dev);
5881ef7ed48SNancy.Lin 	struct platform_device *pdev;
589119f5173SCK Hu 	struct drm_device *drm;
5901ef7ed48SNancy.Lin 	int ret, i;
5911ef7ed48SNancy.Lin 
5921ef7ed48SNancy.Lin 	if (!iommu_present(&platform_bus_type))
5931ef7ed48SNancy.Lin 		return -EPROBE_DEFER;
5941ef7ed48SNancy.Lin 
5951ef7ed48SNancy.Lin 	pdev = of_find_device_by_node(private->mutex_node);
5961ef7ed48SNancy.Lin 	if (!pdev) {
5971ef7ed48SNancy.Lin 		dev_err(dev, "Waiting for disp-mutex device %pOF\n",
5981ef7ed48SNancy.Lin 			private->mutex_node);
5991ef7ed48SNancy.Lin 		of_node_put(private->mutex_node);
6001ef7ed48SNancy.Lin 		return -EPROBE_DEFER;
6011ef7ed48SNancy.Lin 	}
6021ef7ed48SNancy.Lin 
6031ef7ed48SNancy.Lin 	private->mutex_dev = &pdev->dev;
6041ef7ed48SNancy.Lin 	private->mtk_drm_bound = true;
6051ef7ed48SNancy.Lin 	private->dev = dev;
6061ef7ed48SNancy.Lin 
6071ef7ed48SNancy.Lin 	if (!mtk_drm_get_all_drm_priv(dev))
6081ef7ed48SNancy.Lin 		return 0;
609119f5173SCK Hu 
610119f5173SCK Hu 	drm = drm_dev_alloc(&mtk_drm_driver, dev);
6110f288605STom Gundersen 	if (IS_ERR(drm))
6120f288605STom Gundersen 		return PTR_ERR(drm);
613119f5173SCK Hu 
6141ef7ed48SNancy.Lin 	private->drm_master = true;
615119f5173SCK Hu 	drm->dev_private = private;
6161ef7ed48SNancy.Lin 	for (i = 0; i < private->data->mmsys_dev_num; i++)
6171ef7ed48SNancy.Lin 		private->all_drm_private[i]->drm = drm;
618119f5173SCK Hu 
619119f5173SCK Hu 	ret = mtk_drm_kms_init(drm);
620119f5173SCK Hu 	if (ret < 0)
621119f5173SCK Hu 		goto err_free;
622119f5173SCK Hu 
623119f5173SCK Hu 	ret = drm_dev_register(drm, 0);
624119f5173SCK Hu 	if (ret < 0)
625119f5173SCK Hu 		goto err_deinit;
626119f5173SCK Hu 
627c05ca218SThomas Zimmermann 	drm_fbdev_generic_setup(drm, 32);
628d6db988aSCK Hu 
629119f5173SCK Hu 	return 0;
630119f5173SCK Hu 
631119f5173SCK Hu err_deinit:
632119f5173SCK Hu 	mtk_drm_kms_deinit(drm);
633119f5173SCK Hu err_free:
63436aa8c61SNícolas F. R. A. Prado 	private->drm = NULL;
6358272806dSThomas Zimmermann 	drm_dev_put(drm);
636119f5173SCK Hu 	return ret;
637119f5173SCK Hu }
638119f5173SCK Hu 
mtk_drm_unbind(struct device * dev)639119f5173SCK Hu static void mtk_drm_unbind(struct device *dev)
640119f5173SCK Hu {
641119f5173SCK Hu 	struct mtk_drm_private *private = dev_get_drvdata(dev);
642119f5173SCK Hu 
6431ef7ed48SNancy.Lin 	/* for multi mmsys dev, unregister drm dev in mmsys master */
6441ef7ed48SNancy.Lin 	if (private->drm_master) {
645ae9d2daeSDaniel Vetter 		drm_dev_unregister(private->drm);
646f0fd8483SHsin-Yi Wang 		mtk_drm_kms_deinit(private->drm);
6478272806dSThomas Zimmermann 		drm_dev_put(private->drm);
6481ef7ed48SNancy.Lin 	}
6491ef7ed48SNancy.Lin 	private->mtk_drm_bound = false;
6501ef7ed48SNancy.Lin 	private->drm_master = false;
651119f5173SCK Hu 	private->drm = NULL;
652119f5173SCK Hu }
653119f5173SCK Hu 
654119f5173SCK Hu static const struct component_master_ops mtk_drm_ops = {
655119f5173SCK Hu 	.bind		= mtk_drm_bind,
656119f5173SCK Hu 	.unbind		= mtk_drm_unbind,
657119f5173SCK Hu };
658119f5173SCK Hu 
659119f5173SCK Hu static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
66073d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8167-disp-aal",
66173d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_AAL},
66273d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-disp-aal",
66373d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_AAL},
66473d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8183-disp-aal",
66573d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_AAL},
66673d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8192-disp-aal",
66773d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_AAL},
66858e4c539SFabien Parent 	{ .compatible = "mediatek,mt8167-disp-ccorr",
66958e4c539SFabien Parent 	  .data = (void *)MTK_DISP_CCORR },
670641ef9e7SYongqiang Niu 	{ .compatible = "mediatek,mt8183-disp-ccorr",
671641ef9e7SYongqiang Niu 	  .data = (void *)MTK_DISP_CCORR },
67201365f54SYongqiang Niu 	{ .compatible = "mediatek,mt8192-disp-ccorr",
67301365f54SYongqiang Niu 	  .data = (void *)MTK_DISP_CCORR },
6745a2fbbd8SCK Hu 	{ .compatible = "mediatek,mt2701-disp-color",
6755a2fbbd8SCK Hu 	  .data = (void *)MTK_DISP_COLOR },
67658e4c539SFabien Parent 	{ .compatible = "mediatek,mt8167-disp-color",
67758e4c539SFabien Parent 	  .data = (void *)MTK_DISP_COLOR },
6785a2fbbd8SCK Hu 	{ .compatible = "mediatek,mt8173-disp-color",
6795a2fbbd8SCK Hu 	  .data = (void *)MTK_DISP_COLOR },
68073d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8167-disp-dither",
68173d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_DITHER },
68273d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8183-disp-dither",
68373d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_DITHER },
6847266e90aSjason-jh.lin 	{ .compatible = "mediatek,mt8195-disp-dsc",
6857266e90aSjason-jh.lin 	  .data = (void *)MTK_DISP_DSC },
68658e4c539SFabien Parent 	{ .compatible = "mediatek,mt8167-disp-gamma",
68758e4c539SFabien Parent 	  .data = (void *)MTK_DISP_GAMMA, },
6885a2fbbd8SCK Hu 	{ .compatible = "mediatek,mt8173-disp-gamma",
6895a2fbbd8SCK Hu 	  .data = (void *)MTK_DISP_GAMMA, },
690641ef9e7SYongqiang Niu 	{ .compatible = "mediatek,mt8183-disp-gamma",
691641ef9e7SYongqiang Niu 	  .data = (void *)MTK_DISP_GAMMA, },
6927266e90aSjason-jh.lin 	{ .compatible = "mediatek,mt8195-disp-merge",
6937266e90aSjason-jh.lin 	  .data = (void *)MTK_DISP_MERGE },
6945a2fbbd8SCK Hu 	{ .compatible = "mediatek,mt2701-disp-mutex",
6955a2fbbd8SCK Hu 	  .data = (void *)MTK_DISP_MUTEX },
696e6ab087aSstu.hsieh@mediatek.com 	{ .compatible = "mediatek,mt2712-disp-mutex",
697e6ab087aSstu.hsieh@mediatek.com 	  .data = (void *)MTK_DISP_MUTEX },
69858e4c539SFabien Parent 	{ .compatible = "mediatek,mt8167-disp-mutex",
69958e4c539SFabien Parent 	  .data = (void *)MTK_DISP_MUTEX },
7005a2fbbd8SCK Hu 	{ .compatible = "mediatek,mt8173-disp-mutex",
7015a2fbbd8SCK Hu 	  .data = (void *)MTK_DISP_MUTEX },
702641ef9e7SYongqiang Niu 	{ .compatible = "mediatek,mt8183-disp-mutex",
703641ef9e7SYongqiang Niu 	  .data = (void *)MTK_DISP_MUTEX },
704885a0d09SYongqiang Niu 	{ .compatible = "mediatek,mt8186-disp-mutex",
705885a0d09SYongqiang Niu 	  .data = (void *)MTK_DISP_MUTEX },
70654b48080SNathan Lu 	{ .compatible = "mediatek,mt8188-disp-mutex",
70754b48080SNathan Lu 	  .data = (void *)MTK_DISP_MUTEX },
70801365f54SYongqiang Niu 	{ .compatible = "mediatek,mt8192-disp-mutex",
70901365f54SYongqiang Niu 	  .data = (void *)MTK_DISP_MUTEX },
7107266e90aSjason-jh.lin 	{ .compatible = "mediatek,mt8195-disp-mutex",
7117266e90aSjason-jh.lin 	  .data = (void *)MTK_DISP_MUTEX },
71273d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-disp-od",
71373d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OD },
71473d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt2701-disp-ovl",
71573d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OVL },
71673d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8167-disp-ovl",
71773d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OVL },
71873d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-disp-ovl",
71973d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OVL },
72073d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8183-disp-ovl",
72173d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OVL },
72273d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8192-disp-ovl",
72373d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OVL },
72417650925SHsiao Chien Sung 	{ .compatible = "mediatek,mt8195-disp-ovl",
72517650925SHsiao Chien Sung 	  .data = (void *)MTK_DISP_OVL },
72673d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
72773d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OVL_2L },
72873d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
72973d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_OVL_2L },
73073d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8192-disp-postmask",
73173d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_POSTMASK },
7325a2fbbd8SCK Hu 	{ .compatible = "mediatek,mt2701-disp-pwm",
7335a2fbbd8SCK Hu 	  .data = (void *)MTK_DISP_BLS },
73458e4c539SFabien Parent 	{ .compatible = "mediatek,mt8167-disp-pwm",
73558e4c539SFabien Parent 	  .data = (void *)MTK_DISP_PWM },
7365a2fbbd8SCK Hu 	{ .compatible = "mediatek,mt8173-disp-pwm",
7375a2fbbd8SCK Hu 	  .data = (void *)MTK_DISP_PWM },
73873d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt2701-disp-rdma",
73973d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_RDMA },
74073d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8167-disp-rdma",
74173d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_RDMA },
74273d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-disp-rdma",
74373d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_RDMA },
74473d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8183-disp-rdma",
74573d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_RDMA },
7467266e90aSjason-jh.lin 	{ .compatible = "mediatek,mt8195-disp-rdma",
7477266e90aSjason-jh.lin 	  .data = (void *)MTK_DISP_RDMA },
74873d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-disp-ufoe",
74973d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_UFOE },
75073d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-disp-wdma",
75173d37247Sjason-jh.lin 	  .data = (void *)MTK_DISP_WDMA },
75273d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt2701-dpi",
75373d37247Sjason-jh.lin 	  .data = (void *)MTK_DPI },
75473d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8167-dsi",
75573d37247Sjason-jh.lin 	  .data = (void *)MTK_DSI },
75673d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-dpi",
75773d37247Sjason-jh.lin 	  .data = (void *)MTK_DPI },
75873d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8183-dpi",
75973d37247Sjason-jh.lin 	  .data = (void *)MTK_DPI },
760e15b0e6dSXinlei Lee 	{ .compatible = "mediatek,mt8186-dpi",
761e15b0e6dSXinlei Lee 	  .data = (void *)MTK_DPI },
7622847cd7eSxinlei lee 	{ .compatible = "mediatek,mt8188-dp-intf",
7632847cd7eSxinlei lee 	  .data = (void *)MTK_DP_INTF },
764cfab37ffSChen-Yu Tsai 	{ .compatible = "mediatek,mt8192-dpi",
765cfab37ffSChen-Yu Tsai 	  .data = (void *)MTK_DPI },
766d86c1568SGuillaume Ranquet 	{ .compatible = "mediatek,mt8195-dp-intf",
767d86c1568SGuillaume Ranquet 	  .data = (void *)MTK_DP_INTF },
76873d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt2701-dsi",
76973d37247Sjason-jh.lin 	  .data = (void *)MTK_DSI },
77073d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8173-dsi",
77173d37247Sjason-jh.lin 	  .data = (void *)MTK_DSI },
77273d37247Sjason-jh.lin 	{ .compatible = "mediatek,mt8183-dsi",
77373d37247Sjason-jh.lin 	  .data = (void *)MTK_DSI },
7745bb4f807SRex-BC Chen 	{ .compatible = "mediatek,mt8186-dsi",
7755bb4f807SRex-BC Chen 	  .data = (void *)MTK_DSI },
776119f5173SCK Hu 	{ }
777119f5173SCK Hu };
778119f5173SCK Hu 
mtk_drm_probe(struct platform_device * pdev)779119f5173SCK Hu static int mtk_drm_probe(struct platform_device *pdev)
780119f5173SCK Hu {
781119f5173SCK Hu 	struct device *dev = &pdev->dev;
782667c7692SEnric Balletbo i Serra 	struct device_node *phandle = dev->parent->of_node;
783667c7692SEnric Balletbo i Serra 	const struct of_device_id *of_id;
784119f5173SCK Hu 	struct mtk_drm_private *private;
785119f5173SCK Hu 	struct device_node *node;
786119f5173SCK Hu 	struct component_match *match = NULL;
7870d9eee91SNancy.Lin 	struct platform_device *ovl_adaptor;
788119f5173SCK Hu 	int ret;
789119f5173SCK Hu 	int i;
790119f5173SCK Hu 
791119f5173SCK Hu 	private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
792119f5173SCK Hu 	if (!private)
793119f5173SCK Hu 		return -ENOMEM;
794119f5173SCK Hu 
7952c758e30SEnric Balletbo i Serra 	private->mmsys_dev = dev->parent;
7962c758e30SEnric Balletbo i Serra 	if (!private->mmsys_dev) {
7972c758e30SEnric Balletbo i Serra 		dev_err(dev, "Failed to get MMSYS device\n");
7982c758e30SEnric Balletbo i Serra 		return -ENODEV;
799119f5173SCK Hu 	}
800119f5173SCK Hu 
801667c7692SEnric Balletbo i Serra 	of_id = of_match_node(mtk_drm_of_ids, phandle);
802667c7692SEnric Balletbo i Serra 	if (!of_id)
803667c7692SEnric Balletbo i Serra 		return -ENODEV;
804667c7692SEnric Balletbo i Serra 
805813420ebSJason-JH.Lin 	private->data = of_id->data;
806667c7692SEnric Balletbo i Serra 
8071ef7ed48SNancy.Lin 	private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num,
8081ef7ed48SNancy.Lin 						      sizeof(*private->all_drm_private),
8091ef7ed48SNancy.Lin 						      GFP_KERNEL);
8101ef7ed48SNancy.Lin 	if (!private->all_drm_private)
8111ef7ed48SNancy.Lin 		return -ENOMEM;
8121ef7ed48SNancy.Lin 
8130d9eee91SNancy.Lin 	/* Bringup ovl_adaptor */
8140d9eee91SNancy.Lin 	if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVL_ADAPTOR)) {
8150d9eee91SNancy.Lin 		ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovl-adaptor",
8160d9eee91SNancy.Lin 							    PLATFORM_DEVID_AUTO,
8170d9eee91SNancy.Lin 							    (void *)private->mmsys_dev,
8180d9eee91SNancy.Lin 							    sizeof(*private->mmsys_dev));
8190d9eee91SNancy.Lin 		private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev = &ovl_adaptor->dev;
8200d9eee91SNancy.Lin 		mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR],
8210d9eee91SNancy.Lin 				  DDP_COMPONENT_DRM_OVL_ADAPTOR);
8220d9eee91SNancy.Lin 		component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
8230d9eee91SNancy.Lin 	}
8240d9eee91SNancy.Lin 
825119f5173SCK Hu 	/* Iterate over sibling DISP function blocks */
826667c7692SEnric Balletbo i Serra 	for_each_child_of_node(phandle->parent, node) {
827119f5173SCK Hu 		const struct of_device_id *of_id;
828119f5173SCK Hu 		enum mtk_ddp_comp_type comp_type;
829119f5173SCK Hu 		int comp_id;
830119f5173SCK Hu 
831119f5173SCK Hu 		of_id = of_match_node(mtk_ddp_comp_dt_ids, node);
832119f5173SCK Hu 		if (!of_id)
833119f5173SCK Hu 			continue;
834119f5173SCK Hu 
835119f5173SCK Hu 		if (!of_device_is_available(node)) {
8364bf99144SRob Herring 			dev_dbg(dev, "Skipping disabled component %pOF\n",
8374bf99144SRob Herring 				node);
838119f5173SCK Hu 			continue;
839119f5173SCK Hu 		}
840119f5173SCK Hu 
84189cba955SJason-JH.Lin 		comp_type = (enum mtk_ddp_comp_type)(uintptr_t)of_id->data;
842119f5173SCK Hu 
843119f5173SCK Hu 		if (comp_type == MTK_DISP_MUTEX) {
8441ef7ed48SNancy.Lin 			int id;
8451ef7ed48SNancy.Lin 
8461ef7ed48SNancy.Lin 			id = of_alias_get_id(node, "mutex");
8471ef7ed48SNancy.Lin 			if (id < 0 || id == private->data->mmsys_id) {
848119f5173SCK Hu 				private->mutex_node = of_node_get(node);
8491ef7ed48SNancy.Lin 				dev_dbg(dev, "get mutex for mmsys %d", private->data->mmsys_id);
8501ef7ed48SNancy.Lin 			}
851119f5173SCK Hu 			continue;
852119f5173SCK Hu 		}
853119f5173SCK Hu 
854119f5173SCK Hu 		comp_id = mtk_ddp_comp_get_id(node, comp_type);
855119f5173SCK Hu 		if (comp_id < 0) {
8564bf99144SRob Herring 			dev_warn(dev, "Skipping unknown component %pOF\n",
8574bf99144SRob Herring 				 node);
858119f5173SCK Hu 			continue;
859119f5173SCK Hu 		}
860119f5173SCK Hu 
8611ef7ed48SNancy.Lin 		if (!mtk_drm_find_mmsys_comp(private, comp_id))
8621ef7ed48SNancy.Lin 			continue;
8631ef7ed48SNancy.Lin 
864119f5173SCK Hu 		private->comp_node[comp_id] = of_node_get(node);
865119f5173SCK Hu 
866119f5173SCK Hu 		/*
867bd448b88Sjason-jh.lin 		 * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
868072a4cb5SYongqiang Niu 		 * blocks have separate component platform drivers and initialize their own
869119f5173SCK Hu 		 * DDP component structure. The others are initialized here.
870119f5173SCK Hu 		 */
87178d1783cSYongqiang Niu 		if (comp_type == MTK_DISP_AAL ||
87278d1783cSYongqiang Niu 		    comp_type == MTK_DISP_CCORR ||
873072a4cb5SYongqiang Niu 		    comp_type == MTK_DISP_COLOR ||
87469a4237aSYongqiang Niu 		    comp_type == MTK_DISP_GAMMA ||
875bd448b88Sjason-jh.lin 		    comp_type == MTK_DISP_MERGE ||
8765ac5895aSyt.shen@mediatek.com 		    comp_type == MTK_DISP_OVL ||
877b17bdd0dSYongqiang Niu 		    comp_type == MTK_DISP_OVL_2L ||
8780d9eee91SNancy.Lin 		    comp_type == MTK_DISP_OVL_ADAPTOR ||
879119f5173SCK Hu 		    comp_type == MTK_DISP_RDMA ||
880d86c1568SGuillaume Ranquet 		    comp_type == MTK_DP_INTF ||
88173d37247Sjason-jh.lin 		    comp_type == MTK_DPI ||
88273d37247Sjason-jh.lin 		    comp_type == MTK_DSI) {
8834bf99144SRob Herring 			dev_info(dev, "Adding component match for %pOF\n",
8844bf99144SRob Herring 				 node);
88505399aa0SYong Wu 			drm_of_component_match_add(dev, &match, component_compare_of,
88697ac0e47SRussell King 						   node);
887119f5173SCK Hu 		}
888119f5173SCK Hu 
889ff139560SCK Hu 		ret = mtk_ddp_comp_init(node, &private->ddp_comp[comp_id], comp_id);
890165d42c0SNishka Dasgupta 		if (ret) {
891165d42c0SNishka Dasgupta 			of_node_put(node);
892119f5173SCK Hu 			goto err_node;
893165d42c0SNishka Dasgupta 		}
894119f5173SCK Hu 	}
895119f5173SCK Hu 
896119f5173SCK Hu 	if (!private->mutex_node) {
897119f5173SCK Hu 		dev_err(dev, "Failed to find disp-mutex node\n");
898119f5173SCK Hu 		ret = -ENODEV;
899119f5173SCK Hu 		goto err_node;
900119f5173SCK Hu 	}
901119f5173SCK Hu 
902119f5173SCK Hu 	pm_runtime_enable(dev);
903119f5173SCK Hu 
904119f5173SCK Hu 	platform_set_drvdata(pdev, private);
905119f5173SCK Hu 
906119f5173SCK Hu 	ret = component_master_add_with_match(dev, &mtk_drm_ops, match);
907119f5173SCK Hu 	if (ret)
908119f5173SCK Hu 		goto err_pm;
909119f5173SCK Hu 
910119f5173SCK Hu 	return 0;
911119f5173SCK Hu 
912119f5173SCK Hu err_pm:
913119f5173SCK Hu 	pm_runtime_disable(dev);
914119f5173SCK Hu err_node:
915119f5173SCK Hu 	of_node_put(private->mutex_node);
9160d9eee91SNancy.Lin 	for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
917119f5173SCK Hu 		of_node_put(private->comp_node[i]);
918119f5173SCK Hu 	return ret;
919119f5173SCK Hu }
920119f5173SCK Hu 
mtk_drm_remove(struct platform_device * pdev)921b3af12a0SUwe Kleine-König static void mtk_drm_remove(struct platform_device *pdev)
922119f5173SCK Hu {
923119f5173SCK Hu 	struct mtk_drm_private *private = platform_get_drvdata(pdev);
924119f5173SCK Hu 	int i;
925119f5173SCK Hu 
926119f5173SCK Hu 	component_master_del(&pdev->dev, &mtk_drm_ops);
927119f5173SCK Hu 	pm_runtime_disable(&pdev->dev);
928119f5173SCK Hu 	of_node_put(private->mutex_node);
9290d9eee91SNancy.Lin 	for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
930119f5173SCK Hu 		of_node_put(private->comp_node[i]);
931119f5173SCK Hu }
932119f5173SCK Hu 
mtk_drm_shutdown(struct platform_device * pdev)933b241d17aSDouglas Anderson static void mtk_drm_shutdown(struct platform_device *pdev)
934b241d17aSDouglas Anderson {
935b241d17aSDouglas Anderson 	struct mtk_drm_private *private = platform_get_drvdata(pdev);
936b241d17aSDouglas Anderson 
937b241d17aSDouglas Anderson 	drm_atomic_helper_shutdown(private->drm);
938b241d17aSDouglas Anderson }
939b241d17aSDouglas Anderson 
mtk_drm_sys_prepare(struct device * dev)9400f15d785SHsin-Yi Wang static int mtk_drm_sys_prepare(struct device *dev)
941119f5173SCK Hu {
942119f5173SCK Hu 	struct mtk_drm_private *private = dev_get_drvdata(dev);
943119f5173SCK Hu 	struct drm_device *drm = private->drm;
944119f5173SCK Hu 
9451ef7ed48SNancy.Lin 	if (private->drm_master)
9469d3feb63Sye xingchen 		return drm_mode_config_helper_suspend(drm);
9471ef7ed48SNancy.Lin 	else
9481ef7ed48SNancy.Lin 		return 0;
949119f5173SCK Hu }
950119f5173SCK Hu 
mtk_drm_sys_complete(struct device * dev)9510f15d785SHsin-Yi Wang static void mtk_drm_sys_complete(struct device *dev)
952119f5173SCK Hu {
953119f5173SCK Hu 	struct mtk_drm_private *private = dev_get_drvdata(dev);
954119f5173SCK Hu 	struct drm_device *drm = private->drm;
9551ef7ed48SNancy.Lin 	int ret = 0;
956119f5173SCK Hu 
9571ef7ed48SNancy.Lin 	if (private->drm_master)
9582b7bd20dSSouptick Joarder 		ret = drm_mode_config_helper_resume(drm);
9590f15d785SHsin-Yi Wang 	if (ret)
9600f15d785SHsin-Yi Wang 		dev_err(dev, "Failed to resume\n");
961119f5173SCK Hu }
962119f5173SCK Hu 
9630f15d785SHsin-Yi Wang static const struct dev_pm_ops mtk_drm_pm_ops = {
9640f15d785SHsin-Yi Wang 	.prepare = mtk_drm_sys_prepare,
9650f15d785SHsin-Yi Wang 	.complete = mtk_drm_sys_complete,
9660f15d785SHsin-Yi Wang };
967119f5173SCK Hu 
968119f5173SCK Hu static struct platform_driver mtk_drm_platform_driver = {
969119f5173SCK Hu 	.probe	= mtk_drm_probe,
970b3af12a0SUwe Kleine-König 	.remove_new = mtk_drm_remove,
971b241d17aSDouglas Anderson 	.shutdown = mtk_drm_shutdown,
972119f5173SCK Hu 	.driver	= {
973119f5173SCK Hu 		.name	= "mediatek-drm",
974119f5173SCK Hu 		.pm     = &mtk_drm_pm_ops,
975119f5173SCK Hu 	},
976119f5173SCK Hu };
977119f5173SCK Hu 
978119f5173SCK Hu static struct platform_driver * const mtk_drm_drivers[] = {
97978d1783cSYongqiang Niu 	&mtk_disp_aal_driver,
980072a4cb5SYongqiang Niu 	&mtk_disp_ccorr_driver,
9815ac5895aSyt.shen@mediatek.com 	&mtk_disp_color_driver,
98269a4237aSYongqiang Niu 	&mtk_disp_gamma_driver,
983bd448b88Sjason-jh.lin 	&mtk_disp_merge_driver,
9840d9eee91SNancy.Lin 	&mtk_disp_ovl_adaptor_driver,
985119f5173SCK Hu 	&mtk_disp_ovl_driver,
986119f5173SCK Hu 	&mtk_disp_rdma_driver,
9879e629c17SJie Qiu 	&mtk_dpi_driver,
988119f5173SCK Hu 	&mtk_drm_platform_driver,
9892f501cc0SJitao Shi 	&mtk_dsi_driver,
990d886c000SNancy.Lin 	&mtk_ethdr_driver,
991f8946e2bSNancy.Lin 	&mtk_mdp_rdma_driver,
992119f5173SCK Hu };
993119f5173SCK Hu 
mtk_drm_init(void)994119f5173SCK Hu static int __init mtk_drm_init(void)
995119f5173SCK Hu {
996446b8c54SPhilipp Zabel 	return platform_register_drivers(mtk_drm_drivers,
997446b8c54SPhilipp Zabel 					 ARRAY_SIZE(mtk_drm_drivers));
998119f5173SCK Hu }
999119f5173SCK Hu 
mtk_drm_exit(void)1000119f5173SCK Hu static void __exit mtk_drm_exit(void)
1001119f5173SCK Hu {
1002446b8c54SPhilipp Zabel 	platform_unregister_drivers(mtk_drm_drivers,
1003446b8c54SPhilipp Zabel 				    ARRAY_SIZE(mtk_drm_drivers));
1004119f5173SCK Hu }
1005119f5173SCK Hu 
1006119f5173SCK Hu module_init(mtk_drm_init);
1007119f5173SCK Hu module_exit(mtk_drm_exit);
1008119f5173SCK Hu 
1009119f5173SCK Hu MODULE_AUTHOR("YT SHEN <yt.shen@mediatek.com>");
1010119f5173SCK Hu MODULE_DESCRIPTION("Mediatek SoC DRM driver");
1011119f5173SCK Hu MODULE_LICENSE("GPL v2");
1012