xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_vop2.c (revision 7c7eb7613f9522c26eb156f50a2f47b4d4cf84b4)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
4  *
5  */
6 
7 #include <config.h>
8 #include <common.h>
9 #include <errno.h>
10 #include <malloc.h>
11 #include <fdtdec.h>
12 #include <fdt_support.h>
13 #include <asm/arch/cpu.h>
14 #include <asm/unaligned.h>
15 #include <asm/io.h>
16 #include <linux/list.h>
17 #include <linux/media-bus-format.h>
18 #include <clk.h>
19 #include <asm/arch/clock.h>
20 #include <linux/err.h>
21 #include <dm/device.h>
22 #include <dm/read.h>
23 #include <syscon.h>
24 
25 #include "rockchip_display.h"
26 #include "rockchip_crtc.h"
27 #include "rockchip_connector.h"
28 
29 /* System registers definition */
30 #define RK3568_REG_CFG_DONE			0x000
31 #define	CFG_DONE_EN				BIT(15)
32 
33 #define RK3568_VERSION_INFO			0x004
34 #define EN_MASK					1
35 
36 #define RK3568_AUTO_GATING_CTRL			0x008
37 
38 #define RK3568_DSP_IF_EN			0x028
39 #define RGB_EN_SHIFT				0
40 #define HDMI0_EN_SHIFT				1
41 #define EDP0_EN_SHIFT				3
42 #define MIPI0_EN_SHIFT				4
43 #define MIPI1_EN_SHIFT				20
44 #define LVDS0_EN_SHIFT				5
45 #define LVDS1_EN_SHIFT				24
46 #define BT1120_EN_SHIFT				6
47 #define BT656_EN_SHIFT				7
48 #define IF_MUX_MASK				3
49 #define RGB_MUX_SHIFT				8
50 #define HDMI0_MUX_SHIFT				10
51 #define EDP0_MUX_SHIFT				14
52 #define MIPI0_MUX_SHIFT				16
53 #define MIPI1_MUX_SHIFT				21
54 #define LVDS0_MUX_SHIFT				18
55 #define LVDS1_MUX_SHIFT				25
56 
57 #define RK3568_DSP_IF_CTRL			0x02c
58 #define LVDS_DUAL_EN_SHIFT			0
59 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT		1
60 #define LVDS_DUAL_SWAP_EN_SHIFT			2
61 #define RK3568_DSP_IF_POL			0x030
62 #define IF_CTRL_REG_DONE_IMD_MASK		1
63 #define IF_CTRL_REG_DONE_IMD_SHIFT		28
64 #define IF_CRTL_MIPI_DCLK_POL_SHIT		19
65 #define IF_CRTL_EDP_DCLK_POL_SHIT		15
66 #define IF_CRTL_HDMI_DCLK_POL_SHIT		7
67 #define IF_CRTL_HDMI_PIN_POL_MASK		0x7
68 #define IF_CRTL_HDMI_PIN_POL_SHIT		4
69 #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT		3
70 #define RK3568_SYS_OTP_WIN_EN			0x50
71 #define OTP_WIN_EN_SHIFT			0
72 #define RK3568_VP0_LINE_FLAG			0x70
73 #define RK3568_VP1_LINE_FLAG			0x74
74 #define RK3568_VP2_LINE_FLAG			0x78
75 #define RK3568_SYS0_INT_EN			0x80
76 #define RK3568_SYS0_INT_CLR			0x84
77 #define RK3568_SYS0_INT_STATUS			0x88
78 #define RK3568_SYS1_INT_EN			0x90
79 #define RK3568_SYS1_INT_CLR			0x94
80 #define RK3568_SYS1_INT_STATUS			0x98
81 #define RK3568_VP0_INT_EN			0xA0
82 #define RK3568_VP0_INT_CLR			0xA4
83 #define RK3568_VP0_INT_STATUS			0xA8
84 #define RK3568_VP1_INT_EN			0xB0
85 #define RK3568_VP1_INT_CLR			0xB4
86 #define RK3568_VP1_INT_STATUS			0xB8
87 #define RK3568_VP2_INT_EN			0xC0
88 #define RK3568_VP2_INT_CLR			0xC4
89 #define RK3568_VP2_INT_STATUS			0xC8
90 
91 /* Overlay registers definition    */
92 #define RK3568_OVL_CTRL				0x600
93 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT		28
94 #define RK3568_OVL_LAYER_SEL			0x604
95 #define LAYER_SEL_MASK				0xf
96 
97 #define RK3568_OVL_PORT_SEL			0x608
98 #define PORT_MUX_MASK				0xf
99 #define PORT_MUX_SHIFT				0
100 #define LAYER_SEL_PORT_MASK			0x3
101 #define LAYER_SEL_PORT_SHIFT			16
102 
103 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL	0x610
104 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL	0x614
105 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x618
106 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL	0x61C
107 #define RK3568_MIX0_SRC_COLOR_CTRL		0x650
108 #define RK3568_MIX0_DST_COLOR_CTRL		0x654
109 #define RK3568_MIX0_SRC_ALPHA_CTRL		0x658
110 #define RK3568_MIX0_DST_ALPHA_CTRL		0x65C
111 #define RK3568_HDR0_SRC_COLOR_CTRL		0x6C0
112 #define RK3568_HDR0_DST_COLOR_CTRL		0x6C4
113 #define RK3568_HDR0_SRC_ALPHA_CTRL		0x6C8
114 #define RK3568_HDR0_DST_ALPHA_CTRL		0x6CC
115 #define RK3568_VP0_BG_MIX_CTRL			0x6E0
116 #define BG_MIX_CTRL_MASK			0xff
117 #define BG_MIX_CTRL_SHIFT			24
118 #define RK3568_VP1_BG_MIX_CTRL			0x6E4
119 #define RK3568_VP2_BG_MIX_CTRL			0x6E8
120 #define RK3568_CLUSTER_DLY_NUM			0x6F0
121 #define RK3568_SMART_DLY_NUM			0x6F8
122 
123 /* Video Port registers definition */
124 #define RK3568_VP0_DSP_CTRL			0xC00
125 #define OUT_MODE_MASK				0xf
126 #define OUT_MODE_SHIFT				0
127 #define DATA_SWAP_MASK				0x1f
128 #define DATA_SWAP_SHIFT				8
129 #define DSP_RB_SWAP				2
130 #define CORE_DCLK_DIV_EN_SHIFT			4
131 #define P2I_EN_SHIFT				5
132 #define INTERLACE_EN_SHIFT			7
133 #define POST_DSP_OUT_R2Y_SHIFT			15
134 #define PRE_DITHER_DOWN_EN_SHIFT		16
135 #define DITHER_DOWN_EN_SHIFT			17
136 #define STANDBY_EN_SHIFT			31
137 
138 #define RK3568_VP0_MIPI_CTRL			0xC04
139 #define DCLK_DIV2_SHIFT				4
140 #define DCLK_DIV2_MASK				0x3
141 #define MIPI_DUAL_EN_SHIFT			20
142 #define MIPI_DUAL_SWAP_EN_SHIFT			21
143 
144 #define RK3568_VP0_COLOR_BAR_CTRL		0xC08
145 #define RK3568_VP0_DSP_BG			0xC2C
146 #define RK3568_VP0_PRE_SCAN_HTIMING		0xC30
147 #define RK3568_VP0_POST_DSP_HACT_INFO		0xC34
148 #define RK3568_VP0_POST_DSP_VACT_INFO		0xC38
149 #define RK3568_VP0_POST_SCL_FACTOR_YRGB		0xC3C
150 #define RK3568_VP0_POST_SCL_CTRL		0xC40
151 #define RK3568_VP0_POST_DSP_VACT_INFO_F1	0xC44
152 #define RK3568_VP0_DSP_HTOTAL_HS_END		0xC48
153 #define RK3568_VP0_DSP_HACT_ST_END		0xC4C
154 #define RK3568_VP0_DSP_VTOTAL_VS_END		0xC50
155 #define RK3568_VP0_DSP_VACT_ST_END		0xC54
156 #define RK3568_VP0_DSP_VS_ST_END_F1		0xC58
157 #define RK3568_VP0_DSP_VACT_ST_END_F1		0xC5C
158 
159 #define RK3568_VP1_DSP_CTRL			0xD00
160 #define RK3568_VP1_MIPI_CTRL			0xD04
161 #define RK3568_VP1_COLOR_BAR_CTRL		0xD08
162 #define RK3568_VP1_PRE_SCAN_HTIMING		0xD30
163 #define RK3568_VP1_POST_DSP_HACT_INFO		0xD34
164 #define RK3568_VP1_POST_DSP_VACT_INFO		0xD38
165 #define RK3568_VP1_POST_SCL_FACTOR_YRGB		0xD3C
166 #define RK3568_VP1_POST_SCL_CTRL		0xD40
167 #define RK3568_VP1_DSP_HACT_INFO		0xD34
168 #define RK3568_VP1_DSP_VACT_INFO		0xD38
169 #define RK3568_VP1_POST_DSP_VACT_INFO_F1	0xD44
170 #define RK3568_VP1_DSP_HTOTAL_HS_END		0xD48
171 #define RK3568_VP1_DSP_HACT_ST_END		0xD4C
172 #define RK3568_VP1_DSP_VTOTAL_VS_END		0xD50
173 #define RK3568_VP1_DSP_VACT_ST_END		0xD54
174 #define RK3568_VP1_DSP_VS_ST_END_F1		0xD58
175 #define RK3568_VP1_DSP_VACT_ST_END_F1		0xD5C
176 
177 #define RK3568_VP2_DSP_CTRL			0xE00
178 #define RK3568_VP2_MIPI_CTRL			0xE04
179 #define RK3568_VP2_COLOR_BAR_CTRL		0xE08
180 #define RK3568_VP2_PRE_SCAN_HTIMING		0xE30
181 #define RK3568_VP2_POST_DSP_HACT_INFO		0xE34
182 #define RK3568_VP2_POST_DSP_VACT_INFO		0xE38
183 #define RK3568_VP2_POST_SCL_FACTOR_YRGB		0xE3C
184 #define RK3568_VP2_POST_SCL_CTRL		0xE40
185 #define RK3568_VP2_DSP_HACT_INFO		0xE34
186 #define RK3568_VP2_DSP_VACT_INFO		0xE38
187 #define RK3568_VP2_POST_DSP_VACT_INFO_F1	0xE44
188 #define RK3568_VP2_DSP_HTOTAL_HS_END		0xE48
189 #define RK3568_VP2_DSP_HACT_ST_END		0xE4C
190 #define RK3568_VP2_DSP_VTOTAL_VS_END		0xE50
191 #define RK3568_VP2_DSP_VACT_ST_END		0xE54
192 #define RK3568_VP2_DSP_VS_ST_END_F1		0xE58
193 #define RK3568_VP2_DSP_VACT_ST_END_F1		0xE5C
194 
195 /* Cluster0 register definition */
196 #define RK3568_CLUSTER0_WIN0_CTRL0		0x1000
197 #define RK3568_CLUSTER0_WIN0_CTRL1		0x1004
198 #define RK3568_CLUSTER0_WIN0_YRGB_MST		0x1010
199 #define RK3568_CLUSTER0_WIN0_CBR_MST		0x1014
200 #define RK3568_CLUSTER0_WIN0_VIR		0x1018
201 #define RK3568_CLUSTER0_WIN0_ACT_INFO		0x1020
202 #define RK3568_CLUSTER0_WIN0_DSP_INFO		0x1024
203 #define RK3568_CLUSTER0_WIN0_DSP_ST		0x1028
204 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB	0x1030
205 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE	0x1054
206 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR	0x1058
207 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH	0x105C
208 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE	0x1060
209 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET	0x1064
210 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET	0x1068
211 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL		0x106C
212 
213 #define RK3568_CLUSTER0_WIN1_CTRL0		0x1080
214 #define RK3568_CLUSTER0_WIN1_CTRL1		0x1084
215 #define RK3568_CLUSTER0_WIN1_YRGB_MST		0x1090
216 #define RK3568_CLUSTER0_WIN1_CBR_MST		0x1094
217 #define RK3568_CLUSTER0_WIN1_VIR		0x1098
218 #define RK3568_CLUSTER0_WIN1_ACT_INFO		0x10A0
219 #define RK3568_CLUSTER0_WIN1_DSP_INFO		0x10A4
220 #define RK3568_CLUSTER0_WIN1_DSP_ST		0x10A8
221 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB	0x10B0
222 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE	0x10D4
223 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR	0x10D8
224 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH	0x10DC
225 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE	0x10E0
226 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET	0x10E4
227 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET	0x10E8
228 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL		0x10EC
229 
230 #define RK3568_CLUSTER0_CTRL			0x1100
231 
232 #define RK3568_CLUSTER1_WIN0_CTRL0		0x1200
233 #define RK3568_CLUSTER1_WIN0_CTRL1		0x1204
234 #define RK3568_CLUSTER1_WIN0_YRGB_MST		0x1210
235 #define RK3568_CLUSTER1_WIN0_CBR_MST		0x1214
236 #define RK3568_CLUSTER1_WIN0_VIR		0x1218
237 #define RK3568_CLUSTER1_WIN0_ACT_INFO		0x1220
238 #define RK3568_CLUSTER1_WIN0_DSP_INFO		0x1224
239 #define RK3568_CLUSTER1_WIN0_DSP_ST		0x1228
240 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB	0x1230
241 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE	0x1254
242 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR	0x1258
243 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH	0x125C
244 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE	0x1260
245 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET	0x1264
246 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET	0x1268
247 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL		0x126C
248 
249 #define RK3568_CLUSTER1_WIN1_CTRL0		0x1280
250 #define RK3568_CLUSTER1_WIN1_CTRL1		0x1284
251 #define RK3568_CLUSTER1_WIN1_YRGB_MST		0x1290
252 #define RK3568_CLUSTER1_WIN1_CBR_MST		0x1294
253 #define RK3568_CLUSTER1_WIN1_VIR		0x1298
254 #define RK3568_CLUSTER1_WIN1_ACT_INFO		0x12A0
255 #define RK3568_CLUSTER1_WIN1_DSP_INFO		0x12A4
256 #define RK3568_CLUSTER1_WIN1_DSP_ST		0x12A8
257 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB	0x12B0
258 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE	0x12D4
259 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR	0x12D8
260 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH	0x12DC
261 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE	0x12E0
262 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET	0x12E4
263 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET	0x12E8
264 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL		0x12EC
265 
266 #define RK3568_CLUSTER1_CTRL			0x1300
267 
268 /* Esmart register definition */
269 #define RK3568_ESMART0_CTRL0			0x1800
270 #define RGB2YUV_EN_SHIFT			1
271 #define CSC_MODE_SHIFT				2
272 #define CSC_MODE_MASK				0x3
273 
274 #define RK3568_ESMART0_CTRL1			0x1804
275 #define YMIRROR_EN_SHIFT			31
276 #define RK3568_ESMART0_REGION0_CTRL		0x1810
277 #define REGION0_RB_SWAP_SHIFT			14
278 #define WIN_EN_SHIFT				0
279 #define WIN_FORMAT_MASK				0x1f
280 #define WIN_FORMAT_SHIFT			1
281 
282 #define RK3568_ESMART0_REGION0_YRGB_MST		0x1814
283 #define RK3568_ESMART0_REGION0_CBR_MST		0x1818
284 #define RK3568_ESMART0_REGION0_VIR		0x181C
285 #define RK3568_ESMART0_REGION0_ACT_INFO		0x1820
286 #define RK3568_ESMART0_REGION0_DSP_INFO		0x1824
287 #define RK3568_ESMART0_REGION0_DSP_ST		0x1828
288 #define RK3568_ESMART0_REGION0_SCL_CTRL		0x1830
289 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB	0x1834
290 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR	0x1838
291 #define RK3568_ESMART0_REGION0_SCL_OFFSET	0x183C
292 #define RK3568_ESMART0_REGION1_CTRL		0x1840
293 #define RK3568_ESMART0_REGION1_YRGB_MST		0x1844
294 #define RK3568_ESMART0_REGION1_CBR_MST		0x1848
295 #define RK3568_ESMART0_REGION1_VIR		0x184C
296 #define RK3568_ESMART0_REGION1_ACT_INFO		0x1850
297 #define RK3568_ESMART0_REGION1_DSP_INFO		0x1854
298 #define RK3568_ESMART0_REGION1_DSP_ST		0x1858
299 #define RK3568_ESMART0_REGION1_SCL_CTRL		0x1860
300 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB	0x1864
301 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR	0x1868
302 #define RK3568_ESMART0_REGION1_SCL_OFFSET	0x186C
303 #define RK3568_ESMART0_REGION2_CTRL		0x1870
304 #define RK3568_ESMART0_REGION2_YRGB_MST		0x1874
305 #define RK3568_ESMART0_REGION2_CBR_MST		0x1878
306 #define RK3568_ESMART0_REGION2_VIR		0x187C
307 #define RK3568_ESMART0_REGION2_ACT_INFO		0x1880
308 #define RK3568_ESMART0_REGION2_DSP_INFO		0x1884
309 #define RK3568_ESMART0_REGION2_DSP_ST		0x1888
310 #define RK3568_ESMART0_REGION2_SCL_CTRL		0x1890
311 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB	0x1894
312 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR	0x1898
313 #define RK3568_ESMART0_REGION2_SCL_OFFSET	0x189C
314 #define RK3568_ESMART0_REGION3_CTRL		0x18A0
315 #define RK3568_ESMART0_REGION3_YRGB_MST		0x18A4
316 #define RK3568_ESMART0_REGION3_CBR_MST		0x18A8
317 #define RK3568_ESMART0_REGION3_VIR		0x18AC
318 #define RK3568_ESMART0_REGION3_ACT_INFO		0x18B0
319 #define RK3568_ESMART0_REGION3_DSP_INFO		0x18B4
320 #define RK3568_ESMART0_REGION3_DSP_ST		0x18B8
321 #define RK3568_ESMART0_REGION3_SCL_CTRL		0x18C0
322 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB	0x18C4
323 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR	0x18C8
324 #define RK3568_ESMART0_REGION3_SCL_OFFSET	0x18CC
325 
326 #define RK3568_ESMART1_CTRL0			0x1A00
327 #define RK3568_ESMART1_CTRL1			0x1A04
328 #define RK3568_ESMART1_REGION0_CTRL		0x1A10
329 #define RK3568_ESMART1_REGION0_YRGB_MST		0x1A14
330 #define RK3568_ESMART1_REGION0_CBR_MST		0x1A18
331 #define RK3568_ESMART1_REGION0_VIR		0x1A1C
332 #define RK3568_ESMART1_REGION0_ACT_INFO		0x1A20
333 #define RK3568_ESMART1_REGION0_DSP_INFO		0x1A24
334 #define RK3568_ESMART1_REGION0_DSP_ST		0x1A28
335 #define RK3568_ESMART1_REGION0_SCL_CTRL		0x1A30
336 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB	0x1A34
337 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR	0x1A38
338 #define RK3568_ESMART1_REGION0_SCL_OFFSET	0x1A3C
339 #define RK3568_ESMART1_REGION1_CTRL		0x1A40
340 #define RK3568_ESMART1_REGION1_YRGB_MST		0x1A44
341 #define RK3568_ESMART1_REGION1_CBR_MST		0x1A48
342 #define RK3568_ESMART1_REGION1_VIR		0x1A4C
343 #define RK3568_ESMART1_REGION1_ACT_INFO		0x1A50
344 #define RK3568_ESMART1_REGION1_DSP_INFO		0x1A54
345 #define RK3568_ESMART1_REGION1_DSP_ST		0x1A58
346 #define RK3568_ESMART1_REGION1_SCL_CTRL		0x1A60
347 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB	0x1A64
348 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR	0x1A68
349 #define RK3568_ESMART1_REGION1_SCL_OFFSET	0x1A6C
350 #define RK3568_ESMART1_REGION2_CTRL		0x1A70
351 #define RK3568_ESMART1_REGION2_YRGB_MST		0x1A74
352 #define RK3568_ESMART1_REGION2_CBR_MST		0x1A78
353 #define RK3568_ESMART1_REGION2_VIR		0x1A7C
354 #define RK3568_ESMART1_REGION2_ACT_INFO		0x1A80
355 #define RK3568_ESMART1_REGION2_DSP_INFO		0x1A84
356 #define RK3568_ESMART1_REGION2_DSP_ST		0x1A88
357 #define RK3568_ESMART1_REGION2_SCL_CTRL		0x1A90
358 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB	0x1A94
359 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR	0x1A98
360 #define RK3568_ESMART1_REGION2_SCL_OFFSET	0x1A9C
361 #define RK3568_ESMART1_REGION3_CTRL		0x1AA0
362 #define RK3568_ESMART1_REGION3_YRGB_MST		0x1AA4
363 #define RK3568_ESMART1_REGION3_CBR_MST		0x1AA8
364 #define RK3568_ESMART1_REGION3_VIR		0x1AAC
365 #define RK3568_ESMART1_REGION3_ACT_INFO		0x1AB0
366 #define RK3568_ESMART1_REGION3_DSP_INFO		0x1AB4
367 #define RK3568_ESMART1_REGION3_DSP_ST		0x1AB8
368 #define RK3568_ESMART1_REGION3_SCL_CTRL		0x1AC0
369 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB	0x1AC4
370 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR	0x1AC8
371 #define RK3568_ESMART1_REGION3_SCL_OFFSET	0x1ACC
372 
373 #define RK3568_SMART0_CTRL0			0x1C00
374 #define RK3568_SMART0_CTRL1			0x1C04
375 #define RK3568_SMART0_REGION0_CTRL		0x1C10
376 #define RK3568_SMART0_REGION0_YRGB_MST		0x1C14
377 #define RK3568_SMART0_REGION0_CBR_MST		0x1C18
378 #define RK3568_SMART0_REGION0_VIR		0x1C1C
379 #define RK3568_SMART0_REGION0_ACT_INFO		0x1C20
380 #define RK3568_SMART0_REGION0_DSP_INFO		0x1C24
381 #define RK3568_SMART0_REGION0_DSP_ST		0x1C28
382 #define RK3568_SMART0_REGION0_SCL_CTRL		0x1C30
383 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB	0x1C34
384 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR	0x1C38
385 #define RK3568_SMART0_REGION0_SCL_OFFSET	0x1C3C
386 #define RK3568_SMART0_REGION1_CTRL		0x1C40
387 #define RK3568_SMART0_REGION1_YRGB_MST		0x1C44
388 #define RK3568_SMART0_REGION1_CBR_MST		0x1C48
389 #define RK3568_SMART0_REGION1_VIR		0x1C4C
390 #define RK3568_SMART0_REGION1_ACT_INFO		0x1C50
391 #define RK3568_SMART0_REGION1_DSP_INFO		0x1C54
392 #define RK3568_SMART0_REGION1_DSP_ST		0x1C58
393 #define RK3568_SMART0_REGION1_SCL_CTRL		0x1C60
394 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB	0x1C64
395 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR	0x1C68
396 #define RK3568_SMART0_REGION1_SCL_OFFSET	0x1C6C
397 #define RK3568_SMART0_REGION2_CTRL		0x1C70
398 #define RK3568_SMART0_REGION2_YRGB_MST		0x1C74
399 #define RK3568_SMART0_REGION2_CBR_MST		0x1C78
400 #define RK3568_SMART0_REGION2_VIR		0x1C7C
401 #define RK3568_SMART0_REGION2_ACT_INFO		0x1C80
402 #define RK3568_SMART0_REGION2_DSP_INFO		0x1C84
403 #define RK3568_SMART0_REGION2_DSP_ST		0x1C88
404 #define RK3568_SMART0_REGION2_SCL_CTRL		0x1C90
405 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB	0x1C94
406 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR	0x1C98
407 #define RK3568_SMART0_REGION2_SCL_OFFSET	0x1C9C
408 #define RK3568_SMART0_REGION3_CTRL		0x1CA0
409 #define RK3568_SMART0_REGION3_YRGB_MST		0x1CA4
410 #define RK3568_SMART0_REGION3_CBR_MST		0x1CA8
411 #define RK3568_SMART0_REGION3_VIR		0x1CAC
412 #define RK3568_SMART0_REGION3_ACT_INFO		0x1CB0
413 #define RK3568_SMART0_REGION3_DSP_INFO		0x1CB4
414 #define RK3568_SMART0_REGION3_DSP_ST		0x1CB8
415 #define RK3568_SMART0_REGION3_SCL_CTRL		0x1CC0
416 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB	0x1CC4
417 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR	0x1CC8
418 #define RK3568_SMART0_REGION3_SCL_OFFSET	0x1CCC
419 
420 #define RK3568_SMART1_CTRL0			0x1E00
421 #define RK3568_SMART1_CTRL1			0x1E04
422 #define RK3568_SMART1_REGION0_CTRL		0x1E10
423 #define RK3568_SMART1_REGION0_YRGB_MST		0x1E14
424 #define RK3568_SMART1_REGION0_CBR_MST		0x1E18
425 #define RK3568_SMART1_REGION0_VIR		0x1E1C
426 #define RK3568_SMART1_REGION0_ACT_INFO		0x1E20
427 #define RK3568_SMART1_REGION0_DSP_INFO		0x1E24
428 #define RK3568_SMART1_REGION0_DSP_ST		0x1E28
429 #define RK3568_SMART1_REGION0_SCL_CTRL		0x1E30
430 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB	0x1E34
431 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR	0x1E38
432 #define RK3568_SMART1_REGION0_SCL_OFFSET	0x1E3C
433 #define RK3568_SMART1_REGION1_CTRL		0x1E40
434 #define RK3568_SMART1_REGION1_YRGB_MST		0x1E44
435 #define RK3568_SMART1_REGION1_CBR_MST		0x1E48
436 #define RK3568_SMART1_REGION1_VIR		0x1E4C
437 #define RK3568_SMART1_REGION1_ACT_INFO		0x1E50
438 #define RK3568_SMART1_REGION1_DSP_INFO		0x1E54
439 #define RK3568_SMART1_REGION1_DSP_ST		0x1E58
440 #define RK3568_SMART1_REGION1_SCL_CTRL		0x1E60
441 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB	0x1E64
442 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR	0x1E68
443 #define RK3568_SMART1_REGION1_SCL_OFFSET	0x1E6C
444 #define RK3568_SMART1_REGION2_CTRL		0x1E70
445 #define RK3568_SMART1_REGION2_YRGB_MST		0x1E74
446 #define RK3568_SMART1_REGION2_CBR_MST		0x1E78
447 #define RK3568_SMART1_REGION2_VIR		0x1E7C
448 #define RK3568_SMART1_REGION2_ACT_INFO		0x1E80
449 #define RK3568_SMART1_REGION2_DSP_INFO		0x1E84
450 #define RK3568_SMART1_REGION2_DSP_ST		0x1E88
451 #define RK3568_SMART1_REGION2_SCL_CTRL		0x1E90
452 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB	0x1E94
453 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR	0x1E98
454 #define RK3568_SMART1_REGION2_SCL_OFFSET	0x1E9C
455 #define RK3568_SMART1_REGION3_CTRL		0x1EA0
456 #define RK3568_SMART1_REGION3_YRGB_MST		0x1EA4
457 #define RK3568_SMART1_REGION3_CBR_MST		0x1EA8
458 #define RK3568_SMART1_REGION3_VIR		0x1EAC
459 #define RK3568_SMART1_REGION3_ACT_INFO		0x1EB0
460 #define RK3568_SMART1_REGION3_DSP_INFO		0x1EB4
461 #define RK3568_SMART1_REGION3_DSP_ST		0x1EB8
462 #define RK3568_SMART1_REGION3_SCL_CTRL		0x1EC0
463 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB	0x1EC4
464 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR	0x1EC8
465 #define RK3568_SMART1_REGION3_SCL_OFFSET	0x1ECC
466 
467 #define RK3568_MAX_REG				0x1ED0
468 
469 #define RK3568_GRF_VO_CON1			0x0364
470 #define GRF_BT656_CLK_INV_SHIFT			1
471 #define GRF_BT1120_CLK_INV_SHIFT		2
472 #define GRF_RGB_DCLK_INV_SHIFT			3
473 
474 #define VOP2_LAYER_MAX				8
475 
476 #define VOP_FEATURE_OUTPUT_10BIT		BIT(0)
477 
478 enum vop2_csc_format {
479 	CSC_BT601L,
480 	CSC_BT709L,
481 	CSC_BT601F,
482 	CSC_BT2020,
483 };
484 
485 enum vop2_pol {
486 	HSYNC_POSITIVE = 0,
487 	VSYNC_POSITIVE = 1,
488 	DEN_NEGATIVE   = 2,
489 	DCLK_INVERT    = 3
490 };
491 
492 #define _VOP_REG(off, _mask, _shift, _write_mask) \
493 		{ \
494 		 .offset = off, \
495 		 .mask = _mask, \
496 		 .shift = _shift, \
497 		 .write_mask = _write_mask, \
498 		}
499 
500 #define VOP_REG(off, _mask, _shift) \
501 		_VOP_REG(off, _mask, _shift, false)
502 enum dither_down_mode {
503 	RGB888_TO_RGB565 = 0x0,
504 	RGB888_TO_RGB666 = 0x1
505 };
506 
507 enum vop2_video_ports_id {
508 	VOP2_VP0,
509 	VOP2_VP1,
510 	VOP2_VP2,
511 	VOP2_VP3,
512 	VOP2_VP_MAX,
513 };
514 
515 struct vop2_layer {
516 	u8 id;
517 	/**
518 	 * @win_phys_id: window id of the layer selected.
519 	 * Every layer must make sure to select different
520 	 * windows of others.
521 	 */
522 	u8 win_phys_id;
523 };
524 
525 struct vop2_win {
526 	u8 id;
527 	u8 layer_id;
528 	u8 phys_id;
529 };
530 
531 struct vop2_vp_data {
532 	u32 feature;
533 	u8 vp_use_win_id;
534 	u8 pre_scan_max_dly;
535 	struct vop_rect max_output;
536 };
537 
538 struct vop2_data {
539 	u32 version;
540 	struct vop2_vp_data *vp_data;
541 	u8 used_layers[VOP2_MAX_VP];
542 	u8 nr_vps;
543 	u8 nr_layers;
544 	u8 nr_mixers;
545 	/**
546 	 * layer_sel_id: from register LAYER_SEL
547 	 *
548 	 */
549 	u8 layer_sel_id[VOP2_LAYER_MAX];
550 	/*
551 	 * the win register offset
552 	 */
553 	u8 win_offset[VOP2_LAYER_MAX];
554 };
555 
556 struct vop2 {
557 	u32 *regsbak;
558 	void *regs;
559 	void *grf;
560 	u32 reg_len;
561 	u32 version;
562 	u32 win_reg_offset;
563 	bool global_init;
564 	const struct vop2_data *data;
565 	/**
566 	 * @nr_wins: active wins attached to the video port
567 	 */
568 	u8 nr_wins[VOP2_VP_MAX];
569 };
570 
571 static struct vop2 *rockchip_vop2;
572 
573 static inline u16 scl_cal_scale(int src, int dst, int shift)
574 {
575 	return ((src * 2 - 3) << (shift - 1)) / (dst - 1);
576 }
577 
578 static inline u16 scl_cal_scale2(int src, int dst)
579 {
580 	return ((src - 1) << 12) / (dst - 1);
581 }
582 
583 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
584 {
585 	writel(v, vop2->regs + offset);
586 	vop2->regsbak[offset >> 2] = v;
587 }
588 
589 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
590 {
591 	return readl(vop2->regs + offset);
592 }
593 
594 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset,
595 				   u32 mask, u32 shift, u32 v,
596 				   bool write_mask)
597 {
598 	if (!mask)
599 		return;
600 
601 	if (write_mask) {
602 		v = ((v & mask) << shift) | (mask << (shift + 16));
603 	} else {
604 		u32 cached_val = vop2->regsbak[offset >> 2];
605 
606 		v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
607 		vop2->regsbak[offset >> 2] = v;
608 	}
609 
610 	writel(v, vop2->regs + offset);
611 }
612 
613 static inline void vop2_grf_writel(struct vop2 *vop, u32 offset,
614 				   u32 mask, u32 shift, u32 v)
615 {
616 	u32 val = 0;
617 
618 	val = (v << shift) | (mask << (shift + 16));
619 	writel(val, vop->grf + offset);
620 }
621 
622 static inline int us_to_vertical_line(struct drm_display_mode *mode, int us)
623 {
624 	return us * mode->clock / mode->htotal / 1000;
625 }
626 
627 static bool is_yuv_output(u32 bus_format)
628 {
629 	switch (bus_format) {
630 	case MEDIA_BUS_FMT_YUV8_1X24:
631 	case MEDIA_BUS_FMT_YUV10_1X30:
632 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
633 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
634 		return true;
635 	default:
636 		return false;
637 	}
638 }
639 
640 static int vop2_convert_csc_mode(int csc_mode)
641 {
642 	switch (csc_mode) {
643 	case V4L2_COLORSPACE_SMPTE170M:
644 	case V4L2_COLORSPACE_470_SYSTEM_M:
645 	case V4L2_COLORSPACE_470_SYSTEM_BG:
646 		return CSC_BT601L;
647 	case V4L2_COLORSPACE_REC709:
648 	case V4L2_COLORSPACE_SMPTE240M:
649 	case V4L2_COLORSPACE_DEFAULT:
650 		return CSC_BT709L;
651 	case V4L2_COLORSPACE_JPEG:
652 		return CSC_BT601F;
653 	case V4L2_COLORSPACE_BT2020:
654 		return CSC_BT2020;
655 	default:
656 		return CSC_BT709L;
657 	}
658 }
659 
660 static __maybe_unused bool is_uv_swap(u32 bus_format, u32 output_mode)
661 {
662 	/*
663 	 * FIXME:
664 	 *
665 	 * There is no media type for YUV444 output,
666 	 * so when out_mode is AAAA or P888, assume output is YUV444 on
667 	 * yuv format.
668 	 *
669 	 * From H/W testing, YUV444 mode need a rb swap.
670 	 */
671 	if ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
672 	     bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
673 	    (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
674 	     output_mode == ROCKCHIP_OUT_MODE_P888))
675 		return true;
676 	else
677 		return false;
678 }
679 
680 static int vop2_get_port_id(struct vop2 *vop2, struct crtc_state *cstate, int win_id)
681 {
682 	int i = 0, last_active_vp_id = 0;
683 
684 	for (i = 0; i < VOP2_MAX_VP; i++) {
685 		if (vop2->data->vp_data[i].vp_use_win_id == win_id && cstate->crtc->vps[i].enable)
686 			return i;
687 	}
688 
689 	for (i = 0; i < VOP2_MAX_VP; i++) {
690 		if (cstate->crtc->vps[i].enable)
691 			last_active_vp_id = i;
692 	}
693 
694 	return last_active_vp_id; /* unused win attach to the last port */
695 }
696 
697 static int rockchip_vop2_init_gamma(struct vop2 *vop2,
698 				    struct display_state *state)
699 {
700 	return 0;
701 }
702 
703 static void vop2_post_config(struct display_state *state, struct vop2 *vop2)
704 {
705 	struct connector_state *conn_state = &state->conn_state;
706 	struct drm_display_mode *mode = &conn_state->mode;
707 	struct crtc_state *cstate = &state->crtc_state;
708 	u32 vp_offset = (cstate->crtc_id * 0x100);
709 	u16 vtotal = mode->crtc_vtotal;
710 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
711 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
712 	u16 hdisplay = mode->crtc_hdisplay;
713 	u16 vdisplay = mode->crtc_vdisplay;
714 	u16 hsize =
715 	    hdisplay * (conn_state->overscan.left_margin +
716 			conn_state->overscan.right_margin) / 200;
717 	u16 vsize =
718 	    vdisplay * (conn_state->overscan.top_margin +
719 			conn_state->overscan.bottom_margin) / 200;
720 	u16 hact_end, vact_end;
721 	u32 val;
722 	u32 bg_ovl_dly, bg_dly, pre_scan_dly;
723 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
724 
725 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
726 		vsize = round_down(vsize, 2);
727 
728 	hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200;
729 	hact_end = hact_st + hsize;
730 	val = hact_st << 16;
731 	val |= hact_end;
732 
733 	vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val);
734 	vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200;
735 	vact_end = vact_st + vsize;
736 	val = vact_st << 16;
737 	val |= vact_end;
738 	vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val);
739 	val = scl_cal_scale2(vdisplay, vsize) << 16;
740 	val |= scl_cal_scale2(hdisplay, hsize);
741 	vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val);
742 #define POST_HORIZONTAL_SCALEDOWN_EN(x)		((x) << 0)
743 #define POST_VERTICAL_SCALEDOWN_EN(x)		((x) << 1)
744 	vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset,
745 		    POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) |
746 		    POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize));
747 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
748 		u16 vact_st_f1 = vtotal + vact_st + 1;
749 		u16 vact_end_f1 = vact_st_f1 + vsize;
750 
751 		val = vact_st_f1 << 16 | vact_end_f1;
752 		vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val);
753 	}
754 
755 	bg_ovl_dly = cstate->crtc->vps[cstate->crtc_id].bg_ovl_dly;
756 	bg_dly =  vop2->data->vp_data[cstate->crtc_id].pre_scan_max_dly;
757 	bg_dly -= bg_ovl_dly;
758 	pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
759 	pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
760 	vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + cstate->crtc_id * 4,
761 			BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false);
762 	vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + vp_offset, pre_scan_dly);
763 }
764 
765 static void vop2_global_initial(struct vop2 *vop2, struct crtc_state *cstate)
766 {
767 	int i, j, port_mux = 0, total_used_layer = 0, last_active_vp = 0;
768 	u8 shift = 0;
769 
770 	if (vop2->global_init)
771 		return;
772 
773 	memcpy(vop2->regsbak, vop2->regs, vop2->reg_len);
774 	if (soc_is_rk3566())
775 		vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK,
776 				OTP_WIN_EN_SHIFT, 1, false);
777 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK,
778 			OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false);
779 	vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
780 			IF_CTRL_REG_DONE_IMD_SHIFT, 1, false);
781 	/* layer sel win id */
782 	for (i = 0; i < vop2->data->nr_layers; i++) {
783 		shift = i * 4;
784 		vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK,
785 				shift,  vop2->data->layer_sel_id[i], false);
786 	}
787 	/**
788 	 * port mux config
789 	 */
790 	for (i = 0; i < vop2->data->nr_vps - 1; i++) {
791 		shift = i * 4;
792 		if (cstate->crtc->vps[i].enable) {
793 			total_used_layer += vop2->data->used_layers[i];
794 			port_mux = total_used_layer - 1;
795 		} else {
796 			port_mux = 8;
797 		}
798 
799 		/* if it's last active vp, set all lest of mixer to it */
800 		for (j = 0; j < vop2->data->nr_vps; j++) {
801 			if (cstate->crtc->vps[j].enable)
802 				last_active_vp = j;
803 		}
804 		if (i == last_active_vp)
805 			port_mux = vop2->data->nr_mixers;
806 
807 		cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1;
808 		vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK,
809 				PORT_MUX_SHIFT + shift, port_mux, false);
810 	}
811 
812 	/* win sel port */
813 	for (i = 0; i < vop2->data->nr_layers; i++) {
814 		shift = vop2->data->win_offset[i] * 2;
815 		vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK,
816 				LAYER_SEL_PORT_SHIFT + shift,
817 				vop2_get_port_id(vop2, cstate, i), false);
818 	}
819 
820 	vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0);
821 
822 	vop2->global_init = true;
823 }
824 
825 static int vop2_initial(struct vop2 *vop2, struct display_state *state)
826 {
827 	struct crtc_state *cstate = &state->crtc_state;
828 	struct connector_state *conn_state = &state->conn_state;
829 	struct drm_display_mode *mode = &conn_state->mode;
830 	char dclk_name[9];
831 	struct clk dclk;
832 	int ret;
833 
834 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
835 	ret = clk_set_defaults(cstate->dev);
836 	if (ret)
837 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
838 	snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id);
839 	ret = clk_get_by_name(cstate->dev, dclk_name, &dclk);
840 	if (!ret)
841 		ret = clk_set_rate(&dclk, mode->clock * 1000);
842 	if (IS_ERR_VALUE(ret)) {
843 		printf("%s: Failed to set dclk: ret=%d\n", __func__, ret);
844 		return ret;
845 	}
846 
847 	vop2_global_initial(vop2, cstate);
848 	rockchip_vop2_init_gamma(vop2, state);
849 
850 	return 0;
851 }
852 
853 /*
854  * VOP2 have multi video ports.
855  * video port ------- crtc
856  */
857 static int rockchip_vop2_preinit(struct display_state *state)
858 {
859 	struct crtc_state *cstate = &state->crtc_state;
860 	const struct vop2_data *vop2_data = cstate->crtc->data;
861 	int i = 0;
862 
863 	if (!rockchip_vop2) {
864 		rockchip_vop2 = calloc(1, sizeof(struct vop2));
865 		if (!rockchip_vop2)
866 			return -ENOMEM;
867 		rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev);
868 		rockchip_vop2->regsbak = malloc(RK3568_MAX_REG);
869 		rockchip_vop2->reg_len = RK3568_MAX_REG;
870 		rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
871 		if (rockchip_vop2->grf <= 0)
872 			printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf);
873 
874 		rockchip_vop2->version = vop2_data->version;
875 		rockchip_vop2->data = vop2_data;
876 		rockchip_vop2->win_reg_offset = vop2_data->vp_data[0].vp_use_win_id;
877 
878 		/* find the base offset for esmart0 */
879 		for (i = 1; i < vop2_data->nr_vps; i++) {
880 			if (rockchip_vop2->win_reg_offset > vop2_data->vp_data[i].vp_use_win_id)
881 				rockchip_vop2->win_reg_offset = vop2_data->vp_data[i].vp_use_win_id;
882 		}
883 	}
884 
885 	cstate->private = rockchip_vop2;
886 	cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output;
887 	cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature;
888 
889 	return 0;
890 }
891 
892 static int rockchip_vop2_init(struct display_state *state)
893 {
894 	struct crtc_state *cstate = &state->crtc_state;
895 	struct connector_state *conn_state = &state->conn_state;
896 	struct drm_display_mode *mode = &conn_state->mode;
897 	struct vop2 *vop2 = cstate->private;
898 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
899 	u16 hdisplay = mode->crtc_hdisplay;
900 	u16 htotal = mode->crtc_htotal;
901 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
902 	u16 hact_end = hact_st + hdisplay;
903 	u16 vdisplay = mode->crtc_vdisplay;
904 	u16 vtotal = mode->crtc_vtotal;
905 	u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
906 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
907 	u16 vact_end = vact_st + vdisplay;
908 	bool yuv_overlay = false;
909 	u32 vp_offset = (cstate->crtc_id * 0x100);
910 	u32 val;
911 	bool dclk_inv;
912 	u8 dither_down_en = 0;
913 	u8 pre_dither_down_en = 0;
914 
915 	vop2_initial(vop2, state);
916 	dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1;
917 	val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
918 	val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
919 
920 	if (conn_state->output_if & VOP_OUTPUT_IF_RGB) {
921 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
922 				1, false);
923 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
924 				RGB_MUX_SHIFT, cstate->crtc_id, false);
925 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
926 				IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, !!dclk_inv,
927 				false);
928 		vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK,
929 				GRF_RGB_DCLK_INV_SHIFT, !dclk_inv);
930 	}
931 
932 	if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) {
933 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
934 				1, false);
935 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK,
936 				BT1120_EN_SHIFT, 1, false);
937 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
938 				RGB_MUX_SHIFT, cstate->crtc_id, false);
939 		vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK,
940 				GRF_BT1120_CLK_INV_SHIFT, !dclk_inv);
941 	}
942 
943 	if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
944 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
945 				1, false);
946 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
947 				RGB_MUX_SHIFT, cstate->crtc_id, false);
948 		vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK,
949 				GRF_BT656_CLK_INV_SHIFT, !dclk_inv);
950 	}
951 
952 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) {
953 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT,
954 				1, false);
955 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
956 				LVDS0_MUX_SHIFT, cstate->crtc_id, false);
957 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
958 				IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false);
959 	}
960 
961 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) {
962 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT,
963 				1, false);
964 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
965 				LVDS1_MUX_SHIFT, cstate->crtc_id, false);
966 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
967 				IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false);
968 	}
969 
970 	if (conn_state->output_flags &
971 	    (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE |
972 	     ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) {
973 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
974 				LVDS_DUAL_EN_SHIFT, 1, false);
975 		if (conn_state->output_flags &
976 		    ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
977 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
978 					LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1,
979 					false);
980 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
981 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
982 					LVDS_DUAL_SWAP_EN_SHIFT, 1, false);
983 	}
984 
985 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) {
986 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT,
987 				1, false);
988 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
989 				MIPI0_MUX_SHIFT, cstate->crtc_id, false);
990 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
991 				IF_CRTL_MIPI_DCLK_POL_SHIT, !!dclk_inv, false);
992 	}
993 
994 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) {
995 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT,
996 				1, false);
997 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
998 				MIPI1_MUX_SHIFT, cstate->crtc_id, false);
999 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
1000 				IF_CRTL_MIPI_DCLK_POL_SHIT, !!dclk_inv, false);
1001 	}
1002 
1003 	if (conn_state->output_flags &
1004 	    ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
1005 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
1006 				MIPI_DUAL_EN_SHIFT, 1, false);
1007 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
1008 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1009 					EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
1010 					false);
1011 	}
1012 
1013 	if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) {
1014 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT,
1015 				1, false);
1016 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
1017 				EDP0_MUX_SHIFT, cstate->crtc_id, false);
1018 	}
1019 
1020 	if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
1021 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
1022 				1, false);
1023 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
1024 				HDMI0_MUX_SHIFT, cstate->crtc_id, false);
1025 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
1026 				IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
1027 		vop2_mask_write(vop2, RK3568_DSP_IF_POL,
1028 				IF_CRTL_HDMI_PIN_POL_MASK,
1029 				IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
1030 	}
1031 
1032 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
1033 	    !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT))
1034 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
1035 
1036 	if (is_uv_swap(conn_state->bus_format, conn_state->output_mode))
1037 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1038 				DATA_SWAP_MASK, DATA_SWAP_SHIFT, DSP_RB_SWAP,
1039 				false);
1040 	else
1041 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1042 				DATA_SWAP_MASK, DATA_SWAP_SHIFT, 0,
1043 				false);
1044 
1045 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK,
1046 			OUT_MODE_SHIFT, conn_state->output_mode, false);
1047 
1048 	switch (conn_state->bus_format) {
1049 	case MEDIA_BUS_FMT_RGB565_1X16:
1050 		dither_down_en = 1;
1051 		break;
1052 	case MEDIA_BUS_FMT_RGB666_1X18:
1053 	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
1054 	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
1055 	case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA:
1056 		dither_down_en = 1;
1057 		break;
1058 	case MEDIA_BUS_FMT_YUV8_1X24:
1059 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1060 		dither_down_en = 0;
1061 		pre_dither_down_en = 1;
1062 		break;
1063 	case MEDIA_BUS_FMT_YUV10_1X30:
1064 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1065 	case MEDIA_BUS_FMT_RGB888_1X24:
1066 	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
1067 	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
1068 	default:
1069 		dither_down_en = 0;
1070 		pre_dither_down_en = 0;
1071 		break;
1072 	}
1073 
1074 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA)
1075 		pre_dither_down_en = 0;
1076 	else
1077 		pre_dither_down_en = 1;
1078 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1079 			DITHER_DOWN_EN_SHIFT, dither_down_en, false);
1080 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1081 			PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false);
1082 
1083 	yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0;
1084 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id,
1085 			yuv_overlay, false);
1086 
1087 	cstate->yuv_overlay = yuv_overlay;
1088 
1089 	vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset,
1090 		    (htotal << 16) | hsync_len);
1091 	val = hact_st << 16;
1092 	val |= hact_end;
1093 	vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val);
1094 	val = vact_st << 16;
1095 	val |= vact_end;
1096 	vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val);
1097 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1098 		u16 vact_st_f1 = vtotal + vact_st + 1;
1099 		u16 vact_end_f1 = vact_st_f1 + vdisplay;
1100 
1101 		val = vact_st_f1 << 16 | vact_end_f1;
1102 		vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset,
1103 			    val);
1104 
1105 		val = vtotal << 16 | (vtotal + vsync_len);
1106 		vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val);
1107 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1108 				INTERLACE_EN_SHIFT, 1, false);
1109 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1110 				P2I_EN_SHIFT, 1, false);
1111 		vtotal += vtotal + 1;
1112 	} else {
1113 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1114 				INTERLACE_EN_SHIFT, 0, false);
1115 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1116 				P2I_EN_SHIFT, 0, false);
1117 	}
1118 	vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset,
1119 		    (vtotal << 16) | vsync_len);
1120 	val = !!(mode->flags & DRM_MODE_FLAG_DBLCLK);
1121 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1122 			CORE_DCLK_DIV_EN_SHIFT, val, false);
1123 
1124 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420)
1125 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1126 				DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false);
1127 	else
1128 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1129 				DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false);
1130 
1131 	if (yuv_overlay)
1132 		val = 0x20010200;
1133 	else
1134 		val = 0;
1135 	vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val);
1136 
1137 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1138 			POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false);
1139 
1140 	vop2_post_config(state, vop2);
1141 
1142 	return 0;
1143 }
1144 
1145 static int rockchip_vop2_set_plane(struct display_state *state)
1146 {
1147 	struct crtc_state *cstate = &state->crtc_state;
1148 	struct connector_state *conn_state = &state->conn_state;
1149 	struct drm_display_mode *mode = &conn_state->mode;
1150 	u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
1151 	struct vop2 *vop2 = cstate->private;
1152 	int src_w = cstate->src_w;
1153 	int src_h = cstate->src_h;
1154 	int crtc_x = cstate->crtc_x;
1155 	int crtc_y = cstate->crtc_y;
1156 	int crtc_w = cstate->crtc_w;
1157 	int crtc_h = cstate->crtc_h;
1158 	int xvir = cstate->xvir;
1159 	int y_mirror = 0;
1160 	int csc_mode;
1161 	u32 win_offset;
1162 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id);
1163 	struct vop2_vp_data *vp_data = &vop2->data->vp_data[cstate->crtc_id];
1164 
1165 	if (cstate->crtc_id == 1)
1166 		win_offset = 0x400; /* port 1 use smart0*/
1167 	else
1168 		win_offset = 0; /* port 0 use esmart0*/
1169 
1170 	win_offset = (vp_data->vp_use_win_id - vop2->win_reg_offset) * 0x200;
1171 
1172 	if (crtc_w > cstate->max_output.width) {
1173 		printf("ERROR: output w[%d] exceeded max width[%d]\n",
1174 		       crtc_w, cstate->max_output.width);
1175 		return -EINVAL;
1176 	}
1177 
1178 	act_info = (src_h - 1) << 16;
1179 	act_info |= (src_w - 1) & 0xffff;
1180 
1181 	dsp_info = (crtc_h - 1) << 16;
1182 	dsp_info |= (crtc_w - 1) & 0xffff;
1183 
1184 	dsp_stx = crtc_x;
1185 	dsp_sty = crtc_y;
1186 	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
1187 
1188 	if (mode->flags & DRM_MODE_FLAG_YMIRROR)
1189 		y_mirror = 1;
1190 	else
1191 		y_mirror = 0;
1192 
1193 	if (y_mirror)
1194 		cstate->dma_addr += (src_h - 1) * xvir * 4;
1195 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK,
1196 			YMIRROR_EN_SHIFT, y_mirror, false);
1197 
1198 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
1199 			WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
1200 			false);
1201 	vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir);
1202 	vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset,
1203 		    cstate->dma_addr);
1204 
1205 	vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset,
1206 		    act_info);
1207 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset,
1208 		    dsp_info);
1209 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st);
1210 
1211 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK,
1212 			WIN_EN_SHIFT, 1, false);
1213 
1214 	csc_mode = vop2_convert_csc_mode(conn_state->color_space);
1215 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK,
1216 			RGB2YUV_EN_SHIFT,
1217 			is_yuv_output(conn_state->bus_format), false);
1218 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK,
1219 			CSC_MODE_SHIFT, csc_mode, false);
1220 
1221 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
1222 	return 0;
1223 }
1224 
1225 static int rockchip_vop2_prepare(struct display_state *state)
1226 {
1227 	return 0;
1228 }
1229 
1230 static int rockchip_vop2_enable(struct display_state *state)
1231 {
1232 	struct crtc_state *cstate = &state->crtc_state;
1233 	struct vop2 *vop2 = cstate->private;
1234 	u32 vp_offset = (cstate->crtc_id * 0x100);
1235 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id);
1236 
1237 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1238 			STANDBY_EN_SHIFT, 0, false);
1239 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
1240 
1241 	return 0;
1242 }
1243 
1244 static int rockchip_vop2_disable(struct display_state *state)
1245 {
1246 	struct crtc_state *cstate = &state->crtc_state;
1247 	struct vop2 *vop2 = cstate->private;
1248 	u32 vp_offset = (cstate->crtc_id * 0x100);
1249 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id);
1250 
1251 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
1252 			STANDBY_EN_SHIFT, 1, false);
1253 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
1254 
1255 	return 0;
1256 }
1257 
1258 static struct vop2_vp_data rk3568_vp_data[3] = {
1259 	/**
1260 	 * vp_use_win_id index
1261 	 *
1262 	 * Cluster0-Win0: 0
1263 	 * Cluster1-Win0: 1
1264 	 * Esmart0-Win0:  2
1265 	 * Esmart1-Win0:  3
1266 	 * Smart0-Win0:   4
1267 	 * Smart1-Win0:   5
1268 	 *
1269 	 * for rk356x
1270 	 *   Esmart0-Win0[2]->vp0
1271 	 *   Smart0-Win0[4] ->vp1
1272 	 *   Esmart1-Win0[3]->vp2
1273 	 */
1274 	{
1275 		.feature = VOP_FEATURE_OUTPUT_10BIT,
1276 		.vp_use_win_id = 2, /* vp_use_win_id index */
1277 		.pre_scan_max_dly = 42,
1278 		.max_output = {4096, 2304},
1279 	},
1280 	{
1281 		.feature = 0,
1282 		.vp_use_win_id = 4,
1283 		.pre_scan_max_dly = 40,
1284 		.max_output = {2048, 1536},
1285 	},
1286 	{
1287 		.feature = 0,
1288 		.vp_use_win_id = 3,
1289 		.pre_scan_max_dly = 40,
1290 		.max_output = {1920, 1080},
1291 	},
1292 };
1293 
1294 const struct vop2_data rk3568_vop = {
1295 	.nr_vps = 3,
1296 	.vp_data = rk3568_vp_data,
1297 	.used_layers = {1, 1, 4},
1298 	/**
1299 	 * layer select win id: for register VOP2_LAYER_SEL
1300 	 *
1301 	 * Cluster0-Win0: 0
1302 	 * Cluster1-Win0: 1
1303 	 * Esmart0-Win0:  2
1304 	 * Smart0-Win0:   3
1305 	 * reserved:      4
1306 	 * reserved:      5
1307 	 * Esmart1-Win0:  6
1308 	 * Smart1-Win0:   7
1309 	 */
1310 	.layer_sel_id = {2, 3, 6, 7, 0, 1},
1311 	/**
1312 	 * win offset for register VOP2_PORT_SEL and win register
1313 	 *
1314 	 * Cluster0-Win0: 0
1315 	 * Cluster1-Win0: 1
1316 	 * reserved:      2
1317 	 * reserved:      3
1318 	 * Esmart0-Win0:  4
1319 	 * Smart0-Win0:   5
1320 	 * Esmart1-Win0:  6
1321 	 * Smart1-Win0:   7
1322 	 */
1323 	.win_offset = {0, 1, 4, 5, 6, 7},
1324 	.nr_layers = 6,
1325 	.nr_mixers = 5,
1326 };
1327 
1328 const struct rockchip_crtc_funcs rockchip_vop2_funcs = {
1329 	.preinit = rockchip_vop2_preinit,
1330 	.prepare = rockchip_vop2_prepare,
1331 	.init = rockchip_vop2_init,
1332 	.set_plane = rockchip_vop2_set_plane,
1333 	.enable = rockchip_vop2_enable,
1334 	.disable = rockchip_vop2_disable,
1335 };
1336