19c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2a67719d1SMark Yao /*
3a67719d1SMark Yao  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4a67719d1SMark Yao  * Author:Mark Yao <mark.yao@rock-chips.com>
5a67719d1SMark Yao  */
6a67719d1SMark Yao 
7a67719d1SMark Yao #include <linux/component.h>
8c2156ccdSSam Ravnborg #include <linux/mod_devicetable.h>
9c2156ccdSSam Ravnborg #include <linux/module.h>
10c2156ccdSSam Ravnborg #include <linux/of.h>
11c2156ccdSSam Ravnborg #include <linux/platform_device.h>
12c2156ccdSSam Ravnborg 
13c2156ccdSSam Ravnborg #include <drm/drm_fourcc.h>
14c2156ccdSSam Ravnborg #include <drm/drm_plane.h>
15c2156ccdSSam Ravnborg #include <drm/drm_print.h>
16a67719d1SMark Yao 
17a67719d1SMark Yao #include "rockchip_drm_vop.h"
18a67719d1SMark Yao #include "rockchip_vop_reg.h"
19b02516b6SBen Dooks #include "rockchip_drm_drv.h"
20a67719d1SMark Yao 
219548e1b4SMark yao #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
229548e1b4SMark yao 		{ \
239548e1b4SMark yao 		 .offset = off, \
24a67719d1SMark Yao 		 .mask = _mask, \
259548e1b4SMark yao 		 .shift = _shift, \
269548e1b4SMark yao 		 .write_mask = _write_mask, \
279548e1b4SMark yao 		 .relaxed = _relaxed, \
289548e1b4SMark yao 		}
29d49463ecSMark Yao 
309548e1b4SMark yao #define VOP_REG(off, _mask, _shift) \
319548e1b4SMark yao 		_VOP_REG(off, _mask, _shift, false, true)
329548e1b4SMark yao 
339548e1b4SMark yao #define VOP_REG_SYNC(off, _mask, _shift) \
349548e1b4SMark yao 		_VOP_REG(off, _mask, _shift, false, false)
359548e1b4SMark yao 
369548e1b4SMark yao #define VOP_REG_MASK_SYNC(off, _mask, _shift) \
379548e1b4SMark yao 		_VOP_REG(off, _mask, _shift, true, false)
38a67719d1SMark Yao 
39f7673453SMark Yao static const uint32_t formats_win_full[] = {
40a67719d1SMark Yao 	DRM_FORMAT_XRGB8888,
41a67719d1SMark Yao 	DRM_FORMAT_ARGB8888,
42a67719d1SMark Yao 	DRM_FORMAT_XBGR8888,
43a67719d1SMark Yao 	DRM_FORMAT_ABGR8888,
44a67719d1SMark Yao 	DRM_FORMAT_RGB888,
45a67719d1SMark Yao 	DRM_FORMAT_BGR888,
46a67719d1SMark Yao 	DRM_FORMAT_RGB565,
47a67719d1SMark Yao 	DRM_FORMAT_BGR565,
48a67719d1SMark Yao 	DRM_FORMAT_NV12,
49a67719d1SMark Yao 	DRM_FORMAT_NV16,
50a67719d1SMark Yao 	DRM_FORMAT_NV24,
51a67719d1SMark Yao };
52a67719d1SMark Yao 
537707f722SAndrzej Pietrasiewicz static const uint64_t format_modifiers_win_full[] = {
547707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_LINEAR,
557707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_INVALID,
567707f722SAndrzej Pietrasiewicz };
577707f722SAndrzej Pietrasiewicz 
587707f722SAndrzej Pietrasiewicz static const uint64_t format_modifiers_win_full_afbc[] = {
597707f722SAndrzej Pietrasiewicz 	ROCKCHIP_AFBC_MOD,
607707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_LINEAR,
617707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_INVALID,
627707f722SAndrzej Pietrasiewicz };
637707f722SAndrzej Pietrasiewicz 
64f7673453SMark Yao static const uint32_t formats_win_lite[] = {
65a67719d1SMark Yao 	DRM_FORMAT_XRGB8888,
66a67719d1SMark Yao 	DRM_FORMAT_ARGB8888,
67a67719d1SMark Yao 	DRM_FORMAT_XBGR8888,
68a67719d1SMark Yao 	DRM_FORMAT_ABGR8888,
69a67719d1SMark Yao 	DRM_FORMAT_RGB888,
70a67719d1SMark Yao 	DRM_FORMAT_BGR888,
71a67719d1SMark Yao 	DRM_FORMAT_RGB565,
72a67719d1SMark Yao 	DRM_FORMAT_BGR565,
73a67719d1SMark Yao };
74a67719d1SMark Yao 
757707f722SAndrzej Pietrasiewicz static const uint64_t format_modifiers_win_lite[] = {
767707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_LINEAR,
777707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_INVALID,
787707f722SAndrzej Pietrasiewicz };
797707f722SAndrzej Pietrasiewicz 
8053c2710cSAlex Bee static const struct vop_scl_regs rk3036_win0_scl = {
81b51502adSMark Yao 	.scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
82b51502adSMark Yao 	.scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
83b51502adSMark Yao 	.scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
84b51502adSMark Yao 	.scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
85b51502adSMark Yao };
86b51502adSMark Yao 
8753c2710cSAlex Bee static const struct vop_scl_regs rk3036_win1_scl = {
8853c2710cSAlex Bee 	.scale_yrgb_x = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 0x0),
8953c2710cSAlex Bee 	.scale_yrgb_y = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 16),
9053c2710cSAlex Bee };
9153c2710cSAlex Bee 
92b51502adSMark Yao static const struct vop_win_phy rk3036_win0_data = {
9353c2710cSAlex Bee 	.scl = &rk3036_win0_scl,
94b51502adSMark Yao 	.data_formats = formats_win_full,
95b51502adSMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
967707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
97b51502adSMark Yao 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
98b51502adSMark Yao 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
99b51502adSMark Yao 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
100b51502adSMark Yao 	.act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
101b51502adSMark Yao 	.dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
102b51502adSMark Yao 	.dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
103b51502adSMark Yao 	.yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
104b51502adSMark Yao 	.uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
105b51502adSMark Yao 	.yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
106b51502adSMark Yao 	.uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
107b51502adSMark Yao };
108b51502adSMark Yao 
109b51502adSMark Yao static const struct vop_win_phy rk3036_win1_data = {
11053c2710cSAlex Bee 	.scl = &rk3036_win1_scl,
111b51502adSMark Yao 	.data_formats = formats_win_lite,
112b51502adSMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
1137707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
114b51502adSMark Yao 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
115b51502adSMark Yao 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
116b51502adSMark Yao 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
117b51502adSMark Yao 	.act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
118b51502adSMark Yao 	.dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
119b51502adSMark Yao 	.dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
120b51502adSMark Yao 	.yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
121b51502adSMark Yao 	.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
122b51502adSMark Yao };
123b51502adSMark Yao 
124b51502adSMark Yao static const struct vop_win_data rk3036_vop_win_data[] = {
125b51502adSMark Yao 	{ .base = 0x00, .phy = &rk3036_win0_data,
126b51502adSMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
127b51502adSMark Yao 	{ .base = 0x00, .phy = &rk3036_win1_data,
128b51502adSMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
129b51502adSMark Yao };
130b51502adSMark Yao 
131b51502adSMark Yao static const int rk3036_vop_intrs[] = {
132b51502adSMark Yao 	DSP_HOLD_VALID_INTR,
133b51502adSMark Yao 	FS_INTR,
134b51502adSMark Yao 	LINE_FLAG_INTR,
135b51502adSMark Yao 	BUS_ERROR_INTR,
136b51502adSMark Yao };
137b51502adSMark Yao 
138b51502adSMark Yao static const struct vop_intr rk3036_intr = {
139b51502adSMark Yao 	.intrs = rk3036_vop_intrs,
140b51502adSMark Yao 	.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
141ac6560dfSMark yao 	.line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
1429a61c54bSMark yao 	.status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
1439a61c54bSMark yao 	.enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
1449a61c54bSMark yao 	.clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
145b51502adSMark Yao };
146b51502adSMark Yao 
1479a61c54bSMark yao static const struct vop_modeset rk3036_modeset = {
148b51502adSMark Yao 	.htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
149b51502adSMark Yao 	.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
150b51502adSMark Yao 	.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
151b51502adSMark Yao 	.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
1529a61c54bSMark yao };
1539a61c54bSMark yao 
1549a61c54bSMark yao static const struct vop_output rk3036_output = {
1559a61c54bSMark yao 	.pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
1569a61c54bSMark yao };
1579a61c54bSMark yao 
1589a61c54bSMark yao static const struct vop_common rk3036_common = {
1599a61c54bSMark yao 	.standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
1609a61c54bSMark yao 	.out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
1619a61c54bSMark yao 	.dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
162a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
163a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
164a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
1659548e1b4SMark yao 	.cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
166b51502adSMark Yao };
167b51502adSMark Yao 
168b51502adSMark Yao static const struct vop_data rk3036_vop = {
169b51502adSMark Yao 	.intr = &rk3036_intr,
1709a61c54bSMark yao 	.common = &rk3036_common,
1719a61c54bSMark yao 	.modeset = &rk3036_modeset,
1729a61c54bSMark yao 	.output = &rk3036_output,
173b51502adSMark Yao 	.win = rk3036_vop_win_data,
174b51502adSMark Yao 	.win_size = ARRAY_SIZE(rk3036_vop_win_data),
175b51502adSMark Yao };
176b51502adSMark Yao 
177460c3b00SSandy Huang static const struct vop_win_phy rk3126_win1_data = {
178460c3b00SSandy Huang 	.data_formats = formats_win_lite,
179460c3b00SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
1807707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
181460c3b00SSandy Huang 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
182460c3b00SSandy Huang 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
183460c3b00SSandy Huang 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
184460c3b00SSandy Huang 	.dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
185460c3b00SSandy Huang 	.dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
186460c3b00SSandy Huang 	.yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
187460c3b00SSandy Huang 	.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
188460c3b00SSandy Huang };
189460c3b00SSandy Huang 
190460c3b00SSandy Huang static const struct vop_win_data rk3126_vop_win_data[] = {
191460c3b00SSandy Huang 	{ .base = 0x00, .phy = &rk3036_win0_data,
192460c3b00SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
193460c3b00SSandy Huang 	{ .base = 0x00, .phy = &rk3126_win1_data,
194460c3b00SSandy Huang 	  .type = DRM_PLANE_TYPE_CURSOR },
195460c3b00SSandy Huang };
196460c3b00SSandy Huang 
197460c3b00SSandy Huang static const struct vop_data rk3126_vop = {
198460c3b00SSandy Huang 	.intr = &rk3036_intr,
199460c3b00SSandy Huang 	.common = &rk3036_common,
200460c3b00SSandy Huang 	.modeset = &rk3036_modeset,
201460c3b00SSandy Huang 	.output = &rk3036_output,
202460c3b00SSandy Huang 	.win = rk3126_vop_win_data,
203460c3b00SSandy Huang 	.win_size = ARRAY_SIZE(rk3126_vop_win_data),
204460c3b00SSandy Huang };
205460c3b00SSandy Huang 
206570913e0SSandy Huang static const int px30_vop_intrs[] = {
207570913e0SSandy Huang 	FS_INTR,
208570913e0SSandy Huang 	0, 0,
209570913e0SSandy Huang 	LINE_FLAG_INTR,
210570913e0SSandy Huang 	0,
211570913e0SSandy Huang 	BUS_ERROR_INTR,
212570913e0SSandy Huang 	0, 0,
213570913e0SSandy Huang 	DSP_HOLD_VALID_INTR,
214570913e0SSandy Huang };
215570913e0SSandy Huang 
216570913e0SSandy Huang static const struct vop_intr px30_intr = {
217570913e0SSandy Huang 	.intrs = px30_vop_intrs,
218570913e0SSandy Huang 	.nintrs = ARRAY_SIZE(px30_vop_intrs),
219a6edf839SSandy Huang 	.line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
220a6edf839SSandy Huang 	.status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
221a6edf839SSandy Huang 	.enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
222a6edf839SSandy Huang 	.clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
223570913e0SSandy Huang };
224570913e0SSandy Huang 
225570913e0SSandy Huang static const struct vop_common px30_common = {
226570913e0SSandy Huang 	.standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
227570913e0SSandy Huang 	.out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
228570913e0SSandy Huang 	.dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
229a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
230a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
231a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
232570913e0SSandy Huang 	.cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
233570913e0SSandy Huang };
234570913e0SSandy Huang 
235570913e0SSandy Huang static const struct vop_modeset px30_modeset = {
236570913e0SSandy Huang 	.htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
237570913e0SSandy Huang 	.hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
238570913e0SSandy Huang 	.vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
239570913e0SSandy Huang 	.vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
240570913e0SSandy Huang };
241570913e0SSandy Huang 
242570913e0SSandy Huang static const struct vop_output px30_output = {
2431f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1),
2441f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2),
245570913e0SSandy Huang 	.rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
2461f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25),
2471f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26),
248570913e0SSandy Huang 	.mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
249570913e0SSandy Huang };
250570913e0SSandy Huang 
251570913e0SSandy Huang static const struct vop_scl_regs px30_win_scl = {
252570913e0SSandy Huang 	.scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
253570913e0SSandy Huang 	.scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
254570913e0SSandy Huang 	.scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
255570913e0SSandy Huang 	.scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
256570913e0SSandy Huang };
257570913e0SSandy Huang 
258570913e0SSandy Huang static const struct vop_win_phy px30_win0_data = {
259570913e0SSandy Huang 	.scl = &px30_win_scl,
260570913e0SSandy Huang 	.data_formats = formats_win_full,
261570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_full),
2627707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
263570913e0SSandy Huang 	.enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
264570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
265570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
266570913e0SSandy Huang 	.act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
267570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
268570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
269570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
270570913e0SSandy Huang 	.uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
271570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
272570913e0SSandy Huang 	.uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
2732aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2),
2742aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1),
2752aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0),
276570913e0SSandy Huang };
277570913e0SSandy Huang 
278570913e0SSandy Huang static const struct vop_win_phy px30_win1_data = {
279570913e0SSandy Huang 	.data_formats = formats_win_lite,
280570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
2817707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
282570913e0SSandy Huang 	.enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
283570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
284570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
285570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
286570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
287570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
288570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
2892aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2),
2902aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1),
2912aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0),
292570913e0SSandy Huang };
293570913e0SSandy Huang 
294570913e0SSandy Huang static const struct vop_win_phy px30_win2_data = {
295570913e0SSandy Huang 	.data_formats = formats_win_lite,
296570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
2977707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
298a6edf839SSandy Huang 	.gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
299a6edf839SSandy Huang 	.enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
300570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
301570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
302570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
303570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
304570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
305570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
3062aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2),
3072aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1),
3082aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0),
309570913e0SSandy Huang };
310570913e0SSandy Huang 
311570913e0SSandy Huang static const struct vop_win_data px30_vop_big_win_data[] = {
312570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win0_data,
313570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
314570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win1_data,
315570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_OVERLAY },
316570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win2_data,
317570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_CURSOR },
318570913e0SSandy Huang };
319570913e0SSandy Huang 
320570913e0SSandy Huang static const struct vop_data px30_vop_big = {
321570913e0SSandy Huang 	.intr = &px30_intr,
3228d544233SSandy Huang 	.feature = VOP_FEATURE_INTERNAL_RGB,
323570913e0SSandy Huang 	.common = &px30_common,
324570913e0SSandy Huang 	.modeset = &px30_modeset,
325570913e0SSandy Huang 	.output = &px30_output,
326570913e0SSandy Huang 	.win = px30_vop_big_win_data,
327570913e0SSandy Huang 	.win_size = ARRAY_SIZE(px30_vop_big_win_data),
328570913e0SSandy Huang };
329570913e0SSandy Huang 
330570913e0SSandy Huang static const struct vop_win_data px30_vop_lit_win_data[] = {
331570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win1_data,
332570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
333570913e0SSandy Huang };
334570913e0SSandy Huang 
335570913e0SSandy Huang static const struct vop_data px30_vop_lit = {
336570913e0SSandy Huang 	.intr = &px30_intr,
3378d544233SSandy Huang 	.feature = VOP_FEATURE_INTERNAL_RGB,
338570913e0SSandy Huang 	.common = &px30_common,
339570913e0SSandy Huang 	.modeset = &px30_modeset,
340570913e0SSandy Huang 	.output = &px30_output,
341570913e0SSandy Huang 	.win = px30_vop_lit_win_data,
342570913e0SSandy Huang 	.win_size = ARRAY_SIZE(px30_vop_lit_win_data),
343570913e0SSandy Huang };
344570913e0SSandy Huang 
345f4a6de85SMark Yao static const struct vop_scl_regs rk3066_win_scl = {
346f4a6de85SMark Yao 	.scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
347f4a6de85SMark Yao 	.scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
348f4a6de85SMark Yao 	.scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
349f4a6de85SMark Yao 	.scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
350f4a6de85SMark Yao };
351f4a6de85SMark Yao 
352f4a6de85SMark Yao static const struct vop_win_phy rk3066_win0_data = {
353f4a6de85SMark Yao 	.scl = &rk3066_win_scl,
354f4a6de85SMark Yao 	.data_formats = formats_win_full,
355f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
3567707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
357f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
358f4a6de85SMark Yao 	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4),
359f4a6de85SMark Yao 	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19),
360f4a6de85SMark Yao 	.act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
361f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
362f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
363f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
364f4a6de85SMark Yao 	.uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
365f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
366f4a6de85SMark Yao 	.uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
367f4a6de85SMark Yao };
368f4a6de85SMark Yao 
369f4a6de85SMark Yao static const struct vop_win_phy rk3066_win1_data = {
370f4a6de85SMark Yao 	.scl = &rk3066_win_scl,
371f4a6de85SMark Yao 	.data_formats = formats_win_full,
372f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
3737707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
374f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
375f4a6de85SMark Yao 	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7),
376f4a6de85SMark Yao 	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23),
377f4a6de85SMark Yao 	.act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
378f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
379f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
380f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
381f4a6de85SMark Yao 	.uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
382f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
383f4a6de85SMark Yao 	.uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
384f4a6de85SMark Yao };
385f4a6de85SMark Yao 
386f4a6de85SMark Yao static const struct vop_win_phy rk3066_win2_data = {
387f4a6de85SMark Yao 	.data_formats = formats_win_lite,
388f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
3897707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
390f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
391f4a6de85SMark Yao 	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10),
392f4a6de85SMark Yao 	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27),
393f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
394f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
395f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
396f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
397f4a6de85SMark Yao };
398f4a6de85SMark Yao 
399f4a6de85SMark Yao static const struct vop_modeset rk3066_modeset = {
400f4a6de85SMark Yao 	.htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
401f4a6de85SMark Yao 	.hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
402f4a6de85SMark Yao 	.vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
403f4a6de85SMark Yao 	.vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
404f4a6de85SMark Yao };
405f4a6de85SMark Yao 
406f4a6de85SMark Yao static const struct vop_output rk3066_output = {
407f4a6de85SMark Yao 	.pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
408f4a6de85SMark Yao };
409f4a6de85SMark Yao 
410f4a6de85SMark Yao static const struct vop_common rk3066_common = {
411f4a6de85SMark Yao 	.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
412f4a6de85SMark Yao 	.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
413f4a6de85SMark Yao 	.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
414a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
415a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
416f4a6de85SMark Yao 	.dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
417f4a6de85SMark Yao };
418f4a6de85SMark Yao 
419f4a6de85SMark Yao static const struct vop_win_data rk3066_vop_win_data[] = {
420f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win0_data,
421f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
422f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win1_data,
423f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
424f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win2_data,
425f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
426f4a6de85SMark Yao };
427f4a6de85SMark Yao 
428f4a6de85SMark Yao static const int rk3066_vop_intrs[] = {
429f4a6de85SMark Yao 	/*
430f4a6de85SMark Yao 	 * hs_start interrupt fires at frame-start, so serves
431f4a6de85SMark Yao 	 * the same purpose as dsp_hold in the driver.
432f4a6de85SMark Yao 	 */
433f4a6de85SMark Yao 	DSP_HOLD_VALID_INTR,
434f4a6de85SMark Yao 	FS_INTR,
435f4a6de85SMark Yao 	LINE_FLAG_INTR,
436f4a6de85SMark Yao 	BUS_ERROR_INTR,
437f4a6de85SMark Yao };
438f4a6de85SMark Yao 
439f4a6de85SMark Yao static const struct vop_intr rk3066_intr = {
440f4a6de85SMark Yao 	.intrs = rk3066_vop_intrs,
441f4a6de85SMark Yao 	.nintrs = ARRAY_SIZE(rk3066_vop_intrs),
442f4a6de85SMark Yao 	.line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
443f4a6de85SMark Yao 	.status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
444f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
445f4a6de85SMark Yao 	.clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
446f4a6de85SMark Yao };
447f4a6de85SMark Yao 
448f4a6de85SMark Yao static const struct vop_data rk3066_vop = {
449f4a6de85SMark Yao 	.version = VOP_VERSION(2, 1),
450f4a6de85SMark Yao 	.intr = &rk3066_intr,
451f4a6de85SMark Yao 	.common = &rk3066_common,
452f4a6de85SMark Yao 	.modeset = &rk3066_modeset,
453f4a6de85SMark Yao 	.output = &rk3066_output,
454f4a6de85SMark Yao 	.win = rk3066_vop_win_data,
455f4a6de85SMark Yao 	.win_size = ARRAY_SIZE(rk3066_vop_win_data),
456f4a6de85SMark Yao };
457f4a6de85SMark Yao 
458428e15ccSHeiko Stuebner static const struct vop_scl_regs rk3188_win_scl = {
459428e15ccSHeiko Stuebner 	.scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
460428e15ccSHeiko Stuebner 	.scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
461428e15ccSHeiko Stuebner 	.scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
462428e15ccSHeiko Stuebner 	.scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
463428e15ccSHeiko Stuebner };
464428e15ccSHeiko Stuebner 
465428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win0_data = {
466428e15ccSHeiko Stuebner 	.scl = &rk3188_win_scl,
467428e15ccSHeiko Stuebner 	.data_formats = formats_win_full,
468428e15ccSHeiko Stuebner 	.nformats = ARRAY_SIZE(formats_win_full),
4697707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
470428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
471428e15ccSHeiko Stuebner 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
472428e15ccSHeiko Stuebner 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
473428e15ccSHeiko Stuebner 	.act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
474428e15ccSHeiko Stuebner 	.dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
475428e15ccSHeiko Stuebner 	.dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
476428e15ccSHeiko Stuebner 	.yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
477428e15ccSHeiko Stuebner 	.uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
478428e15ccSHeiko Stuebner 	.yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
479428e15ccSHeiko Stuebner };
480428e15ccSHeiko Stuebner 
481428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win1_data = {
482428e15ccSHeiko Stuebner 	.data_formats = formats_win_lite,
483428e15ccSHeiko Stuebner 	.nformats = ARRAY_SIZE(formats_win_lite),
4847707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
485428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
486428e15ccSHeiko Stuebner 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
487428e15ccSHeiko Stuebner 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
488428e15ccSHeiko Stuebner 	/* no act_info on window1 */
489428e15ccSHeiko Stuebner 	.dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
490428e15ccSHeiko Stuebner 	.dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
491428e15ccSHeiko Stuebner 	.yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
492428e15ccSHeiko Stuebner 	.yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
493428e15ccSHeiko Stuebner };
494428e15ccSHeiko Stuebner 
495428e15ccSHeiko Stuebner static const struct vop_modeset rk3188_modeset = {
496428e15ccSHeiko Stuebner 	.htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
497428e15ccSHeiko Stuebner 	.hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
498428e15ccSHeiko Stuebner 	.vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
499428e15ccSHeiko Stuebner 	.vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
500428e15ccSHeiko Stuebner };
501428e15ccSHeiko Stuebner 
502428e15ccSHeiko Stuebner static const struct vop_output rk3188_output = {
503428e15ccSHeiko Stuebner 	.pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
504428e15ccSHeiko Stuebner };
505428e15ccSHeiko Stuebner 
506428e15ccSHeiko Stuebner static const struct vop_common rk3188_common = {
507428e15ccSHeiko Stuebner 	.gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
508428e15ccSHeiko Stuebner 	.standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
509428e15ccSHeiko Stuebner 	.out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
510428e15ccSHeiko Stuebner 	.cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
511a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
512a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
513a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
514*ab64b448SAlex Bee 	.dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24),
515*ab64b448SAlex Bee 	.dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9),
516*ab64b448SAlex Bee 	.dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28),
517*ab64b448SAlex Bee 	.data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25),
518428e15ccSHeiko Stuebner };
519428e15ccSHeiko Stuebner 
520428e15ccSHeiko Stuebner static const struct vop_win_data rk3188_vop_win_data[] = {
521428e15ccSHeiko Stuebner 	{ .base = 0x00, .phy = &rk3188_win0_data,
522428e15ccSHeiko Stuebner 	  .type = DRM_PLANE_TYPE_PRIMARY },
523428e15ccSHeiko Stuebner 	{ .base = 0x00, .phy = &rk3188_win1_data,
524428e15ccSHeiko Stuebner 	  .type = DRM_PLANE_TYPE_CURSOR },
525428e15ccSHeiko Stuebner };
526428e15ccSHeiko Stuebner 
527428e15ccSHeiko Stuebner static const int rk3188_vop_intrs[] = {
5284f297df8SHeiko Stuebner 	/*
5294f297df8SHeiko Stuebner 	 * hs_start interrupt fires at frame-start, so serves
5304f297df8SHeiko Stuebner 	 * the same purpose as dsp_hold in the driver.
5314f297df8SHeiko Stuebner 	 */
5324f297df8SHeiko Stuebner 	DSP_HOLD_VALID_INTR,
533428e15ccSHeiko Stuebner 	FS_INTR,
534428e15ccSHeiko Stuebner 	LINE_FLAG_INTR,
535428e15ccSHeiko Stuebner 	BUS_ERROR_INTR,
536428e15ccSHeiko Stuebner };
537428e15ccSHeiko Stuebner 
538428e15ccSHeiko Stuebner static const struct vop_intr rk3188_vop_intr = {
539428e15ccSHeiko Stuebner 	.intrs = rk3188_vop_intrs,
540428e15ccSHeiko Stuebner 	.nintrs = ARRAY_SIZE(rk3188_vop_intrs),
541428e15ccSHeiko Stuebner 	.line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
542428e15ccSHeiko Stuebner 	.status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
543428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
544428e15ccSHeiko Stuebner 	.clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
545428e15ccSHeiko Stuebner };
546428e15ccSHeiko Stuebner 
547428e15ccSHeiko Stuebner static const struct vop_data rk3188_vop = {
548428e15ccSHeiko Stuebner 	.intr = &rk3188_vop_intr,
549428e15ccSHeiko Stuebner 	.common = &rk3188_common,
550428e15ccSHeiko Stuebner 	.modeset = &rk3188_modeset,
551428e15ccSHeiko Stuebner 	.output = &rk3188_output,
552428e15ccSHeiko Stuebner 	.win = rk3188_vop_win_data,
553428e15ccSHeiko Stuebner 	.win_size = ARRAY_SIZE(rk3188_vop_win_data),
554428e15ccSHeiko Stuebner 	.feature = VOP_FEATURE_INTERNAL_RGB,
555428e15ccSHeiko Stuebner };
556428e15ccSHeiko Stuebner 
557f7673453SMark Yao static const struct vop_scl_extension rk3288_win_full_scl_ext = {
558f7673453SMark Yao 	.cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
559f7673453SMark Yao 	.cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
560f7673453SMark Yao 	.cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
561f7673453SMark Yao 	.cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
562f7673453SMark Yao 	.cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
563f7673453SMark Yao 	.yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
564f7673453SMark Yao 	.yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
565f7673453SMark Yao 	.yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
566f7673453SMark Yao 	.yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
567f7673453SMark Yao 	.yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
568f7673453SMark Yao 	.line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
569f7673453SMark Yao 	.cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
570f7673453SMark Yao 	.yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
571f7673453SMark Yao 	.vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
572f7673453SMark Yao 	.vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
573f7673453SMark Yao 	.vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
574f7673453SMark Yao 	.vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
575f7673453SMark Yao 	.bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
576f7673453SMark Yao 	.cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
577f7673453SMark Yao 	.yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
578f7673453SMark Yao 	.lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
5791194fffbSMark Yao };
5801194fffbSMark Yao 
581f7673453SMark Yao static const struct vop_scl_regs rk3288_win_full_scl = {
582f7673453SMark Yao 	.ext = &rk3288_win_full_scl_ext,
583f7673453SMark Yao 	.scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
584f7673453SMark Yao 	.scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
585f7673453SMark Yao 	.scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
586f7673453SMark Yao 	.scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
587a67719d1SMark Yao };
588a67719d1SMark Yao 
589f7673453SMark Yao static const struct vop_win_phy rk3288_win01_data = {
590f7673453SMark Yao 	.scl = &rk3288_win_full_scl,
591f7673453SMark Yao 	.data_formats = formats_win_full,
592f7673453SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
5937707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
594f7673453SMark Yao 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
595f7673453SMark Yao 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
596f7673453SMark Yao 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
597f7673453SMark Yao 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
598f7673453SMark Yao 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
599f7673453SMark Yao 	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
600f7673453SMark Yao 	.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
601f7673453SMark Yao 	.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
602f7673453SMark Yao 	.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
603f7673453SMark Yao 	.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
604f7673453SMark Yao 	.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
605f7673453SMark Yao 	.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
6069dd2aca4SMark yao 	.channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
607a67719d1SMark Yao };
608a67719d1SMark Yao 
609f7673453SMark Yao static const struct vop_win_phy rk3288_win23_data = {
610f7673453SMark Yao 	.data_formats = formats_win_lite,
611f7673453SMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
6127707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
61360b7ae7fSMark yao 	.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
61460b7ae7fSMark yao 	.gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
615f7673453SMark Yao 	.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
616f7673453SMark Yao 	.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
617f7673453SMark Yao 	.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
618f7673453SMark Yao 	.dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
619f7673453SMark Yao 	.yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
620f7673453SMark Yao 	.yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
621f7673453SMark Yao 	.src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
622f7673453SMark Yao 	.dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
623a67719d1SMark Yao };
624a67719d1SMark Yao 
6259a61c54bSMark yao static const struct vop_modeset rk3288_modeset = {
626f7673453SMark Yao 	.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
627f7673453SMark Yao 	.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
628f7673453SMark Yao 	.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
629f7673453SMark Yao 	.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
630f7673453SMark Yao 	.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
631f7673453SMark Yao 	.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
6329a61c54bSMark yao };
6339a61c54bSMark yao 
6349a61c54bSMark yao static const struct vop_output rk3288_output = {
6359a61c54bSMark yao 	.pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
6369a61c54bSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
6379a61c54bSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
6389a61c54bSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
6399a61c54bSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
6409a61c54bSMark yao };
6419a61c54bSMark yao 
6429a61c54bSMark yao static const struct vop_common rk3288_common = {
6439a61c54bSMark yao 	.standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
6449a61c54bSMark yao 	.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
6459a61c54bSMark yao 	.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
646a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
647a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
648a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
6496bda8112SMark Yao 	.pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
6509a61c54bSMark yao 	.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
651b23ab6acSEzequiel Garcia 	.dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0),
6529a61c54bSMark yao 	.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
6539a61c54bSMark yao 	.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
6549a61c54bSMark yao 	.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
6559548e1b4SMark yao 	.cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
656a67719d1SMark Yao };
657a67719d1SMark Yao 
658a67719d1SMark Yao /*
659a67719d1SMark Yao  * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
660a67719d1SMark Yao  * special support to get alpha blending working.  For now, just use overlay
661a67719d1SMark Yao  * window 3 for the drm cursor.
662a67719d1SMark Yao  *
663a67719d1SMark Yao  */
664a67719d1SMark Yao static const struct vop_win_data rk3288_vop_win_data[] = {
665f7673453SMark Yao 	{ .base = 0x00, .phy = &rk3288_win01_data,
666f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
667f7673453SMark Yao 	{ .base = 0x40, .phy = &rk3288_win01_data,
668f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
669f7673453SMark Yao 	{ .base = 0x00, .phy = &rk3288_win23_data,
670f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
671f7673453SMark Yao 	{ .base = 0x50, .phy = &rk3288_win23_data,
672f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
673a67719d1SMark Yao };
674a67719d1SMark Yao 
675a67719d1SMark Yao static const int rk3288_vop_intrs[] = {
676a67719d1SMark Yao 	DSP_HOLD_VALID_INTR,
677a67719d1SMark Yao 	FS_INTR,
678a67719d1SMark Yao 	LINE_FLAG_INTR,
679a67719d1SMark Yao 	BUS_ERROR_INTR,
680a67719d1SMark Yao };
681a67719d1SMark Yao 
682a67719d1SMark Yao static const struct vop_intr rk3288_vop_intr = {
683a67719d1SMark Yao 	.intrs = rk3288_vop_intrs,
684a67719d1SMark Yao 	.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
685ac6560dfSMark yao 	.line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
686f7673453SMark Yao 	.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
687f7673453SMark Yao 	.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
688f7673453SMark Yao 	.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
689a67719d1SMark Yao };
690a67719d1SMark Yao 
691a67719d1SMark Yao static const struct vop_data rk3288_vop = {
692eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 1),
693efd11cc8SMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
694a67719d1SMark Yao 	.intr = &rk3288_vop_intr,
6959a61c54bSMark yao 	.common = &rk3288_common,
6969a61c54bSMark yao 	.modeset = &rk3288_modeset,
6979a61c54bSMark yao 	.output = &rk3288_output,
698a67719d1SMark Yao 	.win = rk3288_vop_win_data,
699a67719d1SMark Yao 	.win_size = ARRAY_SIZE(rk3288_vop_win_data),
700b23ab6acSEzequiel Garcia 	.lut_size = 1024,
701a67719d1SMark Yao };
702a67719d1SMark Yao 
703eb5cb6aaSMark yao static const int rk3368_vop_intrs[] = {
7040a63bfd0SMark Yao 	FS_INTR,
7050a63bfd0SMark Yao 	0, 0,
7060a63bfd0SMark Yao 	LINE_FLAG_INTR,
7070a63bfd0SMark Yao 	0,
7080a63bfd0SMark Yao 	BUS_ERROR_INTR,
7090a63bfd0SMark Yao 	0, 0, 0, 0, 0, 0, 0,
7100a63bfd0SMark Yao 	DSP_HOLD_VALID_INTR,
711f7673453SMark Yao };
712f7673453SMark Yao 
713eb5cb6aaSMark yao static const struct vop_intr rk3368_vop_intr = {
714eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
715eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
716eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
717eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
718eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
719eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
720eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
721eb5cb6aaSMark yao };
722eb5cb6aaSMark yao 
723fbb1c738SEzequiel Garcia static const struct vop_win_phy rk3368_win01_data = {
724fbb1c738SEzequiel Garcia 	.scl = &rk3288_win_full_scl,
725fbb1c738SEzequiel Garcia 	.data_formats = formats_win_full,
726fbb1c738SEzequiel Garcia 	.nformats = ARRAY_SIZE(formats_win_full),
7277707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
728fbb1c738SEzequiel Garcia 	.enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
729fbb1c738SEzequiel Garcia 	.format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
730fbb1c738SEzequiel Garcia 	.rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
731677e8bbcSDaniele Castagna 	.x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
732677e8bbcSDaniele Castagna 	.y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
733fbb1c738SEzequiel Garcia 	.act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
734fbb1c738SEzequiel Garcia 	.dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
735fbb1c738SEzequiel Garcia 	.dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
736fbb1c738SEzequiel Garcia 	.yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
737fbb1c738SEzequiel Garcia 	.uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
738fbb1c738SEzequiel Garcia 	.yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
739fbb1c738SEzequiel Garcia 	.uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
740fbb1c738SEzequiel Garcia 	.src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
741fbb1c738SEzequiel Garcia 	.dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
742fbb1c738SEzequiel Garcia 	.channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
743fbb1c738SEzequiel Garcia };
744fbb1c738SEzequiel Garcia 
745eb5cb6aaSMark yao static const struct vop_win_phy rk3368_win23_data = {
746eb5cb6aaSMark yao 	.data_formats = formats_win_lite,
747eb5cb6aaSMark yao 	.nformats = ARRAY_SIZE(formats_win_lite),
7487707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
749eb5cb6aaSMark yao 	.gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
750eb5cb6aaSMark yao 	.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
751eb5cb6aaSMark yao 	.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
752eb5cb6aaSMark yao 	.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
753677e8bbcSDaniele Castagna 	.y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
754eb5cb6aaSMark yao 	.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
755eb5cb6aaSMark yao 	.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
756eb5cb6aaSMark yao 	.yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
757eb5cb6aaSMark yao 	.yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
758eb5cb6aaSMark yao 	.src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
759eb5cb6aaSMark yao 	.dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
760eb5cb6aaSMark yao };
761eb5cb6aaSMark yao 
762eb5cb6aaSMark yao static const struct vop_win_data rk3368_vop_win_data[] = {
763fbb1c738SEzequiel Garcia 	{ .base = 0x00, .phy = &rk3368_win01_data,
764eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
765fbb1c738SEzequiel Garcia 	{ .base = 0x40, .phy = &rk3368_win01_data,
766eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
767eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3368_win23_data,
768eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
769eb5cb6aaSMark yao 	{ .base = 0x50, .phy = &rk3368_win23_data,
770eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
771eb5cb6aaSMark yao };
772eb5cb6aaSMark yao 
773eb5cb6aaSMark yao static const struct vop_output rk3368_output = {
7741f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
7751f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
7761f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
7771f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
7781f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
7791f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
7801f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
7811f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
782eb5cb6aaSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
783eb5cb6aaSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
784eb5cb6aaSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
785eb5cb6aaSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
786eb5cb6aaSMark yao };
787eb5cb6aaSMark yao 
788eb5cb6aaSMark yao static const struct vop_misc rk3368_misc = {
789eb5cb6aaSMark yao 	.global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
790eb5cb6aaSMark yao };
791eb5cb6aaSMark yao 
792eb5cb6aaSMark yao static const struct vop_data rk3368_vop = {
793eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 2),
794eb5cb6aaSMark yao 	.intr = &rk3368_vop_intr,
795eb5cb6aaSMark yao 	.common = &rk3288_common,
796eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
797eb5cb6aaSMark yao 	.output = &rk3368_output,
798eb5cb6aaSMark yao 	.misc = &rk3368_misc,
799eb5cb6aaSMark yao 	.win = rk3368_vop_win_data,
800eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3368_vop_win_data),
801eb5cb6aaSMark yao };
802eb5cb6aaSMark yao 
803eb5cb6aaSMark yao static const struct vop_intr rk3366_vop_intr = {
804eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
805eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
806eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
807eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
808eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
809eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
810eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
811eb5cb6aaSMark yao };
812eb5cb6aaSMark yao 
813eb5cb6aaSMark yao static const struct vop_data rk3366_vop = {
814eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 4),
815eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
816eb5cb6aaSMark yao 	.common = &rk3288_common,
817eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
818eb5cb6aaSMark yao 	.output = &rk3368_output,
819eb5cb6aaSMark yao 	.misc = &rk3368_misc,
820eb5cb6aaSMark yao 	.win = rk3368_vop_win_data,
821eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3368_vop_win_data),
822f7673453SMark Yao };
823f7673453SMark Yao 
8249a61c54bSMark yao static const struct vop_output rk3399_output = {
8251f6c62caSNickey Yang 	.dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19),
8261f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
8271f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
8281f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
8291f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
8301f6c62caSNickey Yang 	.dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16),
8311f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
8321f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
8331f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
8341f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
8359a61c54bSMark yao 	.dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
8369a61c54bSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
8379a61c54bSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
8389a61c54bSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
8399a61c54bSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
840cf6d100dSHeiko Stuebner 	.mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
8419a61c54bSMark yao };
8429a61c54bSMark yao 
8431c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
8441c21aa8fSDaniele Castagna 	.y2r_coefficients = {
8451c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
8461c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
8471c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
8481c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
8491c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
8501c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
8511c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
8521c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
8531c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
8541c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
8551c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
8561c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
8571c21aa8fSDaniele Castagna 	},
8581c21aa8fSDaniele Castagna };
8591c21aa8fSDaniele Castagna 
8601c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
8611c21aa8fSDaniele Castagna 
8621c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
8631c21aa8fSDaniele Castagna 	{ .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
8641c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
8651c21aa8fSDaniele Castagna 	{ .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
8661c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
8671c21aa8fSDaniele Castagna 	{ .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
8681c21aa8fSDaniele Castagna 	{ .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
8697707f722SAndrzej Pietrasiewicz 
8707707f722SAndrzej Pietrasiewicz };
8717707f722SAndrzej Pietrasiewicz 
8727707f722SAndrzej Pietrasiewicz static const struct vop_win_phy rk3399_win01_data = {
8737707f722SAndrzej Pietrasiewicz 	.scl = &rk3288_win_full_scl,
8747707f722SAndrzej Pietrasiewicz 	.data_formats = formats_win_full,
8757707f722SAndrzej Pietrasiewicz 	.nformats = ARRAY_SIZE(formats_win_full),
8767707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full_afbc,
8777707f722SAndrzej Pietrasiewicz 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
8787707f722SAndrzej Pietrasiewicz 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
8797707f722SAndrzej Pietrasiewicz 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
8807707f722SAndrzej Pietrasiewicz 	.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
8817707f722SAndrzej Pietrasiewicz 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
8827707f722SAndrzej Pietrasiewicz 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
8837707f722SAndrzej Pietrasiewicz 	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
8847707f722SAndrzej Pietrasiewicz 	.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
8857707f722SAndrzej Pietrasiewicz 	.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
8867707f722SAndrzej Pietrasiewicz 	.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
8877707f722SAndrzej Pietrasiewicz 	.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
8887707f722SAndrzej Pietrasiewicz 	.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
8897707f722SAndrzej Pietrasiewicz 	.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
8907707f722SAndrzej Pietrasiewicz };
8917707f722SAndrzej Pietrasiewicz 
8927707f722SAndrzej Pietrasiewicz /*
8937707f722SAndrzej Pietrasiewicz  * rk3399 vop big windows register layout is same as rk3288, but we
8947707f722SAndrzej Pietrasiewicz  * have a separate rk3399 win data array here so that we can advertise
8957707f722SAndrzej Pietrasiewicz  * AFBC on the primary plane.
8967707f722SAndrzej Pietrasiewicz  */
8977707f722SAndrzej Pietrasiewicz static const struct vop_win_data rk3399_vop_win_data[] = {
8987707f722SAndrzej Pietrasiewicz 	{ .base = 0x00, .phy = &rk3399_win01_data,
8997707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_PRIMARY },
9007707f722SAndrzej Pietrasiewicz 	{ .base = 0x40, .phy = &rk3288_win01_data,
9017707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_OVERLAY },
9027707f722SAndrzej Pietrasiewicz 	{ .base = 0x00, .phy = &rk3288_win23_data,
9037707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_OVERLAY },
9047707f722SAndrzej Pietrasiewicz 	{ .base = 0x50, .phy = &rk3288_win23_data,
9057707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_CURSOR },
9067707f722SAndrzej Pietrasiewicz };
9077707f722SAndrzej Pietrasiewicz 
9087707f722SAndrzej Pietrasiewicz static const struct vop_afbc rk3399_vop_afbc = {
9097707f722SAndrzej Pietrasiewicz 	.rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
9107707f722SAndrzej Pietrasiewicz 	.enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
9117707f722SAndrzej Pietrasiewicz 	.win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
9127707f722SAndrzej Pietrasiewicz 	.format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
9137707f722SAndrzej Pietrasiewicz 	.hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
9147707f722SAndrzej Pietrasiewicz 	.hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
9157707f722SAndrzej Pietrasiewicz 	.pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
9161c21aa8fSDaniele Castagna };
9171c21aa8fSDaniele Castagna 
9180a63bfd0SMark Yao static const struct vop_data rk3399_vop_big = {
919eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 5),
920efd11cc8SMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
921eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
9229a61c54bSMark yao 	.common = &rk3288_common,
9239a61c54bSMark yao 	.modeset = &rk3288_modeset,
9249a61c54bSMark yao 	.output = &rk3399_output,
9257707f722SAndrzej Pietrasiewicz 	.afbc = &rk3399_vop_afbc,
926eb5cb6aaSMark yao 	.misc = &rk3368_misc,
9277707f722SAndrzej Pietrasiewicz 	.win = rk3399_vop_win_data,
9287707f722SAndrzej Pietrasiewicz 	.win_size = ARRAY_SIZE(rk3399_vop_win_data),
9291c21aa8fSDaniele Castagna 	.win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
9300a63bfd0SMark Yao };
9310a63bfd0SMark Yao 
9320a63bfd0SMark Yao static const struct vop_win_data rk3399_vop_lit_win_data[] = {
933fbb1c738SEzequiel Garcia 	{ .base = 0x00, .phy = &rk3368_win01_data,
934f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
935eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3368_win23_data,
936f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR},
937f7673453SMark Yao };
938f7673453SMark Yao 
9391c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
9401c21aa8fSDaniele Castagna 	{ .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
9411c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
9421c21aa8fSDaniele Castagna 	{ .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
9431c21aa8fSDaniele Castagna };
9441c21aa8fSDaniele Castagna 
9450a63bfd0SMark Yao static const struct vop_data rk3399_vop_lit = {
946eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 6),
947eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
9489a61c54bSMark yao 	.common = &rk3288_common,
9499a61c54bSMark yao 	.modeset = &rk3288_modeset,
9509a61c54bSMark yao 	.output = &rk3399_output,
951eb5cb6aaSMark yao 	.misc = &rk3368_misc,
9520a63bfd0SMark Yao 	.win = rk3399_vop_lit_win_data,
9530a63bfd0SMark Yao 	.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
9541c21aa8fSDaniele Castagna 	.win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
955f7673453SMark Yao };
956f7673453SMark Yao 
957eb5cb6aaSMark yao static const struct vop_win_data rk3228_vop_win_data[] = {
958eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3288_win01_data,
959eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
960eb5cb6aaSMark yao 	{ .base = 0x40, .phy = &rk3288_win01_data,
961eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
962eb5cb6aaSMark yao };
963eb5cb6aaSMark yao 
964eb5cb6aaSMark yao static const struct vop_data rk3228_vop = {
965eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 7),
966eb5cb6aaSMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
967eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
968eb5cb6aaSMark yao 	.common = &rk3288_common,
969eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
970eb5cb6aaSMark yao 	.output = &rk3399_output,
971eb5cb6aaSMark yao 	.misc = &rk3368_misc,
972eb5cb6aaSMark yao 	.win = rk3228_vop_win_data,
973eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3228_vop_win_data),
974eb5cb6aaSMark yao };
975eb5cb6aaSMark yao 
976eb5cb6aaSMark yao static const struct vop_modeset rk3328_modeset = {
977eb5cb6aaSMark yao 	.htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
978eb5cb6aaSMark yao 	.hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
979eb5cb6aaSMark yao 	.vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
980eb5cb6aaSMark yao 	.vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
981eb5cb6aaSMark yao 	.hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
982eb5cb6aaSMark yao 	.vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
983eb5cb6aaSMark yao };
984eb5cb6aaSMark yao 
985eb5cb6aaSMark yao static const struct vop_output rk3328_output = {
9861f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19),
9871f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23),
9881f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27),
9891f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31),
990eb5cb6aaSMark yao 	.rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
991eb5cb6aaSMark yao 	.hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
992eb5cb6aaSMark yao 	.edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
993eb5cb6aaSMark yao 	.mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
9941f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16),
9951f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20),
9961f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24),
9971f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28),
998eb5cb6aaSMark yao };
999eb5cb6aaSMark yao 
1000eb5cb6aaSMark yao static const struct vop_misc rk3328_misc = {
1001eb5cb6aaSMark yao 	.global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
1002eb5cb6aaSMark yao };
1003eb5cb6aaSMark yao 
1004eb5cb6aaSMark yao static const struct vop_common rk3328_common = {
1005eb5cb6aaSMark yao 	.standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
1006a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
1007a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
1008a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
1009a5c0fa44SUrja Rannikko 	.pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
1010eb5cb6aaSMark yao 	.dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
1011eb5cb6aaSMark yao 	.dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
1012eb5cb6aaSMark yao 	.out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
1013eb5cb6aaSMark yao 	.cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
1014eb5cb6aaSMark yao };
1015eb5cb6aaSMark yao 
1016eb5cb6aaSMark yao static const struct vop_intr rk3328_vop_intr = {
1017eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
1018eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
1019eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
1020eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
1021eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
1022eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
1023eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
1024eb5cb6aaSMark yao };
1025eb5cb6aaSMark yao 
1026eb5cb6aaSMark yao static const struct vop_win_data rk3328_vop_win_data[] = {
1027fbb1c738SEzequiel Garcia 	{ .base = 0xd0, .phy = &rk3368_win01_data,
1028eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
1029fbb1c738SEzequiel Garcia 	{ .base = 0x1d0, .phy = &rk3368_win01_data,
1030eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
1031fbb1c738SEzequiel Garcia 	{ .base = 0x2d0, .phy = &rk3368_win01_data,
1032eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
1033eb5cb6aaSMark yao };
1034eb5cb6aaSMark yao 
1035eb5cb6aaSMark yao static const struct vop_data rk3328_vop = {
1036eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 8),
1037eb5cb6aaSMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
1038eb5cb6aaSMark yao 	.intr = &rk3328_vop_intr,
1039eb5cb6aaSMark yao 	.common = &rk3328_common,
1040eb5cb6aaSMark yao 	.modeset = &rk3328_modeset,
1041eb5cb6aaSMark yao 	.output = &rk3328_output,
1042eb5cb6aaSMark yao 	.misc = &rk3328_misc,
1043eb5cb6aaSMark yao 	.win = rk3328_vop_win_data,
1044eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3328_vop_win_data),
1045eb5cb6aaSMark yao };
1046eb5cb6aaSMark yao 
1047a67719d1SMark Yao static const struct of_device_id vop_driver_dt_match[] = {
1048f7673453SMark Yao 	{ .compatible = "rockchip,rk3036-vop",
1049f7673453SMark Yao 	  .data = &rk3036_vop },
1050460c3b00SSandy Huang 	{ .compatible = "rockchip,rk3126-vop",
1051460c3b00SSandy Huang 	  .data = &rk3126_vop },
1052570913e0SSandy Huang 	{ .compatible = "rockchip,px30-vop-big",
1053570913e0SSandy Huang 	  .data = &px30_vop_big },
1054570913e0SSandy Huang 	{ .compatible = "rockchip,px30-vop-lit",
1055570913e0SSandy Huang 	  .data = &px30_vop_lit },
1056f4a6de85SMark Yao 	{ .compatible = "rockchip,rk3066-vop",
1057f4a6de85SMark Yao 	  .data = &rk3066_vop },
1058428e15ccSHeiko Stuebner 	{ .compatible = "rockchip,rk3188-vop",
1059428e15ccSHeiko Stuebner 	  .data = &rk3188_vop },
1060b51502adSMark Yao 	{ .compatible = "rockchip,rk3288-vop",
1061b51502adSMark Yao 	  .data = &rk3288_vop },
1062eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3368-vop",
1063eb5cb6aaSMark yao 	  .data = &rk3368_vop },
1064eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3366-vop",
1065eb5cb6aaSMark yao 	  .data = &rk3366_vop },
10660a63bfd0SMark Yao 	{ .compatible = "rockchip,rk3399-vop-big",
10670a63bfd0SMark Yao 	  .data = &rk3399_vop_big },
10680a63bfd0SMark Yao 	{ .compatible = "rockchip,rk3399-vop-lit",
10690a63bfd0SMark Yao 	  .data = &rk3399_vop_lit },
1070eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3228-vop",
1071eb5cb6aaSMark yao 	  .data = &rk3228_vop },
1072eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3328-vop",
1073eb5cb6aaSMark yao 	  .data = &rk3328_vop },
1074a67719d1SMark Yao 	{},
1075a67719d1SMark Yao };
1076a67719d1SMark Yao MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
1077a67719d1SMark Yao 
1078a67719d1SMark Yao static int vop_probe(struct platform_device *pdev)
1079a67719d1SMark Yao {
1080a67719d1SMark Yao 	struct device *dev = &pdev->dev;
1081a67719d1SMark Yao 
1082a67719d1SMark Yao 	if (!dev->of_node) {
1083d8dd6804SHaneen Mohammed 		DRM_DEV_ERROR(dev, "can't find vop devices\n");
1084a67719d1SMark Yao 		return -ENODEV;
1085a67719d1SMark Yao 	}
1086a67719d1SMark Yao 
1087a67719d1SMark Yao 	return component_add(dev, &vop_component_ops);
1088a67719d1SMark Yao }
1089a67719d1SMark Yao 
1090a67719d1SMark Yao static int vop_remove(struct platform_device *pdev)
1091a67719d1SMark Yao {
1092a67719d1SMark Yao 	component_del(&pdev->dev, &vop_component_ops);
1093a67719d1SMark Yao 
1094a67719d1SMark Yao 	return 0;
1095a67719d1SMark Yao }
1096a67719d1SMark Yao 
10978820b68bSJeffy Chen struct platform_driver vop_platform_driver = {
1098a67719d1SMark Yao 	.probe = vop_probe,
1099a67719d1SMark Yao 	.remove = vop_remove,
1100a67719d1SMark Yao 	.driver = {
1101a67719d1SMark Yao 		.name = "rockchip-vop",
1102a67719d1SMark Yao 		.of_match_table = of_match_ptr(vop_driver_dt_match),
1103a67719d1SMark Yao 	},
1104a67719d1SMark Yao };
1105