xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_vop2.c (revision 1e890c7070a4327edda488973f9d4e7add3f4de5)
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 <regmap.h>
14 #include <asm/arch/cpu.h>
15 #include <asm/unaligned.h>
16 #include <asm/io.h>
17 #include <linux/list.h>
18 #include <linux/log2.h>
19 #include <linux/media-bus-format.h>
20 #include <clk.h>
21 #include <asm/arch/clock.h>
22 #include <linux/err.h>
23 #include <linux/ioport.h>
24 #include <dm/device.h>
25 #include <dm/read.h>
26 #include <fixp-arith.h>
27 #include <syscon.h>
28 #include <linux/iopoll.h>
29 
30 #include "rockchip_display.h"
31 #include "rockchip_crtc.h"
32 #include "rockchip_connector.h"
33 
34 /* System registers definition */
35 #define RK3568_REG_CFG_DONE			0x000
36 #define	CFG_DONE_EN				BIT(15)
37 
38 #define RK3568_VERSION_INFO			0x004
39 #define EN_MASK					1
40 
41 #define RK3568_AUTO_GATING_CTRL			0x008
42 
43 #define RK3568_SYS_AXI_LUT_CTRL			0x024
44 #define LUT_DMA_EN_SHIFT			0
45 
46 #define RK3568_DSP_IF_EN			0x028
47 #define RGB_EN_SHIFT				0
48 #define RK3588_DP0_EN_SHIFT			0
49 #define RK3588_DP1_EN_SHIFT			1
50 #define RK3588_RGB_EN_SHIFT			8
51 #define HDMI0_EN_SHIFT				1
52 #define EDP0_EN_SHIFT				3
53 #define RK3588_EDP0_EN_SHIFT			2
54 #define RK3588_HDMI0_EN_SHIFT			3
55 #define MIPI0_EN_SHIFT				4
56 #define RK3588_EDP1_EN_SHIFT			4
57 #define RK3588_HDMI1_EN_SHIFT			5
58 #define RK3588_MIPI0_EN_SHIFT                   6
59 #define MIPI1_EN_SHIFT				20
60 #define RK3588_MIPI1_EN_SHIFT                   7
61 #define LVDS0_EN_SHIFT				5
62 #define LVDS1_EN_SHIFT				24
63 #define BT1120_EN_SHIFT				6
64 #define BT656_EN_SHIFT				7
65 #define IF_MUX_MASK				3
66 #define RGB_MUX_SHIFT				8
67 #define HDMI0_MUX_SHIFT				10
68 #define RK3588_DP0_MUX_SHIFT			12
69 #define RK3588_DP1_MUX_SHIFT			14
70 #define EDP0_MUX_SHIFT				14
71 #define RK3588_HDMI_EDP0_MUX_SHIFT		16
72 #define RK3588_HDMI_EDP1_MUX_SHIFT		18
73 #define MIPI0_MUX_SHIFT				16
74 #define RK3588_MIPI0_MUX_SHIFT			20
75 #define MIPI1_MUX_SHIFT				21
76 #define LVDS0_MUX_SHIFT				18
77 #define LVDS1_MUX_SHIFT				25
78 
79 #define RK3568_DSP_IF_CTRL			0x02c
80 #define LVDS_DUAL_EN_SHIFT			0
81 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT		1
82 #define LVDS_DUAL_SWAP_EN_SHIFT			2
83 #define RK3568_MIPI_DUAL_EN_SHIFT		10
84 #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT		11
85 #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT		12
86 
87 #define RK3568_DSP_IF_POL			0x030
88 #define IF_CTRL_REG_DONE_IMD_MASK		1
89 #define IF_CTRL_REG_DONE_IMD_SHIFT		28
90 #define IF_CRTL_MIPI_DCLK_POL_SHIT		19
91 #define IF_CRTL_EDP_DCLK_POL_SHIT		15
92 #define IF_CRTL_HDMI_DCLK_POL_SHIT		7
93 #define IF_CRTL_HDMI_PIN_POL_MASK		0x7
94 #define IF_CRTL_HDMI_PIN_POL_SHIT		4
95 
96 #define RK3588_DP0_PIN_POL_SHIFT		8
97 #define RK3588_DP1_PIN_POL_SHIFT		12
98 #define RK3588_IF_PIN_POL_MASK			0x7
99 
100 #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT		3
101 
102 #define HDMI_EDP0_DCLK_DIV_SHIFT		16
103 #define HDMI_EDP0_PIXCLK_DIV_SHIFT		18
104 #define HDMI_EDP1_DCLK_DIV_SHIFT		20
105 #define HDMI_EDP1_PIXCLK_DIV_SHIFT		22
106 #define MIPI0_PIXCLK_DIV_SHIFT			24
107 #define MIPI1_PIXCLK_DIV_SHIFT			26
108 
109 #define RK3568_SYS_OTP_WIN_EN			0x50
110 #define OTP_WIN_EN_SHIFT			0
111 #define RK3568_SYS_LUT_PORT_SEL			0x58
112 #define GAMMA_PORT_SEL_MASK			0x3
113 #define GAMMA_PORT_SEL_SHIFT			0
114 
115 #define RK3568_SYS_PD_CTRL			0x034
116 #define RK3568_VP0_LINE_FLAG			0x70
117 #define RK3568_VP1_LINE_FLAG			0x74
118 #define RK3568_VP2_LINE_FLAG			0x78
119 #define RK3568_SYS0_INT_EN			0x80
120 #define RK3568_SYS0_INT_CLR			0x84
121 #define RK3568_SYS0_INT_STATUS			0x88
122 #define RK3568_SYS1_INT_EN			0x90
123 #define RK3568_SYS1_INT_CLR			0x94
124 #define RK3568_SYS1_INT_STATUS			0x98
125 #define RK3568_VP0_INT_EN			0xA0
126 #define RK3568_VP0_INT_CLR			0xA4
127 #define RK3568_VP0_INT_STATUS			0xA8
128 #define RK3568_VP1_INT_EN			0xB0
129 #define RK3568_VP1_INT_CLR			0xB4
130 #define RK3568_VP1_INT_STATUS			0xB8
131 #define RK3568_VP2_INT_EN			0xC0
132 #define RK3568_VP2_INT_CLR			0xC4
133 #define RK3568_VP2_INT_STATUS			0xC8
134 #define RK3588_CLUSTER0_PD_EN_SHIFT		0
135 #define RK3588_CLUSTER1_PD_EN_SHIFT		1
136 #define RK3588_CLUSTER2_PD_EN_SHIFT		2
137 #define RK3588_CLUSTER3_PD_EN_SHIFT		3
138 #define RK3588_ESMART_PD_EN_SHIFT		7
139 
140 #define RK3568_SYS_STATUS0			0x60
141 #define RK3588_CLUSTER0_PD_STATUS_SHIFT		8
142 #define RK3588_CLUSTER1_PD_STATUS_SHIFT		9
143 #define RK3588_CLUSTER2_PD_STATUS_SHIFT		10
144 #define RK3588_CLUSTER3_PD_STATUS_SHIFT		11
145 #define RK3588_ESMART_PD_STATUS_SHIFT		15
146 
147 #define RK3568_SYS_CTRL_LINE_FLAG0		0x70
148 #define LINE_FLAG_NUM_MASK			0x1fff
149 #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT		0
150 #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT		16
151 
152 /* Overlay registers definition    */
153 #define RK3568_OVL_CTRL				0x600
154 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT		28
155 #define RK3568_OVL_LAYER_SEL			0x604
156 #define LAYER_SEL_MASK				0xf
157 
158 #define RK3568_OVL_PORT_SEL			0x608
159 #define PORT_MUX_MASK				0xf
160 #define PORT_MUX_SHIFT				0
161 #define LAYER_SEL_PORT_MASK			0x3
162 #define LAYER_SEL_PORT_SHIFT			16
163 
164 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL	0x610
165 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL	0x614
166 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x618
167 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL	0x61C
168 #define RK3568_MIX0_SRC_COLOR_CTRL		0x650
169 #define RK3568_MIX0_DST_COLOR_CTRL		0x654
170 #define RK3568_MIX0_SRC_ALPHA_CTRL		0x658
171 #define RK3568_MIX0_DST_ALPHA_CTRL		0x65C
172 #define RK3568_HDR0_SRC_COLOR_CTRL		0x6C0
173 #define RK3568_HDR0_DST_COLOR_CTRL		0x6C4
174 #define RK3568_HDR0_SRC_ALPHA_CTRL		0x6C8
175 #define RK3568_HDR0_DST_ALPHA_CTRL		0x6CC
176 #define RK3568_VP0_BG_MIX_CTRL			0x6E0
177 #define BG_MIX_CTRL_MASK			0xff
178 #define BG_MIX_CTRL_SHIFT			24
179 #define RK3568_VP1_BG_MIX_CTRL			0x6E4
180 #define RK3568_VP2_BG_MIX_CTRL			0x6E8
181 #define RK3568_CLUSTER_DLY_NUM			0x6F0
182 #define RK3568_SMART_DLY_NUM			0x6F8
183 
184 /* Video Port registers definition */
185 #define RK3568_VP0_DSP_CTRL			0xC00
186 #define OUT_MODE_MASK				0xf
187 #define OUT_MODE_SHIFT				0
188 #define DATA_SWAP_MASK				0x1f
189 #define DATA_SWAP_SHIFT				8
190 #define DSP_BG_SWAP				0x1
191 #define DSP_RB_SWAP				0x2
192 #define DSP_RG_SWAP				0x4
193 #define DSP_DELTA_SWAP				0x8
194 #define CORE_DCLK_DIV_EN_SHIFT			4
195 #define P2I_EN_SHIFT				5
196 #define DSP_FILED_POL				6
197 #define INTERLACE_EN_SHIFT			7
198 #define POST_DSP_OUT_R2Y_SHIFT			15
199 #define PRE_DITHER_DOWN_EN_SHIFT		16
200 #define DITHER_DOWN_EN_SHIFT			17
201 #define DSP_LUT_EN_SHIFT			28
202 
203 #define STANDBY_EN_SHIFT			31
204 
205 #define RK3568_VP0_MIPI_CTRL			0xC04
206 #define DCLK_DIV2_SHIFT				4
207 #define DCLK_DIV2_MASK				0x3
208 #define MIPI_DUAL_EN_SHIFT			20
209 #define MIPI_DUAL_SWAP_EN_SHIFT			21
210 #define EDPI_TE_EN				28
211 #define EDPI_WMS_HOLD_EN			30
212 #define EDPI_WMS_FS				31
213 
214 
215 #define RK3568_VP0_COLOR_BAR_CTRL		0xC08
216 #define RK3568_VP0_3D_LUT_CTRL			0xC10
217 #define VP0_3D_LUT_EN_SHIFT				0
218 #define VP0_3D_LUT_UPDATE_SHIFT			2
219 
220 #define RK3588_VP0_CLK_CTRL			0xC0C
221 #define DCLK_CORE_DIV_SHIFT			0
222 #define DCLK_OUT_DIV_SHIFT			2
223 
224 #define RK3568_VP0_3D_LUT_MST			0xC20
225 
226 #define RK3568_VP0_DSP_BG			0xC2C
227 #define RK3568_VP0_PRE_SCAN_HTIMING		0xC30
228 #define RK3568_VP0_POST_DSP_HACT_INFO		0xC34
229 #define RK3568_VP0_POST_DSP_VACT_INFO		0xC38
230 #define RK3568_VP0_POST_SCL_FACTOR_YRGB		0xC3C
231 #define RK3568_VP0_POST_SCL_CTRL		0xC40
232 #define RK3568_VP0_POST_DSP_VACT_INFO_F1	0xC44
233 #define RK3568_VP0_DSP_HTOTAL_HS_END		0xC48
234 #define RK3568_VP0_DSP_HACT_ST_END		0xC4C
235 #define RK3568_VP0_DSP_VTOTAL_VS_END		0xC50
236 #define RK3568_VP0_DSP_VACT_ST_END		0xC54
237 #define RK3568_VP0_DSP_VS_ST_END_F1		0xC58
238 #define RK3568_VP0_DSP_VACT_ST_END_F1		0xC5C
239 
240 #define RK3568_VP0_BCSH_CTRL			0xC60
241 #define BCSH_CTRL_Y2R_SHIFT			0
242 #define BCSH_CTRL_Y2R_MASK			0x1
243 #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT		2
244 #define BCSH_CTRL_Y2R_CSC_MODE_MASK		0x3
245 #define BCSH_CTRL_R2Y_SHIFT			4
246 #define BCSH_CTRL_R2Y_MASK			0x1
247 #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT		6
248 #define BCSH_CTRL_R2Y_CSC_MODE_MASK		0x3
249 
250 #define RK3568_VP0_BCSH_BCS			0xC64
251 #define BCSH_BRIGHTNESS_SHIFT			0
252 #define BCSH_BRIGHTNESS_MASK			0xFF
253 #define BCSH_CONTRAST_SHIFT			8
254 #define BCSH_CONTRAST_MASK			0x1FF
255 #define BCSH_SATURATION_SHIFT			20
256 #define BCSH_SATURATION_MASK			0x3FF
257 #define BCSH_OUT_MODE_SHIFT			30
258 #define BCSH_OUT_MODE_MASK			0x3
259 
260 #define RK3568_VP0_BCSH_H			0xC68
261 #define BCSH_SIN_HUE_SHIFT			0
262 #define BCSH_SIN_HUE_MASK			0x1FF
263 #define BCSH_COS_HUE_SHIFT			16
264 #define BCSH_COS_HUE_MASK			0x1FF
265 
266 #define RK3568_VP0_BCSH_COLOR			0xC6C
267 #define BCSH_EN_SHIFT				31
268 #define BCSH_EN_MASK				1
269 
270 #define RK3568_VP1_DSP_CTRL			0xD00
271 #define RK3568_VP1_MIPI_CTRL			0xD04
272 #define RK3568_VP1_COLOR_BAR_CTRL		0xD08
273 #define RK3568_VP1_PRE_SCAN_HTIMING		0xD30
274 #define RK3568_VP1_POST_DSP_HACT_INFO		0xD34
275 #define RK3568_VP1_POST_DSP_VACT_INFO		0xD38
276 #define RK3568_VP1_POST_SCL_FACTOR_YRGB		0xD3C
277 #define RK3568_VP1_POST_SCL_CTRL		0xD40
278 #define RK3568_VP1_DSP_HACT_INFO		0xD34
279 #define RK3568_VP1_DSP_VACT_INFO		0xD38
280 #define RK3568_VP1_POST_DSP_VACT_INFO_F1	0xD44
281 #define RK3568_VP1_DSP_HTOTAL_HS_END		0xD48
282 #define RK3568_VP1_DSP_HACT_ST_END		0xD4C
283 #define RK3568_VP1_DSP_VTOTAL_VS_END		0xD50
284 #define RK3568_VP1_DSP_VACT_ST_END		0xD54
285 #define RK3568_VP1_DSP_VS_ST_END_F1		0xD58
286 #define RK3568_VP1_DSP_VACT_ST_END_F1		0xD5C
287 
288 #define RK3568_VP2_DSP_CTRL			0xE00
289 #define RK3568_VP2_MIPI_CTRL			0xE04
290 #define RK3568_VP2_COLOR_BAR_CTRL		0xE08
291 #define RK3568_VP2_PRE_SCAN_HTIMING		0xE30
292 #define RK3568_VP2_POST_DSP_HACT_INFO		0xE34
293 #define RK3568_VP2_POST_DSP_VACT_INFO		0xE38
294 #define RK3568_VP2_POST_SCL_FACTOR_YRGB		0xE3C
295 #define RK3568_VP2_POST_SCL_CTRL		0xE40
296 #define RK3568_VP2_DSP_HACT_INFO		0xE34
297 #define RK3568_VP2_DSP_VACT_INFO		0xE38
298 #define RK3568_VP2_POST_DSP_VACT_INFO_F1	0xE44
299 #define RK3568_VP2_DSP_HTOTAL_HS_END		0xE48
300 #define RK3568_VP2_DSP_HACT_ST_END		0xE4C
301 #define RK3568_VP2_DSP_VTOTAL_VS_END		0xE50
302 #define RK3568_VP2_DSP_VACT_ST_END		0xE54
303 #define RK3568_VP2_DSP_VS_ST_END_F1		0xE58
304 #define RK3568_VP2_DSP_VACT_ST_END_F1		0xE5C
305 
306 /* Cluster0 register definition */
307 #define RK3568_CLUSTER0_WIN0_CTRL0		0x1000
308 #define CLUSTER_YUV2RGB_EN_SHIFT		8
309 #define CLUSTER_RGB2YUV_EN_SHIFT		9
310 #define CLUSTER_CSC_MODE_SHIFT			10
311 #define CLUSTER_YRGB_XSCL_MODE_SHIFT		12
312 #define CLUSTER_YRGB_YSCL_MODE_SHIFT		14
313 #define RK3568_CLUSTER0_WIN0_CTRL1		0x1004
314 #define CLUSTER_YRGB_GT2_SHIFT			28
315 #define CLUSTER_YRGB_GT4_SHIFT			29
316 #define RK3568_CLUSTER0_WIN0_CTRL2		0x1008
317 #define CLUSTER_AXI_YRGB_ID_MASK		0x1f
318 #define CLUSTER_AXI_YRGB_ID_SHIFT		0
319 #define CLUSTER_AXI_UV_ID_MASK			0x1f
320 #define CLUSTER_AXI_UV_ID_SHIFT			5
321 
322 #define RK3568_CLUSTER0_WIN0_YRGB_MST		0x1010
323 #define RK3568_CLUSTER0_WIN0_CBR_MST		0x1014
324 #define RK3568_CLUSTER0_WIN0_VIR		0x1018
325 #define RK3568_CLUSTER0_WIN0_ACT_INFO		0x1020
326 #define RK3568_CLUSTER0_WIN0_DSP_INFO		0x1024
327 #define RK3568_CLUSTER0_WIN0_DSP_ST		0x1028
328 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB	0x1030
329 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE	0x1054
330 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR	0x1058
331 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH	0x105C
332 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE	0x1060
333 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET	0x1064
334 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET	0x1068
335 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL		0x106C
336 
337 #define RK3568_CLUSTER0_WIN1_CTRL0		0x1080
338 #define RK3568_CLUSTER0_WIN1_CTRL1		0x1084
339 #define RK3568_CLUSTER0_WIN1_YRGB_MST		0x1090
340 #define RK3568_CLUSTER0_WIN1_CBR_MST		0x1094
341 #define RK3568_CLUSTER0_WIN1_VIR		0x1098
342 #define RK3568_CLUSTER0_WIN1_ACT_INFO		0x10A0
343 #define RK3568_CLUSTER0_WIN1_DSP_INFO		0x10A4
344 #define RK3568_CLUSTER0_WIN1_DSP_ST		0x10A8
345 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB	0x10B0
346 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE	0x10D4
347 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR	0x10D8
348 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH	0x10DC
349 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE	0x10E0
350 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET	0x10E4
351 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET	0x10E8
352 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL		0x10EC
353 
354 #define RK3568_CLUSTER0_CTRL			0x1100
355 #define CLUSTER_EN_SHIFT			0
356 #define CLUSTER_AXI_ID_MASK			0x1
357 #define CLUSTER_AXI_ID_SHIFT			13
358 
359 #define RK3568_CLUSTER1_WIN0_CTRL0		0x1200
360 #define RK3568_CLUSTER1_WIN0_CTRL1		0x1204
361 #define RK3568_CLUSTER1_WIN0_YRGB_MST		0x1210
362 #define RK3568_CLUSTER1_WIN0_CBR_MST		0x1214
363 #define RK3568_CLUSTER1_WIN0_VIR		0x1218
364 #define RK3568_CLUSTER1_WIN0_ACT_INFO		0x1220
365 #define RK3568_CLUSTER1_WIN0_DSP_INFO		0x1224
366 #define RK3568_CLUSTER1_WIN0_DSP_ST		0x1228
367 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB	0x1230
368 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE	0x1254
369 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR	0x1258
370 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH	0x125C
371 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE	0x1260
372 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET	0x1264
373 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET	0x1268
374 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL		0x126C
375 
376 #define RK3568_CLUSTER1_WIN1_CTRL0		0x1280
377 #define RK3568_CLUSTER1_WIN1_CTRL1		0x1284
378 #define RK3568_CLUSTER1_WIN1_YRGB_MST		0x1290
379 #define RK3568_CLUSTER1_WIN1_CBR_MST		0x1294
380 #define RK3568_CLUSTER1_WIN1_VIR		0x1298
381 #define RK3568_CLUSTER1_WIN1_ACT_INFO		0x12A0
382 #define RK3568_CLUSTER1_WIN1_DSP_INFO		0x12A4
383 #define RK3568_CLUSTER1_WIN1_DSP_ST		0x12A8
384 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB	0x12B0
385 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE	0x12D4
386 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR	0x12D8
387 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH	0x12DC
388 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE	0x12E0
389 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET	0x12E4
390 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET	0x12E8
391 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL		0x12EC
392 
393 #define RK3568_CLUSTER1_CTRL			0x1300
394 
395 /* Esmart register definition */
396 #define RK3568_ESMART0_CTRL0			0x1800
397 #define RGB2YUV_EN_SHIFT			1
398 #define CSC_MODE_SHIFT				2
399 #define CSC_MODE_MASK				0x3
400 
401 #define RK3568_ESMART0_CTRL1			0x1804
402 #define ESMART_AXI_YRGB_ID_MASK			0x1f
403 #define ESMART_AXI_YRGB_ID_SHIFT		4
404 #define ESMART_AXI_UV_ID_MASK			0x1f
405 #define ESMART_AXI_UV_ID_SHIFT			12
406 #define YMIRROR_EN_SHIFT			31
407 
408 #define RK3568_ESMART0_AXI_CTRL			0x1808
409 #define ESMART_AXI_ID_MASK			0x1
410 #define ESMART_AXI_ID_SHIFT			1
411 
412 #define RK3568_ESMART0_REGION0_CTRL		0x1810
413 #define REGION0_RB_SWAP_SHIFT			14
414 #define WIN_EN_SHIFT				0
415 #define WIN_FORMAT_MASK				0x1f
416 #define WIN_FORMAT_SHIFT			1
417 
418 #define RK3568_ESMART0_REGION0_YRGB_MST		0x1814
419 #define RK3568_ESMART0_REGION0_CBR_MST		0x1818
420 #define RK3568_ESMART0_REGION0_VIR		0x181C
421 #define RK3568_ESMART0_REGION0_ACT_INFO		0x1820
422 #define RK3568_ESMART0_REGION0_DSP_INFO		0x1824
423 #define RK3568_ESMART0_REGION0_DSP_ST		0x1828
424 #define RK3568_ESMART0_REGION0_SCL_CTRL		0x1830
425 #define YRGB_XSCL_MODE_MASK			0x3
426 #define YRGB_XSCL_MODE_SHIFT			0
427 #define YRGB_XSCL_FILTER_MODE_MASK		0x3
428 #define YRGB_XSCL_FILTER_MODE_SHIFT		2
429 #define YRGB_YSCL_MODE_MASK			0x3
430 #define YRGB_YSCL_MODE_SHIFT			4
431 #define YRGB_YSCL_FILTER_MODE_MASK		0x3
432 #define YRGB_YSCL_FILTER_MODE_SHIFT		6
433 
434 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB	0x1834
435 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR	0x1838
436 #define RK3568_ESMART0_REGION0_SCL_OFFSET	0x183C
437 #define RK3568_ESMART0_REGION1_CTRL		0x1840
438 #define YRGB_GT2_MASK				0x1
439 #define YRGB_GT2_SHIFT				8
440 #define YRGB_GT4_MASK				0x1
441 #define YRGB_GT4_SHIFT				9
442 
443 #define RK3568_ESMART0_REGION1_YRGB_MST		0x1844
444 #define RK3568_ESMART0_REGION1_CBR_MST		0x1848
445 #define RK3568_ESMART0_REGION1_VIR		0x184C
446 #define RK3568_ESMART0_REGION1_ACT_INFO		0x1850
447 #define RK3568_ESMART0_REGION1_DSP_INFO		0x1854
448 #define RK3568_ESMART0_REGION1_DSP_ST		0x1858
449 #define RK3568_ESMART0_REGION1_SCL_CTRL		0x1860
450 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB	0x1864
451 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR	0x1868
452 #define RK3568_ESMART0_REGION1_SCL_OFFSET	0x186C
453 #define RK3568_ESMART0_REGION2_CTRL		0x1870
454 #define RK3568_ESMART0_REGION2_YRGB_MST		0x1874
455 #define RK3568_ESMART0_REGION2_CBR_MST		0x1878
456 #define RK3568_ESMART0_REGION2_VIR		0x187C
457 #define RK3568_ESMART0_REGION2_ACT_INFO		0x1880
458 #define RK3568_ESMART0_REGION2_DSP_INFO		0x1884
459 #define RK3568_ESMART0_REGION2_DSP_ST		0x1888
460 #define RK3568_ESMART0_REGION2_SCL_CTRL		0x1890
461 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB	0x1894
462 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR	0x1898
463 #define RK3568_ESMART0_REGION2_SCL_OFFSET	0x189C
464 #define RK3568_ESMART0_REGION3_CTRL		0x18A0
465 #define RK3568_ESMART0_REGION3_YRGB_MST		0x18A4
466 #define RK3568_ESMART0_REGION3_CBR_MST		0x18A8
467 #define RK3568_ESMART0_REGION3_VIR		0x18AC
468 #define RK3568_ESMART0_REGION3_ACT_INFO		0x18B0
469 #define RK3568_ESMART0_REGION3_DSP_INFO		0x18B4
470 #define RK3568_ESMART0_REGION3_DSP_ST		0x18B8
471 #define RK3568_ESMART0_REGION3_SCL_CTRL		0x18C0
472 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB	0x18C4
473 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR	0x18C8
474 #define RK3568_ESMART0_REGION3_SCL_OFFSET	0x18CC
475 
476 #define RK3568_ESMART1_CTRL0			0x1A00
477 #define RK3568_ESMART1_CTRL1			0x1A04
478 #define RK3568_ESMART1_REGION0_CTRL		0x1A10
479 #define RK3568_ESMART1_REGION0_YRGB_MST		0x1A14
480 #define RK3568_ESMART1_REGION0_CBR_MST		0x1A18
481 #define RK3568_ESMART1_REGION0_VIR		0x1A1C
482 #define RK3568_ESMART1_REGION0_ACT_INFO		0x1A20
483 #define RK3568_ESMART1_REGION0_DSP_INFO		0x1A24
484 #define RK3568_ESMART1_REGION0_DSP_ST		0x1A28
485 #define RK3568_ESMART1_REGION0_SCL_CTRL		0x1A30
486 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB	0x1A34
487 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR	0x1A38
488 #define RK3568_ESMART1_REGION0_SCL_OFFSET	0x1A3C
489 #define RK3568_ESMART1_REGION1_CTRL		0x1A40
490 #define RK3568_ESMART1_REGION1_YRGB_MST		0x1A44
491 #define RK3568_ESMART1_REGION1_CBR_MST		0x1A48
492 #define RK3568_ESMART1_REGION1_VIR		0x1A4C
493 #define RK3568_ESMART1_REGION1_ACT_INFO		0x1A50
494 #define RK3568_ESMART1_REGION1_DSP_INFO		0x1A54
495 #define RK3568_ESMART1_REGION1_DSP_ST		0x1A58
496 #define RK3568_ESMART1_REGION1_SCL_CTRL		0x1A60
497 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB	0x1A64
498 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR	0x1A68
499 #define RK3568_ESMART1_REGION1_SCL_OFFSET	0x1A6C
500 #define RK3568_ESMART1_REGION2_CTRL		0x1A70
501 #define RK3568_ESMART1_REGION2_YRGB_MST		0x1A74
502 #define RK3568_ESMART1_REGION2_CBR_MST		0x1A78
503 #define RK3568_ESMART1_REGION2_VIR		0x1A7C
504 #define RK3568_ESMART1_REGION2_ACT_INFO		0x1A80
505 #define RK3568_ESMART1_REGION2_DSP_INFO		0x1A84
506 #define RK3568_ESMART1_REGION2_DSP_ST		0x1A88
507 #define RK3568_ESMART1_REGION2_SCL_CTRL		0x1A90
508 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB	0x1A94
509 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR	0x1A98
510 #define RK3568_ESMART1_REGION2_SCL_OFFSET	0x1A9C
511 #define RK3568_ESMART1_REGION3_CTRL		0x1AA0
512 #define RK3568_ESMART1_REGION3_YRGB_MST		0x1AA4
513 #define RK3568_ESMART1_REGION3_CBR_MST		0x1AA8
514 #define RK3568_ESMART1_REGION3_VIR		0x1AAC
515 #define RK3568_ESMART1_REGION3_ACT_INFO		0x1AB0
516 #define RK3568_ESMART1_REGION3_DSP_INFO		0x1AB4
517 #define RK3568_ESMART1_REGION3_DSP_ST		0x1AB8
518 #define RK3568_ESMART1_REGION3_SCL_CTRL		0x1AC0
519 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB	0x1AC4
520 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR	0x1AC8
521 #define RK3568_ESMART1_REGION3_SCL_OFFSET	0x1ACC
522 
523 #define RK3568_SMART0_CTRL0			0x1C00
524 #define RK3568_SMART0_CTRL1			0x1C04
525 #define RK3568_SMART0_REGION0_CTRL		0x1C10
526 #define RK3568_SMART0_REGION0_YRGB_MST		0x1C14
527 #define RK3568_SMART0_REGION0_CBR_MST		0x1C18
528 #define RK3568_SMART0_REGION0_VIR		0x1C1C
529 #define RK3568_SMART0_REGION0_ACT_INFO		0x1C20
530 #define RK3568_SMART0_REGION0_DSP_INFO		0x1C24
531 #define RK3568_SMART0_REGION0_DSP_ST		0x1C28
532 #define RK3568_SMART0_REGION0_SCL_CTRL		0x1C30
533 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB	0x1C34
534 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR	0x1C38
535 #define RK3568_SMART0_REGION0_SCL_OFFSET	0x1C3C
536 #define RK3568_SMART0_REGION1_CTRL		0x1C40
537 #define RK3568_SMART0_REGION1_YRGB_MST		0x1C44
538 #define RK3568_SMART0_REGION1_CBR_MST		0x1C48
539 #define RK3568_SMART0_REGION1_VIR		0x1C4C
540 #define RK3568_SMART0_REGION1_ACT_INFO		0x1C50
541 #define RK3568_SMART0_REGION1_DSP_INFO		0x1C54
542 #define RK3568_SMART0_REGION1_DSP_ST		0x1C58
543 #define RK3568_SMART0_REGION1_SCL_CTRL		0x1C60
544 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB	0x1C64
545 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR	0x1C68
546 #define RK3568_SMART0_REGION1_SCL_OFFSET	0x1C6C
547 #define RK3568_SMART0_REGION2_CTRL		0x1C70
548 #define RK3568_SMART0_REGION2_YRGB_MST		0x1C74
549 #define RK3568_SMART0_REGION2_CBR_MST		0x1C78
550 #define RK3568_SMART0_REGION2_VIR		0x1C7C
551 #define RK3568_SMART0_REGION2_ACT_INFO		0x1C80
552 #define RK3568_SMART0_REGION2_DSP_INFO		0x1C84
553 #define RK3568_SMART0_REGION2_DSP_ST		0x1C88
554 #define RK3568_SMART0_REGION2_SCL_CTRL		0x1C90
555 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB	0x1C94
556 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR	0x1C98
557 #define RK3568_SMART0_REGION2_SCL_OFFSET	0x1C9C
558 #define RK3568_SMART0_REGION3_CTRL		0x1CA0
559 #define RK3568_SMART0_REGION3_YRGB_MST		0x1CA4
560 #define RK3568_SMART0_REGION3_CBR_MST		0x1CA8
561 #define RK3568_SMART0_REGION3_VIR		0x1CAC
562 #define RK3568_SMART0_REGION3_ACT_INFO		0x1CB0
563 #define RK3568_SMART0_REGION3_DSP_INFO		0x1CB4
564 #define RK3568_SMART0_REGION3_DSP_ST		0x1CB8
565 #define RK3568_SMART0_REGION3_SCL_CTRL		0x1CC0
566 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB	0x1CC4
567 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR	0x1CC8
568 #define RK3568_SMART0_REGION3_SCL_OFFSET	0x1CCC
569 
570 #define RK3568_SMART1_CTRL0			0x1E00
571 #define RK3568_SMART1_CTRL1			0x1E04
572 #define RK3568_SMART1_REGION0_CTRL		0x1E10
573 #define RK3568_SMART1_REGION0_YRGB_MST		0x1E14
574 #define RK3568_SMART1_REGION0_CBR_MST		0x1E18
575 #define RK3568_SMART1_REGION0_VIR		0x1E1C
576 #define RK3568_SMART1_REGION0_ACT_INFO		0x1E20
577 #define RK3568_SMART1_REGION0_DSP_INFO		0x1E24
578 #define RK3568_SMART1_REGION0_DSP_ST		0x1E28
579 #define RK3568_SMART1_REGION0_SCL_CTRL		0x1E30
580 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB	0x1E34
581 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR	0x1E38
582 #define RK3568_SMART1_REGION0_SCL_OFFSET	0x1E3C
583 #define RK3568_SMART1_REGION1_CTRL		0x1E40
584 #define RK3568_SMART1_REGION1_YRGB_MST		0x1E44
585 #define RK3568_SMART1_REGION1_CBR_MST		0x1E48
586 #define RK3568_SMART1_REGION1_VIR		0x1E4C
587 #define RK3568_SMART1_REGION1_ACT_INFO		0x1E50
588 #define RK3568_SMART1_REGION1_DSP_INFO		0x1E54
589 #define RK3568_SMART1_REGION1_DSP_ST		0x1E58
590 #define RK3568_SMART1_REGION1_SCL_CTRL		0x1E60
591 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB	0x1E64
592 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR	0x1E68
593 #define RK3568_SMART1_REGION1_SCL_OFFSET	0x1E6C
594 #define RK3568_SMART1_REGION2_CTRL		0x1E70
595 #define RK3568_SMART1_REGION2_YRGB_MST		0x1E74
596 #define RK3568_SMART1_REGION2_CBR_MST		0x1E78
597 #define RK3568_SMART1_REGION2_VIR		0x1E7C
598 #define RK3568_SMART1_REGION2_ACT_INFO		0x1E80
599 #define RK3568_SMART1_REGION2_DSP_INFO		0x1E84
600 #define RK3568_SMART1_REGION2_DSP_ST		0x1E88
601 #define RK3568_SMART1_REGION2_SCL_CTRL		0x1E90
602 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB	0x1E94
603 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR	0x1E98
604 #define RK3568_SMART1_REGION2_SCL_OFFSET	0x1E9C
605 #define RK3568_SMART1_REGION3_CTRL		0x1EA0
606 #define RK3568_SMART1_REGION3_YRGB_MST		0x1EA4
607 #define RK3568_SMART1_REGION3_CBR_MST		0x1EA8
608 #define RK3568_SMART1_REGION3_VIR		0x1EAC
609 #define RK3568_SMART1_REGION3_ACT_INFO		0x1EB0
610 #define RK3568_SMART1_REGION3_DSP_INFO		0x1EB4
611 #define RK3568_SMART1_REGION3_DSP_ST		0x1EB8
612 #define RK3568_SMART1_REGION3_SCL_CTRL		0x1EC0
613 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB	0x1EC4
614 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR	0x1EC8
615 #define RK3568_SMART1_REGION3_SCL_OFFSET	0x1ECC
616 
617 #define RK3568_MAX_REG				0x1ED0
618 
619 #define RK3568_GRF_VO_CON1			0x0364
620 #define GRF_BT656_CLK_INV_SHIFT			1
621 #define GRF_BT1120_CLK_INV_SHIFT		2
622 #define GRF_RGB_DCLK_INV_SHIFT			3
623 
624 #define RK3588_GRF_VOP_CON2			0x0008
625 #define RK3588_GRF_EDP0_ENABLE_SHIFT		0
626 #define RK3588_GRF_HDMITX0_ENABLE_SHIFT		1
627 #define RK3588_GRF_EDP1_ENABLE_SHIFT		3
628 #define RK3588_GRF_HDMITX1_ENABLE_SHIFT		4
629 
630 #define RK3588_GRF_VO1_CON0			0x0000
631 #define HDMI_SYNC_POL_MASK			0x3
632 #define HDMI0_SYNC_POL_SHIFT			5
633 #define HDMI1_SYNC_POL_SHIFT			7
634 
635 #define RK3588_PMU_BISR_CON3			0x20C
636 #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT	9
637 #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT	10
638 #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT	11
639 #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT	12
640 #define RK3588_PD_ESMART_REPAIR_EN_SHIFT	15
641 
642 #define RK3588_PMU_BISR_STATUS5			0x294
643 #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI	9
644 #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI	10
645 #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI	11
646 #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI	12
647 #define RK3588_PD_ESMART_PWR_STAT_SHIFI		15
648 
649 #define VOP2_LAYER_MAX				8
650 
651 #define VOP_FEATURE_OUTPUT_10BIT		BIT(0)
652 
653 enum vop2_csc_format {
654 	CSC_BT601L,
655 	CSC_BT709L,
656 	CSC_BT601F,
657 	CSC_BT2020,
658 };
659 
660 enum vop2_pol {
661 	HSYNC_POSITIVE = 0,
662 	VSYNC_POSITIVE = 1,
663 	DEN_NEGATIVE   = 2,
664 	DCLK_INVERT    = 3
665 };
666 
667 enum vop2_bcsh_out_mode {
668 	BCSH_OUT_MODE_BLACK,
669 	BCSH_OUT_MODE_BLUE,
670 	BCSH_OUT_MODE_COLOR_BAR,
671 	BCSH_OUT_MODE_NORMAL_VIDEO,
672 };
673 
674 #define _VOP_REG(off, _mask, _shift, _write_mask) \
675 		{ \
676 		 .offset = off, \
677 		 .mask = _mask, \
678 		 .shift = _shift, \
679 		 .write_mask = _write_mask, \
680 		}
681 
682 #define VOP_REG(off, _mask, _shift) \
683 		_VOP_REG(off, _mask, _shift, false)
684 enum dither_down_mode {
685 	RGB888_TO_RGB565 = 0x0,
686 	RGB888_TO_RGB666 = 0x1
687 };
688 
689 enum vop2_video_ports_id {
690 	VOP2_VP0,
691 	VOP2_VP1,
692 	VOP2_VP2,
693 	VOP2_VP3,
694 	VOP2_VP_MAX,
695 };
696 
697 enum vop2_layer_type {
698 	CLUSTER_LAYER = 0,
699 	ESMART_LAYER = 1,
700 	SMART_LAYER = 2,
701 };
702 
703 /* This define must same with kernel win phy id */
704 enum vop2_layer_phy_id {
705 	ROCKCHIP_VOP2_CLUSTER0 = 0,
706 	ROCKCHIP_VOP2_CLUSTER1,
707 	ROCKCHIP_VOP2_ESMART0,
708 	ROCKCHIP_VOP2_ESMART1,
709 	ROCKCHIP_VOP2_SMART0,
710 	ROCKCHIP_VOP2_SMART1,
711 	ROCKCHIP_VOP2_CLUSTER2,
712 	ROCKCHIP_VOP2_CLUSTER3,
713 	ROCKCHIP_VOP2_ESMART2,
714 	ROCKCHIP_VOP2_ESMART3,
715 	ROCKCHIP_VOP2_LAYER_MAX,
716 };
717 
718 enum vop2_scale_up_mode {
719 	VOP2_SCALE_UP_NRST_NBOR,
720 	VOP2_SCALE_UP_BIL,
721 	VOP2_SCALE_UP_BIC,
722 };
723 
724 enum vop2_scale_down_mode {
725 	VOP2_SCALE_DOWN_NRST_NBOR,
726 	VOP2_SCALE_DOWN_BIL,
727 	VOP2_SCALE_DOWN_AVG,
728 };
729 
730 enum scale_mode {
731 	SCALE_NONE = 0x0,
732 	SCALE_UP   = 0x1,
733 	SCALE_DOWN = 0x2
734 };
735 
736 struct vop2_layer {
737 	u8 id;
738 	/**
739 	 * @win_phys_id: window id of the layer selected.
740 	 * Every layer must make sure to select different
741 	 * windows of others.
742 	 */
743 	u8 win_phys_id;
744 };
745 
746 struct vop2_power_domain_data {
747 	bool is_enabled;
748 	bool is_parent_needed;
749 	u8 pd_en_shift;
750 	u8 pd_status_shift;
751 	u8 pmu_status_shift;
752 	u8 bisr_en_status_shift;
753 	u8 parent_phy_id;
754 };
755 
756 struct vop2_win_data {
757 	char *name;
758 	u8 phys_id;
759 	enum vop2_layer_type type;
760 	u8 win_sel_port_offset;
761 	u8 layer_sel_win_id;
762 	u8 axi_id;
763 	u8 axi_uv_id;
764 	u8 axi_yrgb_id;
765 	u32 reg_offset;
766 	struct vop2_power_domain_data *pd_data;
767 };
768 
769 struct vop2_vp_data {
770 	u32 feature;
771 	u8 pre_scan_max_dly;
772 	struct vop_rect max_output;
773 	u32 max_dclk;
774 };
775 
776 struct vop2_plane_table {
777 	enum vop2_layer_phy_id plane_id;
778 	enum vop2_layer_type plane_type;
779 };
780 
781 struct vop2_vp_plane_mask {
782 	u8 primary_plane_id; /* use this win to show logo */
783 	u8 attached_layers_nr; /* number layers attach to this vp */
784 	u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */
785 	u32 plane_mask;
786 	int cursor_plane_id;
787 };
788 
789 struct vop2_data {
790 	u32 version;
791 	struct vop2_vp_data *vp_data;
792 	struct vop2_win_data *win_data;
793 	struct vop2_vp_plane_mask *plane_mask;
794 	struct vop2_plane_table *plane_table;
795 	u8 nr_vps;
796 	u8 nr_layers;
797 	u8 nr_mixers;
798 	u8 nr_gammas;
799 	u8 nr_dscs;
800 	u32 reg_len;
801 };
802 
803 struct vop2 {
804 	u32 *regsbak;
805 	void *regs;
806 	void *grf;
807 	void *vop_grf;
808 	void *vo1_grf;
809 	void *sys_pmu;
810 	u32 reg_len;
811 	u32 version;
812 	bool global_init;
813 	const struct vop2_data *data;
814 	struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX];
815 };
816 
817 static struct vop2 *rockchip_vop2;
818 /*
819  * bli_sd_factor = (src - 1) / (dst - 1) << 12;
820  * avg_sd_factor:
821  * bli_su_factor:
822  * bic_su_factor:
823  * = (src - 1) / (dst - 1) << 16;
824  *
825  * gt2 enable: dst get one line from two line of the src
826  * gt4 enable: dst get one line from four line of the src.
827  *
828  */
829 #define VOP2_BILI_SCL_DN(src, dst)	(((src - 1) << 12) / (dst - 1))
830 #define VOP2_COMMON_SCL(src, dst)	(((src - 1) << 16) / (dst - 1))
831 
832 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)	 \
833 				(fac * (dst - 1) >> 12 < (src - 1))
834 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \
835 				(fac * (dst - 1) >> 16 < (src - 1))
836 
837 static uint16_t vop2_scale_factor(enum scale_mode mode,
838 				  int32_t filter_mode,
839 				  uint32_t src, uint32_t dst)
840 {
841 	uint32_t fac = 0;
842 	int i = 0;
843 
844 	if (mode == SCALE_NONE)
845 		return 0;
846 
847 	/*
848 	 * A workaround to avoid zero div.
849 	 */
850 	if ((dst == 1) || (src == 1)) {
851 		dst = dst + 1;
852 		src = src + 1;
853 	}
854 
855 	if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) {
856 		fac = VOP2_BILI_SCL_DN(src, dst);
857 		for (i = 0; i < 100; i++) {
858 			if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
859 				break;
860 			fac -= 1;
861 			printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
862 		}
863 	} else {
864 		fac = VOP2_COMMON_SCL(src, dst);
865 		for (i = 0; i < 100; i++) {
866 			if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac))
867 				break;
868 			fac -= 1;
869 			printf("up fac cali:  src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
870 		}
871 	}
872 
873 	return fac;
874 }
875 
876 static inline enum scale_mode scl_get_scl_mode(int src, int dst)
877 {
878 	if (src < dst)
879 		return SCALE_UP;
880 	else if (src > dst)
881 		return SCALE_DOWN;
882 
883 	return SCALE_NONE;
884 }
885 
886 static u8 rk3588_vop2_vp_primary_plane_order[VOP2_VP_MAX] = {
887 	ROCKCHIP_VOP2_ESMART0,
888 	ROCKCHIP_VOP2_ESMART1,
889 	ROCKCHIP_VOP2_ESMART2,
890 	ROCKCHIP_VOP2_ESMART3,
891 };
892 
893 static u8 rk3568_vop2_vp_primary_plane_order[VOP2_VP_MAX] = {
894 	ROCKCHIP_VOP2_SMART0,
895 	ROCKCHIP_VOP2_SMART1,
896 	ROCKCHIP_VOP2_ESMART1,
897 };
898 
899 static inline int interpolate(int x1, int y1, int x2, int y2, int x)
900 {
901 	return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
902 }
903 
904 static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask)
905 {
906 	int i = 0;
907 	u8 *vop2_vp_primary_plane_order;
908 	u8 default_primary_plane;
909 
910 	if (vop2->version == VOP_VERSION_RK3588) {
911 		vop2_vp_primary_plane_order = rk3588_vop2_vp_primary_plane_order;
912 		default_primary_plane = ROCKCHIP_VOP2_ESMART0;
913 	} else {
914 		vop2_vp_primary_plane_order = rk3568_vop2_vp_primary_plane_order;
915 		default_primary_plane = ROCKCHIP_VOP2_SMART0;
916 	}
917 
918 	for (i = 0; i < vop2->data->nr_vps; i++) {
919 		if (plane_mask & BIT(vop2_vp_primary_plane_order[i]))
920 			return vop2_vp_primary_plane_order[i];
921 	}
922 
923 	return default_primary_plane;
924 }
925 
926 static inline u16 scl_cal_scale(int src, int dst, int shift)
927 {
928 	return ((src * 2 - 3) << (shift - 1)) / (dst - 1);
929 }
930 
931 static inline u16 scl_cal_scale2(int src, int dst)
932 {
933 	return ((src - 1) << 12) / (dst - 1);
934 }
935 
936 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
937 {
938 	writel(v, vop2->regs + offset);
939 	vop2->regsbak[offset >> 2] = v;
940 }
941 
942 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
943 {
944 	return readl(vop2->regs + offset);
945 }
946 
947 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset,
948 				   u32 mask, u32 shift, u32 v,
949 				   bool write_mask)
950 {
951 	if (!mask)
952 		return;
953 
954 	if (write_mask) {
955 		v = ((v & mask) << shift) | (mask << (shift + 16));
956 	} else {
957 		u32 cached_val = vop2->regsbak[offset >> 2];
958 
959 		v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
960 		vop2->regsbak[offset >> 2] = v;
961 	}
962 
963 	writel(v, vop2->regs + offset);
964 }
965 
966 static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset,
967 				   u32 mask, u32 shift, u32 v)
968 {
969 	u32 val = 0;
970 
971 	val = (v << shift) | (mask << (shift + 16));
972 	writel(val, grf_base + offset);
973 }
974 
975 static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset,
976 				  u32 mask, u32 shift)
977 {
978 	return (readl(grf_base + offset) >> shift) & mask;
979 }
980 
981 static char* get_output_if_name(u32 output_if, char *name)
982 {
983 	if (output_if & VOP_OUTPUT_IF_RGB)
984 		strcat(name, " RGB");
985 	if (output_if & VOP_OUTPUT_IF_BT1120)
986 		strcat(name, " BT1120");
987 	if (output_if & VOP_OUTPUT_IF_BT656)
988 		strcat(name, " BT656");
989 	if (output_if & VOP_OUTPUT_IF_LVDS0)
990 		strcat(name, " LVDS0");
991 	if (output_if & VOP_OUTPUT_IF_LVDS1)
992 		strcat(name, " LVDS1");
993 	if (output_if & VOP_OUTPUT_IF_MIPI0)
994 		strcat(name, " MIPI0");
995 	if (output_if & VOP_OUTPUT_IF_MIPI1)
996 		strcat(name, " MIPI1");
997 	if (output_if & VOP_OUTPUT_IF_eDP0)
998 		strcat(name, " eDP0");
999 	if (output_if & VOP_OUTPUT_IF_eDP1)
1000 		strcat(name, " eDP1");
1001 	if (output_if & VOP_OUTPUT_IF_DP0)
1002 		strcat(name, " DP0");
1003 	if (output_if & VOP_OUTPUT_IF_DP1)
1004 		strcat(name, " DP1");
1005 	if (output_if & VOP_OUTPUT_IF_HDMI0)
1006 		strcat(name, " HDMI0");
1007 	if (output_if & VOP_OUTPUT_IF_HDMI1)
1008 		strcat(name, " HDMI1");
1009 
1010 	return name;
1011 }
1012 
1013 static char *get_plane_name(int plane_id, char *name)
1014 {
1015 	switch (plane_id) {
1016 	case ROCKCHIP_VOP2_CLUSTER0:
1017 		strcat(name, "Cluster0");
1018 		break;
1019 	case ROCKCHIP_VOP2_CLUSTER1:
1020 		strcat(name, "Cluster1");
1021 		break;
1022 	case ROCKCHIP_VOP2_ESMART0:
1023 		strcat(name, "Esmart0");
1024 		break;
1025 	case ROCKCHIP_VOP2_ESMART1:
1026 		strcat(name, "Esmart1");
1027 		break;
1028 	case ROCKCHIP_VOP2_SMART0:
1029 		strcat(name, "Smart0");
1030 		break;
1031 	case ROCKCHIP_VOP2_SMART1:
1032 		strcat(name, "Smart1");
1033 		break;
1034 	case ROCKCHIP_VOP2_CLUSTER2:
1035 		strcat(name, "Cluster2");
1036 		break;
1037 	case ROCKCHIP_VOP2_CLUSTER3:
1038 		strcat(name, "Cluster3");
1039 		break;
1040 	case ROCKCHIP_VOP2_ESMART2:
1041 		strcat(name, "Esmart2");
1042 		break;
1043 	case ROCKCHIP_VOP2_ESMART3:
1044 		strcat(name, "Esmart3");
1045 		break;
1046 	}
1047 
1048 	return name;
1049 }
1050 
1051 static bool is_yuv_output(u32 bus_format)
1052 {
1053 	switch (bus_format) {
1054 	case MEDIA_BUS_FMT_YUV8_1X24:
1055 	case MEDIA_BUS_FMT_YUV10_1X30:
1056 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1057 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1058 	case MEDIA_BUS_FMT_YUYV8_2X8:
1059 	case MEDIA_BUS_FMT_YVYU8_2X8:
1060 	case MEDIA_BUS_FMT_UYVY8_2X8:
1061 	case MEDIA_BUS_FMT_VYUY8_2X8:
1062 	case MEDIA_BUS_FMT_YUYV8_1X16:
1063 	case MEDIA_BUS_FMT_YVYU8_1X16:
1064 	case MEDIA_BUS_FMT_UYVY8_1X16:
1065 	case MEDIA_BUS_FMT_VYUY8_1X16:
1066 		return true;
1067 	default:
1068 		return false;
1069 	}
1070 }
1071 
1072 static int vop2_convert_csc_mode(int csc_mode)
1073 {
1074 	switch (csc_mode) {
1075 	case V4L2_COLORSPACE_SMPTE170M:
1076 	case V4L2_COLORSPACE_470_SYSTEM_M:
1077 	case V4L2_COLORSPACE_470_SYSTEM_BG:
1078 		return CSC_BT601L;
1079 	case V4L2_COLORSPACE_REC709:
1080 	case V4L2_COLORSPACE_SMPTE240M:
1081 	case V4L2_COLORSPACE_DEFAULT:
1082 		return CSC_BT709L;
1083 	case V4L2_COLORSPACE_JPEG:
1084 		return CSC_BT601F;
1085 	case V4L2_COLORSPACE_BT2020:
1086 		return CSC_BT2020;
1087 	default:
1088 		return CSC_BT709L;
1089 	}
1090 }
1091 
1092 static bool is_uv_swap(u32 bus_format, u32 output_mode)
1093 {
1094 	/*
1095 	 * FIXME:
1096 	 *
1097 	 * There is no media type for YUV444 output,
1098 	 * so when out_mode is AAAA or P888, assume output is YUV444 on
1099 	 * yuv format.
1100 	 *
1101 	 * From H/W testing, YUV444 mode need a rb swap.
1102 	 */
1103 	if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
1104 	    bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
1105 	    bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
1106 	    bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
1107 	    ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
1108 	     bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
1109 	    (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
1110 	     output_mode == ROCKCHIP_OUT_MODE_P888)))
1111 		return true;
1112 	else
1113 		return false;
1114 }
1115 
1116 static inline bool is_hot_plug_devices(int output_type)
1117 {
1118 	switch (output_type) {
1119 	case DRM_MODE_CONNECTOR_HDMIA:
1120 	case DRM_MODE_CONNECTOR_HDMIB:
1121 	case DRM_MODE_CONNECTOR_TV:
1122 	case DRM_MODE_CONNECTOR_DisplayPort:
1123 	case DRM_MODE_CONNECTOR_VGA:
1124 	case DRM_MODE_CONNECTOR_Unknown:
1125 		return true;
1126 	default:
1127 		return false;
1128 	}
1129 }
1130 
1131 static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id)
1132 {
1133 	int i = 0;
1134 
1135 	for (i = 0; i < vop2->data->nr_layers; i++) {
1136 		if (vop2->data->win_data[i].phys_id == phys_id)
1137 			return &vop2->data->win_data[i];
1138 	}
1139 
1140 	return NULL;
1141 }
1142 
1143 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2,
1144 					struct display_state *state)
1145 {
1146 	struct connector_state *conn_state = &state->conn_state;
1147 	struct crtc_state *cstate = &state->crtc_state;
1148 	struct resource gamma_res;
1149 	fdt_size_t lut_size;
1150 	int i, lut_len, ret = 0;
1151 	u32 *lut_regs;
1152 	u32 *lut_val;
1153 	u32 r, g, b;
1154 	u32 vp_offset = cstate->crtc_id * 0x100;
1155 	struct base2_disp_info *disp_info = conn_state->disp_info;
1156 	static int gamma_lut_en_num = 1;
1157 
1158 	if (gamma_lut_en_num > vop2->data->nr_gammas) {
1159 		printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas);
1160 		return 0;
1161 	}
1162 
1163 	if (!disp_info)
1164 		return 0;
1165 
1166 	if (!disp_info->gamma_lut_data.size)
1167 		return 0;
1168 
1169 	ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res);
1170 	if (ret)
1171 		printf("failed to get gamma lut res\n");
1172 	lut_regs = (u32 *)gamma_res.start;
1173 	lut_size = gamma_res.end - gamma_res.start + 1;
1174 	if (lut_regs == (u32 *)FDT_ADDR_T_NONE) {
1175 		printf("failed to get gamma lut register\n");
1176 		return 0;
1177 	}
1178 	lut_len = lut_size / 4;
1179 	if (lut_len != 256 && lut_len != 1024) {
1180 		printf("Warning: unsupport gamma lut table[%d]\n", lut_len);
1181 		return 0;
1182 	}
1183 	lut_val = (u32 *)calloc(1, lut_size);
1184 	for (i = 0; i < lut_len; i++) {
1185 		r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff;
1186 		g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff;
1187 		b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff;
1188 
1189 		lut_val[i] = b * lut_len * lut_len + g * lut_len + r;
1190 	}
1191 
1192 	for (i = 0; i < lut_len; i++)
1193 		writel(lut_val[i], lut_regs + i);
1194 
1195 	vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1196 			GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT,
1197 			cstate->crtc_id , false);
1198 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1199 			EN_MASK, DSP_LUT_EN_SHIFT, 1, false);
1200 	gamma_lut_en_num++;
1201 
1202 	return 0;
1203 }
1204 
1205 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2,
1206 					struct display_state *state)
1207 {
1208 	struct connector_state *conn_state = &state->conn_state;
1209 	struct crtc_state *cstate = &state->crtc_state;
1210 	int i, cubic_lut_len;
1211 	u32 vp_offset = cstate->crtc_id * 0x100;
1212 	struct base2_disp_info *disp_info = conn_state->disp_info;
1213 	struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data;
1214 	u32 *cubic_lut_addr;
1215 
1216 	if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0)
1217 		return 0;
1218 
1219 	if (!disp_info->cubic_lut_data.size)
1220 		return 0;
1221 
1222 	cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id);
1223 	cubic_lut_len = disp_info->cubic_lut_data.size;
1224 
1225 	for (i = 0; i < cubic_lut_len / 2; i++) {
1226 		*cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) +
1227 					((lut->lgreen[2 * i] & 0xfff) << 12) +
1228 					((lut->lblue[2 * i] & 0xff) << 24);
1229 		*cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) +
1230 					((lut->lred[2 * i + 1] & 0xfff) << 4) +
1231 					((lut->lgreen[2 * i + 1] & 0xfff) << 16) +
1232 					((lut->lblue[2 * i + 1] & 0xf) << 28);
1233 		*cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4;
1234 		*cubic_lut_addr++ = 0;
1235 	}
1236 
1237 	if (cubic_lut_len % 2) {
1238 		*cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) +
1239 					((lut->lgreen[2 * i] & 0xfff) << 12) +
1240 					((lut->lblue[2 * i] & 0xff) << 24);
1241 		*cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8;
1242 		*cubic_lut_addr++ = 0;
1243 		*cubic_lut_addr = 0;
1244 	}
1245 
1246 	vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset,
1247 		    get_cubic_lut_buffer(cstate->crtc_id));
1248 	vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL,
1249 			EN_MASK, LUT_DMA_EN_SHIFT, 1, false);
1250 	vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
1251 			EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false);
1252 	vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
1253 			EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false);
1254 
1255 	return 0;
1256 }
1257 
1258 static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2)
1259 {
1260 	struct connector_state *conn_state = &state->conn_state;
1261 	struct base_bcsh_info *bcsh_info;
1262 	struct crtc_state *cstate = &state->crtc_state;
1263 	int brightness, contrast, saturation, hue, sin_hue, cos_hue;
1264 	bool bcsh_en = false, post_r2y_en = false, post_y2r_en = false;
1265 	u32 vp_offset = (cstate->crtc_id * 0x100);
1266 	int post_csc_mode;
1267 
1268 	if (!conn_state->disp_info)
1269 		return;
1270 	bcsh_info = &conn_state->disp_info->bcsh_info;
1271 	if (!bcsh_info)
1272 		return;
1273 
1274 	if (bcsh_info->brightness != 50 ||
1275 	    bcsh_info->contrast != 50 ||
1276 	    bcsh_info->saturation != 50 || bcsh_info->hue != 50)
1277 		bcsh_en = true;
1278 
1279 	if (bcsh_en) {
1280 		if (!cstate->yuv_overlay)
1281 			post_r2y_en = 1;
1282 		if (!is_yuv_output(conn_state->bus_format))
1283 			post_y2r_en = 1;
1284 	} else {
1285 		if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format))
1286 			post_r2y_en = 1;
1287 		if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format))
1288 			post_y2r_en = 1;
1289 	}
1290 
1291 	post_csc_mode = vop2_convert_csc_mode(conn_state->color_space);
1292 
1293 
1294 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK,
1295 			BCSH_CTRL_R2Y_SHIFT, post_r2y_en, false);
1296 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK,
1297 			BCSH_CTRL_Y2R_SHIFT, post_y2r_en, false);
1298 
1299 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK,
1300 			BCSH_CTRL_R2Y_CSC_MODE_SHIFT, post_csc_mode, false);
1301 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK,
1302 			BCSH_CTRL_Y2R_CSC_MODE_SHIFT, post_csc_mode, false);
1303 	if (!bcsh_en) {
1304 		vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
1305 				BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false);
1306 		return;
1307 	}
1308 
1309 	if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT)
1310 		brightness = interpolate(0, -128, 100, 127,
1311 					 bcsh_info->brightness);
1312 	else
1313 		brightness = interpolate(0, -32, 100, 31,
1314 					 bcsh_info->brightness);
1315 	contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast);
1316 	saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation);
1317 	hue = interpolate(0, -30, 100, 30, bcsh_info->hue);
1318 
1319 
1320 	/*
1321 	 *  a:[-30~0):
1322 	 *    sin_hue = 0x100 - sin(a)*256;
1323 	 *    cos_hue = cos(a)*256;
1324 	 *  a:[0~30]
1325 	 *    sin_hue = sin(a)*256;
1326 	 *    cos_hue = cos(a)*256;
1327 	 */
1328 	sin_hue = fixp_sin32(hue) >> 23;
1329 	cos_hue = fixp_cos32(hue) >> 23;
1330 
1331 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1332 			BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT,
1333 			brightness, false);
1334 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1335 			BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, contrast, false);
1336 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1337 			BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT,
1338 			saturation * contrast / 0x100, false);
1339 	vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
1340 			BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, sin_hue, false);
1341 	vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
1342 			BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, cos_hue, false);
1343 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1344 			 BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT,
1345 			BCSH_OUT_MODE_NORMAL_VIDEO, false);
1346 	vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
1347 			BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false);
1348 }
1349 
1350 static void vop2_post_config(struct display_state *state, struct vop2 *vop2)
1351 {
1352 	struct connector_state *conn_state = &state->conn_state;
1353 	struct drm_display_mode *mode = &conn_state->mode;
1354 	struct crtc_state *cstate = &state->crtc_state;
1355 	u32 vp_offset = (cstate->crtc_id * 0x100);
1356 	u16 vtotal = mode->crtc_vtotal;
1357 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1358 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1359 	u16 hdisplay = mode->crtc_hdisplay;
1360 	u16 vdisplay = mode->crtc_vdisplay;
1361 	u16 hsize =
1362 	    hdisplay * (conn_state->overscan.left_margin +
1363 			conn_state->overscan.right_margin) / 200;
1364 	u16 vsize =
1365 	    vdisplay * (conn_state->overscan.top_margin +
1366 			conn_state->overscan.bottom_margin) / 200;
1367 	u16 hact_end, vact_end;
1368 	u32 val;
1369 	u32 bg_ovl_dly, bg_dly, pre_scan_dly;
1370 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
1371 
1372 	hsize = round_down(hsize, 2);
1373 	vsize = round_down(vsize, 2);
1374 
1375 	hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200;
1376 	hact_end = hact_st + hsize;
1377 	val = hact_st << 16;
1378 	val |= hact_end;
1379 
1380 	vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val);
1381 	vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200;
1382 	vact_end = vact_st + vsize;
1383 	val = vact_st << 16;
1384 	val |= vact_end;
1385 	vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val);
1386 	val = scl_cal_scale2(vdisplay, vsize) << 16;
1387 	val |= scl_cal_scale2(hdisplay, hsize);
1388 	vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val);
1389 #define POST_HORIZONTAL_SCALEDOWN_EN(x)		((x) << 0)
1390 #define POST_VERTICAL_SCALEDOWN_EN(x)		((x) << 1)
1391 	vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset,
1392 		    POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) |
1393 		    POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize));
1394 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1395 		u16 vact_st_f1 = vtotal + vact_st + 1;
1396 		u16 vact_end_f1 = vact_st_f1 + vsize;
1397 
1398 		val = vact_st_f1 << 16 | vact_end_f1;
1399 		vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val);
1400 	}
1401 
1402 	bg_ovl_dly = cstate->crtc->vps[cstate->crtc_id].bg_ovl_dly;
1403 	bg_dly =  vop2->data->vp_data[cstate->crtc_id].pre_scan_max_dly;
1404 	bg_dly -= bg_ovl_dly;
1405 	pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
1406 	if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8)
1407 		hsync_len = 8;
1408 	pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
1409 	vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + cstate->crtc_id * 4,
1410 			BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false);
1411 	vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + vp_offset, pre_scan_dly);
1412 }
1413 
1414 /*
1415  * Read VOP internal power domain on/off status.
1416  * We should query BISR_STS register in PMU for
1417  * power up/down status when memory repair is enabled.
1418  * Return value: 1 for power on, 0 for power off;
1419  */
1420 static int vop2_wait_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data)
1421 {
1422 	int val = 0;
1423 	int shift = 0;
1424 	bool is_bisr_en = false;
1425 
1426 	is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK,
1427 				    pd_data->bisr_en_status_shift);
1428 	if (is_bisr_en) {
1429 		shift = pd_data->pmu_status_shift;
1430 		return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val,
1431 					  ((val >> shift) & 0x1), 50 * 1000);
1432 	} else {
1433 		shift = pd_data->pd_status_shift;
1434 		return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val,
1435 					  !((val >> shift) & 0x1), 50 * 1000);
1436 	}
1437 }
1438 
1439 static int vop2_power_domain_on(struct vop2 *vop2, int plane_id)
1440 {
1441 	struct vop2_win_data *win_data;
1442 	struct vop2_power_domain_data *pd_data;
1443 	int ret = 0;
1444 
1445 	win_data = vop2_find_win_by_phys_id(vop2, plane_id);
1446 	if (!win_data) {
1447 		printf("can't find win_data by phys_id\n");
1448 		return -EINVAL;
1449 	}
1450 
1451 	pd_data = win_data->pd_data;
1452 	if (!pd_data || pd_data->is_enabled) {
1453 		return 0;
1454 	} else if (pd_data->is_parent_needed) {
1455 		ret = vop2_power_domain_on(vop2, pd_data->parent_phy_id);
1456 		if (ret) {
1457 			printf("can't open parent power domain\n");
1458 			return -EINVAL;
1459 		}
1460 	}
1461 
1462 	vop2_mask_write(vop2, RK3568_SYS_PD_CTRL, EN_MASK, pd_data->pd_en_shift, 0, false);
1463 	ret = vop2_wait_power_domain_on(vop2, pd_data);
1464 	if (ret) {
1465 		printf("wait vop2 power domain timeout\n");
1466 		return ret;
1467 	}
1468 	pd_data->is_enabled = true;
1469 
1470 	return 0;
1471 }
1472 
1473 static void rk3588_vop2_regsbak(struct vop2 *vop2)
1474 {
1475 	u32 *base = vop2->regs;
1476 	int i = 0;
1477 
1478 	/*
1479 	 * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU
1480 	 */
1481 	for (i = 0; i < (vop2->reg_len >> 2); i++)
1482 		vop2->regsbak[i] = base[i];
1483 }
1484 
1485 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state)
1486 {
1487 	struct crtc_state *cstate = &state->crtc_state;
1488 	int i, j, port_mux = 0, total_used_layer = 0;
1489 	u8 shift = 0;
1490 	int layer_phy_id = 0;
1491 	u32 layer_nr = 0;
1492 	struct vop2_win_data *win_data;
1493 	struct vop2_vp_plane_mask *plane_mask;
1494 
1495 	if (vop2->global_init)
1496 		return;
1497 
1498 	/* OTP must enable at the first time, otherwise mirror layer register is error */
1499 	if (soc_is_rk3566())
1500 		vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK,
1501 				OTP_WIN_EN_SHIFT, 1, false);
1502 
1503 	if (cstate->crtc->assign_plane) {/* dts assign plane */
1504 		u32 plane_mask;
1505 		int primary_plane_id;
1506 
1507 		for (i = 0; i < vop2->data->nr_vps; i++) {
1508 			plane_mask = cstate->crtc->vps[i].plane_mask;
1509 			vop2->vp_plane_mask[i].plane_mask = plane_mask;
1510 			layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */
1511 			vop2->vp_plane_mask[i].attached_layers_nr = layer_nr;
1512 			primary_plane_id = vop2_get_primary_plane(vop2, plane_mask);
1513 			vop2->vp_plane_mask[i].primary_plane_id =  primary_plane_id;
1514 			vop2->vp_plane_mask[i].plane_mask = plane_mask;
1515 
1516 			/* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/
1517 			for (j = 0; j < layer_nr; j++) {
1518 				vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1;
1519 				plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]);
1520 			}
1521 		}
1522 	} else {/* need soft assign plane mask */
1523 		/* find the first unplug devices and set it as main display */
1524 		int main_vp_index = -1;
1525 		int active_vp_num = 0;
1526 
1527 		for (i = 0; i < vop2->data->nr_vps; i++) {
1528 			if (cstate->crtc->vps[i].enable)
1529 				active_vp_num++;
1530 		}
1531 		printf("VOP have %d active VP\n", active_vp_num);
1532 
1533 		if (soc_is_rk3566() && active_vp_num > 2)
1534 			printf("ERROR: rk3566 only support 2 display output!!\n");
1535 		plane_mask = vop2->data->plane_mask;
1536 		plane_mask += (active_vp_num - 1) * VOP2_VP_MAX;
1537 
1538 		for (i = 0; i < vop2->data->nr_vps; i++) {
1539 			if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) {
1540 				vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/
1541 				main_vp_index = i;
1542 				break;
1543 			}
1544 		}
1545 
1546 		/* if no find unplug devices, use vp0 as main display */
1547 		if (main_vp_index < 0) {
1548 			main_vp_index = 0;
1549 			vop2->vp_plane_mask[0] = plane_mask[0];
1550 		}
1551 
1552 		j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */
1553 
1554 		/* init other display except main display */
1555 		for (i = 0; i < vop2->data->nr_vps; i++) {
1556 			if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */
1557 				continue;
1558 			vop2->vp_plane_mask[i] = plane_mask[j++];
1559 		}
1560 
1561 		/* store plane mask for vop2_fixup_dts */
1562 		for (i = 0; i < vop2->data->nr_vps; i++) {
1563 			layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
1564 			/* rk3566 only support 3+3 policy */
1565 			if (soc_is_rk3566() && active_vp_num == 1) {
1566 				if (cstate->crtc->vps[i].enable) {
1567 					for (j = 0; j < 3; j++) {
1568 						layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
1569 						vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id);
1570 					}
1571 				}
1572 			} else {
1573 				for (j = 0; j < layer_nr; j++) {
1574 					layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
1575 					vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id);
1576 				}
1577 			}
1578 		}
1579 	}
1580 
1581 	if (vop2->version == VOP_VERSION_RK3588)
1582 		rk3588_vop2_regsbak(vop2);
1583 	else
1584 		memcpy(vop2->regsbak, vop2->regs, vop2->reg_len);
1585 
1586 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK,
1587 			OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false);
1588 	vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
1589 			IF_CTRL_REG_DONE_IMD_SHIFT, 1, false);
1590 
1591 	for (i = 0; i < vop2->data->nr_vps; i++) {
1592 		printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr);
1593 		for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++)
1594 			printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]);
1595 		printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id);
1596 	}
1597 
1598 	shift = 0;
1599 	/* layer sel win id */
1600 	for (i = 0; i < vop2->data->nr_vps; i++) {
1601 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
1602 		for (j = 0; j < layer_nr; j++) {
1603 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
1604 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
1605 			vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK,
1606 					shift, win_data->layer_sel_win_id, false);
1607 			shift += 4;
1608 		}
1609 	}
1610 
1611 	/* win sel port */
1612 	for (i = 0; i < vop2->data->nr_vps; i++) {
1613 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
1614 		for (j = 0; j < layer_nr; j++) {
1615 			if (!vop2->vp_plane_mask[i].attached_layers[j])
1616 				continue;
1617 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
1618 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
1619 			shift = win_data->win_sel_port_offset * 2;
1620 			vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK,
1621 					LAYER_SEL_PORT_SHIFT + shift, i, false);
1622 		}
1623 	}
1624 
1625 	/**
1626 	 * port mux config
1627 	 */
1628 	for (i = 0; i < vop2->data->nr_vps; i++) {
1629 		shift = i * 4;
1630 		if (vop2->vp_plane_mask[i].attached_layers_nr) {
1631 			total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr;
1632 			port_mux = total_used_layer - 1;
1633 		} else {
1634 			port_mux = 8;
1635 		}
1636 
1637 		if (i == vop2->data->nr_vps - 1)
1638 			port_mux = vop2->data->nr_mixers;
1639 
1640 		cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1;
1641 		vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK,
1642 				PORT_MUX_SHIFT + shift, port_mux, false);
1643 	}
1644 
1645 	if (vop2->version == VOP_VERSION_RK3568)
1646 		vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0);
1647 
1648 	vop2->global_init = true;
1649 }
1650 
1651 static int vop2_initial(struct vop2 *vop2, struct display_state *state)
1652 {
1653 	struct crtc_state *cstate = &state->crtc_state;
1654 	int ret;
1655 
1656 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1657 	ret = clk_set_defaults(cstate->dev);
1658 	if (ret)
1659 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
1660 
1661 	rockchip_vop2_gamma_lut_init(vop2, state);
1662 	rockchip_vop2_cubic_lut_init(vop2, state);
1663 
1664 	return 0;
1665 }
1666 
1667 /*
1668  * VOP2 have multi video ports.
1669  * video port ------- crtc
1670  */
1671 static int rockchip_vop2_preinit(struct display_state *state)
1672 {
1673 	struct crtc_state *cstate = &state->crtc_state;
1674 	const struct vop2_data *vop2_data = cstate->crtc->data;
1675 
1676 	if (!rockchip_vop2) {
1677 		rockchip_vop2 = calloc(1, sizeof(struct vop2));
1678 		if (!rockchip_vop2)
1679 			return -ENOMEM;
1680 		rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev);
1681 		rockchip_vop2->regsbak = malloc(RK3568_MAX_REG);
1682 		rockchip_vop2->reg_len = RK3568_MAX_REG;
1683 		rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1684 		if (rockchip_vop2->grf <= 0)
1685 			printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf);
1686 		rockchip_vop2->version = vop2_data->version;
1687 		rockchip_vop2->data = vop2_data;
1688 		if (rockchip_vop2->version == VOP_VERSION_RK3588) {
1689 			struct regmap *map;
1690 
1691 			rockchip_vop2->vop_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VOP_GRF);
1692 			if (rockchip_vop2->vop_grf <= 0)
1693 				printf("%s: Get syscon vop_grf failed (ret=%p)\n", __func__, rockchip_vop2->vop_grf);
1694 			map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf");
1695 			rockchip_vop2->vo1_grf = regmap_get_range(map, 0);
1696 			if (rockchip_vop2->vo1_grf <= 0)
1697 				printf("%s: Get syscon vo1_grf failed (ret=%p)\n", __func__, rockchip_vop2->vo1_grf);
1698 			rockchip_vop2->sys_pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
1699 			if (rockchip_vop2->sys_pmu <= 0)
1700 				printf("%s: Get syscon sys_pmu failed (ret=%p)\n", __func__, rockchip_vop2->sys_pmu);
1701 		}
1702 	}
1703 
1704 	cstate->private = rockchip_vop2;
1705 	cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output;
1706 	cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature;
1707 
1708 	vop2_global_initial(rockchip_vop2, state);
1709 
1710 	return 0;
1711 }
1712 
1713 /*
1714  * calc the dclk on rk3588
1715  * the available div of dclk is 1, 2, 4
1716  *
1717  */
1718 static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
1719 {
1720 	if (child_clk * 4 <= max_dclk)
1721 		return child_clk * 4;
1722 	else if (child_clk * 2 <= max_dclk)
1723 		return child_clk * 2;
1724 	else if (child_clk <= max_dclk)
1725 		return child_clk;
1726 	else
1727 		return 0;
1728 }
1729 
1730 /*
1731  * 4 pixclk/cycle on rk3588
1732  * RGB/eDP/HDMI: if_pixclk >= dclk_core
1733  * DP: dp_pixclk = dclk_out <= dclk_core
1734  * DSI: mipi_pixclk <= dclk_out <= dclk_core
1735  */
1736 static unsigned long vop2_calc_cru_cfg(struct display_state *state,
1737 				       int *dclk_core_div, int *dclk_out_div,
1738 				       int *if_pixclk_div, int *if_dclk_div)
1739 {
1740 	struct crtc_state *cstate = &state->crtc_state;
1741 	struct connector_state *conn_state = &state->conn_state;
1742 	struct drm_display_mode *mode = &conn_state->mode;
1743 	struct vop2 *vop2 = cstate->private;
1744 	unsigned long v_pixclk = mode->clock;
1745 	unsigned long dclk_core_rate = v_pixclk >> 2;
1746 	unsigned long dclk_rate = v_pixclk;
1747 	unsigned long dclk_out_rate;
1748 	u64 if_dclk_rate;
1749 	u64 if_pixclk_rate;
1750 	int output_type = conn_state->type;
1751 	int output_mode = conn_state->output_mode;
1752 	int K = 1;
1753 
1754 	if (output_type == DRM_MODE_CONNECTOR_HDMIA) {
1755 		/*
1756 		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
1757 		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
1758 		 */
1759 		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
1760 			dclk_rate = dclk_rate >> 1;
1761 			K = 2;
1762 		}
1763 		if (conn_state->dsc_enable) {
1764 			if_pixclk_rate = conn_state->dsc_cds_clk << 1;
1765 			if_dclk_rate = conn_state->dsc_cds_clk;
1766 		} else {
1767 			if_pixclk_rate = (dclk_core_rate << 1) / K;
1768 			if_dclk_rate = dclk_core_rate / K;
1769 		}
1770 
1771 		if (!dclk_rate) {
1772 			printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n",
1773 			       vop2->data->vp_data->max_dclk, if_pixclk_rate);
1774 			return -EINVAL;
1775 		}
1776 		*if_pixclk_div = dclk_rate / if_pixclk_rate;
1777 		*if_dclk_div = dclk_rate / if_dclk_rate;
1778 		*dclk_core_div = dclk_rate / dclk_core_rate;
1779 		printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n",
1780 		       dclk_rate, *if_pixclk_div, *if_dclk_div);
1781 	} else if (output_type == DRM_MODE_CONNECTOR_eDP) {
1782 		/* edp_pixclk = edp_dclk > dclk_core */
1783 		if_pixclk_rate = v_pixclk / K;
1784 		if_dclk_rate = v_pixclk / K;
1785 		dclk_rate = if_pixclk_rate * K;
1786 		*dclk_core_div = dclk_rate / dclk_core_rate;
1787 		*if_pixclk_div = dclk_rate / if_pixclk_rate;
1788 		*if_dclk_div = *if_pixclk_div;
1789 	} else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) {
1790 		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
1791 			dclk_out_rate = v_pixclk >> 3;
1792 		else
1793 			dclk_out_rate = v_pixclk >> 2;
1794 
1795 		dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk);
1796 		if (!dclk_rate) {
1797 			printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n",
1798 			       vop2->data->vp_data->max_dclk, dclk_core_rate);
1799 			return -EINVAL;
1800 		}
1801 		*dclk_out_div = dclk_rate / dclk_out_rate;
1802 		*dclk_core_div = dclk_rate / dclk_core_rate;
1803 
1804 	} else if (output_type == DRM_MODE_CONNECTOR_DSI) {
1805 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
1806 			K = 2;
1807 		if (conn_state->dsc_enable)
1808 			if_pixclk_rate = conn_state->dsc_cds_clk >> 1;
1809 		else
1810 			if_pixclk_rate = dclk_core_rate / K;
1811 		/* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */
1812 		dclk_out_rate = if_pixclk_rate;
1813 		/* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */
1814 		dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk);
1815 		if (!dclk_rate) {
1816 			printf("MIPI dclk out of range(max_dclk: %d KHZ, dclk_rate: %ld KHZ)\n",
1817 			       vop2->data->vp_data->max_dclk, dclk_rate);
1818 			return -EINVAL;
1819 		}
1820 		*dclk_out_div = dclk_rate / dclk_out_rate;
1821 		*dclk_core_div = dclk_rate / dclk_core_rate;
1822 		*if_pixclk_div = 1;       /*mipi pixclk == dclk_out*/
1823 
1824 	} else if (output_type == DRM_MODE_CONNECTOR_DPI) {
1825 		dclk_rate = v_pixclk;
1826 		*dclk_core_div = dclk_rate / dclk_core_rate;
1827 	}
1828 
1829 	*if_pixclk_div = ilog2(*if_pixclk_div);
1830 	*if_dclk_div = ilog2(*if_dclk_div);
1831 	*dclk_core_div = ilog2(*dclk_core_div);
1832 	*dclk_out_div = ilog2(*dclk_out_div);
1833 
1834 	return dclk_rate;
1835 }
1836 
1837 static int vop2_calc_dsc_clk(struct connector_state *conn_state)
1838 {
1839 	struct drm_display_mode *mode = &conn_state->mode;
1840 	u64 v_pixclk = mode->clock * 1000LL; /* video timing pixclk */
1841 	u8 k = 1;
1842 
1843 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
1844 		k = 2;
1845 
1846 	conn_state->dsc_pxl_clk = v_pixclk;
1847 	do_div(conn_state->dsc_pxl_clk, (conn_state->dsc_slice_num * k));
1848 
1849 	conn_state->dsc_txp_clk = v_pixclk;
1850 	do_div(conn_state->dsc_txp_clk, (conn_state->dsc_pixel_num * k));
1851 
1852 	/* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel)
1853 	 * cds_dat_width = 96;
1854 	 * bits_per_pixel = [8-12];
1855 	 * As only support 1/2/4 div, so we set dsc_cds = crtc_clock / 8;
1856 	 */
1857 	conn_state->dsc_cds_clk = mode->crtc_clock / 8 * 1000;
1858 
1859 	return 0;
1860 }
1861 
1862 static unsigned long rk3588_vop2_if_cfg(struct display_state *state)
1863 {
1864 	struct crtc_state *cstate = &state->crtc_state;
1865 	struct connector_state *conn_state = &state->conn_state;
1866 	struct drm_display_mode *mode = &conn_state->mode;
1867 	struct rockchip_dsc_sink_cap *dsc_sink_cap = &conn_state->dsc_sink_cap;
1868 	struct vop2 *vop2 = cstate->private;
1869 	u32 vp_offset = (cstate->crtc_id * 0x100);
1870 	u16 hdisplay = mode->crtc_hdisplay;
1871 	int output_if = conn_state->output_if;
1872 	int dclk_core_div = 0;
1873 	int dclk_out_div = 0;
1874 	int if_pixclk_div = 0;
1875 	int if_dclk_div = 0;
1876 	unsigned long dclk_rate;
1877 	u32 val;
1878 
1879 	if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
1880 		val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
1881 		val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
1882 	} else {
1883 		val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
1884 		val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
1885 	}
1886 
1887 	if (conn_state->dsc_enable) {
1888 		if (!vop2->data->nr_dscs) {
1889 			printf("No DSC\n");
1890 			return 0;
1891 		}
1892 		conn_state->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1;
1893 		conn_state->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width;
1894 		conn_state->dsc_pixel_num = conn_state->dsc_slice_num >= 4 ?
1895 					    4 : conn_state->dsc_slice_num >= 2 ? 2 : 1;
1896 		vop2_calc_dsc_clk(conn_state);
1897 	}
1898 
1899 	dclk_rate = vop2_calc_cru_cfg(state, &dclk_core_div, &dclk_out_div, &if_pixclk_div, &if_dclk_div);
1900 
1901 	if (output_if & VOP_OUTPUT_IF_RGB) {
1902 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
1903 				4, false);
1904 	}
1905 
1906 	if (output_if & VOP_OUTPUT_IF_BT1120) {
1907 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
1908 				3, false);
1909 	}
1910 
1911 	if (output_if & VOP_OUTPUT_IF_BT656) {
1912 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
1913 				2, false);
1914 	}
1915 
1916 	if (output_if & VOP_OUTPUT_IF_MIPI0) {
1917 		if (cstate->crtc_id == 2)
1918 			val = 0;
1919 		else
1920 			val = 1;
1921 
1922 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
1923 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
1924 					RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false);
1925 
1926 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT,
1927 				1, false);
1928 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false);
1929 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT,
1930 				if_pixclk_div, false);
1931 
1932 		if (conn_state->hold_mode) {
1933 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1934 					EN_MASK, EDPI_TE_EN, 1, false);
1935 
1936 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1937 					EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
1938 		}
1939 	}
1940 
1941 	if (output_if & VOP_OUTPUT_IF_MIPI1) {
1942 		if (cstate->crtc_id == 2)
1943 			val = 0;
1944 		else if (cstate->crtc_id == 3)
1945 			val = 1;
1946 		else
1947 			val = 3; /*VP1*/
1948 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
1949 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
1950 					RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false);
1951 
1952 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT,
1953 				1, false);
1954 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT,
1955 				val, false);
1956 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT,
1957 				if_pixclk_div, false);
1958 
1959 		if (conn_state->hold_mode) {
1960 			/* UNDO: RK3588 VP1->DSC1->DSI1 only can support soft TE mode */
1961 			if (vop2->version == VOP_VERSION_RK3588 && val == 3)
1962 				vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1963 						EN_MASK, EDPI_TE_EN, 0, false);
1964 			else
1965 				vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1966 						EN_MASK, EDPI_TE_EN, 1, false);
1967 
1968 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1969 					EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
1970 		}
1971 	}
1972 
1973 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
1974 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
1975 				RK3568_MIPI_DUAL_EN_SHIFT, 1, false);
1976 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
1977 				MIPI_DUAL_EN_SHIFT, 1, false);
1978 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
1979 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
1980 					EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
1981 					false);
1982 	}
1983 
1984 	if (output_if & VOP_OUTPUT_IF_eDP0) {
1985 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT,
1986 				1, false);
1987 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
1988 				cstate->crtc_id, false);
1989 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
1990 				if_dclk_div, false);
1991 
1992 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
1993 				if_pixclk_div, false);
1994 
1995 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
1996 				RK3588_GRF_EDP0_ENABLE_SHIFT, 1);
1997 	}
1998 
1999 	if (output_if & VOP_OUTPUT_IF_eDP1) {
2000 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT,
2001 				1, false);
2002 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
2003 				cstate->crtc_id, false);
2004 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
2005 				if_dclk_div, false);
2006 
2007 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
2008 				if_pixclk_div, false);
2009 	}
2010 
2011 	if (output_if & VOP_OUTPUT_IF_HDMI0) {
2012 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT,
2013 				1, false);
2014 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
2015 				cstate->crtc_id, false);
2016 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
2017 				if_dclk_div, false);
2018 
2019 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
2020 				if_pixclk_div, false);
2021 
2022 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2023 				RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1);
2024 		vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
2025 				HDMI_SYNC_POL_MASK,
2026 				HDMI0_SYNC_POL_SHIFT, val);
2027 	}
2028 
2029 	if (output_if & VOP_OUTPUT_IF_HDMI1) {
2030 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT,
2031 				1, false);
2032 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
2033 				cstate->crtc_id, false);
2034 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
2035 				if_dclk_div, false);
2036 
2037 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
2038 				if_pixclk_div, false);
2039 
2040 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2041 				RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1);
2042 		vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
2043 				HDMI_SYNC_POL_MASK,
2044 				HDMI1_SYNC_POL_SHIFT, val);
2045 	}
2046 
2047 	if (output_if & VOP_OUTPUT_IF_DP0) {
2048 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT,
2049 				1, false);
2050 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT,
2051 				cstate->crtc_id, false);
2052 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
2053 				RK3588_DP0_PIN_POL_SHIFT, val, false);
2054 	}
2055 
2056 	if (output_if & VOP_OUTPUT_IF_DP1) {
2057 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT,
2058 				1, false);
2059 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT,
2060 				cstate->crtc_id, false);
2061 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
2062 				RK3588_DP1_PIN_POL_SHIFT, val, false);
2063 	}
2064 
2065 	vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
2066 			DCLK_CORE_DIV_SHIFT, dclk_core_div, false);
2067 	vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
2068 			DCLK_OUT_DIV_SHIFT, dclk_out_div, false);
2069 
2070 	return dclk_rate;
2071 }
2072 
2073 static unsigned long rk3568_vop2_if_cfg(struct display_state *state)
2074 {
2075 	struct crtc_state *cstate = &state->crtc_state;
2076 	struct connector_state *conn_state = &state->conn_state;
2077 	struct drm_display_mode *mode = &conn_state->mode;
2078 	struct vop2 *vop2 = cstate->private;
2079 	u32 vp_offset = (cstate->crtc_id * 0x100);
2080 	bool dclk_inv;
2081 	u32 val;
2082 
2083 	dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1;
2084 	val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
2085 	val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
2086 
2087 	if (conn_state->output_if & VOP_OUTPUT_IF_RGB) {
2088 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
2089 				1, false);
2090 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2091 				RGB_MUX_SHIFT, cstate->crtc_id, false);
2092 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
2093 				GRF_RGB_DCLK_INV_SHIFT, dclk_inv);
2094 	}
2095 
2096 	if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) {
2097 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
2098 				1, false);
2099 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK,
2100 				BT1120_EN_SHIFT, 1, false);
2101 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2102 				RGB_MUX_SHIFT, cstate->crtc_id, false);
2103 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
2104 				GRF_BT1120_CLK_INV_SHIFT, !dclk_inv);
2105 	}
2106 
2107 	if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
2108 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
2109 				1, false);
2110 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2111 				RGB_MUX_SHIFT, cstate->crtc_id, false);
2112 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
2113 				GRF_BT656_CLK_INV_SHIFT, !dclk_inv);
2114 	}
2115 
2116 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) {
2117 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT,
2118 				1, false);
2119 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2120 				LVDS0_MUX_SHIFT, cstate->crtc_id, false);
2121 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2122 				IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false);
2123 	}
2124 
2125 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) {
2126 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT,
2127 				1, false);
2128 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2129 				LVDS1_MUX_SHIFT, cstate->crtc_id, false);
2130 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2131 				IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false);
2132 	}
2133 
2134 	if (conn_state->output_flags &
2135 	    (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE |
2136 	     ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) {
2137 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2138 				LVDS_DUAL_EN_SHIFT, 1, false);
2139 		if (conn_state->output_flags &
2140 		    ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2141 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2142 					LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1,
2143 					false);
2144 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
2145 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2146 					LVDS_DUAL_SWAP_EN_SHIFT, 1, false);
2147 	}
2148 
2149 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) {
2150 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT,
2151 				1, false);
2152 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2153 				MIPI0_MUX_SHIFT, cstate->crtc_id, false);
2154 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2155 				IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
2156 	}
2157 
2158 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) {
2159 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT,
2160 				1, false);
2161 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2162 				MIPI1_MUX_SHIFT, cstate->crtc_id, false);
2163 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2164 				IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
2165 	}
2166 
2167 	if (conn_state->output_flags &
2168 	    ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
2169 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
2170 				MIPI_DUAL_EN_SHIFT, 1, false);
2171 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
2172 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2173 					EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
2174 					false);
2175 	}
2176 
2177 	if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) {
2178 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT,
2179 				1, false);
2180 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2181 				EDP0_MUX_SHIFT, cstate->crtc_id, false);
2182 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2183 				IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false);
2184 	}
2185 
2186 	if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
2187 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
2188 				1, false);
2189 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2190 				HDMI0_MUX_SHIFT, cstate->crtc_id, false);
2191 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2192 				IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
2193 		vop2_mask_write(vop2, RK3568_DSP_IF_POL,
2194 				IF_CRTL_HDMI_PIN_POL_MASK,
2195 				IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
2196 	}
2197 
2198 	return mode->clock;
2199 }
2200 
2201 static void vop2_post_color_swap(struct display_state *state)
2202 {
2203 	struct crtc_state *cstate = &state->crtc_state;
2204 	struct connector_state *conn_state = &state->conn_state;
2205 	struct vop2 *vop2 = cstate->private;
2206 	u32 vp_offset = (cstate->crtc_id * 0x100);
2207 	u32 output_type = conn_state->type;
2208 	u32 data_swap = 0;
2209 
2210 	if (is_uv_swap(conn_state->bus_format, conn_state->output_mode))
2211 		data_swap = DSP_RB_SWAP;
2212 
2213 	if (vop2->version == VOP_VERSION_RK3588 &&
2214 	    (output_type == DRM_MODE_CONNECTOR_HDMIA ||
2215 	     output_type == DRM_MODE_CONNECTOR_eDP) &&
2216 	    (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
2217 	     conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30))
2218 		data_swap |= DSP_RG_SWAP;
2219 
2220 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
2221 			DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false);
2222 }
2223 
2224 static void vop2_clk_set_parent(struct clk *clk, struct clk *parent)
2225 {
2226 	int ret = 0;
2227 
2228 	if (parent->dev)
2229 		ret = clk_set_parent(clk, parent);
2230 	if (ret < 0)
2231 		debug("failed to set %s as parent for %s\n",
2232 		      parent->dev->name, clk->dev->name);
2233 }
2234 
2235 static ulong vop2_clk_set_rate(struct clk *clk, ulong rate)
2236 {
2237 	int ret = 0;
2238 
2239 	if (clk->dev)
2240 		ret = clk_set_rate(clk, rate);
2241 	if (ret < 0)
2242 		debug("failed to set %s rate %lu \n", clk->dev->name, rate);
2243 
2244 	return ret;
2245 }
2246 
2247 static int rockchip_vop2_init(struct display_state *state)
2248 {
2249 	struct crtc_state *cstate = &state->crtc_state;
2250 	struct connector_state *conn_state = &state->conn_state;
2251 	struct drm_display_mode *mode = &conn_state->mode;
2252 	struct vop2 *vop2 = cstate->private;
2253 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
2254 	u16 hdisplay = mode->crtc_hdisplay;
2255 	u16 htotal = mode->crtc_htotal;
2256 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
2257 	u16 hact_end = hact_st + hdisplay;
2258 	u16 vdisplay = mode->crtc_vdisplay;
2259 	u16 vtotal = mode->crtc_vtotal;
2260 	u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
2261 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
2262 	u16 vact_end = vact_st + vdisplay;
2263 	bool yuv_overlay = false;
2264 	u32 vp_offset = (cstate->crtc_id * 0x100);
2265 	u32 line_flag_offset = (cstate->crtc_id * 4);
2266 	u32 val, act_end;
2267 	u8 dither_down_en = 0;
2268 	u8 pre_dither_down_en = 0;
2269 	char output_type_name[30] = {0};
2270 	char dclk_name[9];
2271 	struct clk dclk;
2272 	struct clk hdmi0_phy_pll;
2273 	struct clk hdmi1_phy_pll;
2274 	unsigned long dclk_rate;
2275 	int ret;
2276 
2277 	printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n",
2278 	       mode->hdisplay, mode->vdisplay,
2279 	       mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
2280 	       mode->vscan,
2281 	       get_output_if_name(conn_state->output_if, output_type_name),
2282 	       cstate->crtc_id);
2283 
2284 	vop2_initial(vop2, state);
2285 	if (vop2->version == VOP_VERSION_RK3588)
2286 		dclk_rate = rk3588_vop2_if_cfg(state);
2287 	else
2288 		dclk_rate = rk3568_vop2_if_cfg(state);
2289 
2290 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
2291 	    !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT))
2292 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
2293 
2294 	vop2_post_color_swap(state);
2295 
2296 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK,
2297 			OUT_MODE_SHIFT, conn_state->output_mode, false);
2298 
2299 	switch (conn_state->bus_format) {
2300 	case MEDIA_BUS_FMT_RGB565_1X16:
2301 		dither_down_en = 1;
2302 		break;
2303 	case MEDIA_BUS_FMT_RGB666_1X18:
2304 	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
2305 	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
2306 	case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA:
2307 		dither_down_en = 1;
2308 		break;
2309 	case MEDIA_BUS_FMT_YUV8_1X24:
2310 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
2311 		dither_down_en = 0;
2312 		pre_dither_down_en = 1;
2313 		break;
2314 	case MEDIA_BUS_FMT_YUV10_1X30:
2315 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
2316 	case MEDIA_BUS_FMT_RGB888_1X24:
2317 	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
2318 	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
2319 	default:
2320 		dither_down_en = 0;
2321 		pre_dither_down_en = 0;
2322 		break;
2323 	}
2324 
2325 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA)
2326 		pre_dither_down_en = 0;
2327 	else
2328 		pre_dither_down_en = 1;
2329 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2330 			DITHER_DOWN_EN_SHIFT, dither_down_en, false);
2331 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2332 			PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false);
2333 
2334 	yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0;
2335 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id,
2336 			yuv_overlay, false);
2337 
2338 	cstate->yuv_overlay = yuv_overlay;
2339 
2340 	vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset,
2341 		    (htotal << 16) | hsync_len);
2342 	val = hact_st << 16;
2343 	val |= hact_end;
2344 	vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val);
2345 	val = vact_st << 16;
2346 	val |= vact_end;
2347 	vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val);
2348 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
2349 		u16 vact_st_f1 = vtotal + vact_st + 1;
2350 		u16 vact_end_f1 = vact_st_f1 + vdisplay;
2351 
2352 		val = vact_st_f1 << 16 | vact_end_f1;
2353 		vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset,
2354 			    val);
2355 
2356 		val = vtotal << 16 | (vtotal + vsync_len);
2357 		vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val);
2358 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2359 				INTERLACE_EN_SHIFT, 1, false);
2360 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2361 				DSP_FILED_POL, 1, false);
2362 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2363 				P2I_EN_SHIFT, 1, false);
2364 		vtotal += vtotal + 1;
2365 		act_end = vact_end_f1;
2366 	} else {
2367 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2368 				INTERLACE_EN_SHIFT, 0, false);
2369 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2370 				P2I_EN_SHIFT, 0, false);
2371 		act_end = vact_end;
2372 	}
2373 	vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset,
2374 		    (vtotal << 16) | vsync_len);
2375 
2376 	if (vop2->version == VOP_VERSION_RK3568) {
2377 		if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
2378 		    conn_state->output_if & VOP_OUTPUT_IF_BT656)
2379 			vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2380 					CORE_DCLK_DIV_EN_SHIFT, 1, false);
2381 		else
2382 			vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2383 					CORE_DCLK_DIV_EN_SHIFT, 0, false);
2384 	}
2385 
2386 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420)
2387 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2388 				DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false);
2389 	else
2390 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2391 				DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false);
2392 
2393 	if (yuv_overlay)
2394 		val = 0x20010200;
2395 	else
2396 		val = 0;
2397 	vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val);
2398 
2399 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2400 			POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false);
2401 
2402 	vop2_tv_config_update(state, vop2);
2403 	vop2_post_config(state, vop2);
2404 
2405 	snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id);
2406 	ret = clk_get_by_name(cstate->dev, dclk_name, &dclk);
2407 	if (ret) {
2408 		printf("%s: Failed to get dclk ret=%d\n", __func__, ret);
2409 		return ret;
2410 	}
2411 
2412 	ret = uclass_get_device_by_name(UCLASS_CLK, "hdmiphypll_clk0",
2413 					&hdmi0_phy_pll.dev);
2414 	if (ret) {
2415 		hdmi0_phy_pll.dev = NULL;
2416 		printf("%s:No hdmiphypll clk0 found, use system clk\n",
2417 		       __func__);
2418 	}
2419 
2420 	ret = uclass_get_device_by_name(UCLASS_CLK, "hdmiphypll_clk1",
2421 					&hdmi1_phy_pll.dev);
2422 	if (ret) {
2423 		hdmi1_phy_pll.dev = NULL;
2424 		printf("%s:No hdmiphypll clk1 found, use system clk\n",
2425 		       __func__);
2426 	}
2427 
2428 	if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0)
2429 		vop2_clk_set_parent(&dclk, &hdmi0_phy_pll);
2430 	else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1)
2431 		vop2_clk_set_parent(&dclk, &hdmi1_phy_pll);
2432 
2433 	/*
2434 	 * uboot clk driver won't set dclk parent's rate when use
2435 	 * hdmi phypll as dclk source.
2436 	 * So set dclk rate is meaningless. Set hdmi phypll rate
2437 	 * directly.
2438 	 */
2439 	if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev)
2440 		ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate * 1000);
2441 	else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev)
2442 		ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate * 1000);
2443 	else
2444 		ret = vop2_clk_set_rate(&dclk, dclk_rate * 1000);
2445 
2446 	if (IS_ERR_VALUE(ret)) {
2447 		printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n",
2448 		       __func__, cstate->crtc_id, dclk_rate, ret);
2449 		return ret;
2450 	}
2451 
2452 	vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
2453 			RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false);
2454 	vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
2455 			RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false);
2456 
2457 	if (vop2->version == VOP_VERSION_RK3588) {
2458 		if (vop2_power_domain_on(vop2, vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id))
2459 			printf("open vp%d plane pd fail\n", cstate->crtc_id);
2460 	}
2461 
2462 	return 0;
2463 }
2464 
2465 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win,
2466 			     uint32_t src_w, uint32_t src_h, uint32_t dst_w,
2467 			     uint32_t dst_h)
2468 {
2469 	uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
2470 	uint16_t hscl_filter_mode, vscl_filter_mode;
2471 	uint8_t gt2 = 0, gt4 = 0;
2472 	uint32_t xfac = 0, yfac = 0;
2473 	uint16_t hsu_filter_mode = VOP2_SCALE_UP_BIC;
2474 	uint16_t hsd_filter_mode = VOP2_SCALE_DOWN_BIL;
2475 	uint16_t vsu_filter_mode = VOP2_SCALE_UP_BIL;
2476 	uint16_t vsd_filter_mode = VOP2_SCALE_DOWN_BIL;
2477 	u32 win_offset = win->reg_offset;
2478 
2479 	if (src_h >= (4 * dst_h))
2480 		gt4 = 1;
2481 	else if (src_h >= (2 * dst_h))
2482 		gt2 = 1;
2483 
2484 	if (gt4)
2485 		src_h >>= 2;
2486 	else if (gt2)
2487 		src_h >>= 1;
2488 
2489 	yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
2490 	yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
2491 
2492 	if (yrgb_hor_scl_mode == SCALE_UP)
2493 		hscl_filter_mode = hsu_filter_mode;
2494 	else
2495 		hscl_filter_mode = hsd_filter_mode;
2496 
2497 	if (yrgb_ver_scl_mode == SCALE_UP)
2498 		vscl_filter_mode = vsu_filter_mode;
2499 	else
2500 		vscl_filter_mode = vsd_filter_mode;
2501 
2502 	/*
2503 	 * RK3568 VOP Esmart/Smart dsp_w should be even pixel
2504 	 * at scale down mode
2505 	 */
2506 	if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) {
2507 		printf("win dst_w[%d] should align as 2 pixel\n", dst_w);
2508 		dst_w += 1;
2509 	}
2510 
2511 	xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w);
2512 	yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h);
2513 
2514 	if (win->type == CLUSTER_LAYER) {
2515 		vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset,
2516 			    yfac << 16 | xfac);
2517 
2518 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
2519 				YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, gt2, false);
2520 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
2521 				YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, gt4, false);
2522 
2523 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
2524 				YRGB_XSCL_MODE_MASK, CLUSTER_YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false);
2525 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
2526 				YRGB_YSCL_MODE_MASK, CLUSTER_YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false);
2527 
2528 	} else {
2529 		vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset,
2530 			    yfac << 16 | xfac);
2531 
2532 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
2533 				YRGB_GT2_MASK, YRGB_GT2_SHIFT, gt2, false);
2534 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
2535 				YRGB_GT4_MASK, YRGB_GT4_SHIFT, gt4, false);
2536 
2537 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
2538 				YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false);
2539 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
2540 				YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false);
2541 
2542 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
2543 				YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT,
2544 				hscl_filter_mode, false);
2545 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
2546 				YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT,
2547 				vscl_filter_mode, false);
2548 	}
2549 }
2550 
2551 static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win)
2552 {
2553 	u32 win_offset = win->reg_offset;
2554 
2555 	if (win->type == CLUSTER_LAYER) {
2556 		vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK,
2557 				CLUSTER_AXI_ID_SHIFT, win->axi_id, false);
2558 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK,
2559 				CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
2560 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK,
2561 				CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
2562 	} else {
2563 		vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK,
2564 				ESMART_AXI_ID_SHIFT, win->axi_id, false);
2565 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK,
2566 				ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
2567 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK,
2568 				ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
2569 	}
2570 }
2571 
2572 static void vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win)
2573 {
2574 	struct crtc_state *cstate = &state->crtc_state;
2575 	struct connector_state *conn_state = &state->conn_state;
2576 	struct drm_display_mode *mode = &conn_state->mode;
2577 	struct vop2 *vop2 = cstate->private;
2578 	int src_w = cstate->src_w;
2579 	int src_h = cstate->src_h;
2580 	int crtc_x = cstate->crtc_x;
2581 	int crtc_y = cstate->crtc_y;
2582 	int crtc_w = cstate->crtc_w;
2583 	int crtc_h = cstate->crtc_h;
2584 	int xvir = cstate->xvir;
2585 	int y_mirror = 0;
2586 	int csc_mode;
2587 	u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
2588 	u32 win_offset = win->reg_offset;
2589 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
2590 
2591 	act_info = (src_h - 1) << 16;
2592 	act_info |= (src_w - 1) & 0xffff;
2593 
2594 	dsp_info = (crtc_h - 1) << 16;
2595 	dsp_info |= (crtc_w - 1) & 0xffff;
2596 
2597 	dsp_stx = crtc_x;
2598 	dsp_sty = crtc_y;
2599 	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
2600 
2601 	if (mode->flags & DRM_MODE_FLAG_YMIRROR)
2602 		y_mirror = 1;
2603 	else
2604 		y_mirror = 0;
2605 
2606 	vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
2607 
2608 	if (vop2->version == VOP_VERSION_RK3588)
2609 		vop2_axi_config(vop2, win);
2610 
2611 	if (y_mirror)
2612 		printf("WARN: y mirror is unsupported by cluster window\n");
2613 
2614 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset,
2615 			WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
2616 			false);
2617 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir);
2618 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset, cstate->dma_addr);
2619 
2620 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info);
2621 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info);
2622 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st);
2623 
2624 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false);
2625 
2626 	csc_mode = vop2_convert_csc_mode(conn_state->color_space);
2627 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK,
2628 			CLUSTER_RGB2YUV_EN_SHIFT,
2629 			is_yuv_output(conn_state->bus_format), false);
2630 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK,
2631 			CLUSTER_CSC_MODE_SHIFT, csc_mode, false);
2632 	vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false);
2633 
2634 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
2635 }
2636 
2637 static void vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win)
2638 {
2639 	struct crtc_state *cstate = &state->crtc_state;
2640 	struct connector_state *conn_state = &state->conn_state;
2641 	struct drm_display_mode *mode = &conn_state->mode;
2642 	struct vop2 *vop2 = cstate->private;
2643 	int src_w = cstate->src_w;
2644 	int src_h = cstate->src_h;
2645 	int crtc_x = cstate->crtc_x;
2646 	int crtc_y = cstate->crtc_y;
2647 	int crtc_w = cstate->crtc_w;
2648 	int crtc_h = cstate->crtc_h;
2649 	int xvir = cstate->xvir;
2650 	int y_mirror = 0;
2651 	int csc_mode;
2652 	u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
2653 	u32 win_offset = win->reg_offset;
2654 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
2655 
2656 	/*
2657 	 * This is workaround solution for IC design:
2658 	 * esmart can't support scale down when actual_w % 16 == 1.
2659 	 */
2660 	if (src_w > crtc_w && (src_w & 0xf) == 1) {
2661 		printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w);
2662 		src_w -= 1;
2663 	}
2664 
2665 	act_info = (src_h - 1) << 16;
2666 	act_info |= (src_w - 1) & 0xffff;
2667 
2668 	dsp_info = (crtc_h - 1) << 16;
2669 	dsp_info |= (crtc_w - 1) & 0xffff;
2670 
2671 	dsp_stx = crtc_x;
2672 	dsp_sty = crtc_y;
2673 	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
2674 
2675 	if (mode->flags & DRM_MODE_FLAG_YMIRROR)
2676 		y_mirror = 1;
2677 	else
2678 		y_mirror = 0;
2679 
2680 	vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
2681 
2682 	if (vop2->version == VOP_VERSION_RK3588)
2683 		vop2_axi_config(vop2, win);
2684 
2685 	if (y_mirror)
2686 		cstate->dma_addr += (src_h - 1) * xvir * 4;
2687 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK,
2688 			YMIRROR_EN_SHIFT, y_mirror, false);
2689 
2690 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
2691 			WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
2692 			false);
2693 	vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir);
2694 	vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset,
2695 		    cstate->dma_addr);
2696 
2697 	vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset,
2698 		    act_info);
2699 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset,
2700 		    dsp_info);
2701 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st);
2702 
2703 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK,
2704 			WIN_EN_SHIFT, 1, false);
2705 
2706 	csc_mode = vop2_convert_csc_mode(conn_state->color_space);
2707 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK,
2708 			RGB2YUV_EN_SHIFT,
2709 			is_yuv_output(conn_state->bus_format), false);
2710 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK,
2711 			CSC_MODE_SHIFT, csc_mode, false);
2712 
2713 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
2714 }
2715 
2716 static int rockchip_vop2_set_plane(struct display_state *state)
2717 {
2718 	struct crtc_state *cstate = &state->crtc_state;
2719 	struct vop2 *vop2 = cstate->private;
2720 	struct vop2_win_data *win_data;
2721 	u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
2722 	char plane_name[10] = {0};
2723 
2724 	if (cstate->crtc_w > cstate->max_output.width) {
2725 		printf("ERROR: output w[%d] exceeded max width[%d]\n",
2726 		       cstate->crtc_w, cstate->max_output.width);
2727 		return -EINVAL;
2728 	}
2729 
2730 	win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
2731 	if (!win_data) {
2732 		printf("invalid win id %d\n", primary_plane_id);
2733 		return -ENODEV;
2734 	}
2735 
2736 	if (win_data->type == CLUSTER_LAYER)
2737 		vop2_set_cluster_win(state, win_data);
2738 	else
2739 		vop2_set_smart_win(state, win_data);
2740 
2741 	printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n",
2742 		cstate->crtc_id, get_plane_name(primary_plane_id, plane_name),
2743 		cstate->src_w, cstate->src_h, cstate->crtc_w, cstate->crtc_h,
2744 		cstate->crtc_x, cstate->crtc_y, cstate->format,
2745 		cstate->dma_addr);
2746 
2747 	return 0;
2748 }
2749 
2750 static int rockchip_vop2_prepare(struct display_state *state)
2751 {
2752 	return 0;
2753 }
2754 
2755 static int rockchip_vop2_enable(struct display_state *state)
2756 {
2757 	struct crtc_state *cstate = &state->crtc_state;
2758 	struct vop2 *vop2 = cstate->private;
2759 	u32 vp_offset = (cstate->crtc_id * 0x100);
2760 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
2761 
2762 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2763 			STANDBY_EN_SHIFT, 0, false);
2764 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
2765 
2766 	return 0;
2767 }
2768 
2769 static int rockchip_vop2_disable(struct display_state *state)
2770 {
2771 	struct crtc_state *cstate = &state->crtc_state;
2772 	struct vop2 *vop2 = cstate->private;
2773 	u32 vp_offset = (cstate->crtc_id * 0x100);
2774 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
2775 
2776 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
2777 			STANDBY_EN_SHIFT, 1, false);
2778 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
2779 
2780 	return 0;
2781 }
2782 
2783 static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane)
2784 {
2785 	struct crtc_state *cstate = &state->crtc_state;
2786 	struct vop2 *vop2 = cstate->private;
2787 	int i = 0;
2788 	int correct_cursor_plane = -1;
2789 	int plane_type = -1;
2790 
2791 	if (cursor_plane < 0)
2792 		return -1;
2793 
2794 	if (plane_mask & (1 << cursor_plane))
2795 		return cursor_plane;
2796 
2797 	/* Get current cursor plane type */
2798 	for (i = 0; i < vop2->data->nr_layers; i++) {
2799 		if (vop2->data->plane_table[i].plane_id == cursor_plane) {
2800 			plane_type = vop2->data->plane_table[i].plane_type;
2801 			break;
2802 		}
2803 	}
2804 
2805 	/* Get the other same plane type plane id */
2806 	for (i = 0; i < vop2->data->nr_layers; i++) {
2807 		if (vop2->data->plane_table[i].plane_type == plane_type &&
2808 		    vop2->data->plane_table[i].plane_id != cursor_plane) {
2809 			correct_cursor_plane = vop2->data->plane_table[i].plane_id;
2810 			break;
2811 		}
2812 	}
2813 
2814 	/* To check whether the new correct_cursor_plane is attach to current vp */
2815 	if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) {
2816 		printf("error: faild to find correct plane as cursor plane\n");
2817 		return -1;
2818 	}
2819 
2820 	printf("vp%d adjust cursor plane from %d to %d\n",
2821 	       cstate->crtc_id, cursor_plane, correct_cursor_plane);
2822 
2823 	return correct_cursor_plane;
2824 }
2825 
2826 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob)
2827 {
2828 	struct crtc_state *cstate = &state->crtc_state;
2829 	struct vop2 *vop2 = cstate->private;
2830 	ofnode vp_node;
2831 	struct device_node *port_parent_node = cstate->ports_node;
2832 	static bool vop_fix_dts;
2833 	const char *path;
2834 	u32 plane_mask = 0;
2835 	int vp_id = 0;
2836 	int cursor_plane_id = -1;
2837 
2838 	if (vop_fix_dts)
2839 		return 0;
2840 
2841 	ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) {
2842 		path = vp_node.np->full_name;
2843 		plane_mask = vop2->vp_plane_mask[vp_id].plane_mask;
2844 
2845 		if (cstate->crtc->assign_plane)
2846 			continue;
2847 		cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask,
2848 								 cstate->crtc->vps[vp_id].cursor_plane);
2849 		printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n",
2850 		       vp_id, plane_mask,
2851 		       vop2->vp_plane_mask[vp_id].primary_plane_id,
2852 		       cursor_plane_id);
2853 
2854 		do_fixup_by_path_u32(blob, path, "rockchip,plane-mask",
2855 				     plane_mask, 1);
2856 		do_fixup_by_path_u32(blob, path, "rockchip,primary-plane",
2857 				     vop2->vp_plane_mask[vp_id].primary_plane_id, 1);
2858 		if (cursor_plane_id >= 0)
2859 			do_fixup_by_path_u32(blob, path, "cursor-win-id",
2860 					     cursor_plane_id, 1);
2861 		vp_id++;
2862 	}
2863 
2864 	vop_fix_dts = true;
2865 
2866 	return 0;
2867 }
2868 
2869 static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
2870 	{ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
2871 	{ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER},
2872 	{ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
2873 	{ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
2874 	{ROCKCHIP_VOP2_SMART0, SMART_LAYER},
2875 	{ROCKCHIP_VOP2_SMART0, SMART_LAYER},
2876 };
2877 
2878 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
2879 	{ /* one display policy */
2880 		{/* main display */
2881 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
2882 			.attached_layers_nr = 6,
2883 			.attached_layers = {
2884 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0,
2885 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
2886 				},
2887 		},
2888 		{/* second display */},
2889 		{/* third  display */},
2890 		{/* fourth display */},
2891 	},
2892 
2893 	{ /* two display policy */
2894 		{/* main display */
2895 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
2896 			.attached_layers_nr = 3,
2897 			.attached_layers = {
2898 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
2899 				},
2900 		},
2901 
2902 		{/* second display */
2903 			.primary_plane_id = ROCKCHIP_VOP2_SMART1,
2904 			.attached_layers_nr = 3,
2905 			.attached_layers = {
2906 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
2907 				},
2908 		},
2909 		{/* third  display */},
2910 		{/* fourth display */},
2911 	},
2912 
2913 	{ /* three display policy */
2914 		{/* main display */
2915 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
2916 			.attached_layers_nr = 3,
2917 			.attached_layers = {
2918 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
2919 				},
2920 		},
2921 
2922 		{/* second display */
2923 			.primary_plane_id = ROCKCHIP_VOP2_SMART1,
2924 			.attached_layers_nr = 2,
2925 			.attached_layers = {
2926 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1
2927 				},
2928 		},
2929 
2930 		{/* third  display */
2931 			.primary_plane_id = ROCKCHIP_VOP2_ESMART1,
2932 			.attached_layers_nr = 1,
2933 			.attached_layers = { ROCKCHIP_VOP2_ESMART1 },
2934 		},
2935 
2936 		{/* fourth display */},
2937 	},
2938 
2939 	{/* reserved for four display policy */},
2940 };
2941 
2942 static struct vop2_win_data rk3568_win_data[6] = {
2943 	{
2944 		.name = "Cluster0",
2945 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
2946 		.type = CLUSTER_LAYER,
2947 		.win_sel_port_offset = 0,
2948 		.layer_sel_win_id = 0,
2949 		.reg_offset = 0,
2950 	},
2951 
2952 	{
2953 		.name = "Cluster1",
2954 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
2955 		.type = CLUSTER_LAYER,
2956 		.win_sel_port_offset = 1,
2957 		.layer_sel_win_id = 1,
2958 		.reg_offset = 0x200,
2959 	},
2960 
2961 	{
2962 		.name = "Esmart0",
2963 		.phys_id = ROCKCHIP_VOP2_ESMART0,
2964 		.type = ESMART_LAYER,
2965 		.win_sel_port_offset = 4,
2966 		.layer_sel_win_id = 2,
2967 		.reg_offset = 0,
2968 	},
2969 
2970 	{
2971 		.name = "Esmart1",
2972 		.phys_id = ROCKCHIP_VOP2_ESMART1,
2973 		.type = ESMART_LAYER,
2974 		.win_sel_port_offset = 5,
2975 		.layer_sel_win_id = 6,
2976 		.reg_offset = 0x200,
2977 	},
2978 
2979 	{
2980 		.name = "Smart0",
2981 		.phys_id = ROCKCHIP_VOP2_SMART0,
2982 		.type = SMART_LAYER,
2983 		.win_sel_port_offset = 6,
2984 		.layer_sel_win_id = 3,
2985 		.reg_offset = 0x400,
2986 	},
2987 
2988 	{
2989 		.name = "Smart1",
2990 		.phys_id = ROCKCHIP_VOP2_SMART1,
2991 		.type = SMART_LAYER,
2992 		.win_sel_port_offset = 7,
2993 		.layer_sel_win_id = 7,
2994 		.reg_offset = 0x600,
2995 	},
2996 };
2997 
2998 static struct vop2_vp_data rk3568_vp_data[3] = {
2999 	{
3000 		.feature = VOP_FEATURE_OUTPUT_10BIT,
3001 		.pre_scan_max_dly = 42,
3002 		.max_output = {4096, 2304},
3003 	},
3004 	{
3005 		.feature = 0,
3006 		.pre_scan_max_dly = 40,
3007 		.max_output = {2048, 1536},
3008 	},
3009 	{
3010 		.feature = 0,
3011 		.pre_scan_max_dly = 40,
3012 		.max_output = {1920, 1080},
3013 	},
3014 };
3015 
3016 const struct vop2_data rk3568_vop = {
3017 	.version = VOP_VERSION_RK3568,
3018 	.nr_vps = 3,
3019 	.vp_data = rk3568_vp_data,
3020 	.win_data = rk3568_win_data,
3021 	.plane_mask = rk356x_vp_plane_mask[0],
3022 	.plane_table = rk356x_plane_table,
3023 	.nr_layers = 6,
3024 	.nr_mixers = 5,
3025 	.nr_gammas = 1,
3026 };
3027 
3028 static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
3029 	{ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
3030 	{ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER},
3031 	{ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER},
3032 	{ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER},
3033 	{ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
3034 	{ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
3035 	{ROCKCHIP_VOP2_ESMART2, ESMART_LAYER},
3036 	{ROCKCHIP_VOP2_ESMART3, ESMART_LAYER},
3037 };
3038 
3039 static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
3040 	{ /* one display policy */
3041 		{/* main display */
3042 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
3043 			.attached_layers_nr = 8,
3044 			.attached_layers = {
3045 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2,
3046 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3,
3047 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3
3048 			},
3049 		},
3050 		{/* second display */},
3051 		{/* third  display */},
3052 		{/* fourth display */},
3053 	},
3054 
3055 	{ /* two display policy */
3056 		{/* main display */
3057 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
3058 			.attached_layers_nr = 4,
3059 			.attached_layers = {
3060 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0,
3061 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1
3062 			},
3063 		},
3064 
3065 		{/* second display */
3066 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER2,
3067 			.attached_layers_nr = 4,
3068 			.attached_layers = {
3069 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2,
3070 				  ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3
3071 			},
3072 		},
3073 		{/* third  display */},
3074 		{/* fourth display */},
3075 	},
3076 
3077 	{ /* three display policy */
3078 		{/* main display */
3079 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
3080 			.attached_layers_nr = 3,
3081 			.attached_layers = {
3082 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0
3083 			},
3084 		},
3085 
3086 		{/* second display */
3087 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER2,
3088 			.attached_layers_nr = 3,
3089 			.attached_layers = {
3090 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1
3091 			},
3092 		},
3093 
3094 		{/* third  display */
3095 			.primary_plane_id = ROCKCHIP_VOP2_ESMART2,
3096 			.attached_layers_nr = 2,
3097 			.attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 },
3098 		},
3099 
3100 		{/* fourth display */},
3101 	},
3102 
3103 	{ /* four display policy */
3104 		{/* main display */
3105 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
3106 			.attached_layers_nr = 2,
3107 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 },
3108 		},
3109 
3110 		{/* second display */
3111 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER1,
3112 			.attached_layers_nr = 2,
3113 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 },
3114 		},
3115 
3116 		{/* third  display */
3117 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER2,
3118 			.attached_layers_nr = 2,
3119 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 },
3120 		},
3121 
3122 		{/* fourth display */
3123 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER3,
3124 			.attached_layers_nr = 2,
3125 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 },
3126 		},
3127 	},
3128 
3129 };
3130 
3131 static struct vop2_power_domain_data rk3588_cluster0_pd_data = {
3132 	.pd_en_shift = RK3588_CLUSTER0_PD_EN_SHIFT,
3133 	.pd_status_shift = RK3588_CLUSTER0_PD_STATUS_SHIFT,
3134 	.pmu_status_shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI,
3135 	.bisr_en_status_shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT,
3136 };
3137 
3138 static struct vop2_power_domain_data rk3588_cluster1_pd_data = {
3139 	.is_parent_needed = true,
3140 	.pd_en_shift = RK3588_CLUSTER1_PD_EN_SHIFT,
3141 	.pd_status_shift = RK3588_CLUSTER1_PD_STATUS_SHIFT,
3142 	.pmu_status_shift = RK3588_PD_CLUSTER1_PWR_STAT_SHIFI,
3143 	.bisr_en_status_shift = RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT,
3144 	.parent_phy_id = ROCKCHIP_VOP2_CLUSTER0,
3145 };
3146 
3147 static struct vop2_power_domain_data rk3588_cluster2_pd_data = {
3148 	.is_parent_needed = true,
3149 	.pd_en_shift = RK3588_CLUSTER2_PD_EN_SHIFT,
3150 	.pd_status_shift = RK3588_CLUSTER2_PD_STATUS_SHIFT,
3151 	.pmu_status_shift = RK3588_PD_CLUSTER2_PWR_STAT_SHIFI,
3152 	.bisr_en_status_shift = RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT,
3153 	.parent_phy_id = ROCKCHIP_VOP2_CLUSTER0,
3154 };
3155 
3156 static struct vop2_power_domain_data rk3588_cluster3_pd_data = {
3157 	.is_parent_needed = true,
3158 	.pd_en_shift = RK3588_CLUSTER3_PD_EN_SHIFT,
3159 	.pd_status_shift = RK3588_CLUSTER3_PD_STATUS_SHIFT,
3160 	.pmu_status_shift = RK3588_PD_CLUSTER3_PWR_STAT_SHIFI,
3161 	.bisr_en_status_shift = RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT,
3162 	.parent_phy_id = ROCKCHIP_VOP2_CLUSTER0,
3163 };
3164 
3165 static struct vop2_power_domain_data rk3588_esmart_pd_data = {
3166 	.pd_en_shift = RK3588_ESMART_PD_EN_SHIFT,
3167 	.pd_status_shift = RK3588_ESMART_PD_STATUS_SHIFT,
3168 	.pmu_status_shift = RK3588_PD_ESMART_PWR_STAT_SHIFI,
3169 	.bisr_en_status_shift = RK3588_PD_ESMART_REPAIR_EN_SHIFT,
3170 };
3171 
3172 static struct vop2_win_data rk3588_win_data[8] = {
3173 	{
3174 		.name = "Cluster0",
3175 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
3176 		.type = CLUSTER_LAYER,
3177 		.win_sel_port_offset = 0,
3178 		.layer_sel_win_id = 0,
3179 		.reg_offset = 0,
3180 		.axi_id = 0,
3181 		.axi_yrgb_id = 2,
3182 		.axi_uv_id = 3,
3183 		.pd_data = &rk3588_cluster0_pd_data,
3184 	},
3185 
3186 	{
3187 		.name = "Cluster1",
3188 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
3189 		.type = CLUSTER_LAYER,
3190 		.win_sel_port_offset = 1,
3191 		.layer_sel_win_id = 1,
3192 		.reg_offset = 0x200,
3193 		.axi_id = 0,
3194 		.axi_yrgb_id = 6,
3195 		.axi_uv_id = 7,
3196 		.pd_data = &rk3588_cluster1_pd_data,
3197 	},
3198 
3199 	{
3200 		.name = "Cluster2",
3201 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
3202 		.type = CLUSTER_LAYER,
3203 		.win_sel_port_offset = 2,
3204 		.layer_sel_win_id = 4,
3205 		.reg_offset = 0x400,
3206 		.axi_id = 1,
3207 		.axi_yrgb_id = 2,
3208 		.axi_uv_id = 3,
3209 		.pd_data = &rk3588_cluster2_pd_data,
3210 	},
3211 
3212 	{
3213 		.name = "Cluster3",
3214 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
3215 		.type = CLUSTER_LAYER,
3216 		.win_sel_port_offset = 3,
3217 		.layer_sel_win_id = 5,
3218 		.reg_offset = 0x600,
3219 		.axi_id = 1,
3220 		.axi_yrgb_id = 6,
3221 		.axi_uv_id = 7,
3222 		.pd_data = &rk3588_cluster3_pd_data,
3223 	},
3224 
3225 	{
3226 		.name = "Esmart0",
3227 		.phys_id = ROCKCHIP_VOP2_ESMART0,
3228 		.type = ESMART_LAYER,
3229 		.win_sel_port_offset = 4,
3230 		.layer_sel_win_id = 2,
3231 		.reg_offset = 0,
3232 		.axi_id = 0,
3233 		.axi_yrgb_id = 0x0a,
3234 		.axi_uv_id = 0x0b,
3235 	},
3236 
3237 	{
3238 		.name = "Esmart1",
3239 		.phys_id = ROCKCHIP_VOP2_ESMART1,
3240 		.type = ESMART_LAYER,
3241 		.win_sel_port_offset = 5,
3242 		.layer_sel_win_id = 3,
3243 		.reg_offset = 0x200,
3244 		.axi_id = 0,
3245 		.axi_yrgb_id = 0x0c,
3246 		.axi_uv_id = 0x0d,
3247 		.pd_data = &rk3588_esmart_pd_data,
3248 	},
3249 
3250 	{
3251 		.name = "Esmart2",
3252 		.phys_id = ROCKCHIP_VOP2_ESMART2,
3253 		.type = ESMART_LAYER,
3254 		.win_sel_port_offset = 6,
3255 		.layer_sel_win_id = 6,
3256 		.reg_offset = 0x400,
3257 		.axi_id = 1,
3258 		.axi_yrgb_id = 0x0a,
3259 		.axi_uv_id = 0x0b,
3260 		.pd_data = &rk3588_esmart_pd_data,
3261 	},
3262 
3263 	{
3264 		.name = "Esmart3",
3265 		.phys_id = ROCKCHIP_VOP2_ESMART3,
3266 		.type = ESMART_LAYER,
3267 		.win_sel_port_offset = 7,
3268 		.layer_sel_win_id = 7,
3269 		.reg_offset = 0x600,
3270 		.axi_id = 1,
3271 		.axi_yrgb_id = 0x0c,
3272 		.axi_uv_id = 0x0d,
3273 		.pd_data = &rk3588_esmart_pd_data,
3274 	},
3275 };
3276 
3277 static struct vop2_vp_data rk3588_vp_data[4] = {
3278 	{
3279 		.feature = VOP_FEATURE_OUTPUT_10BIT,
3280 		.pre_scan_max_dly = 54,
3281 		.max_dclk = 600000,
3282 		.max_output = {7680, 4320},
3283 	},
3284 	{
3285 		.feature = VOP_FEATURE_OUTPUT_10BIT,
3286 		.pre_scan_max_dly = 40,
3287 		.max_dclk = 600000,
3288 		.max_output = {4096, 2304},
3289 	},
3290 	{
3291 		.feature = VOP_FEATURE_OUTPUT_10BIT,
3292 		.pre_scan_max_dly = 52,
3293 		.max_dclk = 600000,
3294 		.max_output = {4096, 2304},
3295 	},
3296 	{
3297 		.feature = 0,
3298 		.pre_scan_max_dly = 52,
3299 		.max_dclk = 200000,
3300 		.max_output = {1920, 1080},
3301 	},
3302 };
3303 
3304 const struct vop2_data rk3588_vop = {
3305 	.version = VOP_VERSION_RK3588,
3306 	.nr_vps = 4,
3307 	.vp_data = rk3588_vp_data,
3308 	.win_data = rk3588_win_data,
3309 	.plane_mask = rk3588_vp_plane_mask[0],
3310 	.plane_table = rk3588_plane_table,
3311 	.nr_layers = 8,
3312 	.nr_mixers = 7,
3313 	.nr_gammas = 4,
3314 	.nr_dscs = 2,
3315 };
3316 
3317 const struct rockchip_crtc_funcs rockchip_vop2_funcs = {
3318 	.preinit = rockchip_vop2_preinit,
3319 	.prepare = rockchip_vop2_prepare,
3320 	.init = rockchip_vop2_init,
3321 	.set_plane = rockchip_vop2_set_plane,
3322 	.enable = rockchip_vop2_enable,
3323 	.disable = rockchip_vop2_disable,
3324 	.fixup_dts = rockchip_vop2_fixup_dts,
3325 };
3326