xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_vop2.c (revision a8a4d6c05a2e5f52e75e5096f9470aa3d36fd000)
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 <asm/arch/clock.h>
21 #include <asm/gpio.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 #include <stdlib.h>
32 #include <dm/of_access.h>
33 #include <power-domain.h>
34 
35 #include "rockchip_display.h"
36 #include "rockchip_crtc.h"
37 #include "rockchip_connector.h"
38 #include "rockchip_phy.h"
39 #include "rockchip_post_csc.h"
40 
41 /* System registers definition */
42 #define RK3568_REG_CFG_DONE			0x000
43 #define	CFG_DONE_EN				BIT(15)
44 
45 #define RK3568_VERSION_INFO			0x004
46 #define EN_MASK					1
47 
48 #define RK3568_AUTO_GATING_CTRL			0x008
49 #define AUTO_GATING_EN_SHIFT			31
50 #define PORT_DCLK_AUTO_GATING_EN_SHIFT		14
51 #define ACLK_PRE_AUTO_GATING_EN_SHIFT		7
52 
53 #define RK3576_SYS_AXI_HURRY_CTRL0_IMD		0x014
54 #define AXI0_PORT_URGENCY_EN_SHIFT		24
55 
56 #define RK3576_SYS_AXI_HURRY_CTRL1_IMD		0x018
57 #define AXI1_PORT_URGENCY_EN_SHIFT		24
58 
59 #define RK3576_SYS_MMU_CTRL			0x020
60 #define RKMMU_V2_EN_SHIFT			0
61 #define RKMMU_V2_SEL_AXI_SHIFT			1
62 
63 #define RK3568_SYS_AXI_LUT_CTRL			0x024
64 #define LUT_DMA_EN_SHIFT			0
65 #define DSP_VS_T_SEL_SHIFT			16
66 
67 #define RK3568_DSP_IF_EN			0x028
68 #define RGB_EN_SHIFT				0
69 #define RK3588_DP0_EN_SHIFT			0
70 #define RK3588_DP1_EN_SHIFT			1
71 #define RK3588_RGB_EN_SHIFT			8
72 #define HDMI0_EN_SHIFT				1
73 #define EDP0_EN_SHIFT				3
74 #define RK3588_EDP0_EN_SHIFT			2
75 #define RK3588_HDMI0_EN_SHIFT			3
76 #define MIPI0_EN_SHIFT				4
77 #define RK3588_EDP1_EN_SHIFT			4
78 #define RK3588_HDMI1_EN_SHIFT			5
79 #define RK3588_MIPI0_EN_SHIFT			6
80 #define MIPI1_EN_SHIFT				20
81 #define RK3588_MIPI1_EN_SHIFT			7
82 #define LVDS0_EN_SHIFT				5
83 #define LVDS1_EN_SHIFT				24
84 #define BT1120_EN_SHIFT				6
85 #define BT656_EN_SHIFT				7
86 #define IF_MUX_MASK				3
87 #define RGB_MUX_SHIFT				8
88 #define HDMI0_MUX_SHIFT				10
89 #define RK3588_DP0_MUX_SHIFT			12
90 #define RK3588_DP1_MUX_SHIFT			14
91 #define EDP0_MUX_SHIFT				14
92 #define RK3588_HDMI_EDP0_MUX_SHIFT		16
93 #define RK3588_HDMI_EDP1_MUX_SHIFT		18
94 #define MIPI0_MUX_SHIFT				16
95 #define RK3588_MIPI0_MUX_SHIFT			20
96 #define MIPI1_MUX_SHIFT				21
97 #define LVDS0_MUX_SHIFT				18
98 #define LVDS1_MUX_SHIFT				25
99 
100 #define RK3576_SYS_PORT_CTRL			0x028
101 #define VP_INTR_MERGE_EN_SHIFT			14
102 #define RK3576_DSP_VS_T_SEL_SHIFT		4
103 #define INTERLACE_FRM_REG_DONE_MASK		0x7
104 #define INTERLACE_FRM_REG_DONE_SHIFT		0
105 
106 #define RK3568_DSP_IF_CTRL			0x02c
107 #define LVDS_DUAL_EN_SHIFT			0
108 #define RK3588_BT656_UV_SWAP_SHIFT		0
109 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT		1
110 #define RK3588_BT656_YC_SWAP_SHIFT		1
111 #define LVDS_DUAL_SWAP_EN_SHIFT			2
112 #define BT656_UV_SWAP				4
113 #define RK3588_BT1120_UV_SWAP_SHIFT		4
114 #define BT656_YC_SWAP				5
115 #define RK3588_BT1120_YC_SWAP_SHIFT		5
116 #define BT656_DCLK_POL				6
117 #define RK3588_HDMI_DUAL_EN_SHIFT		8
118 #define RK3588_EDP_DUAL_EN_SHIFT		8
119 #define RK3588_DP_DUAL_EN_SHIFT			9
120 #define RK3568_MIPI_DUAL_EN_SHIFT		10
121 #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT		11
122 #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT		12
123 
124 #define RK3568_DSP_IF_POL			0x030
125 #define IF_CTRL_REG_DONE_IMD_SHIFT		28
126 #define IF_CRTL_MIPI_DCLK_POL_SHIT		19
127 #define IF_CTRL_MIPI_PIN_POL_MASK		0x7
128 #define IF_CTRL_MIPI_PIN_POL_SHIFT		16
129 #define IF_CRTL_EDP_DCLK_POL_SHIT		15
130 #define IF_CTRL_EDP_PIN_POL_MASK		0x7
131 #define IF_CTRL_EDP_PIN_POL_SHIFT		12
132 #define IF_CRTL_HDMI_DCLK_POL_SHIT		7
133 #define IF_CRTL_HDMI_PIN_POL_MASK		0x7
134 #define IF_CRTL_HDMI_PIN_POL_SHIT		4
135 #define IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT		3
136 #define IF_CTRL_RGB_LVDS_PIN_POL_MASK		0x7
137 #define IF_CTRL_RGB_LVDS_PIN_POL_SHIFT		0
138 
139 #define RK3562_MIPI_DCLK_POL_SHIFT		15
140 #define RK3562_MIPI_PIN_POL_SHIFT		12
141 #define RK3562_IF_PIN_POL_MASK			0x7
142 
143 #define RK3588_DP0_PIN_POL_SHIFT		8
144 #define RK3588_DP1_PIN_POL_SHIFT		12
145 #define RK3588_IF_PIN_POL_MASK			0x7
146 
147 #define HDMI_EDP0_DCLK_DIV_SHIFT		16
148 #define HDMI_EDP0_PIXCLK_DIV_SHIFT		18
149 #define HDMI_EDP1_DCLK_DIV_SHIFT		20
150 #define HDMI_EDP1_PIXCLK_DIV_SHIFT		22
151 #define MIPI0_PIXCLK_DIV_SHIFT			24
152 #define MIPI1_PIXCLK_DIV_SHIFT			26
153 
154 #define RK3576_SYS_CLUSTER_PD_CTRL		0x030
155 #define RK3576_CLUSTER_PD_EN_SHIFT		0
156 
157 #define RK3588_SYS_PD_CTRL			0x034
158 #define RK3588_CLUSTER0_PD_EN_SHIFT		0
159 #define RK3588_CLUSTER1_PD_EN_SHIFT		1
160 #define RK3588_CLUSTER2_PD_EN_SHIFT		2
161 #define RK3588_CLUSTER3_PD_EN_SHIFT		3
162 #define RK3588_DSC_8K_PD_EN_SHIFT		5
163 #define RK3588_DSC_4K_PD_EN_SHIFT		6
164 #define RK3588_ESMART_PD_EN_SHIFT		7
165 
166 #define RK3576_SYS_ESMART_PD_CTRL		0x034
167 #define RK3576_ESMART_PD_EN_SHIFT		0
168 #define RK3576_ESMART_LB_MODE_SEL_SHIFT		6
169 #define RK3576_ESMART_LB_MODE_SEL_MASK		0x3
170 
171 #define RK3568_SYS_OTP_WIN_EN			0x50
172 #define OTP_WIN_EN_SHIFT			0
173 #define RK3568_SYS_LUT_PORT_SEL			0x58
174 #define GAMMA_PORT_SEL_MASK			0x3
175 #define GAMMA_PORT_SEL_SHIFT			0
176 #define GAMMA_AHB_WRITE_SEL_MASK		0x3
177 #define GAMMA_AHB_WRITE_SEL_SHIFT		12
178 #define PORT_MERGE_EN_SHIFT			16
179 #define ESMART_LB_MODE_SEL_MASK			0x3
180 #define ESMART_LB_MODE_SEL_SHIFT		26
181 
182 #define RK3568_VP0_LINE_FLAG			0x70
183 #define RK3568_VP1_LINE_FLAG			0x74
184 #define RK3568_VP2_LINE_FLAG			0x78
185 #define RK3568_SYS0_INT_EN			0x80
186 #define RK3568_SYS0_INT_CLR			0x84
187 #define RK3568_SYS0_INT_STATUS			0x88
188 #define RK3568_SYS1_INT_EN			0x90
189 #define RK3568_SYS1_INT_CLR			0x94
190 #define RK3568_SYS1_INT_STATUS			0x98
191 #define RK3568_VP0_INT_EN			0xA0
192 #define RK3568_VP0_INT_CLR			0xA4
193 #define RK3568_VP0_INT_STATUS			0xA8
194 #define RK3568_VP1_INT_EN			0xB0
195 #define RK3568_VP1_INT_CLR			0xB4
196 #define RK3568_VP1_INT_STATUS			0xB8
197 #define RK3568_VP2_INT_EN			0xC0
198 #define RK3568_VP2_INT_CLR			0xC4
199 #define RK3568_VP2_INT_STATUS			0xC8
200 #define RK3568_VP2_INT_RAW_STATUS		0xCC
201 #define RK3588_VP3_INT_EN			0xD0
202 #define RK3588_VP3_INT_CLR			0xD4
203 #define RK3588_VP3_INT_STATUS			0xD8
204 #define RK3576_WB_CTRL				0x100
205 #define RK3576_WB_XSCAL_FACTOR			0x104
206 #define RK3576_WB_YRGB_MST			0x108
207 #define RK3576_WB_CBR_MST			0x10C
208 #define RK3576_WB_VIR_STRIDE			0x110
209 #define RK3576_WB_TIMEOUT_CTRL			0x114
210 #define RK3576_MIPI0_IF_CTRL			0x180
211 #define RK3576_IF_OUT_EN_SHIFT			0
212 #define RK3576_IF_CLK_OUT_EN_SHIFT		1
213 #define RK3576_IF_PORT_SEL_SHIFT		2
214 #define RK3576_IF_PORT_SEL_MASK			0x3
215 #define RK3576_IF_PIN_POL_SHIFT			4
216 #define RK3576_IF_PIN_POL_MASK			0x7
217 #define RK3576_IF_SPLIT_EN_SHIFT		8
218 #define RK3576_IF_DATA1_SEL_SHIFT		9
219 #define RK3576_MIPI_CMD_MODE_SHIFT		11
220 #define RK3576_IF_DCLK_SEL_SHIFT		21
221 #define RK3576_IF_DCLK_SEL_MASK			0x1
222 #define RK3576_IF_PIX_CLK_SEL_SHIFT		20
223 #define RK3576_IF_PIX_CLK_SEL_MASK		0x1
224 #define RK3576_IF_REGDONE_IMD_EN_SHIFT		31
225 #define RK3576_HDMI0_IF_CTRL			0x184
226 #define RK3576_EDP0_IF_CTRL			0x188
227 #define RK3576_DP0_IF_CTRL			0x18C
228 #define RK3576_RGB_IF_CTRL			0x194
229 #define RK3576_BT656_OUT_EN_SHIFT		12
230 #define RK3576_BT656_UV_SWAP_SHIFT		13
231 #define RK3576_BT656_YC_SWAP_SHIFT		14
232 #define RK3576_BT1120_OUT_EN_SHIFT		16
233 #define RK3576_BT1120_UV_SWAP_SHIFT		17
234 #define RK3576_BT1120_YC_SWAP_SHIFT		18
235 #define RK3576_DP1_IF_CTRL			0x1A4
236 #define RK3576_DP2_IF_CTRL			0x1B0
237 
238 #define RK3588_SYS_VAR_FREQ_CTRL		0x038
239 #define RK3588_VP0_LINE_FLAG_OR_EN_SHIFT	20
240 #define RK3588_VP0_DSP_HOLD_OR_EN_SHIFT		24
241 #define RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT	28
242 
243 #define RK3568_SYS_STATUS0			0x60
244 #define RK3588_CLUSTER0_PD_STATUS_SHIFT		8
245 #define RK3588_CLUSTER1_PD_STATUS_SHIFT		9
246 #define RK3588_CLUSTER2_PD_STATUS_SHIFT		10
247 #define RK3588_CLUSTER3_PD_STATUS_SHIFT		11
248 #define RK3588_DSC_8K_PD_STATUS_SHIFT		13
249 #define RK3588_DSC_4K_PD_STATUS_SHIFT		14
250 #define RK3588_ESMART_PD_STATUS_SHIFT		15
251 
252 #define RK3568_SYS_CTRL_LINE_FLAG0		0x70
253 #define LINE_FLAG_NUM_MASK			0x1fff
254 #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT		0
255 #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT		16
256 
257 /* DSC CTRL registers definition */
258 #define RK3588_DSC_8K_SYS_CTRL			0x200
259 #define DSC_PORT_SEL_MASK			0x3
260 #define DSC_PORT_SEL_SHIFT			0
261 #define DSC_MAN_MODE_MASK			0x1
262 #define DSC_MAN_MODE_SHIFT			2
263 #define DSC_INTERFACE_MODE_MASK			0x3
264 #define DSC_INTERFACE_MODE_SHIFT		4
265 #define DSC_PIXEL_NUM_MASK			0x3
266 #define DSC_PIXEL_NUM_SHIFT			6
267 #define DSC_PXL_CLK_DIV_MASK			0x1
268 #define DSC_PXL_CLK_DIV_SHIFT			8
269 #define DSC_CDS_CLK_DIV_MASK			0x3
270 #define DSC_CDS_CLK_DIV_SHIFT			12
271 #define DSC_TXP_CLK_DIV_MASK			0x3
272 #define DSC_TXP_CLK_DIV_SHIFT			14
273 #define DSC_INIT_DLY_MODE_MASK			0x1
274 #define DSC_INIT_DLY_MODE_SHIFT			16
275 #define DSC_SCAN_EN_SHIFT			17
276 #define DSC_HALT_EN_SHIFT			18
277 
278 #define RK3588_DSC_8K_RST			0x204
279 #define RST_DEASSERT_MASK			0x1
280 #define RST_DEASSERT_SHIFT			0
281 
282 #define RK3588_DSC_8K_CFG_DONE			0x208
283 #define DSC_CFG_DONE_SHIFT			0
284 
285 #define RK3588_DSC_8K_INIT_DLY			0x20C
286 #define DSC_INIT_DLY_NUM_MASK			0xffff
287 #define DSC_INIT_DLY_NUM_SHIFT			0
288 #define SCAN_TIMING_PARA_IMD_EN_SHIFT		16
289 
290 #define RK3588_DSC_8K_HTOTAL_HS_END		0x210
291 #define DSC_HTOTAL_PW_MASK			0xffffffff
292 #define DSC_HTOTAL_PW_SHIFT			0
293 
294 #define RK3588_DSC_8K_HACT_ST_END		0x214
295 #define DSC_HACT_ST_END_MASK			0xffffffff
296 #define DSC_HACT_ST_END_SHIFT			0
297 
298 #define RK3588_DSC_8K_VTOTAL_VS_END		0x218
299 #define DSC_VTOTAL_PW_MASK			0xffffffff
300 #define DSC_VTOTAL_PW_SHIFT			0
301 
302 #define RK3588_DSC_8K_VACT_ST_END		0x21C
303 #define DSC_VACT_ST_END_MASK			0xffffffff
304 #define DSC_VACT_ST_END_SHIFT			0
305 
306 #define RK3588_DSC_8K_STATUS			0x220
307 
308 /* Overlay registers definition    */
309 #define RK3528_OVL_SYS				0x500
310 #define RK3528_OVL_SYS_PORT_SEL			0x504
311 #define RK3528_OVL_SYS_GATING_EN		0x508
312 #define RK3528_OVL_SYS_CLUSTER0_CTRL		0x510
313 #define CLUSTER_DLY_NUM_SHIFT			0
314 #define RK3528_OVL_SYS_ESMART0_CTRL		0x520
315 #define ESMART_DLY_NUM_MASK			0xff
316 #define ESMART_DLY_NUM_SHIFT			0
317 #define RK3528_OVL_SYS_ESMART1_CTRL		0x524
318 #define RK3528_OVL_SYS_ESMART2_CTRL		0x528
319 #define RK3528_OVL_SYS_ESMART3_CTRL		0x52C
320 #define RK3528_CLUSTER0_MIX_SRC_COLOR_CTRL	0x530
321 #define RK3528_CLUSTER0_MIX_DST_COLOR_CTRL	0x534
322 #define RK3528_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x538
323 #define RK3528_CLUSTER0_MIX_DST_ALPHA_CTRL	0x53c
324 #define RK3576_CLUSTER1_MIX_SRC_COLOR_CTRL	0x540
325 #define RK3576_CLUSTER1_MIX_DST_COLOR_CTRL	0x544
326 #define RK3576_CLUSTER1_MIX_SRC_ALPHA_CTRL	0x548
327 #define RK3576_CLUSTER1_MIX_DST_ALPHA_CTRL	0x54c
328 
329 #define RK3528_OVL_PORT0_CTRL			0x600
330 #define RK3568_OVL_CTRL				0x600
331 #define OVL_MODE_SEL_MASK			0x1
332 #define OVL_MODE_SEL_SHIFT			0
333 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT		28
334 #define RK3528_OVL_PORT0_LAYER_SEL		0x604
335 #define RK3568_OVL_LAYER_SEL			0x604
336 #define LAYER_SEL_MASK				0xf
337 
338 #define RK3568_OVL_PORT_SEL			0x608
339 #define PORT_MUX_MASK				0xf
340 #define PORT_MUX_SHIFT				0
341 #define LAYER_SEL_PORT_MASK			0x3
342 #define LAYER_SEL_PORT_SHIFT			16
343 
344 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL	0x610
345 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL	0x614
346 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x618
347 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL	0x61C
348 #define RK3528_OVL_PORT0_MIX0_SRC_COLOR_CTRL	0x620
349 #define RK3528_OVL_PORT0_MIX0_DST_COLOR_CTRL	0x624
350 #define RK3528_OVL_PORT0_MIX0_SRC_ALPHA_CTRL	0x628
351 #define RK3528_OVL_PORT0_MIX0_DST_ALPHA_CTRL	0x62C
352 #define RK3528_OVL_PORT0_MIX1_SRC_COLOR_CTRL	0x630
353 #define RK3528_OVL_PORT0_MIX1_DST_COLOR_CTRL	0x634
354 #define RK3528_OVL_PORT0_MIX1_SRC_ALPHA_CTRL	0x638
355 #define RK3528_OVL_PORT0_MIX1_DST_ALPHA_CTRL	0x63C
356 #define RK3528_OVL_PORT0_MIX2_SRC_COLOR_CTRL	0x640
357 #define RK3528_OVL_PORT0_MIX2_DST_COLOR_CTRL	0x644
358 #define RK3528_OVL_PORT0_MIX2_SRC_ALPHA_CTRL	0x648
359 #define RK3528_OVL_PORT0_MIX2_DST_ALPHA_CTRL	0x64C
360 #define RK3568_MIX0_SRC_COLOR_CTRL		0x650
361 #define RK3568_MIX0_DST_COLOR_CTRL		0x654
362 #define RK3568_MIX0_SRC_ALPHA_CTRL		0x658
363 #define RK3568_MIX0_DST_ALPHA_CTRL		0x65C
364 #define RK3576_EXTRA_SRC_COLOR_CTRL		0x650
365 #define RK3576_EXTRA_DST_COLOR_CTRL		0x654
366 #define RK3576_EXTRA_SRC_ALPHA_CTRL		0x658
367 #define RK3576_EXTRA_DST_ALPHA_CTRL		0x65C
368 #define RK3528_HDR_SRC_COLOR_CTRL		0x660
369 #define RK3528_HDR_DST_COLOR_CTRL		0x664
370 #define RK3528_HDR_SRC_ALPHA_CTRL		0x668
371 #define RK3528_HDR_DST_ALPHA_CTRL		0x66C
372 #define RK3528_OVL_PORT0_BG_MIX_CTRL		0x670
373 #define RK3568_HDR0_SRC_COLOR_CTRL		0x6C0
374 #define RK3568_HDR0_DST_COLOR_CTRL		0x6C4
375 #define RK3568_HDR0_SRC_ALPHA_CTRL		0x6C8
376 #define RK3568_HDR0_DST_ALPHA_CTRL		0x6CC
377 #define RK3568_VP0_BG_MIX_CTRL			0x6E0
378 #define BG_MIX_CTRL_MASK			0xff
379 #define BG_MIX_CTRL_SHIFT			24
380 #define RK3568_VP1_BG_MIX_CTRL			0x6E4
381 #define RK3568_VP2_BG_MIX_CTRL			0x6E8
382 #define RK3568_CLUSTER_DLY_NUM			0x6F0
383 #define RK3568_CLUSTER_DLY_NUM1			0x6F4
384 #define CLUSTER_DLY_NUM_MASK			0xffff
385 #define CLUSTER0_DLY_NUM_SHIFT			0
386 #define CLUSTER1_DLY_NUM_SHIFT			16
387 #define RK3568_SMART_DLY_NUM			0x6F8
388 #define SMART_DLY_NUM_MASK			0xff
389 #define ESMART0_DLY_NUM_SHIFT			0
390 #define ESMART1_DLY_NUM_SHIFT			8
391 #define SMART0_DLY_NUM_SHIFT			16
392 #define SMART1_DLY_NUM_SHIFT			24
393 
394 #define RK3528_OVL_PORT1_CTRL			0x700
395 #define RK3528_OVL_PORT1_LAYER_SEL		0x704
396 #define RK3528_OVL_PORT1_MIX0_SRC_COLOR_CTRL	0x720
397 #define RK3528_OVL_PORT1_MIX0_DST_COLOR_CTRL	0x724
398 #define RK3528_OVL_PORT1_MIX0_SRC_ALPHA_CTRL	0x728
399 #define RK3528_OVL_PORT1_MIX0_DST_ALPHA_CTRL	0x72C
400 #define RK3528_OVL_PORT1_MIX1_SRC_COLOR_CTRL	0x730
401 #define RK3528_OVL_PORT1_MIX1_DST_COLOR_CTRL	0x734
402 #define RK3528_OVL_PORT1_MIX1_SRC_ALPHA_CTRL	0x738
403 #define RK3528_OVL_PORT1_MIX1_DST_ALPHA_CTRL	0x73C
404 #define RK3528_OVL_PORT1_MIX2_SRC_COLOR_CTRL	0x740
405 #define RK3528_OVL_PORT1_MIX2_DST_COLOR_CTRL	0x744
406 #define RK3528_OVL_PORT1_MIX2_SRC_ALPHA_CTRL	0x748
407 #define RK3528_OVL_PORT1_MIX2_DST_ALPHA_CTRL	0x74C
408 #define RK3528_OVL_PORT1_BG_MIX_CTRL		0x770
409 #define RK3576_OVL_PORT2_CTRL			0x800
410 #define RK3576_OVL_PORT2_LAYER_SEL		0x804
411 #define RK3576_OVL_PORT2_MIX0_SRC_COLOR_CTRL	0x820
412 #define RK3576_OVL_PORT2_MIX0_DST_COLOR_CTRL	0x824
413 #define RK3576_OVL_PORT2_MIX0_SRC_ALPHA_CTRL	0x828
414 #define RK3576_OVL_PORT2_MIX0_DST_ALPHA_CTRL	0x82C
415 #define RK3576_OVL_PORT2_BG_MIX_CTRL		0x870
416 
417 /* Video Port registers definition */
418 #define RK3568_VP0_DSP_CTRL			0xC00
419 #define OUT_MODE_MASK				0xf
420 #define OUT_MODE_SHIFT				0
421 #define DATA_SWAP_MASK				0x1f
422 #define DATA_SWAP_SHIFT				8
423 #define DSP_BG_SWAP				0x1
424 #define DSP_RB_SWAP				0x2
425 #define DSP_RG_SWAP				0x4
426 #define DSP_DELTA_SWAP				0x8
427 #define CORE_DCLK_DIV_EN_SHIFT			4
428 #define P2I_EN_SHIFT				5
429 #define DSP_FILED_POL				6
430 #define INTERLACE_EN_SHIFT			7
431 #define DSP_X_MIR_EN_SHIFT			13
432 #define POST_DSP_OUT_R2Y_SHIFT			15
433 #define PRE_DITHER_DOWN_EN_SHIFT		16
434 #define DITHER_DOWN_EN_SHIFT			17
435 #define DITHER_DOWN_SEL_SHIFT			18
436 #define DITHER_DOWN_SEL_MASK			0x3
437 #define DITHER_DOWN_MODE_SHIFT			20
438 #define GAMMA_UPDATE_EN_SHIFT			22
439 #define DSP_LUT_EN_SHIFT			28
440 
441 #define STANDBY_EN_SHIFT			31
442 
443 #define RK3568_VP0_MIPI_CTRL			0xC04
444 #define DCLK_DIV2_SHIFT				4
445 #define DCLK_DIV2_MASK				0x3
446 #define MIPI_DUAL_EN_SHIFT			20
447 #define MIPI_DUAL_SWAP_EN_SHIFT			21
448 #define EDPI_TE_EN				28
449 #define EDPI_WMS_HOLD_EN			30
450 #define EDPI_WMS_FS				31
451 
452 
453 #define RK3568_VP0_COLOR_BAR_CTRL		0xC08
454 #define POST_URGENCY_EN_SHIFT			8
455 #define POST_URGENCY_THL_SHIFT			16
456 #define POST_URGENCY_THL_MASK			0xf
457 #define POST_URGENCY_THH_SHIFT			20
458 #define POST_URGENCY_THH_MASK			0xf
459 
460 #define RK3568_VP0_DCLK_SEL			0xC0C
461 #define RK3576_DCLK_CORE_SEL_SHIFT		0
462 #define RK3576_DCLK_OUT_SEL_SHIFT		2
463 
464 #define RK3568_VP0_3D_LUT_CTRL			0xC10
465 #define VP0_3D_LUT_EN_SHIFT				0
466 #define VP0_3D_LUT_UPDATE_SHIFT			2
467 
468 #define RK3588_VP0_CLK_CTRL			0xC0C
469 #define DCLK_CORE_DIV_SHIFT			0
470 #define DCLK_OUT_DIV_SHIFT			2
471 
472 #define RK3568_VP0_3D_LUT_MST			0xC20
473 
474 #define RK3568_VP0_DSP_BG			0xC2C
475 #define RK3568_VP0_PRE_SCAN_HTIMING		0xC30
476 #define RK3568_VP0_POST_DSP_HACT_INFO		0xC34
477 #define RK3568_VP0_POST_DSP_VACT_INFO		0xC38
478 #define RK3568_VP0_POST_SCL_FACTOR_YRGB		0xC3C
479 #define RK3568_VP0_POST_SCL_CTRL		0xC40
480 #define RK3568_VP0_POST_SCALE_MASK		0x3
481 #define RK3568_VP0_POST_SCALE_SHIFT		0
482 #define RK3568_VP0_POST_DSP_VACT_INFO_F1	0xC44
483 #define RK3568_VP0_DSP_HTOTAL_HS_END		0xC48
484 #define RK3568_VP0_DSP_HACT_ST_END		0xC4C
485 #define RK3568_VP0_DSP_VTOTAL_VS_END		0xC50
486 #define RK3568_VP0_DSP_VACT_ST_END		0xC54
487 #define RK3568_VP0_DSP_VS_ST_END_F1		0xC58
488 #define RK3568_VP0_DSP_VACT_ST_END_F1		0xC5C
489 
490 #define RK3568_VP0_BCSH_CTRL			0xC60
491 #define BCSH_CTRL_Y2R_SHIFT			0
492 #define BCSH_CTRL_Y2R_MASK			0x1
493 #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT		2
494 #define BCSH_CTRL_Y2R_CSC_MODE_MASK		0x3
495 #define BCSH_CTRL_R2Y_SHIFT			4
496 #define BCSH_CTRL_R2Y_MASK			0x1
497 #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT		6
498 #define BCSH_CTRL_R2Y_CSC_MODE_MASK		0x3
499 
500 #define RK3568_VP0_BCSH_BCS			0xC64
501 #define BCSH_BRIGHTNESS_SHIFT			0
502 #define BCSH_BRIGHTNESS_MASK			0xFF
503 #define BCSH_CONTRAST_SHIFT			8
504 #define BCSH_CONTRAST_MASK			0x1FF
505 #define BCSH_SATURATION_SHIFT			20
506 #define BCSH_SATURATION_MASK			0x3FF
507 #define BCSH_OUT_MODE_SHIFT			30
508 #define BCSH_OUT_MODE_MASK			0x3
509 
510 #define RK3568_VP0_BCSH_H			0xC68
511 #define BCSH_SIN_HUE_SHIFT			0
512 #define BCSH_SIN_HUE_MASK			0x1FF
513 #define BCSH_COS_HUE_SHIFT			16
514 #define BCSH_COS_HUE_MASK			0x1FF
515 
516 #define RK3568_VP0_BCSH_COLOR			0xC6C
517 #define BCSH_EN_SHIFT				31
518 #define BCSH_EN_MASK				1
519 
520 #define RK3576_VP0_POST_DITHER_FRC_0		0xCA0
521 #define RK3576_VP0_POST_DITHER_FRC_1		0xCA4
522 #define RK3576_VP0_POST_DITHER_FRC_2		0xCA8
523 
524 #define RK3528_VP0_ACM_CTRL			0xCD0
525 #define POST_CSC_COE00_MASK			0xFFFF
526 #define POST_CSC_COE00_SHIFT			16
527 #define POST_R2Y_MODE_MASK			0x7
528 #define POST_R2Y_MODE_SHIFT			8
529 #define POST_CSC_MODE_MASK			0x7
530 #define POST_CSC_MODE_SHIFT			3
531 #define POST_R2Y_EN_MASK			0x1
532 #define POST_R2Y_EN_SHIFT			2
533 #define POST_CSC_EN_MASK			0x1
534 #define POST_CSC_EN_SHIFT			1
535 #define POST_ACM_BYPASS_EN_MASK			0x1
536 #define POST_ACM_BYPASS_EN_SHIFT		0
537 #define RK3528_VP0_CSC_COE01_02			0xCD4
538 #define RK3528_VP0_CSC_COE10_11			0xCD8
539 #define RK3528_VP0_CSC_COE12_20			0xCDC
540 #define RK3528_VP0_CSC_COE21_22			0xCE0
541 #define RK3528_VP0_CSC_OFFSET0			0xCE4
542 #define RK3528_VP0_CSC_OFFSET1			0xCE8
543 #define RK3528_VP0_CSC_OFFSET2			0xCEC
544 
545 #define RK3562_VP0_MCU_CTRL			0xCF8
546 #define MCU_TYPE_SHIFT				31
547 #define MCU_BYPASS_SHIFT			30
548 #define MCU_RS_SHIFT				29
549 #define MCU_FRAME_ST_SHIFT			28
550 #define MCU_HOLD_MODE_SHIFT			27
551 #define MCU_CLK_SEL_SHIFT			26
552 #define MCU_CLK_SEL_MASK			0x1
553 #define MCU_RW_PEND_SHIFT			20
554 #define MCU_RW_PEND_MASK			0x3F
555 #define MCU_RW_PST_SHIFT			16
556 #define MCU_RW_PST_MASK				0xF
557 #define MCU_CS_PEND_SHIFT			10
558 #define MCU_CS_PEND_MASK			0x3F
559 #define MCU_CS_PST_SHIFT			6
560 #define MCU_CS_PST_MASK				0xF
561 #define MCU_PIX_TOTAL_SHIFT			0
562 #define MCU_PIX_TOTAL_MASK			0x3F
563 
564 #define RK3562_VP0_MCU_RW_BYPASS_PORT		0xCFC
565 #define MCU_WRITE_DATA_BYPASS_SHIFT		0
566 #define MCU_WRITE_DATA_BYPASS_MASK		0xFFFFFFFF
567 
568 #define RK3568_VP1_DSP_CTRL			0xD00
569 #define RK3568_VP1_MIPI_CTRL			0xD04
570 #define RK3568_VP1_COLOR_BAR_CTRL		0xD08
571 #define RK3568_VP1_PRE_SCAN_HTIMING		0xD30
572 #define RK3568_VP1_POST_DSP_HACT_INFO		0xD34
573 #define RK3568_VP1_POST_DSP_VACT_INFO		0xD38
574 #define RK3568_VP1_POST_SCL_FACTOR_YRGB		0xD3C
575 #define RK3568_VP1_POST_SCL_CTRL		0xD40
576 #define RK3568_VP1_DSP_HACT_INFO		0xD34
577 #define RK3568_VP1_DSP_VACT_INFO		0xD38
578 #define RK3568_VP1_POST_DSP_VACT_INFO_F1	0xD44
579 #define RK3568_VP1_DSP_HTOTAL_HS_END		0xD48
580 #define RK3568_VP1_DSP_HACT_ST_END		0xD4C
581 #define RK3568_VP1_DSP_VTOTAL_VS_END		0xD50
582 #define RK3568_VP1_DSP_VACT_ST_END		0xD54
583 #define RK3568_VP1_DSP_VS_ST_END_F1		0xD58
584 #define RK3568_VP1_DSP_VACT_ST_END_F1		0xD5C
585 
586 #define RK3568_VP2_DSP_CTRL			0xE00
587 #define RK3568_VP2_MIPI_CTRL			0xE04
588 #define RK3568_VP2_COLOR_BAR_CTRL		0xE08
589 #define RK3568_VP2_PRE_SCAN_HTIMING		0xE30
590 #define RK3568_VP2_POST_DSP_HACT_INFO		0xE34
591 #define RK3568_VP2_POST_DSP_VACT_INFO		0xE38
592 #define RK3568_VP2_POST_SCL_FACTOR_YRGB		0xE3C
593 #define RK3568_VP2_POST_SCL_CTRL		0xE40
594 #define RK3568_VP2_DSP_HACT_INFO		0xE34
595 #define RK3568_VP2_DSP_VACT_INFO		0xE38
596 #define RK3568_VP2_POST_DSP_VACT_INFO_F1	0xE44
597 #define RK3568_VP2_DSP_HTOTAL_HS_END		0xE48
598 #define RK3568_VP2_DSP_HACT_ST_END		0xE4C
599 #define RK3568_VP2_DSP_VTOTAL_VS_END		0xE50
600 #define RK3568_VP2_DSP_VACT_ST_END		0xE54
601 #define RK3568_VP2_DSP_VS_ST_END_F1		0xE58
602 #define RK3568_VP2_DSP_VACT_ST_END_F1		0xE5C
603 #define RK3568_VP2_BCSH_CTRL			0xE60
604 #define RK3568_VP2_BCSH_BCS			0xE64
605 #define RK3568_VP2_BCSH_H			0xE68
606 #define RK3568_VP2_BCSH_COLOR_BAR		0xE6C
607 #define RK3576_VP2_MCU_CTRL			0xEF8
608 #define RK3576_VP2_MCU_RW_BYPASS_PORT		0xEFC
609 
610 /* Cluster0 register definition */
611 #define RK3568_CLUSTER0_WIN0_CTRL0		0x1000
612 #define CLUSTER_YUV2RGB_EN_SHIFT		8
613 #define CLUSTER_RGB2YUV_EN_SHIFT		9
614 #define CLUSTER_CSC_MODE_SHIFT			10
615 #define CLUSTER_RB_SWAP_SHIFT			14
616 #define CLUSTER_DITHER_UP_EN_SHIFT		18
617 #define RK3568_CLUSTER0_WIN0_CTRL1		0x1004
618 #define RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT	12
619 #define RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT	14
620 #define RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT	14
621 #define AVG2_MASK				0x1
622 #define CLUSTER_AVG2_SHIFT			18
623 #define AVG4_MASK				0x1
624 #define CLUSTER_AVG4_SHIFT			19
625 #define RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT	22
626 #define CLUSTER_XGT_EN_SHIFT			24
627 #define XGT_MODE_MASK				0x3
628 #define CLUSTER_XGT_MODE_SHIFT			25
629 #define CLUSTER_XAVG_EN_SHIFT			27
630 #define CLUSTER_YRGB_GT2_SHIFT			28
631 #define CLUSTER_YRGB_GT4_SHIFT			29
632 #define RK3568_CLUSTER0_WIN0_CTRL2		0x1008
633 #define CLUSTER_AXI_YRGB_ID_MASK		0x1f
634 #define CLUSTER_AXI_YRGB_ID_SHIFT		0
635 #define CLUSTER_AXI_UV_ID_MASK			0x1f
636 #define CLUSTER_AXI_UV_ID_SHIFT			5
637 
638 #define RK3568_CLUSTER0_WIN0_YRGB_MST		0x1010
639 #define RK3568_CLUSTER0_WIN0_CBR_MST		0x1014
640 #define RK3568_CLUSTER0_WIN0_VIR		0x1018
641 #define RK3568_CLUSTER0_WIN0_ACT_INFO		0x1020
642 #define RK3568_CLUSTER0_WIN0_DSP_INFO		0x1024
643 #define RK3568_CLUSTER0_WIN0_DSP_ST		0x1028
644 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB	0x1030
645 #define RK3576_CLUSTER0_WIN0_ZME_CTRL		0x1040
646 #define WIN0_ZME_DERING_EN_SHIFT		3
647 #define WIN0_ZME_GATING_EN_SHIFT		31
648 #define RK3576_CLUSTER0_WIN0_ZME_DERING_PARA	0x1044
649 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE	0x1054
650 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR	0x1058
651 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH	0x105C
652 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE	0x1060
653 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET	0x1064
654 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET	0x1068
655 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL		0x106C
656 #define CLUSTER_AFBCD_HALF_BLOCK_SHIFT		7
657 #define RK3576_CLUSTER0_WIN0_PLD_PTR_OFFSET	0x1078
658 #define RK3576_CLUSTER0_WIN0_PLD_PTR_RANGE	0x107C
659 
660 #define RK3568_CLUSTER0_WIN1_CTRL0		0x1080
661 #define RK3568_CLUSTER0_WIN1_CTRL1		0x1084
662 #define RK3568_CLUSTER0_WIN1_YRGB_MST		0x1090
663 #define RK3568_CLUSTER0_WIN1_CBR_MST		0x1094
664 #define RK3568_CLUSTER0_WIN1_VIR		0x1098
665 #define RK3568_CLUSTER0_WIN1_ACT_INFO		0x10A0
666 #define RK3568_CLUSTER0_WIN1_DSP_INFO		0x10A4
667 #define RK3568_CLUSTER0_WIN1_DSP_ST		0x10A8
668 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB	0x10B0
669 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE	0x10D4
670 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR	0x10D8
671 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH	0x10DC
672 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE	0x10E0
673 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET	0x10E4
674 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET	0x10E8
675 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL		0x10EC
676 #define RK3576_CLUSTER0_WIN1_PLD_PTR_OFFSET	0x10F8
677 #define RK3576_CLUSTER0_WIN1_PLD_PTR_RANGE	0x10FC
678 
679 #define RK3568_CLUSTER0_CTRL			0x1100
680 #define CLUSTER_EN_SHIFT			0
681 #define CLUSTER_AXI_ID_MASK			0x1
682 #define CLUSTER_AXI_ID_SHIFT			13
683 #define RK3576_CLUSTER0_PORT_SEL		0x11F4
684 #define CLUSTER_PORT_SEL_SHIFT			0
685 #define CLUSTER_PORT_SEL_MASK			0x3
686 #define RK3576_CLUSTER0_DLY_NUM			0x11F8
687 #define CLUSTER_WIN0_DLY_NUM_SHIFT		0
688 #define CLUSTER_WIN0_DLY_NUM_MASK		0xff
689 #define CLUSTER_WIN1_DLY_NUM_SHIFT		0
690 #define CLUSTER_WIN1_DLY_NUM_MASK		0xff
691 
692 #define RK3568_CLUSTER1_WIN0_CTRL0		0x1200
693 #define RK3568_CLUSTER1_WIN0_CTRL1		0x1204
694 #define RK3568_CLUSTER1_WIN0_YRGB_MST		0x1210
695 #define RK3568_CLUSTER1_WIN0_CBR_MST		0x1214
696 #define RK3568_CLUSTER1_WIN0_VIR		0x1218
697 #define RK3568_CLUSTER1_WIN0_ACT_INFO		0x1220
698 #define RK3568_CLUSTER1_WIN0_DSP_INFO		0x1224
699 #define RK3568_CLUSTER1_WIN0_DSP_ST		0x1228
700 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB	0x1230
701 #define RK3576_CLUSTER1_WIN0_ZME_CTRL		0x1240
702 #define RK3576_CLUSTER1_WIN0_ZME_DERING_PARA	0x1244
703 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE	0x1254
704 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR	0x1258
705 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH	0x125C
706 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE	0x1260
707 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET	0x1264
708 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET	0x1268
709 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL		0x126C
710 #define RK3576_CLUSTER1_WIN0_PLD_PTR_OFFSET	0x1278
711 #define RK3576_CLUSTER1_WIN0_PLD_PTR_RANGE	0x127C
712 
713 #define RK3568_CLUSTER1_WIN1_CTRL0		0x1280
714 #define RK3568_CLUSTER1_WIN1_CTRL1		0x1284
715 #define RK3568_CLUSTER1_WIN1_YRGB_MST		0x1290
716 #define RK3568_CLUSTER1_WIN1_CBR_MST		0x1294
717 #define RK3568_CLUSTER1_WIN1_VIR		0x1298
718 #define RK3568_CLUSTER1_WIN1_ACT_INFO		0x12A0
719 #define RK3568_CLUSTER1_WIN1_DSP_INFO		0x12A4
720 #define RK3568_CLUSTER1_WIN1_DSP_ST		0x12A8
721 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB	0x12B0
722 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE	0x12D4
723 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR	0x12D8
724 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH	0x12DC
725 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE	0x12E0
726 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET	0x12E4
727 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET	0x12E8
728 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL		0x12EC
729 #define RK3576_CLUSTER1_WIN1_PLD_PTR_OFFSET	0x12F8
730 #define RK3576_CLUSTER1_WIN1_PLD_PTR_RANGE	0x12FC
731 
732 #define RK3568_CLUSTER1_CTRL			0x1300
733 #define RK3576_CLUSTER1_PORT_SEL		0x13F4
734 #define RK3576_CLUSTER1_DLY_NUM			0x13F8
735 
736 /* Esmart register definition */
737 #define RK3568_ESMART0_CTRL0			0x1800
738 #define RGB2YUV_EN_SHIFT			1
739 #define CSC_MODE_SHIFT				2
740 #define CSC_MODE_MASK				0x3
741 #define ESMART_LB_SELECT_SHIFT			12
742 #define ESMART_LB_SELECT_MASK			0x3
743 
744 #define RK3568_ESMART0_CTRL1			0x1804
745 #define ESMART_AXI_YRGB_ID_MASK			0x1f
746 #define ESMART_AXI_YRGB_ID_SHIFT		4
747 #define ESMART_AXI_UV_ID_MASK			0x1f
748 #define ESMART_AXI_UV_ID_SHIFT			12
749 #define YMIRROR_EN_SHIFT			31
750 
751 #define RK3568_ESMART0_AXI_CTRL			0x1808
752 #define ESMART_AXI_ID_MASK			0x1
753 #define ESMART_AXI_ID_SHIFT			1
754 
755 #define RK3568_ESMART0_REGION0_CTRL		0x1810
756 #define WIN_EN_SHIFT				0
757 #define WIN_FORMAT_MASK				0x1f
758 #define WIN_FORMAT_SHIFT			1
759 #define REGION0_DITHER_UP_EN_SHIFT		12
760 #define REGION0_RB_SWAP_SHIFT			14
761 #define ESMART_XAVG_EN_SHIFT			20
762 #define ESMART_XGT_EN_SHIFT			21
763 #define ESMART_XGT_MODE_SHIFT			22
764 
765 #define RK3568_ESMART0_REGION0_YRGB_MST		0x1814
766 #define RK3568_ESMART0_REGION0_CBR_MST		0x1818
767 #define RK3568_ESMART0_REGION0_VIR		0x181C
768 #define RK3568_ESMART0_REGION0_ACT_INFO		0x1820
769 #define RK3568_ESMART0_REGION0_DSP_INFO		0x1824
770 #define RK3568_ESMART0_REGION0_DSP_ST		0x1828
771 #define RK3568_ESMART0_REGION0_SCL_CTRL		0x1830
772 #define YRGB_XSCL_MODE_MASK			0x3
773 #define YRGB_XSCL_MODE_SHIFT			0
774 #define YRGB_XSCL_FILTER_MODE_MASK		0x3
775 #define YRGB_XSCL_FILTER_MODE_SHIFT		2
776 #define YRGB_YSCL_MODE_MASK			0x3
777 #define YRGB_YSCL_MODE_SHIFT			4
778 #define YRGB_YSCL_FILTER_MODE_MASK		0x3
779 #define YRGB_YSCL_FILTER_MODE_SHIFT		6
780 
781 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB	0x1834
782 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR	0x1838
783 #define RK3568_ESMART0_REGION0_SCL_OFFSET	0x183C
784 #define RK3568_ESMART0_REGION1_CTRL		0x1840
785 #define YRGB_GT2_MASK				0x1
786 #define YRGB_GT2_SHIFT				8
787 #define YRGB_GT4_MASK				0x1
788 #define YRGB_GT4_SHIFT				9
789 
790 #define RK3568_ESMART0_REGION1_YRGB_MST		0x1844
791 #define RK3568_ESMART0_REGION1_CBR_MST		0x1848
792 #define RK3568_ESMART0_REGION1_VIR		0x184C
793 #define RK3568_ESMART0_REGION1_ACT_INFO		0x1850
794 #define RK3568_ESMART0_REGION1_DSP_INFO		0x1854
795 #define RK3568_ESMART0_REGION1_DSP_ST		0x1858
796 #define RK3568_ESMART0_REGION1_SCL_CTRL		0x1860
797 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB	0x1864
798 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR	0x1868
799 #define RK3568_ESMART0_REGION1_SCL_OFFSET	0x186C
800 #define RK3568_ESMART0_REGION2_CTRL		0x1870
801 #define RK3568_ESMART0_REGION2_YRGB_MST		0x1874
802 #define RK3568_ESMART0_REGION2_CBR_MST		0x1878
803 #define RK3568_ESMART0_REGION2_VIR		0x187C
804 #define RK3568_ESMART0_REGION2_ACT_INFO		0x1880
805 #define RK3568_ESMART0_REGION2_DSP_INFO		0x1884
806 #define RK3568_ESMART0_REGION2_DSP_ST		0x1888
807 #define RK3568_ESMART0_REGION2_SCL_CTRL		0x1890
808 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB	0x1894
809 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR	0x1898
810 #define RK3568_ESMART0_REGION2_SCL_OFFSET	0x189C
811 #define RK3568_ESMART0_REGION3_CTRL		0x18A0
812 #define RK3568_ESMART0_REGION3_YRGB_MST		0x18A4
813 #define RK3568_ESMART0_REGION3_CBR_MST		0x18A8
814 #define RK3568_ESMART0_REGION3_VIR		0x18AC
815 #define RK3568_ESMART0_REGION3_ACT_INFO		0x18B0
816 #define RK3568_ESMART0_REGION3_DSP_INFO		0x18B4
817 #define RK3568_ESMART0_REGION3_DSP_ST		0x18B8
818 #define RK3568_ESMART0_REGION3_SCL_CTRL		0x18C0
819 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB	0x18C4
820 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR	0x18C8
821 #define RK3568_ESMART0_REGION3_SCL_OFFSET	0x18CC
822 #define RK3568_ESMART0_COLOR_KEY_CTRL		0x18D0
823 #define RK3576_ESMART0_ALPHA_MAP		0x18D8
824 #define RK3576_ESMART0_PORT_SEL			0x18F4
825 #define ESMART_PORT_SEL_SHIFT			0
826 #define ESMART_PORT_SEL_MASK			0x3
827 #define RK3576_ESMART0_DLY_NUM			0x18F8
828 
829 #define RK3568_ESMART1_CTRL0			0x1A00
830 #define RK3568_ESMART1_CTRL1			0x1A04
831 #define RK3568_ESMART1_REGION0_CTRL		0x1A10
832 #define RK3568_ESMART1_REGION0_YRGB_MST		0x1A14
833 #define RK3568_ESMART1_REGION0_CBR_MST		0x1A18
834 #define RK3568_ESMART1_REGION0_VIR		0x1A1C
835 #define RK3568_ESMART1_REGION0_ACT_INFO		0x1A20
836 #define RK3568_ESMART1_REGION0_DSP_INFO		0x1A24
837 #define RK3568_ESMART1_REGION0_DSP_ST		0x1A28
838 #define RK3568_ESMART1_REGION0_SCL_CTRL		0x1A30
839 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB	0x1A34
840 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR	0x1A38
841 #define RK3568_ESMART1_REGION0_SCL_OFFSET	0x1A3C
842 #define RK3568_ESMART1_REGION1_CTRL		0x1A40
843 #define RK3568_ESMART1_REGION1_YRGB_MST		0x1A44
844 #define RK3568_ESMART1_REGION1_CBR_MST		0x1A48
845 #define RK3568_ESMART1_REGION1_VIR		0x1A4C
846 #define RK3568_ESMART1_REGION1_ACT_INFO		0x1A50
847 #define RK3568_ESMART1_REGION1_DSP_INFO		0x1A54
848 #define RK3568_ESMART1_REGION1_DSP_ST		0x1A58
849 #define RK3568_ESMART1_REGION1_SCL_CTRL		0x1A60
850 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB	0x1A64
851 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR	0x1A68
852 #define RK3568_ESMART1_REGION1_SCL_OFFSET	0x1A6C
853 #define RK3568_ESMART1_REGION2_CTRL		0x1A70
854 #define RK3568_ESMART1_REGION2_YRGB_MST		0x1A74
855 #define RK3568_ESMART1_REGION2_CBR_MST		0x1A78
856 #define RK3568_ESMART1_REGION2_VIR		0x1A7C
857 #define RK3568_ESMART1_REGION2_ACT_INFO		0x1A80
858 #define RK3568_ESMART1_REGION2_DSP_INFO		0x1A84
859 #define RK3568_ESMART1_REGION2_DSP_ST		0x1A88
860 #define RK3568_ESMART1_REGION2_SCL_CTRL		0x1A90
861 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB	0x1A94
862 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR	0x1A98
863 #define RK3568_ESMART1_REGION2_SCL_OFFSET	0x1A9C
864 #define RK3568_ESMART1_REGION3_CTRL		0x1AA0
865 #define RK3568_ESMART1_REGION3_YRGB_MST		0x1AA4
866 #define RK3568_ESMART1_REGION3_CBR_MST		0x1AA8
867 #define RK3568_ESMART1_REGION3_VIR		0x1AAC
868 #define RK3568_ESMART1_REGION3_ACT_INFO		0x1AB0
869 #define RK3568_ESMART1_REGION3_DSP_INFO		0x1AB4
870 #define RK3568_ESMART1_REGION3_DSP_ST		0x1AB8
871 #define RK3568_ESMART1_REGION3_SCL_CTRL		0x1AC0
872 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB	0x1AC4
873 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR	0x1AC8
874 #define RK3568_ESMART1_REGION3_SCL_OFFSET	0x1ACC
875 #define RK3576_ESMART1_ALPHA_MAP		0x1AD8
876 #define RK3576_ESMART1_PORT_SEL			0x1AF4
877 #define RK3576_ESMART1_DLY_NUM			0x1AF8
878 
879 #define RK3568_SMART0_CTRL0			0x1C00
880 #define RK3568_SMART0_CTRL1			0x1C04
881 #define RK3568_SMART0_REGION0_CTRL		0x1C10
882 #define RK3568_SMART0_REGION0_YRGB_MST		0x1C14
883 #define RK3568_SMART0_REGION0_CBR_MST		0x1C18
884 #define RK3568_SMART0_REGION0_VIR		0x1C1C
885 #define RK3568_SMART0_REGION0_ACT_INFO		0x1C20
886 #define RK3568_SMART0_REGION0_DSP_INFO		0x1C24
887 #define RK3568_SMART0_REGION0_DSP_ST		0x1C28
888 #define RK3568_SMART0_REGION0_SCL_CTRL		0x1C30
889 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB	0x1C34
890 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR	0x1C38
891 #define RK3568_SMART0_REGION0_SCL_OFFSET	0x1C3C
892 #define RK3568_SMART0_REGION1_CTRL		0x1C40
893 #define RK3568_SMART0_REGION1_YRGB_MST		0x1C44
894 #define RK3568_SMART0_REGION1_CBR_MST		0x1C48
895 #define RK3568_SMART0_REGION1_VIR		0x1C4C
896 #define RK3568_SMART0_REGION1_ACT_INFO		0x1C50
897 #define RK3568_SMART0_REGION1_DSP_INFO		0x1C54
898 #define RK3568_SMART0_REGION1_DSP_ST		0x1C58
899 #define RK3568_SMART0_REGION1_SCL_CTRL		0x1C60
900 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB	0x1C64
901 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR	0x1C68
902 #define RK3568_SMART0_REGION1_SCL_OFFSET	0x1C6C
903 #define RK3568_SMART0_REGION2_CTRL		0x1C70
904 #define RK3568_SMART0_REGION2_YRGB_MST		0x1C74
905 #define RK3568_SMART0_REGION2_CBR_MST		0x1C78
906 #define RK3568_SMART0_REGION2_VIR		0x1C7C
907 #define RK3568_SMART0_REGION2_ACT_INFO		0x1C80
908 #define RK3568_SMART0_REGION2_DSP_INFO		0x1C84
909 #define RK3568_SMART0_REGION2_DSP_ST		0x1C88
910 #define RK3568_SMART0_REGION2_SCL_CTRL		0x1C90
911 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB	0x1C94
912 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR	0x1C98
913 #define RK3568_SMART0_REGION2_SCL_OFFSET	0x1C9C
914 #define RK3568_SMART0_REGION3_CTRL		0x1CA0
915 #define RK3568_SMART0_REGION3_YRGB_MST		0x1CA4
916 #define RK3568_SMART0_REGION3_CBR_MST		0x1CA8
917 #define RK3568_SMART0_REGION3_VIR		0x1CAC
918 #define RK3568_SMART0_REGION3_ACT_INFO		0x1CB0
919 #define RK3568_SMART0_REGION3_DSP_INFO		0x1CB4
920 #define RK3568_SMART0_REGION3_DSP_ST		0x1CB8
921 #define RK3568_SMART0_REGION3_SCL_CTRL		0x1CC0
922 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB	0x1CC4
923 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR	0x1CC8
924 #define RK3568_SMART0_REGION3_SCL_OFFSET	0x1CCC
925 #define RK3576_ESMART2_ALPHA_MAP		0x1CD8
926 #define RK3576_ESMART2_PORT_SEL			0x1CF4
927 #define RK3576_ESMART2_DLY_NUM			0x1CF8
928 
929 #define RK3568_SMART1_CTRL0			0x1E00
930 #define RK3568_SMART1_CTRL1			0x1E04
931 #define RK3568_SMART1_REGION0_CTRL		0x1E10
932 #define RK3568_SMART1_REGION0_YRGB_MST		0x1E14
933 #define RK3568_SMART1_REGION0_CBR_MST		0x1E18
934 #define RK3568_SMART1_REGION0_VIR		0x1E1C
935 #define RK3568_SMART1_REGION0_ACT_INFO		0x1E20
936 #define RK3568_SMART1_REGION0_DSP_INFO		0x1E24
937 #define RK3568_SMART1_REGION0_DSP_ST		0x1E28
938 #define RK3568_SMART1_REGION0_SCL_CTRL		0x1E30
939 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB	0x1E34
940 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR	0x1E38
941 #define RK3568_SMART1_REGION0_SCL_OFFSET	0x1E3C
942 #define RK3568_SMART1_REGION1_CTRL		0x1E40
943 #define RK3568_SMART1_REGION1_YRGB_MST		0x1E44
944 #define RK3568_SMART1_REGION1_CBR_MST		0x1E48
945 #define RK3568_SMART1_REGION1_VIR		0x1E4C
946 #define RK3568_SMART1_REGION1_ACT_INFO		0x1E50
947 #define RK3568_SMART1_REGION1_DSP_INFO		0x1E54
948 #define RK3568_SMART1_REGION1_DSP_ST		0x1E58
949 #define RK3568_SMART1_REGION1_SCL_CTRL		0x1E60
950 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB	0x1E64
951 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR	0x1E68
952 #define RK3568_SMART1_REGION1_SCL_OFFSET	0x1E6C
953 #define RK3568_SMART1_REGION2_CTRL		0x1E70
954 #define RK3568_SMART1_REGION2_YRGB_MST		0x1E74
955 #define RK3568_SMART1_REGION2_CBR_MST		0x1E78
956 #define RK3568_SMART1_REGION2_VIR		0x1E7C
957 #define RK3568_SMART1_REGION2_ACT_INFO		0x1E80
958 #define RK3568_SMART1_REGION2_DSP_INFO		0x1E84
959 #define RK3568_SMART1_REGION2_DSP_ST		0x1E88
960 #define RK3568_SMART1_REGION2_SCL_CTRL		0x1E90
961 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB	0x1E94
962 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR	0x1E98
963 #define RK3568_SMART1_REGION2_SCL_OFFSET	0x1E9C
964 #define RK3568_SMART1_REGION3_CTRL		0x1EA0
965 #define RK3568_SMART1_REGION3_YRGB_MST		0x1EA4
966 #define RK3568_SMART1_REGION3_CBR_MST		0x1EA8
967 #define RK3568_SMART1_REGION3_VIR		0x1EAC
968 #define RK3568_SMART1_REGION3_ACT_INFO		0x1EB0
969 #define RK3568_SMART1_REGION3_DSP_INFO		0x1EB4
970 #define RK3568_SMART1_REGION3_DSP_ST		0x1EB8
971 #define RK3568_SMART1_REGION3_SCL_CTRL		0x1EC0
972 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB	0x1EC4
973 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR	0x1EC8
974 #define RK3568_SMART1_REGION3_SCL_OFFSET	0x1ECC
975 #define RK3576_ESMART3_ALPHA_MAP		0x1ED8
976 #define RK3576_ESMART3_PORT_SEL			0x1EF4
977 #define RK3576_ESMART3_DLY_NUM			0x1EF8
978 
979 /* HDR register definition */
980 #define RK3568_HDR_LUT_CTRL			0x2000
981 
982 #define RK3588_VP3_DSP_CTRL			0xF00
983 #define RK3588_CLUSTER2_WIN0_CTRL0		0x1400
984 #define RK3588_CLUSTER3_WIN0_CTRL0		0x1600
985 
986 /* DSC 8K/4K register definition */
987 #define RK3588_DSC_8K_PPS0_3			0x4000
988 #define RK3588_DSC_8K_CTRL0			0x40A0
989 #define DSC_EN_SHIFT				0
990 #define DSC_RBIT_SHIFT				2
991 #define DSC_RBYT_SHIFT				3
992 #define DSC_FLAL_SHIFT				4
993 #define DSC_MER_SHIFT				5
994 #define DSC_EPB_SHIFT				6
995 #define DSC_EPL_SHIFT				7
996 #define DSC_NSLC_MASK				0x7
997 #define DSC_NSLC_SHIFT				16
998 #define DSC_SBO_SHIFT				28
999 #define DSC_IFEP_SHIFT				29
1000 #define DSC_PPS_UPD_SHIFT			31
1001 #define DSC_CTRL0_DEF_CON ((1 << DSC_EN_SHIFT)   | (1 << DSC_RBIT_SHIFT) | (0 << DSC_RBYT_SHIFT) | \
1002 			   (1 << DSC_FLAL_SHIFT) | (1 << DSC_MER_SHIFT)  | (0 << DSC_EPB_SHIFT)  | \
1003 			   (1 << DSC_EPL_SHIFT)  | (1 << DSC_SBO_SHIFT))
1004 
1005 #define RK3588_DSC_8K_CTRL1			0x40A4
1006 #define RK3588_DSC_8K_STS0			0x40A8
1007 #define RK3588_DSC_8K_ERS			0x40C4
1008 
1009 #define RK3588_DSC_4K_PPS0_3			0x4100
1010 #define RK3588_DSC_4K_CTRL0			0x41A0
1011 #define RK3588_DSC_4K_CTRL1			0x41A4
1012 #define RK3588_DSC_4K_STS0			0x41A8
1013 #define RK3588_DSC_4K_ERS			0x41C4
1014 
1015 /* RK3528 HDR register definition */
1016 #define RK3528_HDR_LUT_CTRL			0x2000
1017 
1018 /* RK3528 ACM register definition */
1019 #define RK3528_ACM_CTRL				0x6400
1020 #define RK3528_ACM_DELTA_RANGE			0x6404
1021 #define RK3528_ACM_FETCH_START			0x6408
1022 #define RK3528_ACM_FETCH_DONE			0x6420
1023 #define RK3528_ACM_YHS_DEL_HY_SEG0		0x6500
1024 #define RK3528_ACM_YHS_DEL_HY_SEG152		0x6760
1025 #define RK3528_ACM_YHS_DEL_HS_SEG0		0x6764
1026 #define RK3528_ACM_YHS_DEL_HS_SEG220		0x6ad4
1027 #define RK3528_ACM_YHS_DEL_HGAIN_SEG0		0x6ad8
1028 #define RK3528_ACM_YHS_DEL_HGAIN_SEG64		0x6bd8
1029 
1030 #define RK3568_IOMMU0_DTE_ADDR			0x7e00
1031 #define RK3568_IOMMU0_STATUS			0x7e04
1032 #define MMU_PAGING_EN				BIT(0)
1033 #define MMU_PAGE_FAULT_ACTIVE			BIT(1)
1034 #define RK3568_IOMMU0_COMMAND			0x7e08
1035 #define MMU_ENABLE_PAGING			0
1036 #define MMU_DISABLE_PAGING			1
1037 #define MMU_FORCE_RESET				6
1038 #define RK3568_IOMMU0_PAGEFAULT_ADDR		0x7e0c
1039 
1040 /* RK3576 SHARP register definition */
1041 #define RK3576_SHARP_CTRL			0x0000
1042 #define SW_SHARP_ENABLE_SHIFT			0
1043 
1044 #define RK3568_MAX_REG				0x1ED0
1045 
1046 #define RK3562_GRF_IOC_VO_IO_CON		0x10500
1047 #define RK3568_GRF_VO_CON1			0x0364
1048 #define GRF_BT656_CLK_INV_SHIFT			1
1049 #define GRF_BT1120_CLK_INV_SHIFT		2
1050 #define GRF_RGB_DCLK_INV_SHIFT			3
1051 
1052 /* Base SYS_GRF: 0x2600a000*/
1053 #define RK3576_SYS_GRF_MEMFAULT_STATUS0		0x0148
1054 
1055 /* Base IOC_GRF: 0x26040000 */
1056 #define RK3576_VCCIO_IOC_MISC_CON8		0x6420
1057 #define RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT	9
1058 #define RK3576_IOC_VOPLITE_SEL_SHIFT		11
1059 
1060 /* Base PMU2: 0x27380000 */
1061 #define RK3576_PMU_PWR_GATE_STS			0x0230
1062 #define PD_VOP_ESMART_DWN_STAT			12
1063 #define PD_VOP_CLUSTER_DWN_STAT			13
1064 #define RK3576_PMU_BISR_PDGEN_CON0		0x0510
1065 #define PD_VOP_ESMART_REPAIR_ENA_SHIFT		12
1066 #define PD_VOP_CLUSTER_REPAIR_ENA_SHIFT		13
1067 #define RK3576_PMU_BISR_PWR_REPAIR_STATUS0	0x0570
1068 #define PD_VOP_ESMART_PWR_REPAIR_STAT_SHIFT	12
1069 #define PD_VOP_CLUSTER_PWR_REPAIR_STAT_SHIFT	13
1070 
1071 #define RK3588_GRF_SOC_CON1			0x0304
1072 #define RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT	14
1073 
1074 #define RK3588_GRF_VOP_CON2			0x0008
1075 #define RK3588_GRF_EDP0_ENABLE_SHIFT		0
1076 #define RK3588_GRF_HDMITX0_ENABLE_SHIFT		1
1077 #define RK3588_GRF_HDMITX0_COMPRESS_MODE_SHIFT	2
1078 #define RK3588_GRF_EDP1_ENABLE_SHIFT		3
1079 #define RK3588_GRF_HDMITX1_ENABLE_SHIFT		4
1080 #define RK3588_GRF_HDMITX1_COMPRESS_MODE_SHIFT	5
1081 
1082 #define RK3588_GRF_VO1_CON0			0x0000
1083 #define HDMI_SYNC_POL_MASK			0x3
1084 #define HDMI0_SYNC_POL_SHIFT			5
1085 #define HDMI1_SYNC_POL_SHIFT			7
1086 
1087 #define RK3588_PMU_BISR_CON3			0x20C
1088 #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT	9
1089 #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT	10
1090 #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT	11
1091 #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT	12
1092 #define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT	13
1093 #define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT	14
1094 #define RK3588_PD_ESMART_REPAIR_EN_SHIFT	15
1095 
1096 #define RK3588_PMU_BISR_STATUS5			0x294
1097 #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI	9
1098 #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI	10
1099 #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI	11
1100 #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI	12
1101 #define RK3588_PD_DSC_8K_PWR_STAT_SHIFI		13
1102 #define RK3588_PD_DSC_4K_PWR_STAT_SHIFI		14
1103 #define RK3588_PD_ESMART_PWR_STAT_SHIFI		15
1104 
1105 #define VOP2_LAYER_MAX				8
1106 
1107 #define VOP2_MAX_VP_OUTPUT_WIDTH		4096
1108 
1109 /* KHz */
1110 #define VOP2_MAX_DCLK_RATE			600000
1111 
1112 /*
1113  * vop2 dsc id
1114  */
1115 #define ROCKCHIP_VOP2_DSC_8K	0
1116 #define ROCKCHIP_VOP2_DSC_4K	1
1117 
1118 /*
1119  * vop2 internal power domain id,
1120  * should be all none zero, 0 will be
1121  * treat as invalid;
1122  */
1123 #define VOP2_PD_CLUSTER0			BIT(0)
1124 #define VOP2_PD_CLUSTER1			BIT(1)
1125 #define VOP2_PD_CLUSTER2			BIT(2)
1126 #define VOP2_PD_CLUSTER3			BIT(3)
1127 #define VOP2_PD_DSC_8K				BIT(5)
1128 #define VOP2_PD_DSC_4K				BIT(6)
1129 #define VOP2_PD_ESMART				BIT(7)
1130 #define VOP2_PD_CLUSTER				BIT(8)
1131 
1132 #define VOP2_PLANE_NO_SCALING			BIT(16)
1133 
1134 #define VOP_FEATURE_OUTPUT_10BIT	BIT(0)
1135 #define VOP_FEATURE_AFBDC		BIT(1)
1136 #define VOP_FEATURE_ALPHA_SCALE		BIT(2)
1137 #define VOP_FEATURE_HDR10		BIT(3)
1138 #define VOP_FEATURE_NEXT_HDR		BIT(4)
1139 /* a feature to splice two windows and two vps to support resolution > 4096 */
1140 #define VOP_FEATURE_SPLICE		BIT(5)
1141 #define VOP_FEATURE_OVERSCAN		BIT(6)
1142 #define VOP_FEATURE_VIVID_HDR		BIT(7)
1143 #define VOP_FEATURE_POST_ACM		BIT(8)
1144 #define VOP_FEATURE_POST_CSC		BIT(9)
1145 #define VOP_FEATURE_POST_FRC_V2		BIT(10)
1146 #define VOP_FEATURE_POST_SHARP		BIT(11)
1147 
1148 #define WIN_FEATURE_HDR2SDR		BIT(0)
1149 #define WIN_FEATURE_SDR2HDR		BIT(1)
1150 #define WIN_FEATURE_PRE_OVERLAY		BIT(2)
1151 #define WIN_FEATURE_AFBDC		BIT(3)
1152 #define WIN_FEATURE_CLUSTER_MAIN	BIT(4)
1153 #define WIN_FEATURE_CLUSTER_SUB		BIT(5)
1154 /* a mirror win can only get fb address
1155  * from source win:
1156  * Cluster1---->Cluster0
1157  * Esmart1 ---->Esmart0
1158  * Smart1  ---->Smart0
1159  * This is a feather on rk3566
1160  */
1161 #define WIN_FEATURE_MIRROR		BIT(6)
1162 #define WIN_FEATURE_MULTI_AREA		BIT(7)
1163 #define WIN_FEATURE_Y2R_13BIT_DEPTH	BIT(8)
1164 #define WIN_FEATURE_DCI			BIT(9)
1165 
1166 #define V4L2_COLORSPACE_BT709F		0xfe
1167 #define V4L2_COLORSPACE_BT2020F		0xff
1168 
1169 enum vop_csc_format {
1170 	CSC_BT601L,
1171 	CSC_BT709L,
1172 	CSC_BT601F,
1173 	CSC_BT2020L,
1174 	CSC_BT709L_13BIT,
1175 	CSC_BT709F_13BIT,
1176 	CSC_BT2020L_13BIT,
1177 	CSC_BT2020F_13BIT,
1178 };
1179 
1180 enum vop_csc_bit_depth {
1181 	CSC_10BIT_DEPTH,
1182 	CSC_13BIT_DEPTH,
1183 };
1184 
1185 enum vop2_pol {
1186 	HSYNC_POSITIVE = 0,
1187 	VSYNC_POSITIVE = 1,
1188 	DEN_NEGATIVE   = 2,
1189 	DCLK_INVERT    = 3
1190 };
1191 
1192 enum vop2_bcsh_out_mode {
1193 	BCSH_OUT_MODE_BLACK,
1194 	BCSH_OUT_MODE_BLUE,
1195 	BCSH_OUT_MODE_COLOR_BAR,
1196 	BCSH_OUT_MODE_NORMAL_VIDEO,
1197 };
1198 
1199 #define _VOP_REG(off, _mask, _shift, _write_mask) \
1200 		{ \
1201 		 .offset = off, \
1202 		 .mask = _mask, \
1203 		 .shift = _shift, \
1204 		 .write_mask = _write_mask, \
1205 		}
1206 
1207 #define VOP_REG(off, _mask, _shift) \
1208 		_VOP_REG(off, _mask, _shift, false)
1209 enum dither_down_mode {
1210 	RGB888_TO_RGB565 = 0x0,
1211 	RGB888_TO_RGB666 = 0x1
1212 };
1213 
1214 enum dither_down_mode_sel {
1215 	DITHER_DOWN_ALLEGRO = 0x0,
1216 	DITHER_DOWN_FRC = 0x1
1217 };
1218 
1219 enum vop2_video_ports_id {
1220 	VOP2_VP0,
1221 	VOP2_VP1,
1222 	VOP2_VP2,
1223 	VOP2_VP3,
1224 	VOP2_VP_MAX,
1225 };
1226 
1227 enum vop2_layer_type {
1228 	CLUSTER_LAYER = 0,
1229 	ESMART_LAYER = 1,
1230 	SMART_LAYER = 2,
1231 };
1232 
1233 enum vop2_plane_type {
1234 	VOP2_PLANE_TYPE_OVERLAY = 0,
1235 	VOP2_PLANE_TYPE_PRIMARY = 1,
1236 	VOP2_PLANE_TYPE_CURSOR = 2,
1237 };
1238 
1239 /* This define must same with kernel win phy id */
1240 enum vop2_layer_phy_id {
1241 	ROCKCHIP_VOP2_CLUSTER0 = 0,
1242 	ROCKCHIP_VOP2_CLUSTER1,
1243 	ROCKCHIP_VOP2_ESMART0,
1244 	ROCKCHIP_VOP2_ESMART1,
1245 	ROCKCHIP_VOP2_SMART0,
1246 	ROCKCHIP_VOP2_SMART1,
1247 	ROCKCHIP_VOP2_CLUSTER2,
1248 	ROCKCHIP_VOP2_CLUSTER3,
1249 	ROCKCHIP_VOP2_ESMART2,
1250 	ROCKCHIP_VOP2_ESMART3,
1251 	ROCKCHIP_VOP2_LAYER_MAX,
1252 	ROCKCHIP_VOP2_PHY_ID_INVALID = (u8)-1,
1253 };
1254 
1255 enum vop2_scale_up_mode {
1256 	VOP2_SCALE_UP_NRST_NBOR,
1257 	VOP2_SCALE_UP_BIL,
1258 	VOP2_SCALE_UP_BIC,
1259 	VOP2_SCALE_UP_ZME,
1260 };
1261 
1262 enum vop2_scale_down_mode {
1263 	VOP2_SCALE_DOWN_NRST_NBOR,
1264 	VOP2_SCALE_DOWN_BIL,
1265 	VOP2_SCALE_DOWN_AVG,
1266 	VOP2_SCALE_DOWN_ZME,
1267 };
1268 
1269 enum scale_mode {
1270 	SCALE_NONE = 0x0,
1271 	SCALE_UP   = 0x1,
1272 	SCALE_DOWN = 0x2
1273 };
1274 
1275 enum vop_dsc_interface_mode {
1276 	VOP_DSC_IF_DISABLE = 0,
1277 	VOP_DSC_IF_HDMI = 1,
1278 	VOP_DSC_IF_MIPI_DS_MODE = 2,
1279 	VOP_DSC_IF_MIPI_VIDEO_MODE = 3,
1280 };
1281 
1282 enum vop3_pre_scale_down_mode {
1283 	VOP3_PRE_SCALE_UNSPPORT,
1284 	VOP3_PRE_SCALE_DOWN_GT,
1285 	VOP3_PRE_SCALE_DOWN_AVG,
1286 };
1287 
1288 /*
1289  *  the delay number of a window in different mode.
1290  */
1291 enum vop2_win_dly_mode {
1292 	VOP2_DLY_MODE_DEFAULT,		/* default mode */
1293 	VOP2_DLY_MODE_HISO_S,		/* HDR in SDR out mode, as a SDR window */
1294 	VOP2_DLY_MODE_HIHO_H,		/* HDR in HDR out mode, as a HDR window */
1295 	VOP2_DLY_MODE_DOVI_IN_CORE1,	/* dovi video input, as dovi core1 */
1296 	VOP2_DLY_MODE_DOVI_IN_CORE2,	/* dovi video input, as dovi core2 */
1297 	VOP2_DLY_MODE_NONDOVI_IN_CORE1,	/* ndovi video input, as dovi core1 */
1298 	VOP2_DLY_MODE_NONDOVI_IN_CORE2,	/* ndovi video input, as dovi core2 */
1299 	VOP2_DLY_MODE_MAX,
1300 };
1301 
1302 enum vop3_esmart_lb_mode {
1303 	VOP3_ESMART_8K_MODE,
1304 	VOP3_ESMART_4K_4K_MODE,
1305 	VOP3_ESMART_4K_2K_2K_MODE,
1306 	VOP3_ESMART_2K_2K_2K_2K_MODE,
1307 	VOP3_ESMART_4K_4K_4K_MODE,
1308 	VOP3_ESMART_4K_4K_2K_2K_MODE,
1309 };
1310 
1311 struct vop2_layer {
1312 	u8 id;
1313 	/**
1314 	 * @win_phys_id: window id of the layer selected.
1315 	 * Every layer must make sure to select different
1316 	 * windows of others.
1317 	 */
1318 	u8 win_phys_id;
1319 };
1320 
1321 struct vop2_power_domain_data {
1322 	u16 id;
1323 	u16 parent_id;
1324 	/*
1325 	 * @module_id_mask: module id of which module this power domain is belongs to.
1326 	 * PD_CLUSTER0,1,2,3 only belongs to CLUSTER0/1/2/3, PD_Esmart0 shared by Esmart1/2/3
1327 	 */
1328 	u32 module_id_mask;
1329 };
1330 
1331 struct vop2_win_data {
1332 	char *name;
1333 	u8 phys_id;
1334 	enum vop2_layer_type type;
1335 	enum vop2_plane_type plane_type;
1336 	u8 win_sel_port_offset;
1337 	u8 layer_sel_win_id[VOP2_VP_MAX];
1338 	u8 axi_id;
1339 	u8 axi_uv_id;
1340 	u8 axi_yrgb_id;
1341 	u8 splice_win_id;
1342 	u8 hsu_filter_mode;
1343 	u8 hsd_filter_mode;
1344 	u8 vsu_filter_mode;
1345 	u8 vsd_filter_mode;
1346 	u8 hsd_pre_filter_mode;
1347 	u8 vsd_pre_filter_mode;
1348 	u8 scale_engine_num;
1349 	u8 source_win_id;
1350 	u8 possible_vp_mask;
1351 	u8 dly[VOP2_DLY_MODE_MAX];
1352 	u16 pd_id;
1353 	u32 reg_offset;
1354 	u32 max_upscale_factor;
1355 	u32 max_downscale_factor;
1356 	u32 feature;
1357 	u32 supported_rotations;
1358 	bool splice_mode_right;
1359 };
1360 
1361 struct vop2_vp_data {
1362 	u32 feature;
1363 	u32 max_dclk;
1364 	u8 pre_scan_max_dly;
1365 	u8 layer_mix_dly;
1366 	u8 hdrvivid_dly;
1367 	u8 sdr2hdr_dly;
1368 	u8 hdr_mix_dly;
1369 	u8 win_dly;
1370 	u8 splice_vp_id;
1371 	u8 pixel_rate;
1372 	struct vop_rect max_output;
1373 	struct vop_urgency *urgency;
1374 };
1375 
1376 struct vop2_vp_plane_mask {
1377 	u8 primary_plane_id; /* use this win to show logo */
1378 	u8 cursor_plane_id;
1379 	u8 attached_layers_nr; /* number layers attach to this vp */
1380 	u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */
1381 	u32 plane_mask;
1382 };
1383 
1384 struct vop2_dsc_data {
1385 	u8 id;
1386 	u8 max_slice_num;
1387 	u8 max_linebuf_depth;	/* used to generate the bitstream */
1388 	u8 min_bits_per_pixel;	/* bit num after encoder compress */
1389 	u16 pd_id;
1390 	const char *dsc_txp_clk_src_name;
1391 	const char *dsc_txp_clk_name;
1392 	const char *dsc_pxl_clk_name;
1393 	const char *dsc_cds_clk_name;
1394 };
1395 
1396 struct dsc_error_info {
1397 	u32 dsc_error_val;
1398 	char dsc_error_info[50];
1399 };
1400 
1401 struct vop2_dump_regs {
1402 	u32 offset;
1403 	const char *name;
1404 	u32 state_base;
1405 	u32 state_mask;
1406 	u32 state_shift;
1407 	bool enable_state;
1408 	u32 size;
1409 };
1410 
1411 struct vop2_esmart_lb_map {
1412 	u8 lb_mode;
1413 	u8 lb_map_value;
1414 };
1415 
1416 /**
1417 * struct vop2_ops - helper operations for vop2 hardware
1418 *
1419 * These hooks are used by the common part of the vop2 driver to
1420 * implement the proper behaviour of different variants.
1421 */
1422 struct vop2_ops {
1423 	void (*setup_win_dly)(struct display_state *state, int crtc_id, u8 plane_phy_id);
1424 	void (*setup_overlay)(struct display_state *state);
1425 	void (*assign_plane_mask)(struct display_state *state);
1426 };
1427 
1428 struct vop2_data {
1429 	u32 version;
1430 	u32 esmart_lb_mode;
1431 	struct vop2_vp_data *vp_data;
1432 	struct vop2_win_data *win_data;
1433 	struct vop2_vp_plane_mask *plane_mask;
1434 	struct vop2_power_domain_data *pd;
1435 	struct vop2_dsc_data *dsc;
1436 	struct dsc_error_info *dsc_error_ecw;
1437 	struct dsc_error_info *dsc_error_buffer_flow;
1438 	struct vop2_dump_regs *dump_regs;
1439 	const struct vop2_esmart_lb_map *esmart_lb_mode_map;
1440 	const struct vop2_ops *ops;
1441 	u8 nr_vps;
1442 	u8 nr_layers;
1443 	u8 nr_mixers;
1444 	u8 nr_gammas;
1445 	u8 nr_pd;
1446 	u8 nr_dscs;
1447 	u8 nr_dsc_ecw;
1448 	u8 nr_dsc_buffer_flow;
1449 	u8 esmart_lb_mode_num;
1450 	u32 reg_len;
1451 	u32 dump_regs_size;
1452 	u32 plane_mask_base;
1453 };
1454 
1455 struct vop2 {
1456 	u32 *regsbak;
1457 	void *regs;
1458 	void *grf;
1459 	void *vop_grf;
1460 	void *vo1_grf;
1461 	void *sys_pmu;
1462 	void *ioc_grf;
1463 	void *sharp_res;
1464 	u32 reg_len;
1465 	u32 version;
1466 	u32 esmart_lb_mode;
1467 	bool global_init;
1468 	bool merge_irq;
1469 	const struct vop2_data *data;
1470 	struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX];
1471 };
1472 
1473 static struct vop2 *rockchip_vop2;
1474 
1475 /* vop2_layer_phy_id */
1476 static const char *const vop2_layer_name_list[] = {
1477 	"Cluster0",
1478 	"Cluster1",
1479 	"Esmart0",
1480 	"Esmart1",
1481 	"Smart0",
1482 	"Smart1",
1483 	"Cluster2",
1484 	"Cluster3",
1485 	"Esmart2",
1486 	"Esmart3",
1487 };
1488 
1489 static inline const char *vop2_plane_phys_id_to_string(u8 phys_id)
1490 {
1491 	if (phys_id == ROCKCHIP_VOP2_PHY_ID_INVALID)
1492 		return "INVALID";
1493 
1494 	if (phys_id >= ARRAY_SIZE(vop2_layer_name_list))
1495 		return NULL;
1496 
1497 	return vop2_layer_name_list[phys_id];
1498 }
1499 
1500 static inline bool is_vop3(struct vop2 *vop2)
1501 {
1502 	if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588)
1503 		return false;
1504 	else
1505 		return true;
1506 }
1507 
1508 /*
1509  * bli_sd_factor = (src - 1) / (dst - 1) << 12;
1510  * avg_sd_factor:
1511  * bli_su_factor:
1512  * bic_su_factor:
1513  * = (src - 1) / (dst - 1) << 16;
1514  *
1515  * ygt2 enable: dst get one line from two line of the src
1516  * ygt4 enable: dst get one line from four line of the src.
1517  *
1518  */
1519 #define VOP2_BILI_SCL_DN(src, dst)	(((src - 1) << 12) / (dst - 1))
1520 #define VOP2_COMMON_SCL(src, dst)	(((src - 1) << 16) / (dst - 1))
1521 
1522 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)	 \
1523 				(fac * (dst - 1) >> 12 < (src - 1))
1524 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \
1525 				(fac * (dst - 1) >> 16 < (src - 1))
1526 #define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \
1527 				(fac * (dst - 1) >> 16 < (src - 1))
1528 
1529 static uint16_t vop2_scale_factor(enum scale_mode mode,
1530 				  int32_t filter_mode,
1531 				  uint32_t src, uint32_t dst)
1532 {
1533 	uint32_t fac = 0;
1534 	int i = 0;
1535 
1536 	if (mode == SCALE_NONE)
1537 		return 0;
1538 
1539 	/*
1540 	 * A workaround to avoid zero div.
1541 	 */
1542 	if ((dst == 1) || (src == 1)) {
1543 		dst = dst + 1;
1544 		src = src + 1;
1545 	}
1546 
1547 	if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) {
1548 		fac = VOP2_BILI_SCL_DN(src, dst);
1549 		for (i = 0; i < 100; i++) {
1550 			if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
1551 				break;
1552 			fac -= 1;
1553 			printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1554 		}
1555 	} else {
1556 		fac = VOP2_COMMON_SCL(src, dst);
1557 		for (i = 0; i < 100; i++) {
1558 			if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac))
1559 				break;
1560 			fac -= 1;
1561 			printf("up fac cali:  src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1562 		}
1563 	}
1564 
1565 	return fac;
1566 }
1567 
1568 static bool vop3_scale_up_fac_check(uint32_t src, uint32_t dst, uint32_t fac, bool is_hor)
1569 {
1570 	if (is_hor)
1571 		return VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac);
1572 	return VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac);
1573 }
1574 
1575 static uint16_t vop3_scale_factor(enum scale_mode mode,
1576 				  uint32_t src, uint32_t dst, bool is_hor)
1577 {
1578 	uint32_t fac = 0;
1579 	int i = 0;
1580 
1581 	if (mode == SCALE_NONE)
1582 		return 0;
1583 
1584 	/*
1585 	 * A workaround to avoid zero div.
1586 	 */
1587 	if ((dst == 1) || (src == 1)) {
1588 		dst = dst + 1;
1589 		src = src + 1;
1590 	}
1591 
1592 	if (mode == SCALE_DOWN) {
1593 		fac = VOP2_BILI_SCL_DN(src, dst);
1594 		for (i = 0; i < 100; i++) {
1595 			if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
1596 				break;
1597 			fac -= 1;
1598 			printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1599 		}
1600 	} else {
1601 		fac = VOP2_COMMON_SCL(src, dst);
1602 		for (i = 0; i < 100; i++) {
1603 			if (vop3_scale_up_fac_check(src, dst, fac, is_hor))
1604 				break;
1605 			fac -= 1;
1606 			printf("up fac cali:  src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1607 		}
1608 	}
1609 
1610 	return fac;
1611 }
1612 
1613 static inline enum scale_mode scl_get_scl_mode(int src, int dst)
1614 {
1615 	if (src < dst)
1616 		return SCALE_UP;
1617 	else if (src > dst)
1618 		return SCALE_DOWN;
1619 
1620 	return SCALE_NONE;
1621 }
1622 
1623 static inline int interpolate(int x1, int y1, int x2, int y2, int x)
1624 {
1625 	return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
1626 }
1627 
1628 static inline bool vop2_win_can_attach_to_vp(struct vop2_win_data *win_data, u8 vp_id)
1629 {
1630 	return win_data->possible_vp_mask & BIT(vp_id);
1631 }
1632 
1633 static int vop2_vp_find_attachable_win(struct display_state *state, u8 vp_id)
1634 {
1635 	struct crtc_state *cstate = &state->crtc_state;
1636 	struct vop2 *vop2 = cstate->private;
1637 	u32 plane_mask = cstate->crtc->vps[vp_id].plane_mask;
1638 	int i = 0;
1639 
1640 	if (!plane_mask)
1641 		return ROCKCHIP_VOP2_PHY_ID_INVALID;
1642 
1643 	for (i = 0; i < vop2->data->nr_layers; i++) {
1644 		if (vop2_win_can_attach_to_vp(&vop2->data->win_data[i], vp_id))
1645 			break;
1646 	}
1647 
1648 	return vop2->data->win_data[i].phys_id;
1649 }
1650 
1651 static inline u16 scl_cal_scale(int src, int dst, int shift)
1652 {
1653 	return ((src * 2 - 3) << (shift - 1)) / (dst - 1);
1654 }
1655 
1656 static inline u16 scl_cal_scale2(int src, int dst)
1657 {
1658 	return ((src - 1) << 12) / (dst - 1);
1659 }
1660 
1661 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
1662 {
1663 	writel(v, vop2->regs + offset);
1664 	vop2->regsbak[offset >> 2] = v;
1665 }
1666 
1667 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
1668 {
1669 	return readl(vop2->regs + offset);
1670 }
1671 
1672 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset,
1673 				   u32 mask, u32 shift, u32 v,
1674 				   bool write_mask)
1675 {
1676 	if (!mask)
1677 		return;
1678 
1679 	if (write_mask) {
1680 		v = ((v & mask) << shift) | (mask << (shift + 16));
1681 	} else {
1682 		u32 cached_val = vop2->regsbak[offset >> 2];
1683 
1684 		v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
1685 		vop2->regsbak[offset >> 2] = v;
1686 	}
1687 
1688 	writel(v, vop2->regs + offset);
1689 }
1690 
1691 static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset,
1692 				   u32 mask, u32 shift, u32 v)
1693 {
1694 	u32 val = 0;
1695 
1696 	val = (v << shift) | (mask << (shift + 16));
1697 	writel(val, grf_base + offset);
1698 }
1699 
1700 static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset,
1701 				  u32 mask, u32 shift)
1702 {
1703 	return (readl(grf_base + offset) >> shift) & mask;
1704 }
1705 
1706 static bool is_yuv_output(u32 bus_format)
1707 {
1708 	switch (bus_format) {
1709 	case MEDIA_BUS_FMT_YUV8_1X24:
1710 	case MEDIA_BUS_FMT_YUV10_1X30:
1711 	case MEDIA_BUS_FMT_YUYV10_1X20:
1712 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1713 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1714 	case MEDIA_BUS_FMT_YUYV8_2X8:
1715 	case MEDIA_BUS_FMT_YVYU8_2X8:
1716 	case MEDIA_BUS_FMT_UYVY8_2X8:
1717 	case MEDIA_BUS_FMT_VYUY8_2X8:
1718 	case MEDIA_BUS_FMT_YUYV8_1X16:
1719 	case MEDIA_BUS_FMT_YVYU8_1X16:
1720 	case MEDIA_BUS_FMT_UYVY8_1X16:
1721 	case MEDIA_BUS_FMT_VYUY8_1X16:
1722 		return true;
1723 	default:
1724 		return false;
1725 	}
1726 }
1727 
1728 static enum vop_csc_format vop2_convert_csc_mode(enum drm_color_encoding color_encoding,
1729 						 enum drm_color_range color_range,
1730 						 int bit_depth)
1731 {
1732 	bool full_range = color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
1733 	enum vop_csc_format csc_mode = CSC_BT709L;
1734 
1735 
1736 	switch (color_encoding) {
1737 	case DRM_COLOR_YCBCR_BT601:
1738 		if (full_range)
1739 			csc_mode = CSC_BT601F;
1740 		else
1741 			csc_mode = CSC_BT601L;
1742 		break;
1743 
1744 	case DRM_COLOR_YCBCR_BT709:
1745 		if (full_range) {
1746 			csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT709F_13BIT : CSC_BT601F;
1747 			if (bit_depth != CSC_13BIT_DEPTH)
1748 				printf("Unsupported bt709f at 10bit csc depth, use bt601f instead\n");
1749 		} else {
1750 			csc_mode = CSC_BT709L;
1751 		}
1752 		break;
1753 
1754 	case DRM_COLOR_YCBCR_BT2020:
1755 		if (full_range) {
1756 			csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT2020F_13BIT : CSC_BT601F;
1757 			if (bit_depth != CSC_13BIT_DEPTH)
1758 				printf("Unsupported bt2020f at 10bit csc depth, use bt601f instead\n");
1759 		} else {
1760 			csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT2020L_13BIT : CSC_BT2020L;
1761 		}
1762 		break;
1763 
1764 	default:
1765 		printf("Unsuport color_encoding:%d\n", color_encoding);
1766 	}
1767 
1768 	return csc_mode;
1769 }
1770 
1771 static bool is_uv_swap(struct display_state *state)
1772 {
1773 	struct connector_state *conn_state = &state->conn_state;
1774 	u32 bus_format = conn_state->bus_format;
1775 	u32 output_mode = conn_state->output_mode;
1776 	u32 output_type = conn_state->type;
1777 
1778 	/*
1779 	 * FIXME:
1780 	 *
1781 	 * There is no media type for YUV444 output,
1782 	 * so when out_mode is AAAA or P888, assume output is YUV444 on
1783 	 * yuv format.
1784 	 *
1785 	 * From H/W testing, YUV444 mode need a rb swap except eDP.
1786 	 */
1787 	if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
1788 	    bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
1789 	    bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
1790 	    bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
1791 	    ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
1792 	     bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
1793 	    (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
1794 	     output_mode == ROCKCHIP_OUT_MODE_P888) &&
1795 	     !(output_type == DRM_MODE_CONNECTOR_eDP)))
1796 		return true;
1797 	else
1798 		return false;
1799 }
1800 
1801 static bool is_rb_swap(struct display_state *state)
1802 {
1803 	struct connector_state *conn_state = &state->conn_state;
1804 	u32 bus_format = conn_state->bus_format;
1805 
1806 	/*
1807 	 * The default component order of serial rgb3x8 formats
1808 	 * is BGR. So it is needed to enable RB swap.
1809 	 */
1810 	if (bus_format == MEDIA_BUS_FMT_RGB888_3X8 ||
1811 	    bus_format == MEDIA_BUS_FMT_RGB888_DUMMY_4X8)
1812 		return true;
1813 	else
1814 		return false;
1815 }
1816 
1817 static bool is_yc_swap(u32 bus_format)
1818 {
1819 	switch (bus_format) {
1820 	case MEDIA_BUS_FMT_YUYV8_1X16:
1821 	case MEDIA_BUS_FMT_YVYU8_1X16:
1822 	case MEDIA_BUS_FMT_YUYV8_2X8:
1823 	case MEDIA_BUS_FMT_YVYU8_2X8:
1824 		return true;
1825 	default:
1826 		return false;
1827 	}
1828 }
1829 
1830 static inline bool is_hot_plug_devices(int output_type)
1831 {
1832 	switch (output_type) {
1833 	case DRM_MODE_CONNECTOR_HDMIA:
1834 	case DRM_MODE_CONNECTOR_HDMIB:
1835 	case DRM_MODE_CONNECTOR_TV:
1836 	case DRM_MODE_CONNECTOR_DisplayPort:
1837 	case DRM_MODE_CONNECTOR_VGA:
1838 	case DRM_MODE_CONNECTOR_Unknown:
1839 		return true;
1840 	default:
1841 		return false;
1842 	}
1843 }
1844 
1845 static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id)
1846 {
1847 	int i = 0;
1848 
1849 	for (i = 0; i < vop2->data->nr_layers; i++) {
1850 		if (vop2->data->win_data[i].phys_id == phys_id)
1851 			return &vop2->data->win_data[i];
1852 	}
1853 
1854 	return NULL;
1855 }
1856 
1857 static struct vop2_power_domain_data *vop2_find_pd_data_by_id(struct vop2 *vop2, int pd_id)
1858 {
1859 	int i = 0;
1860 
1861 	for (i = 0; i < vop2->data->nr_pd; i++) {
1862 		if (vop2->data->pd[i].id == pd_id)
1863 			return &vop2->data->pd[i];
1864 	}
1865 
1866 	return NULL;
1867 }
1868 
1869 static void rk3568_vop2_load_lut(struct vop2 *vop2, int crtc_id,
1870 				 u32 *lut_regs, u32 *lut_val, int lut_len)
1871 {
1872 	u32 vp_offset = crtc_id * 0x100;
1873 	int i;
1874 
1875 	vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1876 			GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT,
1877 			crtc_id, false);
1878 
1879 	for (i = 0; i < lut_len; i++)
1880 		writel(lut_val[i], lut_regs + i);
1881 
1882 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1883 			EN_MASK, DSP_LUT_EN_SHIFT, 1, false);
1884 }
1885 
1886 static void rk3588_vop2_load_lut(struct vop2 *vop2, int crtc_id,
1887 				 u32 *lut_regs, u32 *lut_val, int lut_len)
1888 {
1889 	u32 vp_offset = crtc_id * 0x100;
1890 	int i;
1891 
1892 	if (vop2->version == VOP_VERSION_RK3576)
1893 		vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1894 				GAMMA_AHB_WRITE_SEL_MASK, GAMMA_AHB_WRITE_SEL_SHIFT,
1895 				crtc_id, true);
1896 	else
1897 		vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1898 				GAMMA_AHB_WRITE_SEL_MASK, GAMMA_AHB_WRITE_SEL_SHIFT,
1899 				crtc_id, false);
1900 
1901 	for (i = 0; i < lut_len; i++)
1902 		writel(lut_val[i], lut_regs + i);
1903 
1904 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1905 			EN_MASK, DSP_LUT_EN_SHIFT, 1, false);
1906 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1907 			EN_MASK, GAMMA_UPDATE_EN_SHIFT, 1, false);
1908 }
1909 
1910 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2,
1911 					struct display_state *state)
1912 {
1913 	struct connector_state *conn_state = &state->conn_state;
1914 	struct crtc_state *cstate = &state->crtc_state;
1915 	struct resource gamma_res;
1916 	fdt_size_t lut_size;
1917 	int i, lut_len, ret = 0;
1918 	u32 *lut_regs;
1919 	u32 r, g, b;
1920 	struct base2_disp_info *disp_info = conn_state->disp_info;
1921 	static int gamma_lut_en_num = 1;
1922 
1923 	if (gamma_lut_en_num > vop2->data->nr_gammas) {
1924 		printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas);
1925 		return 0;
1926 	}
1927 
1928 	ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res);
1929 	if (ret)
1930 		printf("failed to get gamma lut res\n");
1931 	lut_regs = (u32 *)gamma_res.start;
1932 	lut_size = gamma_res.end - gamma_res.start + 1;
1933 	if (lut_regs == (u32 *)FDT_ADDR_T_NONE) {
1934 		printf("failed to get gamma lut register\n");
1935 		return 0;
1936 	}
1937 	lut_len = lut_size / 4;
1938 	if (lut_len != 256 && lut_len != 1024) {
1939 		printf("Warning: unsupport gamma lut table[%d]\n", lut_len);
1940 		return 0;
1941 	}
1942 
1943 	if (!cstate->lut_val) {
1944 		if (!disp_info)
1945 			return 0;
1946 
1947 		if (!disp_info->gamma_lut_data.size)
1948 			return 0;
1949 
1950 		cstate->lut_val = (u32 *)calloc(1, lut_size);
1951 		for (i = 0; i < lut_len; i++) {
1952 			r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff;
1953 			g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff;
1954 			b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff;
1955 
1956 			cstate->lut_val[i] = b * lut_len * lut_len + g * lut_len + r;
1957 		}
1958 	}
1959 
1960 	if (vop2->version == VOP_VERSION_RK3568) {
1961 		rk3568_vop2_load_lut(vop2, cstate->crtc_id, lut_regs,
1962 				     cstate->lut_val, lut_len);
1963 		gamma_lut_en_num++;
1964 	} else {
1965 		rk3588_vop2_load_lut(vop2, cstate->crtc_id, lut_regs,
1966 				     cstate->lut_val, lut_len);
1967 		if (cstate->splice_mode) {
1968 			rk3588_vop2_load_lut(vop2, cstate->splice_crtc_id, lut_regs,
1969 					     cstate->lut_val, lut_len);
1970 			gamma_lut_en_num++;
1971 		}
1972 		gamma_lut_en_num++;
1973 	}
1974 
1975 	free(cstate->lut_val);
1976 
1977 	return 0;
1978 }
1979 
1980 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2,
1981 					struct display_state *state)
1982 {
1983 	struct connector_state *conn_state = &state->conn_state;
1984 	struct crtc_state *cstate = &state->crtc_state;
1985 	int i, cubic_lut_len;
1986 	u32 vp_offset = cstate->crtc_id * 0x100;
1987 	struct base2_disp_info *disp_info = conn_state->disp_info;
1988 	struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data;
1989 	u32 *cubic_lut_addr;
1990 
1991 	if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0)
1992 		return 0;
1993 
1994 	if (!disp_info->cubic_lut_data.size)
1995 		return 0;
1996 
1997 	cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id);
1998 	cubic_lut_len = disp_info->cubic_lut_data.size;
1999 
2000 	for (i = 0; i < cubic_lut_len / 2; i++) {
2001 		*cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) +
2002 					((lut->lgreen[2 * i] & 0xfff) << 12) +
2003 					((lut->lblue[2 * i] & 0xff) << 24);
2004 		*cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) +
2005 					((lut->lred[2 * i + 1] & 0xfff) << 4) +
2006 					((lut->lgreen[2 * i + 1] & 0xfff) << 16) +
2007 					((lut->lblue[2 * i + 1] & 0xf) << 28);
2008 		*cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4;
2009 		*cubic_lut_addr++ = 0;
2010 	}
2011 
2012 	if (cubic_lut_len % 2) {
2013 		*cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) +
2014 					((lut->lgreen[2 * i] & 0xfff) << 12) +
2015 					((lut->lblue[2 * i] & 0xff) << 24);
2016 		*cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8;
2017 		*cubic_lut_addr++ = 0;
2018 		*cubic_lut_addr = 0;
2019 	}
2020 
2021 	vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset,
2022 		    get_cubic_lut_buffer(cstate->crtc_id));
2023 	vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL,
2024 			EN_MASK, LUT_DMA_EN_SHIFT, 1, false);
2025 	vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
2026 			EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false);
2027 	vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
2028 			EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false);
2029 
2030 	return 0;
2031 }
2032 
2033 static void vop2_bcsh_reg_update(struct display_state *state, struct vop2 *vop2,
2034 				 struct bcsh_state *bcsh_state, int crtc_id)
2035 {
2036 	struct crtc_state *cstate = &state->crtc_state;
2037 	u32 vp_offset = crtc_id * 0x100;
2038 
2039 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK,
2040 			BCSH_CTRL_R2Y_SHIFT, cstate->post_r2y_en, false);
2041 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK,
2042 			BCSH_CTRL_Y2R_SHIFT, cstate->post_y2r_en, false);
2043 
2044 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK,
2045 			BCSH_CTRL_R2Y_CSC_MODE_SHIFT, cstate->post_csc_mode, false);
2046 	vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK,
2047 			BCSH_CTRL_Y2R_CSC_MODE_SHIFT, cstate->post_csc_mode, false);
2048 
2049 	if (!cstate->bcsh_en) {
2050 		vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
2051 				BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false);
2052 		return;
2053 	}
2054 
2055 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
2056 			BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT,
2057 			bcsh_state->brightness, false);
2058 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
2059 			BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, bcsh_state->contrast, false);
2060 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
2061 			BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT,
2062 			bcsh_state->saturation * bcsh_state->contrast / 0x100, false);
2063 	vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
2064 			BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, bcsh_state->sin_hue, false);
2065 	vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
2066 			BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, bcsh_state->cos_hue, false);
2067 	vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
2068 			BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT,
2069 			BCSH_OUT_MODE_NORMAL_VIDEO, false);
2070 	vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
2071 			BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false);
2072 }
2073 
2074 static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2)
2075 {
2076 	struct connector_state *conn_state = &state->conn_state;
2077 	struct base_bcsh_info *bcsh_info;
2078 	struct crtc_state *cstate = &state->crtc_state;
2079 	struct bcsh_state bcsh_state;
2080 	int brightness, contrast, saturation, hue, sin_hue, cos_hue;
2081 
2082 	if (!conn_state->disp_info)
2083 		return;
2084 	bcsh_info = &conn_state->disp_info->bcsh_info;
2085 	if (!bcsh_info)
2086 		return;
2087 
2088 	if (bcsh_info->brightness != 50 ||
2089 	    bcsh_info->contrast != 50 ||
2090 	    bcsh_info->saturation != 50 || bcsh_info->hue != 50)
2091 		cstate->bcsh_en = true;
2092 
2093 	if (cstate->bcsh_en) {
2094 		if (!cstate->yuv_overlay)
2095 			cstate->post_r2y_en = 1;
2096 		if (!is_yuv_output(conn_state->bus_format))
2097 			cstate->post_y2r_en = 1;
2098 	} else {
2099 		if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format))
2100 			cstate->post_r2y_en = 1;
2101 		if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format))
2102 			cstate->post_y2r_en = 1;
2103 	}
2104 
2105 	cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_encoding,
2106 						      conn_state->color_range,
2107 						      CSC_10BIT_DEPTH);
2108 
2109 	if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT)
2110 		brightness = interpolate(0, -128, 100, 127,
2111 					 bcsh_info->brightness);
2112 	else
2113 		brightness = interpolate(0, -32, 100, 31,
2114 					 bcsh_info->brightness);
2115 	contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast);
2116 	saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation);
2117 	hue = interpolate(0, -30, 100, 30, bcsh_info->hue);
2118 
2119 
2120 	/*
2121 	 *  a:[-30~0):
2122 	 *    sin_hue = 0x100 - sin(a)*256;
2123 	 *    cos_hue = cos(a)*256;
2124 	 *  a:[0~30]
2125 	 *    sin_hue = sin(a)*256;
2126 	 *    cos_hue = cos(a)*256;
2127 	 */
2128 	sin_hue = fixp_sin32(hue) >> 23;
2129 	cos_hue = fixp_cos32(hue) >> 23;
2130 
2131 	bcsh_state.brightness = brightness;
2132 	bcsh_state.contrast = contrast;
2133 	bcsh_state.saturation = saturation;
2134 	bcsh_state.sin_hue = sin_hue;
2135 	bcsh_state.cos_hue = cos_hue;
2136 
2137 	vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->crtc_id);
2138 	if (cstate->splice_mode)
2139 		vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->splice_crtc_id);
2140 }
2141 
2142 static void vop2_setup_dly_for_vp(struct display_state *state, struct vop2 *vop2, int crtc_id)
2143 {
2144 	struct connector_state *conn_state = &state->conn_state;
2145 	struct drm_display_mode *mode = &conn_state->mode;
2146 	struct crtc_state *cstate = &state->crtc_state;
2147 	u32 bg_ovl_dly, bg_dly, pre_scan_dly;
2148 	u16 hdisplay = mode->crtc_hdisplay;
2149 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
2150 
2151 	bg_ovl_dly = cstate->crtc->vps[crtc_id].bg_ovl_dly;
2152 	bg_dly = vop2->data->vp_data[crtc_id].pre_scan_max_dly;
2153 	bg_dly -= bg_ovl_dly;
2154 
2155 	/*
2156 	 * splice mode: hdisplay must roundup as 4 pixel,
2157 	 * no splice mode: hdisplay must roundup as 2 pixel.
2158 	 */
2159 	if (cstate->splice_mode)
2160 		pre_scan_dly = bg_dly + (roundup(hdisplay, 4) >> 2) - 1;
2161 	else
2162 		pre_scan_dly = bg_dly + (roundup(hdisplay, 2) >> 1) - 1;
2163 
2164 	if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8)
2165 		hsync_len = 8;
2166 	pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
2167 	vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + crtc_id * 4,
2168 			BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false);
2169 	vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly);
2170 }
2171 
2172 static void vop3_setup_pipe_dly(struct display_state *state, struct vop2 *vop2, int crtc_id)
2173 {
2174 	struct connector_state *conn_state = &state->conn_state;
2175 	struct drm_display_mode *mode = &conn_state->mode;
2176 	u32 bg_dly, pre_scan_dly;
2177 	u16 hdisplay = mode->crtc_hdisplay;
2178 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
2179 
2180 	bg_dly = vop2->data->vp_data[crtc_id].win_dly +
2181 		 vop2->data->vp_data[crtc_id].layer_mix_dly +
2182 		 vop2->data->vp_data[crtc_id].hdr_mix_dly;
2183 	/* hdisplay must roundup as 2 pixel */
2184 	pre_scan_dly = bg_dly + (roundup(hdisplay, 2) >> 1) - 1;
2185 	/**
2186 	 * pre_scan_hblank minimum value is 8, otherwise the win reset signal will
2187 	 * lead to first line data be zero.
2188 	 */
2189 	pre_scan_dly = (pre_scan_dly << 16) | (hsync_len < 8 ? 8 : hsync_len);
2190 	vop2_mask_write(vop2, RK3528_OVL_PORT0_BG_MIX_CTRL + crtc_id * 0x100,
2191 			BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false);
2192 	vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly);
2193 }
2194 
2195 static void vop2_post_config(struct display_state *state, struct vop2 *vop2)
2196 {
2197 	struct connector_state *conn_state = &state->conn_state;
2198 	struct drm_display_mode *mode = &conn_state->mode;
2199 	struct crtc_state *cstate = &state->crtc_state;
2200 	const struct vop2_data *vop2_data = vop2->data;
2201 	const struct vop2_ops *vop2_ops = vop2_data->ops;
2202 	struct vop2_vp_plane_mask *plane_mask = &vop2->vp_plane_mask[cstate->crtc_id];
2203 	u32 vp_offset = (cstate->crtc_id * 0x100);
2204 	u16 vtotal = mode->crtc_vtotal;
2205 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
2206 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
2207 	u16 hdisplay = mode->crtc_hdisplay;
2208 	u16 vdisplay = mode->crtc_vdisplay;
2209 	u16 hsize;
2210 	u16 vsize;
2211 	u16 hact_end, vact_end;
2212 	u32 val;
2213 
2214 	/*
2215 	 * For RK3576, use the win scale instead of the post scale to configure
2216 	 * overscan parameters, because the sharp/post scale/split functions are
2217 	 * mutually exclusice.
2218 	 */
2219 	if (vop2->version == VOP_VERSION_RK3576) {
2220 		hsize = hdisplay;
2221 		vsize = vdisplay;
2222 
2223 		cstate->overscan_by_win_scale = true;
2224 	} else {
2225 		hsize = hdisplay * (conn_state->overscan.left_margin +
2226 				    conn_state->overscan.right_margin) / 200;
2227 		vsize = vdisplay * (conn_state->overscan.top_margin +
2228 				    conn_state->overscan.bottom_margin) / 200;
2229 		hsize = round_down(hsize, 2);
2230 		vsize = round_down(vsize, 2);
2231 
2232 		hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200;
2233 		vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200;
2234 	}
2235 
2236 	hact_end = hact_st + hsize;
2237 	val = hact_st << 16;
2238 	val |= hact_end;
2239 	vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val);
2240 	vact_end = vact_st + vsize;
2241 	val = vact_st << 16;
2242 	val |= vact_end;
2243 	vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val);
2244 	val = scl_cal_scale2(vdisplay, vsize) << 16;
2245 	val |= scl_cal_scale2(hdisplay, hsize);
2246 	vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val);
2247 #define POST_HORIZONTAL_SCALEDOWN_EN(x)		((x) << 0)
2248 #define POST_VERTICAL_SCALEDOWN_EN(x)		((x) << 1)
2249 	vop2_mask_write(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset,
2250 			RK3568_VP0_POST_SCALE_MASK, RK3568_VP0_POST_SCALE_SHIFT,
2251 			POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) |
2252 			POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize), false);
2253 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
2254 		u16 vact_st_f1 = vtotal + vact_st + 1;
2255 		u16 vact_end_f1 = vact_st_f1 + vsize;
2256 
2257 		val = vact_st_f1 << 16 | vact_end_f1;
2258 		vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val);
2259 	}
2260 
2261 	if (is_vop3(vop2)) {
2262 		vop3_setup_pipe_dly(state, vop2, cstate->crtc_id);
2263 	} else {
2264 		vop2_setup_dly_for_vp(state, vop2, cstate->crtc_id);
2265 		vop2_ops->setup_win_dly(state, cstate->crtc_id, plane_mask->primary_plane_id);
2266 		if (cstate->splice_mode) {
2267 			plane_mask = &vop2->vp_plane_mask[cstate->splice_crtc_id];
2268 			vop2_setup_dly_for_vp(state, vop2, cstate->splice_crtc_id);
2269 			vop2_ops->setup_win_dly(state, cstate->splice_crtc_id, plane_mask->primary_plane_id);
2270 		}
2271 	}
2272 }
2273 
2274 static void vop3_post_acm_config(struct display_state *state, struct vop2 *vop2)
2275 {
2276 	struct connector_state *conn_state = &state->conn_state;
2277 	struct crtc_state *cstate = &state->crtc_state;
2278 	struct acm_data *acm = &conn_state->disp_info->acm_data;
2279 	struct drm_display_mode *mode = &conn_state->mode;
2280 	u32 vp_offset = (cstate->crtc_id * 0x100);
2281 	s16 *lut_y;
2282 	s16 *lut_h;
2283 	s16 *lut_s;
2284 	u32 value;
2285 	int i;
2286 
2287 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2288 		POST_ACM_BYPASS_EN_MASK, POST_ACM_BYPASS_EN_SHIFT, 0, false);
2289 	if (!acm->acm_enable) {
2290 		writel(0, vop2->regs + RK3528_ACM_CTRL);
2291 		return;
2292 	}
2293 
2294 	printf("post acm enable\n");
2295 
2296 	writel(1, vop2->regs + RK3528_ACM_FETCH_START);
2297 
2298 	value = (acm->acm_enable & 0x1) + ((mode->hdisplay & 0xfff) << 8) +
2299 		((mode->vdisplay & 0xfff) << 20);
2300 	writel(value, vop2->regs + RK3528_ACM_CTRL);
2301 
2302 	value = (acm->y_gain & 0x3ff) + ((acm->h_gain << 10) & 0xffc00) +
2303 		((acm->s_gain << 20) & 0x3ff00000);
2304 	writel(value, vop2->regs + RK3528_ACM_DELTA_RANGE);
2305 
2306 	lut_y = &acm->gain_lut_hy[0];
2307 	lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH];
2308 	lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2];
2309 	for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) {
2310 		value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
2311 			((lut_s[i] << 16) & 0xff0000);
2312 		writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2));
2313 	}
2314 
2315 	lut_y = &acm->gain_lut_hs[0];
2316 	lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH];
2317 	lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2];
2318 	for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) {
2319 		value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
2320 			((lut_s[i] << 16) & 0xff0000);
2321 		writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2));
2322 	}
2323 
2324 	lut_y = &acm->delta_lut_h[0];
2325 	lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH];
2326 	lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2];
2327 	for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) {
2328 		value = (lut_y[i] & 0x3ff) + ((lut_h[i] << 12) & 0xff000) +
2329 			((lut_s[i] << 20) & 0x3ff00000);
2330 		writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2));
2331 	}
2332 
2333 	writel(1, vop2->regs + RK3528_ACM_FETCH_DONE);
2334 }
2335 
2336 static void vop3_get_csc_info_from_bcsh(struct display_state *state,
2337 					struct csc_info *csc_info)
2338 {
2339 	struct connector_state *conn_state = &state->conn_state;
2340 	struct base_bcsh_info *bcsh_info;
2341 
2342 	if (!conn_state->disp_info)
2343 		return;
2344 
2345 	bcsh_info = &conn_state->disp_info->bcsh_info;
2346 	if (!bcsh_info)
2347 		return;
2348 
2349 	csc_info->r_gain = 256;
2350 	csc_info->g_gain = 256;
2351 	csc_info->b_gain = 256;
2352 	csc_info->r_offset = 256;
2353 	csc_info->g_offset = 256;
2354 	csc_info->b_offset = 256;
2355 	if (bcsh_info->brightness == 50 && bcsh_info->contrast == 50 &&
2356 	    bcsh_info->saturation == 50 && bcsh_info->hue == 50) {
2357 		csc_info->csc_enable = false;
2358 		csc_info->brightness = 256;
2359 		csc_info->contrast = 256;
2360 		csc_info->saturation = 256;
2361 		csc_info->hue = 256;
2362 	} else {
2363 		csc_info->csc_enable = true;
2364 		csc_info->brightness = bcsh_info->brightness * 511 / 100;
2365 		csc_info->contrast = bcsh_info->contrast * 511 / 100;
2366 		csc_info->saturation = bcsh_info->saturation * 511 / 100;
2367 		csc_info->hue = bcsh_info->hue * 511 / 100;
2368 	}
2369 }
2370 
2371 static void vop3_post_csc_config(struct display_state *state, struct vop2 *vop2)
2372 {
2373 	struct connector_state *conn_state = &state->conn_state;
2374 	struct crtc_state *cstate = &state->crtc_state;
2375 	struct acm_data *acm = &conn_state->disp_info->acm_data;
2376 	struct csc_info *csc = &conn_state->disp_info->csc_info;
2377 	struct post_csc_coef csc_coef;
2378 	bool is_input_yuv = false;
2379 	bool is_output_yuv = false;
2380 	bool post_r2y_en = false;
2381 	bool post_csc_en = false;
2382 	u32 vp_offset = (cstate->crtc_id * 0x100);
2383 	u32 value;
2384 	int range_type;
2385 
2386 	printf("post csc enable\n");
2387 
2388 	if (!csc->csc_enable)
2389 		vop3_get_csc_info_from_bcsh(state, csc);
2390 
2391 	if (acm->acm_enable) {
2392 		if (!cstate->yuv_overlay)
2393 			post_r2y_en = true;
2394 
2395 		/* do y2r in csc module */
2396 		if (!is_yuv_output(conn_state->bus_format))
2397 			post_csc_en = true;
2398 	} else {
2399 		if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format))
2400 			post_r2y_en = true;
2401 
2402 		/* do y2r in csc module */
2403 		if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format))
2404 			post_csc_en = true;
2405 	}
2406 
2407 	if (csc->csc_enable)
2408 		post_csc_en = true;
2409 
2410 	if (cstate->yuv_overlay || post_r2y_en)
2411 		is_input_yuv = true;
2412 
2413 	if (is_yuv_output(conn_state->bus_format))
2414 		is_output_yuv = true;
2415 
2416 	cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_encoding,
2417 						      conn_state->color_range,
2418 						      CSC_13BIT_DEPTH);
2419 
2420 	if (post_csc_en) {
2421 		rockchip_calc_post_csc(csc, &csc_coef, cstate->post_csc_mode, is_input_yuv,
2422 				       is_output_yuv);
2423 
2424 		vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2425 				POST_CSC_COE00_MASK, POST_CSC_COE00_SHIFT,
2426 				csc_coef.csc_coef00, false);
2427 		value = csc_coef.csc_coef01 & 0xffff;
2428 		value |= (csc_coef.csc_coef02 << 16) & 0xffff0000;
2429 		writel(value, vop2->regs + RK3528_VP0_CSC_COE01_02);
2430 		value = csc_coef.csc_coef10 & 0xffff;
2431 		value |= (csc_coef.csc_coef11 << 16) & 0xffff0000;
2432 		writel(value, vop2->regs + RK3528_VP0_CSC_COE10_11);
2433 		value = csc_coef.csc_coef12 & 0xffff;
2434 		value |= (csc_coef.csc_coef20 << 16) & 0xffff0000;
2435 		writel(value, vop2->regs + RK3528_VP0_CSC_COE12_20);
2436 		value = csc_coef.csc_coef21 & 0xffff;
2437 		value |= (csc_coef.csc_coef22 << 16) & 0xffff0000;
2438 		writel(value, vop2->regs + RK3528_VP0_CSC_COE21_22);
2439 		writel(csc_coef.csc_dc0, vop2->regs + RK3528_VP0_CSC_OFFSET0);
2440 		writel(csc_coef.csc_dc1, vop2->regs + RK3528_VP0_CSC_OFFSET1);
2441 		writel(csc_coef.csc_dc2, vop2->regs + RK3528_VP0_CSC_OFFSET2);
2442 
2443 		range_type = csc_coef.range_type ? 0 : 1;
2444 		range_type <<= is_input_yuv ? 0 : 1;
2445 		vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2446 				POST_CSC_MODE_MASK, POST_CSC_MODE_SHIFT, range_type, false);
2447 	}
2448 
2449 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2450 			POST_R2Y_EN_MASK, POST_R2Y_EN_SHIFT, post_r2y_en ? 1 : 0, false);
2451 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2452 			POST_CSC_EN_MASK, POST_CSC_EN_SHIFT, post_csc_en ? 1 : 0, false);
2453 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2454 			POST_R2Y_MODE_MASK, POST_R2Y_MODE_SHIFT, cstate->post_csc_mode, false);
2455 }
2456 
2457 static void vop3_post_config(struct display_state *state, struct vop2 *vop2)
2458 {
2459 	struct connector_state *conn_state = &state->conn_state;
2460 	struct base2_disp_info *disp_info = conn_state->disp_info;
2461 	const char *enable_flag;
2462 	if (!disp_info) {
2463 		printf("disp_info is empty\n");
2464 		return;
2465 	}
2466 
2467 	enable_flag = (const char *)&disp_info->cacm_header;
2468 	if (strncasecmp(enable_flag, "CACM", 4)) {
2469 		printf("acm and csc is not support\n");
2470 		return;
2471 	}
2472 
2473 	vop3_post_acm_config(state, vop2);
2474 	vop3_post_csc_config(state, vop2);
2475 }
2476 
2477 static int rk3576_vop2_wait_power_domain_on(struct vop2 *vop2,
2478 					    struct vop2_power_domain_data *pd_data)
2479 {
2480 	int val = 0;
2481 	bool is_bisr_en, is_otp_bisr_en;
2482 
2483 	if (pd_data->id == VOP2_PD_CLUSTER) {
2484 		is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3576_PMU_BISR_PDGEN_CON0,
2485 					    EN_MASK, PD_VOP_CLUSTER_REPAIR_ENA_SHIFT);
2486 		is_otp_bisr_en = vop2_grf_readl(vop2, vop2->grf, RK3576_SYS_GRF_MEMFAULT_STATUS0,
2487 						EN_MASK, PD_VOP_CLUSTER_REPAIR_ENA_SHIFT);
2488 		if (is_bisr_en && is_otp_bisr_en)
2489 			return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_BISR_PWR_REPAIR_STATUS0,
2490 						  val, ((val >> PD_VOP_CLUSTER_PWR_REPAIR_STAT_SHIFT) & 0x1),
2491 						  50 * 1000);
2492 		else
2493 			return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_PWR_GATE_STS,
2494 						  val, !((val >> PD_VOP_CLUSTER_DWN_STAT) & 0x1),
2495 						  50 * 1000);
2496 	} else {
2497 		is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3576_PMU_BISR_PDGEN_CON0,
2498 					    EN_MASK, PD_VOP_ESMART_REPAIR_ENA_SHIFT);
2499 		is_otp_bisr_en = vop2_grf_readl(vop2, vop2->grf, RK3576_SYS_GRF_MEMFAULT_STATUS0,
2500 						EN_MASK, PD_VOP_ESMART_REPAIR_ENA_SHIFT);
2501 		if (is_bisr_en && is_otp_bisr_en)
2502 			return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_BISR_PWR_REPAIR_STATUS0,
2503 						  val, ((val >> PD_VOP_ESMART_PWR_REPAIR_STAT_SHIFT) & 0x1),
2504 						  50 * 1000);
2505 		else
2506 			return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_PWR_GATE_STS,
2507 						  val, !((val >> PD_VOP_ESMART_DWN_STAT) & 0x1),
2508 						  50 * 1000);
2509 	}
2510 }
2511 
2512 static int rk3576_vop2_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data)
2513 {
2514 	int ret = 0;
2515 
2516 	if (pd_data->id == VOP2_PD_CLUSTER)
2517 		vop2_mask_write(vop2, RK3576_SYS_CLUSTER_PD_CTRL, EN_MASK,
2518 				RK3576_CLUSTER_PD_EN_SHIFT, 0, true);
2519 	else
2520 		vop2_mask_write(vop2, RK3576_SYS_ESMART_PD_CTRL, EN_MASK,
2521 				RK3576_ESMART_PD_EN_SHIFT, 0, true);
2522 	ret = rk3576_vop2_wait_power_domain_on(vop2, pd_data);
2523 	if (ret) {
2524 		printf("wait vop2 power domain timeout\n");
2525 		return ret;
2526 	}
2527 
2528 	return 0;
2529 }
2530 
2531 static int rk3588_vop2_wait_power_domain_on(struct vop2 *vop2,
2532 					    struct vop2_power_domain_data *pd_data)
2533 {
2534 	int val = 0;
2535 	int shift = 0;
2536 	int shift_factor = 0;
2537 	bool is_bisr_en = false;
2538 
2539 	/*
2540 	 * The order of pd status bits in BISR_STS register
2541 	 * is different from that in VOP SYS_STS register.
2542 	 */
2543 	if (pd_data->id == VOP2_PD_DSC_8K ||
2544 	    pd_data->id == VOP2_PD_DSC_4K ||
2545 	    pd_data->id == VOP2_PD_ESMART)
2546 		shift_factor = 1;
2547 
2548 	shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT + generic_ffs(pd_data->id) - 1 - shift_factor;
2549 	is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, shift);
2550 	if (is_bisr_en) {
2551 		shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI + generic_ffs(pd_data->id) - 1 - shift_factor;
2552 
2553 		return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val,
2554 					  ((val >> shift) & 0x1), 50 * 1000);
2555 	} else {
2556 		shift = RK3588_CLUSTER0_PD_STATUS_SHIFT + generic_ffs(pd_data->id) - 1;
2557 
2558 		return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val,
2559 					  !((val >> shift) & 0x1), 50 * 1000);
2560 	}
2561 }
2562 
2563 static int rk3588_vop2_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data)
2564 {
2565 	int ret = 0;
2566 
2567 	vop2_mask_write(vop2, RK3588_SYS_PD_CTRL, EN_MASK,
2568 			RK3588_CLUSTER0_PD_EN_SHIFT + generic_ffs(pd_data->id) - 1, 0, false);
2569 	ret = rk3588_vop2_wait_power_domain_on(vop2, pd_data);
2570 	if (ret) {
2571 		printf("wait vop2 power domain timeout\n");
2572 		return ret;
2573 	}
2574 
2575 	return 0;
2576 }
2577 
2578 static int vop2_power_domain_on(struct vop2 *vop2, int pd_id)
2579 {
2580 	struct vop2_power_domain_data *pd_data;
2581 	int ret = 0;
2582 
2583 	if (!pd_id)
2584 		return 0;
2585 
2586 	pd_data = vop2_find_pd_data_by_id(vop2, pd_id);
2587 	if (!pd_data) {
2588 		printf("can't find pd_data by id\n");
2589 		return -EINVAL;
2590 	}
2591 
2592 	if (pd_data->parent_id) {
2593 		ret = vop2_power_domain_on(vop2, pd_data->parent_id);
2594 		if (ret) {
2595 			printf("can't open parent power domain\n");
2596 			return -EINVAL;
2597 		}
2598 	}
2599 
2600 	/*
2601 	 * Read VOP internal power domain on/off status.
2602 	 * We should query BISR_STS register in PMU for
2603 	 * power up/down status when memory repair is enabled.
2604 	 * Return value: 1 for power on, 0 for power off;
2605 	 */
2606 	if (vop2->version == VOP_VERSION_RK3576)
2607 		ret = rk3576_vop2_power_domain_on(vop2, pd_data);
2608 	else
2609 		ret = rk3588_vop2_power_domain_on(vop2, pd_data);
2610 
2611 	return ret;
2612 }
2613 
2614 static void rk3588_vop2_regsbak(struct vop2 *vop2)
2615 {
2616 	u32 *base = vop2->regs;
2617 	int i = 0;
2618 
2619 	/*
2620 	 * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU
2621 	 */
2622 	for (i = 0; i < (vop2->reg_len >> 2); i++)
2623 		vop2->regsbak[i] = base[i];
2624 }
2625 
2626 static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win_data *win)
2627 {
2628 	if (!is_vop3(vop2))
2629 		return false;
2630 
2631 	if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE &&
2632 	    win->phys_id != ROCKCHIP_VOP2_ESMART0)
2633 		return true;
2634 	else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE &&
2635 		 (win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3))
2636 		return true;
2637 	else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE &&
2638 		 win->phys_id == ROCKCHIP_VOP2_ESMART1)
2639 		return true;
2640 	else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_4K_MODE &&
2641 		 win->phys_id == ROCKCHIP_VOP2_ESMART3)
2642 		return true;
2643 	else
2644 		return false;
2645 }
2646 
2647 static void vop3_init_esmart_scale_engine(struct vop2 *vop2)
2648 {
2649 	struct vop2_win_data *win_data;
2650 	int i;
2651 	u8 scale_engine_num = 0;
2652 
2653 	/* store plane mask for vop2_fixup_dts */
2654 	for (i = 0; i < vop2->data->nr_layers; i++) {
2655 		win_data = &vop2->data->win_data[i];
2656 		if (win_data->type == CLUSTER_LAYER || vop3_ignore_plane(vop2, win_data))
2657 			continue;
2658 
2659 		win_data->scale_engine_num = scale_engine_num++;
2660 	}
2661 }
2662 
2663 static int vop3_get_esmart_lb_mode(struct vop2 *vop2)
2664 {
2665 	const struct vop2_esmart_lb_map *esmart_lb_mode_map = vop2->data->esmart_lb_mode_map;
2666 	int i;
2667 
2668 	if (!esmart_lb_mode_map)
2669 		return vop2->esmart_lb_mode;
2670 
2671 	for (i = 0; i < vop2->data->esmart_lb_mode_num; i++) {
2672 		if (vop2->esmart_lb_mode == esmart_lb_mode_map->lb_mode)
2673 			return esmart_lb_mode_map->lb_map_value;
2674 		esmart_lb_mode_map++;
2675 	}
2676 
2677 	if (i == vop2->data->esmart_lb_mode_num)
2678 		printf("Unsupported esmart_lb_mode:%d\n", vop2->esmart_lb_mode);
2679 
2680 	return vop2->data->esmart_lb_mode_map[0].lb_map_value;
2681 }
2682 
2683 static inline void vop2_plane_mask_to_possible_vp_mask(struct display_state *state)
2684 {
2685 	struct crtc_state *cstate = &state->crtc_state;
2686 	struct vop2 *vop2 = cstate->private;
2687 	const struct vop2_data *vop2_data = vop2->data;
2688 	struct vop2_win_data *win_data;
2689 	u32 plane_mask;
2690 	u32 nr_planes;
2691 	u32 phys_id;
2692 	int i, j;
2693 
2694 	for (i = 0; i < vop2_data->nr_layers; i++) {
2695 		win_data = &vop2_data->win_data[i];
2696 		win_data->possible_vp_mask = 0;
2697 	}
2698 
2699 	for (i = 0; i < vop2_data->nr_vps; i++) {
2700 		plane_mask = cstate->crtc->vps[i].plane_mask;
2701 		nr_planes = hweight32(plane_mask);
2702 
2703 		for (j = 0; j < nr_planes; j++) {
2704 			phys_id = ffs(plane_mask) - 1;
2705 			win_data = vop2_find_win_by_phys_id(vop2, phys_id);
2706 			win_data->possible_vp_mask |= BIT(i);
2707 			plane_mask &= ~BIT(phys_id);
2708 		}
2709 	}
2710 }
2711 
2712 /*
2713  * The function checks whether the 'rockchip,plane-mask' property assigned
2714  * in DTS is valid.
2715  */
2716 static bool vop2_plane_mask_check(struct display_state *state)
2717 {
2718 	struct crtc_state *cstate = &state->crtc_state;
2719 	struct vop2 *vop2 = cstate->private;
2720 	struct vop2_win_data *win_data;
2721 	u32 assigned_plane_mask = 0, plane_mask = 0;
2722 	u32 phys_id;
2723 	u32 nr_planes;
2724 	u8 primary_plane_id, cursor_plane_id;
2725 	int i, j;
2726 
2727 	/*
2728 	 * If plane mask is assigned in DTS, then every plane need to be assigned to
2729 	 * one of all the VPs, and no single plane can be assigned to more than one
2730 	 * VP.
2731 	 */
2732 	for (i = 0; i < vop2->data->nr_vps; i++) {
2733 		plane_mask = cstate->crtc->vps[i].plane_mask;
2734 		primary_plane_id = cstate->crtc->vps[i].primary_plane_id;
2735 		cursor_plane_id = cstate->crtc->vps[i].cursor_plane_id;
2736 		nr_planes = hweight32(plane_mask);
2737 
2738 		/*
2739 		 * If the plane mask and primary plane both are assigned in DTS, the
2740 		 * primary plane should be included in the plane mask of VPx.
2741 		 */
2742 		if (plane_mask && primary_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID &&
2743 		    !(BIT(primary_plane_id) & plane_mask)) {
2744 			printf("Invalid primary plane %s[0x%lx] for VP%d[plane mask: 0x%08x]\n",
2745 			       vop2_plane_phys_id_to_string(primary_plane_id),
2746 			       BIT(primary_plane_id), i, plane_mask);
2747 			return false;
2748 		}
2749 
2750 		if (cursor_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID &&
2751 		    cursor_plane_id == primary_plane_id) {
2752 			printf("Assigned cursor plane of VP%d [%s] has been assigned as its pirmary plane\n",
2753 			       i, vop2_plane_phys_id_to_string(cursor_plane_id));
2754 			return false;
2755 		}
2756 
2757 		/*
2758 		 * If the plane mask and cursor plane both are assigned in DTS, the
2759 		 * cursor plane should be included in the plane mask of VPx.
2760 		 */
2761 		if (plane_mask && cursor_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID &&
2762 		    !(BIT(cursor_plane_id) & plane_mask)) {
2763 			printf("Invalid cursor plane %s[0x%lx] for VP%d[plane mask: 0x%08x]\n",
2764 			       vop2_plane_phys_id_to_string(cursor_plane_id),
2765 			       BIT(cursor_plane_id), i, plane_mask);
2766 			return false;
2767 		}
2768 
2769 		/*
2770 		 * Every plane assigned to the specific VP should follow the constraints
2771 		 * of default &vop2_win_data.possible_vp_mask.
2772 		 */
2773 		for (j = 0; j < nr_planes; j++) {
2774 			phys_id = ffs(plane_mask) - 1;
2775 			win_data = vop2_find_win_by_phys_id(vop2, phys_id);
2776 			if (!win_data) {
2777 				printf("Invalid plane id %d in VP%d assigned plane mask\n",
2778 				       phys_id, i);
2779 				return false;
2780 			}
2781 
2782 			if (!(vop2_win_can_attach_to_vp(win_data, i))) {
2783 				printf("%s can not attach to VP%d\n",
2784 				       vop2_plane_phys_id_to_string(phys_id), i);
2785 				return false;
2786 			}
2787 
2788 			plane_mask &= ~BIT(phys_id);
2789 		}
2790 
2791 		if (assigned_plane_mask & cstate->crtc->vps[i].plane_mask) {
2792 			printf("the same window can't be assigned to two vp\n");
2793 			return false;
2794 		}
2795 		assigned_plane_mask |= cstate->crtc->vps[i].plane_mask;
2796 	}
2797 
2798 	if (assigned_plane_mask != vop2->data->plane_mask_base) {
2799 		printf("all windows should be assigned, full plane mask: [0x%08x], current plane mask: [0x%08x]\n",
2800 		       vop2->data->plane_mask_base, assigned_plane_mask);
2801 		return false;
2802 	}
2803 
2804 	/*
2805 	 * If plane_mask assigned in DTS is valid, then convert it to &vop2_win_data.possible_vp_mask
2806 	 * and replace the default one with it.
2807 	 */
2808 	vop2_plane_mask_to_possible_vp_mask(state);
2809 
2810 	return true;
2811 }
2812 
2813 static void rockchip_cursor_plane_assign(struct display_state *state, u8 vp_id)
2814 {
2815 	struct crtc_state *cstate = &state->crtc_state;
2816 	struct vop2 *vop2 = cstate->private;
2817 	struct vop2_win_data *win_data;
2818 	int i, j;
2819 
2820 	if (cstate->crtc->vps[vp_id].cursor_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID) {
2821 		win_data = vop2_find_win_by_phys_id(vop2, cstate->crtc->vps[vp_id].cursor_plane_id);
2822 		if (win_data) {
2823 			if (vop2_win_can_attach_to_vp(win_data, vp_id))
2824 				vop2->vp_plane_mask[vp_id].cursor_plane_id =
2825 					cstate->crtc->vps[vp_id].cursor_plane_id;
2826 			return;
2827 		}
2828 	}
2829 
2830 	for (i = 0; i < vop2->data->nr_layers; i++) {
2831 		win_data = &vop2->data->win_data[i];
2832 
2833 		if (win_data->plane_type != VOP2_PLANE_TYPE_CURSOR)
2834 			continue;
2835 
2836 		if (!vop2_win_can_attach_to_vp(win_data, vp_id))
2837 			continue;
2838 
2839 		for (j = 0; j < vop2->data->nr_vps; j++) {
2840 			if (win_data->phys_id == vop2->vp_plane_mask[j].cursor_plane_id)
2841 				break;
2842 		}
2843 
2844 		/* The win has been used as the cursor plane for other VPs */
2845 		if (j < vop2->data->nr_vps)
2846 			continue;
2847 
2848 		vop2->vp_plane_mask[vp_id].cursor_plane_id = win_data->phys_id;
2849 		return;
2850 	}
2851 
2852 	vop2->vp_plane_mask[vp_id].cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
2853 }
2854 
2855 /*
2856  * For vop3, &vop2_vp_plane_mask.plane_mask will not be fixup in
2857  * &rockchip_crtc_funcs.fixup_dts(), because planes can be switched
2858  * between different CRTCs flexibly and the userspace do not need
2859  * the plane_mask to restrict the switch between the crtc and plane.
2860  * We just find a expected plane for logo display.
2861  */
2862 static void rk3528_assign_plane_mask(struct display_state *state)
2863 {
2864 	struct crtc_state *cstate = &state->crtc_state;
2865 	struct vop2 *vop2 = cstate->private;
2866 	struct vop2_win_data *win_data;
2867 	int active_vp_num = 0;
2868 	int i, j, k;
2869 
2870 	printf("Assign default plane mask\n");
2871 
2872 	for (i = 0; i < vop2->data->nr_vps; i++) {
2873 		if (!cstate->crtc->vps[i].enable)
2874 			continue;
2875 
2876 		for (j = 0; j < vop2->data->nr_layers; j++) {
2877 			win_data = &vop2->data->win_data[j];
2878 
2879 			if (win_data->plane_type != VOP2_PLANE_TYPE_PRIMARY)
2880 				continue;
2881 
2882 			if (!vop2_win_can_attach_to_vp(win_data, i))
2883 				continue;
2884 
2885 			for (k = 0; k < vop2->data->nr_vps; k++) {
2886 				if (win_data->phys_id == vop2->vp_plane_mask[k].primary_plane_id)
2887 					break;
2888 			}
2889 
2890 			/* The win has been used as the primary plane for other VPs */
2891 			if (k < vop2->data->nr_vps)
2892 				continue;
2893 
2894 			vop2->vp_plane_mask[i].attached_layers_nr = 1;
2895 			vop2->vp_plane_mask[i].primary_plane_id = win_data->phys_id;
2896 			vop2->vp_plane_mask[i].attached_layers[0] = win_data->phys_id;
2897 			vop2->vp_plane_mask[i].plane_mask |= BIT(win_data->phys_id);
2898 			active_vp_num++;
2899 			break;
2900 		}
2901 
2902 		if (vop2->vp_plane_mask[i].primary_plane_id == ROCKCHIP_VOP2_PHY_ID_INVALID)
2903 			printf("ERROR: No primary plane find for video_port%d\n", i);
2904 
2905 		rockchip_cursor_plane_assign(state, i);
2906 	}
2907 	printf("VOP have %d active VP\n", active_vp_num);
2908 }
2909 
2910 static void rk3568_assign_plane_mask(struct display_state *state)
2911 {
2912 	struct crtc_state *cstate = &state->crtc_state;
2913 	struct vop2 *vop2 = cstate->private;
2914 	struct vop2_vp_plane_mask *plane_mask;
2915 	u32 nr_planes = 0;
2916 	int active_vp_num = 0;
2917 	int main_vp_index = -1;
2918 	int layer_phy_id = 0;
2919 	int i, j;
2920 
2921 	printf("Assign default plane mask\n");
2922 
2923 	for (i = 0; i < vop2->data->nr_vps; i++) {
2924 		if (cstate->crtc->vps[i].enable)
2925 			active_vp_num++;
2926 	}
2927 
2928 	printf("VOP have %d active VP\n", active_vp_num);
2929 
2930 	if (soc_is_rk3566() && active_vp_num > 2)
2931 		printf("ERROR: rk3566 only support 2 display output!!\n");
2932 	plane_mask = vop2->data->plane_mask;
2933 	plane_mask += (active_vp_num - 1) * VOP2_VP_MAX;
2934 
2935 	/*
2936 	 * For RK3566, the main planes should be enabled before the mirror planes.
2937 	 * The devices that support hot plug may be disconnected initially, so we
2938 	 * assign the main planes to the first device that does not support hot
2939 	 * plug, in order to ensure that the mirror planes are not enabled first.
2940 	 */
2941 	if (soc_is_rk3566()) {
2942 		for (i = 0; i < vop2->data->nr_vps; i++) {
2943 			if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) {
2944 				/* the first store main display plane mask */
2945 				vop2->vp_plane_mask[i] = plane_mask[0];
2946 				main_vp_index = i;
2947 				break;
2948 			}
2949 		}
2950 
2951 		/* if no find unplug devices, use vp0 as main display */
2952 		if (main_vp_index < 0) {
2953 			main_vp_index = 0;
2954 			vop2->vp_plane_mask[0] = plane_mask[0];
2955 		}
2956 
2957 		/* plane_mask[0] store main display, so we from plane_mask[1] */
2958 		j = 1;
2959 	} else {
2960 		/*
2961 		 * For the platforms except RK3566, we assign the plane mask of
2962 		 * VPx according to the &vop2_data.plane_mask[active_vp_num][x].
2963 		 */
2964 		j = 0;
2965 	}
2966 
2967 	/* init other display except main display */
2968 	for (i = 0; i < vop2->data->nr_vps; i++) {
2969 		/* main display or no connect devices */
2970 		if (i == main_vp_index || !cstate->crtc->vps[i].enable)
2971 			continue;
2972 		vop2->vp_plane_mask[i] = plane_mask[j++];
2973 		/*
2974 		 * For rk3588, the main window should attach to the VP0 while
2975 		 * the splice window should attach to the VP1 when the display
2976 		 * mode is over 4k.
2977 		 * If only one VP is enabled and the plane mask is not assigned
2978 		 * in DTS, all main windows will be assigned to the enabled VPx,
2979 		 * and all splice windows will be assigned to the VPx+1, in order
2980 		 * to ensure that the splice mode work well.
2981 		 */
2982 		if (vop2->version == VOP_VERSION_RK3588 && active_vp_num == 1)
2983 			vop2->vp_plane_mask[(i + 1) % vop2->data->nr_vps] = plane_mask[j++];
2984 	}
2985 
2986 	/* store plane mask for vop2_fixup_dts */
2987 	for (i = 0; i < vop2->data->nr_vps; i++) {
2988 		nr_planes = vop2->vp_plane_mask[i].attached_layers_nr;
2989 		for (j = 0; j < nr_planes; j++) {
2990 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2991 			vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id);
2992 		}
2993 	}
2994 
2995 	/*
2996 	 * For RK3568 and RK3588, to aovid &vop2.vp_plane_mask[].cursor_plane_id
2997 	 * being overwritten by &vop2.data->plane_mask[].cursor_plane_id, which
2998 	 * is always 0, the assignment of cursor plane should be placed at the
2999 	 * end.
3000 	 */
3001 	for (i = 0; i < vop2->data->nr_vps; i++) {
3002 		vop2->vp_plane_mask[i].cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
3003 		if (cstate->crtc->vps[i].enable)
3004 			rockchip_cursor_plane_assign(state, i);
3005 	}
3006 }
3007 
3008 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state)
3009 {
3010 	struct crtc_state *cstate = &state->crtc_state;
3011 	const struct vop2_data *vop2_data = vop2->data;
3012 	const struct vop2_ops *vop2_ops = vop2_data->ops;
3013 	struct vop2_vp_plane_mask *vp_plane_mask;
3014 	u32 nr_planes = 0;
3015 	u32 plane_mask;
3016 	u8 primary_plane_id;
3017 	const u8 *tmp;
3018 	int i, j;
3019 
3020 	if (vop2->global_init)
3021 		return;
3022 
3023 	/*
3024 	 * Initialize struct vop2_vp_plane_mask, whose main function is to
3025 	 * fixup the DTS.
3026 	 */
3027 	for (i = 0; i < vop2->data->nr_vps; i++) {
3028 		vp_plane_mask = &vop2->vp_plane_mask[i];
3029 		/*
3030 		 * Set default value of the primary plane id and cursor plane
3031 		 * id to invalid.
3032 		 */
3033 		vp_plane_mask->primary_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
3034 		vp_plane_mask->cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
3035 	}
3036 
3037 	/* OTP must enable at the first time, otherwise mirror layer register is error */
3038 	if (soc_is_rk3566())
3039 		vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK,
3040 				OTP_WIN_EN_SHIFT, 1, false);
3041 
3042 	/* The plane mask is assigned in DTS */
3043 	if (cstate->crtc->assign_plane) {
3044 		/* check whether plane mask and primary plane are valid */
3045 		if (vop2_plane_mask_check(state)) {
3046 			for (i = 0; i < vop2->data->nr_vps; i++) {
3047 				plane_mask = cstate->crtc->vps[i].plane_mask;
3048 				nr_planes = hweight32(plane_mask); /* use bitmap to store plane mask */
3049 				vop2->vp_plane_mask[i].attached_layers_nr = nr_planes;
3050 				primary_plane_id = cstate->crtc->vps[i].primary_plane_id;
3051 				/*
3052 				 * If the primary plane of specific VP is not assigned
3053 				 * in DTS, find a proper primary plane according to the
3054 				 * &vop2_win_data.possible_vp_mask.
3055 				 */
3056 				if (primary_plane_id == ROCKCHIP_VOP2_PHY_ID_INVALID)
3057 					primary_plane_id = vop2_vp_find_attachable_win(state, i);
3058 				vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id;
3059 				vop2->vp_plane_mask[i].plane_mask = plane_mask;
3060 
3061 				/* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id] */
3062 				for (j = 0; j < nr_planes; j++) {
3063 					vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1;
3064 					plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]);
3065 				}
3066 			}
3067 		} else {
3068 			vop2_ops->assign_plane_mask(state);
3069 		}
3070 	} else {
3071 		/*
3072 		 * If no plane mask assignment, plane mask and primary plane will be
3073 		 * assigned automatically.
3074 		 */
3075 		vop2_ops->assign_plane_mask(state);
3076 	}
3077 
3078 	if (vop2->version == VOP_VERSION_RK3588)
3079 		rk3588_vop2_regsbak(vop2);
3080 	else
3081 		memcpy(vop2->regsbak, vop2->regs, vop2->reg_len);
3082 
3083 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK,
3084 			OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false);
3085 	vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3086 			IF_CTRL_REG_DONE_IMD_SHIFT, 1, false);
3087 
3088 	for (i = 0; i < vop2->data->nr_vps; i++) {
3089 		printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr);
3090 		for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++)
3091 			printf("%s ",
3092 			       vop2_plane_phys_id_to_string(vop2->vp_plane_mask[i].attached_layers[j]));
3093 		printf("], primary plane: %s\n",
3094 		       vop2_plane_phys_id_to_string(vop2->vp_plane_mask[i].primary_plane_id));
3095 	}
3096 
3097 	vop2_ops->setup_overlay(state);
3098 
3099 	if (is_vop3(vop2)) {
3100 		/*
3101 		 * you can rewrite at dts vop node:
3102 		 *
3103 		 * VOP3_ESMART_8K_MODE = 0,
3104 		 * VOP3_ESMART_4K_4K_MODE = 1,
3105 		 * VOP3_ESMART_4K_2K_2K_MODE = 2,
3106 		 * VOP3_ESMART_2K_2K_2K_2K_MODE = 3,
3107 		 *
3108 		 * &vop {
3109 		 * 	esmart_lb_mode = /bits/ 8 <2>;
3110 		 * };
3111 		 */
3112 		tmp = dev_read_u8_array_ptr(cstate->dev, "esmart_lb_mode", 1);
3113 		if (tmp)
3114 			vop2->esmart_lb_mode = *tmp;
3115 		else
3116 			vop2->esmart_lb_mode = vop2->data->esmart_lb_mode;
3117 		if (vop2->version == VOP_VERSION_RK3576)
3118 			vop2_mask_write(vop2, RK3576_SYS_ESMART_PD_CTRL,
3119 					RK3576_ESMART_LB_MODE_SEL_MASK,
3120 					RK3576_ESMART_LB_MODE_SEL_SHIFT,
3121 					vop3_get_esmart_lb_mode(vop2), true);
3122 		else
3123 			vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
3124 					ESMART_LB_MODE_SEL_MASK,
3125 					ESMART_LB_MODE_SEL_SHIFT,
3126 					vop3_get_esmart_lb_mode(vop2), false);
3127 
3128 		vop3_init_esmart_scale_engine(vop2);
3129 
3130 		if (vop2->version == VOP_VERSION_RK3576)
3131 			vop2_mask_write(vop2, RK3576_SYS_PORT_CTRL, EN_MASK,
3132 					RK3576_DSP_VS_T_SEL_SHIFT, 0, true);
3133 		else
3134 			vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, EN_MASK,
3135 					DSP_VS_T_SEL_SHIFT, 0, false);
3136 
3137 		/*
3138 		 * This is a workaround for RK3528/RK3562/RK3576:
3139 		 *
3140 		 * The aclk pre auto gating function may disable the aclk
3141 		 * in some unexpected cases, which detected by hardware
3142 		 * automatically.
3143 		 *
3144 		 * For example, if the above function is enabled, the post
3145 		 * scale function will be affected, resulting in abnormal
3146 		 * display.
3147 		 */
3148 		if (vop2->version == VOP_VERSION_RK3528 || vop2->version == VOP_VERSION_RK3562 ||
3149 		    vop2->version == VOP_VERSION_RK3576)
3150 			vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK,
3151 					ACLK_PRE_AUTO_GATING_EN_SHIFT, 0, false);
3152 	}
3153 
3154 	if (vop2->version == VOP_VERSION_RK3568)
3155 		vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0);
3156 
3157 	if (vop2->version == VOP_VERSION_RK3576) {
3158 		vop2->merge_irq = ofnode_read_bool(cstate->node, "rockchip,vop-merge-irq");
3159 
3160 		/* Default use rkiommu 2.0 for axi0 */
3161 		vop2_mask_write(vop2, RK3576_SYS_MMU_CTRL, EN_MASK, RKMMU_V2_EN_SHIFT, 1, true);
3162 
3163 		/* Init frc2.0 config */
3164 		vop2_writel(vop2, 0xca0, 0xc8);
3165 		vop2_writel(vop2, 0xca4, 0x01000100);
3166 		vop2_writel(vop2, 0xca8, 0x03ff0100);
3167 		vop2_writel(vop2, 0xda0, 0xc8);
3168 		vop2_writel(vop2, 0xda4, 0x01000100);
3169 		vop2_writel(vop2, 0xda8, 0x03ff0100);
3170 
3171 		if (vop2->version == VOP_VERSION_RK3576 && vop2->merge_irq == true)
3172 			vop2_mask_write(vop2, RK3576_SYS_PORT_CTRL, EN_MASK,
3173 					VP_INTR_MERGE_EN_SHIFT, 1, true);
3174 
3175 		/* Set reg done every field for interlace */
3176 		vop2_mask_write(vop2, RK3576_SYS_PORT_CTRL, INTERLACE_FRM_REG_DONE_MASK,
3177 				INTERLACE_FRM_REG_DONE_SHIFT, 0, false);
3178 	}
3179 
3180 	vop2->global_init = true;
3181 }
3182 
3183 static void rockchip_vop2_sharp_init(struct vop2 *vop2, struct display_state *state)
3184 {
3185 	struct crtc_state *cstate = &state->crtc_state;
3186 	const struct vop2_data *vop2_data = vop2->data;
3187 	const struct vop2_vp_data *vp_data = &vop2_data->vp_data[cstate->crtc_id];
3188 	struct rockchip_vp *vp = &cstate->crtc->vps[cstate->crtc_id];
3189 	struct resource sharp_regs;
3190 	int ret;
3191 
3192 	if (!(vp_data->feature & VOP_FEATURE_POST_SHARP) || !vp->sharp_en)
3193 		return;
3194 
3195 	ret = ofnode_read_resource_byname(cstate->node, "sharp_regs", &sharp_regs);
3196 	if (ret) {
3197 		printf("failed to get sharp regs\n");
3198 		return;
3199 	}
3200 	vop2->sharp_res = (void *)sharp_regs.start;
3201 
3202 	/*
3203 	 * After vop initialization, keep sw_sharp_enable always on.
3204 	 * Only enable/disable sharp submodule to avoid black screen.
3205 	 */
3206 	writel(true << SW_SHARP_ENABLE_SHIFT, vop2->sharp_res + RK3576_SHARP_CTRL);
3207 }
3208 
3209 static void rockchip_vop2_acm_init(struct vop2 *vop2, struct display_state *state)
3210 {
3211 	struct crtc_state *cstate = &state->crtc_state;
3212 	const struct vop2_data *vop2_data = vop2->data;
3213 	const struct vop2_vp_data *vp_data = &vop2_data->vp_data[cstate->crtc_id];
3214 	struct resource acm_regs;
3215 	u32 *acm_reg_base;
3216 	u32 vp_offset = (cstate->crtc_id * 0x100);
3217 	int ret;
3218 
3219 	if (!(vp_data->feature & VOP_FEATURE_POST_ACM))
3220 		return;
3221 
3222 	ret = ofnode_read_resource_byname(cstate->node, "acm_regs", &acm_regs);
3223 	if (ret) {
3224 		printf("failed to get acm regs\n");
3225 		return;
3226 	}
3227 	acm_reg_base = (u32 *)acm_regs.start;
3228 
3229 	/*
3230 	 * Black screen is displayed when acm bypass switched
3231 	 * between enable and disable. Therefore, disable acm
3232 	 * bypass by default after system boot.
3233 	 */
3234 	vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
3235 			POST_ACM_BYPASS_EN_MASK, POST_ACM_BYPASS_EN_SHIFT, 0, false);
3236 
3237 	writel(0, acm_reg_base + 0);
3238 }
3239 
3240 static int rockchip_vop2_of_get_gamma_lut(struct display_state *state,
3241 					  struct device_node *dsp_lut_node)
3242 {
3243 	struct crtc_state *cstate = &state->crtc_state;
3244 	struct resource gamma_res;
3245 	fdt_size_t lut_size;
3246 	u32 *lut_regs;
3247 	u32 *lut;
3248 	u32 r, g, b;
3249 	int lut_len;
3250 	int length;
3251 	int i, j;
3252 	int ret = 0;
3253 
3254 	of_get_property(dsp_lut_node, "gamma-lut", &length);
3255 	if (!length)
3256 		return -EINVAL;
3257 
3258 	ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res);
3259 	if (ret)
3260 		printf("failed to get gamma lut res\n");
3261 	lut_regs = (u32 *)gamma_res.start;
3262 	lut_size = gamma_res.end - gamma_res.start + 1;
3263 	if (lut_regs == (u32 *)FDT_ADDR_T_NONE) {
3264 		printf("failed to get gamma lut register\n");
3265 		return -EINVAL;
3266 	}
3267 	lut_len = lut_size / 4;
3268 
3269 	cstate->lut_val = (u32 *)calloc(1, lut_size);
3270 	if (!cstate->lut_val)
3271 		return -ENOMEM;
3272 
3273 	length >>= 2;
3274 	if (length != lut_len) {
3275 		lut = (u32 *)calloc(1, lut_len);
3276 		if (!lut) {
3277 			free(cstate->lut_val);
3278 			return -ENOMEM;
3279 		}
3280 
3281 		ret = of_read_u32_array(dsp_lut_node, "gamma-lut", lut, length);
3282 		if (ret) {
3283 			printf("Failed to load gamma-lut for vp%d\n", cstate->crtc_id);
3284 			free(cstate->lut_val);
3285 			free(lut);
3286 			return -EINVAL;
3287 		}
3288 
3289 		/*
3290 		 * In order to achieve the same gamma correction effect in different
3291 		 * platforms, the following conversion helps to translate from 8bit
3292 		 * gamma table with 256 parameters to 10bit gamma with 1024 parameters.
3293 		 */
3294 		for (i = 0; i < lut_len; i++) {
3295 			j = i * length / lut_len;
3296 			r = lut[j] / length / length * lut_len / length;
3297 			g = lut[j] / length % length * lut_len / length;
3298 			b = lut[j] % length * lut_len / length;
3299 
3300 			cstate->lut_val[i] = r * lut_len * lut_len + g * lut_len + b;
3301 		}
3302 		free(lut);
3303 	} else {
3304 		of_read_u32_array(dsp_lut_node, "gamma-lut", cstate->lut_val, lut_len);
3305 	}
3306 
3307 	return 0;
3308 }
3309 
3310 static void rockchip_vop2_of_get_dsp_lut(struct vop2 *vop2, struct display_state *state)
3311 {
3312 	struct crtc_state *cstate = &state->crtc_state;
3313 	struct device_node *dsp_lut_node;
3314 	int phandle;
3315 	int ret = 0;
3316 
3317 	phandle = ofnode_read_u32_default(np_to_ofnode(cstate->port_node), "dsp-lut", -1);
3318 	if (phandle < 0)
3319 		return;
3320 
3321 	dsp_lut_node = of_find_node_by_phandle(phandle);
3322 	if (!dsp_lut_node)
3323 		return;
3324 
3325 	ret = rockchip_vop2_of_get_gamma_lut(state, dsp_lut_node);
3326 	if (ret)
3327 		printf("failed to load vp%d gamma-lut from dts\n", cstate->crtc_id);
3328 }
3329 
3330 static int vop2_initial(struct vop2 *vop2, struct display_state *state)
3331 {
3332 	rockchip_vop2_of_get_dsp_lut(vop2, state);
3333 
3334 	rockchip_vop2_gamma_lut_init(vop2, state);
3335 	rockchip_vop2_cubic_lut_init(vop2, state);
3336 	rockchip_vop2_sharp_init(vop2, state);
3337 	rockchip_vop2_acm_init(vop2, state);
3338 
3339 	return 0;
3340 }
3341 
3342 /*
3343  * VOP2 have multi video ports.
3344  * video port ------- crtc
3345  */
3346 static int rockchip_vop2_preinit(struct display_state *state)
3347 {
3348 	struct crtc_state *cstate = &state->crtc_state;
3349 	const struct vop2_data *vop2_data = cstate->crtc->data;
3350 	struct regmap *map;
3351 #if defined(CONFIG_MOS_SUPPORT) && !defined(CONFIG_SPL_BUILD)
3352 	struct power_domain pwrdom;
3353 	struct clk_bulk clks;
3354 #endif
3355 	char dclk_name[16];
3356 	int ret;
3357 
3358 	if (!rockchip_vop2) {
3359 		rockchip_vop2 = calloc(1, sizeof(struct vop2));
3360 		if (!rockchip_vop2)
3361 			return -ENOMEM;
3362 		memset(rockchip_vop2, 0, sizeof(struct vop2));
3363 		rockchip_vop2->regsbak = malloc(RK3568_MAX_REG);
3364 		rockchip_vop2->reg_len = RK3568_MAX_REG;
3365 #ifdef CONFIG_SPL_BUILD
3366 		rockchip_vop2->regs = (void *)RK3528_VOP_BASE;
3367 #else
3368 		rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev);
3369 		map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,grf");
3370 		rockchip_vop2->grf = regmap_get_range(map, 0);
3371 		if (rockchip_vop2->grf <= 0)
3372 			printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf);
3373 #endif
3374 		rockchip_vop2->version = vop2_data->version;
3375 		rockchip_vop2->data = vop2_data;
3376 		if (rockchip_vop2->version == VOP_VERSION_RK3588) {
3377 			map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vop-grf");
3378 			rockchip_vop2->vop_grf = regmap_get_range(map, 0);
3379 			if (rockchip_vop2->vop_grf <= 0)
3380 				printf("%s: Get syscon vop_grf failed (ret=%p)\n",
3381 				       __func__, rockchip_vop2->vop_grf);
3382 			map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf");
3383 			rockchip_vop2->vo1_grf = regmap_get_range(map, 0);
3384 			if (rockchip_vop2->vo1_grf <= 0)
3385 				printf("%s: Get syscon vo1_grf failed (ret=%p)\n",
3386 				       __func__, rockchip_vop2->vo1_grf);
3387 			map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,pmu");
3388 			rockchip_vop2->sys_pmu = regmap_get_range(map, 0);
3389 			if (rockchip_vop2->sys_pmu <= 0)
3390 				printf("%s: Get syscon sys_pmu failed (ret=%p)\n",
3391 				       __func__, rockchip_vop2->sys_pmu);
3392 		} else if (rockchip_vop2->version == VOP_VERSION_RK3576) {
3393 			map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,ioc-grf");
3394 			rockchip_vop2->ioc_grf = regmap_get_range(map, 0);
3395 			if (rockchip_vop2->ioc_grf <= 0)
3396 				printf("%s: Get syscon ioc_grf failed (ret=%p)\n",
3397 				       __func__, rockchip_vop2->ioc_grf);
3398 			map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,pmu");
3399 			rockchip_vop2->sys_pmu = regmap_get_range(map, 0);
3400 			if (rockchip_vop2->sys_pmu <= 0)
3401 				printf("%s: Get syscon sys_pmu failed (ret=%p)\n",
3402 				       __func__, rockchip_vop2->sys_pmu);
3403 		}
3404 #if defined(CONFIG_MOS_SUPPORT) && !defined(CONFIG_SPL_BUILD)
3405 		ret = power_domain_get(cstate->dev, &pwrdom);
3406 		if (ret) {
3407 			printf("failed to get pwrdom: %d\n", ret);
3408 			return ret;
3409 		}
3410 		ret = power_domain_on(&pwrdom);
3411 		if (ret) {
3412 			printf("failed to power on pd: %d\n", ret);
3413 			return ret;
3414 		}
3415 		ret = clk_get_bulk(cstate->dev, &clks);
3416 		if (ret) {
3417 			if (ret != -ENOSYS && ret != -ENOENT) {
3418 				printf("failed to get clk: %d\n", ret);
3419 				return ret;
3420 			}
3421 		}
3422 		ret = clk_enable_bulk(&clks);
3423 		if (ret) {
3424 			printf("failed to enable clk: %d\n", ret);
3425 			clk_release_bulk(&clks);
3426 			return ret;
3427 		}
3428 #endif
3429 	}
3430 
3431 	snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id);
3432 	if (dev_read_stringlist_search(cstate->dev, "reset-names", dclk_name) > 0) {
3433 		ret = reset_get_by_name(cstate->dev, dclk_name, &cstate->dclk_rst);
3434 		if (ret < 0) {
3435 			printf("%s: failed to get dclk reset: %d\n", __func__, ret);
3436 			cstate->dclk_rst.dev = NULL;
3437 		}
3438 	}
3439 
3440 	cstate->private = rockchip_vop2;
3441 	cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output;
3442 	cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature;
3443 
3444 	vop2_global_initial(rockchip_vop2, state);
3445 
3446 	return 0;
3447 }
3448 
3449 /*
3450  * calc the dclk on rk3588
3451  * the available div of dclk is 1, 2, 4
3452  *
3453  */
3454 static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
3455 {
3456 	if (child_clk * 4 <= max_dclk)
3457 		return child_clk * 4;
3458 	else if (child_clk * 2 <= max_dclk)
3459 		return child_clk * 2;
3460 	else if (child_clk <= max_dclk)
3461 		return child_clk;
3462 	else
3463 		return 0;
3464 }
3465 
3466 /*
3467  * 4 pixclk/cycle on rk3588
3468  * RGB/eDP/HDMI: if_pixclk >= dclk_core
3469  * DP: dp_pixclk = dclk_out <= dclk_core
3470  * DSI: mipi_pixclk <= dclk_out <= dclk_core
3471  */
3472 static unsigned long vop2_calc_cru_cfg(struct display_state *state,
3473 				       int *dclk_core_div, int *dclk_out_div,
3474 				       int *if_pixclk_div, int *if_dclk_div)
3475 {
3476 	struct crtc_state *cstate = &state->crtc_state;
3477 	struct connector_state *conn_state = &state->conn_state;
3478 	struct drm_display_mode *mode = &conn_state->mode;
3479 	struct vop2 *vop2 = cstate->private;
3480 	unsigned long v_pixclk = mode->crtc_clock * 1000L;
3481 	unsigned long dclk_core_rate = v_pixclk >> 2;
3482 	unsigned long dclk_rate = v_pixclk;
3483 	unsigned long dclk_out_rate;
3484 	u64 if_dclk_rate;
3485 	u64 if_pixclk_rate;
3486 	int output_type = conn_state->type;
3487 	int output_mode = conn_state->output_mode;
3488 	int K = 1;
3489 
3490 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE &&
3491 	    output_mode == ROCKCHIP_OUT_MODE_YUV420) {
3492 		printf("Dual channel and YUV420 can't work together\n");
3493 		return -EINVAL;
3494 	}
3495 
3496 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE ||
3497 	    output_mode == ROCKCHIP_OUT_MODE_YUV420)
3498 		K = 2;
3499 
3500 	if (output_type == DRM_MODE_CONNECTOR_HDMIA) {
3501 		/*
3502 		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
3503 		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
3504 		 */
3505 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE ||
3506 		    output_mode == ROCKCHIP_OUT_MODE_YUV420) {
3507 			dclk_rate = dclk_rate >> 1;
3508 			K = 2;
3509 		}
3510 		if (cstate->dsc_enable) {
3511 			if_pixclk_rate = cstate->dsc_cds_clk_rate << 1;
3512 			if_dclk_rate = cstate->dsc_cds_clk_rate;
3513 		} else {
3514 			if_pixclk_rate = (dclk_core_rate << 1) / K;
3515 			if_dclk_rate = dclk_core_rate / K;
3516 		}
3517 
3518 		if (v_pixclk > VOP2_MAX_DCLK_RATE * 1000L)
3519 			dclk_rate = vop2_calc_dclk(dclk_core_rate,
3520 						   vop2->data->vp_data[cstate->crtc_id].max_dclk * 1000L);
3521 
3522 		if (!dclk_rate) {
3523 			printf("HDMI if_pixclk_rate out of range(max_dclk: %ld HZ, dclk_core: %lld HZ)\n",
3524 			       vop2->data->vp_data[cstate->crtc_id].max_dclk * 1000L, if_pixclk_rate);
3525 			return -EINVAL;
3526 		}
3527 		*if_pixclk_div = dclk_rate / if_pixclk_rate;
3528 		*if_dclk_div = dclk_rate / if_dclk_rate;
3529 		*dclk_core_div = dclk_rate / dclk_core_rate;
3530 		/* For HDMI DSC mode, the dclk_out_div should be the same as dclk_core_div */
3531 		if (cstate->dsc_enable)
3532 			*dclk_out_div = *dclk_core_div;
3533 		printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n",
3534 		       dclk_rate, *if_pixclk_div, *if_dclk_div);
3535 	} else if (output_type == DRM_MODE_CONNECTOR_eDP) {
3536 		/* edp_pixclk = edp_dclk > dclk_core */
3537 		if_pixclk_rate = v_pixclk / K;
3538 		if_dclk_rate = v_pixclk / K;
3539 		dclk_rate = if_pixclk_rate * K;
3540 		*dclk_core_div = dclk_rate / dclk_core_rate;
3541 		*if_pixclk_div = dclk_rate / if_pixclk_rate;
3542 		*if_dclk_div = *if_pixclk_div;
3543 	} else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) {
3544 		dclk_out_rate = v_pixclk >> 2;
3545 		dclk_out_rate = dclk_out_rate / K;
3546 
3547 		dclk_rate = vop2_calc_dclk(dclk_out_rate,
3548 					   vop2->data->vp_data[cstate->crtc_id].max_dclk * 1000L);
3549 		if (!dclk_rate) {
3550 			printf("DP dclk_core out of range(max_dclk: %ld HZ, dclk_core: %ld HZ)\n",
3551 			       vop2->data->vp_data[cstate->crtc_id].max_dclk * 1000L, dclk_core_rate);
3552 			return -EINVAL;
3553 		}
3554 		*dclk_out_div = dclk_rate / dclk_out_rate;
3555 		*dclk_core_div = dclk_rate / dclk_core_rate;
3556 	} else if (output_type == DRM_MODE_CONNECTOR_DSI) {
3557 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3558 			K = 2;
3559 		if (cstate->dsc_enable)
3560 			/* dsc output is 96bit, dsi input is 192 bit */
3561 			if_pixclk_rate = cstate->dsc_cds_clk_rate >> 1;
3562 		else
3563 			if_pixclk_rate = dclk_core_rate / K;
3564 		/* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */
3565 		dclk_out_rate = dclk_core_rate / K;
3566 		/* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */
3567 		dclk_rate = vop2_calc_dclk(dclk_out_rate,
3568 					   vop2->data->vp_data[cstate->crtc_id].max_dclk * 1000L);
3569 		if (!dclk_rate) {
3570 			printf("MIPI dclk out of range(max_dclk: %ld HZ, dclk_rate: %ld HZ)\n",
3571 			       vop2->data->vp_data[cstate->crtc_id].max_dclk * 1000L, dclk_rate);
3572 			return -EINVAL;
3573 		}
3574 
3575 		if (cstate->dsc_enable)
3576 			dclk_rate /= cstate->dsc_slice_num;
3577 
3578 		*dclk_out_div = dclk_rate / dclk_out_rate;
3579 		*dclk_core_div = dclk_rate / dclk_core_rate;
3580 		*if_pixclk_div = 1;       /*mipi pixclk == dclk_out*/
3581 		if (cstate->dsc_enable)
3582 			*if_pixclk_div = dclk_out_rate / if_pixclk_rate;
3583 
3584 	} else if (output_type == DRM_MODE_CONNECTOR_DPI) {
3585 		dclk_rate = v_pixclk;
3586 		*dclk_core_div = dclk_rate / dclk_core_rate;
3587 	}
3588 
3589 	*if_pixclk_div = ilog2(*if_pixclk_div);
3590 	*if_dclk_div = ilog2(*if_dclk_div);
3591 	*dclk_core_div = ilog2(*dclk_core_div);
3592 	/*
3593 	 * For RK3588, dclk_out is designed for DP, MIPI(both DSC and non-DSC mode)
3594 	 * and HDMI in DSC mode.
3595 	 */
3596 	if (output_type == DRM_MODE_CONNECTOR_DisplayPort ||
3597 	    output_type == DRM_MODE_CONNECTOR_DSI ||
3598 	    (output_type == DRM_MODE_CONNECTOR_HDMIA && cstate->dsc_enable))
3599 		*dclk_out_div = ilog2(*dclk_out_div);
3600 	else
3601 		*dclk_out_div = 0;
3602 
3603 	return dclk_rate;
3604 }
3605 
3606 static int vop2_calc_dsc_clk(struct display_state *state)
3607 {
3608 	struct connector_state *conn_state = &state->conn_state;
3609 	struct drm_display_mode *mode = &conn_state->mode;
3610 	struct crtc_state *cstate = &state->crtc_state;
3611 	u64 v_pixclk = mode->crtc_clock * 1000LL; /* video timing pixclk */
3612 	u8 k = 1;
3613 
3614 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3615 		k = 2;
3616 
3617 	cstate->dsc_txp_clk_rate = v_pixclk;
3618 	do_div(cstate->dsc_txp_clk_rate, (cstate->dsc_pixel_num * k));
3619 
3620 	cstate->dsc_pxl_clk_rate = v_pixclk;
3621 	do_div(cstate->dsc_pxl_clk_rate, (cstate->dsc_slice_num * k));
3622 
3623 	/* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel)
3624 	 * cds_dat_width = 96;
3625 	 * bits_per_pixel = [8-12];
3626 	 * As cds clk is div from txp clk and only support 1/2/4 div,
3627 	 * so when txp_clk is equal to v_pixclk, we set dsc_cds = crtc_clock / 4,
3628 	 * otherwise dsc_cds = crtc_clock / 8;
3629 	 */
3630 	cstate->dsc_cds_clk_rate = v_pixclk / (cstate->dsc_txp_clk_rate == v_pixclk ? 4 : 8);
3631 
3632 	return 0;
3633 }
3634 
3635 static unsigned long rk3588_vop2_if_cfg(struct display_state *state)
3636 {
3637 	struct crtc_state *cstate = &state->crtc_state;
3638 	struct connector_state *conn_state = &state->conn_state;
3639 	struct drm_display_mode *mode = &conn_state->mode;
3640 	struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap;
3641 	struct vop2 *vop2 = cstate->private;
3642 	u32 vp_offset = (cstate->crtc_id * 0x100);
3643 	u16 hdisplay = mode->crtc_hdisplay;
3644 	int output_if = conn_state->output_if;
3645 	int if_pixclk_div = 0;
3646 	int if_dclk_div = 0;
3647 	unsigned long dclk_rate;
3648 	bool dclk_inv, yc_swap = false;
3649 	u32 val;
3650 
3651 	dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
3652 	if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
3653 		val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
3654 		val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
3655 	} else {
3656 		val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
3657 		val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
3658 	}
3659 
3660 	if (cstate->dsc_enable) {
3661 		int k = 1;
3662 
3663 		if (!vop2->data->nr_dscs) {
3664 			printf("Unsupported DSC\n");
3665 			return 0;
3666 		}
3667 
3668 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3669 			k = 2;
3670 
3671 		cstate->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1;
3672 		cstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k;
3673 		cstate->dsc_pixel_num = cstate->dsc_slice_num > 4 ? 4 : cstate->dsc_slice_num;
3674 
3675 		vop2_calc_dsc_clk(state);
3676 		printf("Enable DSC%d slice:%dx%d, slice num:%d\n",
3677 		       cstate->dsc_id, dsc_sink_cap->slice_width,
3678 		       dsc_sink_cap->slice_height, cstate->dsc_slice_num);
3679 	}
3680 
3681 	dclk_rate = vop2_calc_cru_cfg(state, &cstate->dclk_core_div, &cstate->dclk_out_div, &if_pixclk_div, &if_dclk_div);
3682 
3683 	if (output_if & VOP_OUTPUT_IF_RGB) {
3684 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
3685 				4, false);
3686 		vop2_grf_writel(vop2, vop2->grf, RK3588_GRF_SOC_CON1, EN_MASK,
3687 				RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv);
3688 	}
3689 
3690 	if (output_if & VOP_OUTPUT_IF_BT1120) {
3691 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
3692 				3, false);
3693 		vop2_grf_writel(vop2, vop2->grf, RK3588_GRF_SOC_CON1, EN_MASK,
3694 				RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv);
3695 		yc_swap = is_yc_swap(conn_state->bus_format);
3696 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, RK3588_BT1120_YC_SWAP_SHIFT,
3697 				yc_swap, false);
3698 	}
3699 
3700 	if (output_if & VOP_OUTPUT_IF_BT656) {
3701 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
3702 				2, false);
3703 		vop2_grf_writel(vop2, vop2->grf, RK3588_GRF_SOC_CON1, EN_MASK,
3704 				RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv);
3705 		yc_swap = is_yc_swap(conn_state->bus_format);
3706 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, RK3588_BT656_YC_SWAP_SHIFT,
3707 				yc_swap, false);
3708 	}
3709 
3710 	if (output_if & VOP_OUTPUT_IF_MIPI0) {
3711 		if (cstate->crtc_id == 2)
3712 			val = 0;
3713 		else
3714 			val = 1;
3715 
3716 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
3717 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3718 					RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false);
3719 
3720 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT,
3721 				1, false);
3722 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false);
3723 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT,
3724 				if_pixclk_div, false);
3725 
3726 		if (conn_state->hold_mode) {
3727 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3728 					EN_MASK, EDPI_TE_EN, !cstate->soft_te, false);
3729 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3730 					EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
3731 		}
3732 	}
3733 
3734 	if (output_if & VOP_OUTPUT_IF_MIPI1) {
3735 		if (cstate->crtc_id == 2)
3736 			val = 0;
3737 		else if (cstate->crtc_id == 3)
3738 			val = 1;
3739 		else
3740 			val = 3; /*VP1*/
3741 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
3742 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3743 					RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false);
3744 
3745 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT,
3746 				1, false);
3747 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT,
3748 				val, false);
3749 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT,
3750 				if_pixclk_div, false);
3751 
3752 		if (conn_state->hold_mode) {
3753 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3754 					EN_MASK, EDPI_TE_EN, !cstate->soft_te, false);
3755 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3756 					EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
3757 		}
3758 	}
3759 
3760 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
3761 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
3762 				MIPI_DUAL_EN_SHIFT, 1, false);
3763 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
3764 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3765 					EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
3766 					false);
3767 		switch (conn_state->type) {
3768 		case DRM_MODE_CONNECTOR_DisplayPort:
3769 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3770 					RK3588_DP_DUAL_EN_SHIFT, 1, false);
3771 			break;
3772 		case DRM_MODE_CONNECTOR_eDP:
3773 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3774 					RK3588_EDP_DUAL_EN_SHIFT, 1, false);
3775 			break;
3776 		case DRM_MODE_CONNECTOR_HDMIA:
3777 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3778 					RK3588_HDMI_DUAL_EN_SHIFT, 1, false);
3779 			break;
3780 		case DRM_MODE_CONNECTOR_DSI:
3781 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3782 					RK3568_MIPI_DUAL_EN_SHIFT, 1, false);
3783 			break;
3784 		default:
3785 			break;
3786 		}
3787 	}
3788 
3789 	if (output_if & VOP_OUTPUT_IF_eDP0) {
3790 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT,
3791 				1, false);
3792 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
3793 				cstate->crtc_id, false);
3794 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
3795 				if_dclk_div, false);
3796 
3797 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
3798 				if_pixclk_div, false);
3799 
3800 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
3801 				RK3588_GRF_EDP0_ENABLE_SHIFT, 1);
3802 	}
3803 
3804 	if (output_if & VOP_OUTPUT_IF_eDP1) {
3805 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT,
3806 				1, false);
3807 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
3808 				cstate->crtc_id, false);
3809 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
3810 				if_dclk_div, false);
3811 
3812 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
3813 				if_pixclk_div, false);
3814 
3815 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
3816 				RK3588_GRF_EDP1_ENABLE_SHIFT, 1);
3817 	}
3818 
3819 	if (output_if & VOP_OUTPUT_IF_HDMI0) {
3820 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT,
3821 				1, false);
3822 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
3823 				cstate->crtc_id, false);
3824 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
3825 				if_dclk_div, false);
3826 
3827 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
3828 				if_pixclk_div, false);
3829 
3830 		if (cstate->dsc_enable)
3831 			vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
3832 					RK3588_GRF_HDMITX0_COMPRESS_MODE_SHIFT, 1);
3833 
3834 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
3835 				RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1);
3836 		vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
3837 				HDMI_SYNC_POL_MASK,
3838 				HDMI0_SYNC_POL_SHIFT, val);
3839 	}
3840 
3841 	if (output_if & VOP_OUTPUT_IF_HDMI1) {
3842 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT,
3843 				1, false);
3844 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
3845 				cstate->crtc_id, false);
3846 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
3847 				if_dclk_div, false);
3848 
3849 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
3850 				if_pixclk_div, false);
3851 
3852 		if (cstate->dsc_enable)
3853 			vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
3854 					RK3588_GRF_HDMITX1_COMPRESS_MODE_SHIFT, 1);
3855 
3856 		vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
3857 				RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1);
3858 		vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
3859 				HDMI_SYNC_POL_MASK,
3860 				HDMI1_SYNC_POL_SHIFT, val);
3861 	}
3862 
3863 	if (output_if & VOP_OUTPUT_IF_DP0) {
3864 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT,
3865 				cstate->crtc_id, false);
3866 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
3867 				RK3588_DP0_PIN_POL_SHIFT, val, false);
3868 	}
3869 
3870 	if (output_if & VOP_OUTPUT_IF_DP1) {
3871 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT,
3872 				cstate->crtc_id, false);
3873 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
3874 				RK3588_DP1_PIN_POL_SHIFT, val, false);
3875 	}
3876 
3877 	vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
3878 			DCLK_CORE_DIV_SHIFT, cstate->dclk_core_div, false);
3879 	vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
3880 			DCLK_OUT_DIV_SHIFT, cstate->dclk_out_div, false);
3881 
3882 	return dclk_rate / 1000;
3883 }
3884 
3885 static unsigned long rk3576_vop2_if_cfg(struct display_state *state)
3886 {
3887 	struct crtc_state *cstate = &state->crtc_state;
3888 	struct connector_state *conn_state = &state->conn_state;
3889 	struct drm_display_mode *mode = &conn_state->mode;
3890 	struct vop2 *vop2 = cstate->private;
3891 	u32 vp_offset = (cstate->crtc_id * 0x100);
3892 	u8 port_pix_rate = vop2->data->vp_data[cstate->crtc_id].pixel_rate;
3893 	int output_if = conn_state->output_if;
3894 	bool dclk_inv, yc_swap = false;
3895 	bool split_mode = !!(conn_state->output_flags &
3896 			     ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE);
3897 	bool post_dclk_core_sel = false, pix_half_rate = false, post_dclk_out_sel = false;
3898 	bool interface_dclk_sel, interface_pix_clk_sel = false;
3899 	bool double_pixel = mode->flags & DRM_MODE_FLAG_DBLCLK ||
3900 			    conn_state->output_if & VOP_OUTPUT_IF_BT656;
3901 	unsigned long dclk_in_rate, dclk_core_rate;
3902 	u32 val;
3903 
3904 	if (split_mode) {
3905 		printf("WARN: split is enabled, post-scaler shouldn't be set\n");
3906 		conn_state->overscan.left_margin = 100;
3907 		conn_state->overscan.right_margin = 100;
3908 		conn_state->overscan.top_margin = 100;
3909 		conn_state->overscan.bottom_margin = 100;
3910 
3911 		/*
3912 		 * VOP split and sharp use the same line buffer. If enable
3913 		 * split, sharp must be disabled completely.
3914 		 */
3915 		if (vop2->data->vp_data[cstate->crtc_id].feature & VOP_FEATURE_POST_SHARP)
3916 			writel(false << SW_SHARP_ENABLE_SHIFT,
3917 			       vop2->sharp_res + RK3576_SHARP_CTRL);
3918 	}
3919 
3920 	dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
3921 	if (output_if & VOP_OUTPUT_IF_MIPI0) {
3922 		/*
3923 		 * RK3576 DSI CTRL hsync/vsync polarity is positive and can't update,
3924 		 * so set VOP hsync/vsync polarity as positive by default.
3925 		 */
3926 		val = BIT(HSYNC_POSITIVE) | BIT(VSYNC_POSITIVE);
3927 	} else {
3928 		val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
3929 		val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
3930 	}
3931 
3932 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420 ||
3933 	    mode->crtc_clock > VOP2_MAX_DCLK_RATE || (cstate->crtc_id == 0 && split_mode))
3934 		cstate->crtc->vps[cstate->crtc_id].dclk_div = 2; /* div2 */
3935 	else
3936 		cstate->crtc->vps[cstate->crtc_id].dclk_div = 1; /* no div */
3937 	dclk_in_rate = mode->crtc_clock / cstate->crtc->vps[cstate->crtc_id].dclk_div;
3938 
3939 	if (double_pixel)
3940 		dclk_core_rate = mode->crtc_clock / 2;
3941 	else
3942 		dclk_core_rate = mode->crtc_clock / port_pix_rate;
3943 	post_dclk_core_sel = dclk_in_rate > dclk_core_rate ? 1 : 0; /* 0: no div, 1: div2 */
3944 
3945 	if (split_mode || conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
3946 		pix_half_rate = true;
3947 		post_dclk_out_sel = true;
3948 	}
3949 
3950 	if (output_if & VOP_OUTPUT_IF_RGB) {
3951 		interface_dclk_sel = pix_half_rate == 1 ? 1 : 0;
3952 		/*
3953 		 * RGB interface_pix_clk_sel will auto config according
3954 		 * to rgb_en/bt1120_en/bt656_en.
3955 		 */
3956 	} else if (output_if & VOP_OUTPUT_IF_eDP0) {
3957 		interface_dclk_sel = pix_half_rate == 1 ? 1 : 0;
3958 		interface_pix_clk_sel = port_pix_rate == 2 ? 1 : 0;
3959 	} else {
3960 		interface_dclk_sel = pix_half_rate == 1 ? 1 : 0;
3961 		interface_pix_clk_sel = port_pix_rate == 1 ? 1 : 0;
3962 	}
3963 
3964 	/* dclk_core */
3965 	vop2_mask_write(vop2, RK3568_VP0_DCLK_SEL + vp_offset, EN_MASK,
3966 			RK3576_DCLK_CORE_SEL_SHIFT, post_dclk_core_sel, false);
3967 	/* dclk_out */
3968 	vop2_mask_write(vop2, RK3568_VP0_DCLK_SEL + vp_offset, EN_MASK,
3969 			RK3576_DCLK_OUT_SEL_SHIFT, post_dclk_out_sel, false);
3970 
3971 	if (output_if & VOP_OUTPUT_IF_RGB) {
3972 		/* 0: dclk_core, 1: dclk_out */
3973 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
3974 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
3975 
3976 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
3977 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
3978 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
3979 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
3980 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
3981 				RK3576_IF_OUT_EN_SHIFT, 1, false);
3982 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
3983 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
3984 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PIN_POL_MASK,
3985 				RK3576_IF_PIN_POL_SHIFT, val, false);
3986 		vop2_grf_writel(vop2, vop2->ioc_grf, RK3576_VCCIO_IOC_MISC_CON8, EN_MASK,
3987 				RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT, dclk_inv);
3988 	}
3989 
3990 	if (output_if & VOP_OUTPUT_IF_BT1120) {
3991 		/* 0: dclk_core, 1: dclk_out */
3992 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
3993 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
3994 
3995 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
3996 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
3997 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
3998 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
3999 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4000 				RK3576_IF_OUT_EN_SHIFT, 1, false);
4001 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4002 				RK3576_BT1120_OUT_EN_SHIFT, 1, false);
4003 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4004 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4005 		vop2_grf_writel(vop2, vop2->ioc_grf, RK3576_VCCIO_IOC_MISC_CON8, EN_MASK,
4006 				RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv);
4007 		yc_swap = is_yc_swap(conn_state->bus_format);
4008 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4009 				RK3576_BT1120_YC_SWAP_SHIFT, yc_swap, false);
4010 	}
4011 
4012 	if (output_if & VOP_OUTPUT_IF_BT656) {
4013 		/* 0: dclk_core, 1: dclk_out */
4014 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
4015 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
4016 
4017 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4018 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
4019 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4020 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
4021 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4022 				RK3576_IF_OUT_EN_SHIFT, 1, false);
4023 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4024 				RK3576_BT656_OUT_EN_SHIFT, 1, false);
4025 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4026 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4027 		vop2_grf_writel(vop2, vop2->ioc_grf, RK3576_VCCIO_IOC_MISC_CON8, EN_MASK,
4028 				RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv);
4029 		yc_swap = is_yc_swap(conn_state->bus_format);
4030 		vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK,
4031 				RK3576_BT656_YC_SWAP_SHIFT, yc_swap, false);
4032 	}
4033 
4034 	if (output_if & VOP_OUTPUT_IF_MIPI0) {
4035 		vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
4036 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
4037 		/* 0: div2, 1: div4 */
4038 		vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK,
4039 				RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false);
4040 
4041 		vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK,
4042 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
4043 		vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK,
4044 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
4045 		vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK,
4046 				RK3576_IF_OUT_EN_SHIFT, 1, false);
4047 		vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4048 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4049 		/*
4050 		 * RK3576 DSI CTRL hsync/vsync polarity is positive and can't update,
4051 		 * so set VOP hsync/vsync polarity as positive by default.
4052 		 */
4053 		if (vop2->version == VOP_VERSION_RK3576)
4054 			val = BIT(HSYNC_POSITIVE) | BIT(VSYNC_POSITIVE);
4055 		vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_PIN_POL_MASK,
4056 				RK3576_IF_PIN_POL_SHIFT, val, false);
4057 
4058 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
4059 			vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK,
4060 					RK3576_MIPI_CMD_MODE_SHIFT, 1, false);
4061 
4062 		if (conn_state->hold_mode) {
4063 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
4064 					EDPI_TE_EN, !cstate->soft_te, false);
4065 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
4066 					EDPI_WMS_HOLD_EN, 1, false);
4067 		}
4068 	}
4069 
4070 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
4071 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
4072 				MIPI_DUAL_EN_SHIFT, 1, false);
4073 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
4074 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
4075 					MIPI_DUAL_SWAP_EN_SHIFT, 1, false);
4076 		switch (conn_state->type) {
4077 		case DRM_MODE_CONNECTOR_DisplayPort:
4078 			vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK,
4079 					RK3576_IF_SPLIT_EN_SHIFT, 1, false);
4080 			break;
4081 		case DRM_MODE_CONNECTOR_eDP:
4082 			vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK,
4083 					RK3576_IF_SPLIT_EN_SHIFT, 1, false);
4084 			break;
4085 		case DRM_MODE_CONNECTOR_HDMIA:
4086 			vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK,
4087 					RK3576_IF_SPLIT_EN_SHIFT, 1, false);
4088 			break;
4089 		case DRM_MODE_CONNECTOR_DSI:
4090 			vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK,
4091 					RK3576_IF_SPLIT_EN_SHIFT, 1, false);
4092 			break;
4093 		default:
4094 			break;
4095 		}
4096 	}
4097 
4098 	if (output_if & VOP_OUTPUT_IF_eDP0) {
4099 		vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
4100 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
4101 		/* 0: dclk, 1: port0_dclk */
4102 		vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK,
4103 				RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false);
4104 
4105 		vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK,
4106 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
4107 		vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK,
4108 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
4109 		vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK,
4110 				RK3576_IF_OUT_EN_SHIFT, 1, false);
4111 		vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4112 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4113 		vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_PIN_POL_MASK,
4114 				RK3576_IF_PIN_POL_SHIFT, val, false);
4115 	}
4116 
4117 	if (output_if & VOP_OUTPUT_IF_HDMI0) {
4118 		vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
4119 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
4120 		/* 0: div2, 1: div4 */
4121 		vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK,
4122 				RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false);
4123 
4124 		vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK,
4125 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
4126 		vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK,
4127 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
4128 		vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK,
4129 				RK3576_IF_OUT_EN_SHIFT, 1, false);
4130 		vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4131 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4132 		vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_PIN_POL_MASK,
4133 				RK3576_IF_PIN_POL_SHIFT, val, false);
4134 	}
4135 
4136 	if (output_if & VOP_OUTPUT_IF_DP0) {
4137 		vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
4138 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
4139 		/* 0: no div, 1: div2 */
4140 		vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK,
4141 				RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false);
4142 
4143 		vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK,
4144 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
4145 		vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK,
4146 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
4147 		vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4148 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4149 		vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_PIN_POL_MASK,
4150 				RK3576_IF_PIN_POL_SHIFT, val, false);
4151 	}
4152 
4153 	if (output_if & VOP_OUTPUT_IF_DP1) {
4154 		vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
4155 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
4156 		/* 0: no div, 1: div2 */
4157 		vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK,
4158 				RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false);
4159 
4160 		vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, EN_MASK,
4161 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
4162 		vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, EN_MASK,
4163 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
4164 		vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4165 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4166 		vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_PIN_POL_MASK,
4167 				RK3576_IF_PIN_POL_SHIFT, val, false);
4168 	}
4169 
4170 	if (output_if & VOP_OUTPUT_IF_DP2) {
4171 		vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_DCLK_SEL_MASK,
4172 				RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false);
4173 		/* 0: no div, 1: div2 */
4174 		vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK,
4175 				RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false);
4176 
4177 		vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, EN_MASK,
4178 				RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false);
4179 		vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, EN_MASK,
4180 				RK3576_IF_CLK_OUT_EN_SHIFT, 1, false);
4181 		vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_PORT_SEL_MASK,
4182 				RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false);
4183 		vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_PIN_POL_MASK,
4184 				RK3576_IF_PIN_POL_SHIFT, val, false);
4185 	}
4186 
4187 	return mode->crtc_clock;
4188 }
4189 
4190 static void rk3568_vop2_setup_dual_channel_if(struct display_state *state)
4191 {
4192 	struct crtc_state *cstate = &state->crtc_state;
4193 	struct connector_state *conn_state = &state->conn_state;
4194 	struct vop2 *vop2 = cstate->private;
4195 	u32 vp_offset = (cstate->crtc_id * 0x100);
4196 
4197 	if (conn_state->output_flags &
4198 	    ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE) {
4199 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
4200 				LVDS_DUAL_EN_SHIFT, 1, false);
4201 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
4202 				LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 0, false);
4203 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
4204 			vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
4205 					LVDS_DUAL_SWAP_EN_SHIFT, 1, false);
4206 
4207 		return;
4208 	}
4209 
4210 	vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
4211 			MIPI_DUAL_EN_SHIFT, 1, false);
4212 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) {
4213 		vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
4214 				MIPI_DUAL_SWAP_EN_SHIFT, 1, false);
4215 	}
4216 
4217 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) {
4218 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
4219 				LVDS_DUAL_EN_SHIFT, 1, false);
4220 		vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
4221 				LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, false);
4222 	}
4223 }
4224 
4225 static unsigned long rk3568_vop2_if_cfg(struct display_state *state)
4226 {
4227 	struct crtc_state *cstate = &state->crtc_state;
4228 	struct connector_state *conn_state = &state->conn_state;
4229 	struct drm_display_mode *mode = &conn_state->mode;
4230 	struct vop2 *vop2 = cstate->private;
4231 	bool dclk_inv;
4232 	u32 val;
4233 
4234 	dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
4235 	val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
4236 	val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
4237 
4238 	if (conn_state->output_if & VOP_OUTPUT_IF_RGB) {
4239 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
4240 				1, false);
4241 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4242 				RGB_MUX_SHIFT, cstate->crtc_id, false);
4243 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK,
4244 				IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
4245 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
4246 				GRF_RGB_DCLK_INV_SHIFT, dclk_inv);
4247 	}
4248 
4249 	if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) {
4250 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
4251 				1, false);
4252 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK,
4253 				BT1120_EN_SHIFT, 1, false);
4254 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4255 				RGB_MUX_SHIFT, cstate->crtc_id, false);
4256 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
4257 				GRF_BT1120_CLK_INV_SHIFT, !dclk_inv);
4258 	}
4259 
4260 	if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
4261 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
4262 				1, false);
4263 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4264 				RGB_MUX_SHIFT, cstate->crtc_id, false);
4265 		vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
4266 				GRF_BT656_CLK_INV_SHIFT, !dclk_inv);
4267 	}
4268 
4269 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) {
4270 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT,
4271 				1, false);
4272 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4273 				LVDS0_MUX_SHIFT, cstate->crtc_id, false);
4274 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK,
4275 				IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
4276 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4277 				IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false);
4278 	}
4279 
4280 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) {
4281 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT,
4282 				1, false);
4283 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4284 				LVDS1_MUX_SHIFT, cstate->crtc_id, false);
4285 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK,
4286 				IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
4287 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4288 				IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false);
4289 	}
4290 
4291 
4292 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) {
4293 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT,
4294 				1, false);
4295 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4296 				MIPI0_MUX_SHIFT, cstate->crtc_id, false);
4297 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4298 				IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
4299 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_MIPI_PIN_POL_MASK,
4300 				IF_CTRL_MIPI_PIN_POL_SHIFT, val, false);
4301 	}
4302 
4303 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) {
4304 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT,
4305 				1, false);
4306 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4307 				MIPI1_MUX_SHIFT, cstate->crtc_id, false);
4308 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4309 				IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
4310 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_MIPI_PIN_POL_MASK,
4311 				IF_CTRL_MIPI_PIN_POL_SHIFT, val, false);
4312 	}
4313 
4314 	if (conn_state->output_flags &
4315 		    ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE ||
4316 	    conn_state->output_flags &
4317 		    ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE)
4318 		rk3568_vop2_setup_dual_channel_if(state);
4319 
4320 	if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) {
4321 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT,
4322 				1, false);
4323 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4324 				EDP0_MUX_SHIFT, cstate->crtc_id, false);
4325 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4326 				IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false);
4327 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_EDP_PIN_POL_MASK,
4328 				IF_CTRL_EDP_PIN_POL_SHIFT, val, false);
4329 	}
4330 
4331 	if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
4332 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
4333 				1, false);
4334 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4335 				HDMI0_MUX_SHIFT, cstate->crtc_id, false);
4336 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4337 				IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
4338 		vop2_mask_write(vop2, RK3568_DSP_IF_POL,
4339 				IF_CRTL_HDMI_PIN_POL_MASK,
4340 				IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
4341 	}
4342 
4343 	return mode->crtc_clock;
4344 }
4345 
4346 static unsigned long rk3562_vop2_if_cfg(struct display_state *state)
4347 {
4348 	struct crtc_state *cstate = &state->crtc_state;
4349 	struct connector_state *conn_state = &state->conn_state;
4350 	struct drm_display_mode *mode = &conn_state->mode;
4351 	struct vop2 *vop2 = cstate->private;
4352 	bool dclk_inv;
4353 	u32 vp_offset = (cstate->crtc_id * 0x100);
4354 	u32 val;
4355 
4356 	dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
4357 	val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
4358 	val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
4359 
4360 	if (conn_state->output_if & VOP_OUTPUT_IF_RGB) {
4361 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
4362 				1, false);
4363 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4364 				RGB_MUX_SHIFT, cstate->crtc_id, false);
4365 		vop2_grf_writel(vop2, vop2->grf, RK3562_GRF_IOC_VO_IO_CON, EN_MASK,
4366 				GRF_RGB_DCLK_INV_SHIFT, dclk_inv);
4367 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK,
4368 				IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
4369 	}
4370 
4371 	if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) {
4372 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT,
4373 				1, false);
4374 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4375 				LVDS0_MUX_SHIFT, cstate->crtc_id, false);
4376 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4377 				IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false);
4378 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK,
4379 				IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
4380 	}
4381 
4382 	if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) {
4383 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT,
4384 				1, false);
4385 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4386 				MIPI0_MUX_SHIFT, cstate->crtc_id, false);
4387 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4388 				RK3562_MIPI_DCLK_POL_SHIFT, dclk_inv, false);
4389 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK,
4390 				RK3562_MIPI_PIN_POL_SHIFT, val, false);
4391 
4392 		if (conn_state->hold_mode) {
4393 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
4394 					EN_MASK, EDPI_TE_EN, !cstate->soft_te, false);
4395 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
4396 					EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
4397 		}
4398 	}
4399 
4400 	return mode->crtc_clock;
4401 }
4402 
4403 static unsigned long rk3528_vop2_if_cfg(struct display_state *state)
4404 {
4405 	struct crtc_state *cstate = &state->crtc_state;
4406 	struct connector_state *conn_state = &state->conn_state;
4407 	struct drm_display_mode *mode = &conn_state->mode;
4408 	struct vop2 *vop2 = cstate->private;
4409 	u32 val;
4410 
4411 	val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
4412 	val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
4413 
4414 	if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
4415 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
4416 				1, false);
4417 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4418 				RGB_MUX_SHIFT, cstate->crtc_id, false);
4419 	}
4420 
4421 	if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
4422 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
4423 				1, false);
4424 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
4425 				HDMI0_MUX_SHIFT, cstate->crtc_id, false);
4426 		vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
4427 				IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
4428 		vop2_mask_write(vop2, RK3568_DSP_IF_POL,
4429 				IF_CRTL_HDMI_PIN_POL_MASK,
4430 				IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
4431 	}
4432 
4433 	return mode->crtc_clock;
4434 }
4435 
4436 static void vop2_post_color_swap(struct display_state *state)
4437 {
4438 	struct crtc_state *cstate = &state->crtc_state;
4439 	struct connector_state *conn_state = &state->conn_state;
4440 	struct vop2 *vop2 = cstate->private;
4441 	u32 vp_offset = (cstate->crtc_id * 0x100);
4442 	u32 output_type = conn_state->type;
4443 	u32 data_swap = 0;
4444 
4445 	if (is_uv_swap(state) || is_rb_swap(state))
4446 		data_swap = DSP_RB_SWAP;
4447 
4448 	if ((vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3576)) {
4449 		if ((output_type == DRM_MODE_CONNECTOR_HDMIA ||
4450 		     output_type == DRM_MODE_CONNECTOR_DisplayPort) &&
4451 		    (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
4452 		     conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30))
4453 		data_swap |= DSP_RG_SWAP;
4454 	}
4455 
4456 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
4457 			DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false);
4458 }
4459 
4460 static void vop2_clk_set_parent(struct clk *clk, struct clk *parent)
4461 {
4462 #ifndef CONFIG_MOS_SUPPORT
4463 	int ret = 0;
4464 
4465 	if (parent->dev)
4466 		ret = clk_set_parent(clk, parent);
4467 	if (ret < 0)
4468 		debug("failed to set %s as parent for %s\n",
4469 		      parent->dev->name, clk->dev->name);
4470 #endif
4471 }
4472 
4473 static ulong vop2_clk_set_rate(struct clk *clk, ulong rate)
4474 {
4475 	int ret = 0;
4476 
4477 	if (clk->dev)
4478 		ret = clk_set_rate(clk, rate);
4479 	if (ret < 0)
4480 		debug("failed to set %s rate %lu \n", clk->dev->name, rate);
4481 
4482 	return ret;
4483 }
4484 
4485 static void vop2_calc_dsc_cru_cfg(struct display_state *state,
4486 				  int *dsc_txp_clk_div, int *dsc_pxl_clk_div,
4487 				  int *dsc_cds_clk_div, u64 dclk_rate)
4488 {
4489 	struct crtc_state *cstate = &state->crtc_state;
4490 
4491 	*dsc_txp_clk_div = dclk_rate / cstate->dsc_txp_clk_rate;
4492 	*dsc_pxl_clk_div = dclk_rate / cstate->dsc_pxl_clk_rate;
4493 	*dsc_cds_clk_div = dclk_rate / cstate->dsc_cds_clk_rate;
4494 
4495 	*dsc_txp_clk_div = ilog2(*dsc_txp_clk_div);
4496 	*dsc_pxl_clk_div = ilog2(*dsc_pxl_clk_div);
4497 	*dsc_cds_clk_div = ilog2(*dsc_cds_clk_div);
4498 }
4499 
4500 static void vop2_load_pps(struct display_state *state, struct vop2 *vop2, u8 dsc_id)
4501 {
4502 	struct crtc_state *cstate = &state->crtc_state;
4503 	struct drm_dsc_picture_parameter_set *pps = &cstate->pps;
4504 	struct drm_dsc_picture_parameter_set config_pps;
4505 	const struct vop2_data *vop2_data = vop2->data;
4506 	const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
4507 	u32 *pps_val = (u32 *)&config_pps;
4508 	u32 decoder_regs_offset = (dsc_id * 0x100);
4509 	int i = 0;
4510 
4511 	memcpy(&config_pps, pps, sizeof(config_pps));
4512 
4513 	if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) {
4514 		config_pps.pps_3 &= 0xf0;
4515 		config_pps.pps_3 |= dsc_data->max_linebuf_depth;
4516 		printf("DSC%d max_linebuf_depth is: %d, current set value is: %d\n",
4517 		       dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf);
4518 	}
4519 
4520 	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
4521 		config_pps.rc_range_parameters[i] =
4522 			(pps->rc_range_parameters[i] >> 3 & 0x1f) |
4523 			((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) |
4524 			((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) |
4525 			((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10);
4526 	}
4527 
4528 	for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++)
4529 		vop2_writel(vop2, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++);
4530 }
4531 
4532 static void vop2_dsc_enable(struct display_state *state, struct vop2 *vop2, u8 dsc_id, u64 dclk_rate)
4533 {
4534 	struct connector_state *conn_state = &state->conn_state;
4535 	struct drm_display_mode *mode = &conn_state->mode;
4536 	struct crtc_state *cstate = &state->crtc_state;
4537 	struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap;
4538 	const struct vop2_data *vop2_data = vop2->data;
4539 	const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
4540 	bool mipi_ds_mode = false;
4541 	u8 dsc_interface_mode = 0;
4542 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
4543 	u16 hdisplay = mode->crtc_hdisplay;
4544 	u16 htotal = mode->crtc_htotal;
4545 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
4546 	u16 vdisplay = mode->crtc_vdisplay;
4547 	u16 vtotal = mode->crtc_vtotal;
4548 	u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
4549 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
4550 	u16 vact_end = vact_st + vdisplay;
4551 	u32 ctrl_regs_offset = (dsc_id * 0x30);
4552 	u32 decoder_regs_offset = (dsc_id * 0x100);
4553 	int dsc_txp_clk_div = 0;
4554 	int dsc_pxl_clk_div = 0;
4555 	int dsc_cds_clk_div = 0;
4556 	int val = 0;
4557 
4558 	if (!vop2->data->nr_dscs) {
4559 		printf("Unsupported DSC\n");
4560 		return;
4561 	}
4562 
4563 	if (cstate->dsc_slice_num > dsc_data->max_slice_num)
4564 		printf("DSC%d supported max slice is: %d, current is: %d\n",
4565 		       dsc_data->id, dsc_data->max_slice_num, cstate->dsc_slice_num);
4566 
4567 	if (dsc_data->pd_id) {
4568 		if (vop2_power_domain_on(vop2, dsc_data->pd_id))
4569 			printf("open dsc%d pd fail\n", dsc_id);
4570 	}
4571 
4572 	vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK,
4573 			SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, false);
4574 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK,
4575 			DSC_PORT_SEL_SHIFT, cstate->crtc_id, false);
4576 	if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
4577 		dsc_interface_mode = VOP_DSC_IF_HDMI;
4578 	} else {
4579 		mipi_ds_mode = !!(conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE);
4580 		if (mipi_ds_mode)
4581 			dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE;
4582 		else
4583 			dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE;
4584 	}
4585 
4586 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
4587 		vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
4588 				DSC_MAN_MODE_SHIFT, 0, false);
4589 	else
4590 		vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
4591 				DSC_MAN_MODE_SHIFT, 1, false);
4592 
4593 	vop2_calc_dsc_cru_cfg(state, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate);
4594 
4595 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK,
4596 			DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, false);
4597 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK,
4598 			DSC_PIXEL_NUM_SHIFT, cstate->dsc_pixel_num >> 1, false);
4599 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK,
4600 			DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, false);
4601 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK,
4602 			DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, false);
4603 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
4604 			DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, false);
4605 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK,
4606 			DSC_SCAN_EN_SHIFT, !mipi_ds_mode, false);
4607 	vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
4608 			DSC_HALT_EN_SHIFT, mipi_ds_mode, false);
4609 
4610 	if (!mipi_ds_mode) {
4611 		u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end;
4612 		u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16;
4613 		u64 dsc_cds_rate = cstate->dsc_cds_clk_rate;
4614 		u32 v_pixclk_mhz = mode->crtc_clock / 1000; /* video timing pixclk */
4615 		u32 dly_num, dsc_cds_rate_mhz, val = 0;
4616 		int k = 1;
4617 
4618 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
4619 			k = 2;
4620 
4621 		if (target_bpp >> 4 < dsc_data->min_bits_per_pixel)
4622 			printf("Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel);
4623 
4624 		/*
4625 		 * dly_num = delay_line_num * T(one-line) / T (dsc_cds)
4626 		 * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz
4627 		 * T (dsc_cds) = 1 / dsc_cds_rate_mhz
4628 		 *
4629 		 * HDMI:
4630 		 * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay
4631 		 *                 delay_line_num = 4 - BPP / 8
4632 		 *                                = (64 - target_bpp / 8) / 16
4633 		 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
4634 		 *
4635 		 * MIPI DSI[4320 and 9216 is buffer size for DSC]:
4636 		 * DSC0:delay_line_num = 4320 * 8 / slince_num / chunk_size;
4637 		 *	delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
4638 		 * DSC1:delay_line_num = 9216 * 2 / slince_num / chunk_size;
4639 		 *	delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
4640 		 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num
4641 		 */
4642 		do_div(dsc_cds_rate, 1000000); /* hz to Mhz */
4643 		dsc_cds_rate_mhz = dsc_cds_rate;
4644 		dsc_hsync = hsync_len / 2;
4645 		if (dsc_interface_mode == VOP_DSC_IF_HDMI) {
4646 			dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
4647 		} else {
4648 			int dsc_buf_size  = dsc_id == 0 ? 4320 * 8 : 9216 * 2;
4649 			int delay_line_num = dsc_buf_size / cstate->dsc_slice_num /
4650 					     be16_to_cpu(cstate->pps.chunk_size);
4651 
4652 			delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
4653 			dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num;
4654 
4655 			/* The dsc mipi video mode dsc_hsync minimum size is 8 pixels */
4656 			if (dsc_hsync < 8)
4657 				dsc_hsync = 8;
4658 		}
4659 		vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK,
4660 				DSC_INIT_DLY_MODE_SHIFT, 0, false);
4661 		vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK,
4662 				DSC_INIT_DLY_NUM_SHIFT, dly_num, false);
4663 
4664 		/*
4665 		 * htotal / dclk_core = dsc_htotal /cds_clk
4666 		 *
4667 		 * dclk_core = DCLK / (1 << dclk_core->div_val)
4668 		 * cds_clk = txp_clk / (1 << dsc_cds_clk->div_val)
4669 		 * txp_clk = DCLK / (1 << dsc_txp_clk->div_val)
4670 		 *
4671 		 * dsc_htotal = htotal * (1 << dclk_core->div_val) /
4672 		 *              ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val))
4673 		 */
4674 		dsc_htotal = htotal * (1 << cstate->dclk_core_div) /
4675 			     ((1 << dsc_txp_clk_div) * (1 << dsc_cds_clk_div));
4676 		val = dsc_htotal << 16 | dsc_hsync;
4677 		vop2_mask_write(vop2, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK,
4678 				DSC_HTOTAL_PW_SHIFT, val, false);
4679 
4680 		dsc_hact_st = hact_st / 2;
4681 		dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st;
4682 		val = dsc_hact_end << 16 | dsc_hact_st;
4683 		vop2_mask_write(vop2, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK,
4684 				DSC_HACT_ST_END_SHIFT, val, false);
4685 
4686 		vop2_mask_write(vop2, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK,
4687 				DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, false);
4688 		vop2_mask_write(vop2, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK,
4689 				DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, false);
4690 	}
4691 
4692 	vop2_mask_write(vop2, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK,
4693 			RST_DEASSERT_SHIFT, 1, false);
4694 	udelay(10);
4695 
4696 	val |= DSC_CTRL0_DEF_CON | (ilog2(cstate->dsc_slice_num) << DSC_NSLC_SHIFT) |
4697 	       ((dsc_sink_cap->version_minor == 2 ? 1 : 0) << DSC_IFEP_SHIFT);
4698 	vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
4699 
4700 	vop2_load_pps(state, vop2, dsc_id);
4701 
4702 	val |= (1 << DSC_PPS_UPD_SHIFT);
4703 	vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
4704 
4705 	printf("DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n",
4706 	       dsc_id,
4707 	       cstate->dsc_txp_clk_rate, dsc_txp_clk_div,
4708 	       cstate->dsc_pxl_clk_rate, dsc_pxl_clk_div,
4709 	       cstate->dsc_cds_clk_rate, dsc_cds_clk_div);
4710 }
4711 
4712 static bool is_extend_pll(struct display_state *state, struct udevice **clk_dev)
4713 {
4714 	struct crtc_state *cstate = &state->crtc_state;
4715 	struct vop2 *vop2 = cstate->private;
4716 	struct udevice *vp_dev, *dev;
4717 	struct ofnode_phandle_args args;
4718 	char vp_name[10];
4719 	int ret;
4720 
4721 	if (vop2->version != VOP_VERSION_RK3588 && vop2->version != VOP_VERSION_RK3576)
4722 		return false;
4723 
4724 	sprintf(vp_name, "port@%d", cstate->crtc_id);
4725 	if (uclass_find_device_by_name(UCLASS_VIDEO_CRTC, vp_name, &vp_dev)) {
4726 		debug("warn: can't get vp device\n");
4727 		return false;
4728 	}
4729 
4730 	ret = dev_read_phandle_with_args(vp_dev, "assigned-clock-parents", "#clock-cells", 0,
4731 					 0, &args);
4732 	if (ret) {
4733 		debug("assigned-clock-parents's node not define\n");
4734 		return false;
4735 	}
4736 
4737 	if (uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &dev)) {
4738 		debug("warn: can't get clk device\n");
4739 		return false;
4740 	}
4741 
4742 	if (!strcmp(dev->name, "hdmiphypll_clk0") || !strcmp(dev->name, "hdmiphypll_clk1")) {
4743 		printf("%s: clk dev :%s: vp port:%s\n", __func__, dev->name, vp_dev->name);
4744 		if (clk_dev)
4745 			*clk_dev = dev;
4746 		return true;
4747 	}
4748 
4749 	return false;
4750 }
4751 
4752 static void vop3_mcu_mode_setup(struct display_state *state)
4753 {
4754 	struct crtc_state *cstate = &state->crtc_state;
4755 	struct vop2 *vop2 = cstate->private;
4756 	u32 vp_offset = (cstate->crtc_id * 0x100);
4757 
4758 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4759 			MCU_TYPE_SHIFT, 1, false);
4760 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4761 			MCU_HOLD_MODE_SHIFT, 1, false);
4762 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK,
4763 			MCU_PIX_TOTAL_SHIFT, cstate->mcu_timing.mcu_pix_total, false);
4764 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK,
4765 			MCU_CS_PST_SHIFT, cstate->mcu_timing.mcu_cs_pst, false);
4766 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK,
4767 			MCU_CS_PEND_SHIFT, cstate->mcu_timing.mcu_cs_pend, false);
4768 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK,
4769 			MCU_RW_PST_SHIFT, cstate->mcu_timing.mcu_rw_pst, false);
4770 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK,
4771 			MCU_RW_PEND_SHIFT, cstate->mcu_timing.mcu_rw_pend, false);
4772 }
4773 
4774 static void vop3_mcu_bypass_mode_setup(struct display_state *state)
4775 {
4776 	struct crtc_state *cstate = &state->crtc_state;
4777 	struct vop2 *vop2 = cstate->private;
4778 	u32 vp_offset = (cstate->crtc_id * 0x100);
4779 
4780 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4781 			MCU_TYPE_SHIFT, 1, false);
4782 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4783 			MCU_HOLD_MODE_SHIFT, 1, false);
4784 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK,
4785 			MCU_PIX_TOTAL_SHIFT, 53, false);
4786 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK,
4787 			MCU_CS_PST_SHIFT, 6, false);
4788 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK,
4789 			MCU_CS_PEND_SHIFT, 48, false);
4790 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK,
4791 			MCU_RW_PST_SHIFT, 12, false);
4792 	vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK,
4793 			MCU_RW_PEND_SHIFT, 30, false);
4794 }
4795 
4796 static int rockchip_vop2_send_mcu_cmd(struct display_state *state, u32 type, u32 value)
4797 {
4798 	struct crtc_state *cstate = &state->crtc_state;
4799 	struct connector_state *conn_state = &state->conn_state;
4800 	struct drm_display_mode *mode = &conn_state->mode;
4801 	struct vop2 *vop2 = cstate->private;
4802 	u32 vp_offset = (cstate->crtc_id * 0x100);
4803 
4804 	/*
4805 	 * 1.set mcu bypass mode timing.
4806 	 * 2.set dclk rate to 150M.
4807 	 */
4808 	if (type == MCU_SETBYPASS && value) {
4809 		vop3_mcu_bypass_mode_setup(state);
4810 		vop2_clk_set_rate(&cstate->dclk, 150000000);
4811 	}
4812 
4813 	switch (type) {
4814 	case MCU_WRCMD:
4815 		vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4816 				MCU_RS_SHIFT, 0, false);
4817 		vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset,
4818 				MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT,
4819 				value, false);
4820 		vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4821 				MCU_RS_SHIFT, 1, false);
4822 		break;
4823 	case MCU_WRDATA:
4824 		vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4825 				MCU_RS_SHIFT, 1, false);
4826 		vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset,
4827 				MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT,
4828 				value, false);
4829 		break;
4830 	case MCU_SETBYPASS:
4831 		vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4832 				MCU_BYPASS_SHIFT, value ? 1 : 0, false);
4833 		break;
4834 	default:
4835 		break;
4836 	}
4837 
4838 	/*
4839 	 * 1.restore mcu data mode timing.
4840 	 * 2.restore dclk rate to crtc_clock.
4841 	 */
4842 	if (type == MCU_SETBYPASS && !value) {
4843 		vop3_mcu_mode_setup(state);
4844 		vop2_clk_set_rate(&cstate->dclk, mode->crtc_clock * 1000);
4845 	}
4846 
4847 	return 0;
4848 }
4849 
4850 static void vop2_dither_setup(struct vop2 *vop2, int bus_format, int crtc_id)
4851 {
4852 	const struct vop2_data *vop2_data = vop2->data;
4853 	const struct vop2_vp_data *vp_data = &vop2_data->vp_data[crtc_id];
4854 	u32 vp_offset = crtc_id * 0x100;
4855 	bool pre_dither_down_en = false;
4856 
4857 	switch (bus_format) {
4858 	case MEDIA_BUS_FMT_RGB565_1X16:
4859 	case MEDIA_BUS_FMT_RGB565_2X8_LE:
4860 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4861 				PRE_DITHER_DOWN_EN_SHIFT, true, false);
4862 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4863 				DITHER_DOWN_MODE_SHIFT, RGB888_TO_RGB565, false);
4864 		pre_dither_down_en = true;
4865 		break;
4866 	case MEDIA_BUS_FMT_RGB666_1X18:
4867 	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
4868 	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
4869 	case MEDIA_BUS_FMT_RGB666_3X6:
4870 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4871 				PRE_DITHER_DOWN_EN_SHIFT, true, false);
4872 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4873 				DITHER_DOWN_MODE_SHIFT, RGB888_TO_RGB666, false);
4874 		pre_dither_down_en = true;
4875 		break;
4876 	case MEDIA_BUS_FMT_YUYV8_1X16:
4877 	case MEDIA_BUS_FMT_YUV8_1X24:
4878 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
4879 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4880 				PRE_DITHER_DOWN_EN_SHIFT, false, false);
4881 		pre_dither_down_en = true;
4882 		break;
4883 	case MEDIA_BUS_FMT_YUYV10_1X20:
4884 	case MEDIA_BUS_FMT_YUV10_1X30:
4885 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
4886 	case MEDIA_BUS_FMT_RGB101010_1X30:
4887 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4888 				PRE_DITHER_DOWN_EN_SHIFT, false, false);
4889 		pre_dither_down_en = false;
4890 		break;
4891 	case MEDIA_BUS_FMT_RGB888_3X8:
4892 	case MEDIA_BUS_FMT_RGB888_DUMMY_4X8:
4893 	case MEDIA_BUS_FMT_RGB888_1X24:
4894 	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
4895 	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
4896 	default:
4897 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4898 				PRE_DITHER_DOWN_EN_SHIFT, false, false);
4899 		pre_dither_down_en = true;
4900 		break;
4901 	}
4902 
4903 	if (is_yuv_output(bus_format) && (vp_data->feature & VOP_FEATURE_POST_FRC_V2) == 0)
4904 		pre_dither_down_en = false;
4905 
4906 	if ((vp_data->feature & VOP_FEATURE_POST_FRC_V2) && pre_dither_down_en) {
4907 		if (vop2->version == VOP_VERSION_RK3576) {
4908 			vop2_writel(vop2, RK3576_VP0_POST_DITHER_FRC_0 + vp_offset, 0x00000000);
4909 			vop2_writel(vop2, RK3576_VP0_POST_DITHER_FRC_1 + vp_offset, 0x01000100);
4910 			vop2_writel(vop2, RK3576_VP0_POST_DITHER_FRC_2 + vp_offset, 0x04030100);
4911 		}
4912 
4913 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4914 				PRE_DITHER_DOWN_EN_SHIFT, 0, false);
4915 		/* enable frc2.0 do 10->8 */
4916 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4917 				DITHER_DOWN_EN_SHIFT, 1, false);
4918 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, DITHER_DOWN_SEL_MASK,
4919 				DITHER_DOWN_SEL_SHIFT, DITHER_DOWN_FRC, false);
4920 	} else {
4921 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4922 				PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false);
4923 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, DITHER_DOWN_SEL_MASK,
4924 				DITHER_DOWN_SEL_SHIFT, DITHER_DOWN_ALLEGRO, false);
4925 	}
4926 }
4927 
4928 static int rockchip_vop2_init(struct display_state *state)
4929 {
4930 	struct crtc_state *cstate = &state->crtc_state;
4931 	struct rockchip_vp *vp = &cstate->crtc->vps[cstate->crtc_id];
4932 	struct connector_state *conn_state = &state->conn_state;
4933 	struct drm_display_mode *mode = &conn_state->mode;
4934 	struct vop2 *vop2 = cstate->private;
4935 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
4936 	u16 hdisplay = mode->crtc_hdisplay;
4937 	u16 htotal = mode->crtc_htotal;
4938 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
4939 	u16 hact_end = hact_st + hdisplay;
4940 	u16 vdisplay = mode->crtc_vdisplay;
4941 	u16 vtotal = mode->crtc_vtotal;
4942 	u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
4943 	u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
4944 	u16 vact_end = vact_st + vdisplay;
4945 	bool yuv_overlay = false;
4946 	u32 vp_offset = (cstate->crtc_id * 0x100);
4947 	u32 line_flag_offset = (cstate->crtc_id * 4);
4948 	u32 val, act_end;
4949 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
4950 	u8 dclk_div_factor = 0;
4951 	u8 vp_dclk_div = 1;
4952 	char output_type_name[30] = {0};
4953 #ifndef CONFIG_SPL_BUILD
4954 	char dclk_name[9];
4955 #endif
4956 	struct clk hdmi0_phy_pll;
4957 	struct clk hdmi1_phy_pll;
4958 	struct clk hdmi_phy_pll;
4959 	struct udevice *disp_dev;
4960 	unsigned long dclk_rate = 0;
4961 	int ret;
4962 
4963 	printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n",
4964 	       mode->crtc_hdisplay, mode->vdisplay,
4965 	       mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
4966 	       mode->vrefresh,
4967 	       rockchip_get_output_if_name(conn_state->output_if, output_type_name),
4968 	       cstate->crtc_id);
4969 
4970 	if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
4971 		cstate->splice_mode = true;
4972 		cstate->splice_crtc_id = vop2->data->vp_data[cstate->crtc_id].splice_vp_id;
4973 		if (!cstate->splice_crtc_id) {
4974 			printf("%s: Splice mode is unsupported by vp%d\n",
4975 			       __func__, cstate->crtc_id);
4976 			return -EINVAL;
4977 		}
4978 
4979 		vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, EN_MASK,
4980 				PORT_MERGE_EN_SHIFT, 1, false);
4981 	}
4982 
4983 	vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK,
4984 			RK3588_VP0_LINE_FLAG_OR_EN_SHIFT + cstate->crtc_id, 1, false);
4985 	vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK,
4986 			RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT + cstate->crtc_id, 1, false);
4987 
4988 	if (vop2->data->vp_data[cstate->crtc_id].urgency) {
4989 		u8 urgen_thl = vop2->data->vp_data[cstate->crtc_id].urgency->urgen_thl;
4990 		u8 urgen_thh = vop2->data->vp_data[cstate->crtc_id].urgency->urgen_thh;
4991 
4992 		vop2_mask_write(vop2, RK3576_SYS_AXI_HURRY_CTRL0_IMD, EN_MASK,
4993 				AXI0_PORT_URGENCY_EN_SHIFT + cstate->crtc_id, 1, false);
4994 		vop2_mask_write(vop2, RK3576_SYS_AXI_HURRY_CTRL1_IMD, EN_MASK,
4995 				AXI1_PORT_URGENCY_EN_SHIFT + cstate->crtc_id, 1, false);
4996 		vop2_mask_write(vop2, RK3568_VP0_COLOR_BAR_CTRL + vp_offset, EN_MASK,
4997 				POST_URGENCY_EN_SHIFT, 1, false);
4998 		vop2_mask_write(vop2, RK3568_VP0_COLOR_BAR_CTRL + vp_offset, POST_URGENCY_THL_MASK,
4999 				POST_URGENCY_THL_SHIFT, urgen_thl, false);
5000 		vop2_mask_write(vop2, RK3568_VP0_COLOR_BAR_CTRL + vp_offset, POST_URGENCY_THH_MASK,
5001 				POST_URGENCY_THH_SHIFT, urgen_thh, false);
5002 	}
5003 
5004 	vop2_initial(vop2, state);
5005 	if (vop2->version == VOP_VERSION_RK3588)
5006 		dclk_rate = rk3588_vop2_if_cfg(state);
5007 	else if (vop2->version == VOP_VERSION_RK3576)
5008 		dclk_rate = rk3576_vop2_if_cfg(state);
5009 	else if (vop2->version == VOP_VERSION_RK3568)
5010 		dclk_rate = rk3568_vop2_if_cfg(state);
5011 	else if (vop2->version == VOP_VERSION_RK3562)
5012 		dclk_rate = rk3562_vop2_if_cfg(state);
5013 	else if (vop2->version == VOP_VERSION_RK3528)
5014 		dclk_rate = rk3528_vop2_if_cfg(state);
5015 
5016 	if ((conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
5017 	     !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT)) ||
5018 	    conn_state->output_if & VOP_OUTPUT_IF_BT656)
5019 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
5020 
5021 	if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
5022 		if (vop2->version == VOP_VERSION_RK3588 &&
5023 		    conn_state->type == DRM_MODE_CONNECTOR_DisplayPort)
5024 			conn_state->output_mode = RK3588_DP_OUT_MODE_YUV420;
5025 	} else if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV422) {
5026 		if (vop2->version == VOP_VERSION_RK3576 &&
5027 		    conn_state->type == DRM_MODE_CONNECTOR_eDP)
5028 			conn_state->output_mode = RK3576_EDP_OUT_MODE_YUV422;
5029 		else if (vop2->version == VOP_VERSION_RK3588 &&
5030 			 conn_state->type == DRM_MODE_CONNECTOR_eDP)
5031 			conn_state->output_mode = RK3588_EDP_OUTPUT_MODE_YUV422;
5032 		else if (vop2->version == VOP_VERSION_RK3576 &&
5033 			 conn_state->type == DRM_MODE_CONNECTOR_HDMIA)
5034 			conn_state->output_mode = RK3576_HDMI_OUT_MODE_YUV422;
5035 		else if (conn_state->type == DRM_MODE_CONNECTOR_DisplayPort)
5036 			conn_state->output_mode = RK3588_DP_OUT_MODE_YUV422;
5037 	}
5038 
5039 	vop2_post_color_swap(state);
5040 
5041 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK,
5042 			OUT_MODE_SHIFT, conn_state->output_mode, false);
5043 
5044 	vop2_dither_setup(vop2, conn_state->bus_format, cstate->crtc_id);
5045 	if (cstate->splice_mode)
5046 		vop2_dither_setup(vop2, conn_state->bus_format, cstate->splice_crtc_id);
5047 
5048 	yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0;
5049 	vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id,
5050 			yuv_overlay, false);
5051 
5052 	cstate->yuv_overlay = yuv_overlay;
5053 
5054 	vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset,
5055 		    (htotal << 16) | hsync_len);
5056 	val = hact_st << 16;
5057 	val |= hact_end;
5058 	vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val);
5059 	val = vact_st << 16;
5060 	val |= vact_end;
5061 	vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val);
5062 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
5063 		u16 vact_st_f1 = vtotal + vact_st + 1;
5064 		u16 vact_end_f1 = vact_st_f1 + vdisplay;
5065 
5066 		val = vact_st_f1 << 16 | vact_end_f1;
5067 		vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset,
5068 			    val);
5069 
5070 		val = vtotal << 16 | (vtotal + vsync_len);
5071 		vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val);
5072 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5073 				INTERLACE_EN_SHIFT, 1, false);
5074 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5075 				DSP_FILED_POL, 1, false);
5076 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5077 				P2I_EN_SHIFT, 1, false);
5078 		vtotal += vtotal + 1;
5079 		act_end = vact_end_f1;
5080 	} else {
5081 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5082 				INTERLACE_EN_SHIFT, 0, false);
5083 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5084 				P2I_EN_SHIFT, 0, false);
5085 		act_end = vact_end;
5086 	}
5087 	vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset,
5088 		    (vtotal << 16) | vsync_len);
5089 
5090 	if (vop2->version == VOP_VERSION_RK3528 ||
5091 	    vop2->version == VOP_VERSION_RK3562 ||
5092 	    vop2->version == VOP_VERSION_RK3568) {
5093 		if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
5094 		conn_state->output_if & VOP_OUTPUT_IF_BT656)
5095 			vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5096 					CORE_DCLK_DIV_EN_SHIFT, 1, false);
5097 		else
5098 			vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5099 					CORE_DCLK_DIV_EN_SHIFT, 0, false);
5100 
5101 		if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420)
5102 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
5103 					DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false);
5104 		else
5105 			vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
5106 					DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false);
5107 	}
5108 
5109 	vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK,
5110 			OVL_MODE_SEL_SHIFT + cstate->crtc_id, yuv_overlay, false);
5111 
5112 	if (yuv_overlay)
5113 		val = 0x20010200;
5114 	else
5115 		val = 0;
5116 	vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val);
5117 	if (cstate->splice_mode) {
5118 		vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK,
5119 				OVL_MODE_SEL_SHIFT + cstate->splice_crtc_id,
5120 				yuv_overlay, false);
5121 		vop2_writel(vop2, RK3568_VP0_DSP_BG + (cstate->splice_crtc_id * 0x100), val);
5122 	}
5123 
5124 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5125 			POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false);
5126 
5127 	if (vp->xmirror_en)
5128 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5129 				DSP_X_MIR_EN_SHIFT, 1, false);
5130 
5131 	vop2_tv_config_update(state, vop2);
5132 	vop2_post_config(state, vop2);
5133 	if (cstate->feature & (VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC))
5134 		vop3_post_config(state, vop2);
5135 
5136 	if (cstate->dsc_enable) {
5137 		if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
5138 			vop2_dsc_enable(state, vop2, 0, dclk_rate * 1000LL);
5139 			vop2_dsc_enable(state, vop2, 1, dclk_rate * 1000LL);
5140 		} else {
5141 			vop2_dsc_enable(state, vop2, cstate->dsc_id, dclk_rate * 1000LL);
5142 		}
5143 	}
5144 
5145 #ifndef CONFIG_SPL_BUILD
5146 	snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id);
5147 	ret = clk_get_by_name(cstate->dev, dclk_name, &cstate->dclk);
5148 	if (ret) {
5149 		printf("%s: Failed to get dclk ret=%d\n", __func__, ret);
5150 		return ret;
5151 	}
5152 #endif
5153 
5154 	ret = uclass_get_device_by_name(UCLASS_VIDEO, "display-subsystem", &disp_dev);
5155 	if (!ret) {
5156 		ret = clk_get_by_name(disp_dev, "hdmi0_phy_pll", &hdmi0_phy_pll);
5157 		if (ret)
5158 			debug("%s: hdmi0_phy_pll may not define\n", __func__);
5159 		ret = clk_get_by_name(disp_dev, "hdmi1_phy_pll", &hdmi1_phy_pll);
5160 		if (ret)
5161 			debug("%s: hdmi1_phy_pll may not define\n", __func__);
5162 	} else {
5163 		hdmi0_phy_pll.dev = NULL;
5164 		hdmi1_phy_pll.dev = NULL;
5165 		debug("%s: Faile to find display-subsystem node\n", __func__);
5166 	}
5167 
5168 	if (vop2->version == VOP_VERSION_RK3528) {
5169 		struct ofnode_phandle_args args;
5170 
5171 		ret = dev_read_phandle_with_args(cstate->dev, "assigned-clock-parents",
5172 						 "#clock-cells", 0, 0, &args);
5173 		if (!ret) {
5174 			ret = uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &hdmi0_phy_pll.dev);
5175 			if (ret) {
5176 				debug("warn: can't get clk device\n");
5177 				return ret;
5178 			}
5179 		} else {
5180 			debug("assigned-clock-parents's node not define\n");
5181 		}
5182 	}
5183 
5184 	if (vop2->version == VOP_VERSION_RK3576)
5185 		vp_dclk_div = cstate->crtc->vps[cstate->crtc_id].dclk_div;
5186 
5187 	if (mode->crtc_clock < VOP2_MAX_DCLK_RATE) {
5188 		if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0)
5189 			vop2_clk_set_parent(&cstate->dclk, &hdmi0_phy_pll);
5190 		else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1)
5191 			vop2_clk_set_parent(&cstate->dclk, &hdmi1_phy_pll);
5192 
5193 		/*
5194 		 * uboot clk driver won't set dclk parent's rate when use
5195 		 * hdmi phypll as dclk source.
5196 		 * So set dclk rate is meaningless. Set hdmi phypll rate
5197 		 * directly.
5198 		 */
5199 		if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev) {
5200 			ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate / vp_dclk_div * 1000);
5201 		} else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev) {
5202 			ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate / vp_dclk_div * 1000);
5203 		} else {
5204 			if (is_extend_pll(state, &hdmi_phy_pll.dev)) {
5205 				ret = vop2_clk_set_rate(&hdmi_phy_pll,
5206 							dclk_rate / vp_dclk_div * 1000);
5207 			} else {
5208 #ifndef CONFIG_SPL_BUILD
5209 				ret = vop2_clk_set_rate(&cstate->dclk,
5210 							dclk_rate / vp_dclk_div * 1000);
5211 #else
5212 				if (vop2->version == VOP_VERSION_RK3528) {
5213 					void *cru_base = (void *)RK3528_CRU_BASE;
5214 
5215 					/* dclk src switch to hdmiphy pll */
5216 					writel((BIT(0) << 16) | BIT(0), cru_base + 0x450);
5217 					rockchip_phy_set_pll(conn_state->connector->phy, dclk_rate * 1000);
5218 					ret = dclk_rate * 1000;
5219 				}
5220 #endif
5221 			}
5222 		}
5223 	} else {
5224 		if (is_extend_pll(state, &hdmi_phy_pll.dev))
5225 			ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate / vp_dclk_div * 1000);
5226 		else
5227 			ret = vop2_clk_set_rate(&cstate->dclk, dclk_rate / vp_dclk_div * 1000);
5228 	}
5229 
5230 	if (IS_ERR_VALUE(ret)) {
5231 		printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n",
5232 		       __func__, cstate->crtc_id, dclk_rate, ret);
5233 		return ret;
5234 	} else {
5235 		if (cstate->mcu_timing.mcu_pix_total) {
5236 			mode->crtc_clock = roundup(ret, 1000) / 1000;
5237 		} else {
5238 			dclk_div_factor = mode->crtc_clock / dclk_rate;
5239 			mode->crtc_clock = roundup(ret, 1000) * dclk_div_factor / 1000;
5240 		}
5241 		printf("VP%d set crtc_clock to %dKHz\n", cstate->crtc_id, mode->crtc_clock);
5242 	}
5243 
5244 	vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
5245 			RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false);
5246 	vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
5247 			RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false);
5248 
5249 	if (cstate->mcu_timing.mcu_pix_total) {
5250 		vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
5251 		vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5252 				STANDBY_EN_SHIFT, 0, false);
5253 		vop3_mcu_mode_setup(state);
5254 	}
5255 
5256 	return 0;
5257 }
5258 
5259 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win,
5260 			     uint32_t src_w, uint32_t src_h, uint32_t dst_w,
5261 			     uint32_t dst_h)
5262 {
5263 	uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
5264 	uint16_t hscl_filter_mode, vscl_filter_mode;
5265 	uint8_t xgt2 = 0, xgt4 = 0;
5266 	uint8_t ygt2 = 0, ygt4 = 0;
5267 	uint32_t xfac = 0, yfac = 0;
5268 	u32 win_offset = win->reg_offset;
5269 	bool xgt_en = false;
5270 	bool xavg_en = false;
5271 
5272 	if (is_vop3(vop2)) {
5273 		if (vop2->version == VOP_VERSION_RK3576 && win->type == CLUSTER_LAYER) {
5274 			if (src_w >= (8 * dst_w)) {
5275 				xgt4 = 1;
5276 				src_w >>= 2;
5277 			} else if (src_w >= (4 * dst_w)) {
5278 				xgt2 = 1;
5279 				src_w >>= 1;
5280 			}
5281 		} else {
5282 			if (src_w >= (4 * dst_w)) {
5283 				xgt4 = 1;
5284 				src_w >>= 2;
5285 			} else if (src_w >= (2 * dst_w)) {
5286 				xgt2 = 1;
5287 				src_w >>= 1;
5288 			}
5289 		}
5290 	}
5291 
5292 	/**
5293 	 * The rk3528 is processed as 2 pixel/cycle,
5294 	 * so ygt2/ygt4 needs to be triggered in advance to improve performance
5295 	 * when src_w is bigger than 1920.
5296 	 * dst_h / src_h is at [1, 0.65)     ygt2=0; ygt4=0;
5297 	 * dst_h / src_h is at [0.65, 0.35)  ygt2=1; ygt4=0;
5298 	 * dst_h / src_h is at [0.35, 0)     ygt2=0; ygt4=1;
5299 	 */
5300 	if (vop2->version == VOP_VERSION_RK3528 && src_w > 1920) {
5301 		if (src_h >= (100 * dst_h / 35)) {
5302 			ygt4 = 1;
5303 			src_h >>= 2;
5304 		} else if ((src_h >= 100 * dst_h / 65) && (src_h < 100 * dst_h / 35)) {
5305 			ygt2 = 1;
5306 			src_h >>= 1;
5307 		}
5308 	} else {
5309 		if (win->vsd_filter_mode == VOP2_SCALE_DOWN_ZME) {
5310 			if (src_h >= (8 * dst_h)) {
5311 				ygt4 = 1;
5312 				src_h >>= 2;
5313 			} else if (src_h >= (4 * dst_h)) {
5314 				ygt2 = 1;
5315 				src_h >>= 1;
5316 			}
5317 		} else {
5318 			if (src_h >= (4 * dst_h)) {
5319 				ygt4 = 1;
5320 				src_h >>= 2;
5321 			} else if (src_h >= (2 * dst_h)) {
5322 				ygt2 = 1;
5323 				src_h >>= 1;
5324 			}
5325 		}
5326 	}
5327 
5328 	yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
5329 	yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
5330 
5331 	if (yrgb_hor_scl_mode == SCALE_UP)
5332 		hscl_filter_mode = win->hsu_filter_mode;
5333 	else
5334 		hscl_filter_mode = win->hsd_filter_mode;
5335 
5336 	if (yrgb_ver_scl_mode == SCALE_UP)
5337 		vscl_filter_mode = win->vsu_filter_mode;
5338 	else
5339 		vscl_filter_mode = win->vsd_filter_mode;
5340 
5341 	/*
5342 	 * RK3568 VOP Esmart/Smart dsp_w should be even pixel
5343 	 * at scale down mode
5344 	 */
5345 	if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1) && !is_vop3(vop2)) {
5346 		printf("win dst_w[%d] should align as 2 pixel\n", dst_w);
5347 		dst_w += 1;
5348 	}
5349 
5350 	if (is_vop3(vop2)) {
5351 		xfac = vop3_scale_factor(yrgb_hor_scl_mode, src_w, dst_w, true);
5352 		yfac = vop3_scale_factor(yrgb_ver_scl_mode, src_h, dst_h, false);
5353 
5354 		if (win->hsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_AVG)
5355 			xavg_en = xgt2 || xgt4;
5356 		else
5357 			xgt_en = xgt2 || xgt4;
5358 
5359 		if (vop2->version == VOP_VERSION_RK3576) {
5360 			bool zme_dering_en = false;
5361 
5362 			if ((yrgb_hor_scl_mode == SCALE_UP &&
5363 			     hscl_filter_mode == VOP2_SCALE_UP_ZME) ||
5364 			    (yrgb_ver_scl_mode == SCALE_UP &&
5365 			     vscl_filter_mode == VOP2_SCALE_UP_ZME))
5366 				zme_dering_en = true;
5367 
5368 			/* Recommended configuration from the algorithm */
5369 			vop2_writel(vop2, RK3576_CLUSTER0_WIN0_ZME_DERING_PARA + win_offset,
5370 				    0x04100d10);
5371 			vop2_mask_write(vop2, RK3576_CLUSTER0_WIN0_ZME_CTRL + win_offset,
5372 					EN_MASK, WIN0_ZME_DERING_EN_SHIFT, zme_dering_en, false);
5373 		}
5374 	} else {
5375 		xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w);
5376 		yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h);
5377 	}
5378 
5379 	if (win->type == CLUSTER_LAYER) {
5380 		vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset,
5381 			    yfac << 16 | xfac);
5382 
5383 		if (is_vop3(vop2)) {
5384 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5385 					EN_MASK, CLUSTER_XGT_EN_SHIFT, xgt_en, false);
5386 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5387 					EN_MASK, CLUSTER_XAVG_EN_SHIFT, xavg_en, false);
5388 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5389 					XGT_MODE_MASK, CLUSTER_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false);
5390 
5391 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5392 					YRGB_XSCL_MODE_MASK, RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT,
5393 					yrgb_hor_scl_mode, false);
5394 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5395 					YRGB_YSCL_MODE_MASK, RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT,
5396 					yrgb_ver_scl_mode, false);
5397 		} else {
5398 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5399 					YRGB_XSCL_MODE_MASK, RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT,
5400 					yrgb_hor_scl_mode, false);
5401 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5402 					YRGB_YSCL_MODE_MASK, RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT,
5403 					yrgb_ver_scl_mode, false);
5404 		}
5405 
5406 		if (!is_vop3(vop2) || win->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) {
5407 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5408 					YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, ygt2, false);
5409 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5410 					YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, ygt4, false);
5411 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5412 					AVG2_MASK, CLUSTER_AVG2_SHIFT, 0, false);
5413 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5414 					AVG4_MASK, CLUSTER_AVG4_SHIFT, 0, false);
5415 		} else {
5416 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5417 					YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, 0, false);
5418 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5419 					YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, 0, false);
5420 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5421 					AVG2_MASK, CLUSTER_AVG2_SHIFT, ygt2, false);
5422 			vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
5423 					AVG4_MASK, CLUSTER_AVG4_SHIFT, ygt4, false);
5424 		}
5425 	} else {
5426 		vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset,
5427 			    yfac << 16 | xfac);
5428 
5429 		if (is_vop3(vop2)) {
5430 			vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
5431 					EN_MASK, ESMART_XGT_EN_SHIFT, xgt_en, false);
5432 			vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
5433 					EN_MASK, ESMART_XAVG_EN_SHIFT, xavg_en, false);
5434 			vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
5435 					XGT_MODE_MASK, ESMART_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false);
5436 		}
5437 
5438 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
5439 				YRGB_GT2_MASK, YRGB_GT2_SHIFT, ygt2, false);
5440 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
5441 				YRGB_GT4_MASK, YRGB_GT4_SHIFT, ygt4, false);
5442 
5443 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
5444 				YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false);
5445 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
5446 				YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false);
5447 
5448 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
5449 				YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT,
5450 				hscl_filter_mode, false);
5451 		vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
5452 				YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT,
5453 				vscl_filter_mode, false);
5454 	}
5455 }
5456 
5457 static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win)
5458 {
5459 	u32 win_offset = win->reg_offset;
5460 
5461 	if (win->type == CLUSTER_LAYER) {
5462 		vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK,
5463 				CLUSTER_AXI_ID_SHIFT, win->axi_id, false);
5464 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK,
5465 				CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
5466 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK,
5467 				CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
5468 	} else {
5469 		vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK,
5470 				ESMART_AXI_ID_SHIFT, win->axi_id, false);
5471 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK,
5472 				ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
5473 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK,
5474 				ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
5475 	}
5476 }
5477 
5478 static bool vop2_win_dither_up(uint32_t format)
5479 {
5480 	switch (format) {
5481 	case ROCKCHIP_FMT_RGB565:
5482 		return true;
5483 	default:
5484 		return false;
5485 	}
5486 }
5487 
5488 static bool vop2_is_mirror_win(struct vop2_win_data *win)
5489 {
5490 	return soc_is_rk3566() && (win->feature & WIN_FEATURE_MIRROR);
5491 }
5492 
5493 static int vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win)
5494 {
5495 	struct crtc_state *cstate = &state->crtc_state;
5496 	struct connector_state *conn_state = &state->conn_state;
5497 	struct drm_display_mode *mode = &conn_state->mode;
5498 	struct vop2 *vop2 = cstate->private;
5499 	const struct vop2_data *vop2_data = vop2->data;
5500 	const struct vop2_ops *vop2_ops = vop2_data->ops;
5501 	int src_w = cstate->src_rect.w;
5502 	int src_h = cstate->src_rect.h;
5503 	int crtc_x = cstate->crtc_rect.x;
5504 	int crtc_y = cstate->crtc_rect.y;
5505 	int crtc_w = cstate->crtc_rect.w;
5506 	int crtc_h = cstate->crtc_rect.h;
5507 	int xvir = cstate->xvir;
5508 	int y_mirror = 0;
5509 	int csc_mode;
5510 	u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
5511 	/* offset of the right window in splice mode */
5512 	u32 splice_pixel_offset = 0;
5513 	u32 splice_yrgb_offset = 0;
5514 	u32 win_offset = win->reg_offset;
5515 	bool dither_up;
5516 
5517 	if (win->splice_mode_right) {
5518 		src_w = cstate->right_src_rect.w;
5519 		src_h = cstate->right_src_rect.h;
5520 		crtc_x = cstate->right_crtc_rect.x;
5521 		crtc_y = cstate->right_crtc_rect.y;
5522 		crtc_w = cstate->right_crtc_rect.w;
5523 		crtc_h = cstate->right_crtc_rect.h;
5524 		splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x;
5525 		splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3);
5526 	}
5527 
5528 	act_info = (src_h - 1) << 16;
5529 	act_info |= (src_w - 1) & 0xffff;
5530 
5531 	dsp_info = (crtc_h - 1) << 16;
5532 	dsp_info |= (crtc_w - 1) & 0xffff;
5533 
5534 	dsp_stx = crtc_x;
5535 	dsp_sty = crtc_y;
5536 	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
5537 
5538 	if (mode->flags & DRM_MODE_FLAG_YMIRROR)
5539 		y_mirror = 1;
5540 	else
5541 		y_mirror = 0;
5542 
5543 	vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
5544 
5545 	if (vop2->version != VOP_VERSION_RK3568)
5546 		vop2_axi_config(vop2, win);
5547 
5548 	if (y_mirror)
5549 		printf("WARN: y mirror is unsupported by cluster window\n");
5550 
5551 	if (is_vop3(vop2)) {
5552 		vop2_mask_write(vop2, RK3576_CLUSTER0_PORT_SEL + win_offset,
5553 				CLUSTER_PORT_SEL_MASK, CLUSTER_PORT_SEL_SHIFT,
5554 				cstate->crtc_id, false);
5555 		vop2_ops->setup_win_dly(state, cstate->crtc_id, win->phys_id);
5556 	}
5557 
5558 	/*
5559 	 * rk3588 and later platforms should set half_blocK_en to 1 in line and tile mode.
5560 	 */
5561 	if (vop2->version >= VOP_VERSION_RK3588)
5562 		vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_AFBCD_CTRL + win_offset,
5563 				EN_MASK, CLUSTER_AFBCD_HALF_BLOCK_SHIFT, 1, false);
5564 
5565 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset,
5566 			WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
5567 			false);
5568 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset,
5569 			0x1, CLUSTER_RB_SWAP_SHIFT, cstate->rb_swap, false);
5570 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir);
5571 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset,
5572 		    cstate->dma_addr + splice_yrgb_offset);
5573 
5574 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info);
5575 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info);
5576 	vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st);
5577 
5578 	csc_mode = vop2_convert_csc_mode(conn_state->color_encoding, conn_state->color_range,
5579 					 CSC_10BIT_DEPTH);
5580 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK,
5581 			CLUSTER_RGB2YUV_EN_SHIFT,
5582 			is_yuv_output(conn_state->bus_format), false);
5583 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK,
5584 			CLUSTER_CSC_MODE_SHIFT, csc_mode, false);
5585 
5586 	dither_up = vop2_win_dither_up(cstate->format);
5587 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK,
5588 			CLUSTER_DITHER_UP_EN_SHIFT, dither_up, false);
5589 
5590 	vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false);
5591 	vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false);
5592 
5593 	return 0;
5594 }
5595 
5596 static int vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win)
5597 {
5598 	struct crtc_state *cstate = &state->crtc_state;
5599 	struct connector_state *conn_state = &state->conn_state;
5600 	struct drm_display_mode *mode = &conn_state->mode;
5601 	struct vop2 *vop2 = cstate->private;
5602 	const struct vop2_data *vop2_data = vop2->data;
5603 	const struct vop2_ops *vop2_ops = vop2_data->ops;
5604 	int src_w = cstate->src_rect.w;
5605 	int src_h = cstate->src_rect.h;
5606 	int crtc_x = cstate->crtc_rect.x;
5607 	int crtc_y = cstate->crtc_rect.y;
5608 	int crtc_w = cstate->crtc_rect.w;
5609 	int crtc_h = cstate->crtc_rect.h;
5610 	int xvir = cstate->xvir;
5611 	int y_mirror = 0;
5612 	int csc_mode;
5613 	u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
5614 	/* offset of the right window in splice mode */
5615 	u32 splice_pixel_offset = 0;
5616 	u32 splice_yrgb_offset = 0;
5617 	u32 win_offset = win->reg_offset;
5618 	u32 val;
5619 	bool dither_up;
5620 
5621 	if (vop2_is_mirror_win(win)) {
5622 		struct vop2_win_data *source_win = vop2_find_win_by_phys_id(vop2, win->source_win_id);
5623 
5624 		if (!source_win) {
5625 			printf("invalid source win id %d\n", win->source_win_id);
5626 			return -ENODEV;
5627 		}
5628 
5629 		val = vop2_readl(vop2, RK3568_ESMART0_REGION0_CTRL + source_win->reg_offset);
5630 		if (!(val & BIT(WIN_EN_SHIFT))) {
5631 			printf("WARN: the source win should be enabled before mirror win\n");
5632 			return -EAGAIN;
5633 		}
5634 	}
5635 
5636 	if (win->splice_mode_right) {
5637 		src_w = cstate->right_src_rect.w;
5638 		src_h = cstate->right_src_rect.h;
5639 		crtc_x = cstate->right_crtc_rect.x;
5640 		crtc_y = cstate->right_crtc_rect.y;
5641 		crtc_w = cstate->right_crtc_rect.w;
5642 		crtc_h = cstate->right_crtc_rect.h;
5643 		splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x;
5644 		splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3);
5645 	}
5646 
5647 	/*
5648 	 * This is workaround solution for IC design:
5649 	 * esmart can't support scale down when actual_w % 16 == 1.
5650 	 */
5651 	if (src_w > crtc_w && (src_w & 0xf) == 1) {
5652 		printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w);
5653 		src_w -= 1;
5654 	}
5655 
5656 	act_info = (src_h - 1) << 16;
5657 	act_info |= (src_w - 1) & 0xffff;
5658 
5659 	dsp_info = (crtc_h - 1) << 16;
5660 	dsp_info |= (crtc_w - 1) & 0xffff;
5661 
5662 	dsp_stx = crtc_x;
5663 	dsp_sty = crtc_y;
5664 	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
5665 
5666 	if (mode->flags & DRM_MODE_FLAG_YMIRROR)
5667 		y_mirror = 1;
5668 	else
5669 		y_mirror = 0;
5670 
5671 	if (is_vop3(vop2)) {
5672 		vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset,
5673 				ESMART_LB_SELECT_MASK, ESMART_LB_SELECT_SHIFT,
5674 				win->scale_engine_num, false);
5675 		vop2_mask_write(vop2, RK3576_ESMART0_PORT_SEL + win_offset,
5676 				ESMART_PORT_SEL_MASK, ESMART_PORT_SEL_SHIFT,
5677 				cstate->crtc_id, false);
5678 		vop2_ops->setup_win_dly(state, cstate->crtc_id, win->phys_id);
5679 
5680 		/* Merge esmart1/3 from vp1 post to vp0 */
5681 		if (vop2->version == VOP_VERSION_RK3576 && cstate->crtc_id == 0 &&
5682 		    (win->phys_id == ROCKCHIP_VOP2_ESMART1 ||
5683 		     win->phys_id == ROCKCHIP_VOP2_ESMART3))
5684 			vop2_mask_write(vop2, RK3576_ESMART0_PORT_SEL + win_offset,
5685 					ESMART_PORT_SEL_MASK, ESMART_PORT_SEL_SHIFT,
5686 					1, false);
5687 	}
5688 
5689 	vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
5690 
5691 	if (vop2->version != VOP_VERSION_RK3568)
5692 		vop2_axi_config(vop2, win);
5693 
5694 	if (y_mirror)
5695 		cstate->dma_addr += (src_h - 1) * xvir * 4;
5696 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK,
5697 			YMIRROR_EN_SHIFT, y_mirror, false);
5698 
5699 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
5700 			WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
5701 			false);
5702 
5703 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
5704 			0x1, REGION0_RB_SWAP_SHIFT, cstate->rb_swap, false);
5705 
5706 	if (vop2->version == VOP_VERSION_RK3576)
5707 		vop2_writel(vop2, RK3576_ESMART0_ALPHA_MAP + win_offset, 0x8000ff00);
5708 
5709 	vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir);
5710 	vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset,
5711 		    cstate->dma_addr + splice_yrgb_offset);
5712 
5713 	vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset,
5714 		    act_info);
5715 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset,
5716 		    dsp_info);
5717 	vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st);
5718 
5719 	csc_mode = vop2_convert_csc_mode(conn_state->color_encoding, conn_state->color_range,
5720 					 CSC_10BIT_DEPTH);
5721 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK,
5722 			RGB2YUV_EN_SHIFT,
5723 			is_yuv_output(conn_state->bus_format), false);
5724 	vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK,
5725 			CSC_MODE_SHIFT, csc_mode, false);
5726 
5727 	dither_up = vop2_win_dither_up(cstate->format);
5728 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK,
5729 			REGION0_DITHER_UP_EN_SHIFT, dither_up, false);
5730 
5731 	vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK,
5732 			WIN_EN_SHIFT, 1, false);
5733 
5734 	return 0;
5735 }
5736 
5737 static void vop2_calc_display_rect_for_splice(struct display_state *state)
5738 {
5739 	struct crtc_state *cstate = &state->crtc_state;
5740 	struct connector_state *conn_state = &state->conn_state;
5741 	struct drm_display_mode *mode = &conn_state->mode;
5742 	struct display_rect *src_rect = &cstate->src_rect;
5743 	struct display_rect *dst_rect = &cstate->crtc_rect;
5744 	struct display_rect left_src, left_dst, right_src, right_dst;
5745 	u16 half_hdisplay = mode->crtc_hdisplay >> 1;
5746 	int left_src_w, left_dst_w, right_dst_w;
5747 
5748 	left_dst_w = min_t(u16, half_hdisplay, dst_rect->x + dst_rect->w) - dst_rect->x;
5749 	if (left_dst_w < 0)
5750 		left_dst_w = 0;
5751 	right_dst_w = dst_rect->w - left_dst_w;
5752 
5753 	if (!right_dst_w)
5754 		left_src_w = src_rect->w;
5755 	else
5756 		left_src_w = src_rect->x + src_rect->w - src_rect->w / 2;
5757 
5758 	left_src.x = src_rect->x;
5759 	left_src.w = left_src_w;
5760 	left_dst.x = dst_rect->x;
5761 	left_dst.w = left_dst_w;
5762 	right_src.x = left_src.x + left_src.w;
5763 	right_src.w = src_rect->x + src_rect->w - left_src.x - left_src.w;
5764 	right_dst.x = dst_rect->x + left_dst_w - half_hdisplay;
5765 	right_dst.w = right_dst_w;
5766 
5767 	left_src.y = src_rect->y;
5768 	left_src.h = src_rect->h;
5769 	left_dst.y = dst_rect->y;
5770 	left_dst.h = dst_rect->h;
5771 	right_src.y = src_rect->y;
5772 	right_src.h = src_rect->h;
5773 	right_dst.y = dst_rect->y;
5774 	right_dst.h = dst_rect->h;
5775 
5776 	memcpy(&cstate->src_rect, &left_src, sizeof(struct display_rect));
5777 	memcpy(&cstate->crtc_rect, &left_dst, sizeof(struct display_rect));
5778 	memcpy(&cstate->right_src_rect, &right_src, sizeof(struct display_rect));
5779 	memcpy(&cstate->right_crtc_rect, &right_dst, sizeof(struct display_rect));
5780 }
5781 
5782 static int rockchip_vop2_set_plane(struct display_state *state)
5783 {
5784 	struct crtc_state *cstate = &state->crtc_state;
5785 	struct vop2 *vop2 = cstate->private;
5786 	struct vop2_win_data *win_data;
5787 	struct vop2_win_data *splice_win_data;
5788 	u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
5789 	int ret;
5790 
5791 	if (cstate->crtc_rect.w > cstate->max_output.width) {
5792 		printf("ERROR: output w[%d] exceeded max width[%d]\n",
5793 		       cstate->crtc_rect.w, cstate->max_output.width);
5794 		return -EINVAL;
5795 	}
5796 
5797 	win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
5798 	if (!win_data) {
5799 		printf("invalid win id %d\n", primary_plane_id);
5800 		return -ENODEV;
5801 	}
5802 
5803 	/* ignore some plane register according vop3 esmart lb mode */
5804 	if (vop3_ignore_plane(vop2, win_data))
5805 		return -EACCES;
5806 
5807 	if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3576) {
5808 		if (vop2_power_domain_on(vop2, win_data->pd_id))
5809 			printf("open vp%d plane pd fail\n", cstate->crtc_id);
5810 	}
5811 
5812 	if (cstate->splice_mode) {
5813 		if (win_data->splice_win_id) {
5814 			splice_win_data = vop2_find_win_by_phys_id(vop2, win_data->splice_win_id);
5815 			splice_win_data->splice_mode_right = true;
5816 
5817 			if (vop2_power_domain_on(vop2, splice_win_data->pd_id))
5818 				printf("splice mode: open vp%d plane pd fail\n", cstate->splice_crtc_id);
5819 
5820 			vop2_calc_display_rect_for_splice(state);
5821 			if (win_data->type == CLUSTER_LAYER)
5822 				vop2_set_cluster_win(state, splice_win_data);
5823 			else
5824 				vop2_set_smart_win(state, splice_win_data);
5825 		} else {
5826 			printf("ERROR: splice mode is unsupported by plane %s\n",
5827 			       vop2_plane_phys_id_to_string(primary_plane_id));
5828 			return -EINVAL;
5829 		}
5830 	}
5831 
5832 	if (win_data->type == CLUSTER_LAYER)
5833 		ret = vop2_set_cluster_win(state, win_data);
5834 	else
5835 		ret = vop2_set_smart_win(state, win_data);
5836 	if (ret)
5837 		return ret;
5838 
5839 	printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n",
5840 		cstate->crtc_id, vop2_plane_phys_id_to_string(primary_plane_id),
5841 		cstate->src_rect.w, cstate->src_rect.h, cstate->crtc_rect.w, cstate->crtc_rect.h,
5842 		cstate->crtc_rect.x, cstate->crtc_rect.y, cstate->format,
5843 		cstate->dma_addr);
5844 
5845 	return 0;
5846 }
5847 
5848 static int rockchip_vop2_prepare(struct display_state *state)
5849 {
5850 	return 0;
5851 }
5852 
5853 static void vop2_dsc_cfg_done(struct display_state *state)
5854 {
5855 	struct connector_state *conn_state = &state->conn_state;
5856 	struct crtc_state *cstate = &state->crtc_state;
5857 	struct vop2 *vop2 = cstate->private;
5858 	u8 dsc_id = cstate->dsc_id;
5859 	u32 ctrl_regs_offset = (dsc_id * 0x30);
5860 
5861 	if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
5862 		vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE, EN_MASK,
5863 				DSC_CFG_DONE_SHIFT, 1, false);
5864 		vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK,
5865 				DSC_CFG_DONE_SHIFT, 1, false);
5866 	} else {
5867 		vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK,
5868 				DSC_CFG_DONE_SHIFT, 1, false);
5869 	}
5870 }
5871 
5872 static int rockchip_vop2_enable(struct display_state *state)
5873 {
5874 	struct crtc_state *cstate = &state->crtc_state;
5875 	struct vop2 *vop2 = cstate->private;
5876 	u32 vp_offset = (cstate->crtc_id * 0x100);
5877 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
5878 
5879 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5880 			STANDBY_EN_SHIFT, 0, false);
5881 
5882 	if (cstate->splice_mode)
5883 		cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
5884 
5885 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
5886 
5887 	if (cstate->dsc_enable)
5888 		vop2_dsc_cfg_done(state);
5889 
5890 	if (cstate->mcu_timing.mcu_pix_total)
5891 		vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
5892 				MCU_HOLD_MODE_SHIFT, 0, false);
5893 
5894 	return 0;
5895 }
5896 
5897 static int rk3588_vop2_post_enable(struct display_state *state)
5898 {
5899 	struct connector_state *conn_state = &state->conn_state;
5900 	struct crtc_state *cstate = &state->crtc_state;
5901 	struct vop2 *vop2 = cstate->private;
5902 	int output_if = conn_state->output_if;
5903 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
5904 	int ret, val;
5905 
5906 	if (output_if & VOP_OUTPUT_IF_DP0)
5907 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT,
5908 				1, false);
5909 
5910 	if (output_if & VOP_OUTPUT_IF_DP1)
5911 		vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT,
5912 				1, false);
5913 
5914 	if (output_if & (VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1)) {
5915 		vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
5916 		ret = readl_poll_timeout(vop2->regs + RK3568_REG_CFG_DONE, val,
5917 					 val & BIT(cstate->crtc_id), 50 * 1000);
5918 		if (ret)
5919 			printf("%s wait cfg done timeout\n", __func__);
5920 
5921 		if (cstate->dclk_rst.dev) {
5922 			reset_assert(&cstate->dclk_rst);
5923 			udelay(20);
5924 			reset_deassert(&cstate->dclk_rst);
5925 		}
5926 	}
5927 
5928 	return 0;
5929 }
5930 
5931 static int rk3576_vop2_post_enable(struct display_state *state)
5932 {
5933 	struct connector_state *conn_state = &state->conn_state;
5934 	struct crtc_state *cstate = &state->crtc_state;
5935 	struct vop2 *vop2 = cstate->private;
5936 	int output_if = conn_state->output_if;
5937 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
5938 	int ret, val;
5939 
5940 	if (output_if & VOP_OUTPUT_IF_DP0)
5941 		vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK,
5942 				RK3576_IF_OUT_EN_SHIFT, 1, false);
5943 
5944 	if (output_if & VOP_OUTPUT_IF_DP1)
5945 		vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, EN_MASK,
5946 				RK3576_IF_OUT_EN_SHIFT, 1, false);
5947 
5948 	if (output_if & VOP_OUTPUT_IF_DP2)
5949 		vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, EN_MASK,
5950 				RK3576_IF_OUT_EN_SHIFT, 1, false);
5951 
5952 	if (output_if & (VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1 | VOP_OUTPUT_IF_DP2)) {
5953 		vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
5954 		ret = readl_poll_timeout(vop2->regs + RK3568_REG_CFG_DONE, val,
5955 					 val & BIT(cstate->crtc_id), 50 * 1000);
5956 		if (ret)
5957 			printf("%s wait cfg done timeout\n", __func__);
5958 
5959 		if (cstate->dclk_rst.dev) {
5960 			reset_assert(&cstate->dclk_rst);
5961 			udelay(20);
5962 			reset_deassert(&cstate->dclk_rst);
5963 		}
5964 	}
5965 
5966 	return 0;
5967 }
5968 
5969 static int rockchip_vop2_post_enable(struct display_state *state)
5970 {
5971 	struct crtc_state *cstate = &state->crtc_state;
5972 	struct vop2 *vop2 = cstate->private;
5973 
5974 	if (vop2->version == VOP_VERSION_RK3588)
5975 		rk3588_vop2_post_enable(state);
5976 	else if (vop2->version == VOP_VERSION_RK3576)
5977 		rk3576_vop2_post_enable(state);
5978 
5979 	return 0;
5980 }
5981 
5982 static int rockchip_vop2_disable(struct display_state *state)
5983 {
5984 	struct crtc_state *cstate = &state->crtc_state;
5985 	struct vop2 *vop2 = cstate->private;
5986 	u32 vp_offset = (cstate->crtc_id * 0x100);
5987 	u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
5988 
5989 	vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
5990 			STANDBY_EN_SHIFT, 1, false);
5991 
5992 	if (cstate->splice_mode)
5993 		cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
5994 
5995 	vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
5996 
5997 	return 0;
5998 }
5999 
6000 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob)
6001 {
6002 	struct crtc_state *cstate = &state->crtc_state;
6003 	struct vop2 *vop2 = cstate->private;
6004 	ofnode vp_node;
6005 	struct device_node *port_parent_node = cstate->ports_node;
6006 	static bool vop_fix_dts;
6007 	const char *path;
6008 	u32 plane_mask = 0;
6009 	int vp_id = 0;
6010 
6011 	/*
6012 	 * For vop3, &vop2_vp_plane_mask.plane_mask will not be fixup in
6013 	 * &rockchip_crtc_funcs.fixup_dts(), because planes can be switched
6014 	 * between different CRTCs flexibly and the userspace do not need
6015 	 * the plane_mask to restrict the binding between the crtc and plane.
6016 	 * We just find a expected plane for logo display.
6017 	 */
6018 	if (vop_fix_dts || is_vop3(vop2))
6019 		return 0;
6020 
6021 	ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) {
6022 		path = vp_node.np->full_name;
6023 		plane_mask = vop2->vp_plane_mask[vp_id].plane_mask;
6024 
6025 		if (cstate->crtc->assign_plane)
6026 			continue;
6027 
6028 		printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n",
6029 		       vp_id, plane_mask,
6030 		       vop2->vp_plane_mask[vp_id].primary_plane_id,
6031 		       vop2->vp_plane_mask[vp_id].cursor_plane_id);
6032 
6033 		do_fixup_by_path_u32(blob, path, "rockchip,plane-mask",
6034 				     plane_mask, 1);
6035 		do_fixup_by_path_u32(blob, path, "rockchip,primary-plane",
6036 				     vop2->vp_plane_mask[vp_id].primary_plane_id, 1);
6037 		if (vop2->vp_plane_mask[vp_id].cursor_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID)
6038 			do_fixup_by_path_u32(blob, path, "cursor-win-id",
6039 					     vop2->vp_plane_mask[vp_id].cursor_plane_id, 1);
6040 		vp_id++;
6041 	}
6042 
6043 	vop_fix_dts = true;
6044 
6045 	return 0;
6046 }
6047 
6048 static int rockchip_vop2_check(struct display_state *state)
6049 {
6050 	struct crtc_state *cstate = &state->crtc_state;
6051 	struct rockchip_crtc *crtc = cstate->crtc;
6052 
6053 	if (crtc->splice_mode && cstate->crtc_id == crtc->splice_crtc_id) {
6054 		printf("WARN: VP%d is busy in splice mode\n", cstate->crtc_id);
6055 		return -ENOTSUPP;
6056 	}
6057 
6058 	if (cstate->splice_mode) {
6059 		crtc->splice_mode = true;
6060 		crtc->splice_crtc_id = cstate->splice_crtc_id;
6061 	}
6062 
6063 	return 0;
6064 }
6065 
6066 static int rockchip_vop2_mode_valid(struct display_state *state)
6067 {
6068 	struct connector_state *conn_state = &state->conn_state;
6069 	struct crtc_state *cstate = &state->crtc_state;
6070 	struct drm_display_mode *mode = &conn_state->mode;
6071 	struct videomode vm;
6072 
6073 	drm_display_mode_to_videomode(mode, &vm);
6074 
6075 	if (vm.hactive < 32 || vm.vactive < 32 ||
6076 	    (vm.hfront_porch * vm.hsync_len * vm.hback_porch *
6077 	     vm.vfront_porch * vm.vsync_len * vm.vback_porch == 0)) {
6078 		printf("ERROR: VP%d: unsupported display timing\n", cstate->crtc_id);
6079 		return -EINVAL;
6080 	}
6081 
6082 	return 0;
6083 }
6084 
6085 static int rockchip_vop2_mode_fixup(struct display_state *state)
6086 {
6087 	struct connector_state *conn_state = &state->conn_state;
6088 	struct rockchip_connector *conn = conn_state->connector;
6089 	struct drm_display_mode *mode = &conn_state->mode;
6090 	struct crtc_state *cstate = &state->crtc_state;
6091 	struct vop2 *vop2 = cstate->private;
6092 
6093 	if (conn_state->secondary) {
6094 		if (!(conn->dual_channel_mode &&
6095 		      conn_state->secondary->type == DRM_MODE_CONNECTOR_eDP) &&
6096 		    conn_state->secondary->type != DRM_MODE_CONNECTOR_LVDS)
6097 			drm_mode_convert_to_split_mode(mode);
6098 	}
6099 
6100 	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE);
6101 
6102 	/*
6103 	 * For RK3568 and RK3588, the hactive of video timing must
6104 	 * be 4-pixel aligned.
6105 	 */
6106 	if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588) {
6107 		if (mode->crtc_hdisplay % 4) {
6108 			int old_hdisplay = mode->crtc_hdisplay;
6109 			int align = 4 - (mode->crtc_hdisplay % 4);
6110 
6111 			mode->crtc_hdisplay += align;
6112 			mode->crtc_hsync_start += align;
6113 			mode->crtc_hsync_end += align;
6114 			mode->crtc_htotal += align;
6115 
6116 			printf("WARN: hactive need to be aligned with 4-pixel, %d -> %d\n",
6117 			       old_hdisplay, mode->hdisplay);
6118 		}
6119 	}
6120 
6121 	/*
6122 	 * When the dsc bpp is less than 9, hdmi output will flash on TV.
6123 	 * It is speculated that the reason is that pixel rate of sink
6124 	 * decoding is not enough.
6125 	 * Taking 8bpp as an example, dsc clk needs to be 1/3 of the input
6126 	 * clk. the theoretical calculation of DEN compression 1/3, at this
6127 	 * time, the clk of vop dsc to hdmi tx can be reduced to about 260M
6128 	 * to meet the 8bpp transmission.
6129 	 * RK3588 dsc clk only supports 1/2 frequency division, so dsc clk
6130 	 * is 1/2 input clk, which needs to increase blank, which is
6131 	 * equivalent to compressing the absolute DEN time. TV is likely to
6132 	 * decode at a decoding rate of around 260M. DEN absolute time
6133 	 * shortening results in abnormal TV decoding.
6134 	 * So the value of hblank needs to be reduced when bpp is below 9.
6135 	 * The measurement can be displayed normally on TV, but reducing
6136 	 * the hblank will result in non-standard timing of the hdmi output.
6137 	 * This may cause compatibility issues and hdmi cts certification
6138 	 * may fail.
6139 	 */
6140 	if (vop2->version == VOP_VERSION_RK3588) {
6141 		if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
6142 			if (cstate->dsc_sink_cap.target_bits_per_pixel_x16 < 0x90 &&
6143 			    cstate->dsc_enable) {
6144 				u8 vrefresh = drm_mode_vrefresh(mode);
6145 
6146 				mode->crtc_hsync_start = mode->hdisplay + 10;
6147 				mode->crtc_hsync_end = mode->crtc_hsync_start + 10;
6148 				mode->crtc_htotal = mode->crtc_hsync_end + 10;
6149 				mode->crtc_clock = (u32)mode->crtc_htotal * mode->crtc_vtotal *
6150 					vrefresh / 1000;
6151 			}
6152 		}
6153 	}
6154 
6155 	if (vop2->version == VOP_VERSION_RK3576) {
6156 		/*
6157 		 * For RK3576 YUV420 output, hden signal introduce one cycle delay,
6158 		 * so we need to adjust hfp and hbp to compatible with this design.
6159 		 */
6160 		if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
6161 			mode->crtc_hsync_start += 2;
6162 			mode->crtc_hsync_end += 2;
6163 		}
6164 		/*
6165 		 * For RK3576 DP output, vp send 2 pixels 1 cycle. So the hactive,
6166 		 * hfp, hsync, hbp should be 2-pixel aligned.
6167 		 */
6168 		if (conn_state->output_if &
6169 		    (VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1 | VOP_OUTPUT_IF_DP2)) {
6170 			mode->crtc_hdisplay += mode->crtc_hdisplay % 2;
6171 			mode->crtc_hsync_start += mode->crtc_hsync_start % 2;
6172 			mode->crtc_hsync_end += mode->crtc_hsync_end % 2;
6173 			mode->crtc_htotal += mode->crtc_htotal % 2;
6174 		}
6175 	}
6176 
6177 	if (mode->flags & DRM_MODE_FLAG_DBLCLK || conn_state->output_if & VOP_OUTPUT_IF_BT656)
6178 		mode->crtc_clock *= 2;
6179 
6180 	/*
6181 	 * For RK3528, the path of CVBS output is like:
6182 	 * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
6183 	 * The vop2 dclk should be four times crtc_clock for CVBS sampling
6184 	 * clock needs.
6185 	 */
6186 	if (vop2->version == VOP_VERSION_RK3528 && conn_state->output_if & VOP_OUTPUT_IF_BT656)
6187 		mode->crtc_clock *= 4;
6188 
6189 	mode->crtc_clock *= rockchip_drm_get_cycles_per_pixel(conn_state->bus_format);
6190 	if (cstate->mcu_timing.mcu_pix_total)
6191 		mode->crtc_clock *= cstate->mcu_timing.mcu_pix_total + 1;
6192 
6193 	return 0;
6194 }
6195 
6196 #define FRAC_16_16(mult, div)	(((mult) << 16) / (div))
6197 
6198 static int rockchip_vop2_plane_check(struct display_state *state)
6199 {
6200 	struct crtc_state *cstate = &state->crtc_state;
6201 	struct vop2 *vop2 = cstate->private;
6202 	struct display_rect *src = &cstate->src_rect;
6203 	struct display_rect *dst = &cstate->crtc_rect;
6204 	struct vop2_win_data *win_data;
6205 	int min_scale, max_scale;
6206 	int hscale, vscale;
6207 	u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
6208 
6209 	win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
6210 	if (!win_data) {
6211 		printf("ERROR: invalid win id %d\n", primary_plane_id);
6212 		return -ENODEV;
6213 	}
6214 
6215 	min_scale = FRAC_16_16(1, win_data->max_downscale_factor);
6216 	max_scale = FRAC_16_16(win_data->max_upscale_factor, 1);
6217 
6218 	hscale = display_rect_calc_hscale(src, dst, min_scale, max_scale);
6219 	vscale = display_rect_calc_vscale(src, dst, min_scale, max_scale);
6220 	if (hscale < 0 || vscale < 0) {
6221 		printf("ERROR: VP%d %s: scale factor is out of range\n", cstate->crtc_id, win_data->name);
6222 		return -ERANGE;
6223 		}
6224 
6225 	return 0;
6226 }
6227 
6228 static int rockchip_vop2_apply_soft_te(struct display_state *state)
6229 {
6230 	__maybe_unused struct connector_state *conn_state = &state->conn_state;
6231 	struct crtc_state *cstate = &state->crtc_state;
6232 	struct vop2 *vop2 = cstate->private;
6233 	u32 vp_offset = (cstate->crtc_id * 0x100);
6234 	int val = 0;
6235 	int ret = 0;
6236 
6237 	ret = readl_poll_timeout(vop2->regs + RK3568_VP0_MIPI_CTRL + vp_offset, val,
6238 				 (val >> EDPI_WMS_FS) & 0x1, 50 * 1000);
6239 	if (!ret) {
6240 #ifndef CONFIG_SPL_BUILD
6241 		ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val,
6242 					 !val, 50 * 1000);
6243 		if (!ret) {
6244 			ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val,
6245 						 val, 50 * 1000);
6246 			if (!ret) {
6247 				vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
6248 						EN_MASK, EDPI_WMS_FS, 1, false);
6249 			} else {
6250 				printf("ERROR: vp%d wait for active TE signal timeout\n",
6251 				       cstate->crtc_id);
6252 				return ret;
6253 			}
6254 		} else {
6255 			printf("ERROR: vp%d TE signal maybe always high\n", cstate->crtc_id);
6256 			return ret;
6257 		}
6258 #endif
6259 	} else {
6260 		printf("ERROR: vp%d wait vop2 frame start timeout in hold mode\n", cstate->crtc_id);
6261 		return ret;
6262 	}
6263 
6264 	return 0;
6265 }
6266 
6267 static int rockchip_vop2_regs_dump(struct display_state *state)
6268 {
6269 	struct crtc_state *cstate = &state->crtc_state;
6270 	struct vop2 *vop2 = cstate->private;
6271 	const struct vop2_data *vop2_data = vop2->data;
6272 	const struct vop2_dump_regs *regs = vop2_data->dump_regs;
6273 	u32 len = 128;
6274 	u32 n, i, j;
6275 	u32 base;
6276 
6277 	if (!cstate->crtc->active)
6278 		return -EINVAL;
6279 
6280 	n = vop2_data->dump_regs_size;
6281 	for (i = 0; i < n; i++) {
6282 		base = regs[i].offset;
6283 		len = 128;
6284 		if (regs[i].size)
6285 			len = min(len, regs[i].size >> 2);
6286 		printf("\n%s:\n", regs[i].name);
6287 		for (j = 0; j < len;) {
6288 			printf("%08lx:  %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4,
6289 			       vop2_readl(vop2, base + (4 * j)),
6290 			       vop2_readl(vop2, base + (4 * (j + 1))),
6291 			       vop2_readl(vop2, base + (4 * (j + 2))),
6292 			       vop2_readl(vop2, base + (4 * (j + 3))));
6293 			j += 4;
6294 		}
6295 	}
6296 
6297 	return 0;
6298 }
6299 
6300 static int rockchip_vop2_active_regs_dump(struct display_state *state)
6301 {
6302 	struct crtc_state *cstate = &state->crtc_state;
6303 	struct vop2 *vop2 = cstate->private;
6304 	const struct vop2_data *vop2_data = vop2->data;
6305 	const struct vop2_dump_regs *regs = vop2_data->dump_regs;
6306 	u32 len = 128;
6307 	u32 n, i, j;
6308 	u32 base;
6309 	bool enable_state;
6310 
6311 	if (!cstate->crtc->active)
6312 		return -EINVAL;
6313 
6314 	n = vop2_data->dump_regs_size;
6315 	for (i = 0; i < n; i++) {
6316 		if (regs[i].state_mask) {
6317 			enable_state = (vop2_readl(vop2, regs[i].state_base) >> regs[i].state_shift) &
6318 				       regs[i].state_mask;
6319 			if (enable_state != regs[i].enable_state)
6320 				continue;
6321 		}
6322 
6323 		base = regs[i].offset;
6324 		len = 128;
6325 		if (regs[i].size)
6326 			len = min(len, regs[i].size >> 2);
6327 		printf("\n%s:\n", regs[i].name);
6328 		for (j = 0; j < len;) {
6329 			printf("%08lx:  %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4,
6330 			       vop2_readl(vop2, base + (4 * j)),
6331 			       vop2_readl(vop2, base + (4 * (j + 1))),
6332 			       vop2_readl(vop2, base + (4 * (j + 2))),
6333 			       vop2_readl(vop2, base + (4 * (j + 3))));
6334 			j += 4;
6335 		}
6336 	}
6337 
6338 	return 0;
6339 }
6340 
6341 static void rk3528_setup_win_dly(struct display_state *state, int crtc_id, u8 plane_phy_id)
6342 {
6343 	struct crtc_state *cstate = &state->crtc_state;
6344 	struct vop2 *vop2 = cstate->private;
6345 	uint32_t dly = 0; /* For vop3, the default window delay is 0 */
6346 
6347 	switch (plane_phy_id) {
6348 	case ROCKCHIP_VOP2_CLUSTER0:
6349 		vop2_mask_write(vop2, RK3528_OVL_SYS_CLUSTER0_CTRL, CLUSTER_DLY_NUM_MASK,
6350 				CLUSTER_DLY_NUM_SHIFT, dly, false);
6351 		break;
6352 	case ROCKCHIP_VOP2_ESMART0:
6353 		vop2_mask_write(vop2, RK3528_OVL_SYS_ESMART0_CTRL, ESMART_DLY_NUM_MASK,
6354 				ESMART_DLY_NUM_SHIFT, dly, false);
6355 		break;
6356 	case ROCKCHIP_VOP2_ESMART1:
6357 		vop2_mask_write(vop2, RK3528_OVL_SYS_ESMART1_CTRL, ESMART_DLY_NUM_MASK,
6358 				ESMART_DLY_NUM_SHIFT, dly, false);
6359 		break;
6360 	case ROCKCHIP_VOP2_ESMART2:
6361 		vop2_mask_write(vop2, RK3528_OVL_SYS_ESMART2_CTRL, ESMART_DLY_NUM_MASK,
6362 				ESMART_DLY_NUM_SHIFT, dly, false);
6363 		break;
6364 	case ROCKCHIP_VOP2_ESMART3:
6365 		vop2_mask_write(vop2, RK3528_OVL_SYS_ESMART3_CTRL, ESMART_DLY_NUM_MASK,
6366 				ESMART_DLY_NUM_SHIFT, dly, false);
6367 		break;
6368 	}
6369 }
6370 
6371 static void rk3528_setup_overlay(struct display_state *state)
6372 {
6373 	struct crtc_state *cstate = &state->crtc_state;
6374 	struct vop2 *vop2 = cstate->private;
6375 	struct vop2_win_data *win_data;
6376 	int i;
6377 	u32 offset = 0;
6378 	u8 shift = 0;
6379 
6380 	/* init the layer sel value to 0xff(Disable layer) */
6381 	for (i = 0; i < vop2->data->nr_vps; i++) {
6382 		offset = 0x100 * i;
6383 		vop2_writel(vop2, RK3528_OVL_PORT0_LAYER_SEL + offset, 0xffffffff);
6384 	}
6385 
6386 	/* layer sel win id */
6387 	for (i = 0; i < vop2->data->nr_vps; i++) {
6388 		if (vop2->vp_plane_mask[i].primary_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID) {
6389 			offset = 0x100 * i;
6390 			win_data = vop2_find_win_by_phys_id(vop2, vop2->vp_plane_mask[i].primary_plane_id);
6391 			vop2_mask_write(vop2, RK3528_OVL_PORT0_LAYER_SEL + offset,
6392 					LAYER_SEL_MASK, 0, win_data->layer_sel_win_id[i], false);
6393 		}
6394 	}
6395 
6396 	/* win sel port */
6397 	for (i = 0; i < vop2->data->nr_vps; i++) {
6398 		if (vop2->vp_plane_mask[i].primary_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID) {
6399 			win_data = vop2_find_win_by_phys_id(vop2, vop2->vp_plane_mask[i].primary_plane_id);
6400 			shift = win_data->win_sel_port_offset * 2;
6401 			vop2_mask_write(vop2, RK3528_OVL_SYS_PORT_SEL,
6402 					LAYER_SEL_PORT_MASK, shift, i, false);
6403 		}
6404 	}
6405 }
6406 
6407 static void rk3568_setup_win_dly(struct display_state *state, int crtc_id, u8 plane_phy_id)
6408 {
6409 	struct crtc_state *cstate = &state->crtc_state;
6410 	struct vop2 *vop2 = cstate->private;
6411 	struct vop2_win_data *win_data;
6412 	uint32_t dly;
6413 
6414 	win_data = vop2_find_win_by_phys_id(vop2, plane_phy_id);
6415 	dly = win_data->dly[VOP2_DLY_MODE_DEFAULT];
6416 	if (win_data->type == CLUSTER_LAYER)
6417 		dly |= dly << 8;
6418 
6419 	switch (plane_phy_id) {
6420 	case ROCKCHIP_VOP2_CLUSTER0:
6421 		vop2_mask_write(vop2, RK3568_CLUSTER_DLY_NUM, CLUSTER_DLY_NUM_MASK,
6422 				CLUSTER0_DLY_NUM_SHIFT, dly, false);
6423 		break;
6424 	case ROCKCHIP_VOP2_CLUSTER1:
6425 		vop2_mask_write(vop2, RK3568_CLUSTER_DLY_NUM, CLUSTER_DLY_NUM_MASK,
6426 				CLUSTER1_DLY_NUM_SHIFT, dly, false);
6427 		break;
6428 	case ROCKCHIP_VOP2_CLUSTER2:
6429 		vop2_mask_write(vop2, RK3568_CLUSTER_DLY_NUM1, CLUSTER_DLY_NUM_MASK,
6430 				CLUSTER0_DLY_NUM_SHIFT, dly, false);
6431 		break;
6432 	case ROCKCHIP_VOP2_CLUSTER3:
6433 		vop2_mask_write(vop2, RK3568_CLUSTER_DLY_NUM1, CLUSTER_DLY_NUM_MASK,
6434 				CLUSTER1_DLY_NUM_SHIFT, dly, false);
6435 		break;
6436 	case ROCKCHIP_VOP2_ESMART0:
6437 		vop2_mask_write(vop2, RK3568_SMART_DLY_NUM, SMART_DLY_NUM_MASK,
6438 				ESMART0_DLY_NUM_SHIFT, dly, false);
6439 		break;
6440 	case ROCKCHIP_VOP2_ESMART1:
6441 		vop2_mask_write(vop2, RK3568_SMART_DLY_NUM, SMART_DLY_NUM_MASK,
6442 				ESMART1_DLY_NUM_SHIFT, dly, false);
6443 		break;
6444 	case ROCKCHIP_VOP2_SMART0:
6445 	case ROCKCHIP_VOP2_ESMART2:
6446 		vop2_mask_write(vop2, RK3568_SMART_DLY_NUM, SMART_DLY_NUM_MASK,
6447 				SMART0_DLY_NUM_SHIFT, dly, false);
6448 		break;
6449 	case ROCKCHIP_VOP2_SMART1:
6450 	case ROCKCHIP_VOP2_ESMART3:
6451 		vop2_mask_write(vop2, RK3568_SMART_DLY_NUM, SMART_DLY_NUM_MASK,
6452 				SMART1_DLY_NUM_SHIFT, dly, false);
6453 		break;
6454 	}
6455 }
6456 
6457 static void rk3568_setup_overlay(struct display_state *state)
6458 {
6459 	struct crtc_state *cstate = &state->crtc_state;
6460 	struct vop2 *vop2 = cstate->private;
6461 	struct vop2_win_data *win_data;
6462 	int layer_phy_id = 0;
6463 	int total_used_layer = 0;
6464 	int port_mux = 0;
6465 	int i, j;
6466 	u32 layer_nr = 0;
6467 	u8 shift = 0;
6468 
6469 	/* layer sel win id */
6470 	for (i = 0; i < vop2->data->nr_vps; i++) {
6471 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
6472 		for (j = 0; j < layer_nr; j++) {
6473 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
6474 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
6475 			vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK,
6476 					shift, win_data->layer_sel_win_id[i], false);
6477 			shift += 4;
6478 		}
6479 	}
6480 
6481 	/* win sel port */
6482 	for (i = 0; i < vop2->data->nr_vps; i++) {
6483 		layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
6484 		for (j = 0; j < layer_nr; j++) {
6485 			if (!vop2->vp_plane_mask[i].attached_layers[j])
6486 				continue;
6487 			layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
6488 			win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
6489 			shift = win_data->win_sel_port_offset * 2;
6490 			vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK,
6491 					LAYER_SEL_PORT_SHIFT + shift, i, false);
6492 		}
6493 	}
6494 
6495 	/**
6496 	 * port mux config
6497 	 */
6498 	for (i = 0; i < vop2->data->nr_vps; i++) {
6499 		shift = i * 4;
6500 		if (vop2->vp_plane_mask[i].attached_layers_nr) {
6501 			total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr;
6502 			port_mux = total_used_layer - 1;
6503 		} else {
6504 			port_mux = 8;
6505 		}
6506 
6507 		if (i == vop2->data->nr_vps - 1)
6508 			port_mux = vop2->data->nr_mixers;
6509 
6510 		cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1;
6511 		vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK,
6512 				PORT_MUX_SHIFT + shift, port_mux, false);
6513 	}
6514 }
6515 
6516 static void rk3576_setup_win_dly(struct display_state *state, int crtc_id, u8 plane_phy_id)
6517 {
6518 	struct crtc_state *cstate = &state->crtc_state;
6519 	struct vop2 *vop2 = cstate->private;
6520 	uint32_t dly = 0; /* For vop3, the default window delay is 0 */
6521 
6522 	switch (plane_phy_id) {
6523 	case ROCKCHIP_VOP2_CLUSTER0:
6524 		vop2_mask_write(vop2, RK3576_CLUSTER0_DLY_NUM, CLUSTER_DLY_NUM_MASK,
6525 				CLUSTER_DLY_NUM_SHIFT, dly, false);
6526 		break;
6527 	case ROCKCHIP_VOP2_CLUSTER1:
6528 		vop2_mask_write(vop2, RK3576_CLUSTER1_DLY_NUM, CLUSTER_DLY_NUM_MASK,
6529 				CLUSTER_DLY_NUM_SHIFT, dly, false);
6530 		break;
6531 	case ROCKCHIP_VOP2_ESMART0:
6532 		vop2_mask_write(vop2, RK3576_ESMART0_DLY_NUM, ESMART_DLY_NUM_MASK,
6533 				ESMART_DLY_NUM_SHIFT, dly, false);
6534 		break;
6535 	case ROCKCHIP_VOP2_ESMART1:
6536 		vop2_mask_write(vop2, RK3576_ESMART1_DLY_NUM, ESMART_DLY_NUM_MASK,
6537 				ESMART_DLY_NUM_SHIFT, dly, false);
6538 		break;
6539 	case ROCKCHIP_VOP2_ESMART2:
6540 		vop2_mask_write(vop2, RK3576_ESMART2_DLY_NUM, ESMART_DLY_NUM_MASK,
6541 				ESMART_DLY_NUM_SHIFT, dly, false);
6542 		break;
6543 	case ROCKCHIP_VOP2_ESMART3:
6544 		vop2_mask_write(vop2, RK3576_ESMART3_DLY_NUM, ESMART_DLY_NUM_MASK,
6545 				ESMART_DLY_NUM_SHIFT, dly, false);
6546 		break;
6547 	}
6548 }
6549 
6550 static void rk3576_setup_overlay(struct display_state *state)
6551 {
6552 	struct crtc_state *cstate = &state->crtc_state;
6553 	struct vop2 *vop2 = cstate->private;
6554 	struct vop2_win_data *win_data;
6555 	int i;
6556 	u32 offset = 0;
6557 
6558 	/* layer sel win id */
6559 	for (i = 0; i < vop2->data->nr_vps; i++) {
6560 		if (vop2->vp_plane_mask[i].primary_plane_id != ROCKCHIP_VOP2_PHY_ID_INVALID) {
6561 			offset = 0x100 * i;
6562 			win_data = vop2_find_win_by_phys_id(vop2, vop2->vp_plane_mask[i].primary_plane_id);
6563 			vop2_mask_write(vop2, RK3528_OVL_PORT0_LAYER_SEL + offset, LAYER_SEL_MASK,
6564 					0, win_data->layer_sel_win_id[i], false);
6565 		}
6566 	}
6567 }
6568 
6569 #ifdef CONFIG_MOS_SECONDARY
6570 static void vop2_cluster_disable(void *regs, u32 offset)
6571 {
6572 	writel(0x0, regs + RK3568_CLUSTER0_WIN0_CTRL0 + offset);
6573 	writel(0x0, regs + RK3568_CLUSTER0_WIN1_CTRL0 + offset);
6574 	writel(0x0, regs + RK3568_CLUSTER0_CTRL + offset);
6575 }
6576 
6577 static void vop2_esmart_disable(void *regs, u32 offset)
6578 {
6579 	writel(0x0, regs + RK3568_ESMART0_REGION0_CTRL + offset);
6580 	writel(0x0, regs + RK3568_ESMART0_REGION1_CTRL + offset);
6581 	writel(0x0, regs + RK3568_ESMART0_REGION2_CTRL + offset);
6582 	writel(0x0, regs + RK3568_ESMART0_REGION3_CTRL + offset);
6583 }
6584 
6585 static void vop2_vp_irqs_disable(void *regs, u32 vp_id)
6586 {
6587 	u32 offset = 0x10 * vp_id;
6588 
6589 	writel(0xffff0000, regs + RK3568_VP0_INT_EN + offset);
6590 	writel(0xffffffff, regs + RK3568_VP0_INT_CLR + offset);
6591 }
6592 
6593 static void vop2_axi_irqs_disable(void *regs, u32 axi_id)
6594 {
6595 	u32 offset = 0x10 * axi_id;
6596 
6597 	writel(0xffff0000, regs + RK3568_VP0_INT_EN + offset);
6598 	writel(0xffffffff, regs + RK3568_VP0_INT_CLR + offset);
6599 }
6600 
6601 static bool vop2_vp_in_standby(void *regs, u32 vp_id)
6602 {
6603 	u32 offset = vp_id * 0x100;
6604 
6605 	return !!(readl(regs + RK3568_VP0_DSP_CTRL + offset) & BIT(STANDBY_EN_SHIFT));
6606 }
6607 
6608 static void vop2_vp_standby(void *regs, u32 vp_id)
6609 {
6610 	u32 offset = vp_id * 0x100;
6611 
6612 	writel(BIT(STANDBY_EN_SHIFT), regs + RK3568_VP0_DSP_CTRL + offset);
6613 }
6614 
6615 static void vop2_vp_config_done(void *regs, u32 vp_id)
6616 {
6617 	u32 cfg_done = CFG_DONE_EN | BIT(vp_id) | (BIT(vp_id) << 16);
6618 	u32 offset = vp_id * 0x100;
6619 
6620 	writel(cfg_done, regs + RK3568_REG_CFG_DONE + offset);
6621 }
6622 
6623 static void vop2_iommu_disable(void *regs, u32 axi_id)
6624 {
6625 	u32 val = readl(regs + RK3568_IOMMU0_STATUS);
6626 	bool pagefault = val & MMU_PAGE_FAULT_ACTIVE;
6627 	u32 offset = axi_id * 0x100;
6628 
6629 	writel(MMU_DISABLE_PAGING, regs + RK3568_IOMMU0_COMMAND + offset);
6630 
6631 	if (pagefault) {
6632 		printf("iommu%d status:0x%x, pagefault addr: 0x%x\n",
6633 			axi_id, val, readl(regs + RK3568_IOMMU0_PAGEFAULT_ADDR + offset));
6634 		writel(MMU_FORCE_RESET, regs + RK3568_IOMMU0_COMMAND + offset);
6635 	}
6636 }
6637 
6638 static int rockchip_vop2_reset(struct udevice *dev, u32 axi, u32 vp_mask, u32 plane_mask)
6639 {
6640 	void *regs = dev_read_addr_ptr(dev);
6641 	struct rockchip_crtc *crtc = (struct rockchip_crtc *)dev_get_driver_data(dev);
6642 	const struct vop2_data *vop2_data = crtc->data;
6643 	u32 enabled_vp_mask = 0;
6644 	int i = 0;
6645 
6646 	for (i = 0; i < vop2_data->nr_vps; i++) {
6647 		if (BIT(i) & vp_mask) {
6648 			if (!vop2_vp_in_standby(regs,i)) {
6649 				enabled_vp_mask |= BIT(i);
6650 			}
6651 		}
6652 	}
6653 
6654 	if (enabled_vp_mask == 0)
6655 		return 0;
6656 
6657 	for (i = 0; i < vop2_data->nr_layers; i++) {
6658 		if (BIT(vop2_data->win_data[i].phys_id) & plane_mask) {
6659 			if (vop2_data->win_data[i].type == CLUSTER_LAYER)
6660 				vop2_cluster_disable(regs, vop2_data->win_data[i].reg_offset);
6661 			else
6662 				vop2_esmart_disable(regs, vop2_data->win_data[i].reg_offset);
6663 		}
6664 	}
6665 
6666 	for (i = 0; i < vop2_data->nr_vps; i++) {
6667 		if (BIT(i) & vp_mask)
6668 			vop2_vp_config_done(regs, i);
6669 	}
6670 	mdelay(50);
6671 	vop2_iommu_disable(regs, axi);
6672 	vop2_axi_irqs_disable(regs, axi);
6673 
6674 	for (i = 0; i < vop2_data->nr_vps; i++) {
6675 		if (BIT(i) & vp_mask) {
6676 			vop2_vp_irqs_disable(regs, i);
6677 			vop2_vp_standby(regs, i);
6678 		}
6679 	}
6680 	printf("Reset vop success\n");
6681 
6682 	return 0;
6683 }
6684 #else
6685 static int rockchip_vop2_reset(struct udevice *dev, u32 axi, u32 vp_mask, u32 plane_mask)
6686 {
6687 	return 0;
6688 }
6689 #endif
6690 
6691 static struct vop2_dump_regs rk3528_dump_regs[] = {
6692 	{ RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
6693 	{ RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 },
6694 	{ RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
6695 	{ RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
6696 	{ RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
6697 	{ RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
6698 	{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 },
6699 	{ RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
6700 	{ RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
6701 	{ RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 },
6702 	{ RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 },
6703 	{ RK3528_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 },
6704 	{ RK3528_ACM_CTRL, "ACM", RK3528_ACM_CTRL, 0x1, 0, 1},
6705 };
6706 
6707 #define RK3528_PLANE_MASK_BASE \
6708 	(BIT(ROCKCHIP_VOP2_CLUSTER0) | \
6709 	 BIT(ROCKCHIP_VOP2_ESMART0)  | BIT(ROCKCHIP_VOP2_ESMART1)  | \
6710 	 BIT(ROCKCHIP_VOP2_ESMART2)  | BIT(ROCKCHIP_VOP2_ESMART3))
6711 
6712 static struct vop2_win_data rk3528_win_data[5] = {
6713 	{
6714 		.name = "Esmart0",
6715 		.phys_id = ROCKCHIP_VOP2_ESMART0,
6716 		.type = ESMART_LAYER,
6717 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
6718 		.win_sel_port_offset = 8,
6719 		.layer_sel_win_id = { 1, 0xff, 0xff, 0xff },
6720 		.reg_offset = 0,
6721 		.axi_id = 0,
6722 		.axi_yrgb_id = 0x06,
6723 		.axi_uv_id = 0x07,
6724 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6725 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6726 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6727 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6728 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
6729 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
6730 		.possible_vp_mask = BIT(VOP2_VP0),
6731 		.max_upscale_factor = 8,
6732 		.max_downscale_factor = 8,
6733 	},
6734 
6735 	{
6736 		.name = "Esmart1",
6737 		.phys_id = ROCKCHIP_VOP2_ESMART1,
6738 		.type = ESMART_LAYER,
6739 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
6740 		.win_sel_port_offset = 10,
6741 		.layer_sel_win_id = { 2, 0xff, 0xff, 0xff },
6742 		.reg_offset = 0x200,
6743 		.axi_id = 0,
6744 		.axi_yrgb_id = 0x08,
6745 		.axi_uv_id = 0x09,
6746 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6747 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6748 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6749 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6750 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
6751 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
6752 		.possible_vp_mask = BIT(VOP2_VP0),
6753 		.max_upscale_factor = 8,
6754 		.max_downscale_factor = 8,
6755 	},
6756 
6757 	{
6758 		.name = "Esmart2",
6759 		.phys_id = ROCKCHIP_VOP2_ESMART2,
6760 		.type = ESMART_LAYER,
6761 		.plane_type = VOP2_PLANE_TYPE_CURSOR,
6762 		.win_sel_port_offset = 12,
6763 		.layer_sel_win_id = { 3, 0, 0xff, 0xff },
6764 		.reg_offset = 0x400,
6765 		.axi_id = 0,
6766 		.axi_yrgb_id = 0x0a,
6767 		.axi_uv_id = 0x0b,
6768 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6769 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6770 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6771 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6772 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
6773 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
6774 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1),
6775 		.max_upscale_factor = 8,
6776 		.max_downscale_factor = 8,
6777 	},
6778 
6779 	{
6780 		.name = "Esmart3",
6781 		.phys_id = ROCKCHIP_VOP2_ESMART3,
6782 		.type = ESMART_LAYER,
6783 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
6784 		.win_sel_port_offset = 14,
6785 		.layer_sel_win_id = { 0xff, 1, 0xff, 0xff },
6786 		.reg_offset = 0x600,
6787 		.axi_id = 0,
6788 		.axi_yrgb_id = 0x0c,
6789 		.axi_uv_id = 0x0d,
6790 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6791 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6792 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6793 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6794 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
6795 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,	/* gt only */
6796 		.possible_vp_mask = BIT(VOP2_VP1),
6797 		.max_upscale_factor = 8,
6798 		.max_downscale_factor = 8,
6799 	},
6800 
6801 	{
6802 		.name = "Cluster0",
6803 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
6804 		.type = CLUSTER_LAYER,
6805 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
6806 		.win_sel_port_offset = 0,
6807 		.layer_sel_win_id = { 0, 0xff, 0xff, 0xff },
6808 		.reg_offset = 0,
6809 		.axi_id = 0,
6810 		.axi_yrgb_id = 0x02,
6811 		.axi_uv_id = 0x03,
6812 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6813 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6814 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6815 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6816 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
6817 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,	/* gt or avg */
6818 		.possible_vp_mask = BIT(VOP2_VP0),
6819 		.max_upscale_factor = 8,
6820 		.max_downscale_factor = 8,
6821 	},
6822 };
6823 
6824 static struct vop2_vp_data rk3528_vp_data[2] = {
6825 	{
6826 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_POST_ACM |
6827 			   VOP_FEATURE_POST_CSC,
6828 		.max_output = {4096, 4096},
6829 		.layer_mix_dly = 6,
6830 		.hdr_mix_dly = 2,
6831 		.win_dly = 8,
6832 	},
6833 	{
6834 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
6835 		.max_output = {1920, 1080},
6836 		.layer_mix_dly = 2,
6837 		.hdr_mix_dly = 0,
6838 		.win_dly = 8,
6839 	},
6840 };
6841 
6842 static const struct vop2_ops rk3528_vop_ops = {
6843 	.setup_win_dly = rk3528_setup_win_dly,
6844 	.setup_overlay = rk3528_setup_overlay,
6845 	.assign_plane_mask = rk3528_assign_plane_mask,
6846 };
6847 
6848 const struct vop2_data rk3528_vop = {
6849 	.version = VOP_VERSION_RK3528,
6850 	.nr_vps = 2,
6851 	.vp_data = rk3528_vp_data,
6852 	.win_data = rk3528_win_data,
6853 	.plane_mask_base = RK3528_PLANE_MASK_BASE,
6854 	.nr_layers = 5,
6855 	.nr_mixers = 3,
6856 	.nr_gammas = 2,
6857 	.esmart_lb_mode = VOP3_ESMART_4K_2K_2K_MODE,
6858 	.dump_regs = rk3528_dump_regs,
6859 	.dump_regs_size = ARRAY_SIZE(rk3528_dump_regs),
6860 	.ops = &rk3528_vop_ops,
6861 
6862 };
6863 
6864 static struct vop2_dump_regs rk3562_dump_regs[] = {
6865 	{ RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
6866 	{ RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 },
6867 	{ RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
6868 	{ RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
6869 	{ RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
6870 	{ RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
6871 	{ RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
6872 	{ RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
6873 	{ RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 },
6874 	{ RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 },
6875 };
6876 
6877 #define RK3562_PLANE_MASK_BASE \
6878 	(BIT(ROCKCHIP_VOP2_ESMART0)  | BIT(ROCKCHIP_VOP2_ESMART1)  | \
6879 	 BIT(ROCKCHIP_VOP2_ESMART2)  | BIT(ROCKCHIP_VOP2_ESMART3))
6880 
6881 static struct vop2_win_data rk3562_win_data[4] = {
6882 	{
6883 		.name = "Esmart0",
6884 		.phys_id = ROCKCHIP_VOP2_ESMART0,
6885 		.type = ESMART_LAYER,
6886 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
6887 		.win_sel_port_offset = 8,
6888 		.layer_sel_win_id = { 0, 0, 0xff, 0xff },
6889 		.reg_offset = 0,
6890 		.axi_id = 0,
6891 		.axi_yrgb_id = 0x02,
6892 		.axi_uv_id = 0x03,
6893 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6894 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6895 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6896 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6897 		.possible_vp_mask = BIT(VOP2_VP0),
6898 		.max_upscale_factor = 8,
6899 		.max_downscale_factor = 8,
6900 	},
6901 
6902 	{
6903 		.name = "Esmart1",
6904 		.phys_id = ROCKCHIP_VOP2_ESMART1,
6905 		.type = ESMART_LAYER,
6906 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
6907 		.win_sel_port_offset = 10,
6908 		.layer_sel_win_id = { 1, 1, 0xff, 0xff },
6909 		.reg_offset = 0x200,
6910 		.axi_id = 0,
6911 		.axi_yrgb_id = 0x04,
6912 		.axi_uv_id = 0x05,
6913 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6914 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6915 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6916 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6917 		.possible_vp_mask = BIT(VOP2_VP0),
6918 		.max_upscale_factor = 8,
6919 		.max_downscale_factor = 8,
6920 	},
6921 
6922 	{
6923 		.name = "Esmart2",
6924 		.phys_id = ROCKCHIP_VOP2_ESMART2,
6925 		.type = ESMART_LAYER,
6926 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
6927 		.win_sel_port_offset = 12,
6928 		.layer_sel_win_id = { 2, 2, 0xff, 0xff },
6929 		.reg_offset = 0x400,
6930 		.axi_id = 0,
6931 		.axi_yrgb_id = 0x06,
6932 		.axi_uv_id = 0x07,
6933 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6934 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6935 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6936 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6937 		.possible_vp_mask = BIT(VOP2_VP0),
6938 		.max_upscale_factor = 8,
6939 		.max_downscale_factor = 8,
6940 	},
6941 
6942 	{
6943 		.name = "Esmart3",
6944 		.phys_id = ROCKCHIP_VOP2_ESMART3,
6945 		.type = ESMART_LAYER,
6946 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
6947 		.win_sel_port_offset = 14,
6948 		.layer_sel_win_id = { 3, 3, 0xff, 0xff },
6949 		.reg_offset = 0x600,
6950 		.axi_id = 0,
6951 		.axi_yrgb_id = 0x08,
6952 		.axi_uv_id = 0x0d,
6953 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
6954 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6955 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
6956 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
6957 		.possible_vp_mask = BIT(VOP2_VP0),
6958 		.max_upscale_factor = 8,
6959 		.max_downscale_factor = 8,
6960 	},
6961 };
6962 
6963 static struct vop2_vp_data rk3562_vp_data[2] = {
6964 	{
6965 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
6966 		.max_output = {2048, 4096},
6967 		.win_dly = 6,
6968 		.layer_mix_dly = 8,
6969 	},
6970 	{
6971 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
6972 		.max_output = {2048, 1080},
6973 		.win_dly = 8,
6974 		.layer_mix_dly = 8,
6975 	},
6976 };
6977 
6978 static const struct vop2_ops rk3562_vop_ops = {
6979 	.setup_win_dly = rk3528_setup_win_dly,
6980 	.setup_overlay = rk3528_setup_overlay,
6981 	.assign_plane_mask = rk3528_assign_plane_mask,
6982 };
6983 
6984 const struct vop2_data rk3562_vop = {
6985 	.version = VOP_VERSION_RK3562,
6986 	.nr_vps = 2,
6987 	.vp_data = rk3562_vp_data,
6988 	.win_data = rk3562_win_data,
6989 	.plane_mask_base = RK3562_PLANE_MASK_BASE,
6990 	.nr_layers = 4,
6991 	.nr_mixers = 3,
6992 	.nr_gammas = 2,
6993 	.esmart_lb_mode = VOP3_ESMART_2K_2K_2K_2K_MODE,
6994 	.dump_regs = rk3562_dump_regs,
6995 	.dump_regs_size = ARRAY_SIZE(rk3562_dump_regs),
6996 	.ops = &rk3562_vop_ops,
6997 };
6998 
6999 static struct vop2_dump_regs rk3568_dump_regs[] = {
7000 	{ RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
7001 	{ RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 },
7002 	{ RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
7003 	{ RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
7004 	{ RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 },
7005 	{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 },
7006 	{ RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 },
7007 	{ RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
7008 	{ RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
7009 	{ RK3568_SMART0_CTRL0, "Smart0", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 },
7010 	{ RK3568_SMART1_CTRL0, "Smart1", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 },
7011 	{ RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 },
7012 };
7013 
7014 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
7015 	{ /* one display policy */
7016 		{/* main display */
7017 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
7018 			.attached_layers_nr = 6,
7019 			.attached_layers = {
7020 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0,
7021 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
7022 				},
7023 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7024 		},
7025 		{/* second display */},
7026 		{/* third  display */},
7027 		{/* fourth display */},
7028 	},
7029 
7030 	{ /* two display policy */
7031 		{/* main display */
7032 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
7033 			.attached_layers_nr = 3,
7034 			.attached_layers = {
7035 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
7036 				},
7037 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7038 		},
7039 
7040 		{/* second display */
7041 			.primary_plane_id = ROCKCHIP_VOP2_SMART1,
7042 			.attached_layers_nr = 3,
7043 			.attached_layers = {
7044 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
7045 				},
7046 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7047 		},
7048 		{/* third  display */},
7049 		{/* fourth display */},
7050 	},
7051 
7052 	{ /* three display policy */
7053 		{/* main display */
7054 			.primary_plane_id = ROCKCHIP_VOP2_SMART0,
7055 			.attached_layers_nr = 3,
7056 			.attached_layers = {
7057 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
7058 				},
7059 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7060 		},
7061 
7062 		{/* second display */
7063 			.primary_plane_id = ROCKCHIP_VOP2_SMART1,
7064 			.attached_layers_nr = 2,
7065 			.attached_layers = {
7066 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1
7067 				},
7068 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7069 		},
7070 
7071 		{/* third  display */
7072 			.primary_plane_id = ROCKCHIP_VOP2_ESMART1,
7073 			.attached_layers_nr = 1,
7074 			.attached_layers = { ROCKCHIP_VOP2_ESMART1 },
7075 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7076 		},
7077 
7078 		{/* fourth display */},
7079 	},
7080 
7081 	{/* reserved for four display policy */},
7082 };
7083 
7084 #define RK3568_PLANE_MASK_BASE \
7085 	(BIT(ROCKCHIP_VOP2_CLUSTER0) | BIT(ROCKCHIP_VOP2_CLUSTER1) | \
7086 	 BIT(ROCKCHIP_VOP2_ESMART0)  | BIT(ROCKCHIP_VOP2_ESMART1)  | \
7087 	 BIT(ROCKCHIP_VOP2_SMART0)   | BIT(ROCKCHIP_VOP2_SMART1))
7088 
7089 static struct vop2_win_data rk3568_win_data[6] = {
7090 	{
7091 		.name = "Cluster0",
7092 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
7093 		.type = CLUSTER_LAYER,
7094 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7095 		.win_sel_port_offset = 0,
7096 		.layer_sel_win_id = { 0, 0, 0, 0xff },
7097 		.reg_offset = 0,
7098 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7099 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7100 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7101 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7102 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2),
7103 		.max_upscale_factor = 4,
7104 		.max_downscale_factor = 4,
7105 		.dly = { 0, 27, 21 },
7106 	},
7107 
7108 	{
7109 		.name = "Cluster1",
7110 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
7111 		.type = CLUSTER_LAYER,
7112 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7113 		.win_sel_port_offset = 1,
7114 		.layer_sel_win_id = { 1, 1, 1, 0xff },
7115 		.reg_offset = 0x200,
7116 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7117 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7118 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7119 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7120 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2),
7121 		.max_upscale_factor = 4,
7122 		.max_downscale_factor = 4,
7123 		.source_win_id = ROCKCHIP_VOP2_CLUSTER0,
7124 		.feature = WIN_FEATURE_MIRROR,
7125 		.dly = { 0, 27, 21 },
7126 	},
7127 
7128 	{
7129 		.name = "Esmart0",
7130 		.phys_id = ROCKCHIP_VOP2_ESMART0,
7131 		.type = ESMART_LAYER,
7132 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7133 		.win_sel_port_offset = 4,
7134 		.layer_sel_win_id = { 2, 2, 2, 0xff },
7135 		.reg_offset = 0,
7136 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7137 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7138 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7139 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7140 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2),
7141 		.max_upscale_factor = 8,
7142 		.max_downscale_factor = 8,
7143 		.dly = { 20, 47, 41 },
7144 	},
7145 
7146 	{
7147 		.name = "Esmart1",
7148 		.phys_id = ROCKCHIP_VOP2_ESMART1,
7149 		.type = ESMART_LAYER,
7150 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7151 		.win_sel_port_offset = 5,
7152 		.layer_sel_win_id = { 6, 6, 6, 0xff },
7153 		.reg_offset = 0x200,
7154 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7155 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7156 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7157 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7158 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2),
7159 		.max_upscale_factor = 8,
7160 		.max_downscale_factor = 8,
7161 		.dly = { 20, 47, 41 },
7162 		.source_win_id = ROCKCHIP_VOP2_ESMART0,
7163 		.feature = WIN_FEATURE_MIRROR,
7164 	},
7165 
7166 	{
7167 		.name = "Smart0",
7168 		.phys_id = ROCKCHIP_VOP2_SMART0,
7169 		.type = SMART_LAYER,
7170 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7171 		.win_sel_port_offset = 6,
7172 		.layer_sel_win_id = { 3, 3, 3, 0xff },
7173 		.reg_offset = 0x400,
7174 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7175 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7176 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7177 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7178 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2),
7179 		.max_upscale_factor = 8,
7180 		.max_downscale_factor = 8,
7181 		.dly = { 20, 47, 41 },
7182 	},
7183 
7184 	{
7185 		.name = "Smart1",
7186 		.phys_id = ROCKCHIP_VOP2_SMART1,
7187 		.type = SMART_LAYER,
7188 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7189 		.win_sel_port_offset = 7,
7190 		.layer_sel_win_id = { 7, 7, 7, 0xff },
7191 		.reg_offset = 0x600,
7192 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7193 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7194 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7195 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7196 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2),
7197 		.max_upscale_factor = 8,
7198 		.max_downscale_factor = 8,
7199 		.dly = { 20, 47, 41 },
7200 		.source_win_id = ROCKCHIP_VOP2_SMART0,
7201 		.feature = WIN_FEATURE_MIRROR,
7202 	},
7203 };
7204 
7205 static struct vop2_vp_data rk3568_vp_data[3] = {
7206 	{
7207 		.feature = VOP_FEATURE_OUTPUT_10BIT,
7208 		.pre_scan_max_dly = 42,
7209 		.max_output = {4096, 2304},
7210 	},
7211 	{
7212 		.feature = 0,
7213 		.pre_scan_max_dly = 40,
7214 		.max_output = {2048, 1536},
7215 	},
7216 	{
7217 		.feature = 0,
7218 		.pre_scan_max_dly = 40,
7219 		.max_output = {1920, 1080},
7220 	},
7221 };
7222 
7223 static const struct vop2_ops rk3568_vop_ops = {
7224 	.setup_win_dly = rk3568_setup_win_dly,
7225 	.setup_overlay = rk3568_setup_overlay,
7226 	.assign_plane_mask = rk3568_assign_plane_mask,
7227 };
7228 
7229 const struct vop2_data rk3568_vop = {
7230 	.version = VOP_VERSION_RK3568,
7231 	.nr_vps = 3,
7232 	.vp_data = rk3568_vp_data,
7233 	.win_data = rk3568_win_data,
7234 	.plane_mask = rk356x_vp_plane_mask[0],
7235 	.plane_mask_base = RK3568_PLANE_MASK_BASE,
7236 	.nr_layers = 6,
7237 	.nr_mixers = 5,
7238 	.nr_gammas = 1,
7239 	.dump_regs = rk3568_dump_regs,
7240 	.dump_regs_size = ARRAY_SIZE(rk3568_dump_regs),
7241 	.ops = &rk3568_vop_ops,
7242 };
7243 
7244 #define RK3576_PLANE_MASK_BASE \
7245 	(BIT(ROCKCHIP_VOP2_CLUSTER0) | BIT(ROCKCHIP_VOP2_CLUSTER1) | \
7246 	 BIT(ROCKCHIP_VOP2_ESMART0)  | BIT(ROCKCHIP_VOP2_ESMART1)  | \
7247 	 BIT(ROCKCHIP_VOP2_ESMART2)  | BIT(ROCKCHIP_VOP2_ESMART3))
7248 
7249 static struct vop2_dump_regs rk3576_dump_regs[] = {
7250 	{ RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0, 0x200 },
7251 	{ RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0, 0x50 },
7252 	{ RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x80 },
7253 	{ RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0, 0x80 },
7254 	{ RK3576_OVL_PORT2_CTRL, "OVL_VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0, 0x80 },
7255 	{ RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x100 },
7256 	{ RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x100 },
7257 	{ RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x100 },
7258 	{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1, 0x200 },
7259 	{ RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1, 0x200 },
7260 	{ RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1, 0x100 },
7261 	{ RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1, 0x100 },
7262 	{ RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1, 0x100 },
7263 	{ RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1, 0x100 },
7264 	{ RK3528_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0, 0x100 },
7265 };
7266 
7267 /*
7268  * RK3576 VOP with 2 Cluster win and 4 Esmart win.
7269  * Every Esmart win support 4 multi-region.
7270  * VP0 can use Cluster0/1 and Esmart0/2
7271  * VP1 can use Cluster0/1 and Esmart1/3
7272  * VP2 can use Esmart0/1/2/3
7273  *
7274  * Scale filter mode:
7275  *
7276  * * Cluster:
7277  * * Support prescale down:
7278  * * H/V: gt2/avg2 or gt4/avg4
7279  * * After prescale down:
7280  *	* nearest-neighbor/bilinear/multi-phase filter for scale up
7281  *	* nearest-neighbor/bilinear/multi-phase filter for scale down
7282  *
7283  * * Esmart:
7284  * * Support prescale down:
7285  * * H: gt2/avg2 or gt4/avg4
7286  * * V: gt2 or gt4
7287  * * After prescale down:
7288  *	* nearest-neighbor/bilinear/bicubic for scale up
7289  *	* nearest-neighbor/bilinear for scale down
7290  *
7291  * AXI config::
7292  *
7293  * * Cluster0 win0: 0xa,  0xb       [AXI0]
7294  * * Cluster0 win1: 0xc,  0xd       [AXI0]
7295  * * Cluster1 win0: 0x6,  0x7       [AXI0]
7296  * * Cluster1 win1: 0x8,  0x9       [AXI0]
7297  * * Esmart0:       0x10, 0x11      [AXI0]
7298  * * Esmart1:       0x12, 0x13      [AXI0]
7299  * * Esmart2:       0xa,  0xb       [AXI1]
7300  * * Esmart3:       0xc,  0xd       [AXI1]
7301  * * Lut dma rid:   0x1,  0x2,  0x3 [AXI0]
7302  * * DCI dma rid:   0x4             [AXI0]
7303  * * Metadata rid:  0x5             [AXI0]
7304  *
7305  * * Limit:
7306  * * (1) 0x0 and 0xf can't be used;
7307  * * (2) cluster and lut/dci/metadata rid must smaller than 0xf, If Cluster rid is bigger than 0xf,
7308  * * VOP will dead at the system bandwidth very terrible scene.
7309  */
7310 static struct vop2_win_data rk3576_win_data[6] = {
7311 	{
7312 		.name = "Esmart0",
7313 		.phys_id = ROCKCHIP_VOP2_ESMART0,
7314 		.type = ESMART_LAYER,
7315 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7316 		.layer_sel_win_id = { 2, 0xff, 0, 0xff },
7317 		.reg_offset = 0x0,
7318 		.supported_rotations = DRM_MODE_REFLECT_Y,
7319 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7320 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7321 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7322 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7323 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7324 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */
7325 		.pd_id = VOP2_PD_ESMART,
7326 		.axi_id = 0,
7327 		.axi_yrgb_id = 0x10,
7328 		.axi_uv_id = 0x11,
7329 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP2),
7330 		.max_upscale_factor = 8,
7331 		.max_downscale_factor = 8,
7332 		.feature = WIN_FEATURE_MULTI_AREA | WIN_FEATURE_Y2R_13BIT_DEPTH,
7333 	},
7334 	{
7335 		.name = "Esmart1",
7336 		.phys_id = ROCKCHIP_VOP2_ESMART1,
7337 		.type = ESMART_LAYER,
7338 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7339 		.layer_sel_win_id = { 0xff, 2, 1, 0xff },
7340 		.reg_offset = 0x200,
7341 		.supported_rotations = DRM_MODE_REFLECT_Y,
7342 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7343 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7344 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7345 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7346 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7347 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */
7348 		.pd_id = VOP2_PD_ESMART,
7349 		.axi_id = 0,
7350 		.axi_yrgb_id = 0x12,
7351 		.axi_uv_id = 0x13,
7352 		.possible_vp_mask = BIT(VOP2_VP1) | BIT(VOP2_VP2),
7353 		.max_upscale_factor = 8,
7354 		.max_downscale_factor = 8,
7355 		.feature = WIN_FEATURE_MULTI_AREA,
7356 	},
7357 
7358 	{
7359 		.name = "Esmart2",
7360 		.phys_id = ROCKCHIP_VOP2_ESMART2,
7361 		.type = ESMART_LAYER,
7362 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7363 		.layer_sel_win_id = { 3, 0xff, 2, 0xff },
7364 		.reg_offset = 0x400,
7365 		.supported_rotations = DRM_MODE_REFLECT_Y,
7366 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7367 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7368 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7369 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7370 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7371 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */
7372 		.pd_id = VOP2_PD_ESMART,
7373 		.axi_id = 1,
7374 		.axi_yrgb_id = 0x0a,
7375 		.axi_uv_id = 0x0b,
7376 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP2),
7377 		.max_upscale_factor = 8,
7378 		.max_downscale_factor = 8,
7379 		.feature = WIN_FEATURE_MULTI_AREA,
7380 	},
7381 
7382 	{
7383 		.name = "Esmart3",
7384 		.phys_id = ROCKCHIP_VOP2_ESMART3,
7385 		.type = ESMART_LAYER,
7386 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7387 		.layer_sel_win_id = { 0xff, 3, 3, 0xff },
7388 		.reg_offset = 0x600,
7389 		.supported_rotations = DRM_MODE_REFLECT_Y,
7390 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7391 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7392 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7393 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7394 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7395 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */
7396 		.pd_id = VOP2_PD_ESMART,
7397 		.axi_id = 1,
7398 		.axi_yrgb_id = 0x0c,
7399 		.axi_uv_id = 0x0d,
7400 		.possible_vp_mask = BIT(VOP2_VP1) | BIT(VOP2_VP2),
7401 		.max_upscale_factor = 8,
7402 		.max_downscale_factor = 8,
7403 		.feature = WIN_FEATURE_MULTI_AREA,
7404 	},
7405 
7406 	{
7407 		.name = "Cluster0",
7408 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
7409 		.type = CLUSTER_LAYER,
7410 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7411 		.layer_sel_win_id = { 0, 0, 0xff, 0xff },
7412 		.reg_offset = 0x0,
7413 		.supported_rotations = DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
7414 		.hsu_filter_mode = VOP2_SCALE_UP_BIL,
7415 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7416 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7417 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7418 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7419 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7420 		.pd_id = VOP2_PD_CLUSTER,
7421 		.axi_yrgb_id = 0x0a,
7422 		.axi_uv_id = 0x0b,
7423 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1),
7424 		.max_upscale_factor = 8,
7425 		.max_downscale_factor = 8,
7426 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_MAIN |
7427 			   WIN_FEATURE_Y2R_13BIT_DEPTH | WIN_FEATURE_DCI,
7428 	},
7429 
7430 	{
7431 		.name = "Cluster1",
7432 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
7433 		.type = CLUSTER_LAYER,
7434 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7435 		.layer_sel_win_id = { 1, 1, 0xff, 0xff },
7436 		.reg_offset = 0x200,
7437 		.supported_rotations = DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
7438 		.hsu_filter_mode = VOP2_SCALE_UP_BIL,
7439 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7440 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7441 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7442 		.hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7443 		.vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */
7444 		.pd_id = VOP2_PD_CLUSTER,
7445 		.axi_yrgb_id = 0x06,
7446 		.axi_uv_id = 0x07,
7447 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1),
7448 		.max_upscale_factor = 8,
7449 		.max_downscale_factor = 8,
7450 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_MAIN |
7451 			   WIN_FEATURE_Y2R_13BIT_DEPTH,
7452 	},
7453 };
7454 
7455 /*
7456  * RK3576 VP0 has 8 lines post linebuffer, when full post line buffer is less 4,
7457  * the urgency signal will be set to 1, when full post line buffer is over 6, the
7458  * urgency signal will be set to 0.
7459  */
7460 static struct vop_urgency rk3576_vp0_urgency = {
7461 	.urgen_thl = 4,
7462 	.urgen_thh = 6,
7463 };
7464 
7465 static struct vop2_vp_data rk3576_vp_data[3] = {
7466 	{
7467 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_VIVID_HDR |
7468 			   VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC | VOP_FEATURE_OUTPUT_10BIT |
7469 			   VOP_FEATURE_POST_FRC_V2 | VOP_FEATURE_POST_SHARP,
7470 		.max_output = { 4096, 4096 },
7471 		.hdrvivid_dly = 21,
7472 		.sdr2hdr_dly = 21,
7473 		.layer_mix_dly = 8,
7474 		.hdr_mix_dly = 2,
7475 		.win_dly = 10,
7476 		.pixel_rate = 2,
7477 		.urgency = &rk3576_vp0_urgency,
7478 	},
7479 	{
7480 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN |
7481 			   VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_POST_FRC_V2,
7482 		.max_output = { 2560, 2560 },
7483 		.hdrvivid_dly = 0,
7484 		.sdr2hdr_dly = 0,
7485 		.layer_mix_dly = 6,
7486 		.hdr_mix_dly = 0,
7487 		.win_dly = 10,
7488 		.pixel_rate = 1,
7489 	},
7490 	{
7491 		.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
7492 		.max_output = { 1920, 1920 },
7493 		.hdrvivid_dly = 0,
7494 		.sdr2hdr_dly = 0,
7495 		.layer_mix_dly = 6,
7496 		.hdr_mix_dly = 0,
7497 		.win_dly = 10,
7498 		.pixel_rate = 1,
7499 	},
7500 };
7501 
7502 static struct vop2_power_domain_data rk3576_vop_pd_data[] = {
7503 	{
7504 		.id = VOP2_PD_CLUSTER,
7505 		.module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0) | BIT(ROCKCHIP_VOP2_CLUSTER1),
7506 	},
7507 	{
7508 		.id = VOP2_PD_ESMART,
7509 		.module_id_mask = BIT(ROCKCHIP_VOP2_ESMART0) | BIT(ROCKCHIP_VOP2_ESMART1) |
7510 				  BIT(ROCKCHIP_VOP2_ESMART2) | BIT(ROCKCHIP_VOP2_ESMART3),
7511 	},
7512 };
7513 
7514 static const struct vop2_esmart_lb_map rk3576_esmart_lb_mode_map[] = {
7515 	{VOP3_ESMART_4K_4K_4K_MODE, 2},
7516 	{VOP3_ESMART_4K_4K_2K_2K_MODE, 3}
7517 };
7518 
7519 static const struct vop2_ops rk3576_vop_ops = {
7520 	.setup_win_dly = rk3576_setup_win_dly,
7521 	.setup_overlay = rk3576_setup_overlay,
7522 	.assign_plane_mask = rk3528_assign_plane_mask,
7523 };
7524 
7525 const struct vop2_data rk3576_vop = {
7526 	.version = VOP_VERSION_RK3576,
7527 	.nr_vps = 3,
7528 	.nr_mixers = 4,
7529 	.nr_layers = 6,
7530 	.nr_gammas = 3,
7531 	.esmart_lb_mode = VOP3_ESMART_4K_4K_2K_2K_MODE,
7532 	.esmart_lb_mode_num = ARRAY_SIZE(rk3576_esmart_lb_mode_map),
7533 	.esmart_lb_mode_map = rk3576_esmart_lb_mode_map,
7534 	.vp_data = rk3576_vp_data,
7535 	.win_data = rk3576_win_data,
7536 	.plane_mask_base = RK3576_PLANE_MASK_BASE,
7537 	.pd = rk3576_vop_pd_data,
7538 	.nr_pd = ARRAY_SIZE(rk3576_vop_pd_data),
7539 	.dump_regs = rk3576_dump_regs,
7540 	.dump_regs_size = ARRAY_SIZE(rk3576_dump_regs),
7541 	.ops = &rk3576_vop_ops,
7542 };
7543 
7544 static struct vop2_dump_regs rk3588_dump_regs[] = {
7545 	{ RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
7546 	{ RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 },
7547 	{ RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
7548 	{ RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
7549 	{ RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 },
7550 	{ RK3588_VP3_DSP_CTRL, "VP3", RK3588_VP3_DSP_CTRL, 0x1, 31, 0 },
7551 	{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 },
7552 	{ RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 },
7553 	{ RK3588_CLUSTER2_WIN0_CTRL0, "Cluster2", RK3588_CLUSTER2_WIN0_CTRL0, 0x1, 0, 1 },
7554 	{ RK3588_CLUSTER3_WIN0_CTRL0, "Cluster3", RK3588_CLUSTER3_WIN0_CTRL0, 0x1, 0, 1 },
7555 	{ RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
7556 	{ RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
7557 	{ RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 },
7558 	{ RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 },
7559 	{ RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 },
7560 };
7561 
7562 static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
7563 	{ /* one display policy */
7564 		{/* main display */
7565 			.primary_plane_id = ROCKCHIP_VOP2_ESMART0,
7566 			.attached_layers_nr = 4,
7567 			.attached_layers = {
7568 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0,
7569 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2
7570 			},
7571 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7572 		},
7573 
7574 		{/* planes for the splice mode */
7575 			.primary_plane_id = ROCKCHIP_VOP2_ESMART1,
7576 			.attached_layers_nr = 4,
7577 			.attached_layers = {
7578 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1,
7579 				  ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3
7580 			},
7581 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7582 		},
7583 		{/* third  display */},
7584 		{/* fourth display */},
7585 	},
7586 
7587 	{ /* two display policy */
7588 		{/* main display */
7589 			.primary_plane_id = ROCKCHIP_VOP2_ESMART0,
7590 			.attached_layers_nr = 4,
7591 			.attached_layers = {
7592 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0,
7593 				  ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2
7594 			},
7595 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7596 		},
7597 
7598 		{/* second display */
7599 			.primary_plane_id = ROCKCHIP_VOP2_ESMART1,
7600 			.attached_layers_nr = 4,
7601 			.attached_layers = {
7602 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1,
7603 				  ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3
7604 			},
7605 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7606 		},
7607 		{/* third  display */},
7608 		{/* fourth display */},
7609 	},
7610 
7611 	{ /* three display policy */
7612 		{/* main display */
7613 			.primary_plane_id = ROCKCHIP_VOP2_ESMART0,
7614 			.attached_layers_nr = 3,
7615 			.attached_layers = {
7616 				  ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER2,
7617 				  ROCKCHIP_VOP2_ESMART0
7618 			},
7619 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7620 		},
7621 
7622 		{/* second display */
7623 			.primary_plane_id = ROCKCHIP_VOP2_ESMART1,
7624 			.attached_layers_nr = 3,
7625 			.attached_layers = {
7626 				  ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_CLUSTER3,
7627 				  ROCKCHIP_VOP2_ESMART1
7628 			},
7629 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7630 		},
7631 
7632 		{/* third  display */
7633 			.primary_plane_id = ROCKCHIP_VOP2_ESMART2,
7634 			.attached_layers_nr = 2,
7635 			.attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 },
7636 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7637 		},
7638 
7639 		{/* fourth display */},
7640 	},
7641 
7642 	{ /* four display policy */
7643 		{/* main display */
7644 			.primary_plane_id = ROCKCHIP_VOP2_ESMART0,
7645 			.attached_layers_nr = 2,
7646 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 },
7647 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7648 		},
7649 
7650 		{/* second display */
7651 			.primary_plane_id = ROCKCHIP_VOP2_ESMART1,
7652 			.attached_layers_nr = 2,
7653 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 },
7654 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7655 		},
7656 
7657 		{/* third  display */
7658 			.primary_plane_id = ROCKCHIP_VOP2_ESMART2,
7659 			.attached_layers_nr = 2,
7660 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 },
7661 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7662 		},
7663 
7664 		{/* fourth display */
7665 			.primary_plane_id = ROCKCHIP_VOP2_ESMART3,
7666 			.attached_layers_nr = 2,
7667 			.attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 },
7668 			.cursor_plane_id = ROCKCHIP_VOP2_PHY_ID_INVALID,
7669 		},
7670 	},
7671 
7672 };
7673 
7674 #define RK3588_PLANE_MASK_BASE \
7675 	(BIT(ROCKCHIP_VOP2_CLUSTER0) | BIT(ROCKCHIP_VOP2_CLUSTER1) | \
7676 	 BIT(ROCKCHIP_VOP2_CLUSTER2) | BIT(ROCKCHIP_VOP2_CLUSTER3) | \
7677 	 BIT(ROCKCHIP_VOP2_ESMART0)  | BIT(ROCKCHIP_VOP2_ESMART1)  | \
7678 	 BIT(ROCKCHIP_VOP2_ESMART2)  | BIT(ROCKCHIP_VOP2_ESMART3))
7679 
7680 static struct vop2_win_data rk3588_win_data[8] = {
7681 	{
7682 		.name = "Cluster0",
7683 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
7684 		.splice_win_id = ROCKCHIP_VOP2_CLUSTER1,
7685 		.type = CLUSTER_LAYER,
7686 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7687 		.win_sel_port_offset = 0,
7688 		.layer_sel_win_id = { 0, 0, 0, 0 },
7689 		.reg_offset = 0,
7690 		.axi_id = 0,
7691 		.axi_yrgb_id = 2,
7692 		.axi_uv_id = 3,
7693 		.pd_id = VOP2_PD_CLUSTER0,
7694 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7695 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7696 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7697 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7698 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7699 		.max_upscale_factor = 4,
7700 		.max_downscale_factor = 4,
7701 		.dly = { 4, 26, 29, 4, 35, 3, 5 },
7702 	},
7703 
7704 	{
7705 		.name = "Cluster1",
7706 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
7707 		.type = CLUSTER_LAYER,
7708 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7709 		.win_sel_port_offset = 1,
7710 		.layer_sel_win_id = { 1, 1, 1, 1 },
7711 		.reg_offset = 0x200,
7712 		.axi_id = 0,
7713 		.axi_yrgb_id = 6,
7714 		.axi_uv_id = 7,
7715 		.pd_id = VOP2_PD_CLUSTER1,
7716 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7717 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7718 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7719 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7720 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7721 		.max_upscale_factor = 4,
7722 		.max_downscale_factor = 4,
7723 		.dly = { 4, 26, 29, 4, 35, 3, 5 },
7724 	},
7725 
7726 	{
7727 		.name = "Cluster2",
7728 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
7729 		.splice_win_id = ROCKCHIP_VOP2_CLUSTER3,
7730 		.type = CLUSTER_LAYER,
7731 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7732 		.win_sel_port_offset = 2,
7733 		.layer_sel_win_id = { 4, 4, 4, 4 },
7734 		.reg_offset = 0x400,
7735 		.axi_id = 1,
7736 		.axi_yrgb_id = 2,
7737 		.axi_uv_id = 3,
7738 		.pd_id = VOP2_PD_CLUSTER2,
7739 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7740 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7741 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7742 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7743 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7744 		.max_upscale_factor = 4,
7745 		.max_downscale_factor = 4,
7746 		.dly = { 4, 26, 29, 4, 35, 3, 5 },
7747 	},
7748 
7749 	{
7750 		.name = "Cluster3",
7751 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
7752 		.type = CLUSTER_LAYER,
7753 		.plane_type = VOP2_PLANE_TYPE_OVERLAY,
7754 		.win_sel_port_offset = 3,
7755 		.layer_sel_win_id = { 5, 5, 5, 5 },
7756 		.reg_offset = 0x600,
7757 		.axi_id = 1,
7758 		.axi_yrgb_id = 6,
7759 		.axi_uv_id = 7,
7760 		.pd_id = VOP2_PD_CLUSTER3,
7761 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7762 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7763 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7764 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7765 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7766 		.max_upscale_factor = 4,
7767 		.max_downscale_factor = 4,
7768 		.dly = { 4, 26, 29, 4, 35, 3, 5 },
7769 	},
7770 
7771 	{
7772 		.name = "Esmart0",
7773 		.phys_id = ROCKCHIP_VOP2_ESMART0,
7774 		.splice_win_id = ROCKCHIP_VOP2_ESMART1,
7775 		.type = ESMART_LAYER,
7776 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7777 		.win_sel_port_offset = 4,
7778 		.layer_sel_win_id = { 2, 2, 2, 2 },
7779 		.reg_offset = 0,
7780 		.axi_id = 0,
7781 		.axi_yrgb_id = 0x0a,
7782 		.axi_uv_id = 0x0b,
7783 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7784 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7785 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7786 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7787 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7788 		.max_upscale_factor = 8,
7789 		.max_downscale_factor = 8,
7790 		.dly = { 23, 45, 48, 23, 54, 22, 24 },
7791 	},
7792 
7793 	{
7794 		.name = "Esmart1",
7795 		.phys_id = ROCKCHIP_VOP2_ESMART1,
7796 		.type = ESMART_LAYER,
7797 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7798 		.win_sel_port_offset = 5,
7799 		.layer_sel_win_id = { 3, 3, 3, 3 },
7800 		.reg_offset = 0x200,
7801 		.axi_id = 0,
7802 		.axi_yrgb_id = 0x0c,
7803 		.axi_uv_id = 0x0d,
7804 		.pd_id = VOP2_PD_ESMART,
7805 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7806 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7807 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7808 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7809 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7810 		.max_upscale_factor = 8,
7811 		.max_downscale_factor = 8,
7812 		.dly = { 23, 45, 48, 23, 54, 22, 24 },
7813 	},
7814 
7815 	{
7816 		.name = "Esmart2",
7817 		.phys_id = ROCKCHIP_VOP2_ESMART2,
7818 		.splice_win_id = ROCKCHIP_VOP2_ESMART3,
7819 		.type = ESMART_LAYER,
7820 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7821 		.win_sel_port_offset = 6,
7822 		.layer_sel_win_id = { 6, 6, 6, 6 },
7823 		.reg_offset = 0x400,
7824 		.axi_id = 1,
7825 		.axi_yrgb_id = 0x0a,
7826 		.axi_uv_id = 0x0b,
7827 		.pd_id = VOP2_PD_ESMART,
7828 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7829 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7830 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7831 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7832 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7833 		.max_upscale_factor = 8,
7834 		.max_downscale_factor = 8,
7835 		.dly = { 23, 45, 48, 23, 54, 22, 24 },
7836 	},
7837 
7838 	{
7839 		.name = "Esmart3",
7840 		.phys_id = ROCKCHIP_VOP2_ESMART3,
7841 		.type = ESMART_LAYER,
7842 		.plane_type = VOP2_PLANE_TYPE_PRIMARY,
7843 		.win_sel_port_offset = 7,
7844 		.layer_sel_win_id = { 7, 7, 7, 7 },
7845 		.reg_offset = 0x600,
7846 		.axi_id = 1,
7847 		.axi_yrgb_id = 0x0c,
7848 		.axi_uv_id = 0x0d,
7849 		.pd_id = VOP2_PD_ESMART,
7850 		.hsu_filter_mode = VOP2_SCALE_UP_BIC,
7851 		.hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7852 		.vsu_filter_mode = VOP2_SCALE_UP_BIL,
7853 		.vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
7854 		.possible_vp_mask = BIT(VOP2_VP0) | BIT(VOP2_VP1) | BIT(VOP2_VP2) | BIT(VOP2_VP3),
7855 		.max_upscale_factor = 8,
7856 		.max_downscale_factor = 8,
7857 		.dly = { 23, 45, 48, 23, 54, 22, 24 },
7858 	},
7859 };
7860 
7861 static struct dsc_error_info dsc_ecw[] = {
7862 	{0x00000000, "no error detected by DSC encoder"},
7863 	{0x0030ffff, "bits per component error"},
7864 	{0x0040ffff, "multiple mode error"},
7865 	{0x0050ffff, "line buffer depth error"},
7866 	{0x0060ffff, "minor version error"},
7867 	{0x0070ffff, "picture height error"},
7868 	{0x0080ffff, "picture width error"},
7869 	{0x0090ffff, "number of slices error"},
7870 	{0x00c0ffff, "slice height Error "},
7871 	{0x00d0ffff, "slice width error"},
7872 	{0x00e0ffff, "second line BPG offset error"},
7873 	{0x00f0ffff, "non second line BPG offset error"},
7874 	{0x0100ffff, "PPS ID error"},
7875 	{0x0110ffff, "bits per pixel (BPP) Error"},
7876 	{0x0120ffff, "buffer flow error"},  /* dsc_buffer_flow */
7877 
7878 	{0x01510001, "slice 0 RC buffer model overflow error"},
7879 	{0x01510002, "slice 1 RC buffer model overflow error"},
7880 	{0x01510004, "slice 2 RC buffer model overflow error"},
7881 	{0x01510008, "slice 3 RC buffer model overflow error"},
7882 	{0x01510010, "slice 4 RC buffer model overflow error"},
7883 	{0x01510020, "slice 5 RC buffer model overflow error"},
7884 	{0x01510040, "slice 6 RC buffer model overflow error"},
7885 	{0x01510080, "slice 7 RC buffer model overflow error"},
7886 
7887 	{0x01610001, "slice 0 RC buffer model underflow error"},
7888 	{0x01610002, "slice 1 RC buffer model underflow error"},
7889 	{0x01610004, "slice 2 RC buffer model underflow error"},
7890 	{0x01610008, "slice 3 RC buffer model underflow error"},
7891 	{0x01610010, "slice 4 RC buffer model underflow error"},
7892 	{0x01610020, "slice 5 RC buffer model underflow error"},
7893 	{0x01610040, "slice 6 RC buffer model underflow error"},
7894 	{0x01610080, "slice 7 RC buffer model underflow error"},
7895 
7896 	{0xffffffff, "unsuccessful RESET cycle status"},
7897 	{0x00a0ffff, "ICH full error precision settings error"},
7898 	{0x0020ffff, "native mode"},
7899 };
7900 
7901 static struct dsc_error_info dsc_buffer_flow[] = {
7902 	{0x00000000, "rate buffer status"},
7903 	{0x00000001, "line buffer status"},
7904 	{0x00000002, "decoder model status"},
7905 	{0x00000003, "pixel buffer status"},
7906 	{0x00000004, "balance fifo buffer status"},
7907 	{0x00000005, "syntax element fifo status"},
7908 };
7909 
7910 static struct vop2_dsc_data rk3588_dsc_data[] = {
7911 	{
7912 		.id = ROCKCHIP_VOP2_DSC_8K,
7913 		.pd_id = VOP2_PD_DSC_8K,
7914 		.max_slice_num = 8,
7915 		.max_linebuf_depth = 11,
7916 		.min_bits_per_pixel = 8,
7917 		.dsc_txp_clk_src_name = "dsc_8k_txp_clk_src",
7918 		.dsc_txp_clk_name = "dsc_8k_txp_clk",
7919 		.dsc_pxl_clk_name = "dsc_8k_pxl_clk",
7920 		.dsc_cds_clk_name = "dsc_8k_cds_clk",
7921 	},
7922 
7923 	{
7924 		.id = ROCKCHIP_VOP2_DSC_4K,
7925 		.pd_id = VOP2_PD_DSC_4K,
7926 		.max_slice_num = 2,
7927 		.max_linebuf_depth = 11,
7928 		.min_bits_per_pixel = 8,
7929 		.dsc_txp_clk_src_name = "dsc_4k_txp_clk_src",
7930 		.dsc_txp_clk_name = "dsc_4k_txp_clk",
7931 		.dsc_pxl_clk_name = "dsc_4k_pxl_clk",
7932 		.dsc_cds_clk_name = "dsc_4k_cds_clk",
7933 	},
7934 };
7935 
7936 static struct vop2_vp_data rk3588_vp_data[4] = {
7937 	{
7938 		.splice_vp_id = 1,
7939 		.feature = VOP_FEATURE_OUTPUT_10BIT,
7940 		.pre_scan_max_dly = 54,
7941 		.max_dclk = 600000,
7942 		.max_output = {7680, 4320},
7943 	},
7944 	{
7945 		.feature = VOP_FEATURE_OUTPUT_10BIT,
7946 		.pre_scan_max_dly = 54,
7947 		.max_dclk = 600000,
7948 		.max_output = {4096, 2304},
7949 	},
7950 	{
7951 		.feature = VOP_FEATURE_OUTPUT_10BIT,
7952 		.pre_scan_max_dly = 52,
7953 		.max_dclk = 600000,
7954 		.max_output = {4096, 2304},
7955 	},
7956 	{
7957 		.feature = 0,
7958 		.pre_scan_max_dly = 52,
7959 		.max_dclk = 200000,
7960 		.max_output = {1920, 1080},
7961 	},
7962 };
7963 
7964 static struct vop2_power_domain_data rk3588_vop_pd_data[] = {
7965 	{
7966 	  .id = VOP2_PD_CLUSTER0,
7967 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0),
7968 	},
7969 	{
7970 	  .id = VOP2_PD_CLUSTER1,
7971 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER1),
7972 	  .parent_id = VOP2_PD_CLUSTER0,
7973 	},
7974 	{
7975 	  .id = VOP2_PD_CLUSTER2,
7976 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER2),
7977 	  .parent_id = VOP2_PD_CLUSTER0,
7978 	},
7979 	{
7980 	  .id = VOP2_PD_CLUSTER3,
7981 	  .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER3),
7982 	  .parent_id = VOP2_PD_CLUSTER0,
7983 	},
7984 	{
7985 	  .id = VOP2_PD_ESMART,
7986 	  .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART1) |
7987 			    BIT(ROCKCHIP_VOP2_ESMART2) |
7988 			    BIT(ROCKCHIP_VOP2_ESMART3),
7989 	},
7990 	{
7991 	  .id = VOP2_PD_DSC_8K,
7992 	  .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_8K),
7993 	},
7994 	{
7995 	  .id = VOP2_PD_DSC_4K,
7996 	  .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_4K),
7997 	},
7998 };
7999 
8000 static const struct vop2_ops rk3588_vop_ops = {
8001 	.setup_win_dly = rk3568_setup_win_dly,
8002 	.setup_overlay = rk3568_setup_overlay,
8003 	.assign_plane_mask = rk3568_assign_plane_mask,
8004 };
8005 
8006 const struct vop2_data rk3588_vop = {
8007 	.version = VOP_VERSION_RK3588,
8008 	.nr_vps = 4,
8009 	.vp_data = rk3588_vp_data,
8010 	.win_data = rk3588_win_data,
8011 	.plane_mask = rk3588_vp_plane_mask[0],
8012 	.plane_mask_base = RK3588_PLANE_MASK_BASE,
8013 	.pd = rk3588_vop_pd_data,
8014 	.dsc = rk3588_dsc_data,
8015 	.dsc_error_ecw = dsc_ecw,
8016 	.dsc_error_buffer_flow = dsc_buffer_flow,
8017 	.nr_layers = 8,
8018 	.nr_mixers = 7,
8019 	.nr_gammas = 4,
8020 	.nr_pd = ARRAY_SIZE(rk3588_vop_pd_data),
8021 	.nr_dscs = 2,
8022 	.nr_dsc_ecw = ARRAY_SIZE(dsc_ecw),
8023 	.nr_dsc_buffer_flow = ARRAY_SIZE(dsc_buffer_flow),
8024 	.dump_regs = rk3588_dump_regs,
8025 	.dump_regs_size = ARRAY_SIZE(rk3588_dump_regs),
8026 	.ops = &rk3588_vop_ops,
8027 };
8028 
8029 const struct rockchip_crtc_funcs rockchip_vop2_funcs = {
8030 	.reset = rockchip_vop2_reset,
8031 	.preinit = rockchip_vop2_preinit,
8032 	.prepare = rockchip_vop2_prepare,
8033 	.init = rockchip_vop2_init,
8034 	.set_plane = rockchip_vop2_set_plane,
8035 	.enable = rockchip_vop2_enable,
8036 	.post_enable = rockchip_vop2_post_enable,
8037 	.disable = rockchip_vop2_disable,
8038 	.fixup_dts = rockchip_vop2_fixup_dts,
8039 	.send_mcu_cmd = rockchip_vop2_send_mcu_cmd,
8040 	.check = rockchip_vop2_check,
8041 	.mode_valid = rockchip_vop2_mode_valid,
8042 	.mode_fixup = rockchip_vop2_mode_fixup,
8043 	.plane_check = rockchip_vop2_plane_check,
8044 	.regs_dump = rockchip_vop2_regs_dump,
8045 	.active_regs_dump = rockchip_vop2_active_regs_dump,
8046 	.apply_soft_te = rockchip_vop2_apply_soft_te,
8047 };
8048