xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vconn.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun #include <drm/drm_of.h>
3*4882a593Smuzhiyun #include <drm/drm_crtc_helper.h>
4*4882a593Smuzhiyun #include <drm/drm_probe_helper.h>
5*4882a593Smuzhiyun #include <drm/drm_simple_kms_helper.h>
6*4882a593Smuzhiyun #include <linux/component.h>
7*4882a593Smuzhiyun #include <linux/module.h>
8*4882a593Smuzhiyun #include <linux/platform_device.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "rockchip_drm_drv.h"
11*4882a593Smuzhiyun #include "rockchip_drm_vop.h"
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define XRES_DEF  1920
14*4882a593Smuzhiyun #define YRES_DEF  1080
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun struct vconn_device {
17*4882a593Smuzhiyun 	struct rockchip_vconn *vconn;
18*4882a593Smuzhiyun 	struct drm_encoder encoder;
19*4882a593Smuzhiyun 	struct drm_connector connector;
20*4882a593Smuzhiyun 	struct list_head list;
21*4882a593Smuzhiyun 	int encoder_type;
22*4882a593Smuzhiyun 	int output_type;
23*4882a593Smuzhiyun 	int output_mode;
24*4882a593Smuzhiyun 	int bus_format;
25*4882a593Smuzhiyun 	int if_id;
26*4882a593Smuzhiyun 	int vp_id_mask;
27*4882a593Smuzhiyun 	bool connected;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun struct rockchip_vconn {
31*4882a593Smuzhiyun 	struct device *dev;
32*4882a593Smuzhiyun 	struct drm_device *drm_dev;
33*4882a593Smuzhiyun 	struct platform_device *pdev;
34*4882a593Smuzhiyun 	struct list_head list_head;
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define to_vconn_device(x)	container_of(x, struct vconn_device, x)
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun static const struct drm_display_mode edid_cea_modes_1[] = {
40*4882a593Smuzhiyun 	/* 1 - 640x480@60Hz 4:3 */
41*4882a593Smuzhiyun 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
42*4882a593Smuzhiyun 		   752, 800, 0, 480, 490, 492, 525, 0,
43*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
44*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
45*4882a593Smuzhiyun 	/* 2 - 720x480@60Hz 4:3 */
46*4882a593Smuzhiyun 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
47*4882a593Smuzhiyun 		   798, 858, 0, 480, 489, 495, 525, 0,
48*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
49*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
50*4882a593Smuzhiyun 	/* 3 - 720x480@60Hz 16:9 */
51*4882a593Smuzhiyun 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
52*4882a593Smuzhiyun 		   798, 858, 0, 480, 489, 495, 525, 0,
53*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
54*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
55*4882a593Smuzhiyun 	/* 4 - 1280x720@60Hz 16:9 */
56*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
57*4882a593Smuzhiyun 		   1430, 1650, 0, 720, 725, 730, 750, 0,
58*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
59*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
60*4882a593Smuzhiyun 	/* 5 - 1920x1080i@60Hz 16:9 */
61*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
62*4882a593Smuzhiyun 		   2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
63*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
64*4882a593Smuzhiyun 		   DRM_MODE_FLAG_INTERLACE),
65*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
66*4882a593Smuzhiyun 	/* 6 - 720(1440)x480i@60Hz 4:3 */
67*4882a593Smuzhiyun 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
68*4882a593Smuzhiyun 		   801, 858, 0, 480, 488, 494, 525, 0,
69*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
70*4882a593Smuzhiyun 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
71*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
72*4882a593Smuzhiyun 	/* 7 - 720(1440)x480i@60Hz 16:9 */
73*4882a593Smuzhiyun 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
74*4882a593Smuzhiyun 		   801, 858, 0, 480, 488, 494, 525, 0,
75*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
76*4882a593Smuzhiyun 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
77*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
78*4882a593Smuzhiyun 	/* 16 - 1920x1080@60Hz 16:9 */
79*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
80*4882a593Smuzhiyun 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
81*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
82*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
83*4882a593Smuzhiyun 	/* 17 - 720x576@50Hz 4:3 */
84*4882a593Smuzhiyun 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
85*4882a593Smuzhiyun 		   796, 864, 0, 576, 581, 586, 625, 0,
86*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
87*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
88*4882a593Smuzhiyun 	/* 18 - 720x576@50Hz 16:9 */
89*4882a593Smuzhiyun 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
90*4882a593Smuzhiyun 		   796, 864, 0, 576, 581, 586, 625, 0,
91*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
92*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
93*4882a593Smuzhiyun 	/* 19 - 1280x720@50Hz 16:9 */
94*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
95*4882a593Smuzhiyun 		   1760, 1980, 0, 720, 725, 730, 750, 0,
96*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
97*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
98*4882a593Smuzhiyun 	/* 20 - 1920x1080i@50Hz 16:9 */
99*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
100*4882a593Smuzhiyun 		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
101*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
102*4882a593Smuzhiyun 		   DRM_MODE_FLAG_INTERLACE),
103*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
104*4882a593Smuzhiyun 	/* 21 - 720(1440)x576i@50Hz 4:3 */
105*4882a593Smuzhiyun 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
106*4882a593Smuzhiyun 		   795, 864, 0, 576, 580, 586, 625, 0,
107*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
108*4882a593Smuzhiyun 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
109*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
110*4882a593Smuzhiyun 	/* 22 - 720(1440)x576i@50Hz 16:9 */
111*4882a593Smuzhiyun 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
112*4882a593Smuzhiyun 		   795, 864, 0, 576, 580, 586, 625, 0,
113*4882a593Smuzhiyun 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
114*4882a593Smuzhiyun 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
115*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
116*4882a593Smuzhiyun 	/* 31 - 1920x1080@50Hz 16:9 */
117*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
118*4882a593Smuzhiyun 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
119*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
120*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
121*4882a593Smuzhiyun 	/* 34 - 1920x1080@30Hz 16:9 */
122*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
123*4882a593Smuzhiyun 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
124*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
125*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
126*4882a593Smuzhiyun 	/* 39 - 1920x1080i@50Hz 16:9 */
127*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
128*4882a593Smuzhiyun 		   2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
129*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
130*4882a593Smuzhiyun 		   DRM_MODE_FLAG_INTERLACE),
131*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
132*4882a593Smuzhiyun 	/* 62 - 1280x720@30Hz 16:9 */
133*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
134*4882a593Smuzhiyun 		   3080, 3300, 0, 720, 725, 730, 750, 0,
135*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
136*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
137*4882a593Smuzhiyun 	/* 63 - 1920x1080@120Hz 16:9 */
138*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
139*4882a593Smuzhiyun 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
140*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
141*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
142*4882a593Smuzhiyun 	/* 67 - 1280x720@30Hz 64:27 */
143*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
144*4882a593Smuzhiyun 		   3080, 3300, 0, 720, 725, 730, 750, 0,
145*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
146*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
147*4882a593Smuzhiyun 	/* 68 - 1280x720@50Hz 64:27 */
148*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
149*4882a593Smuzhiyun 		   1760, 1980, 0, 720, 725, 730, 750, 0,
150*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
151*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
152*4882a593Smuzhiyun 	/* 69 - 1280x720@60Hz 64:27 */
153*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
154*4882a593Smuzhiyun 		   1430, 1650, 0, 720, 725, 730, 750, 0,
155*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
156*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
157*4882a593Smuzhiyun 	/* 70 - 1280x720@100Hz 64:27 */
158*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
159*4882a593Smuzhiyun 		   1760, 1980, 0, 720, 725, 730, 750, 0,
160*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
161*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
162*4882a593Smuzhiyun 	/* 71 - 1280x720@120Hz 64:27 */
163*4882a593Smuzhiyun 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
164*4882a593Smuzhiyun 		   1430, 1650, 0, 720, 725, 730, 750, 0,
165*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
166*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
167*4882a593Smuzhiyun 	/* 74 - 1920x1080@30Hz 64:27 */
168*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
169*4882a593Smuzhiyun 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
170*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
171*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
172*4882a593Smuzhiyun 	/* 75 - 1920x1080@50Hz 64:27 */
173*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
174*4882a593Smuzhiyun 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
175*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
176*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
177*4882a593Smuzhiyun 	/* 76 - 1920x1080@60Hz 64:27 */
178*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
179*4882a593Smuzhiyun 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
180*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
181*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
182*4882a593Smuzhiyun 	/* 77 - 1920x1080@100Hz 64:27 */
183*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
184*4882a593Smuzhiyun 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
185*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
186*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
187*4882a593Smuzhiyun 	/* 78 - 1920x1080@120Hz 64:27 */
188*4882a593Smuzhiyun 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
189*4882a593Smuzhiyun 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
190*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
191*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
192*4882a593Smuzhiyun 	/* 95 - 3840x2160@30Hz 16:9 */
193*4882a593Smuzhiyun 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
194*4882a593Smuzhiyun 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
195*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
196*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
197*4882a593Smuzhiyun 	/* 96 - 3840x2160@50Hz 16:9 */
198*4882a593Smuzhiyun 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
199*4882a593Smuzhiyun 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
200*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
201*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
202*4882a593Smuzhiyun 	/* 97 - 3840x2160@60Hz 16:9 */
203*4882a593Smuzhiyun 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
204*4882a593Smuzhiyun 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
205*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
206*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
207*4882a593Smuzhiyun 	/* 100 - 4096x2160@30Hz 256:135 */
208*4882a593Smuzhiyun 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
209*4882a593Smuzhiyun 		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
210*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
211*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
212*4882a593Smuzhiyun 	/* 101 - 4096x2160@50Hz 256:135 */
213*4882a593Smuzhiyun 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5064,
214*4882a593Smuzhiyun 		   5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
215*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
216*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
217*4882a593Smuzhiyun 	/* 102 - 4096x2160@60Hz 256:135 */
218*4882a593Smuzhiyun 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
219*4882a593Smuzhiyun 		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
220*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
221*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
222*4882a593Smuzhiyun 	/* 105 - 3840x2160@30Hz 64:27 */
223*4882a593Smuzhiyun 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
224*4882a593Smuzhiyun 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
225*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
226*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
227*4882a593Smuzhiyun 	/* 106 - 3840x2160@50Hz 64:27 */
228*4882a593Smuzhiyun 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
229*4882a593Smuzhiyun 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
230*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
231*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
232*4882a593Smuzhiyun 	/* 107 - 3840x2160@60Hz 64:27 */
233*4882a593Smuzhiyun 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
234*4882a593Smuzhiyun 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
235*4882a593Smuzhiyun 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
236*4882a593Smuzhiyun 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
237*4882a593Smuzhiyun };
238*4882a593Smuzhiyun 
vconn_drm_add_modes_noedid(struct drm_connector * connector)239*4882a593Smuzhiyun static int vconn_drm_add_modes_noedid(struct drm_connector *connector)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	struct drm_device *dev = connector->dev;
242*4882a593Smuzhiyun 	struct drm_display_mode *mode;
243*4882a593Smuzhiyun 	int i, count, num_modes = 0;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	count = ARRAY_SIZE(edid_cea_modes_1);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
248*4882a593Smuzhiyun 		const struct drm_display_mode *ptr = &edid_cea_modes_1[i];
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 		mode = drm_mode_duplicate(dev, ptr);
251*4882a593Smuzhiyun 		if (mode) {
252*4882a593Smuzhiyun 			drm_mode_probed_add(connector, mode);
253*4882a593Smuzhiyun 			num_modes++;
254*4882a593Smuzhiyun 		}
255*4882a593Smuzhiyun 	}
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	return num_modes;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
rockchip_virtual_encoder_enable(struct drm_encoder * encoder)260*4882a593Smuzhiyun static void rockchip_virtual_encoder_enable(struct drm_encoder *encoder)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	struct vconn_device *vconn_dev = to_vconn_device(encoder);
263*4882a593Smuzhiyun 	struct rockchip_vconn *vconn = vconn_dev->vconn;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	dev_info(vconn->dev, "encoder enable for output%d\n", ffs(vconn_dev->if_id) - 1);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun 
rockchip_virtual_encoder_disable(struct drm_encoder * encoder)268*4882a593Smuzhiyun static void rockchip_virtual_encoder_disable(struct drm_encoder *encoder)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun 	struct vconn_device *vconn_dev = to_vconn_device(encoder);
271*4882a593Smuzhiyun 	struct rockchip_vconn *vconn = vconn_dev->vconn;
272*4882a593Smuzhiyun 	struct drm_crtc *crtc = encoder->crtc;
273*4882a593Smuzhiyun 	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	vcstate->output_if &= ~vconn_dev->if_id;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	dev_info(vconn->dev, "encoder disable for output%d\n", ffs(vconn_dev->if_id) - 1);
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun 
rockchip_virtual_encoder_atomic_check(struct drm_encoder * encoder,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state)280*4882a593Smuzhiyun static int rockchip_virtual_encoder_atomic_check(struct drm_encoder *encoder,
281*4882a593Smuzhiyun 						 struct drm_crtc_state *crtc_state,
282*4882a593Smuzhiyun 						 struct drm_connector_state *conn_state)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	return 0;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun 
rockchip_virtual_encoder_mode_set(struct drm_encoder * encoder,struct drm_display_mode * mode,struct drm_display_mode * adj)287*4882a593Smuzhiyun static void rockchip_virtual_encoder_mode_set(struct drm_encoder *encoder,
288*4882a593Smuzhiyun 					      struct drm_display_mode *mode,
289*4882a593Smuzhiyun 					      struct drm_display_mode *adj)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	struct drm_crtc *crtc = encoder->crtc;
292*4882a593Smuzhiyun 	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
293*4882a593Smuzhiyun 	struct vconn_device *vconn_dev = to_vconn_device(encoder);
294*4882a593Smuzhiyun 	struct rockchip_vconn *vconn = vconn_dev->vconn;
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	vcstate->output_if |= vconn_dev->if_id;
297*4882a593Smuzhiyun 	vcstate->output_mode = vconn_dev->output_mode;
298*4882a593Smuzhiyun 	vcstate->output_type = vconn_dev->output_type;
299*4882a593Smuzhiyun 	vcstate->bus_format = vconn_dev->bus_format;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	dev_info(vconn->dev, "mode set for output%d\n", ffs(vconn_dev->if_id) - 1);
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun static const struct drm_encoder_helper_funcs rockchip_virtual_encoder_helper_funcs = {
305*4882a593Smuzhiyun 	.enable     = rockchip_virtual_encoder_enable,
306*4882a593Smuzhiyun 	.disable    = rockchip_virtual_encoder_disable,
307*4882a593Smuzhiyun 	.atomic_check = rockchip_virtual_encoder_atomic_check,
308*4882a593Smuzhiyun 	.mode_set = rockchip_virtual_encoder_mode_set,
309*4882a593Smuzhiyun };
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun static enum drm_connector_status
rockchip_virtual_connector_detect(struct drm_connector * connector,bool force)312*4882a593Smuzhiyun rockchip_virtual_connector_detect(struct drm_connector *connector, bool force)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun 	struct vconn_device *vconn_dev = to_vconn_device(connector);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	if (vconn_dev->output_type == DRM_MODE_CONNECTOR_VIRTUAL)
317*4882a593Smuzhiyun 		return vconn_dev->connected ? connector_status_connected :
318*4882a593Smuzhiyun 					      connector_status_disconnected;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	return connector_status_connected;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
rockchip_virtual_connector_destroy(struct drm_connector * connector)323*4882a593Smuzhiyun static void rockchip_virtual_connector_destroy(struct drm_connector *connector)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun 	drm_connector_unregister(connector);
326*4882a593Smuzhiyun 	drm_connector_cleanup(connector);
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun static const struct drm_connector_funcs rockchip_virtual_connector_funcs = {
330*4882a593Smuzhiyun 	.detect = rockchip_virtual_connector_detect,
331*4882a593Smuzhiyun 	.fill_modes = drm_helper_probe_single_connector_modes,
332*4882a593Smuzhiyun 	.destroy = rockchip_virtual_connector_destroy,
333*4882a593Smuzhiyun 	.reset = drm_atomic_helper_connector_reset,
334*4882a593Smuzhiyun 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
335*4882a593Smuzhiyun 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
336*4882a593Smuzhiyun };
337*4882a593Smuzhiyun 
vvop_conn_get_modes(struct drm_connector * connector)338*4882a593Smuzhiyun static int vvop_conn_get_modes(struct drm_connector *connector)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun 	int count;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	count = vconn_drm_add_modes_noedid(connector);
343*4882a593Smuzhiyun 	drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	return count;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun static const struct drm_connector_helper_funcs rockchip_virtual_connector_helper_funcs = {
349*4882a593Smuzhiyun 	.get_modes    = vvop_conn_get_modes,
350*4882a593Smuzhiyun };
351*4882a593Smuzhiyun 
rockchip_virtual_connector_register(struct rockchip_vconn * vconn)352*4882a593Smuzhiyun static int rockchip_virtual_connector_register(struct rockchip_vconn *vconn)
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun 	struct vconn_device *vconn_dev, *n;
355*4882a593Smuzhiyun 	struct drm_encoder *encoder;
356*4882a593Smuzhiyun 	struct drm_connector *connector;
357*4882a593Smuzhiyun 	int ret;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	list_for_each_entry_safe(vconn_dev, n, &vconn->list_head, list) {
360*4882a593Smuzhiyun 		encoder = &vconn_dev->encoder;
361*4882a593Smuzhiyun 		connector = &vconn_dev->connector;
362*4882a593Smuzhiyun 		encoder->possible_crtcs = vconn_dev->vp_id_mask;
363*4882a593Smuzhiyun 		drm_encoder_helper_add(encoder, &rockchip_virtual_encoder_helper_funcs);
364*4882a593Smuzhiyun 		ret = drm_simple_encoder_init(vconn->drm_dev, encoder, vconn_dev->encoder_type);
365*4882a593Smuzhiyun 		if (ret < 0) {
366*4882a593Smuzhiyun 			dev_err(vconn->dev, "failed to register encoder for output%d",
367*4882a593Smuzhiyun 				ffs(vconn_dev->if_id) - 1);
368*4882a593Smuzhiyun 			return ret;
369*4882a593Smuzhiyun 		}
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 		drm_connector_helper_add(connector, &rockchip_virtual_connector_helper_funcs);
372*4882a593Smuzhiyun 		ret = drm_connector_init(vconn->drm_dev, connector,
373*4882a593Smuzhiyun 					 &rockchip_virtual_connector_funcs, vconn_dev->output_type);
374*4882a593Smuzhiyun 		if (ret) {
375*4882a593Smuzhiyun 			dev_err(vconn->dev, "Failed to initialize connector for output%d\n",
376*4882a593Smuzhiyun 				ffs(vconn_dev->if_id) - 1);
377*4882a593Smuzhiyun 			return ret;
378*4882a593Smuzhiyun 		}
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 		drm_connector_attach_encoder(connector, encoder);
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	return 0;
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun 
rockchip_vconn_parse_vp_id(struct rockchip_vconn * vconn,const char * name)386*4882a593Smuzhiyun static int rockchip_vconn_parse_vp_id(struct rockchip_vconn *vconn, const char *name)
387*4882a593Smuzhiyun {
388*4882a593Smuzhiyun 	struct device_node *np = vconn->dev->of_node;
389*4882a593Smuzhiyun 	char propname[16];
390*4882a593Smuzhiyun 	int ret;
391*4882a593Smuzhiyun 	u32 id;
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	if (strlen(name) > 6) {
394*4882a593Smuzhiyun 		dev_err(vconn->dev, "invalid connector name %s\n", name);
395*4882a593Smuzhiyun 		return -EINVAL;
396*4882a593Smuzhiyun 	}
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	snprintf(propname, sizeof(propname), "%s-enable", name);
399*4882a593Smuzhiyun 	if (of_property_read_bool(np, propname)) {
400*4882a593Smuzhiyun 		snprintf(propname, sizeof(propname), "%s-vp-id", name);
401*4882a593Smuzhiyun 		ret = of_property_read_u32(np, propname, &id);
402*4882a593Smuzhiyun 		if (ret < 0) {
403*4882a593Smuzhiyun 			dev_err(vconn->dev, "no specific vp-id for %s\n", name);
404*4882a593Smuzhiyun 			return ret;
405*4882a593Smuzhiyun 		}
406*4882a593Smuzhiyun 		return id;
407*4882a593Smuzhiyun 	}
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	return -ENODEV;
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun 
rockchip_vconn_get_encoder_type(int conn_type)412*4882a593Smuzhiyun static int rockchip_vconn_get_encoder_type(int conn_type)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun 	if (conn_type == DRM_MODE_CONNECTOR_DSI)
415*4882a593Smuzhiyun 		return DRM_MODE_ENCODER_DSI;
416*4882a593Smuzhiyun 	else if (conn_type == DRM_MODE_CONNECTOR_DPI)
417*4882a593Smuzhiyun 		return DRM_MODE_ENCODER_DPI;
418*4882a593Smuzhiyun 	else if (conn_type == DRM_MODE_CONNECTOR_VIRTUAL)
419*4882a593Smuzhiyun 		return DRM_MODE_ENCODER_VIRTUAL;
420*4882a593Smuzhiyun 	else
421*4882a593Smuzhiyun 		return DRM_MODE_ENCODER_TMDS;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun 
rockchip_vconn_device_create(struct rockchip_vconn * vconn,const char * name,int conn_type,int output_mode,int bus_format,int if_id)424*4882a593Smuzhiyun static int rockchip_vconn_device_create(struct rockchip_vconn *vconn,
425*4882a593Smuzhiyun 					const char *name,
426*4882a593Smuzhiyun 					int conn_type,
427*4882a593Smuzhiyun 					int output_mode,
428*4882a593Smuzhiyun 					int bus_format,
429*4882a593Smuzhiyun 					int if_id)
430*4882a593Smuzhiyun {
431*4882a593Smuzhiyun 	struct vconn_device *vconn_dev;
432*4882a593Smuzhiyun 	int id;
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	id = rockchip_vconn_parse_vp_id(vconn, name);
435*4882a593Smuzhiyun 	if (id >= 0) {
436*4882a593Smuzhiyun 		vconn_dev = devm_kzalloc(vconn->dev, sizeof(*vconn_dev), GFP_KERNEL);
437*4882a593Smuzhiyun 		if (!vconn_dev)
438*4882a593Smuzhiyun 			return -ENOMEM;
439*4882a593Smuzhiyun 		vconn_dev->vconn = vconn;
440*4882a593Smuzhiyun 		vconn_dev->encoder_type = rockchip_vconn_get_encoder_type(conn_type);
441*4882a593Smuzhiyun 		vconn_dev->output_type = conn_type;
442*4882a593Smuzhiyun 		vconn_dev->output_mode = output_mode;
443*4882a593Smuzhiyun 		vconn_dev->bus_format = bus_format;
444*4882a593Smuzhiyun 		vconn_dev->if_id = if_id;
445*4882a593Smuzhiyun 		vconn_dev->vp_id_mask = BIT(id);
446*4882a593Smuzhiyun 		list_add_tail(&vconn_dev->list, &vconn->list_head);
447*4882a593Smuzhiyun 	}
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	return 0;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun 
rockchip_virtual_connectors_create(struct rockchip_vconn * vconn)452*4882a593Smuzhiyun static int rockchip_virtual_connectors_create(struct rockchip_vconn *vconn)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun 	struct device_node *np = vconn->dev->of_node;
455*4882a593Smuzhiyun 	struct vconn_device *vconn_dev;
456*4882a593Smuzhiyun 	char propname[64];
457*4882a593Smuzhiyun 	u32 count;
458*4882a593Smuzhiyun 	int i;
459*4882a593Smuzhiyun 	int ret;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	ret = of_property_read_u32(np, "virtual-connector-count", &count);
462*4882a593Smuzhiyun 	if (ret)
463*4882a593Smuzhiyun 		return ret;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
466*4882a593Smuzhiyun 		vconn_dev = devm_kzalloc(vconn->dev, sizeof(*vconn_dev), GFP_KERNEL);
467*4882a593Smuzhiyun 		if (!vconn_dev)
468*4882a593Smuzhiyun 			return -ENOMEM;
469*4882a593Smuzhiyun 		snprintf(propname, sizeof(propname), "virtual%d-disconnected", i);
470*4882a593Smuzhiyun 		vconn_dev->connected = !of_property_read_bool(np, propname);
471*4882a593Smuzhiyun 		vconn_dev->vconn = vconn;
472*4882a593Smuzhiyun 		vconn_dev->encoder_type = DRM_MODE_ENCODER_VIRTUAL;
473*4882a593Smuzhiyun 		vconn_dev->output_type = DRM_MODE_CONNECTOR_VIRTUAL;
474*4882a593Smuzhiyun 		vconn_dev->output_mode = ROCKCHIP_OUT_MODE_AAAA;
475*4882a593Smuzhiyun 		vconn_dev->bus_format = MEDIA_BUS_FMT_FIXED;
476*4882a593Smuzhiyun 		vconn_dev->if_id = 0;
477*4882a593Smuzhiyun 		vconn_dev->vp_id_mask = 0;
478*4882a593Smuzhiyun 		list_add_tail(&vconn_dev->list, &vconn->list_head);
479*4882a593Smuzhiyun 	}
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	return 0;
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun 
rockchip_virtual_connector_bind(struct device * dev,struct device * master,void * data)484*4882a593Smuzhiyun static int rockchip_virtual_connector_bind(struct device *dev, struct device *master, void *data)
485*4882a593Smuzhiyun {
486*4882a593Smuzhiyun 	struct platform_device *pdev = to_platform_device(dev);
487*4882a593Smuzhiyun 	struct drm_device *drm = data;
488*4882a593Smuzhiyun 	struct rockchip_vconn *vconn;
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	if (!pdev->dev.of_node)
491*4882a593Smuzhiyun 		return -ENODEV;
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	vconn = devm_kzalloc(&pdev->dev, sizeof(*vconn), GFP_KERNEL);
494*4882a593Smuzhiyun 	if (!vconn)
495*4882a593Smuzhiyun 		return -ENOMEM;
496*4882a593Smuzhiyun 	vconn->dev = dev;
497*4882a593Smuzhiyun 	vconn->drm_dev = drm;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	INIT_LIST_HEAD(&vconn->list_head);
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "hdmi0", DRM_MODE_CONNECTOR_HDMIA,
502*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_AAAA, MEDIA_BUS_FMT_RGB888_1X24,
503*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_HDMI0);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "hdmi1", DRM_MODE_CONNECTOR_HDMIA,
506*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_AAAA, MEDIA_BUS_FMT_RGB888_1X24,
507*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_HDMI1);
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "dp0", DRM_MODE_CONNECTOR_DisplayPort,
510*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_AAAA, MEDIA_BUS_FMT_RGB888_1X24,
511*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_DP0);
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "dp1", DRM_MODE_CONNECTOR_DisplayPort,
514*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_AAAA, MEDIA_BUS_FMT_RGB888_1X24,
515*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_DP1);
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "edp0", DRM_MODE_CONNECTOR_eDP,
518*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_AAAA, MEDIA_BUS_FMT_RGB888_1X24,
519*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_eDP0);
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "edp0", DRM_MODE_CONNECTOR_eDP,
522*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_AAAA, MEDIA_BUS_FMT_RGB888_1X24,
523*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_eDP1);
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "mipi0", DRM_MODE_CONNECTOR_DSI,
526*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_P888, MEDIA_BUS_FMT_RGB888_1X24,
527*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_MIPI0);
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "mipi1", DRM_MODE_CONNECTOR_DSI,
530*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_P888, MEDIA_BUS_FMT_RGB888_1X24,
531*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_MIPI1);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 	rockchip_vconn_device_create(vconn, "rgb", DRM_MODE_CONNECTOR_DPI,
534*4882a593Smuzhiyun 				     ROCKCHIP_OUT_MODE_P888, MEDIA_BUS_FMT_RGB888_1X24,
535*4882a593Smuzhiyun 				     VOP_OUTPUT_IF_RGB);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	rockchip_virtual_connectors_create(vconn);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	platform_set_drvdata(pdev, vconn);
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	rockchip_virtual_connector_register(vconn);
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	return 0;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun 
rockchip_virtual_connector_unbind(struct device * dev,struct device * master,void * data)546*4882a593Smuzhiyun static void rockchip_virtual_connector_unbind(struct device *dev, struct device *master,
547*4882a593Smuzhiyun 					       void *data)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun static const struct component_ops rockchip_virtual_connector_ops = {
552*4882a593Smuzhiyun 	.bind	= rockchip_virtual_connector_bind,
553*4882a593Smuzhiyun 	.unbind	= rockchip_virtual_connector_unbind,
554*4882a593Smuzhiyun };
555*4882a593Smuzhiyun 
rockchip_virtual_connector_probe(struct platform_device * pdev)556*4882a593Smuzhiyun static int rockchip_virtual_connector_probe(struct platform_device *pdev)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun 	return component_add(&pdev->dev, &rockchip_virtual_connector_ops);
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun 
rockchip_virtual_connector_shutdown(struct platform_device * pdev)561*4882a593Smuzhiyun static void rockchip_virtual_connector_shutdown(struct platform_device *pdev)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun 
rockchip_virtual_connector_remove(struct platform_device * pdev)565*4882a593Smuzhiyun static int rockchip_virtual_connector_remove(struct platform_device *pdev)
566*4882a593Smuzhiyun {
567*4882a593Smuzhiyun 	component_del(&pdev->dev, &rockchip_virtual_connector_ops);
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	return 0;
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun static const struct of_device_id rockchip_virtual_connector_dt_ids[] = {
573*4882a593Smuzhiyun 	{ .compatible = "rockchip,virtual-connector",
574*4882a593Smuzhiyun 	},
575*4882a593Smuzhiyun 	{},
576*4882a593Smuzhiyun };
577*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rockchip_virtual_connector_dt_ids);
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun struct platform_driver vconn_platform_driver = {
580*4882a593Smuzhiyun 	.probe  = rockchip_virtual_connector_probe,
581*4882a593Smuzhiyun 	.remove = rockchip_virtual_connector_remove,
582*4882a593Smuzhiyun 	.shutdown = rockchip_virtual_connector_shutdown,
583*4882a593Smuzhiyun 	.driver = {
584*4882a593Smuzhiyun 		.name = "drm-virtual-connector",
585*4882a593Smuzhiyun 		.of_match_table = rockchip_virtual_connector_dt_ids,
586*4882a593Smuzhiyun 	},
587*4882a593Smuzhiyun };
588