xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_vop2.c (revision cd6c85a92fdb3d2487c0f464232fd1caa851f4af)
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 <dm/ofnode.h>
27 #include <fixp-arith.h>
28 #include <syscon.h>
29 #include <linux/iopoll.h>
30 #include <dm/uclass-internal.h>
31 
32 #include "rockchip_display.h"
33 #include "rockchip_crtc.h"
34 #include "rockchip_connector.h"
35 #include "rockchip_post_csc.h"
36 
37 /* System registers definition */
38 #define RK3568_REG_CFG_DONE			0x000
39 #define	CFG_DONE_EN				BIT(15)
40 
41 #define RK3568_VERSION_INFO			0x004
42 #define EN_MASK					1
43 
44 #define RK3568_AUTO_GATING_CTRL			0x008
45 
46 #define RK3568_SYS_AXI_LUT_CTRL			0x024
47 #define LUT_DMA_EN_SHIFT			0
48 #define DSP_VS_T_SEL_SHIFT			16
49 
50 #define RK3568_DSP_IF_EN			0x028
51 #define RGB_EN_SHIFT				0
52 #define RK3588_DP0_EN_SHIFT			0
53 #define RK3588_DP1_EN_SHIFT			1
54 #define RK3588_RGB_EN_SHIFT			8
55 #define HDMI0_EN_SHIFT				1
56 #define EDP0_EN_SHIFT				3
57 #define RK3588_EDP0_EN_SHIFT			2
58 #define RK3588_HDMI0_EN_SHIFT			3
59 #define MIPI0_EN_SHIFT				4
60 #define RK3588_EDP1_EN_SHIFT			4
61 #define RK3588_HDMI1_EN_SHIFT			5
62 #define RK3588_MIPI0_EN_SHIFT                   6
63 #define MIPI1_EN_SHIFT				20
64 #define RK3588_MIPI1_EN_SHIFT                   7
65 #define LVDS0_EN_SHIFT				5
66 #define LVDS1_EN_SHIFT				24
67 #define BT1120_EN_SHIFT				6
68 #define BT656_EN_SHIFT				7
69 #define IF_MUX_MASK				3
70 #define RGB_MUX_SHIFT				8
71 #define HDMI0_MUX_SHIFT				10
72 #define RK3588_DP0_MUX_SHIFT			12
73 #define RK3588_DP1_MUX_SHIFT			14
74 #define EDP0_MUX_SHIFT				14
75 #define RK3588_HDMI_EDP0_MUX_SHIFT		16
76 #define RK3588_HDMI_EDP1_MUX_SHIFT		18
77 #define MIPI0_MUX_SHIFT				16
78 #define RK3588_MIPI0_MUX_SHIFT			20
79 #define MIPI1_MUX_SHIFT				21
80 #define LVDS0_MUX_SHIFT				18
81 #define LVDS1_MUX_SHIFT				25
82 
83 #define RK3568_DSP_IF_CTRL			0x02c
84 #define LVDS_DUAL_EN_SHIFT			0
85 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT		1
86 #define LVDS_DUAL_SWAP_EN_SHIFT			2
87 #define BT656_UV_SWAP				4
88 #define BT656_YC_SWAP				5
89 #define BT656_DCLK_POL				6
90 #define RK3588_HDMI_DUAL_EN_SHIFT		8
91 #define RK3588_EDP_DUAL_EN_SHIFT		8
92 #define RK3588_DP_DUAL_EN_SHIFT			9
93 #define RK3568_MIPI_DUAL_EN_SHIFT		10
94 #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT		11
95 #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT		12
96 
97 #define RK3568_DSP_IF_POL			0x030
98 #define IF_CTRL_REG_DONE_IMD_MASK		1
99 #define IF_CTRL_REG_DONE_IMD_SHIFT		28
100 #define IF_CRTL_MIPI_DCLK_POL_SHIT		19
101 #define IF_CRTL_EDP_DCLK_POL_SHIT		15
102 #define IF_CRTL_HDMI_DCLK_POL_SHIT		7
103 #define IF_CRTL_HDMI_PIN_POL_MASK		0x7
104 #define IF_CRTL_HDMI_PIN_POL_SHIT		4
105 
106 #define RK3588_DP0_PIN_POL_SHIFT		8
107 #define RK3588_DP1_PIN_POL_SHIFT		12
108 #define RK3588_IF_PIN_POL_MASK			0x7
109 
110 #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT		3
111 
112 #define HDMI_EDP0_DCLK_DIV_SHIFT		16
113 #define HDMI_EDP0_PIXCLK_DIV_SHIFT		18
114 #define HDMI_EDP1_DCLK_DIV_SHIFT		20
115 #define HDMI_EDP1_PIXCLK_DIV_SHIFT		22
116 #define MIPI0_PIXCLK_DIV_SHIFT			24
117 #define MIPI1_PIXCLK_DIV_SHIFT			26
118 
119 #define RK3568_SYS_OTP_WIN_EN			0x50
120 #define OTP_WIN_EN_SHIFT			0
121 #define RK3568_SYS_LUT_PORT_SEL			0x58
122 #define GAMMA_PORT_SEL_MASK			0x3
123 #define GAMMA_PORT_SEL_SHIFT			0
124 #define GAMMA_AHB_WRITE_SEL_MASK		0x3
125 #define GAMMA_AHB_WRITE_SEL_SHIFT		12
126 #define PORT_MERGE_EN_SHIFT			16
127 #define ESMART_LB_MODE_SEL_MASK			0x3
128 #define ESMART_LB_MODE_SEL_SHIFT		26
129 
130 #define RK3568_SYS_PD_CTRL			0x034
131 #define RK3568_VP0_LINE_FLAG			0x70
132 #define RK3568_VP1_LINE_FLAG			0x74
133 #define RK3568_VP2_LINE_FLAG			0x78
134 #define RK3568_SYS0_INT_EN			0x80
135 #define RK3568_SYS0_INT_CLR			0x84
136 #define RK3568_SYS0_INT_STATUS			0x88
137 #define RK3568_SYS1_INT_EN			0x90
138 #define RK3568_SYS1_INT_CLR			0x94
139 #define RK3568_SYS1_INT_STATUS			0x98
140 #define RK3568_VP0_INT_EN			0xA0
141 #define RK3568_VP0_INT_CLR			0xA4
142 #define RK3568_VP0_INT_STATUS			0xA8
143 #define RK3568_VP1_INT_EN			0xB0
144 #define RK3568_VP1_INT_CLR			0xB4
145 #define RK3568_VP1_INT_STATUS			0xB8
146 #define RK3568_VP2_INT_EN			0xC0
147 #define RK3568_VP2_INT_CLR			0xC4
148 #define RK3568_VP2_INT_STATUS			0xC8
149 #define RK3588_CLUSTER0_PD_EN_SHIFT		0
150 #define RK3588_CLUSTER1_PD_EN_SHIFT		1
151 #define RK3588_CLUSTER2_PD_EN_SHIFT		2
152 #define RK3588_CLUSTER3_PD_EN_SHIFT		3
153 #define RK3588_DSC_8K_PD_EN_SHIFT		5
154 #define RK3588_DSC_4K_PD_EN_SHIFT		6
155 #define RK3588_ESMART_PD_EN_SHIFT		7
156 
157 #define RK3588_SYS_VAR_FREQ_CTRL		0x038
158 #define RK3588_VP0_LINE_FLAG_OR_EN_SHIFT	20
159 #define RK3588_VP0_DSP_HOLD_OR_EN_SHIFT		24
160 #define RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT	28
161 
162 #define RK3568_SYS_STATUS0			0x60
163 #define RK3588_CLUSTER0_PD_STATUS_SHIFT		8
164 #define RK3588_CLUSTER1_PD_STATUS_SHIFT		9
165 #define RK3588_CLUSTER2_PD_STATUS_SHIFT		10
166 #define RK3588_CLUSTER3_PD_STATUS_SHIFT		11
167 #define RK3588_DSC_8K_PD_STATUS_SHIFT		13
168 #define RK3588_DSC_4K_PD_STATUS_SHIFT		14
169 #define RK3588_ESMART_PD_STATUS_SHIFT		15
170 
171 #define RK3568_SYS_CTRL_LINE_FLAG0		0x70
172 #define LINE_FLAG_NUM_MASK			0x1fff
173 #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT		0
174 #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT		16
175 
176 /* DSC CTRL registers definition */
177 #define RK3588_DSC_8K_SYS_CTRL			0x200
178 #define DSC_PORT_SEL_MASK			0x3
179 #define DSC_PORT_SEL_SHIFT			0
180 #define DSC_MAN_MODE_MASK			0x1
181 #define DSC_MAN_MODE_SHIFT			2
182 #define DSC_INTERFACE_MODE_MASK			0x3
183 #define DSC_INTERFACE_MODE_SHIFT		4
184 #define DSC_PIXEL_NUM_MASK			0x3
185 #define DSC_PIXEL_NUM_SHIFT			6
186 #define DSC_PXL_CLK_DIV_MASK			0x1
187 #define DSC_PXL_CLK_DIV_SHIFT			8
188 #define DSC_CDS_CLK_DIV_MASK			0x3
189 #define DSC_CDS_CLK_DIV_SHIFT			12
190 #define DSC_TXP_CLK_DIV_MASK			0x3
191 #define DSC_TXP_CLK_DIV_SHIFT			14
192 #define DSC_INIT_DLY_MODE_MASK			0x1
193 #define DSC_INIT_DLY_MODE_SHIFT			16
194 #define DSC_SCAN_EN_SHIFT			17
195 #define DSC_HALT_EN_SHIFT			18
196 
197 #define RK3588_DSC_8K_RST			0x204
198 #define RST_DEASSERT_MASK			0x1
199 #define RST_DEASSERT_SHIFT			0
200 
201 #define RK3588_DSC_8K_CFG_DONE			0x208
202 #define DSC_CFG_DONE_SHIFT			0
203 
204 #define RK3588_DSC_8K_INIT_DLY			0x20C
205 #define DSC_INIT_DLY_NUM_MASK			0xffff
206 #define DSC_INIT_DLY_NUM_SHIFT			0
207 #define SCAN_TIMING_PARA_IMD_EN_SHIFT		16
208 
209 #define RK3588_DSC_8K_HTOTAL_HS_END		0x210
210 #define DSC_HTOTAL_PW_MASK			0xffffffff
211 #define DSC_HTOTAL_PW_SHIFT			0
212 
213 #define RK3588_DSC_8K_HACT_ST_END		0x214
214 #define DSC_HACT_ST_END_MASK			0xffffffff
215 #define DSC_HACT_ST_END_SHIFT			0
216 
217 #define RK3588_DSC_8K_VTOTAL_VS_END		0x218
218 #define DSC_VTOTAL_PW_MASK			0xffffffff
219 #define DSC_VTOTAL_PW_SHIFT			0
220 
221 #define RK3588_DSC_8K_VACT_ST_END		0x21C
222 #define DSC_VACT_ST_END_MASK			0xffffffff
223 #define DSC_VACT_ST_END_SHIFT			0
224 
225 #define RK3588_DSC_8K_STATUS			0x220
226 
227 /* Overlay registers definition    */
228 #define RK3528_OVL_SYS				0x500
229 #define RK3528_OVL_SYS_PORT_SEL_IMD		0x504
230 #define RK3528_OVL_SYS_GATING_EN_IMD		0x508
231 #define RK3528_OVL_SYS_CLUSTER0_CTRL		0x510
232 #define RK3528_OVL_SYS_ESMART0_CTRL		0x520
233 #define RK3528_OVL_SYS_ESMART1_CTRL		0x524
234 #define RK3528_OVL_SYS_ESMART2_CTRL		0x528
235 #define RK3528_OVL_SYS_ESMART3_CTRL		0x52C
236 #define RK3528_CLUSTER0_MIX_SRC_COLOR_CTRL	0x530
237 #define RK3528_CLUSTER0_MIX_DST_COLOR_CTRL	0x534
238 #define RK3528_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x538
239 #define RK3528_CLUSTER0_MIX_DST_ALPHA_CTRL	0x53c
240 
241 #define RK3528_OVL_PORT0_CTRL			0x600
242 #define RK3568_OVL_CTRL				0x600
243 #define OVL_MODE_SEL_MASK			0x1
244 #define OVL_MODE_SEL_SHIFT			0
245 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT		28
246 #define RK3528_OVL_PORT0_LAYER_SEL		0x604
247 #define RK3568_OVL_LAYER_SEL			0x604
248 #define LAYER_SEL_MASK				0xf
249 
250 #define RK3568_OVL_PORT_SEL			0x608
251 #define PORT_MUX_MASK				0xf
252 #define PORT_MUX_SHIFT				0
253 #define LAYER_SEL_PORT_MASK			0x3
254 #define LAYER_SEL_PORT_SHIFT			16
255 
256 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL	0x610
257 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL	0x614
258 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x618
259 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL	0x61C
260 #define RK3528_OVL_PORT0_MIX0_SRC_COLOR_CTRL	0x620
261 #define RK3528_OVL_PORT0_MIX0_DST_COLOR_CTRL	0x624
262 #define RK3528_OVL_PORT0_MIX0_SRC_ALPHA_CTRL	0x628
263 #define RK3528_OVL_PORT0_MIX0_DST_ALPHA_CTRL	0x62C
264 #define RK3528_OVL_PORT0_MIX1_SRC_COLOR_CTRL	0x630
265 #define RK3528_OVL_PORT0_MIX1_DST_COLOR_CTRL	0x634
266 #define RK3528_OVL_PORT0_MIX1_SRC_ALPHA_CTRL	0x638
267 #define RK3528_OVL_PORT0_MIX1_DST_ALPHA_CTRL	0x63C
268 #define RK3528_OVL_PORT0_MIX2_SRC_COLOR_CTRL	0x640
269 #define RK3528_OVL_PORT0_MIX2_DST_COLOR_CTRL	0x644
270 #define RK3528_OVL_PORT0_MIX2_SRC_ALPHA_CTRL	0x648
271 #define RK3528_OVL_PORT0_MIX2_DST_ALPHA_CTRL	0x64C
272 #define RK3568_MIX0_SRC_COLOR_CTRL		0x650
273 #define RK3568_MIX0_DST_COLOR_CTRL		0x654
274 #define RK3568_MIX0_SRC_ALPHA_CTRL		0x658
275 #define RK3568_MIX0_DST_ALPHA_CTRL		0x65C
276 #define RK3528_HDR_SRC_COLOR_CTRL		0x660
277 #define RK3528_HDR_DST_COLOR_CTRL		0x664
278 #define RK3528_HDR_SRC_ALPHA_CTRL		0x668
279 #define RK3528_HDR_DST_ALPHA_CTRL		0x66C
280 #define RK3528_OVL_PORT0_BG_MIX_CTRL		0x670
281 #define RK3568_HDR0_SRC_COLOR_CTRL		0x6C0
282 #define RK3568_HDR0_DST_COLOR_CTRL		0x6C4
283 #define RK3568_HDR0_SRC_ALPHA_CTRL		0x6C8
284 #define RK3568_HDR0_DST_ALPHA_CTRL		0x6CC
285 #define RK3568_VP0_BG_MIX_CTRL			0x6E0
286 #define BG_MIX_CTRL_MASK			0xff
287 #define BG_MIX_CTRL_SHIFT			24
288 #define RK3568_VP1_BG_MIX_CTRL			0x6E4
289 #define RK3568_VP2_BG_MIX_CTRL			0x6E8
290 #define RK3568_CLUSTER_DLY_NUM			0x6F0
291 #define RK3568_SMART_DLY_NUM			0x6F8
292 
293 #define RK3528_OVL_PORT1_CTRL			0x700
294 #define RK3528_OVL_PORT1_LAYER_SEL		0x704
295 #define RK3528_OVL_PORT1_MIX0_SRC_COLOR_CTRL	0x720
296 #define RK3528_OVL_PORT1_MIX0_DST_COLOR_CTRL	0x724
297 #define RK3528_OVL_PORT1_MIX0_SRC_ALPHA_CTRL	0x728
298 #define RK3528_OVL_PORT1_MIX0_DST_ALPHA_CTRL	0x72C
299 #define RK3528_OVL_PORT1_MIX1_SRC_COLOR_CTRL	0x730
300 #define RK3528_OVL_PORT1_MIX1_DST_COLOR_CTRL	0x734
301 #define RK3528_OVL_PORT1_MIX1_SRC_ALPHA_CTRL	0x738
302 #define RK3528_OVL_PORT1_MIX1_DST_ALPHA_CTRL	0x73C
303 #define RK3528_OVL_PORT1_MIX2_SRC_COLOR_CTRL	0x740
304 #define RK3528_OVL_PORT1_MIX2_DST_COLOR_CTRL	0x744
305 #define RK3528_OVL_PORT1_MIX2_SRC_ALPHA_CTRL	0x748
306 #define RK3528_OVL_PORT1_MIX2_DST_ALPHA_CTRL	0x74C
307 #define RK3528_OVL_PORT1_BG_MIX_CTRL		0x770
308 
309 /* Video Port registers definition */
310 #define RK3568_VP0_DSP_CTRL			0xC00
311 #define OUT_MODE_MASK				0xf
312 #define OUT_MODE_SHIFT				0
313 #define DATA_SWAP_MASK				0x1f
314 #define DATA_SWAP_SHIFT				8
315 #define DSP_BG_SWAP				0x1
316 #define DSP_RB_SWAP				0x2
317 #define DSP_RG_SWAP				0x4
318 #define DSP_DELTA_SWAP				0x8
319 #define CORE_DCLK_DIV_EN_SHIFT			4
320 #define P2I_EN_SHIFT				5
321 #define DSP_FILED_POL				6
322 #define INTERLACE_EN_SHIFT			7
323 #define DSP_X_MIR_EN_SHIFT			13
324 #define POST_DSP_OUT_R2Y_SHIFT			15
325 #define PRE_DITHER_DOWN_EN_SHIFT		16
326 #define DITHER_DOWN_EN_SHIFT			17
327 #define GAMMA_UPDATE_EN_SHIFT			22
328 #define DSP_LUT_EN_SHIFT			28
329 
330 #define STANDBY_EN_SHIFT			31
331 
332 #define RK3568_VP0_MIPI_CTRL			0xC04
333 #define DCLK_DIV2_SHIFT				4
334 #define DCLK_DIV2_MASK				0x3
335 #define MIPI_DUAL_EN_SHIFT			20
336 #define MIPI_DUAL_SWAP_EN_SHIFT			21
337 #define EDPI_TE_EN				28
338 #define EDPI_WMS_HOLD_EN			30
339 #define EDPI_WMS_FS				31
340 
341 
342 #define RK3568_VP0_COLOR_BAR_CTRL		0xC08
343 
344 #define RK3568_VP0_DCLK_SEL			0xC0C
345 
346 #define RK3568_VP0_3D_LUT_CTRL			0xC10
347 #define VP0_3D_LUT_EN_SHIFT				0
348 #define VP0_3D_LUT_UPDATE_SHIFT			2
349 
350 #define RK3588_VP0_CLK_CTRL			0xC0C
351 #define DCLK_CORE_DIV_SHIFT			0
352 #define DCLK_OUT_DIV_SHIFT			2
353 
354 #define RK3568_VP0_3D_LUT_MST			0xC20
355 
356 #define RK3568_VP0_DSP_BG			0xC2C
357 #define RK3568_VP0_PRE_SCAN_HTIMING		0xC30
358 #define RK3568_VP0_POST_DSP_HACT_INFO		0xC34
359 #define RK3568_VP0_POST_DSP_VACT_INFO		0xC38
360 #define RK3568_VP0_POST_SCL_FACTOR_YRGB		0xC3C
361 #define RK3568_VP0_POST_SCL_CTRL		0xC40
362 #define RK3568_VP0_POST_DSP_VACT_INFO_F1	0xC44
363 #define RK3568_VP0_DSP_HTOTAL_HS_END		0xC48
364 #define RK3568_VP0_DSP_HACT_ST_END		0xC4C
365 #define RK3568_VP0_DSP_VTOTAL_VS_END		0xC50
366 #define RK3568_VP0_DSP_VACT_ST_END		0xC54
367 #define RK3568_VP0_DSP_VS_ST_END_F1		0xC58
368 #define RK3568_VP0_DSP_VACT_ST_END_F1		0xC5C
369 
370 #define RK3568_VP0_BCSH_CTRL			0xC60
371 #define BCSH_CTRL_Y2R_SHIFT			0
372 #define BCSH_CTRL_Y2R_MASK			0x1
373 #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT		2
374 #define BCSH_CTRL_Y2R_CSC_MODE_MASK		0x3
375 #define BCSH_CTRL_R2Y_SHIFT			4
376 #define BCSH_CTRL_R2Y_MASK			0x1
377 #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT		6
378 #define BCSH_CTRL_R2Y_CSC_MODE_MASK		0x3
379 
380 #define RK3568_VP0_BCSH_BCS			0xC64
381 #define BCSH_BRIGHTNESS_SHIFT			0
382 #define BCSH_BRIGHTNESS_MASK			0xFF
383 #define BCSH_CONTRAST_SHIFT			8
384 #define BCSH_CONTRAST_MASK			0x1FF
385 #define BCSH_SATURATION_SHIFT			20
386 #define BCSH_SATURATION_MASK			0x3FF
387 #define BCSH_OUT_MODE_SHIFT			30
388 #define BCSH_OUT_MODE_MASK			0x3
389 
390 #define RK3568_VP0_BCSH_H			0xC68
391 #define BCSH_SIN_HUE_SHIFT			0
392 #define BCSH_SIN_HUE_MASK			0x1FF
393 #define BCSH_COS_HUE_SHIFT			16
394 #define BCSH_COS_HUE_MASK			0x1FF
395 
396 #define RK3568_VP0_BCSH_COLOR			0xC6C
397 #define BCSH_EN_SHIFT				31
398 #define BCSH_EN_MASK				1
399 
400 #define RK3528_VP0_ACM_CTRL			0xCD0
401 #define POST_CSC_COE00_MASK			0xFFFF
402 #define POST_CSC_COE00_SHIFT			16
403 #define POST_R2Y_MODE_MASK			0x7
404 #define POST_R2Y_MODE_SHIFT			8
405 #define POST_CSC_MODE_MASK			0x7
406 #define POST_CSC_MODE_SHIFT			3
407 #define POST_R2Y_EN_MASK			0x1
408 #define POST_R2Y_EN_SHIFT			2
409 #define POST_CSC_EN_MASK			0x1
410 #define POST_CSC_EN_SHIFT			1
411 #define POST_ACM_BYPASS_EN_MASK			0x1
412 #define POST_ACM_BYPASS_EN_SHIFT		0
413 #define RK3528_VP0_CSC_COE01_02			0xCD4
414 #define RK3528_VP0_CSC_COE10_11			0xCD8
415 #define RK3528_VP0_CSC_COE12_20			0xCDC
416 #define RK3528_VP0_CSC_COE21_22			0xCE0
417 #define RK3528_VP0_CSC_OFFSET0			0xCE4
418 #define RK3528_VP0_CSC_OFFSET1			0xCE8
419 #define RK3528_VP0_CSC_OFFSET2			0xCEC
420 
421 #define RK3568_VP1_DSP_CTRL			0xD00
422 #define RK3568_VP1_MIPI_CTRL			0xD04
423 #define RK3568_VP1_COLOR_BAR_CTRL		0xD08
424 #define RK3568_VP1_PRE_SCAN_HTIMING		0xD30
425 #define RK3568_VP1_POST_DSP_HACT_INFO		0xD34
426 #define RK3568_VP1_POST_DSP_VACT_INFO		0xD38
427 #define RK3568_VP1_POST_SCL_FACTOR_YRGB		0xD3C
428 #define RK3568_VP1_POST_SCL_CTRL		0xD40
429 #define RK3568_VP1_DSP_HACT_INFO		0xD34
430 #define RK3568_VP1_DSP_VACT_INFO		0xD38
431 #define RK3568_VP1_POST_DSP_VACT_INFO_F1	0xD44
432 #define RK3568_VP1_DSP_HTOTAL_HS_END		0xD48
433 #define RK3568_VP1_DSP_HACT_ST_END		0xD4C
434 #define RK3568_VP1_DSP_VTOTAL_VS_END		0xD50
435 #define RK3568_VP1_DSP_VACT_ST_END		0xD54
436 #define RK3568_VP1_DSP_VS_ST_END_F1		0xD58
437 #define RK3568_VP1_DSP_VACT_ST_END_F1		0xD5C
438 
439 #define RK3568_VP2_DSP_CTRL			0xE00
440 #define RK3568_VP2_MIPI_CTRL			0xE04
441 #define RK3568_VP2_COLOR_BAR_CTRL		0xE08
442 #define RK3568_VP2_PRE_SCAN_HTIMING		0xE30
443 #define RK3568_VP2_POST_DSP_HACT_INFO		0xE34
444 #define RK3568_VP2_POST_DSP_VACT_INFO		0xE38
445 #define RK3568_VP2_POST_SCL_FACTOR_YRGB		0xE3C
446 #define RK3568_VP2_POST_SCL_CTRL		0xE40
447 #define RK3568_VP2_DSP_HACT_INFO		0xE34
448 #define RK3568_VP2_DSP_VACT_INFO		0xE38
449 #define RK3568_VP2_POST_DSP_VACT_INFO_F1	0xE44
450 #define RK3568_VP2_DSP_HTOTAL_HS_END		0xE48
451 #define RK3568_VP2_DSP_HACT_ST_END		0xE4C
452 #define RK3568_VP2_DSP_VTOTAL_VS_END		0xE50
453 #define RK3568_VP2_DSP_VACT_ST_END		0xE54
454 #define RK3568_VP2_DSP_VS_ST_END_F1		0xE58
455 #define RK3568_VP2_DSP_VACT_ST_END_F1		0xE5C
456 
457 /* Cluster0 register definition */
458 #define RK3568_CLUSTER0_WIN0_CTRL0		0x1000
459 #define CLUSTER_YUV2RGB_EN_SHIFT		8
460 #define CLUSTER_RGB2YUV_EN_SHIFT		9
461 #define CLUSTER_CSC_MODE_SHIFT			10
462 #define RK3568_CLUSTER0_WIN0_CTRL1		0x1004
463 #define RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT	12
464 #define RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT	14
465 #define RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT	14
466 #define AVG2_MASK				0x1
467 #define CLUSTER_AVG2_SHIFT			18
468 #define AVG4_MASK				0x1
469 #define CLUSTER_AVG4_SHIFT			19
470 #define RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT	22
471 #define CLUSTER_XGT_EN_SHIFT			24
472 #define XGT_MODE_MASK				0x3
473 #define CLUSTER_XGT_MODE_SHIFT			25
474 #define CLUSTER_XAVG_EN_SHIFT			27
475 #define CLUSTER_YRGB_GT2_SHIFT			28
476 #define CLUSTER_YRGB_GT4_SHIFT			29
477 #define RK3568_CLUSTER0_WIN0_CTRL2		0x1008
478 #define CLUSTER_AXI_YRGB_ID_MASK		0x1f
479 #define CLUSTER_AXI_YRGB_ID_SHIFT		0
480 #define CLUSTER_AXI_UV_ID_MASK			0x1f
481 #define CLUSTER_AXI_UV_ID_SHIFT			5
482 
483 #define RK3568_CLUSTER0_WIN0_YRGB_MST		0x1010
484 #define RK3568_CLUSTER0_WIN0_CBR_MST		0x1014
485 #define RK3568_CLUSTER0_WIN0_VIR		0x1018
486 #define RK3568_CLUSTER0_WIN0_ACT_INFO		0x1020
487 #define RK3568_CLUSTER0_WIN0_DSP_INFO		0x1024
488 #define RK3568_CLUSTER0_WIN0_DSP_ST		0x1028
489 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB	0x1030
490 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE	0x1054
491 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR	0x1058
492 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH	0x105C
493 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE	0x1060
494 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET	0x1064
495 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET	0x1068
496 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL		0x106C
497 
498 #define RK3568_CLUSTER0_WIN1_CTRL0		0x1080
499 #define RK3568_CLUSTER0_WIN1_CTRL1		0x1084
500 #define RK3568_CLUSTER0_WIN1_YRGB_MST		0x1090
501 #define RK3568_CLUSTER0_WIN1_CBR_MST		0x1094
502 #define RK3568_CLUSTER0_WIN1_VIR		0x1098
503 #define RK3568_CLUSTER0_WIN1_ACT_INFO		0x10A0
504 #define RK3568_CLUSTER0_WIN1_DSP_INFO		0x10A4
505 #define RK3568_CLUSTER0_WIN1_DSP_ST		0x10A8
506 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB	0x10B0
507 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE	0x10D4
508 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR	0x10D8
509 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH	0x10DC
510 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE	0x10E0
511 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET	0x10E4
512 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET	0x10E8
513 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL		0x10EC
514 
515 #define RK3568_CLUSTER0_CTRL			0x1100
516 #define CLUSTER_EN_SHIFT			0
517 #define CLUSTER_AXI_ID_MASK			0x1
518 #define CLUSTER_AXI_ID_SHIFT			13
519 
520 #define RK3568_CLUSTER1_WIN0_CTRL0		0x1200
521 #define RK3568_CLUSTER1_WIN0_CTRL1		0x1204
522 #define RK3568_CLUSTER1_WIN0_YRGB_MST		0x1210
523 #define RK3568_CLUSTER1_WIN0_CBR_MST		0x1214
524 #define RK3568_CLUSTER1_WIN0_VIR		0x1218
525 #define RK3568_CLUSTER1_WIN0_ACT_INFO		0x1220
526 #define RK3568_CLUSTER1_WIN0_DSP_INFO		0x1224
527 #define RK3568_CLUSTER1_WIN0_DSP_ST		0x1228
528 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB	0x1230
529 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE	0x1254
530 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR	0x1258
531 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH	0x125C
532 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE	0x1260
533 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET	0x1264
534 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET	0x1268
535 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL		0x126C
536 
537 #define RK3568_CLUSTER1_WIN1_CTRL0		0x1280
538 #define RK3568_CLUSTER1_WIN1_CTRL1		0x1284
539 #define RK3568_CLUSTER1_WIN1_YRGB_MST		0x1290
540 #define RK3568_CLUSTER1_WIN1_CBR_MST		0x1294
541 #define RK3568_CLUSTER1_WIN1_VIR		0x1298
542 #define RK3568_CLUSTER1_WIN1_ACT_INFO		0x12A0
543 #define RK3568_CLUSTER1_WIN1_DSP_INFO		0x12A4
544 #define RK3568_CLUSTER1_WIN1_DSP_ST		0x12A8
545 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB	0x12B0
546 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE	0x12D4
547 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR	0x12D8
548 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH	0x12DC
549 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE	0x12E0
550 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET	0x12E4
551 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET	0x12E8
552 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL		0x12EC
553 
554 #define RK3568_CLUSTER1_CTRL			0x1300
555 
556 /* Esmart register definition */
557 #define RK3568_ESMART0_CTRL0			0x1800
558 #define RGB2YUV_EN_SHIFT			1
559 #define CSC_MODE_SHIFT				2
560 #define CSC_MODE_MASK				0x3
561 #define ESMART_LB_SELECT_SHIFT			12
562 #define ESMART_LB_SELECT_MASK			0x3
563 
564 #define RK3568_ESMART0_CTRL1			0x1804
565 #define ESMART_AXI_YRGB_ID_MASK			0x1f
566 #define ESMART_AXI_YRGB_ID_SHIFT		4
567 #define ESMART_AXI_UV_ID_MASK			0x1f
568 #define ESMART_AXI_UV_ID_SHIFT			12
569 #define YMIRROR_EN_SHIFT			31
570 
571 #define RK3568_ESMART0_AXI_CTRL			0x1808
572 #define ESMART_AXI_ID_MASK			0x1
573 #define ESMART_AXI_ID_SHIFT			1
574 
575 #define RK3568_ESMART0_REGION0_CTRL		0x1810
576 #define WIN_EN_SHIFT				0
577 #define WIN_FORMAT_MASK				0x1f
578 #define WIN_FORMAT_SHIFT			1
579 #define REGION0_RB_SWAP_SHIFT			14
580 #define ESMART_XAVG_EN_SHIFT			20
581 #define ESMART_XGT_EN_SHIFT			21
582 #define ESMART_XGT_MODE_SHIFT			22
583 
584 #define RK3568_ESMART0_REGION0_YRGB_MST		0x1814
585 #define RK3568_ESMART0_REGION0_CBR_MST		0x1818
586 #define RK3568_ESMART0_REGION0_VIR		0x181C
587 #define RK3568_ESMART0_REGION0_ACT_INFO		0x1820
588 #define RK3568_ESMART0_REGION0_DSP_INFO		0x1824
589 #define RK3568_ESMART0_REGION0_DSP_ST		0x1828
590 #define RK3568_ESMART0_REGION0_SCL_CTRL		0x1830
591 #define YRGB_XSCL_MODE_MASK			0x3
592 #define YRGB_XSCL_MODE_SHIFT			0
593 #define YRGB_XSCL_FILTER_MODE_MASK		0x3
594 #define YRGB_XSCL_FILTER_MODE_SHIFT		2
595 #define YRGB_YSCL_MODE_MASK			0x3
596 #define YRGB_YSCL_MODE_SHIFT			4
597 #define YRGB_YSCL_FILTER_MODE_MASK		0x3
598 #define YRGB_YSCL_FILTER_MODE_SHIFT		6
599 
600 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB	0x1834
601 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR	0x1838
602 #define RK3568_ESMART0_REGION0_SCL_OFFSET	0x183C
603 #define RK3568_ESMART0_REGION1_CTRL		0x1840
604 #define YRGB_GT2_MASK				0x1
605 #define YRGB_GT2_SHIFT				8
606 #define YRGB_GT4_MASK				0x1
607 #define YRGB_GT4_SHIFT				9
608 
609 #define RK3568_ESMART0_REGION1_YRGB_MST		0x1844
610 #define RK3568_ESMART0_REGION1_CBR_MST		0x1848
611 #define RK3568_ESMART0_REGION1_VIR		0x184C
612 #define RK3568_ESMART0_REGION1_ACT_INFO		0x1850
613 #define RK3568_ESMART0_REGION1_DSP_INFO		0x1854
614 #define RK3568_ESMART0_REGION1_DSP_ST		0x1858
615 #define RK3568_ESMART0_REGION1_SCL_CTRL		0x1860
616 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB	0x1864
617 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR	0x1868
618 #define RK3568_ESMART0_REGION1_SCL_OFFSET	0x186C
619 #define RK3568_ESMART0_REGION2_CTRL		0x1870
620 #define RK3568_ESMART0_REGION2_YRGB_MST		0x1874
621 #define RK3568_ESMART0_REGION2_CBR_MST		0x1878
622 #define RK3568_ESMART0_REGION2_VIR		0x187C
623 #define RK3568_ESMART0_REGION2_ACT_INFO		0x1880
624 #define RK3568_ESMART0_REGION2_DSP_INFO		0x1884
625 #define RK3568_ESMART0_REGION2_DSP_ST		0x1888
626 #define RK3568_ESMART0_REGION2_SCL_CTRL		0x1890
627 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB	0x1894
628 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR	0x1898
629 #define RK3568_ESMART0_REGION2_SCL_OFFSET	0x189C
630 #define RK3568_ESMART0_REGION3_CTRL		0x18A0
631 #define RK3568_ESMART0_REGION3_YRGB_MST		0x18A4
632 #define RK3568_ESMART0_REGION3_CBR_MST		0x18A8
633 #define RK3568_ESMART0_REGION3_VIR		0x18AC
634 #define RK3568_ESMART0_REGION3_ACT_INFO		0x18B0
635 #define RK3568_ESMART0_REGION3_DSP_INFO		0x18B4
636 #define RK3568_ESMART0_REGION3_DSP_ST		0x18B8
637 #define RK3568_ESMART0_REGION3_SCL_CTRL		0x18C0
638 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB	0x18C4
639 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR	0x18C8
640 #define RK3568_ESMART0_REGION3_SCL_OFFSET	0x18CC
641 
642 #define RK3568_ESMART1_CTRL0			0x1A00
643 #define RK3568_ESMART1_CTRL1			0x1A04
644 #define RK3568_ESMART1_REGION0_CTRL		0x1A10
645 #define RK3568_ESMART1_REGION0_YRGB_MST		0x1A14
646 #define RK3568_ESMART1_REGION0_CBR_MST		0x1A18
647 #define RK3568_ESMART1_REGION0_VIR		0x1A1C
648 #define RK3568_ESMART1_REGION0_ACT_INFO		0x1A20
649 #define RK3568_ESMART1_REGION0_DSP_INFO		0x1A24
650 #define RK3568_ESMART1_REGION0_DSP_ST		0x1A28
651 #define RK3568_ESMART1_REGION0_SCL_CTRL		0x1A30
652 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB	0x1A34
653 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR	0x1A38
654 #define RK3568_ESMART1_REGION0_SCL_OFFSET	0x1A3C
655 #define RK3568_ESMART1_REGION1_CTRL		0x1A40
656 #define RK3568_ESMART1_REGION1_YRGB_MST		0x1A44
657 #define RK3568_ESMART1_REGION1_CBR_MST		0x1A48
658 #define RK3568_ESMART1_REGION1_VIR		0x1A4C
659 #define RK3568_ESMART1_REGION1_ACT_INFO		0x1A50
660 #define RK3568_ESMART1_REGION1_DSP_INFO		0x1A54
661 #define RK3568_ESMART1_REGION1_DSP_ST		0x1A58
662 #define RK3568_ESMART1_REGION1_SCL_CTRL		0x1A60
663 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB	0x1A64
664 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR	0x1A68
665 #define RK3568_ESMART1_REGION1_SCL_OFFSET	0x1A6C
666 #define RK3568_ESMART1_REGION2_CTRL		0x1A70
667 #define RK3568_ESMART1_REGION2_YRGB_MST		0x1A74
668 #define RK3568_ESMART1_REGION2_CBR_MST		0x1A78
669 #define RK3568_ESMART1_REGION2_VIR		0x1A7C
670 #define RK3568_ESMART1_REGION2_ACT_INFO		0x1A80
671 #define RK3568_ESMART1_REGION2_DSP_INFO		0x1A84
672 #define RK3568_ESMART1_REGION2_DSP_ST		0x1A88
673 #define RK3568_ESMART1_REGION2_SCL_CTRL		0x1A90
674 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB	0x1A94
675 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR	0x1A98
676 #define RK3568_ESMART1_REGION2_SCL_OFFSET	0x1A9C
677 #define RK3568_ESMART1_REGION3_CTRL		0x1AA0
678 #define RK3568_ESMART1_REGION3_YRGB_MST		0x1AA4
679 #define RK3568_ESMART1_REGION3_CBR_MST		0x1AA8
680 #define RK3568_ESMART1_REGION3_VIR		0x1AAC
681 #define RK3568_ESMART1_REGION3_ACT_INFO		0x1AB0
682 #define RK3568_ESMART1_REGION3_DSP_INFO		0x1AB4
683 #define RK3568_ESMART1_REGION3_DSP_ST		0x1AB8
684 #define RK3568_ESMART1_REGION3_SCL_CTRL		0x1AC0
685 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB	0x1AC4
686 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR	0x1AC8
687 #define RK3568_ESMART1_REGION3_SCL_OFFSET	0x1ACC
688 
689 #define RK3568_SMART0_CTRL0			0x1C00
690 #define RK3568_SMART0_CTRL1			0x1C04
691 #define RK3568_SMART0_REGION0_CTRL		0x1C10
692 #define RK3568_SMART0_REGION0_YRGB_MST		0x1C14
693 #define RK3568_SMART0_REGION0_CBR_MST		0x1C18
694 #define RK3568_SMART0_REGION0_VIR		0x1C1C
695 #define RK3568_SMART0_REGION0_ACT_INFO		0x1C20
696 #define RK3568_SMART0_REGION0_DSP_INFO		0x1C24
697 #define RK3568_SMART0_REGION0_DSP_ST		0x1C28
698 #define RK3568_SMART0_REGION0_SCL_CTRL		0x1C30
699 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB	0x1C34
700 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR	0x1C38
701 #define RK3568_SMART0_REGION0_SCL_OFFSET	0x1C3C
702 #define RK3568_SMART0_REGION1_CTRL		0x1C40
703 #define RK3568_SMART0_REGION1_YRGB_MST		0x1C44
704 #define RK3568_SMART0_REGION1_CBR_MST		0x1C48
705 #define RK3568_SMART0_REGION1_VIR		0x1C4C
706 #define RK3568_SMART0_REGION1_ACT_INFO		0x1C50
707 #define RK3568_SMART0_REGION1_DSP_INFO		0x1C54
708 #define RK3568_SMART0_REGION1_DSP_ST		0x1C58
709 #define RK3568_SMART0_REGION1_SCL_CTRL		0x1C60
710 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB	0x1C64
711 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR	0x1C68
712 #define RK3568_SMART0_REGION1_SCL_OFFSET	0x1C6C
713 #define RK3568_SMART0_REGION2_CTRL		0x1C70
714 #define RK3568_SMART0_REGION2_YRGB_MST		0x1C74
715 #define RK3568_SMART0_REGION2_CBR_MST		0x1C78
716 #define RK3568_SMART0_REGION2_VIR		0x1C7C
717 #define RK3568_SMART0_REGION2_ACT_INFO		0x1C80
718 #define RK3568_SMART0_REGION2_DSP_INFO		0x1C84
719 #define RK3568_SMART0_REGION2_DSP_ST		0x1C88
720 #define RK3568_SMART0_REGION2_SCL_CTRL		0x1C90
721 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB	0x1C94
722 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR	0x1C98
723 #define RK3568_SMART0_REGION2_SCL_OFFSET	0x1C9C
724 #define RK3568_SMART0_REGION3_CTRL		0x1CA0
725 #define RK3568_SMART0_REGION3_YRGB_MST		0x1CA4
726 #define RK3568_SMART0_REGION3_CBR_MST		0x1CA8
727 #define RK3568_SMART0_REGION3_VIR		0x1CAC
728 #define RK3568_SMART0_REGION3_ACT_INFO		0x1CB0
729 #define RK3568_SMART0_REGION3_DSP_INFO		0x1CB4
730 #define RK3568_SMART0_REGION3_DSP_ST		0x1CB8
731 #define RK3568_SMART0_REGION3_SCL_CTRL		0x1CC0
732 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB	0x1CC4
733 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR	0x1CC8
734 #define RK3568_SMART0_REGION3_SCL_OFFSET	0x1CCC
735 
736 #define RK3568_SMART1_CTRL0			0x1E00
737 #define RK3568_SMART1_CTRL1			0x1E04
738 #define RK3568_SMART1_REGION0_CTRL		0x1E10
739 #define RK3568_SMART1_REGION0_YRGB_MST		0x1E14
740 #define RK3568_SMART1_REGION0_CBR_MST		0x1E18
741 #define RK3568_SMART1_REGION0_VIR		0x1E1C
742 #define RK3568_SMART1_REGION0_ACT_INFO		0x1E20
743 #define RK3568_SMART1_REGION0_DSP_INFO		0x1E24
744 #define RK3568_SMART1_REGION0_DSP_ST		0x1E28
745 #define RK3568_SMART1_REGION0_SCL_CTRL		0x1E30
746 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB	0x1E34
747 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR	0x1E38
748 #define RK3568_SMART1_REGION0_SCL_OFFSET	0x1E3C
749 #define RK3568_SMART1_REGION1_CTRL		0x1E40
750 #define RK3568_SMART1_REGION1_YRGB_MST		0x1E44
751 #define RK3568_SMART1_REGION1_CBR_MST		0x1E48
752 #define RK3568_SMART1_REGION1_VIR		0x1E4C
753 #define RK3568_SMART1_REGION1_ACT_INFO		0x1E50
754 #define RK3568_SMART1_REGION1_DSP_INFO		0x1E54
755 #define RK3568_SMART1_REGION1_DSP_ST		0x1E58
756 #define RK3568_SMART1_REGION1_SCL_CTRL		0x1E60
757 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB	0x1E64
758 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR	0x1E68
759 #define RK3568_SMART1_REGION1_SCL_OFFSET	0x1E6C
760 #define RK3568_SMART1_REGION2_CTRL		0x1E70
761 #define RK3568_SMART1_REGION2_YRGB_MST		0x1E74
762 #define RK3568_SMART1_REGION2_CBR_MST		0x1E78
763 #define RK3568_SMART1_REGION2_VIR		0x1E7C
764 #define RK3568_SMART1_REGION2_ACT_INFO		0x1E80
765 #define RK3568_SMART1_REGION2_DSP_INFO		0x1E84
766 #define RK3568_SMART1_REGION2_DSP_ST		0x1E88
767 #define RK3568_SMART1_REGION2_SCL_CTRL		0x1E90
768 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB	0x1E94
769 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR	0x1E98
770 #define RK3568_SMART1_REGION2_SCL_OFFSET	0x1E9C
771 #define RK3568_SMART1_REGION3_CTRL		0x1EA0
772 #define RK3568_SMART1_REGION3_YRGB_MST		0x1EA4
773 #define RK3568_SMART1_REGION3_CBR_MST		0x1EA8
774 #define RK3568_SMART1_REGION3_VIR		0x1EAC
775 #define RK3568_SMART1_REGION3_ACT_INFO		0x1EB0
776 #define RK3568_SMART1_REGION3_DSP_INFO		0x1EB4
777 #define RK3568_SMART1_REGION3_DSP_ST		0x1EB8
778 #define RK3568_SMART1_REGION3_SCL_CTRL		0x1EC0
779 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB	0x1EC4
780 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR	0x1EC8
781 #define RK3568_SMART1_REGION3_SCL_OFFSET	0x1ECC
782 
783 /* DSC 8K/4K register definition */
784 #define RK3588_DSC_8K_PPS0_3			0x4000
785 #define RK3588_DSC_8K_CTRL0			0x40A0
786 #define DSC_EN_SHIFT				0
787 #define DSC_RBIT_SHIFT				2
788 #define DSC_RBYT_SHIFT				3
789 #define DSC_FLAL_SHIFT				4
790 #define DSC_MER_SHIFT				5
791 #define DSC_EPB_SHIFT				6
792 #define DSC_EPL_SHIFT				7
793 #define DSC_NSLC_MASK				0x7
794 #define DSC_NSLC_SHIFT				16
795 #define DSC_SBO_SHIFT				28
796 #define DSC_IFEP_SHIFT				29
797 #define DSC_PPS_UPD_SHIFT			31
798 #define DSC_CTRL0_DEF_CON ((1 << DSC_EN_SHIFT)   | (1 << DSC_RBIT_SHIFT) | (0 << DSC_RBYT_SHIFT) | \
799 			   (1 << DSC_FLAL_SHIFT) | (1 << DSC_MER_SHIFT)  | (0 << DSC_EPB_SHIFT)  | \
800 			   (1 << DSC_EPL_SHIFT)  | (1 << DSC_SBO_SHIFT))
801 
802 #define RK3588_DSC_8K_CTRL1			0x40A4
803 #define RK3588_DSC_8K_STS0			0x40A8
804 #define RK3588_DSC_8K_ERS			0x40C4
805 
806 #define RK3588_DSC_4K_PPS0_3			0x4100
807 #define RK3588_DSC_4K_CTRL0			0x41A0
808 #define RK3588_DSC_4K_CTRL1			0x41A4
809 #define RK3588_DSC_4K_STS0			0x41A8
810 #define RK3588_DSC_4K_ERS			0x41C4
811 
812 /* RK3528 ACM register definition */
813 #define RK3528_ACM_CTRL				0x6400
814 #define RK3528_ACM_DELTA_RANGE			0x6404
815 #define RK3528_ACM_FETCH_START			0x6408
816 #define RK3528_ACM_FETCH_DONE			0x6420
817 #define RK3528_ACM_YHS_DEL_HY_SEG0		0x6500
818 #define RK3528_ACM_YHS_DEL_HY_SEG152		0x6760
819 #define RK3528_ACM_YHS_DEL_HS_SEG0		0x6764
820 #define RK3528_ACM_YHS_DEL_HS_SEG220		0x6ad4
821 #define RK3528_ACM_YHS_DEL_HGAIN_SEG0		0x6ad8
822 #define RK3528_ACM_YHS_DEL_HGAIN_SEG64		0x6bd8
823 
824 #define RK3568_MAX_REG				0x1ED0
825 
826 #define RK3568_GRF_VO_CON1			0x0364
827 #define GRF_BT656_CLK_INV_SHIFT			1
828 #define GRF_BT1120_CLK_INV_SHIFT		2
829 #define GRF_RGB_DCLK_INV_SHIFT			3
830 
831 #define RK3588_GRF_VOP_CON2			0x0008
832 #define RK3588_GRF_EDP0_ENABLE_SHIFT		0
833 #define RK3588_GRF_HDMITX0_ENABLE_SHIFT		1
834 #define RK3588_GRF_EDP1_ENABLE_SHIFT		3
835 #define RK3588_GRF_HDMITX1_ENABLE_SHIFT		4
836 
837 #define RK3588_GRF_VO1_CON0			0x0000
838 #define HDMI_SYNC_POL_MASK			0x3
839 #define HDMI0_SYNC_POL_SHIFT			5
840 #define HDMI1_SYNC_POL_SHIFT			7
841 
842 #define RK3588_PMU_BISR_CON3			0x20C
843 #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT	9
844 #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT	10
845 #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT	11
846 #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT	12
847 #define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT	13
848 #define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT	14
849 #define RK3588_PD_ESMART_REPAIR_EN_SHIFT	15
850 
851 #define RK3588_PMU_BISR_STATUS5			0x294
852 #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI	9
853 #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI	10
854 #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI	11
855 #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI	12
856 #define RK3588_PD_DSC_8K_PWR_STAT_SHIFI		13
857 #define RK3588_PD_DSC_4K_PWR_STAT_SHIFI		14
858 #define RK3588_PD_ESMART_PWR_STAT_SHIFI		15
859 
860 #define VOP2_LAYER_MAX				8
861 
862 #define VOP2_MAX_VP_OUTPUT_WIDTH		4096
863 
864 #define VOP_FEATURE_OUTPUT_10BIT		BIT(0)
865 
866 /* KHz */
867 #define VOP2_MAX_DCLK_RATE			600000
868 
869 /*
870  * vop2 dsc id
871  */
872 #define ROCKCHIP_VOP2_DSC_8K	0
873 #define ROCKCHIP_VOP2_DSC_4K	1
874 
875 /*
876  * vop2 internal power domain id,
877  * should be all none zero, 0 will be
878  * treat as invalid;
879  */
880 #define VOP2_PD_CLUSTER0			BIT(0)
881 #define VOP2_PD_CLUSTER1			BIT(1)
882 #define VOP2_PD_CLUSTER2			BIT(2)
883 #define VOP2_PD_CLUSTER3			BIT(3)
884 #define VOP2_PD_DSC_8K				BIT(5)
885 #define VOP2_PD_DSC_4K				BIT(6)
886 #define VOP2_PD_ESMART				BIT(7)
887 
888 #define VOP2_PLANE_NO_SCALING			BIT(16)
889 
890 #define VOP_FEATURE_OUTPUT_10BIT	BIT(0)
891 #define VOP_FEATURE_AFBDC		BIT(1)
892 #define VOP_FEATURE_ALPHA_SCALE		BIT(2)
893 #define VOP_FEATURE_HDR10		BIT(3)
894 #define VOP_FEATURE_NEXT_HDR		BIT(4)
895 /* a feature to splice two windows and two vps to support resolution > 4096 */
896 #define VOP_FEATURE_SPLICE		BIT(5)
897 #define VOP_FEATURE_OVERSCAN		BIT(6)
898 #define VOP_FEATURE_VIVID_HDR		BIT(7)
899 #define VOP_FEATURE_POST_ACM		BIT(8)
900 #define VOP_FEATURE_POST_CSC		BIT(9)
901 
902 #define WIN_FEATURE_HDR2SDR		BIT(0)
903 #define WIN_FEATURE_SDR2HDR		BIT(1)
904 #define WIN_FEATURE_PRE_OVERLAY		BIT(2)
905 #define WIN_FEATURE_AFBDC		BIT(3)
906 #define WIN_FEATURE_CLUSTER_MAIN	BIT(4)
907 #define WIN_FEATURE_CLUSTER_SUB		BIT(5)
908 /* a mirror win can only get fb address
909  * from source win:
910  * Cluster1---->Cluster0
911  * Esmart1 ---->Esmart0
912  * Smart1  ---->Smart0
913  * This is a feather on rk3566
914  */
915 #define WIN_FEATURE_MIRROR		BIT(6)
916 #define WIN_FEATURE_MULTI_AREA		BIT(7)
917 #define WIN_FEATURE_Y2R_13BIT_DEPTH	BIT(8)
918 
919 #define V4L2_COLORSPACE_BT709F		0xfe
920 #define V4L2_COLORSPACE_BT2020F		0xff
921 
922 enum vop_csc_format {
923 	CSC_BT601L,
924 	CSC_BT709L,
925 	CSC_BT601F,
926 	CSC_BT2020,
927 	CSC_BT709L_13BIT,
928 	CSC_BT709F_13BIT,
929 	CSC_BT2020L_13BIT,
930 	CSC_BT2020F_13BIT,
931 };
932 
933 enum vop_csc_bit_depth {
934 	CSC_10BIT_DEPTH,
935 	CSC_13BIT_DEPTH,
936 };
937 
938 enum vop2_pol {
939 	HSYNC_POSITIVE = 0,
940 	VSYNC_POSITIVE = 1,
941 	DEN_NEGATIVE   = 2,
942 	DCLK_INVERT    = 3
943 };
944 
945 enum vop2_bcsh_out_mode {
946 	BCSH_OUT_MODE_BLACK,
947 	BCSH_OUT_MODE_BLUE,
948 	BCSH_OUT_MODE_COLOR_BAR,
949 	BCSH_OUT_MODE_NORMAL_VIDEO,
950 };
951 
952 #define _VOP_REG(off, _mask, _shift, _write_mask) \
953 		{ \
954 		 .offset = off, \
955 		 .mask = _mask, \
956 		 .shift = _shift, \
957 		 .write_mask = _write_mask, \
958 		}
959 
960 #define VOP_REG(off, _mask, _shift) \
961 		_VOP_REG(off, _mask, _shift, false)
962 enum dither_down_mode {
963 	RGB888_TO_RGB565 = 0x0,
964 	RGB888_TO_RGB666 = 0x1
965 };
966 
967 enum vop2_video_ports_id {
968 	VOP2_VP0,
969 	VOP2_VP1,
970 	VOP2_VP2,
971 	VOP2_VP3,
972 	VOP2_VP_MAX,
973 };
974 
975 enum vop2_layer_type {
976 	CLUSTER_LAYER = 0,
977 	ESMART_LAYER = 1,
978 	SMART_LAYER = 2,
979 };
980 
981 /* This define must same with kernel win phy id */
982 enum vop2_layer_phy_id {
983 	ROCKCHIP_VOP2_CLUSTER0 = 0,
984 	ROCKCHIP_VOP2_CLUSTER1,
985 	ROCKCHIP_VOP2_ESMART0,
986 	ROCKCHIP_VOP2_ESMART1,
987 	ROCKCHIP_VOP2_SMART0,
988 	ROCKCHIP_VOP2_SMART1,
989 	ROCKCHIP_VOP2_CLUSTER2,
990 	ROCKCHIP_VOP2_CLUSTER3,
991 	ROCKCHIP_VOP2_ESMART2,
992 	ROCKCHIP_VOP2_ESMART3,
993 	ROCKCHIP_VOP2_LAYER_MAX,
994 };
995 
996 enum vop2_scale_up_mode {
997 	VOP2_SCALE_UP_NRST_NBOR,
998 	VOP2_SCALE_UP_BIL,
999 	VOP2_SCALE_UP_BIC,
1000 };
1001 
1002 enum vop2_scale_down_mode {
1003 	VOP2_SCALE_DOWN_NRST_NBOR,
1004 	VOP2_SCALE_DOWN_BIL,
1005 	VOP2_SCALE_DOWN_AVG,
1006 };
1007 
1008 enum scale_mode {
1009 	SCALE_NONE = 0x0,
1010 	SCALE_UP   = 0x1,
1011 	SCALE_DOWN = 0x2
1012 };
1013 
1014 enum vop_dsc_interface_mode {
1015 	VOP_DSC_IF_DISABLE = 0,
1016 	VOP_DSC_IF_HDMI = 1,
1017 	VOP_DSC_IF_MIPI_DS_MODE = 2,
1018 	VOP_DSC_IF_MIPI_VIDEO_MODE = 3,
1019 };
1020 
1021 enum vop3_pre_scale_down_mode {
1022 	VOP3_PRE_SCALE_UNSPPORT,
1023 	VOP3_PRE_SCALE_DOWN_GT,
1024 	VOP3_PRE_SCALE_DOWN_AVG,
1025 };
1026 
1027 enum vop3_esmart_lb_mode {
1028 	VOP3_ESMART_8K_MODE,
1029 	VOP3_ESMART_4K_4K_MODE,
1030 	VOP3_ESMART_4K_2K_2K_MODE,
1031 	VOP3_ESMART_2K_2K_2K_2K_MODE,
1032 };
1033 
1034 struct vop2_layer {
1035 	u8 id;
1036 	/**
1037 	 * @win_phys_id: window id of the layer selected.
1038 	 * Every layer must make sure to select different
1039 	 * windows of others.
1040 	 */
1041 	u8 win_phys_id;
1042 };
1043 
1044 struct vop2_power_domain_data {
1045 	u8 id;
1046 	u8 parent_id;
1047 	/*
1048 	 * @module_id_mask: module id of which module this power domain is belongs to.
1049 	 * PD_CLUSTER0,1,2,3 only belongs to CLUSTER0/1/2/3, PD_Esmart0 shared by Esmart1/2/3
1050 	 */
1051 	u32 module_id_mask;
1052 };
1053 
1054 struct vop2_win_data {
1055 	char *name;
1056 	u8 phys_id;
1057 	enum vop2_layer_type type;
1058 	u8 win_sel_port_offset;
1059 	u8 layer_sel_win_id[VOP2_VP_MAX];
1060 	u8 axi_id;
1061 	u8 axi_uv_id;
1062 	u8 axi_yrgb_id;
1063 	u8 splice_win_id;
1064 	u8 pd_id;
1065 	u8 hsu_filter_mode;
1066 	u8 hsd_filter_mode;
1067 	u8 vsu_filter_mode;
1068 	u8 vsd_filter_mode;
1069 	u8 hsd_pre_filter_mode;
1070 	u8 vsd_pre_filter_mode;
1071 	u8 scale_engine_num;
1072 	u32 reg_offset;
1073 	u32 max_upscale_factor;
1074 	u32 max_downscale_factor;
1075 	bool splice_mode_right;
1076 };
1077 
1078 struct vop2_vp_data {
1079 	u32 feature;
1080 	u8 pre_scan_max_dly;
1081 	u8 splice_vp_id;
1082 	struct vop_rect max_output;
1083 	u32 max_dclk;
1084 };
1085 
1086 struct vop2_plane_table {
1087 	enum vop2_layer_phy_id plane_id;
1088 	enum vop2_layer_type plane_type;
1089 };
1090 
1091 struct vop2_vp_plane_mask {
1092 	u8 primary_plane_id; /* use this win to show logo */
1093 	u8 attached_layers_nr; /* number layers attach to this vp */
1094 	u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */
1095 	u32 plane_mask;
1096 	int cursor_plane_id;
1097 };
1098 
1099 struct vop2_dsc_data {
1100 	u8 id;
1101 	u8 pd_id;
1102 	u8 max_slice_num;
1103 	u8 max_linebuf_depth;	/* used to generate the bitstream */
1104 	u8 min_bits_per_pixel;	/* bit num after encoder compress */
1105 	const char *dsc_txp_clk_src_name;
1106 	const char *dsc_txp_clk_name;
1107 	const char *dsc_pxl_clk_name;
1108 	const char *dsc_cds_clk_name;
1109 };
1110 
1111 struct dsc_error_info {
1112 	u32 dsc_error_val;
1113 	char dsc_error_info[50];
1114 };
1115 
1116 struct vop2_data {
1117 	u32 version;
1118 	u32 esmart_lb_mode;
1119 	struct vop2_vp_data *vp_data;
1120 	struct vop2_win_data *win_data;
1121 	struct vop2_vp_plane_mask *plane_mask;
1122 	struct vop2_plane_table *plane_table;
1123 	struct vop2_power_domain_data *pd;
1124 	struct vop2_dsc_data *dsc;
1125 	struct dsc_error_info *dsc_error_ecw;
1126 	struct dsc_error_info *dsc_error_buffer_flow;
1127 	u8 *vp_primary_plane_order;
1128 	u8 nr_vps;
1129 	u8 nr_layers;
1130 	u8 nr_mixers;
1131 	u8 nr_gammas;
1132 	u8 nr_pd;
1133 	u8 nr_dscs;
1134 	u8 nr_dsc_ecw;
1135 	u8 nr_dsc_buffer_flow;
1136 	u32 reg_len;
1137 };
1138 
1139 struct vop2 {
1140 	u32 *regsbak;
1141 	void *regs;
1142 	void *grf;
1143 	void *vop_grf;
1144 	void *vo1_grf;
1145 	void *sys_pmu;
1146 	u32 reg_len;
1147 	u32 version;
1148 	u32 esmart_lb_mode;
1149 	bool global_init;
1150 	const struct vop2_data *data;
1151 	struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX];
1152 };
1153 
1154 static struct vop2 *rockchip_vop2;
1155 
1156 static inline bool is_vop3(struct vop2 *vop2)
1157 {
1158 	if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588)
1159 		return false;
1160 	else
1161 		return true;
1162 }
1163 
1164 /*
1165  * bli_sd_factor = (src - 1) / (dst - 1) << 12;
1166  * avg_sd_factor:
1167  * bli_su_factor:
1168  * bic_su_factor:
1169  * = (src - 1) / (dst - 1) << 16;
1170  *
1171  * ygt2 enable: dst get one line from two line of the src
1172  * ygt4 enable: dst get one line from four line of the src.
1173  *
1174  */
1175 #define VOP2_BILI_SCL_DN(src, dst)	(((src - 1) << 12) / (dst - 1))
1176 #define VOP2_COMMON_SCL(src, dst)	(((src - 1) << 16) / (dst - 1))
1177 
1178 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)	 \
1179 				(fac * (dst - 1) >> 12 < (src - 1))
1180 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \
1181 				(fac * (dst - 1) >> 16 < (src - 1))
1182 #define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \
1183 				(fac * (dst - 1) >> 16 < (src - 1))
1184 
1185 static uint16_t vop2_scale_factor(enum scale_mode mode,
1186 				  int32_t filter_mode,
1187 				  uint32_t src, uint32_t dst)
1188 {
1189 	uint32_t fac = 0;
1190 	int i = 0;
1191 
1192 	if (mode == SCALE_NONE)
1193 		return 0;
1194 
1195 	/*
1196 	 * A workaround to avoid zero div.
1197 	 */
1198 	if ((dst == 1) || (src == 1)) {
1199 		dst = dst + 1;
1200 		src = src + 1;
1201 	}
1202 
1203 	if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) {
1204 		fac = VOP2_BILI_SCL_DN(src, dst);
1205 		for (i = 0; i < 100; i++) {
1206 			if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
1207 				break;
1208 			fac -= 1;
1209 			printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1210 		}
1211 	} else {
1212 		fac = VOP2_COMMON_SCL(src, dst);
1213 		for (i = 0; i < 100; i++) {
1214 			if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac))
1215 				break;
1216 			fac -= 1;
1217 			printf("up fac cali:  src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1218 		}
1219 	}
1220 
1221 	return fac;
1222 }
1223 
1224 static bool vop3_scale_up_fac_check(uint32_t src, uint32_t dst, uint32_t fac, bool is_hor)
1225 {
1226 	if (is_hor)
1227 		return VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac);
1228 	return VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac);
1229 }
1230 
1231 static uint16_t vop3_scale_factor(enum scale_mode mode,
1232 				  uint32_t src, uint32_t dst, bool is_hor)
1233 {
1234 	uint32_t fac = 0;
1235 	int i = 0;
1236 
1237 	if (mode == SCALE_NONE)
1238 		return 0;
1239 
1240 	/*
1241 	 * A workaround to avoid zero div.
1242 	 */
1243 	if ((dst == 1) || (src == 1)) {
1244 		dst = dst + 1;
1245 		src = src + 1;
1246 	}
1247 
1248 	if (mode == SCALE_DOWN) {
1249 		fac = VOP2_BILI_SCL_DN(src, dst);
1250 		for (i = 0; i < 100; i++) {
1251 			if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
1252 				break;
1253 			fac -= 1;
1254 			printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1255 		}
1256 	} else {
1257 		fac = VOP2_COMMON_SCL(src, dst);
1258 		for (i = 0; i < 100; i++) {
1259 			if (vop3_scale_up_fac_check(src, dst, fac, is_hor))
1260 				break;
1261 			fac -= 1;
1262 			printf("up fac cali:  src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1263 		}
1264 	}
1265 
1266 	return fac;
1267 }
1268 
1269 static inline enum scale_mode scl_get_scl_mode(int src, int dst)
1270 {
1271 	if (src < dst)
1272 		return SCALE_UP;
1273 	else if (src > dst)
1274 		return SCALE_DOWN;
1275 
1276 	return SCALE_NONE;
1277 }
1278 
1279 static inline int interpolate(int x1, int y1, int x2, int y2, int x)
1280 {
1281 	return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
1282 }
1283 
1284 static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask)
1285 {
1286 	int i = 0;
1287 
1288 	for (i = 0; i < vop2->data->nr_layers; i++) {
1289 		if (plane_mask & BIT(vop2->data->vp_primary_plane_order[i]))
1290 			return vop2->data->vp_primary_plane_order[i];
1291 	}
1292 
1293 	return vop2->data->vp_primary_plane_order[0];
1294 }
1295 
1296 static inline u16 scl_cal_scale(int src, int dst, int shift)
1297 {
1298 	return ((src * 2 - 3) << (shift - 1)) / (dst - 1);
1299 }
1300 
1301 static inline u16 scl_cal_scale2(int src, int dst)
1302 {
1303 	return ((src - 1) << 12) / (dst - 1);
1304 }
1305 
1306 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
1307 {
1308 	writel(v, vop2->regs + offset);
1309 	vop2->regsbak[offset >> 2] = v;
1310 }
1311 
1312 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
1313 {
1314 	return readl(vop2->regs + offset);
1315 }
1316 
1317 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset,
1318 				   u32 mask, u32 shift, u32 v,
1319 				   bool write_mask)
1320 {
1321 	if (!mask)
1322 		return;
1323 
1324 	if (write_mask) {
1325 		v = ((v & mask) << shift) | (mask << (shift + 16));
1326 	} else {
1327 		u32 cached_val = vop2->regsbak[offset >> 2];
1328 
1329 		v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
1330 		vop2->regsbak[offset >> 2] = v;
1331 	}
1332 
1333 	writel(v, vop2->regs + offset);
1334 }
1335 
1336 static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset,
1337 				   u32 mask, u32 shift, u32 v)
1338 {
1339 	u32 val = 0;
1340 
1341 	val = (v << shift) | (mask << (shift + 16));
1342 	writel(val, grf_base + offset);
1343 }
1344 
1345 static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset,
1346 				  u32 mask, u32 shift)
1347 {
1348 	return (readl(grf_base + offset) >> shift) & mask;
1349 }
1350 
1351 static char* get_output_if_name(u32 output_if, char *name)
1352 {
1353 	if (output_if & VOP_OUTPUT_IF_RGB)
1354 		strcat(name, " RGB");
1355 	if (output_if & VOP_OUTPUT_IF_BT1120)
1356 		strcat(name, " BT1120");
1357 	if (output_if & VOP_OUTPUT_IF_BT656)
1358 		strcat(name, " BT656");
1359 	if (output_if & VOP_OUTPUT_IF_LVDS0)
1360 		strcat(name, " LVDS0");
1361 	if (output_if & VOP_OUTPUT_IF_LVDS1)
1362 		strcat(name, " LVDS1");
1363 	if (output_if & VOP_OUTPUT_IF_MIPI0)
1364 		strcat(name, " MIPI0");
1365 	if (output_if & VOP_OUTPUT_IF_MIPI1)
1366 		strcat(name, " MIPI1");
1367 	if (output_if & VOP_OUTPUT_IF_eDP0)
1368 		strcat(name, " eDP0");
1369 	if (output_if & VOP_OUTPUT_IF_eDP1)
1370 		strcat(name, " eDP1");
1371 	if (output_if & VOP_OUTPUT_IF_DP0)
1372 		strcat(name, " DP0");
1373 	if (output_if & VOP_OUTPUT_IF_DP1)
1374 		strcat(name, " DP1");
1375 	if (output_if & VOP_OUTPUT_IF_HDMI0)
1376 		strcat(name, " HDMI0");
1377 	if (output_if & VOP_OUTPUT_IF_HDMI1)
1378 		strcat(name, " HDMI1");
1379 
1380 	return name;
1381 }
1382 
1383 static char *get_plane_name(int plane_id, char *name)
1384 {
1385 	switch (plane_id) {
1386 	case ROCKCHIP_VOP2_CLUSTER0:
1387 		strcat(name, "Cluster0");
1388 		break;
1389 	case ROCKCHIP_VOP2_CLUSTER1:
1390 		strcat(name, "Cluster1");
1391 		break;
1392 	case ROCKCHIP_VOP2_ESMART0:
1393 		strcat(name, "Esmart0");
1394 		break;
1395 	case ROCKCHIP_VOP2_ESMART1:
1396 		strcat(name, "Esmart1");
1397 		break;
1398 	case ROCKCHIP_VOP2_SMART0:
1399 		strcat(name, "Smart0");
1400 		break;
1401 	case ROCKCHIP_VOP2_SMART1:
1402 		strcat(name, "Smart1");
1403 		break;
1404 	case ROCKCHIP_VOP2_CLUSTER2:
1405 		strcat(name, "Cluster2");
1406 		break;
1407 	case ROCKCHIP_VOP2_CLUSTER3:
1408 		strcat(name, "Cluster3");
1409 		break;
1410 	case ROCKCHIP_VOP2_ESMART2:
1411 		strcat(name, "Esmart2");
1412 		break;
1413 	case ROCKCHIP_VOP2_ESMART3:
1414 		strcat(name, "Esmart3");
1415 		break;
1416 	}
1417 
1418 	return name;
1419 }
1420 
1421 static bool is_yuv_output(u32 bus_format)
1422 {
1423 	switch (bus_format) {
1424 	case MEDIA_BUS_FMT_YUV8_1X24:
1425 	case MEDIA_BUS_FMT_YUV10_1X30:
1426 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1427 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1428 	case MEDIA_BUS_FMT_YUYV8_2X8:
1429 	case MEDIA_BUS_FMT_YVYU8_2X8:
1430 	case MEDIA_BUS_FMT_UYVY8_2X8:
1431 	case MEDIA_BUS_FMT_VYUY8_2X8:
1432 	case MEDIA_BUS_FMT_YUYV8_1X16:
1433 	case MEDIA_BUS_FMT_YVYU8_1X16:
1434 	case MEDIA_BUS_FMT_UYVY8_1X16:
1435 	case MEDIA_BUS_FMT_VYUY8_1X16:
1436 		return true;
1437 	default:
1438 		return false;
1439 	}
1440 }
1441 
1442 static int vop2_convert_csc_mode(int csc_mode, int bit_depth)
1443 {
1444 	switch (csc_mode) {
1445 	case V4L2_COLORSPACE_SMPTE170M:
1446 	case V4L2_COLORSPACE_470_SYSTEM_M:
1447 	case V4L2_COLORSPACE_470_SYSTEM_BG:
1448 		return CSC_BT601L;
1449 	case V4L2_COLORSPACE_REC709:
1450 	case V4L2_COLORSPACE_SMPTE240M:
1451 	case V4L2_COLORSPACE_DEFAULT:
1452 		if (bit_depth == CSC_13BIT_DEPTH)
1453 			return CSC_BT709L_13BIT;
1454 		else
1455 			return CSC_BT709L;
1456 	case V4L2_COLORSPACE_JPEG:
1457 		return CSC_BT601F;
1458 	case V4L2_COLORSPACE_BT2020:
1459 		if (bit_depth == CSC_13BIT_DEPTH)
1460 			return CSC_BT2020L_13BIT;
1461 		else
1462 			return CSC_BT2020;
1463 	case V4L2_COLORSPACE_BT709F:
1464 		if (bit_depth == CSC_10BIT_DEPTH) {
1465 			printf("WARN: Unsupported bt709f at 10bit csc depth, use bt601f instead\n");
1466 			return CSC_BT601F;
1467 		} else {
1468 			return CSC_BT709F_13BIT;
1469 		}
1470 	case V4L2_COLORSPACE_BT2020F:
1471 		if (bit_depth == CSC_10BIT_DEPTH) {
1472 			printf("WARN: Unsupported bt2020f at 10bit csc depth, use bt601f instead\n");
1473 			return CSC_BT601F;
1474 		} else {
1475 			return CSC_BT2020F_13BIT;
1476 		}
1477 	default:
1478 		return CSC_BT709L;
1479 	}
1480 }
1481 
1482 static bool is_uv_swap(u32 bus_format, u32 output_mode)
1483 {
1484 	/*
1485 	 * FIXME:
1486 	 *
1487 	 * There is no media type for YUV444 output,
1488 	 * so when out_mode is AAAA or P888, assume output is YUV444 on
1489 	 * yuv format.
1490 	 *
1491 	 * From H/W testing, YUV444 mode need a rb swap.
1492 	 */
1493 	if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
1494 	    bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
1495 	    bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
1496 	    bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
1497 	    ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
1498 	     bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
1499 	    (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
1500 	     output_mode == ROCKCHIP_OUT_MODE_P888)))
1501 		return true;
1502 	else
1503 		return false;
1504 }
1505 
1506 static inline bool is_hot_plug_devices(int output_type)
1507 {
1508 	switch (output_type) {
1509 	case DRM_MODE_CONNECTOR_HDMIA:
1510 	case DRM_MODE_CONNECTOR_HDMIB:
1511 	case DRM_MODE_CONNECTOR_TV:
1512 	case DRM_MODE_CONNECTOR_DisplayPort:
1513 	case DRM_MODE_CONNECTOR_VGA:
1514 	case DRM_MODE_CONNECTOR_Unknown:
1515 		return true;
1516 	default:
1517 		return false;
1518 	}
1519 }
1520 
1521 static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id)
1522 {
1523 	int i = 0;
1524 
1525 	for (i = 0; i < vop2->data->nr_layers; i++) {
1526 		if (vop2->data->win_data[i].phys_id == phys_id)
1527 			return &vop2->data->win_data[i];
1528 	}
1529 
1530 	return NULL;
1531 }
1532 
1533 static struct vop2_power_domain_data *vop2_find_pd_data_by_id(struct vop2 *vop2, int pd_id)
1534 {
1535 	int i = 0;
1536 
1537 	for (i = 0; i < vop2->data->nr_pd; i++) {
1538 		if (vop2->data->pd[i].id == pd_id)
1539 			return &vop2->data->pd[i];
1540 	}
1541 
1542 	return NULL;
1543 }
1544 
1545 static void rk3568_vop2_load_lut(struct vop2 *vop2, int crtc_id,
1546 				 u32 *lut_regs, u32 *lut_val, int lut_len)
1547 {
1548 	u32 vp_offset = crtc_id * 0x100;
1549 	int i;
1550 
1551 	vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1552 			GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT,
1553 			crtc_id, false);
1554 
1555 	for (i = 0; i < lut_len; i++)
1556 		writel(lut_val[i], lut_regs + i);
1557 
1558 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1559 			EN_MASK, DSP_LUT_EN_SHIFT, 1, false);
1560 }
1561 
1562 static void rk3588_vop2_load_lut(struct vop2 *vop2, int crtc_id,
1563 				 u32 *lut_regs, u32 *lut_val, int lut_len)
1564 {
1565 	u32 vp_offset = crtc_id * 0x100;
1566 	int i;
1567 
1568 	vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1569 			GAMMA_AHB_WRITE_SEL_MASK, GAMMA_AHB_WRITE_SEL_SHIFT,
1570 			crtc_id, false);
1571 
1572 	for (i = 0; i < lut_len; i++)
1573 		writel(lut_val[i], lut_regs + i);
1574 
1575 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1576 			EN_MASK, DSP_LUT_EN_SHIFT, 1, false);
1577 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1578 			EN_MASK, GAMMA_UPDATE_EN_SHIFT, 1, false);
1579 }
1580 
1581 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2,
1582 					struct display_state *state)
1583 {
1584 	struct connector_state *conn_state = &state->conn_state;
1585 	struct crtc_state *cstate = &state->crtc_state;
1586 	struct resource gamma_res;
1587 	fdt_size_t lut_size;
1588 	int i, lut_len, ret = 0;
1589 	u32 *lut_regs;
1590 	u32 *lut_val;
1591 	u32 r, g, b;
1592 	struct base2_disp_info *disp_info = conn_state->disp_info;
1593 	static int gamma_lut_en_num = 1;
1594 
1595 	if (gamma_lut_en_num > vop2->data->nr_gammas) {
1596 		printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas);
1597 		return 0;
1598 	}
1599 
1600 	if (!disp_info)
1601 		return 0;
1602 
1603 	if (!disp_info->gamma_lut_data.size)
1604 		return 0;
1605 
1606 	ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res);
1607 	if (ret)
1608 		printf("failed to get gamma lut res\n");
1609 	lut_regs = (u32 *)gamma_res.start;
1610 	lut_size = gamma_res.end - gamma_res.start + 1;
1611 	if (lut_regs == (u32 *)FDT_ADDR_T_NONE) {
1612 		printf("failed to get gamma lut register\n");
1613 		return 0;
1614 	}
1615 	lut_len = lut_size / 4;
1616 	if (lut_len != 256 && lut_len != 1024) {
1617 		printf("Warning: unsupport gamma lut table[%d]\n", lut_len);
1618 		return 0;
1619 	}
1620 	lut_val = (u32 *)calloc(1, lut_size);
1621 	for (i = 0; i < lut_len; i++) {
1622 		r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff;
1623 		g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff;
1624 		b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff;
1625 
1626 		lut_val[i] = b * lut_len * lut_len + g * lut_len + r;
1627 	}
1628 
1629 	if (vop2->version == VOP_VERSION_RK3568) {
1630 		rk3568_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len);
1631 		gamma_lut_en_num++;
1632 	} else if (vop2->version == VOP_VERSION_RK3588) {
1633 		rk3588_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len);
1634 		if (cstate->splice_mode) {
1635 			rk3588_vop2_load_lut(vop2, cstate->splice_crtc_id, lut_regs, lut_val, lut_len);
1636 			gamma_lut_en_num++;
1637 		}
1638 		gamma_lut_en_num++;
1639 	}
1640 
1641 	return 0;
1642 }
1643 
1644 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2,
1645 					struct display_state *state)
1646 {
1647 	struct connector_state *conn_state = &state->conn_state;
1648 	struct crtc_state *cstate = &state->crtc_state;
1649 	int i, cubic_lut_len;
1650 	u32 vp_offset = cstate->crtc_id * 0x100;
1651 	struct base2_disp_info *disp_info = conn_state->disp_info;
1652 	struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data;
1653 	u32 *cubic_lut_addr;
1654 
1655 	if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0)
1656 		return 0;
1657 
1658 	if (!disp_info->cubic_lut_data.size)
1659 		return 0;
1660 
1661 	cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id);
1662 	cubic_lut_len = disp_info->cubic_lut_data.size;
1663 
1664 	for (i = 0; i < cubic_lut_len / 2; i++) {
1665 		*cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) +
1666 					((lut->lgreen[2 * i] & 0xfff) << 12) +
1667 					((lut->lblue[2 * i] & 0xff) << 24);
1668 		*cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) +
1669 					((lut->lred[2 * i + 1] & 0xfff) << 4) +
1670 					((lut->lgreen[2 * i + 1] & 0xfff) << 16) +
1671 					((lut->lblue[2 * i + 1] & 0xf) << 28);
1672 		*cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4;
1673 		*cubic_lut_addr++ = 0;
1674 	}
1675 
1676 	if (cubic_lut_len % 2) {
1677 		*cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) +
1678 					((lut->lgreen[2 * i] & 0xfff) << 12) +
1679 					((lut->lblue[2 * i] & 0xff) << 24);
1680 		*cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8;
1681 		*cubic_lut_addr++ = 0;
1682 		*cubic_lut_addr = 0;
1683 	}
1684 
1685 	vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset,
1686 		    get_cubic_lut_buffer(cstate->crtc_id));
1687 	vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL,
1688 			EN_MASK, LUT_DMA_EN_SHIFT, 1, false);
1689 	vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
1690 			EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false);
1691 	vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
1692 			EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false);
1693 
1694 	return 0;
1695 }
1696 
1697 static void vop2_bcsh_reg_update(struct display_state *state, struct vop2 *vop2,
1698 				 struct bcsh_state *bcsh_state, int crtc_id)
1699 {
1700 	struct crtc_state *cstate = &state->crtc_state;
1701 	u32 vp_offset = crtc_id * 0x100;
1702 
1703 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK,
1704 			BCSH_CTRL_R2Y_SHIFT, cstate->post_r2y_en, false);
1705 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK,
1706 			BCSH_CTRL_Y2R_SHIFT, cstate->post_y2r_en, false);
1707 
1708 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK,
1709 			BCSH_CTRL_R2Y_CSC_MODE_SHIFT, cstate->post_csc_mode, false);
1710 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK,
1711 			BCSH_CTRL_Y2R_CSC_MODE_SHIFT, cstate->post_csc_mode, false);
1712 
1713 	if (!cstate->bcsh_en) {
1714 		vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
1715 				BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false);
1716 		return;
1717 	}
1718 
1719 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1720 			BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT,
1721 			bcsh_state->brightness, false);
1722 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1723 			BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, bcsh_state->contrast, false);
1724 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1725 			BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT,
1726 			bcsh_state->saturation * bcsh_state->contrast / 0x100, false);
1727 	vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
1728 			BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, bcsh_state->sin_hue, false);
1729 	vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
1730 			BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, bcsh_state->cos_hue, false);
1731 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1732 			BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT,
1733 			BCSH_OUT_MODE_NORMAL_VIDEO, false);
1734 	vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
1735 			BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false);
1736 }
1737 
1738 static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2)
1739 {
1740 	struct connector_state *conn_state = &state->conn_state;
1741 	struct base_bcsh_info *bcsh_info;
1742 	struct crtc_state *cstate = &state->crtc_state;
1743 	struct bcsh_state bcsh_state;
1744 	int brightness, contrast, saturation, hue, sin_hue, cos_hue;
1745 
1746 	if (!conn_state->disp_info)
1747 		return;
1748 	bcsh_info = &conn_state->disp_info->bcsh_info;
1749 	if (!bcsh_info)
1750 		return;
1751 
1752 	if (bcsh_info->brightness != 50 ||
1753 	    bcsh_info->contrast != 50 ||
1754 	    bcsh_info->saturation != 50 || bcsh_info->hue != 50)
1755 		cstate->bcsh_en = true;
1756 
1757 	if (cstate->bcsh_en) {
1758 		if (!cstate->yuv_overlay)
1759 			cstate->post_r2y_en = 1;
1760 		if (!is_yuv_output(conn_state->bus_format))
1761 			cstate->post_y2r_en = 1;
1762 	} else {
1763 		if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format))
1764 			cstate->post_r2y_en = 1;
1765 		if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format))
1766 			cstate->post_y2r_en = 1;
1767 	}
1768 
1769 	cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH);
1770 
1771 	if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT)
1772 		brightness = interpolate(0, -128, 100, 127,
1773 					 bcsh_info->brightness);
1774 	else
1775 		brightness = interpolate(0, -32, 100, 31,
1776 					 bcsh_info->brightness);
1777 	contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast);
1778 	saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation);
1779 	hue = interpolate(0, -30, 100, 30, bcsh_info->hue);
1780 
1781 
1782 	/*
1783 	 *  a:[-30~0):
1784 	 *    sin_hue = 0x100 - sin(a)*256;
1785 	 *    cos_hue = cos(a)*256;
1786 	 *  a:[0~30]
1787 	 *    sin_hue = sin(a)*256;
1788 	 *    cos_hue = cos(a)*256;
1789 	 */
1790 	sin_hue = fixp_sin32(hue) >> 23;
1791 	cos_hue = fixp_cos32(hue) >> 23;
1792 
1793 	bcsh_state.brightness = brightness;
1794 	bcsh_state.contrast = contrast;
1795 	bcsh_state.saturation = saturation;
1796 	bcsh_state.sin_hue = sin_hue;
1797 	bcsh_state.cos_hue = cos_hue;
1798 
1799 	vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->crtc_id);
1800 	if (cstate->splice_mode)
1801 		vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->splice_crtc_id);
1802 }
1803 
1804 static void vop2_setup_dly_for_vp(struct display_state *state, struct vop2 *vop2, int crtc_id)
1805 {
1806 	struct connector_state *conn_state = &state->conn_state;
1807 	struct drm_display_mode *mode = &conn_state->mode;
1808 	struct crtc_state *cstate = &state->crtc_state;
1809 	u32 bg_ovl_dly, bg_dly, pre_scan_dly;
1810 	u16 hdisplay = mode->crtc_hdisplay;
1811 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
1812 
1813 	bg_ovl_dly = cstate->crtc->vps[crtc_id].bg_ovl_dly;
1814 	bg_dly = vop2->data->vp_data[crtc_id].pre_scan_max_dly;
1815 	bg_dly -= bg_ovl_dly;
1816 
1817 	if (cstate->splice_mode)
1818 		pre_scan_dly = bg_dly + (hdisplay >> 2) - 1;
1819 	else
1820 		pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
1821 
1822 	if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8)
1823 		hsync_len = 8;
1824 	pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
1825 	vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + crtc_id * 4,
1826 			BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false);
1827 	vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly);
1828 }
1829 
1830 static void vop2_post_config(struct display_state *state, struct vop2 *vop2)
1831 {
1832 	struct connector_state *conn_state = &state->conn_state;
1833 	struct drm_display_mode *mode = &conn_state->mode;
1834 	struct crtc_state *cstate = &state->crtc_state;
1835 	u32 vp_offset = (cstate->crtc_id * 0x100);
1836 	u16 vtotal = mode->crtc_vtotal;
1837 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1838 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1839 	u16 hdisplay = mode->crtc_hdisplay;
1840 	u16 vdisplay = mode->crtc_vdisplay;
1841 	u16 hsize =
1842 	    hdisplay * (conn_state->overscan.left_margin +
1843 			conn_state->overscan.right_margin) / 200;
1844 	u16 vsize =
1845 	    vdisplay * (conn_state->overscan.top_margin +
1846 			conn_state->overscan.bottom_margin) / 200;
1847 	u16 hact_end, vact_end;
1848 	u32 val;
1849 
1850 	hsize = round_down(hsize, 2);
1851 	vsize = round_down(vsize, 2);
1852 
1853 	hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200;
1854 	hact_end = hact_st + hsize;
1855 	val = hact_st << 16;
1856 	val |= hact_end;
1857 
1858 	vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val);
1859 	vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200;
1860 	vact_end = vact_st + vsize;
1861 	val = vact_st << 16;
1862 	val |= vact_end;
1863 	vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val);
1864 	val = scl_cal_scale2(vdisplay, vsize) << 16;
1865 	val |= scl_cal_scale2(hdisplay, hsize);
1866 	vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val);
1867 #define POST_HORIZONTAL_SCALEDOWN_EN(x)		((x) << 0)
1868 #define POST_VERTICAL_SCALEDOWN_EN(x)		((x) << 1)
1869 	vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset,
1870 		    POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) |
1871 		    POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize));
1872 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1873 		u16 vact_st_f1 = vtotal + vact_st + 1;
1874 		u16 vact_end_f1 = vact_st_f1 + vsize;
1875 
1876 		val = vact_st_f1 << 16 | vact_end_f1;
1877 		vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val);
1878 	}
1879 
1880 	vop2_setup_dly_for_vp(state, vop2, cstate->crtc_id);
1881 	if (cstate->splice_mode)
1882 		vop2_setup_dly_for_vp(state, vop2, cstate->splice_crtc_id);
1883 }
1884 
1885 static void vop3_post_acm_config(struct display_state *state, struct vop2 *vop2)
1886 {
1887 	struct connector_state *conn_state = &state->conn_state;
1888 	struct crtc_state *cstate = &state->crtc_state;
1889 	struct acm_data *acm = &conn_state->disp_info->acm_data;
1890 	struct drm_display_mode *mode = &conn_state->mode;
1891 	u32 vp_offset = (cstate->crtc_id * 0x100);
1892 	s16 *lut_y;
1893 	s16 *lut_h;
1894 	s16 *lut_s;
1895 	u32 value;
1896 	int i;
1897 
1898 	if (!acm->acm_enable) {
1899 		writel(0x2, vop2->regs + RK3528_ACM_CTRL);
1900 		vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
1901 				POST_ACM_BYPASS_EN_MASK, POST_ACM_BYPASS_EN_SHIFT, 1, false);
1902 		return;
1903 	}
1904 
1905 	printf("post acm enable\n");
1906 
1907 	writel(1, vop2->regs + RK3528_ACM_FETCH_START);
1908 
1909 	value = (acm->acm_enable & 0x1) + ((mode->hdisplay & 0xfff) << 8) +
1910 		((mode->vdisplay & 0xfff) << 20);
1911 	writel(value, vop2->regs + RK3528_ACM_CTRL);
1912 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
1913 			POST_ACM_BYPASS_EN_MASK, POST_ACM_BYPASS_EN_SHIFT, 0, false);
1914 
1915 	value = (acm->y_gain & 0x3ff) + ((acm->h_gain << 10) & 0xffc00) +
1916 		((acm->s_gain << 20) & 0x3ff00000);
1917 	writel(value, vop2->regs + RK3528_ACM_DELTA_RANGE);
1918 
1919 	lut_y = &acm->gain_lut_hy[0];
1920 	lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH];
1921 	lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2];
1922 	for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) {
1923 		value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
1924 			((lut_s[i] << 16) & 0xff0000);
1925 		writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2));
1926 	}
1927 
1928 	lut_y = &acm->gain_lut_hs[0];
1929 	lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH];
1930 	lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2];
1931 	for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) {
1932 		value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
1933 			((lut_s[i] << 16) & 0xff0000);
1934 		writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2));
1935 	}
1936 
1937 	lut_y = &acm->delta_lut_h[0];
1938 	lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH];
1939 	lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2];
1940 	for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) {
1941 		value = (lut_y[i] & 0x3ff) + ((lut_h[i] << 12) & 0xff000) +
1942 			((lut_s[i] << 20) & 0x3ff00000);
1943 		writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2));
1944 	}
1945 
1946 	writel(1, vop2->regs + RK3528_ACM_FETCH_DONE);
1947 }
1948 
1949 static void vop3_post_csc_config(struct display_state *state, struct vop2 *vop2)
1950 {
1951 	struct connector_state *conn_state = &state->conn_state;
1952 	struct crtc_state *cstate = &state->crtc_state;
1953 	struct acm_data *acm = &conn_state->disp_info->acm_data;
1954 	struct csc_info *csc = &conn_state->disp_info->csc_info;
1955 	struct post_csc_coef csc_coef;
1956 	bool is_input_yuv = false;
1957 	bool is_output_yuv = false;
1958 	bool post_r2y_en = false;
1959 	bool post_csc_en = false;
1960 	u32 vp_offset = (cstate->crtc_id * 0x100);
1961 	u32 value;
1962 	int range_type;
1963 
1964 	printf("post csc enable\n");
1965 
1966 	if (acm->acm_enable) {
1967 		if (!cstate->yuv_overlay)
1968 			post_r2y_en = true;
1969 
1970 		/* do y2r in csc module */
1971 		if (!is_yuv_output(conn_state->bus_format))
1972 			post_csc_en = true;
1973 	} else {
1974 		if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format))
1975 			post_r2y_en = true;
1976 
1977 		/* do y2r in csc module */
1978 		if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format))
1979 			post_csc_en = true;
1980 	}
1981 
1982 	if (csc->csc_enable)
1983 		post_csc_en = true;
1984 
1985 	if (cstate->yuv_overlay || post_r2y_en)
1986 		is_input_yuv = true;
1987 
1988 	if (is_yuv_output(conn_state->bus_format))
1989 		is_output_yuv = true;
1990 
1991 	cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_13BIT_DEPTH);
1992 
1993 	if (post_csc_en) {
1994 		rockchip_calc_post_csc(csc, &csc_coef, cstate->post_csc_mode, is_input_yuv,
1995 				       is_output_yuv);
1996 
1997 		vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
1998 				POST_CSC_COE00_MASK, POST_CSC_COE00_SHIFT,
1999 				csc_coef.csc_coef00, false);
2000 		value = (csc_coef.csc_coef02 << 16) | csc_coef.csc_coef01;
2001 		writel(value, vop2->regs + RK3528_VP0_CSC_COE01_02);
2002 		value = (csc_coef.csc_coef11 << 16) | csc_coef.csc_coef10;
2003 		writel(value, vop2->regs + RK3528_VP0_CSC_COE10_11);
2004 		value = (csc_coef.csc_coef20 << 16) | csc_coef.csc_coef12;
2005 		writel(value, vop2->regs + RK3528_VP0_CSC_COE12_20);
2006 		value = (csc_coef.csc_coef22 << 16) | csc_coef.csc_coef21;
2007 		writel(value, vop2->regs + RK3528_VP0_CSC_COE21_22);
2008 		writel(csc_coef.csc_dc0, vop2->regs + RK3528_VP0_CSC_OFFSET0);
2009 		writel(csc_coef.csc_dc1, vop2->regs + RK3528_VP0_CSC_OFFSET1);
2010 		writel(csc_coef.csc_dc2, vop2->regs + RK3528_VP0_CSC_OFFSET2);
2011 
2012 		range_type = csc_coef.range_type ? 0 : 1;
2013 		range_type <<= is_input_yuv ? 0 : 1;
2014 		vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2015 				POST_CSC_MODE_MASK, POST_CSC_MODE_SHIFT, range_type, false);
2016 	}
2017 
2018 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2019 			POST_R2Y_MODE_MASK, POST_R2Y_MODE_SHIFT, post_r2y_en ? 1 : 0, false);
2020 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2021 			POST_CSC_EN_MASK, POST_CSC_EN_SHIFT, post_csc_en ? 1 : 0, false);
2022 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2023 			POST_R2Y_MODE_MASK, POST_R2Y_MODE_SHIFT, cstate->post_csc_mode, false);
2024 }
2025 
2026 static void vop3_post_config(struct display_state *state, struct vop2 *vop2)
2027 {
2028 	struct connector_state *conn_state = &state->conn_state;
2029 	struct base2_disp_info *disp_info = conn_state->disp_info;
2030 	const char *enable_flag;
2031 
2032 	if (!disp_info) {
2033 		printf("disp_info is empty\n");
2034 		return;
2035 	}
2036 
2037 	enable_flag = (const char *)&disp_info->cacm_header;
2038 	if (strncasecmp(enable_flag, "CACM", 4)) {
2039 		printf("acm and csc is not support\n");
2040 		return;
2041 	}
2042 
2043 	vop3_post_acm_config(state, vop2);
2044 	vop3_post_csc_config(state, vop2);
2045 }
2046 
2047 /*
2048  * Read VOP internal power domain on/off status.
2049  * We should query BISR_STS register in PMU for
2050  * power up/down status when memory repair is enabled.
2051  * Return value: 1 for power on, 0 for power off;
2052  */
2053 static int vop2_wait_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data)
2054 {
2055 	int val = 0;
2056 	int shift = 0;
2057 	int shift_factor = 0;
2058 	bool is_bisr_en = false;
2059 
2060 	/*
2061 	 * The order of pd status bits in BISR_STS register
2062 	 * is different from that in VOP SYS_STS register.
2063 	 */
2064 	if (pd_data->id == VOP2_PD_DSC_8K ||
2065 	    pd_data->id == VOP2_PD_DSC_4K ||
2066 	    pd_data->id == VOP2_PD_ESMART)
2067 			shift_factor = 1;
2068 
2069 	shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT + generic_ffs(pd_data->id) - 1 - shift_factor;
2070 	is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, shift);
2071 	if (is_bisr_en) {
2072 		shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI + generic_ffs(pd_data->id) - 1 - shift_factor;
2073 
2074 		return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val,
2075 					  ((val >> shift) & 0x1), 50 * 1000);
2076 	} else {
2077 		shift = RK3588_CLUSTER0_PD_STATUS_SHIFT + generic_ffs(pd_data->id) - 1;
2078 
2079 		return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val,
2080 					  !((val >> shift) & 0x1), 50 * 1000);
2081 	}
2082 }
2083 
2084 static int vop2_power_domain_on(struct vop2 *vop2, int pd_id)
2085 {
2086 	struct vop2_power_domain_data *pd_data;
2087 	int ret = 0;
2088 
2089 	if (!pd_id)
2090 		return 0;
2091 
2092 	pd_data = vop2_find_pd_data_by_id(vop2, pd_id);
2093 	if (!pd_data) {
2094 		printf("can't find pd_data by id\n");
2095 		return -EINVAL;
2096 	}
2097 
2098 	if (pd_data->parent_id) {
2099 		ret = vop2_power_domain_on(vop2, pd_data->parent_id);
2100 		if (ret) {
2101 			printf("can't open parent power domain\n");
2102 			return -EINVAL;
2103 		}
2104 	}
2105 
2106 	vop2_mask_write(vop2, RK3568_SYS_PD_CTRL, EN_MASK,
2107 			RK3588_CLUSTER0_PD_EN_SHIFT + generic_ffs(pd_id) - 1, 0, false);
2108 	ret = vop2_wait_power_domain_on(vop2, pd_data);
2109 	if (ret) {
2110 		printf("wait vop2 power domain timeout\n");
2111 		return ret;
2112 	}
2113 
2114 	return 0;
2115 }
2116 
2117 static void rk3588_vop2_regsbak(struct vop2 *vop2)
2118 {
2119 	u32 *base = vop2->regs;
2120 	int i = 0;
2121 
2122 	/*
2123 	 * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU
2124 	 */
2125 	for (i = 0; i < (vop2->reg_len >> 2); i++)
2126 		vop2->regsbak[i] = base[i];
2127 }
2128 
2129 static void vop3_overlay_init(struct vop2 *vop2, struct display_state *state)
2130 {
2131 	struct vop2_win_data *win_data;
2132 	int layer_phy_id = 0;
2133 	int i, j;
2134 	u32 ovl_port_offset = 0;
2135 	u32 layer_nr = 0;
2136 	u8 shift = 0;
2137 
2138 	/* layer sel win id */
2139 	for (i = 0; i < vop2->data->nr_vps; i++) {
2140 		shift = 0;
2141 		ovl_port_offset = 0x100 * i;
2142 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2143 		for (j = 0; j < layer_nr; j++) {
2144 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2145 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2146 			vop2_mask_write(vop2, RK3528_OVL_PORT0_LAYER_SEL + ovl_port_offset, LAYER_SEL_MASK,
2147 					shift, win_data->layer_sel_win_id[i], false);
2148 			shift += 4;
2149 		}
2150 	}
2151 
2152 	/* win sel port */
2153 	for (i = 0; i < vop2->data->nr_vps; i++) {
2154 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2155 		for (j = 0; j < layer_nr; j++) {
2156 			if (!vop2->vp_plane_mask[i].attached_layers[j])
2157 				continue;
2158 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2159 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2160 			shift = win_data->win_sel_port_offset * 2;
2161 			vop2_mask_write(vop2, RK3528_OVL_SYS_PORT_SEL_IMD, LAYER_SEL_PORT_MASK,
2162 					shift, i, false);
2163 		}
2164 	}
2165 }
2166 
2167 static void vop2_overlay_init(struct vop2 *vop2, struct display_state *state)
2168 {
2169 	struct crtc_state *cstate = &state->crtc_state;
2170 	struct vop2_win_data *win_data;
2171 	int layer_phy_id = 0;
2172 	int total_used_layer = 0;
2173 	int port_mux = 0;
2174 	int i, j;
2175 	u32 layer_nr = 0;
2176 	u8 shift = 0;
2177 
2178 	/* layer sel win id */
2179 	for (i = 0; i < vop2->data->nr_vps; i++) {
2180 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2181 		for (j = 0; j < layer_nr; j++) {
2182 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2183 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2184 			vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK,
2185 					shift, win_data->layer_sel_win_id[i], false);
2186 			shift += 4;
2187 		}
2188 	}
2189 
2190 	/* win sel port */
2191 	for (i = 0; i < vop2->data->nr_vps; i++) {
2192 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2193 		for (j = 0; j < layer_nr; j++) {
2194 			if (!vop2->vp_plane_mask[i].attached_layers[j])
2195 				continue;
2196 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2197 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2198 			shift = win_data->win_sel_port_offset * 2;
2199 			vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK,
2200 					LAYER_SEL_PORT_SHIFT + shift, i, false);
2201 		}
2202 	}
2203 
2204 	/**
2205 	 * port mux config
2206 	 */
2207 	for (i = 0; i < vop2->data->nr_vps; i++) {
2208 		shift = i * 4;
2209 		if (vop2->vp_plane_mask[i].attached_layers_nr) {
2210 			total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr;
2211 			port_mux = total_used_layer - 1;
2212 		} else {
2213 			port_mux = 8;
2214 		}
2215 
2216 		if (i == vop2->data->nr_vps - 1)
2217 			port_mux = vop2->data->nr_mixers;
2218 
2219 		cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1;
2220 		vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK,
2221 				PORT_MUX_SHIFT + shift, port_mux, false);
2222 	}
2223 }
2224 
2225 static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win_data *win)
2226 {
2227 	if (!is_vop3(vop2))
2228 		return false;
2229 
2230 	if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE &&
2231 	    win->phys_id != ROCKCHIP_VOP2_ESMART0)
2232 		return true;
2233 	else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE &&
2234 		 (win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3))
2235 		return true;
2236 	else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE &&
2237 		 win->phys_id == ROCKCHIP_VOP2_ESMART1)
2238 		return true;
2239 	else
2240 		return false;
2241 }
2242 
2243 static void vop3_init_esmart_scale_engine(struct vop2 *vop2)
2244 {
2245 	struct vop2_win_data *win_data;
2246 	int layer_phy_id = 0;
2247 	int i, j;
2248 	u8 scale_engine_num = 0;
2249 	u32 layer_nr = 0;
2250 
2251 	/* store plane mask for vop2_fixup_dts */
2252 	for (i = 0; i < vop2->data->nr_vps; i++) {
2253 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2254 		for (j = 0; j < layer_nr; j++) {
2255 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2256 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2257 			if (win_data->type == CLUSTER_LAYER || vop3_ignore_plane(vop2, win_data))
2258 				continue;
2259 
2260 			win_data->scale_engine_num = scale_engine_num++;
2261 		}
2262 	}
2263 }
2264 
2265 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state)
2266 {
2267 	struct crtc_state *cstate = &state->crtc_state;
2268 	struct vop2_vp_plane_mask *plane_mask;
2269 	int layer_phy_id = 0;
2270 	int i, j;
2271 	u32 layer_nr = 0;
2272 
2273 	if (vop2->global_init)
2274 		return;
2275 
2276 	/* OTP must enable at the first time, otherwise mirror layer register is error */
2277 	if (soc_is_rk3566())
2278 		vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK,
2279 				OTP_WIN_EN_SHIFT, 1, false);
2280 
2281 	if (cstate->crtc->assign_plane) {/* dts assign plane */
2282 		u32 plane_mask;
2283 		int primary_plane_id;
2284 
2285 		for (i = 0; i < vop2->data->nr_vps; i++) {
2286 			plane_mask = cstate->crtc->vps[i].plane_mask;
2287 			vop2->vp_plane_mask[i].plane_mask = plane_mask;
2288 			layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */
2289 			vop2->vp_plane_mask[i].attached_layers_nr = layer_nr;
2290 			primary_plane_id = cstate->crtc->vps[i].primary_plane_id;
2291 			if (primary_plane_id >= ROCKCHIP_VOP2_LAYER_MAX)
2292 				primary_plane_id = vop2_get_primary_plane(vop2, plane_mask);
2293 			vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id;
2294 			vop2->vp_plane_mask[i].plane_mask = plane_mask;
2295 
2296 			/* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/
2297 			for (j = 0; j < layer_nr; j++) {
2298 				vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1;
2299 				plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]);
2300 			}
2301 		}
2302 	} else {/* need soft assign plane mask */
2303 		/* find the first unplug devices and set it as main display */
2304 		int main_vp_index = -1;
2305 		int active_vp_num = 0;
2306 
2307 		for (i = 0; i < vop2->data->nr_vps; i++) {
2308 			if (cstate->crtc->vps[i].enable)
2309 				active_vp_num++;
2310 		}
2311 		printf("VOP have %d active VP\n", active_vp_num);
2312 
2313 		if (soc_is_rk3566() && active_vp_num > 2)
2314 			printf("ERROR: rk3566 only support 2 display output!!\n");
2315 		plane_mask = vop2->data->plane_mask;
2316 		plane_mask += (active_vp_num - 1) * VOP2_VP_MAX;
2317 		/*
2318 		 * For rk3528, one display policy for hdmi store in plane_mask[0], and the other
2319 		 * for cvbs store in plane_mask[2].
2320 		 */
2321 		if (vop2->version == VOP_VERSION_RK3528 && active_vp_num == 1 &&
2322 		    cstate->crtc->vps[1].output_type == DRM_MODE_CONNECTOR_TV)
2323 			plane_mask += 2 * VOP2_VP_MAX;
2324 
2325 		if (vop2->version == VOP_VERSION_RK3528) {
2326 			/*
2327 			 * For rk3528, the plane mask of vp is limited, only esmart2 can be selected
2328 			 * by both vp0 and vp1.
2329 			 */
2330 			j = 0;
2331 		} else {
2332 			for (i = 0; i < vop2->data->nr_vps; i++) {
2333 				if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) {
2334 					vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/
2335 					main_vp_index = i;
2336 					break;
2337 				}
2338 			}
2339 
2340 			/* if no find unplug devices, use vp0 as main display */
2341 			if (main_vp_index < 0) {
2342 				main_vp_index = 0;
2343 				vop2->vp_plane_mask[0] = plane_mask[0];
2344 			}
2345 
2346 			j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */
2347 		}
2348 
2349 		/* init other display except main display */
2350 		for (i = 0; i < vop2->data->nr_vps; i++) {
2351 			if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */
2352 				continue;
2353 			vop2->vp_plane_mask[i] = plane_mask[j++];
2354 		}
2355 
2356 		/* store plane mask for vop2_fixup_dts */
2357 		for (i = 0; i < vop2->data->nr_vps; i++) {
2358 			layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2359 			for (j = 0; j < layer_nr; j++) {
2360 				layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2361 				vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id);
2362 			}
2363 		}
2364 	}
2365 
2366 	if (vop2->version == VOP_VERSION_RK3588)
2367 		rk3588_vop2_regsbak(vop2);
2368 	else
2369 		memcpy(vop2->regsbak, vop2->regs, vop2->reg_len);
2370 
2371 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK,
2372 			OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false);
2373 	vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2374 			IF_CTRL_REG_DONE_IMD_SHIFT, 1, false);
2375 
2376 	for (i = 0; i < vop2->data->nr_vps; i++) {
2377 		printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr);
2378 		for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++)
2379 			printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]);
2380 		printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id);
2381 	}
2382 
2383 	if (is_vop3(vop2))
2384 		vop3_overlay_init(vop2, state);
2385 	else
2386 		vop2_overlay_init(vop2, state);
2387 
2388 	if (is_vop3(vop2)) {
2389 		/*
2390 		 * you can rewrite at dts vop node:
2391 		 *
2392 		 * VOP3_ESMART_8K_MODE = 0,
2393 		 * VOP3_ESMART_4K_4K_MODE = 1,
2394 		 * VOP3_ESMART_4K_2K_2K_MODE = 2,
2395 		 * VOP3_ESMART_2K_2K_2K_2K_MODE = 3,
2396 		 *
2397 		 * &vop {
2398 		 * 	esmart_lb_mode = /bits/ 8 <2>;
2399 		 * };
2400 		 */
2401 		vop2->esmart_lb_mode = ofnode_read_u32_default(cstate->node, "esmart_lb_mode", -1);
2402 		if (vop2->esmart_lb_mode < 0)
2403 			vop2->esmart_lb_mode = vop2->data->esmart_lb_mode;
2404 		vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, ESMART_LB_MODE_SEL_MASK,
2405 				ESMART_LB_MODE_SEL_SHIFT, vop2->esmart_lb_mode, false);
2406 
2407 		vop3_init_esmart_scale_engine(vop2);
2408 
2409 		vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, EN_MASK,
2410 				DSP_VS_T_SEL_SHIFT, 0, false);
2411 	}
2412 
2413 	if (vop2->version == VOP_VERSION_RK3568)
2414 		vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0);
2415 
2416 	vop2->global_init = true;
2417 }
2418 
2419 static int vop2_initial(struct vop2 *vop2, struct display_state *state)
2420 {
2421 	struct crtc_state *cstate = &state->crtc_state;
2422 	int ret;
2423 
2424 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2425 	ret = clk_set_defaults(cstate->dev);
2426 	if (ret)
2427 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2428 
2429 	rockchip_vop2_gamma_lut_init(vop2, state);
2430 	rockchip_vop2_cubic_lut_init(vop2, state);
2431 
2432 	return 0;
2433 }
2434 
2435 /*
2436  * VOP2 have multi video ports.
2437  * video port ------- crtc
2438  */
2439 static int rockchip_vop2_preinit(struct display_state *state)
2440 {
2441 	struct crtc_state *cstate = &state->crtc_state;
2442 	const struct vop2_data *vop2_data = cstate->crtc->data;
2443 
2444 	if (!rockchip_vop2) {
2445 		rockchip_vop2 = calloc(1, sizeof(struct vop2));
2446 		if (!rockchip_vop2)
2447 			return -ENOMEM;
2448 		rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev);
2449 		rockchip_vop2->regsbak = malloc(RK3568_MAX_REG);
2450 		rockchip_vop2->reg_len = RK3568_MAX_REG;
2451 		rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2452 		if (rockchip_vop2->grf <= 0)
2453 			printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf);
2454 		rockchip_vop2->version = vop2_data->version;
2455 		rockchip_vop2->data = vop2_data;
2456 		if (rockchip_vop2->version == VOP_VERSION_RK3588) {
2457 			struct regmap *map;
2458 
2459 			rockchip_vop2->vop_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VOP_GRF);
2460 			if (rockchip_vop2->vop_grf <= 0)
2461 				printf("%s: Get syscon vop_grf failed (ret=%p)\n", __func__, rockchip_vop2->vop_grf);
2462 			map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf");
2463 			rockchip_vop2->vo1_grf = regmap_get_range(map, 0);
2464 			if (rockchip_vop2->vo1_grf <= 0)
2465 				printf("%s: Get syscon vo1_grf failed (ret=%p)\n", __func__, rockchip_vop2->vo1_grf);
2466 			rockchip_vop2->sys_pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
2467 			if (rockchip_vop2->sys_pmu <= 0)
2468 				printf("%s: Get syscon sys_pmu failed (ret=%p)\n", __func__, rockchip_vop2->sys_pmu);
2469 		}
2470 	}
2471 
2472 	cstate->private = rockchip_vop2;
2473 	cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output;
2474 	cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature;
2475 
2476 	vop2_global_initial(rockchip_vop2, state);
2477 
2478 	return 0;
2479 }
2480 
2481 /*
2482  * calc the dclk on rk3588
2483  * the available div of dclk is 1, 2, 4
2484  *
2485  */
2486 static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
2487 {
2488 	if (child_clk * 4 <= max_dclk)
2489 		return child_clk * 4;
2490 	else if (child_clk * 2 <= max_dclk)
2491 		return child_clk * 2;
2492 	else if (child_clk <= max_dclk)
2493 		return child_clk;
2494 	else
2495 		return 0;
2496 }
2497 
2498 /*
2499  * 4 pixclk/cycle on rk3588
2500  * RGB/eDP/HDMI: if_pixclk >= dclk_core
2501  * DP: dp_pixclk = dclk_out <= dclk_core
2502  * DSI: mipi_pixclk <= dclk_out <= dclk_core
2503  */
2504 static unsigned long vop2_calc_cru_cfg(struct display_state *state,
2505 				       int *dclk_core_div, int *dclk_out_div,
2506 				       int *if_pixclk_div, int *if_dclk_div)
2507 {
2508 	struct crtc_state *cstate = &state->crtc_state;
2509 	struct connector_state *conn_state = &state->conn_state;
2510 	struct drm_display_mode *mode = &conn_state->mode;
2511 	struct vop2 *vop2 = cstate->private;
2512 	unsigned long v_pixclk = mode->crtc_clock;
2513 	unsigned long dclk_core_rate = v_pixclk >> 2;
2514 	unsigned long dclk_rate = v_pixclk;
2515 	unsigned long dclk_out_rate;
2516 	u64 if_dclk_rate;
2517 	u64 if_pixclk_rate;
2518 	int output_type = conn_state->type;
2519 	int output_mode = conn_state->output_mode;
2520 	int K = 1;
2521 
2522 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE &&
2523 	    output_mode == ROCKCHIP_OUT_MODE_YUV420) {
2524 		printf("Dual channel and YUV420 can't work together\n");
2525 		return -EINVAL;
2526 	}
2527 
2528 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE ||
2529 	    output_mode == ROCKCHIP_OUT_MODE_YUV420)
2530 		K = 2;
2531 
2532 	if (output_type == DRM_MODE_CONNECTOR_HDMIA) {
2533 		/*
2534 		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
2535 		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
2536 		 */
2537 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE ||
2538 		    output_mode == ROCKCHIP_OUT_MODE_YUV420) {
2539 			dclk_rate = dclk_rate >> 1;
2540 			K = 2;
2541 		}
2542 		if (cstate->dsc_enable) {
2543 			if_pixclk_rate = cstate->dsc_cds_clk_rate << 1;
2544 			if_dclk_rate = cstate->dsc_cds_clk_rate;
2545 		} else {
2546 			if_pixclk_rate = (dclk_core_rate << 1) / K;
2547 			if_dclk_rate = dclk_core_rate / K;
2548 		}
2549 
2550 		if (v_pixclk > VOP2_MAX_DCLK_RATE)
2551 			dclk_rate = vop2_calc_dclk(dclk_core_rate, vop2->data->vp_data->max_dclk);
2552 
2553 		if (!dclk_rate) {
2554 			printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n",
2555 			       vop2->data->vp_data->max_dclk, if_pixclk_rate);
2556 			return -EINVAL;
2557 		}
2558 		*if_pixclk_div = dclk_rate / if_pixclk_rate;
2559 		*if_dclk_div = dclk_rate / if_dclk_rate;
2560 		*dclk_core_div = dclk_rate / dclk_core_rate;
2561 		printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n",
2562 		       dclk_rate, *if_pixclk_div, *if_dclk_div);
2563 	} else if (output_type == DRM_MODE_CONNECTOR_eDP) {
2564 		/* edp_pixclk = edp_dclk > dclk_core */
2565 		if_pixclk_rate = v_pixclk / K;
2566 		if_dclk_rate = v_pixclk / K;
2567 		dclk_rate = if_pixclk_rate * K;
2568 		*dclk_core_div = dclk_rate / dclk_core_rate;
2569 		*if_pixclk_div = dclk_rate / if_pixclk_rate;
2570 		*if_dclk_div = *if_pixclk_div;
2571 	} else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) {
2572 		dclk_out_rate = v_pixclk >> 2;
2573 		dclk_out_rate = dclk_out_rate / K;
2574 
2575 		dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk);
2576 		if (!dclk_rate) {
2577 			printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n",
2578 			       vop2->data->vp_data->max_dclk, dclk_core_rate);
2579 			return -EINVAL;
2580 		}
2581 		*dclk_out_div = dclk_rate / dclk_out_rate;
2582 		*dclk_core_div = dclk_rate / dclk_core_rate;
2583 	} else if (output_type == DRM_MODE_CONNECTOR_DSI) {
2584 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2585 			K = 2;
2586 		if (cstate->dsc_enable)
2587 			/* dsc output is 96bit, dsi input is 192 bit */
2588 			if_pixclk_rate = cstate->dsc_cds_clk_rate >> 1;
2589 		else
2590 			if_pixclk_rate = dclk_core_rate / K;
2591 		/* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */
2592 		dclk_out_rate = dclk_core_rate / K;
2593 		/* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */
2594 		dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk);
2595 		if (!dclk_rate) {
2596 			printf("MIPI dclk out of range(max_dclk: %d KHZ, dclk_rate: %ld KHZ)\n",
2597 			       vop2->data->vp_data->max_dclk, dclk_rate);
2598 			return -EINVAL;
2599 		}
2600 
2601 		if (cstate->dsc_enable)
2602 			dclk_rate = dclk_rate >> 1;
2603 
2604 		*dclk_out_div = dclk_rate / dclk_out_rate;
2605 		*dclk_core_div = dclk_rate / dclk_core_rate;
2606 		*if_pixclk_div = 1;       /*mipi pixclk == dclk_out*/
2607 		if (cstate->dsc_enable)
2608 			*if_pixclk_div = dclk_out_rate * 1000LL / if_pixclk_rate;
2609 
2610 	} else if (output_type == DRM_MODE_CONNECTOR_DPI) {
2611 		dclk_rate = v_pixclk;
2612 		*dclk_core_div = dclk_rate / dclk_core_rate;
2613 	}
2614 
2615 	*if_pixclk_div = ilog2(*if_pixclk_div);
2616 	*if_dclk_div = ilog2(*if_dclk_div);
2617 	*dclk_core_div = ilog2(*dclk_core_div);
2618 	*dclk_out_div = ilog2(*dclk_out_div);
2619 
2620 	return dclk_rate;
2621 }
2622 
2623 static int vop2_calc_dsc_clk(struct display_state *state)
2624 {
2625 	struct connector_state *conn_state = &state->conn_state;
2626 	struct drm_display_mode *mode = &conn_state->mode;
2627 	struct crtc_state *cstate = &state->crtc_state;
2628 	u64 v_pixclk = mode->crtc_clock * 1000LL; /* video timing pixclk */
2629 	u8 k = 1;
2630 
2631 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2632 		k = 2;
2633 
2634 	cstate->dsc_txp_clk_rate = v_pixclk;
2635 	do_div(cstate->dsc_txp_clk_rate, (cstate->dsc_pixel_num * k));
2636 
2637 	cstate->dsc_pxl_clk_rate = v_pixclk;
2638 	do_div(cstate->dsc_pxl_clk_rate, (cstate->dsc_slice_num * k));
2639 
2640 	/* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel)
2641 	 * cds_dat_width = 96;
2642 	 * bits_per_pixel = [8-12];
2643 	 * As cds clk is div from txp clk and only support 1/2/4 div,
2644 	 * so when txp_clk is equal to v_pixclk, we set dsc_cds = crtc_clock / 4,
2645 	 * otherwise dsc_cds = crtc_clock / 8;
2646 	 */
2647 	cstate->dsc_cds_clk_rate = v_pixclk / (cstate->dsc_txp_clk_rate == v_pixclk ? 4 : 8);
2648 
2649 	return 0;
2650 }
2651 
2652 static unsigned long rk3588_vop2_if_cfg(struct display_state *state)
2653 {
2654 	struct crtc_state *cstate = &state->crtc_state;
2655 	struct connector_state *conn_state = &state->conn_state;
2656 	struct drm_display_mode *mode = &conn_state->mode;
2657 	struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap;
2658 	struct vop2 *vop2 = cstate->private;
2659 	u32 vp_offset = (cstate->crtc_id * 0x100);
2660 	u16 hdisplay = mode->crtc_hdisplay;
2661 	int output_if = conn_state->output_if;
2662 	int if_pixclk_div = 0;
2663 	int if_dclk_div = 0;
2664 	unsigned long dclk_rate;
2665 	u32 val;
2666 
2667 	if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
2668 		val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
2669 		val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
2670 	} else {
2671 		val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
2672 		val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
2673 	}
2674 
2675 	if (cstate->dsc_enable) {
2676 		int k = 1;
2677 
2678 		if (!vop2->data->nr_dscs) {
2679 			printf("Unsupported DSC\n");
2680 			return 0;
2681 		}
2682 
2683 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2684 			k = 2;
2685 
2686 		cstate->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1;
2687 		cstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k;
2688 		cstate->dsc_pixel_num = cstate->dsc_slice_num > 4 ? 4 : cstate->dsc_slice_num;
2689 
2690 		vop2_calc_dsc_clk(state);
2691 		printf("Enable DSC%d slice:%dx%d, slice num:%d\n",
2692 		       cstate->dsc_id, dsc_sink_cap->slice_width,
2693 		       dsc_sink_cap->slice_height, cstate->dsc_slice_num);
2694 	}
2695 
2696 	dclk_rate = vop2_calc_cru_cfg(state, &cstate->dclk_core_div, &cstate->dclk_out_div, &if_pixclk_div, &if_dclk_div);
2697 
2698 	if (output_if & VOP_OUTPUT_IF_RGB) {
2699 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
2700 				4, false);
2701 	}
2702 
2703 	if (output_if & VOP_OUTPUT_IF_BT1120) {
2704 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
2705 				3, false);
2706 	}
2707 
2708 	if (output_if & VOP_OUTPUT_IF_BT656) {
2709 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
2710 				2, false);
2711 	}
2712 
2713 	if (output_if & VOP_OUTPUT_IF_MIPI0) {
2714 		if (cstate->crtc_id == 2)
2715 			val = 0;
2716 		else
2717 			val = 1;
2718 
2719 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
2720 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2721 					RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false);
2722 
2723 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT,
2724 				1, false);
2725 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false);
2726 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT,
2727 				if_pixclk_div, false);
2728 
2729 		if (conn_state->hold_mode) {
2730 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2731 					EN_MASK, EDPI_TE_EN, 1, false);
2732 
2733 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2734 					EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
2735 		}
2736 	}
2737 
2738 	if (output_if & VOP_OUTPUT_IF_MIPI1) {
2739 		if (cstate->crtc_id == 2)
2740 			val = 0;
2741 		else if (cstate->crtc_id == 3)
2742 			val = 1;
2743 		else
2744 			val = 3; /*VP1*/
2745 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
2746 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2747 					RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false);
2748 
2749 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT,
2750 				1, false);
2751 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT,
2752 				val, false);
2753 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT,
2754 				if_pixclk_div, false);
2755 
2756 		if (conn_state->hold_mode) {
2757 			/* UNDO: RK3588 VP1->DSC1->DSI1 only can support soft TE mode */
2758 			if (vop2->version == VOP_VERSION_RK3588 && val == 3)
2759 				vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2760 						EN_MASK, EDPI_TE_EN, 0, false);
2761 			else
2762 				vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2763 						EN_MASK, EDPI_TE_EN, 1, false);
2764 
2765 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2766 					EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
2767 		}
2768 	}
2769 
2770 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
2771 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
2772 				MIPI_DUAL_EN_SHIFT, 1, false);
2773 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
2774 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2775 					EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
2776 					false);
2777 		switch (conn_state->type) {
2778 		case DRM_MODE_CONNECTOR_DisplayPort:
2779 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2780 					RK3588_DP_DUAL_EN_SHIFT, 1, false);
2781 			break;
2782 		case DRM_MODE_CONNECTOR_eDP:
2783 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2784 					RK3588_EDP_DUAL_EN_SHIFT, 1, false);
2785 			break;
2786 		case DRM_MODE_CONNECTOR_HDMIA:
2787 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2788 					RK3588_HDMI_DUAL_EN_SHIFT, 1, false);
2789 			break;
2790 		case DRM_MODE_CONNECTOR_DSI:
2791 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2792 					RK3568_MIPI_DUAL_EN_SHIFT, 1, false);
2793 			break;
2794 		default:
2795 			break;
2796 		}
2797 	}
2798 
2799 	if (output_if & VOP_OUTPUT_IF_eDP0) {
2800 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT,
2801 				1, false);
2802 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
2803 				cstate->crtc_id, false);
2804 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
2805 				if_dclk_div, false);
2806 
2807 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
2808 				if_pixclk_div, false);
2809 
2810 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2811 				RK3588_GRF_EDP0_ENABLE_SHIFT, 1);
2812 	}
2813 
2814 	if (output_if & VOP_OUTPUT_IF_eDP1) {
2815 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT,
2816 				1, false);
2817 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
2818 				cstate->crtc_id, false);
2819 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
2820 				if_dclk_div, false);
2821 
2822 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
2823 				if_pixclk_div, false);
2824 
2825 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2826 				RK3588_GRF_EDP1_ENABLE_SHIFT, 1);
2827 	}
2828 
2829 	if (output_if & VOP_OUTPUT_IF_HDMI0) {
2830 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT,
2831 				1, false);
2832 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
2833 				cstate->crtc_id, false);
2834 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
2835 				if_dclk_div, false);
2836 
2837 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
2838 				if_pixclk_div, false);
2839 
2840 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2841 				RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1);
2842 		vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
2843 				HDMI_SYNC_POL_MASK,
2844 				HDMI0_SYNC_POL_SHIFT, val);
2845 	}
2846 
2847 	if (output_if & VOP_OUTPUT_IF_HDMI1) {
2848 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT,
2849 				1, false);
2850 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
2851 				cstate->crtc_id, false);
2852 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
2853 				if_dclk_div, false);
2854 
2855 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
2856 				if_pixclk_div, false);
2857 
2858 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2859 				RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1);
2860 		vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
2861 				HDMI_SYNC_POL_MASK,
2862 				HDMI1_SYNC_POL_SHIFT, val);
2863 	}
2864 
2865 	if (output_if & VOP_OUTPUT_IF_DP0) {
2866 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT,
2867 				1, false);
2868 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT,
2869 				cstate->crtc_id, false);
2870 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
2871 				RK3588_DP0_PIN_POL_SHIFT, val, false);
2872 	}
2873 
2874 	if (output_if & VOP_OUTPUT_IF_DP1) {
2875 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT,
2876 				1, false);
2877 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT,
2878 				cstate->crtc_id, false);
2879 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
2880 				RK3588_DP1_PIN_POL_SHIFT, val, false);
2881 	}
2882 
2883 	vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
2884 			DCLK_CORE_DIV_SHIFT, cstate->dclk_core_div, false);
2885 	vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
2886 			DCLK_OUT_DIV_SHIFT, cstate->dclk_out_div, false);
2887 
2888 	return dclk_rate;
2889 }
2890 
2891 static unsigned long rk3568_vop2_if_cfg(struct display_state *state)
2892 {
2893 	struct crtc_state *cstate = &state->crtc_state;
2894 	struct connector_state *conn_state = &state->conn_state;
2895 	struct drm_display_mode *mode = &conn_state->mode;
2896 	struct vop2 *vop2 = cstate->private;
2897 	u32 vp_offset = (cstate->crtc_id * 0x100);
2898 	bool dclk_inv;
2899 	u32 val;
2900 
2901 	dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1;
2902 	val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
2903 	val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
2904 
2905 	if (conn_state->output_if & VOP_OUTPUT_IF_RGB) {
2906 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
2907 				1, false);
2908 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2909 				RGB_MUX_SHIFT, cstate->crtc_id, false);
2910 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
2911 				GRF_RGB_DCLK_INV_SHIFT, dclk_inv);
2912 	}
2913 
2914 	if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) {
2915 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
2916 				1, false);
2917 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK,
2918 				BT1120_EN_SHIFT, 1, false);
2919 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2920 				RGB_MUX_SHIFT, cstate->crtc_id, false);
2921 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
2922 				GRF_BT1120_CLK_INV_SHIFT, !dclk_inv);
2923 	}
2924 
2925 	if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
2926 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
2927 				1, false);
2928 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2929 				RGB_MUX_SHIFT, cstate->crtc_id, false);
2930 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
2931 				GRF_BT656_CLK_INV_SHIFT, !dclk_inv);
2932 	}
2933 
2934 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) {
2935 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT,
2936 				1, false);
2937 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2938 				LVDS0_MUX_SHIFT, cstate->crtc_id, false);
2939 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2940 				IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false);
2941 	}
2942 
2943 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) {
2944 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT,
2945 				1, false);
2946 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2947 				LVDS1_MUX_SHIFT, cstate->crtc_id, false);
2948 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2949 				IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false);
2950 	}
2951 
2952 	if (conn_state->output_flags &
2953 	    (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE |
2954 	     ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) {
2955 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2956 				LVDS_DUAL_EN_SHIFT, 1, false);
2957 		if (conn_state->output_flags &
2958 		    ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2959 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2960 					LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1,
2961 					false);
2962 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
2963 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2964 					LVDS_DUAL_SWAP_EN_SHIFT, 1, false);
2965 	}
2966 
2967 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) {
2968 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT,
2969 				1, false);
2970 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2971 				MIPI0_MUX_SHIFT, cstate->crtc_id, false);
2972 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2973 				IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
2974 	}
2975 
2976 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) {
2977 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT,
2978 				1, false);
2979 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2980 				MIPI1_MUX_SHIFT, cstate->crtc_id, false);
2981 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2982 				IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
2983 	}
2984 
2985 	if (conn_state->output_flags &
2986 	    ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
2987 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
2988 				MIPI_DUAL_EN_SHIFT, 1, false);
2989 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
2990 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2991 					EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
2992 					false);
2993 	}
2994 
2995 	if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) {
2996 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT,
2997 				1, false);
2998 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
2999 				EDP0_MUX_SHIFT, cstate->crtc_id, false);
3000 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3001 				IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false);
3002 	}
3003 
3004 	if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
3005 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
3006 				1, false);
3007 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3008 				HDMI0_MUX_SHIFT, cstate->crtc_id, false);
3009 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3010 				IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
3011 		vop2_mask_write(vop2, RK3568_DSP_IF_POL,
3012 				IF_CRTL_HDMI_PIN_POL_MASK,
3013 				IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
3014 	}
3015 
3016 	return mode->clock;
3017 }
3018 
3019 static unsigned long rk3528_vop2_if_cfg(struct display_state *state)
3020 {
3021 	struct crtc_state *cstate = &state->crtc_state;
3022 	struct connector_state *conn_state = &state->conn_state;
3023 	struct drm_display_mode *mode = &conn_state->mode;
3024 	struct vop2 *vop2 = cstate->private;
3025 	u32 val;
3026 
3027 	val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
3028 	val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
3029 
3030 	if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
3031 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
3032 				1, false);
3033 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3034 				RGB_MUX_SHIFT, cstate->crtc_id, false);
3035 	}
3036 
3037 	if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
3038 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
3039 				1, false);
3040 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3041 				HDMI0_MUX_SHIFT, cstate->crtc_id, false);
3042 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3043 				IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
3044 		vop2_mask_write(vop2, RK3568_DSP_IF_POL,
3045 				IF_CRTL_HDMI_PIN_POL_MASK,
3046 				IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
3047 	}
3048 
3049 	return mode->crtc_clock;
3050 }
3051 
3052 static void vop2_post_color_swap(struct display_state *state)
3053 {
3054 	struct crtc_state *cstate = &state->crtc_state;
3055 	struct connector_state *conn_state = &state->conn_state;
3056 	struct vop2 *vop2 = cstate->private;
3057 	u32 vp_offset = (cstate->crtc_id * 0x100);
3058 	u32 output_type = conn_state->type;
3059 	u32 data_swap = 0;
3060 
3061 	if (is_uv_swap(conn_state->bus_format, conn_state->output_mode))
3062 		data_swap = DSP_RB_SWAP;
3063 
3064 	if (vop2->version == VOP_VERSION_RK3588 &&
3065 	    (output_type == DRM_MODE_CONNECTOR_HDMIA ||
3066 	     output_type == DRM_MODE_CONNECTOR_eDP) &&
3067 	    (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
3068 	     conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30))
3069 		data_swap |= DSP_RG_SWAP;
3070 
3071 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
3072 			DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false);
3073 }
3074 
3075 static void vop2_clk_set_parent(struct clk *clk, struct clk *parent)
3076 {
3077 	int ret = 0;
3078 
3079 	if (parent->dev)
3080 		ret = clk_set_parent(clk, parent);
3081 	if (ret < 0)
3082 		debug("failed to set %s as parent for %s\n",
3083 		      parent->dev->name, clk->dev->name);
3084 }
3085 
3086 static ulong vop2_clk_set_rate(struct clk *clk, ulong rate)
3087 {
3088 	int ret = 0;
3089 
3090 	if (clk->dev)
3091 		ret = clk_set_rate(clk, rate);
3092 	if (ret < 0)
3093 		debug("failed to set %s rate %lu \n", clk->dev->name, rate);
3094 
3095 	return ret;
3096 }
3097 
3098 static void vop2_calc_dsc_cru_cfg(struct display_state *state,
3099 				  int *dsc_txp_clk_div, int *dsc_pxl_clk_div,
3100 				  int *dsc_cds_clk_div, u64 dclk_rate)
3101 {
3102 	struct crtc_state *cstate = &state->crtc_state;
3103 
3104 	*dsc_txp_clk_div = dclk_rate / cstate->dsc_txp_clk_rate;
3105 	*dsc_pxl_clk_div = dclk_rate / cstate->dsc_pxl_clk_rate;
3106 	*dsc_cds_clk_div = dclk_rate / cstate->dsc_cds_clk_rate;
3107 
3108 	*dsc_txp_clk_div = ilog2(*dsc_txp_clk_div);
3109 	*dsc_pxl_clk_div = ilog2(*dsc_pxl_clk_div);
3110 	*dsc_cds_clk_div = ilog2(*dsc_cds_clk_div);
3111 }
3112 
3113 static void vop2_load_pps(struct display_state *state, struct vop2 *vop2, u8 dsc_id)
3114 {
3115 	struct crtc_state *cstate = &state->crtc_state;
3116 	struct drm_dsc_picture_parameter_set *pps = &cstate->pps;
3117 	struct drm_dsc_picture_parameter_set config_pps;
3118 	const struct vop2_data *vop2_data = vop2->data;
3119 	const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
3120 	u32 *pps_val = (u32 *)&config_pps;
3121 	u32 decoder_regs_offset = (dsc_id * 0x100);
3122 	int i = 0;
3123 
3124 	memcpy(&config_pps, pps, sizeof(config_pps));
3125 
3126 	if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) {
3127 		config_pps.pps_3 &= 0xf0;
3128 		config_pps.pps_3 |= dsc_data->max_linebuf_depth;
3129 		printf("DSC%d max_linebuf_depth is: %d, current set value is: %d\n",
3130 		       dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf);
3131 	}
3132 
3133 	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
3134 		config_pps.rc_range_parameters[i] =
3135 			(pps->rc_range_parameters[i] >> 3 & 0x1f) |
3136 			((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) |
3137 			((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) |
3138 			((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10);
3139 	}
3140 
3141 	for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++)
3142 		vop2_writel(vop2, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++);
3143 }
3144 
3145 static void vop2_dsc_enable(struct display_state *state, struct vop2 *vop2, u8 dsc_id, u64 dclk_rate)
3146 {
3147 	struct connector_state *conn_state = &state->conn_state;
3148 	struct drm_display_mode *mode = &conn_state->mode;
3149 	struct crtc_state *cstate = &state->crtc_state;
3150 	struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap;
3151 	const struct vop2_data *vop2_data = vop2->data;
3152 	const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
3153 	bool mipi_ds_mode = false;
3154 	u8 dsc_interface_mode = 0;
3155 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
3156 	u16 hdisplay = mode->crtc_hdisplay;
3157 	u16 htotal = mode->crtc_htotal;
3158 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
3159 	u16 vdisplay = mode->crtc_vdisplay;
3160 	u16 vtotal = mode->crtc_vtotal;
3161 	u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
3162 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
3163 	u16 vact_end = vact_st + vdisplay;
3164 	u32 ctrl_regs_offset = (dsc_id * 0x30);
3165 	u32 decoder_regs_offset = (dsc_id * 0x100);
3166 	int dsc_txp_clk_div = 0;
3167 	int dsc_pxl_clk_div = 0;
3168 	int dsc_cds_clk_div = 0;
3169 	int val = 0;
3170 
3171 	if (!vop2->data->nr_dscs) {
3172 		printf("Unsupported DSC\n");
3173 		return;
3174 	}
3175 
3176 	if (cstate->dsc_slice_num > dsc_data->max_slice_num)
3177 		printf("DSC%d supported max slice is: %d, current is: %d\n",
3178 		       dsc_data->id, dsc_data->max_slice_num, cstate->dsc_slice_num);
3179 
3180 	if (dsc_data->pd_id) {
3181 		if (vop2_power_domain_on(vop2, dsc_data->pd_id))
3182 			printf("open dsc%d pd fail\n", dsc_id);
3183 	}
3184 
3185 	vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK,
3186 			SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, false);
3187 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK,
3188 			DSC_PORT_SEL_SHIFT, cstate->crtc_id, false);
3189 	if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
3190 		dsc_interface_mode = VOP_DSC_IF_HDMI;
3191 	} else {
3192 		mipi_ds_mode = !!(conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE);
3193 		if (mipi_ds_mode)
3194 			dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE;
3195 		else
3196 			dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE;
3197 	}
3198 
3199 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3200 		vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
3201 				DSC_MAN_MODE_SHIFT, 0, false);
3202 	else
3203 		vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
3204 				DSC_MAN_MODE_SHIFT, 1, false);
3205 
3206 	vop2_calc_dsc_cru_cfg(state, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate);
3207 
3208 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK,
3209 			DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, false);
3210 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK,
3211 			DSC_PIXEL_NUM_SHIFT, cstate->dsc_pixel_num >> 1, false);
3212 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK,
3213 			DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, false);
3214 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK,
3215 			DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, false);
3216 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
3217 			DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, false);
3218 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK,
3219 			DSC_SCAN_EN_SHIFT, !mipi_ds_mode, false);
3220 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
3221 			DSC_HALT_EN_SHIFT, mipi_ds_mode, false);
3222 
3223 	if (!mipi_ds_mode) {
3224 		u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end;
3225 		u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16;
3226 		u64 dsc_cds_rate = cstate->dsc_cds_clk_rate;
3227 		u32 v_pixclk_mhz = mode->crtc_clock / 1000; /* video timing pixclk */
3228 		u32 dly_num, dsc_cds_rate_mhz, val = 0;
3229 		int k = 1;
3230 
3231 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3232 			k = 2;
3233 
3234 		if (target_bpp >> 4 < dsc_data->min_bits_per_pixel)
3235 			printf("Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel);
3236 
3237 		/*
3238 		 * dly_num = delay_line_num * T(one-line) / T (dsc_cds)
3239 		 * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz
3240 		 * T (dsc_cds) = 1 / dsc_cds_rate_mhz
3241 		 *
3242 		 * HDMI:
3243 		 * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay
3244 		 *                 delay_line_num = 4 - BPP / 8
3245 		 *                                = (64 - target_bpp / 8) / 16
3246 		 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
3247 		 *
3248 		 * MIPI DSI[4320 and 9216 is buffer size for DSC]:
3249 		 * DSC0:delay_line_num = 4320 * 8 / slince_num / chunk_size;
3250 		 *	delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
3251 		 * DSC1:delay_line_num = 9216 * 2 / slince_num / chunk_size;
3252 		 *	delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
3253 		 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num
3254 		 */
3255 		do_div(dsc_cds_rate, 1000000); /* hz to Mhz */
3256 		dsc_cds_rate_mhz = dsc_cds_rate;
3257 		dsc_hsync = hsync_len / 2;
3258 		if (dsc_interface_mode == VOP_DSC_IF_HDMI) {
3259 			dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
3260 		} else {
3261 			int dsc_buf_size  = dsc_id == 0 ? 4320 * 8 : 9216 * 2;
3262 			int delay_line_num = dsc_buf_size / cstate->dsc_slice_num /
3263 					     be16_to_cpu(cstate->pps.chunk_size);
3264 
3265 			delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
3266 			dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num;
3267 
3268 			/* The dsc mipi video mode dsc_hsync minimum size is 8 pixels */
3269 			if (dsc_hsync < 8)
3270 				dsc_hsync = 8;
3271 		}
3272 		vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK,
3273 				DSC_INIT_DLY_MODE_SHIFT, 0, false);
3274 		vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK,
3275 				DSC_INIT_DLY_NUM_SHIFT, dly_num, false);
3276 
3277 		/*
3278 		 * htotal / dclk_core = dsc_htotal /cds_clk
3279 		 *
3280 		 * dclk_core = DCLK / (1 << dclk_core->div_val)
3281 		 * cds_clk = txp_clk / (1 << dsc_cds_clk->div_val)
3282 		 * txp_clk = DCLK / (1 << dsc_txp_clk->div_val)
3283 		 *
3284 		 * dsc_htotal = htotal * (1 << dclk_core->div_val) /
3285 		 *              ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val))
3286 		 */
3287 		dsc_htotal = htotal * (1 << cstate->dclk_core_div) /
3288 			     ((1 << dsc_txp_clk_div) * (1 << dsc_cds_clk_div));
3289 		val = dsc_htotal << 16 | dsc_hsync;
3290 		vop2_mask_write(vop2, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK,
3291 				DSC_HTOTAL_PW_SHIFT, val, false);
3292 
3293 		dsc_hact_st = hact_st / 2;
3294 		dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st;
3295 		val = dsc_hact_end << 16 | dsc_hact_st;
3296 		vop2_mask_write(vop2, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK,
3297 				DSC_HACT_ST_END_SHIFT, val, false);
3298 
3299 		vop2_mask_write(vop2, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK,
3300 				DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, false);
3301 		vop2_mask_write(vop2, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK,
3302 				DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, false);
3303 	}
3304 
3305 	vop2_mask_write(vop2, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK,
3306 			RST_DEASSERT_SHIFT, 1, false);
3307 	udelay(10);
3308 
3309 	val |= DSC_CTRL0_DEF_CON | (ilog2(cstate->dsc_slice_num) << DSC_NSLC_SHIFT) |
3310 	       ((dsc_sink_cap->version_minor == 2 ? 1 : 0) << DSC_IFEP_SHIFT);
3311 	vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
3312 
3313 	vop2_load_pps(state, vop2, dsc_id);
3314 
3315 	val |= (1 << DSC_PPS_UPD_SHIFT);
3316 	vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
3317 
3318 	printf("DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n",
3319 	       dsc_id,
3320 	       cstate->dsc_txp_clk_rate, dsc_txp_clk_div,
3321 	       cstate->dsc_pxl_clk_rate, dsc_pxl_clk_div,
3322 	       cstate->dsc_cds_clk_rate, dsc_cds_clk_div);
3323 }
3324 
3325 static bool is_extend_pll(struct display_state *state, struct udevice **clk_dev)
3326 {
3327 	struct crtc_state *cstate = &state->crtc_state;
3328 	struct vop2 *vop2 = cstate->private;
3329 	struct udevice *vp_dev, *dev;
3330 	struct ofnode_phandle_args args;
3331 	char vp_name[10];
3332 	int ret;
3333 
3334 	if (vop2->version != VOP_VERSION_RK3588)
3335 		return false;
3336 
3337 	sprintf(vp_name, "port@%d", cstate->crtc_id);
3338 	if (uclass_find_device_by_name(UCLASS_VIDEO_CRTC, vp_name, &vp_dev)) {
3339 		debug("warn: can't get vp device\n");
3340 		return false;
3341 	}
3342 
3343 	ret = dev_read_phandle_with_args(vp_dev, "assigned-clock-parents", "#clock-cells", 0,
3344 					 0, &args);
3345 	if (ret) {
3346 		debug("assigned-clock-parents's node not define\n");
3347 		return false;
3348 	}
3349 
3350 	if (uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &dev)) {
3351 		debug("warn: can't get clk device\n");
3352 		return false;
3353 	}
3354 
3355 	if (!strcmp(dev->name, "hdmiphypll_clk0") || !strcmp(dev->name, "hdmiphypll_clk1")) {
3356 		printf("%s: clk dev :%s: vp port:%s\n", __func__, dev->name, vp_dev->name);
3357 		if (clk_dev)
3358 			*clk_dev = dev;
3359 		return true;
3360 	}
3361 
3362 	return false;
3363 }
3364 
3365 static int rockchip_vop2_init(struct display_state *state)
3366 {
3367 	struct crtc_state *cstate = &state->crtc_state;
3368 	struct rockchip_vp *vp = &cstate->crtc->vps[cstate->crtc_id];
3369 	struct connector_state *conn_state = &state->conn_state;
3370 	struct drm_display_mode *mode = &conn_state->mode;
3371 	struct vop2 *vop2 = cstate->private;
3372 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
3373 	u16 hdisplay = mode->crtc_hdisplay;
3374 	u16 htotal = mode->crtc_htotal;
3375 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
3376 	u16 hact_end = hact_st + hdisplay;
3377 	u16 vdisplay = mode->crtc_vdisplay;
3378 	u16 vtotal = mode->crtc_vtotal;
3379 	u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
3380 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
3381 	u16 vact_end = vact_st + vdisplay;
3382 	bool yuv_overlay = false;
3383 	u32 vp_offset = (cstate->crtc_id * 0x100);
3384 	u32 line_flag_offset = (cstate->crtc_id * 4);
3385 	u32 val, act_end;
3386 	u8 dither_down_en = 0;
3387 	u8 pre_dither_down_en = 0;
3388 	u8 dclk_div_factor = 0;
3389 	char output_type_name[30] = {0};
3390 	char dclk_name[9];
3391 	struct clk dclk;
3392 	struct clk hdmi0_phy_pll;
3393 	struct clk hdmi1_phy_pll;
3394 	struct clk hdmi_phy_pll;
3395 	struct udevice *disp_dev;
3396 	unsigned long dclk_rate = 0;
3397 	int ret;
3398 
3399 	printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n",
3400 	       mode->crtc_hdisplay, mode->vdisplay,
3401 	       mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
3402 	       mode->vrefresh,
3403 	       get_output_if_name(conn_state->output_if, output_type_name),
3404 	       cstate->crtc_id);
3405 
3406 	if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
3407 		cstate->splice_mode = true;
3408 		cstate->splice_crtc_id = vop2->data->vp_data[cstate->crtc_id].splice_vp_id;
3409 		if (!cstate->splice_crtc_id) {
3410 			printf("%s: Splice mode is unsupported by vp%d\n",
3411 			       __func__, cstate->crtc_id);
3412 			return -EINVAL;
3413 		}
3414 
3415 		vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, EN_MASK,
3416 				PORT_MERGE_EN_SHIFT, 1, false);
3417 	}
3418 
3419 	vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK,
3420 			RK3588_VP0_LINE_FLAG_OR_EN_SHIFT + cstate->crtc_id, 1, false);
3421 	vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK,
3422 			RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT + cstate->crtc_id, 1, false);
3423 
3424 	vop2_initial(vop2, state);
3425 	if (vop2->version == VOP_VERSION_RK3588)
3426 		dclk_rate = rk3588_vop2_if_cfg(state);
3427 	else if (vop2->version == VOP_VERSION_RK3568)
3428 		dclk_rate = rk3568_vop2_if_cfg(state);
3429 	else if (vop2->version == VOP_VERSION_RK3528)
3430 		dclk_rate = rk3528_vop2_if_cfg(state);
3431 
3432 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
3433 	    !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT))
3434 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
3435 
3436 	vop2_post_color_swap(state);
3437 
3438 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK,
3439 			OUT_MODE_SHIFT, conn_state->output_mode, false);
3440 
3441 	switch (conn_state->bus_format) {
3442 	case MEDIA_BUS_FMT_RGB565_1X16:
3443 		dither_down_en = 1;
3444 		break;
3445 	case MEDIA_BUS_FMT_RGB666_1X18:
3446 	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
3447 	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
3448 	case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA:
3449 		dither_down_en = 1;
3450 		break;
3451 	case MEDIA_BUS_FMT_YUV8_1X24:
3452 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
3453 		dither_down_en = 0;
3454 		pre_dither_down_en = 1;
3455 		break;
3456 	case MEDIA_BUS_FMT_YUV10_1X30:
3457 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
3458 	case MEDIA_BUS_FMT_RGB888_1X24:
3459 	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
3460 	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
3461 	default:
3462 		dither_down_en = 0;
3463 		pre_dither_down_en = 0;
3464 		break;
3465 	}
3466 
3467 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA)
3468 		pre_dither_down_en = 0;
3469 	else
3470 		pre_dither_down_en = 1;
3471 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3472 			DITHER_DOWN_EN_SHIFT, dither_down_en, false);
3473 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3474 			PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false);
3475 
3476 	yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0;
3477 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id,
3478 			yuv_overlay, false);
3479 
3480 	cstate->yuv_overlay = yuv_overlay;
3481 
3482 	vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset,
3483 		    (htotal << 16) | hsync_len);
3484 	val = hact_st << 16;
3485 	val |= hact_end;
3486 	vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val);
3487 	val = vact_st << 16;
3488 	val |= vact_end;
3489 	vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val);
3490 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
3491 		u16 vact_st_f1 = vtotal + vact_st + 1;
3492 		u16 vact_end_f1 = vact_st_f1 + vdisplay;
3493 
3494 		val = vact_st_f1 << 16 | vact_end_f1;
3495 		vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset,
3496 			    val);
3497 
3498 		val = vtotal << 16 | (vtotal + vsync_len);
3499 		vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val);
3500 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3501 				INTERLACE_EN_SHIFT, 1, false);
3502 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3503 				DSP_FILED_POL, 1, false);
3504 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3505 				P2I_EN_SHIFT, 1, false);
3506 		vtotal += vtotal + 1;
3507 		act_end = vact_end_f1;
3508 	} else {
3509 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3510 				INTERLACE_EN_SHIFT, 0, false);
3511 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3512 				P2I_EN_SHIFT, 0, false);
3513 		act_end = vact_end;
3514 	}
3515 	vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset,
3516 		    (vtotal << 16) | vsync_len);
3517 
3518 	if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3528) {
3519 		if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
3520 		    conn_state->output_if & VOP_OUTPUT_IF_BT656)
3521 			vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3522 					CORE_DCLK_DIV_EN_SHIFT, 1, false);
3523 		else
3524 			vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3525 					CORE_DCLK_DIV_EN_SHIFT, 0, false);
3526 	}
3527 
3528 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420)
3529 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3530 				DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false);
3531 	else
3532 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3533 				DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false);
3534 
3535 	vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK,
3536 			OVL_MODE_SEL_SHIFT + cstate->crtc_id, yuv_overlay, false);
3537 
3538 	if (yuv_overlay)
3539 		val = 0x20010200;
3540 	else
3541 		val = 0;
3542 	vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val);
3543 	if (cstate->splice_mode) {
3544 		vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK,
3545 				OVL_MODE_SEL_SHIFT + cstate->splice_crtc_id,
3546 				yuv_overlay, false);
3547 		vop2_writel(vop2, RK3568_VP0_DSP_BG + (cstate->splice_crtc_id * 0x100), val);
3548 	}
3549 
3550 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3551 			POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false);
3552 
3553 	if (vp->xmirror_en)
3554 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3555 				DSP_X_MIR_EN_SHIFT, 1, false);
3556 
3557 	vop2_tv_config_update(state, vop2);
3558 	vop2_post_config(state, vop2);
3559 	if (cstate->feature & (VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC))
3560 		vop3_post_config(state, vop2);
3561 
3562 	if (cstate->dsc_enable) {
3563 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
3564 			vop2_dsc_enable(state, vop2, 0, dclk_rate * 1000LL);
3565 			vop2_dsc_enable(state, vop2, 1, dclk_rate * 1000LL);
3566 		} else {
3567 			vop2_dsc_enable(state, vop2, cstate->dsc_id, dclk_rate * 1000LL);
3568 		}
3569 	}
3570 
3571 	snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id);
3572 	ret = clk_get_by_name(cstate->dev, dclk_name, &dclk);
3573 	if (ret) {
3574 		printf("%s: Failed to get dclk ret=%d\n", __func__, ret);
3575 		return ret;
3576 	}
3577 
3578 	ret = uclass_get_device_by_name(UCLASS_VIDEO, "display-subsystem", &disp_dev);
3579 	if (!ret) {
3580 		ret = clk_get_by_name(disp_dev, "hdmi0_phy_pll", &hdmi0_phy_pll);
3581 		if (ret)
3582 			debug("%s: hdmi0_phy_pll may not define\n", __func__);
3583 		ret = clk_get_by_name(disp_dev, "hdmi1_phy_pll", &hdmi1_phy_pll);
3584 		if (ret)
3585 			debug("%s: hdmi1_phy_pll may not define\n", __func__);
3586 	} else {
3587 		hdmi0_phy_pll.dev = NULL;
3588 		hdmi1_phy_pll.dev = NULL;
3589 		debug("%s: Faile to find display-subsystem node\n", __func__);
3590 	}
3591 
3592 	if (vop2->version == VOP_VERSION_RK3528) {
3593 		struct ofnode_phandle_args args;
3594 
3595 		ret = dev_read_phandle_with_args(cstate->dev, "assigned-clock-parents",
3596 						 "#clock-cells", 0, 0, &args);
3597 		if (!ret) {
3598 			ret = uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &hdmi0_phy_pll.dev);
3599 			if (ret) {
3600 				debug("warn: can't get clk device\n");
3601 				return ret;
3602 			}
3603 		} else {
3604 			debug("assigned-clock-parents's node not define\n");
3605 		}
3606 	}
3607 
3608 	if (mode->crtc_clock < VOP2_MAX_DCLK_RATE) {
3609 		if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0)
3610 			vop2_clk_set_parent(&dclk, &hdmi0_phy_pll);
3611 		else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1)
3612 			vop2_clk_set_parent(&dclk, &hdmi1_phy_pll);
3613 
3614 		/*
3615 		 * uboot clk driver won't set dclk parent's rate when use
3616 		 * hdmi phypll as dclk source.
3617 		 * So set dclk rate is meaningless. Set hdmi phypll rate
3618 		 * directly.
3619 		 */
3620 		if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev) {
3621 			ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate * 1000);
3622 		} else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev) {
3623 			ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate * 1000);
3624 		} else {
3625 			if (is_extend_pll(state, &hdmi_phy_pll.dev)) {
3626 				ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000);
3627 			} else {
3628 				/*
3629 				 * For RK3528, the path of CVBS output is like:
3630 				 * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
3631 				 * The vop2 dclk should be four times crtc_clock for CVBS sampling
3632 				 * clock needs.
3633 				 */
3634 				if (vop2->version == VOP_VERSION_RK3528 &&
3635 				    conn_state->output_if & VOP_OUTPUT_IF_BT656)
3636 					ret = vop2_clk_set_rate(&dclk, 4 * dclk_rate * 1000);
3637 				else
3638 					ret = vop2_clk_set_rate(&dclk, dclk_rate * 1000);
3639 			}
3640 		}
3641 	} else {
3642 		if (is_extend_pll(state, &hdmi_phy_pll.dev))
3643 			ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000);
3644 		else
3645 			ret = vop2_clk_set_rate(&dclk, dclk_rate * 1000);
3646 	}
3647 
3648 	if (IS_ERR_VALUE(ret)) {
3649 		printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n",
3650 		       __func__, cstate->crtc_id, dclk_rate, ret);
3651 		return ret;
3652 	} else {
3653 		dclk_div_factor = mode->clock / dclk_rate;
3654 		if (vop2->version == VOP_VERSION_RK3528 &&
3655 		    conn_state->output_if & VOP_OUTPUT_IF_BT656)
3656 			mode->crtc_clock = ret / 4 / 1000;
3657 		else
3658 			mode->crtc_clock = ret * dclk_div_factor / 1000;
3659 		printf("VP%d set crtc_clock to %dKHz\n", cstate->crtc_id, mode->crtc_clock);
3660 	}
3661 
3662 	vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
3663 			RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false);
3664 	vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
3665 			RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false);
3666 
3667 	return 0;
3668 }
3669 
3670 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win,
3671 			     uint32_t src_w, uint32_t src_h, uint32_t dst_w,
3672 			     uint32_t dst_h)
3673 {
3674 	uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
3675 	uint16_t hscl_filter_mode, vscl_filter_mode;
3676 	uint8_t xgt2 = 0, xgt4 = 0;
3677 	uint8_t ygt2 = 0, ygt4 = 0;
3678 	uint32_t xfac = 0, yfac = 0;
3679 	u32 win_offset = win->reg_offset;
3680 	bool xgt_en = false;
3681 	bool xavg_en = false;
3682 
3683 	if (is_vop3(vop2)) {
3684 		if (src_w >= (4 * dst_w)) {
3685 			xgt4 = 1;
3686 			src_w >>= 2;
3687 		} else if (src_w >= (2 * dst_w)) {
3688 			xgt2 = 1;
3689 			src_w >>= 1;
3690 		}
3691 	}
3692 
3693 	if (src_h >= (4 * dst_h)) {
3694 		ygt4 = 1;
3695 		src_h >>= 2;
3696 	} else if (src_h >= (2 * dst_h)) {
3697 		ygt2 = 1;
3698 		src_h >>= 1;
3699 	}
3700 
3701 	yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
3702 	yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
3703 
3704 	if (yrgb_hor_scl_mode == SCALE_UP)
3705 		hscl_filter_mode = win->hsu_filter_mode;
3706 	else
3707 		hscl_filter_mode = win->hsd_filter_mode;
3708 
3709 	if (yrgb_ver_scl_mode == SCALE_UP)
3710 		vscl_filter_mode = win->vsu_filter_mode;
3711 	else
3712 		vscl_filter_mode = win->vsd_filter_mode;
3713 
3714 	/*
3715 	 * RK3568 VOP Esmart/Smart dsp_w should be even pixel
3716 	 * at scale down mode
3717 	 */
3718 	if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1) && !is_vop3(vop2)) {
3719 		printf("win dst_w[%d] should align as 2 pixel\n", dst_w);
3720 		dst_w += 1;
3721 	}
3722 
3723 	if (is_vop3(vop2)) {
3724 		xfac = vop3_scale_factor(yrgb_hor_scl_mode, src_w, dst_w, true);
3725 		yfac = vop3_scale_factor(yrgb_ver_scl_mode, src_h, dst_h, false);
3726 
3727 		if (win->hsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_AVG)
3728 			xavg_en = xgt2 || xgt4;
3729 		else
3730 			xgt_en = xgt2 || xgt4;
3731 	} else {
3732 		xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w);
3733 		yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h);
3734 	}
3735 
3736 	if (win->type == CLUSTER_LAYER) {
3737 		vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset,
3738 			    yfac << 16 | xfac);
3739 
3740 		if (is_vop3(vop2)) {
3741 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3742 					EN_MASK, CLUSTER_XGT_EN_SHIFT, xgt_en, false);
3743 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3744 					EN_MASK, CLUSTER_XAVG_EN_SHIFT, xavg_en, false);
3745 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3746 					XGT_MODE_MASK, CLUSTER_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false);
3747 
3748 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3749 					YRGB_XSCL_MODE_MASK, RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT,
3750 					yrgb_hor_scl_mode, false);
3751 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3752 					YRGB_YSCL_MODE_MASK, RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT,
3753 					yrgb_ver_scl_mode, false);
3754 		} else {
3755 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3756 					YRGB_XSCL_MODE_MASK, RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT,
3757 					yrgb_hor_scl_mode, false);
3758 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3759 					YRGB_YSCL_MODE_MASK, RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT,
3760 					yrgb_ver_scl_mode, false);
3761 		}
3762 
3763 		if (!is_vop3(vop2) || win->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) {
3764 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3765 					YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, ygt2, false);
3766 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3767 					YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, ygt4, false);
3768 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3769 					AVG2_MASK, CLUSTER_AVG2_SHIFT, 0, false);
3770 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3771 					AVG4_MASK, CLUSTER_AVG4_SHIFT, 0, false);
3772 		} else {
3773 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3774 					YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, 0, false);
3775 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3776 					YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, 0, false);
3777 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3778 					AVG2_MASK, CLUSTER_AVG2_SHIFT, ygt2, false);
3779 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
3780 					AVG4_MASK, CLUSTER_AVG4_SHIFT, ygt4, false);
3781 		}
3782 	} else {
3783 		vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset,
3784 			    yfac << 16 | xfac);
3785 
3786 		if (is_vop3(vop2)) {
3787 			vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
3788 					EN_MASK, ESMART_XGT_EN_SHIFT, xgt_en, false);
3789 			vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
3790 					EN_MASK, ESMART_XAVG_EN_SHIFT, xavg_en, false);
3791 			vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
3792 					XGT_MODE_MASK, ESMART_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false);
3793 		}
3794 
3795 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
3796 				YRGB_GT2_MASK, YRGB_GT2_SHIFT, ygt2, false);
3797 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
3798 				YRGB_GT4_MASK, YRGB_GT4_SHIFT, ygt4, false);
3799 
3800 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
3801 				YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false);
3802 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
3803 				YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false);
3804 
3805 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
3806 				YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT,
3807 				hscl_filter_mode, false);
3808 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
3809 				YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT,
3810 				vscl_filter_mode, false);
3811 	}
3812 }
3813 
3814 static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win)
3815 {
3816 	u32 win_offset = win->reg_offset;
3817 
3818 	if (win->type == CLUSTER_LAYER) {
3819 		vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK,
3820 				CLUSTER_AXI_ID_SHIFT, win->axi_id, false);
3821 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK,
3822 				CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
3823 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK,
3824 				CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
3825 	} else {
3826 		vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK,
3827 				ESMART_AXI_ID_SHIFT, win->axi_id, false);
3828 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK,
3829 				ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
3830 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK,
3831 				ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
3832 	}
3833 }
3834 
3835 static void vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win)
3836 {
3837 	struct crtc_state *cstate = &state->crtc_state;
3838 	struct connector_state *conn_state = &state->conn_state;
3839 	struct drm_display_mode *mode = &conn_state->mode;
3840 	struct vop2 *vop2 = cstate->private;
3841 	int src_w = cstate->src_rect.w;
3842 	int src_h = cstate->src_rect.h;
3843 	int crtc_x = cstate->crtc_rect.x;
3844 	int crtc_y = cstate->crtc_rect.y;
3845 	int crtc_w = cstate->crtc_rect.w;
3846 	int crtc_h = cstate->crtc_rect.h;
3847 	int xvir = cstate->xvir;
3848 	int y_mirror = 0;
3849 	int csc_mode;
3850 	u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
3851 	/* offset of the right window in splice mode */
3852 	u32 splice_pixel_offset = 0;
3853 	u32 splice_yrgb_offset = 0;
3854 	u32 win_offset = win->reg_offset;
3855 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
3856 
3857 	if (win->splice_mode_right) {
3858 		src_w = cstate->right_src_rect.w;
3859 		src_h = cstate->right_src_rect.h;
3860 		crtc_x = cstate->right_crtc_rect.x;
3861 		crtc_y = cstate->right_crtc_rect.y;
3862 		crtc_w = cstate->right_crtc_rect.w;
3863 		crtc_h = cstate->right_crtc_rect.h;
3864 		splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x;
3865 		splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3);
3866 		cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
3867 	}
3868 
3869 	act_info = (src_h - 1) << 16;
3870 	act_info |= (src_w - 1) & 0xffff;
3871 
3872 	dsp_info = (crtc_h - 1) << 16;
3873 	dsp_info |= (crtc_w - 1) & 0xffff;
3874 
3875 	dsp_stx = crtc_x;
3876 	dsp_sty = crtc_y;
3877 	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
3878 
3879 	if (mode->flags & DRM_MODE_FLAG_YMIRROR)
3880 		y_mirror = 1;
3881 	else
3882 		y_mirror = 0;
3883 
3884 	vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
3885 
3886 	if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528)
3887 		vop2_axi_config(vop2, win);
3888 
3889 	if (y_mirror)
3890 		printf("WARN: y mirror is unsupported by cluster window\n");
3891 
3892 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset,
3893 			WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
3894 			false);
3895 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir);
3896 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset,
3897 		    cstate->dma_addr + splice_yrgb_offset);
3898 
3899 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info);
3900 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info);
3901 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st);
3902 
3903 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false);
3904 
3905 	csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH);
3906 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK,
3907 			CLUSTER_RGB2YUV_EN_SHIFT,
3908 			is_yuv_output(conn_state->bus_format), false);
3909 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK,
3910 			CLUSTER_CSC_MODE_SHIFT, csc_mode, false);
3911 	vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false);
3912 
3913 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
3914 }
3915 
3916 static void vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win)
3917 {
3918 	struct crtc_state *cstate = &state->crtc_state;
3919 	struct connector_state *conn_state = &state->conn_state;
3920 	struct drm_display_mode *mode = &conn_state->mode;
3921 	struct vop2 *vop2 = cstate->private;
3922 	int src_w = cstate->src_rect.w;
3923 	int src_h = cstate->src_rect.h;
3924 	int crtc_x = cstate->crtc_rect.x;
3925 	int crtc_y = cstate->crtc_rect.y;
3926 	int crtc_w = cstate->crtc_rect.w;
3927 	int crtc_h = cstate->crtc_rect.h;
3928 	int xvir = cstate->xvir;
3929 	int y_mirror = 0;
3930 	int csc_mode;
3931 	u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
3932 	/* offset of the right window in splice mode */
3933 	u32 splice_pixel_offset = 0;
3934 	u32 splice_yrgb_offset = 0;
3935 	u32 win_offset = win->reg_offset;
3936 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
3937 
3938 	if (win->splice_mode_right) {
3939 		src_w = cstate->right_src_rect.w;
3940 		src_h = cstate->right_src_rect.h;
3941 		crtc_x = cstate->right_crtc_rect.x;
3942 		crtc_y = cstate->right_crtc_rect.y;
3943 		crtc_w = cstate->right_crtc_rect.w;
3944 		crtc_h = cstate->right_crtc_rect.h;
3945 		splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x;
3946 		splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3);
3947 		cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
3948 	}
3949 
3950 	/*
3951 	 * This is workaround solution for IC design:
3952 	 * esmart can't support scale down when actual_w % 16 == 1.
3953 	 */
3954 	if (src_w > crtc_w && (src_w & 0xf) == 1) {
3955 		printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w);
3956 		src_w -= 1;
3957 	}
3958 
3959 	act_info = (src_h - 1) << 16;
3960 	act_info |= (src_w - 1) & 0xffff;
3961 
3962 	dsp_info = (crtc_h - 1) << 16;
3963 	dsp_info |= (crtc_w - 1) & 0xffff;
3964 
3965 	dsp_stx = crtc_x;
3966 	dsp_sty = crtc_y;
3967 	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
3968 
3969 	if (mode->flags & DRM_MODE_FLAG_YMIRROR)
3970 		y_mirror = 1;
3971 	else
3972 		y_mirror = 0;
3973 
3974 	if (is_vop3(vop2))
3975 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, ESMART_LB_SELECT_MASK,
3976 				ESMART_LB_SELECT_SHIFT, win->scale_engine_num, false);
3977 
3978 	vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
3979 
3980 	if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528)
3981 		vop2_axi_config(vop2, win);
3982 
3983 	if (y_mirror)
3984 		cstate->dma_addr += (src_h - 1) * xvir * 4;
3985 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK,
3986 			YMIRROR_EN_SHIFT, y_mirror, false);
3987 
3988 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
3989 			WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
3990 			false);
3991 	vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir);
3992 	vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset,
3993 		    cstate->dma_addr + splice_yrgb_offset);
3994 
3995 	vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset,
3996 		    act_info);
3997 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset,
3998 		    dsp_info);
3999 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st);
4000 
4001 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK,
4002 			WIN_EN_SHIFT, 1, false);
4003 
4004 	csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH);
4005 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK,
4006 			RGB2YUV_EN_SHIFT,
4007 			is_yuv_output(conn_state->bus_format), false);
4008 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK,
4009 			CSC_MODE_SHIFT, csc_mode, false);
4010 
4011 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
4012 }
4013 
4014 static void vop2_calc_display_rect_for_splice(struct display_state *state)
4015 {
4016 	struct crtc_state *cstate = &state->crtc_state;
4017 	struct connector_state *conn_state = &state->conn_state;
4018 	struct drm_display_mode *mode = &conn_state->mode;
4019 	struct display_rect *src_rect = &cstate->src_rect;
4020 	struct display_rect *dst_rect = &cstate->crtc_rect;
4021 	struct display_rect left_src, left_dst, right_src, right_dst;
4022 	u16 half_hdisplay = mode->crtc_hdisplay >> 1;
4023 	int left_src_w, left_dst_w, right_dst_w;
4024 
4025 	left_dst_w = min_t(u16, half_hdisplay, dst_rect->x + dst_rect->w) - dst_rect->x;
4026 	if (left_dst_w < 0)
4027 		left_dst_w = 0;
4028 	right_dst_w = dst_rect->w - left_dst_w;
4029 
4030 	if (!right_dst_w)
4031 		left_src_w = src_rect->w;
4032 	else
4033 		left_src_w = src_rect->x + src_rect->w - src_rect->w / 2;
4034 
4035 	left_src.x = src_rect->x;
4036 	left_src.w = left_src_w;
4037 	left_dst.x = dst_rect->x;
4038 	left_dst.w = left_dst_w;
4039 	right_src.x = left_src.x + left_src.w;
4040 	right_src.w = src_rect->x + src_rect->w - left_src.x - left_src.w;
4041 	right_dst.x = dst_rect->x + left_dst_w - half_hdisplay;
4042 	right_dst.w = right_dst_w;
4043 
4044 	left_src.y = src_rect->y;
4045 	left_src.h = src_rect->h;
4046 	left_dst.y = dst_rect->y;
4047 	left_dst.h = dst_rect->h;
4048 	right_src.y = src_rect->y;
4049 	right_src.h = src_rect->h;
4050 	right_dst.y = dst_rect->y;
4051 	right_dst.h = dst_rect->h;
4052 
4053 	memcpy(&cstate->src_rect, &left_src, sizeof(struct display_rect));
4054 	memcpy(&cstate->crtc_rect, &left_dst, sizeof(struct display_rect));
4055 	memcpy(&cstate->right_src_rect, &right_src, sizeof(struct display_rect));
4056 	memcpy(&cstate->right_crtc_rect, &right_dst, sizeof(struct display_rect));
4057 }
4058 
4059 static int rockchip_vop2_set_plane(struct display_state *state)
4060 {
4061 	struct crtc_state *cstate = &state->crtc_state;
4062 	struct vop2 *vop2 = cstate->private;
4063 	struct vop2_win_data *win_data;
4064 	struct vop2_win_data *splice_win_data;
4065 	u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
4066 	char plane_name[10] = {0};
4067 
4068 	if (cstate->crtc_rect.w > cstate->max_output.width) {
4069 		printf("ERROR: output w[%d] exceeded max width[%d]\n",
4070 		       cstate->crtc_rect.w, cstate->max_output.width);
4071 		return -EINVAL;
4072 	}
4073 
4074 	win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
4075 	if (!win_data) {
4076 		printf("invalid win id %d\n", primary_plane_id);
4077 		return -ENODEV;
4078 	}
4079 
4080 	/* ignore some plane register according vop3 esmart lb mode */
4081 	if (vop3_ignore_plane(vop2, win_data))
4082 		return -EACCES;
4083 
4084 	if (vop2->version == VOP_VERSION_RK3588) {
4085 		if (vop2_power_domain_on(vop2, win_data->pd_id))
4086 			printf("open vp%d plane pd fail\n", cstate->crtc_id);
4087 	}
4088 
4089 	if (cstate->splice_mode) {
4090 		if (win_data->splice_win_id) {
4091 			splice_win_data = vop2_find_win_by_phys_id(vop2, win_data->splice_win_id);
4092 			splice_win_data->splice_mode_right = true;
4093 
4094 			if (vop2_power_domain_on(vop2, splice_win_data->pd_id))
4095 				printf("splice mode: open vp%d plane pd fail\n", cstate->splice_crtc_id);
4096 
4097 			vop2_calc_display_rect_for_splice(state);
4098 			if (win_data->type == CLUSTER_LAYER)
4099 				vop2_set_cluster_win(state, splice_win_data);
4100 			else
4101 				vop2_set_smart_win(state, splice_win_data);
4102 		} else {
4103 			printf("ERROR: splice mode is unsupported by plane %s\n",
4104 			       get_plane_name(primary_plane_id, plane_name));
4105 			return -EINVAL;
4106 		}
4107 	}
4108 
4109 	if (win_data->type == CLUSTER_LAYER)
4110 		vop2_set_cluster_win(state, win_data);
4111 	else
4112 		vop2_set_smart_win(state, win_data);
4113 
4114 	printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n",
4115 		cstate->crtc_id, get_plane_name(primary_plane_id, plane_name),
4116 		cstate->src_rect.w, cstate->src_rect.h, cstate->crtc_rect.w, cstate->crtc_rect.h,
4117 		cstate->crtc_rect.x, cstate->crtc_rect.y, cstate->format,
4118 		cstate->dma_addr);
4119 
4120 	return 0;
4121 }
4122 
4123 static int rockchip_vop2_prepare(struct display_state *state)
4124 {
4125 	return 0;
4126 }
4127 
4128 static void vop2_dsc_cfg_done(struct display_state *state)
4129 {
4130 	struct connector_state *conn_state = &state->conn_state;
4131 	struct crtc_state *cstate = &state->crtc_state;
4132 	struct vop2 *vop2 = cstate->private;
4133 	u8 dsc_id = cstate->dsc_id;
4134 	u32 ctrl_regs_offset = (dsc_id * 0x30);
4135 
4136 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
4137 		vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE, EN_MASK,
4138 				DSC_CFG_DONE_SHIFT, 1, false);
4139 		vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK,
4140 				DSC_CFG_DONE_SHIFT, 1, false);
4141 	} else {
4142 		vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK,
4143 				DSC_CFG_DONE_SHIFT, 1, false);
4144 	}
4145 }
4146 
4147 static int rockchip_vop2_enable(struct display_state *state)
4148 {
4149 	struct crtc_state *cstate = &state->crtc_state;
4150 	struct vop2 *vop2 = cstate->private;
4151 	u32 vp_offset = (cstate->crtc_id * 0x100);
4152 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
4153 
4154 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4155 			STANDBY_EN_SHIFT, 0, false);
4156 
4157 	if (cstate->splice_mode)
4158 		cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
4159 
4160 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
4161 
4162 	if (cstate->dsc_enable)
4163 		vop2_dsc_cfg_done(state);
4164 
4165 	return 0;
4166 }
4167 
4168 static int rockchip_vop2_disable(struct display_state *state)
4169 {
4170 	struct crtc_state *cstate = &state->crtc_state;
4171 	struct vop2 *vop2 = cstate->private;
4172 	u32 vp_offset = (cstate->crtc_id * 0x100);
4173 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
4174 
4175 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4176 			STANDBY_EN_SHIFT, 1, false);
4177 
4178 	if (cstate->splice_mode)
4179 		cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
4180 
4181 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
4182 
4183 	return 0;
4184 }
4185 
4186 static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane)
4187 {
4188 	struct crtc_state *cstate = &state->crtc_state;
4189 	struct vop2 *vop2 = cstate->private;
4190 	int i = 0;
4191 	int correct_cursor_plane = -1;
4192 	int plane_type = -1;
4193 
4194 	if (cursor_plane < 0)
4195 		return -1;
4196 
4197 	if (plane_mask & (1 << cursor_plane))
4198 		return cursor_plane;
4199 
4200 	/* Get current cursor plane type */
4201 	for (i = 0; i < vop2->data->nr_layers; i++) {
4202 		if (vop2->data->plane_table[i].plane_id == cursor_plane) {
4203 			plane_type = vop2->data->plane_table[i].plane_type;
4204 			break;
4205 		}
4206 	}
4207 
4208 	/* Get the other same plane type plane id */
4209 	for (i = 0; i < vop2->data->nr_layers; i++) {
4210 		if (vop2->data->plane_table[i].plane_type == plane_type &&
4211 		    vop2->data->plane_table[i].plane_id != cursor_plane) {
4212 			correct_cursor_plane = vop2->data->plane_table[i].plane_id;
4213 			break;
4214 		}
4215 	}
4216 
4217 	/* To check whether the new correct_cursor_plane is attach to current vp */
4218 	if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) {
4219 		printf("error: faild to find correct plane as cursor plane\n");
4220 		return -1;
4221 	}
4222 
4223 	printf("vp%d adjust cursor plane from %d to %d\n",
4224 	       cstate->crtc_id, cursor_plane, correct_cursor_plane);
4225 
4226 	return correct_cursor_plane;
4227 }
4228 
4229 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob)
4230 {
4231 	struct crtc_state *cstate = &state->crtc_state;
4232 	struct vop2 *vop2 = cstate->private;
4233 	ofnode vp_node;
4234 	struct device_node *port_parent_node = cstate->ports_node;
4235 	static bool vop_fix_dts;
4236 	const char *path;
4237 	u32 plane_mask = 0;
4238 	int vp_id = 0;
4239 	int cursor_plane_id = -1;
4240 
4241 	if (vop_fix_dts || vop2->version == VOP_VERSION_RK3528)
4242 		return 0;
4243 
4244 	ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) {
4245 		path = vp_node.np->full_name;
4246 		plane_mask = vop2->vp_plane_mask[vp_id].plane_mask;
4247 
4248 		if (cstate->crtc->assign_plane)
4249 			continue;
4250 		cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask,
4251 								 cstate->crtc->vps[vp_id].cursor_plane);
4252 		printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n",
4253 		       vp_id, plane_mask,
4254 		       vop2->vp_plane_mask[vp_id].primary_plane_id,
4255 		       cursor_plane_id);
4256 
4257 		do_fixup_by_path_u32(blob, path, "rockchip,plane-mask",
4258 				     plane_mask, 1);
4259 		do_fixup_by_path_u32(blob, path, "rockchip,primary-plane",
4260 				     vop2->vp_plane_mask[vp_id].primary_plane_id, 1);
4261 		if (cursor_plane_id >= 0)
4262 			do_fixup_by_path_u32(blob, path, "cursor-win-id",
4263 					     cursor_plane_id, 1);
4264 		vp_id++;
4265 	}
4266 
4267 	vop_fix_dts = true;
4268 
4269 	return 0;
4270 }
4271 
4272 static int rockchip_vop2_check(struct display_state *state)
4273 {
4274 	struct crtc_state *cstate = &state->crtc_state;
4275 	struct rockchip_crtc *crtc = cstate->crtc;
4276 
4277 	if (crtc->splice_mode && cstate->crtc_id == crtc->splice_crtc_id) {
4278 		printf("WARN: VP%d is busy in splice mode\n", cstate->crtc_id);
4279 		return -ENOTSUPP;
4280 	}
4281 
4282 	if (cstate->splice_mode) {
4283 		crtc->splice_mode = true;
4284 		crtc->splice_crtc_id = cstate->splice_crtc_id;
4285 	}
4286 
4287 	return 0;
4288 }
4289 
4290 static int rockchip_vop2_mode_valid(struct display_state *state)
4291 {
4292 	struct connector_state *conn_state = &state->conn_state;
4293 	struct crtc_state *cstate = &state->crtc_state;
4294 	struct drm_display_mode *mode = &conn_state->mode;
4295 	struct videomode vm;
4296 
4297 	drm_display_mode_to_videomode(mode, &vm);
4298 
4299 	if (vm.hactive < 32 || vm.vactive < 32 ||
4300 	    (vm.hfront_porch * vm.hsync_len * vm.hback_porch *
4301 	     vm.vfront_porch * vm.vsync_len * vm.vback_porch == 0)) {
4302 		printf("ERROR: VP%d: unsupported display timing\n", cstate->crtc_id);
4303 		return -EINVAL;
4304 	}
4305 
4306 	return 0;
4307 }
4308 
4309 #define FRAC_16_16(mult, div)	(((mult) << 16) / (div))
4310 
4311 static int rockchip_vop2_plane_check(struct display_state *state)
4312 {
4313 	struct crtc_state *cstate = &state->crtc_state;
4314 	struct vop2 *vop2 = cstate->private;
4315 	struct display_rect *src = &cstate->src_rect;
4316 	struct display_rect *dst = &cstate->crtc_rect;
4317 	struct vop2_win_data *win_data;
4318 	int min_scale, max_scale;
4319 	int hscale, vscale;
4320 	u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
4321 
4322 	win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
4323 	if (!win_data) {
4324 		printf("ERROR: invalid win id %d\n", primary_plane_id);
4325 		return -ENODEV;
4326 	}
4327 
4328 	min_scale = FRAC_16_16(1, win_data->max_downscale_factor);
4329 	max_scale = FRAC_16_16(win_data->max_upscale_factor, 1);
4330 
4331 	hscale = display_rect_calc_hscale(src, dst, min_scale, max_scale);
4332 	vscale = display_rect_calc_vscale(src, dst, min_scale, max_scale);
4333 	if (hscale < 0 || vscale < 0) {
4334 		printf("ERROR: VP%d %s: scale factor is out of range\n", cstate->crtc_id, win_data->name);
4335 		return -ERANGE;
4336 	}
4337 
4338 	return 0;
4339 }
4340 
4341 static u8 rk3528_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = {
4342 	ROCKCHIP_VOP2_ESMART0,
4343 	ROCKCHIP_VOP2_ESMART1,
4344 	ROCKCHIP_VOP2_ESMART2,
4345 	ROCKCHIP_VOP2_ESMART3,
4346 };
4347 
4348 static struct vop2_plane_table rk3528_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
4349 	{ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
4350 	{ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
4351 	{ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
4352 	{ROCKCHIP_VOP2_ESMART2, ESMART_LAYER},
4353 	{ROCKCHIP_VOP2_ESMART3, ESMART_LAYER},
4354 };
4355 
4356 static struct vop2_vp_plane_mask rk3528_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
4357 	{ /* one display policy for hdmi */
4358 		{/* main display */
4359 			.primary_plane_id = ROCKCHIP_VOP2_ESMART0,
4360 			.attached_layers_nr = 4,
4361 			.attached_layers = {
4362 				  ROCKCHIP_VOP2_CLUSTER0,
4363 				  ROCKCHIP_VOP2_ESMART0,  ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART2
4364 				},
4365 		},
4366 		{/* second display */},
4367 		{/* third  display */},
4368 		{/* fourth display */},
4369 	},
4370 
4371 	{ /* two display policy */
4372 		{/* main display */
4373 			.primary_plane_id = ROCKCHIP_VOP2_ESMART0,
4374 			.attached_layers_nr = 3,
4375 			.attached_layers = {
4376 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1
4377 				},
4378 		},
4379 
4380 		{/* second display */
4381 			.primary_plane_id = ROCKCHIP_VOP2_ESMART3,
4382 			.attached_layers_nr = 2,
4383 			.attached_layers = {
4384 				  ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3
4385 				},
4386 		},
4387 		{/* third  display */},
4388 		{/* fourth display */},
4389 	},
4390 
4391 	{ /* one display policy for cvbs */
4392 		{/* main display */
4393 			.primary_plane_id = ROCKCHIP_VOP2_ESMART3,
4394 			.attached_layers_nr = 2,
4395 			.attached_layers = {
4396 				  ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3
4397 				},
4398 		},
4399 		{/* second display */},
4400 		{/* third  display */},
4401 		{/* fourth display */},
4402 	},
4403 
4404 	{/* reserved */},
4405 };
4406 
4407 static struct vop2_win_data rk3528_win_data[5] = {
4408 	{
4409 		.name = "Esmart0",
4410 		.phys_id = ROCKCHIP_VOP2_ESMART0,
4411 		.type = ESMART_LAYER,
4412 		.win_sel_port_offset = 8,
4413 		.layer_sel_win_id = { 1, 0xff, 0xff, 0xff },
4414 		.reg_offset = 0,
4415 		.axi_id = 0,
4416 		.axi_yrgb_id = 0x06,
4417 		.axi_uv_id = 0x07,
4418 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4419 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4420 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4421 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4422 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
4423 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
4424 		.max_upscale_factor = 8,
4425 		.max_downscale_factor = 8,
4426 	},
4427 
4428 	{
4429 		.name = "Esmart1",
4430 		.phys_id = ROCKCHIP_VOP2_ESMART1,
4431 		.type = ESMART_LAYER,
4432 		.win_sel_port_offset = 10,
4433 		.layer_sel_win_id = { 2, 0xff, 0xff, 0xff },
4434 		.reg_offset = 0x200,
4435 		.axi_id = 0,
4436 		.axi_yrgb_id = 0x08,
4437 		.axi_uv_id = 0x09,
4438 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4439 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4440 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4441 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4442 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
4443 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
4444 		.max_upscale_factor = 8,
4445 		.max_downscale_factor = 8,
4446 	},
4447 
4448 	{
4449 		.name = "Esmart2",
4450 		.phys_id = ROCKCHIP_VOP2_ESMART2,
4451 		.type = ESMART_LAYER,
4452 		.win_sel_port_offset = 12,
4453 		.layer_sel_win_id = { 3, 0, 0xff, 0xff },
4454 		.reg_offset = 0x400,
4455 		.axi_id = 0,
4456 		.axi_yrgb_id = 0x0a,
4457 		.axi_uv_id = 0x0b,
4458 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4459 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4460 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4461 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4462 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
4463 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
4464 		.max_upscale_factor = 8,
4465 		.max_downscale_factor = 8,
4466 	},
4467 
4468 	{
4469 		.name = "Esmart3",
4470 		.phys_id = ROCKCHIP_VOP2_ESMART3,
4471 		.type = ESMART_LAYER,
4472 		.win_sel_port_offset = 14,
4473 		.layer_sel_win_id = { 0xff, 1, 0xff, 0xff },
4474 		.reg_offset = 0x600,
4475 		.axi_id = 0,
4476 		.axi_yrgb_id = 0x0c,
4477 		.axi_uv_id = 0x0d,
4478 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4479 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4480 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4481 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4482 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
4483 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
4484 		.max_upscale_factor = 8,
4485 		.max_downscale_factor = 8,
4486 	},
4487 
4488 	{
4489 		.name = "Cluster0",
4490 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
4491 		.type = CLUSTER_LAYER,
4492 		.win_sel_port_offset = 0,
4493 		.layer_sel_win_id = { 0, 0xff, 0xff, 0xff },
4494 		.reg_offset = 0,
4495 		.axi_id = 0,
4496 		.axi_yrgb_id = 0x02,
4497 		.axi_uv_id = 0x03,
4498 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4499 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4500 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4501 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4502 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
4503 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
4504 		.max_upscale_factor = 8,
4505 		.max_downscale_factor = 8,
4506 	},
4507 };
4508 
4509 static struct vop2_vp_data rk3528_vp_data[2] = {
4510 	{
4511 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_POST_ACM |
4512 			   VOP_FEATURE_POST_CSC,
4513 		.pre_scan_max_dly = 43,
4514 		.max_output = {4096, 4096},
4515 	},
4516 	{
4517 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
4518 		.pre_scan_max_dly = 37,
4519 		.max_output = {1920, 1080},
4520 	},
4521 };
4522 
4523 const struct vop2_data rk3528_vop = {
4524 	.version = VOP_VERSION_RK3528,
4525 	.nr_vps = 2,
4526 	.vp_data = rk3528_vp_data,
4527 	.win_data = rk3528_win_data,
4528 	.plane_mask = rk3528_vp_plane_mask[0],
4529 	.plane_table = rk3528_plane_table,
4530 	.vp_primary_plane_order = rk3528_vp_primary_plane_order,
4531 	.nr_layers = 5,
4532 	.nr_mixers = 3,
4533 	.nr_gammas = 2,
4534 	.esmart_lb_mode = VOP3_ESMART_4K_2K_2K_MODE,
4535 };
4536 
4537 static u8 rk3568_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = {
4538 	ROCKCHIP_VOP2_SMART0,
4539 	ROCKCHIP_VOP2_SMART1,
4540 	ROCKCHIP_VOP2_ESMART0,
4541 	ROCKCHIP_VOP2_ESMART1,
4542 };
4543 
4544 static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
4545 	{ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
4546 	{ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER},
4547 	{ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
4548 	{ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
4549 	{ROCKCHIP_VOP2_SMART0, SMART_LAYER},
4550 	{ROCKCHIP_VOP2_SMART0, SMART_LAYER},
4551 };
4552 
4553 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
4554 	{ /* one display policy */
4555 		{/* main display */
4556 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
4557 			.attached_layers_nr = 6,
4558 			.attached_layers = {
4559 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0,
4560 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
4561 				},
4562 		},
4563 		{/* second display */},
4564 		{/* third  display */},
4565 		{/* fourth display */},
4566 	},
4567 
4568 	{ /* two display policy */
4569 		{/* main display */
4570 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
4571 			.attached_layers_nr = 3,
4572 			.attached_layers = {
4573 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
4574 				},
4575 		},
4576 
4577 		{/* second display */
4578 			.primary_plane_id = ROCKCHIP_VOP2_SMART1,
4579 			.attached_layers_nr = 3,
4580 			.attached_layers = {
4581 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
4582 				},
4583 		},
4584 		{/* third  display */},
4585 		{/* fourth display */},
4586 	},
4587 
4588 	{ /* three display policy */
4589 		{/* main display */
4590 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
4591 			.attached_layers_nr = 3,
4592 			.attached_layers = {
4593 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
4594 				},
4595 		},
4596 
4597 		{/* second display */
4598 			.primary_plane_id = ROCKCHIP_VOP2_SMART1,
4599 			.attached_layers_nr = 2,
4600 			.attached_layers = {
4601 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1
4602 				},
4603 		},
4604 
4605 		{/* third  display */
4606 			.primary_plane_id = ROCKCHIP_VOP2_ESMART1,
4607 			.attached_layers_nr = 1,
4608 			.attached_layers = { ROCKCHIP_VOP2_ESMART1 },
4609 		},
4610 
4611 		{/* fourth display */},
4612 	},
4613 
4614 	{/* reserved for four display policy */},
4615 };
4616 
4617 static struct vop2_win_data rk3568_win_data[6] = {
4618 	{
4619 		.name = "Cluster0",
4620 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
4621 		.type = CLUSTER_LAYER,
4622 		.win_sel_port_offset = 0,
4623 		.layer_sel_win_id = { 0, 0, 0, 0xff },
4624 		.reg_offset = 0,
4625 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4626 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4627 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4628 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4629 		.max_upscale_factor = 4,
4630 		.max_downscale_factor = 4,
4631 	},
4632 
4633 	{
4634 		.name = "Cluster1",
4635 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
4636 		.type = CLUSTER_LAYER,
4637 		.win_sel_port_offset = 1,
4638 		.layer_sel_win_id = { 1, 1, 1, 0xff },
4639 		.reg_offset = 0x200,
4640 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4641 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4642 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4643 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4644 		.max_upscale_factor = 4,
4645 		.max_downscale_factor = 4,
4646 	},
4647 
4648 	{
4649 		.name = "Esmart0",
4650 		.phys_id = ROCKCHIP_VOP2_ESMART0,
4651 		.type = ESMART_LAYER,
4652 		.win_sel_port_offset = 4,
4653 		.layer_sel_win_id = { 2, 2, 2, 0xff },
4654 		.reg_offset = 0,
4655 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4656 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4657 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4658 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4659 		.max_upscale_factor = 8,
4660 		.max_downscale_factor = 8,
4661 	},
4662 
4663 	{
4664 		.name = "Esmart1",
4665 		.phys_id = ROCKCHIP_VOP2_ESMART1,
4666 		.type = ESMART_LAYER,
4667 		.win_sel_port_offset = 5,
4668 		.layer_sel_win_id = { 6, 6, 6, 0xff },
4669 		.reg_offset = 0x200,
4670 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4671 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4672 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4673 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4674 		.max_upscale_factor = 8,
4675 		.max_downscale_factor = 8,
4676 	},
4677 
4678 	{
4679 		.name = "Smart0",
4680 		.phys_id = ROCKCHIP_VOP2_SMART0,
4681 		.type = SMART_LAYER,
4682 		.win_sel_port_offset = 6,
4683 		.layer_sel_win_id = { 3, 3, 3, 0xff },
4684 		.reg_offset = 0x400,
4685 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4686 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4687 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4688 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4689 		.max_upscale_factor = 8,
4690 		.max_downscale_factor = 8,
4691 	},
4692 
4693 	{
4694 		.name = "Smart1",
4695 		.phys_id = ROCKCHIP_VOP2_SMART1,
4696 		.type = SMART_LAYER,
4697 		.win_sel_port_offset = 7,
4698 		.layer_sel_win_id = { 7, 7, 7, 0xff },
4699 		.reg_offset = 0x600,
4700 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4701 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4702 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4703 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4704 		.max_upscale_factor = 8,
4705 		.max_downscale_factor = 8,
4706 	},
4707 };
4708 
4709 static struct vop2_vp_data rk3568_vp_data[3] = {
4710 	{
4711 		.feature = VOP_FEATURE_OUTPUT_10BIT,
4712 		.pre_scan_max_dly = 42,
4713 		.max_output = {4096, 2304},
4714 	},
4715 	{
4716 		.feature = 0,
4717 		.pre_scan_max_dly = 40,
4718 		.max_output = {2048, 1536},
4719 	},
4720 	{
4721 		.feature = 0,
4722 		.pre_scan_max_dly = 40,
4723 		.max_output = {1920, 1080},
4724 	},
4725 };
4726 
4727 const struct vop2_data rk3568_vop = {
4728 	.version = VOP_VERSION_RK3568,
4729 	.nr_vps = 3,
4730 	.vp_data = rk3568_vp_data,
4731 	.win_data = rk3568_win_data,
4732 	.plane_mask = rk356x_vp_plane_mask[0],
4733 	.plane_table = rk356x_plane_table,
4734 	.vp_primary_plane_order = rk3568_vp_primary_plane_order,
4735 	.nr_layers = 6,
4736 	.nr_mixers = 5,
4737 	.nr_gammas = 1,
4738 };
4739 
4740 static u8 rk3588_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = {
4741 	ROCKCHIP_VOP2_ESMART0,
4742 	ROCKCHIP_VOP2_ESMART1,
4743 	ROCKCHIP_VOP2_ESMART2,
4744 	ROCKCHIP_VOP2_ESMART3,
4745 	ROCKCHIP_VOP2_CLUSTER0,
4746 	ROCKCHIP_VOP2_CLUSTER1,
4747 	ROCKCHIP_VOP2_CLUSTER2,
4748 	ROCKCHIP_VOP2_CLUSTER3,
4749 };
4750 
4751 static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
4752 	{ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
4753 	{ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER},
4754 	{ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER},
4755 	{ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER},
4756 	{ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
4757 	{ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
4758 	{ROCKCHIP_VOP2_ESMART2, ESMART_LAYER},
4759 	{ROCKCHIP_VOP2_ESMART3, ESMART_LAYER},
4760 };
4761 
4762 static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
4763 	{ /* one display policy */
4764 		{/* main display */
4765 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
4766 			.attached_layers_nr = 8,
4767 			.attached_layers = {
4768 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2,
4769 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3,
4770 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3
4771 			},
4772 		},
4773 		{/* second display */},
4774 		{/* third  display */},
4775 		{/* fourth display */},
4776 	},
4777 
4778 	{ /* two display policy */
4779 		{/* main display */
4780 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
4781 			.attached_layers_nr = 4,
4782 			.attached_layers = {
4783 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0,
4784 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1
4785 			},
4786 		},
4787 
4788 		{/* second display */
4789 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER2,
4790 			.attached_layers_nr = 4,
4791 			.attached_layers = {
4792 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2,
4793 				  ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3
4794 			},
4795 		},
4796 		{/* third  display */},
4797 		{/* fourth display */},
4798 	},
4799 
4800 	{ /* three display policy */
4801 		{/* main display */
4802 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
4803 			.attached_layers_nr = 3,
4804 			.attached_layers = {
4805 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0
4806 			},
4807 		},
4808 
4809 		{/* second display */
4810 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER2,
4811 			.attached_layers_nr = 3,
4812 			.attached_layers = {
4813 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1
4814 			},
4815 		},
4816 
4817 		{/* third  display */
4818 			.primary_plane_id = ROCKCHIP_VOP2_ESMART2,
4819 			.attached_layers_nr = 2,
4820 			.attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 },
4821 		},
4822 
4823 		{/* fourth display */},
4824 	},
4825 
4826 	{ /* four display policy */
4827 		{/* main display */
4828 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER0,
4829 			.attached_layers_nr = 2,
4830 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 },
4831 		},
4832 
4833 		{/* second display */
4834 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER1,
4835 			.attached_layers_nr = 2,
4836 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 },
4837 		},
4838 
4839 		{/* third  display */
4840 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER2,
4841 			.attached_layers_nr = 2,
4842 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 },
4843 		},
4844 
4845 		{/* fourth display */
4846 			.primary_plane_id = ROCKCHIP_VOP2_CLUSTER3,
4847 			.attached_layers_nr = 2,
4848 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 },
4849 		},
4850 	},
4851 
4852 };
4853 
4854 static struct vop2_win_data rk3588_win_data[8] = {
4855 	{
4856 		.name = "Cluster0",
4857 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
4858 		.splice_win_id = ROCKCHIP_VOP2_CLUSTER1,
4859 		.type = CLUSTER_LAYER,
4860 		.win_sel_port_offset = 0,
4861 		.layer_sel_win_id = { 0, 0, 0, 0 },
4862 		.reg_offset = 0,
4863 		.axi_id = 0,
4864 		.axi_yrgb_id = 2,
4865 		.axi_uv_id = 3,
4866 		.pd_id = VOP2_PD_CLUSTER0,
4867 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4868 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4869 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4870 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4871 		.max_upscale_factor = 4,
4872 		.max_downscale_factor = 4,
4873 	},
4874 
4875 	{
4876 		.name = "Cluster1",
4877 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
4878 		.type = CLUSTER_LAYER,
4879 		.win_sel_port_offset = 1,
4880 		.layer_sel_win_id = { 1, 1, 1, 1 },
4881 		.reg_offset = 0x200,
4882 		.axi_id = 0,
4883 		.axi_yrgb_id = 6,
4884 		.axi_uv_id = 7,
4885 		.pd_id = VOP2_PD_CLUSTER1,
4886 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4887 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4888 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4889 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4890 		.max_upscale_factor = 4,
4891 		.max_downscale_factor = 4,
4892 	},
4893 
4894 	{
4895 		.name = "Cluster2",
4896 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
4897 		.splice_win_id = ROCKCHIP_VOP2_CLUSTER3,
4898 		.type = CLUSTER_LAYER,
4899 		.win_sel_port_offset = 2,
4900 		.layer_sel_win_id = { 4, 4, 4, 4 },
4901 		.reg_offset = 0x400,
4902 		.axi_id = 1,
4903 		.axi_yrgb_id = 2,
4904 		.axi_uv_id = 3,
4905 		.pd_id = VOP2_PD_CLUSTER2,
4906 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4907 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4908 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4909 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4910 		.max_upscale_factor = 4,
4911 		.max_downscale_factor = 4,
4912 	},
4913 
4914 	{
4915 		.name = "Cluster3",
4916 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
4917 		.type = CLUSTER_LAYER,
4918 		.win_sel_port_offset = 3,
4919 		.layer_sel_win_id = { 5, 5, 5, 5 },
4920 		.reg_offset = 0x600,
4921 		.axi_id = 1,
4922 		.axi_yrgb_id = 6,
4923 		.axi_uv_id = 7,
4924 		.pd_id = VOP2_PD_CLUSTER3,
4925 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4926 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4927 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4928 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4929 		.max_upscale_factor = 4,
4930 		.max_downscale_factor = 4,
4931 	},
4932 
4933 	{
4934 		.name = "Esmart0",
4935 		.phys_id = ROCKCHIP_VOP2_ESMART0,
4936 		.splice_win_id = ROCKCHIP_VOP2_ESMART1,
4937 		.type = ESMART_LAYER,
4938 		.win_sel_port_offset = 4,
4939 		.layer_sel_win_id = { 2, 2, 2, 2 },
4940 		.reg_offset = 0,
4941 		.axi_id = 0,
4942 		.axi_yrgb_id = 0x0a,
4943 		.axi_uv_id = 0x0b,
4944 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4945 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4946 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4947 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4948 		.max_upscale_factor = 8,
4949 		.max_downscale_factor = 8,
4950 	},
4951 
4952 	{
4953 		.name = "Esmart1",
4954 		.phys_id = ROCKCHIP_VOP2_ESMART1,
4955 		.type = ESMART_LAYER,
4956 		.win_sel_port_offset = 5,
4957 		.layer_sel_win_id = { 3, 3, 3, 3 },
4958 		.reg_offset = 0x200,
4959 		.axi_id = 0,
4960 		.axi_yrgb_id = 0x0c,
4961 		.axi_uv_id = 0x0d,
4962 		.pd_id = VOP2_PD_ESMART,
4963 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4964 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4965 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4966 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4967 		.max_upscale_factor = 8,
4968 		.max_downscale_factor = 8,
4969 	},
4970 
4971 	{
4972 		.name = "Esmart2",
4973 		.phys_id = ROCKCHIP_VOP2_ESMART2,
4974 		.splice_win_id = ROCKCHIP_VOP2_ESMART3,
4975 		.type = ESMART_LAYER,
4976 		.win_sel_port_offset = 6,
4977 		.layer_sel_win_id = { 6, 6, 6, 6 },
4978 		.reg_offset = 0x400,
4979 		.axi_id = 1,
4980 		.axi_yrgb_id = 0x0a,
4981 		.axi_uv_id = 0x0b,
4982 		.pd_id = VOP2_PD_ESMART,
4983 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
4984 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4985 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
4986 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4987 		.max_upscale_factor = 8,
4988 		.max_downscale_factor = 8,
4989 	},
4990 
4991 	{
4992 		.name = "Esmart3",
4993 		.phys_id = ROCKCHIP_VOP2_ESMART3,
4994 		.type = ESMART_LAYER,
4995 		.win_sel_port_offset = 7,
4996 		.layer_sel_win_id = { 7, 7, 7, 7 },
4997 		.reg_offset = 0x600,
4998 		.axi_id = 1,
4999 		.axi_yrgb_id = 0x0c,
5000 		.axi_uv_id = 0x0d,
5001 		.pd_id = VOP2_PD_ESMART,
5002 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
5003 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5004 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
5005 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5006 		.max_upscale_factor = 8,
5007 		.max_downscale_factor = 8,
5008 	},
5009 };
5010 
5011 static struct dsc_error_info dsc_ecw[] = {
5012 	{0x00000000, "no error detected by DSC encoder"},
5013 	{0x0030ffff, "bits per component error"},
5014 	{0x0040ffff, "multiple mode error"},
5015 	{0x0050ffff, "line buffer depth error"},
5016 	{0x0060ffff, "minor version error"},
5017 	{0x0070ffff, "picture height error"},
5018 	{0x0080ffff, "picture width error"},
5019 	{0x0090ffff, "number of slices error"},
5020 	{0x00c0ffff, "slice height Error "},
5021 	{0x00d0ffff, "slice width error"},
5022 	{0x00e0ffff, "second line BPG offset error"},
5023 	{0x00f0ffff, "non second line BPG offset error"},
5024 	{0x0100ffff, "PPS ID error"},
5025 	{0x0110ffff, "bits per pixel (BPP) Error"},
5026 	{0x0120ffff, "buffer flow error"},  /* dsc_buffer_flow */
5027 
5028 	{0x01510001, "slice 0 RC buffer model overflow error"},
5029 	{0x01510002, "slice 1 RC buffer model overflow error"},
5030 	{0x01510004, "slice 2 RC buffer model overflow error"},
5031 	{0x01510008, "slice 3 RC buffer model overflow error"},
5032 	{0x01510010, "slice 4 RC buffer model overflow error"},
5033 	{0x01510020, "slice 5 RC buffer model overflow error"},
5034 	{0x01510040, "slice 6 RC buffer model overflow error"},
5035 	{0x01510080, "slice 7 RC buffer model overflow error"},
5036 
5037 	{0x01610001, "slice 0 RC buffer model underflow error"},
5038 	{0x01610002, "slice 1 RC buffer model underflow error"},
5039 	{0x01610004, "slice 2 RC buffer model underflow error"},
5040 	{0x01610008, "slice 3 RC buffer model underflow error"},
5041 	{0x01610010, "slice 4 RC buffer model underflow error"},
5042 	{0x01610020, "slice 5 RC buffer model underflow error"},
5043 	{0x01610040, "slice 6 RC buffer model underflow error"},
5044 	{0x01610080, "slice 7 RC buffer model underflow error"},
5045 
5046 	{0xffffffff, "unsuccessful RESET cycle status"},
5047 	{0x00a0ffff, "ICH full error precision settings error"},
5048 	{0x0020ffff, "native mode"},
5049 };
5050 
5051 static struct dsc_error_info dsc_buffer_flow[] = {
5052 	{0x00000000, "rate buffer status"},
5053 	{0x00000001, "line buffer status"},
5054 	{0x00000002, "decoder model status"},
5055 	{0x00000003, "pixel buffer status"},
5056 	{0x00000004, "balance fifo buffer status"},
5057 	{0x00000005, "syntax element fifo status"},
5058 };
5059 
5060 static struct vop2_dsc_data rk3588_dsc_data[] = {
5061 	{
5062 		.id = ROCKCHIP_VOP2_DSC_8K,
5063 		.pd_id = VOP2_PD_DSC_8K,
5064 		.max_slice_num = 8,
5065 		.max_linebuf_depth = 11,
5066 		.min_bits_per_pixel = 8,
5067 		.dsc_txp_clk_src_name = "dsc_8k_txp_clk_src",
5068 		.dsc_txp_clk_name = "dsc_8k_txp_clk",
5069 		.dsc_pxl_clk_name = "dsc_8k_pxl_clk",
5070 		.dsc_cds_clk_name = "dsc_8k_cds_clk",
5071 	},
5072 
5073 	{
5074 		.id = ROCKCHIP_VOP2_DSC_4K,
5075 		.pd_id = VOP2_PD_DSC_4K,
5076 		.max_slice_num = 2,
5077 		.max_linebuf_depth = 11,
5078 		.min_bits_per_pixel = 8,
5079 		.dsc_txp_clk_src_name = "dsc_4k_txp_clk_src",
5080 		.dsc_txp_clk_name = "dsc_4k_txp_clk",
5081 		.dsc_pxl_clk_name = "dsc_4k_pxl_clk",
5082 		.dsc_cds_clk_name = "dsc_4k_cds_clk",
5083 	},
5084 };
5085 
5086 static struct vop2_vp_data rk3588_vp_data[4] = {
5087 	{
5088 		.splice_vp_id = 1,
5089 		.feature = VOP_FEATURE_OUTPUT_10BIT,
5090 		.pre_scan_max_dly = 54,
5091 		.max_dclk = 600000,
5092 		.max_output = {7680, 4320},
5093 	},
5094 	{
5095 		.feature = VOP_FEATURE_OUTPUT_10BIT,
5096 		.pre_scan_max_dly = 54,
5097 		.max_dclk = 600000,
5098 		.max_output = {4096, 2304},
5099 	},
5100 	{
5101 		.feature = VOP_FEATURE_OUTPUT_10BIT,
5102 		.pre_scan_max_dly = 52,
5103 		.max_dclk = 600000,
5104 		.max_output = {4096, 2304},
5105 	},
5106 	{
5107 		.feature = 0,
5108 		.pre_scan_max_dly = 52,
5109 		.max_dclk = 200000,
5110 		.max_output = {1920, 1080},
5111 	},
5112 };
5113 
5114 static struct vop2_power_domain_data rk3588_vop_pd_data[] = {
5115 	{
5116 	  .id = VOP2_PD_CLUSTER0,
5117 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0),
5118 	},
5119 	{
5120 	  .id = VOP2_PD_CLUSTER1,
5121 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER1),
5122 	  .parent_id = VOP2_PD_CLUSTER0,
5123 	},
5124 	{
5125 	  .id = VOP2_PD_CLUSTER2,
5126 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER2),
5127 	  .parent_id = VOP2_PD_CLUSTER0,
5128 	},
5129 	{
5130 	  .id = VOP2_PD_CLUSTER3,
5131 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER3),
5132 	  .parent_id = VOP2_PD_CLUSTER0,
5133 	},
5134 	{
5135 	  .id = VOP2_PD_ESMART,
5136 	  .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART1) |
5137 			    BIT(ROCKCHIP_VOP2_ESMART2) |
5138 			    BIT(ROCKCHIP_VOP2_ESMART3),
5139 	},
5140 	{
5141 	  .id = VOP2_PD_DSC_8K,
5142 	  .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_8K),
5143 	},
5144 	{
5145 	  .id = VOP2_PD_DSC_4K,
5146 	  .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_4K),
5147 	},
5148 };
5149 
5150 const struct vop2_data rk3588_vop = {
5151 	.version = VOP_VERSION_RK3588,
5152 	.nr_vps = 4,
5153 	.vp_data = rk3588_vp_data,
5154 	.win_data = rk3588_win_data,
5155 	.plane_mask = rk3588_vp_plane_mask[0],
5156 	.plane_table = rk3588_plane_table,
5157 	.pd = rk3588_vop_pd_data,
5158 	.dsc = rk3588_dsc_data,
5159 	.dsc_error_ecw = dsc_ecw,
5160 	.dsc_error_buffer_flow = dsc_buffer_flow,
5161 	.vp_primary_plane_order = rk3588_vp_primary_plane_order,
5162 	.nr_layers = 8,
5163 	.nr_mixers = 7,
5164 	.nr_gammas = 4,
5165 	.nr_pd = ARRAY_SIZE(rk3588_vop_pd_data),
5166 	.nr_dscs = 2,
5167 	.nr_dsc_ecw = ARRAY_SIZE(dsc_ecw),
5168 	.nr_dsc_buffer_flow = ARRAY_SIZE(dsc_buffer_flow),
5169 };
5170 
5171 const struct rockchip_crtc_funcs rockchip_vop2_funcs = {
5172 	.preinit = rockchip_vop2_preinit,
5173 	.prepare = rockchip_vop2_prepare,
5174 	.init = rockchip_vop2_init,
5175 	.set_plane = rockchip_vop2_set_plane,
5176 	.enable = rockchip_vop2_enable,
5177 	.disable = rockchip_vop2_disable,
5178 	.fixup_dts = rockchip_vop2_fixup_dts,
5179 	.check = rockchip_vop2_check,
5180 	.mode_valid = rockchip_vop2_mode_valid,
5181 	.plane_check = rockchip_vop2_plane_check,
5182 };
5183