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),
107*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 18),
108*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 0),
109*d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
110b51502adSMark Yao };
111b51502adSMark Yao 
112b51502adSMark Yao static const struct vop_win_phy rk3036_win1_data = {
11353c2710cSAlex Bee 	.scl = &rk3036_win1_scl,
114b51502adSMark Yao 	.data_formats = formats_win_lite,
115b51502adSMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
1167707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
117b51502adSMark Yao 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
118b51502adSMark Yao 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
119b51502adSMark Yao 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
120b51502adSMark Yao 	.act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
121b51502adSMark Yao 	.dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
122b51502adSMark Yao 	.dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
123b51502adSMark Yao 	.yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
124b51502adSMark Yao 	.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
125*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
126*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1),
127*d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
128b51502adSMark Yao };
129b51502adSMark Yao 
130b51502adSMark Yao static const struct vop_win_data rk3036_vop_win_data[] = {
131b51502adSMark Yao 	{ .base = 0x00, .phy = &rk3036_win0_data,
132b51502adSMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
133b51502adSMark Yao 	{ .base = 0x00, .phy = &rk3036_win1_data,
134b51502adSMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
135b51502adSMark Yao };
136b51502adSMark Yao 
137b51502adSMark Yao static const int rk3036_vop_intrs[] = {
138b51502adSMark Yao 	DSP_HOLD_VALID_INTR,
139b51502adSMark Yao 	FS_INTR,
140b51502adSMark Yao 	LINE_FLAG_INTR,
141b51502adSMark Yao 	BUS_ERROR_INTR,
142b51502adSMark Yao };
143b51502adSMark Yao 
144b51502adSMark Yao static const struct vop_intr rk3036_intr = {
145b51502adSMark Yao 	.intrs = rk3036_vop_intrs,
146b51502adSMark Yao 	.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
147ac6560dfSMark yao 	.line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
1489a61c54bSMark yao 	.status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
1499a61c54bSMark yao 	.enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
1509a61c54bSMark yao 	.clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
151b51502adSMark Yao };
152b51502adSMark Yao 
1539a61c54bSMark yao static const struct vop_modeset rk3036_modeset = {
154b51502adSMark Yao 	.htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
155b51502adSMark Yao 	.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
156b51502adSMark Yao 	.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
157b51502adSMark Yao 	.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
1589a61c54bSMark yao };
1599a61c54bSMark yao 
1609a61c54bSMark yao static const struct vop_output rk3036_output = {
1619a61c54bSMark yao 	.pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
1629a61c54bSMark yao };
1639a61c54bSMark yao 
1649a61c54bSMark yao static const struct vop_common rk3036_common = {
1659a61c54bSMark yao 	.standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
1669a61c54bSMark yao 	.out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
1679a61c54bSMark yao 	.dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
168a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
169a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
170a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
1719548e1b4SMark yao 	.cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
172b51502adSMark Yao };
173b51502adSMark Yao 
174b51502adSMark Yao static const struct vop_data rk3036_vop = {
175b51502adSMark Yao 	.intr = &rk3036_intr,
1769a61c54bSMark yao 	.common = &rk3036_common,
1779a61c54bSMark yao 	.modeset = &rk3036_modeset,
1789a61c54bSMark yao 	.output = &rk3036_output,
179b51502adSMark Yao 	.win = rk3036_vop_win_data,
180b51502adSMark Yao 	.win_size = ARRAY_SIZE(rk3036_vop_win_data),
181b51502adSMark Yao };
182b51502adSMark Yao 
183460c3b00SSandy Huang static const struct vop_win_phy rk3126_win1_data = {
184460c3b00SSandy Huang 	.data_formats = formats_win_lite,
185460c3b00SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
1867707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
187460c3b00SSandy Huang 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
188460c3b00SSandy Huang 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
189460c3b00SSandy Huang 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
190460c3b00SSandy Huang 	.dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
191460c3b00SSandy Huang 	.dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
192460c3b00SSandy Huang 	.yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
193460c3b00SSandy Huang 	.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
194*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
195*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1),
196*d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
197460c3b00SSandy Huang };
198460c3b00SSandy Huang 
199460c3b00SSandy Huang static const struct vop_win_data rk3126_vop_win_data[] = {
200460c3b00SSandy Huang 	{ .base = 0x00, .phy = &rk3036_win0_data,
201460c3b00SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
202460c3b00SSandy Huang 	{ .base = 0x00, .phy = &rk3126_win1_data,
203460c3b00SSandy Huang 	  .type = DRM_PLANE_TYPE_CURSOR },
204460c3b00SSandy Huang };
205460c3b00SSandy Huang 
206460c3b00SSandy Huang static const struct vop_data rk3126_vop = {
207460c3b00SSandy Huang 	.intr = &rk3036_intr,
208460c3b00SSandy Huang 	.common = &rk3036_common,
209460c3b00SSandy Huang 	.modeset = &rk3036_modeset,
210460c3b00SSandy Huang 	.output = &rk3036_output,
211460c3b00SSandy Huang 	.win = rk3126_vop_win_data,
212460c3b00SSandy Huang 	.win_size = ARRAY_SIZE(rk3126_vop_win_data),
213460c3b00SSandy Huang };
214460c3b00SSandy Huang 
215570913e0SSandy Huang static const int px30_vop_intrs[] = {
216570913e0SSandy Huang 	FS_INTR,
217570913e0SSandy Huang 	0, 0,
218570913e0SSandy Huang 	LINE_FLAG_INTR,
219570913e0SSandy Huang 	0,
220570913e0SSandy Huang 	BUS_ERROR_INTR,
221570913e0SSandy Huang 	0, 0,
222570913e0SSandy Huang 	DSP_HOLD_VALID_INTR,
223570913e0SSandy Huang };
224570913e0SSandy Huang 
225570913e0SSandy Huang static const struct vop_intr px30_intr = {
226570913e0SSandy Huang 	.intrs = px30_vop_intrs,
227570913e0SSandy Huang 	.nintrs = ARRAY_SIZE(px30_vop_intrs),
228a6edf839SSandy Huang 	.line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
229a6edf839SSandy Huang 	.status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
230a6edf839SSandy Huang 	.enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
231a6edf839SSandy Huang 	.clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
232570913e0SSandy Huang };
233570913e0SSandy Huang 
234570913e0SSandy Huang static const struct vop_common px30_common = {
235570913e0SSandy Huang 	.standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
236570913e0SSandy Huang 	.out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
237570913e0SSandy Huang 	.dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
238a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
239a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
240a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
241570913e0SSandy Huang 	.cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
242570913e0SSandy Huang };
243570913e0SSandy Huang 
244570913e0SSandy Huang static const struct vop_modeset px30_modeset = {
245570913e0SSandy Huang 	.htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
246570913e0SSandy Huang 	.hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
247570913e0SSandy Huang 	.vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
248570913e0SSandy Huang 	.vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
249570913e0SSandy Huang };
250570913e0SSandy Huang 
251570913e0SSandy Huang static const struct vop_output px30_output = {
2521f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1),
2531f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2),
254570913e0SSandy Huang 	.rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
2551f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25),
2561f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26),
257570913e0SSandy Huang 	.mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
258570913e0SSandy Huang };
259570913e0SSandy Huang 
260570913e0SSandy Huang static const struct vop_scl_regs px30_win_scl = {
261570913e0SSandy Huang 	.scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
262570913e0SSandy Huang 	.scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
263570913e0SSandy Huang 	.scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
264570913e0SSandy Huang 	.scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
265570913e0SSandy Huang };
266570913e0SSandy Huang 
267570913e0SSandy Huang static const struct vop_win_phy px30_win0_data = {
268570913e0SSandy Huang 	.scl = &px30_win_scl,
269570913e0SSandy Huang 	.data_formats = formats_win_full,
270570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_full),
2717707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
272570913e0SSandy Huang 	.enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
273570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
274570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
275570913e0SSandy Huang 	.act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
276570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
277570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
278570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
279570913e0SSandy Huang 	.uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
280570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
281570913e0SSandy Huang 	.uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
2822aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2),
2832aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1),
2842aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0),
285570913e0SSandy Huang };
286570913e0SSandy Huang 
287570913e0SSandy Huang static const struct vop_win_phy px30_win1_data = {
288570913e0SSandy Huang 	.data_formats = formats_win_lite,
289570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
2907707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
291570913e0SSandy Huang 	.enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
292570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
293570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
294570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
295570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
296570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
297570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
2982aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2),
2992aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1),
3002aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0),
301570913e0SSandy Huang };
302570913e0SSandy Huang 
303570913e0SSandy Huang static const struct vop_win_phy px30_win2_data = {
304570913e0SSandy Huang 	.data_formats = formats_win_lite,
305570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
3067707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
307a6edf839SSandy Huang 	.gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
308a6edf839SSandy Huang 	.enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
309570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
310570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
311570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
312570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
313570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
314570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
3152aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2),
3162aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1),
3172aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0),
318570913e0SSandy Huang };
319570913e0SSandy Huang 
320570913e0SSandy Huang static const struct vop_win_data px30_vop_big_win_data[] = {
321570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win0_data,
322570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
323570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win1_data,
324570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_OVERLAY },
325570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win2_data,
326570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_CURSOR },
327570913e0SSandy Huang };
328570913e0SSandy Huang 
329570913e0SSandy Huang static const struct vop_data px30_vop_big = {
330570913e0SSandy Huang 	.intr = &px30_intr,
3318d544233SSandy Huang 	.feature = VOP_FEATURE_INTERNAL_RGB,
332570913e0SSandy Huang 	.common = &px30_common,
333570913e0SSandy Huang 	.modeset = &px30_modeset,
334570913e0SSandy Huang 	.output = &px30_output,
335570913e0SSandy Huang 	.win = px30_vop_big_win_data,
336570913e0SSandy Huang 	.win_size = ARRAY_SIZE(px30_vop_big_win_data),
337570913e0SSandy Huang };
338570913e0SSandy Huang 
339570913e0SSandy Huang static const struct vop_win_data px30_vop_lit_win_data[] = {
340570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win1_data,
341570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
342570913e0SSandy Huang };
343570913e0SSandy Huang 
344570913e0SSandy Huang static const struct vop_data px30_vop_lit = {
345570913e0SSandy Huang 	.intr = &px30_intr,
3468d544233SSandy Huang 	.feature = VOP_FEATURE_INTERNAL_RGB,
347570913e0SSandy Huang 	.common = &px30_common,
348570913e0SSandy Huang 	.modeset = &px30_modeset,
349570913e0SSandy Huang 	.output = &px30_output,
350570913e0SSandy Huang 	.win = px30_vop_lit_win_data,
351570913e0SSandy Huang 	.win_size = ARRAY_SIZE(px30_vop_lit_win_data),
352570913e0SSandy Huang };
353570913e0SSandy Huang 
354f4a6de85SMark Yao static const struct vop_scl_regs rk3066_win_scl = {
355f4a6de85SMark Yao 	.scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
356f4a6de85SMark Yao 	.scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
357f4a6de85SMark Yao 	.scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
358f4a6de85SMark Yao 	.scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
359f4a6de85SMark Yao };
360f4a6de85SMark Yao 
361f4a6de85SMark Yao static const struct vop_win_phy rk3066_win0_data = {
362f4a6de85SMark Yao 	.scl = &rk3066_win_scl,
363f4a6de85SMark Yao 	.data_formats = formats_win_full,
364f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
3657707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
366f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
367742203cdSAlex Bee 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4),
368742203cdSAlex Bee 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19),
369f4a6de85SMark Yao 	.act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
370f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
371f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
372f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
373f4a6de85SMark Yao 	.uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
374f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
375f4a6de85SMark Yao 	.uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
376*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 21),
377*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 0),
378f4a6de85SMark Yao };
379f4a6de85SMark Yao 
380f4a6de85SMark Yao static const struct vop_win_phy rk3066_win1_data = {
381f4a6de85SMark Yao 	.data_formats = formats_win_full,
382f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
3837707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
384f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
385742203cdSAlex Bee 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7),
386742203cdSAlex Bee 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23),
387f4a6de85SMark Yao 	.act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
388f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
389f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
390f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
391f4a6de85SMark Yao 	.uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
392f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
393f4a6de85SMark Yao 	.uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
394*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 22),
395*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 1),
396f4a6de85SMark Yao };
397f4a6de85SMark Yao 
398f4a6de85SMark Yao static const struct vop_win_phy rk3066_win2_data = {
399f4a6de85SMark Yao 	.data_formats = formats_win_lite,
400f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
4017707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
402f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
403742203cdSAlex Bee 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10),
404742203cdSAlex Bee 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27),
405f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
406f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
407f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
408f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
409*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 23),
410*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 2),
411f4a6de85SMark Yao };
412f4a6de85SMark Yao 
413f4a6de85SMark Yao static const struct vop_modeset rk3066_modeset = {
414f4a6de85SMark Yao 	.htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
415f4a6de85SMark Yao 	.hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
416f4a6de85SMark Yao 	.vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
417f4a6de85SMark Yao 	.vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
418f4a6de85SMark Yao };
419f4a6de85SMark Yao 
420f4a6de85SMark Yao static const struct vop_output rk3066_output = {
421f4a6de85SMark Yao 	.pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
422f4a6de85SMark Yao };
423f4a6de85SMark Yao 
424f4a6de85SMark Yao static const struct vop_common rk3066_common = {
425f4a6de85SMark Yao 	.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
426f4a6de85SMark Yao 	.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
427f4a6de85SMark Yao 	.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
428a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
429a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
430f4a6de85SMark Yao 	.dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
431742203cdSAlex Bee 	.dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9),
432742203cdSAlex Bee 	.dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31),
433742203cdSAlex Bee 	.data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25),
434f4a6de85SMark Yao };
435f4a6de85SMark Yao 
436f4a6de85SMark Yao static const struct vop_win_data rk3066_vop_win_data[] = {
437f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win0_data,
438f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
439f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win1_data,
440f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
441f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win2_data,
442f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
443f4a6de85SMark Yao };
444f4a6de85SMark Yao 
445f4a6de85SMark Yao static const int rk3066_vop_intrs[] = {
446f4a6de85SMark Yao 	/*
447f4a6de85SMark Yao 	 * hs_start interrupt fires at frame-start, so serves
448f4a6de85SMark Yao 	 * the same purpose as dsp_hold in the driver.
449f4a6de85SMark Yao 	 */
450f4a6de85SMark Yao 	DSP_HOLD_VALID_INTR,
451f4a6de85SMark Yao 	FS_INTR,
452f4a6de85SMark Yao 	LINE_FLAG_INTR,
453f4a6de85SMark Yao 	BUS_ERROR_INTR,
454f4a6de85SMark Yao };
455f4a6de85SMark Yao 
456f4a6de85SMark Yao static const struct vop_intr rk3066_intr = {
457f4a6de85SMark Yao 	.intrs = rk3066_vop_intrs,
458f4a6de85SMark Yao 	.nintrs = ARRAY_SIZE(rk3066_vop_intrs),
459f4a6de85SMark Yao 	.line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
460f4a6de85SMark Yao 	.status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
461f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
462f4a6de85SMark Yao 	.clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
463f4a6de85SMark Yao };
464f4a6de85SMark Yao 
465f4a6de85SMark Yao static const struct vop_data rk3066_vop = {
466f4a6de85SMark Yao 	.version = VOP_VERSION(2, 1),
467f4a6de85SMark Yao 	.intr = &rk3066_intr,
468f4a6de85SMark Yao 	.common = &rk3066_common,
469f4a6de85SMark Yao 	.modeset = &rk3066_modeset,
470f4a6de85SMark Yao 	.output = &rk3066_output,
471f4a6de85SMark Yao 	.win = rk3066_vop_win_data,
472f4a6de85SMark Yao 	.win_size = ARRAY_SIZE(rk3066_vop_win_data),
473f4a6de85SMark Yao };
474f4a6de85SMark Yao 
475428e15ccSHeiko Stuebner static const struct vop_scl_regs rk3188_win_scl = {
476428e15ccSHeiko Stuebner 	.scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
477428e15ccSHeiko Stuebner 	.scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
478428e15ccSHeiko Stuebner 	.scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
479428e15ccSHeiko Stuebner 	.scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
480428e15ccSHeiko Stuebner };
481428e15ccSHeiko Stuebner 
482428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win0_data = {
483428e15ccSHeiko Stuebner 	.scl = &rk3188_win_scl,
484428e15ccSHeiko Stuebner 	.data_formats = formats_win_full,
485428e15ccSHeiko Stuebner 	.nformats = ARRAY_SIZE(formats_win_full),
4867707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
487428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
488428e15ccSHeiko Stuebner 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
489428e15ccSHeiko Stuebner 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
490428e15ccSHeiko Stuebner 	.act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
491428e15ccSHeiko Stuebner 	.dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
492428e15ccSHeiko Stuebner 	.dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
493428e15ccSHeiko Stuebner 	.yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
494428e15ccSHeiko Stuebner 	.uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
495428e15ccSHeiko Stuebner 	.yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
496*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 18),
497*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 0),
498*d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29),
499428e15ccSHeiko Stuebner };
500428e15ccSHeiko Stuebner 
501428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win1_data = {
502428e15ccSHeiko Stuebner 	.data_formats = formats_win_lite,
503428e15ccSHeiko Stuebner 	.nformats = ARRAY_SIZE(formats_win_lite),
5047707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
505428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
506428e15ccSHeiko Stuebner 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
507428e15ccSHeiko Stuebner 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
508428e15ccSHeiko Stuebner 	/* no act_info on window1 */
509428e15ccSHeiko Stuebner 	.dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
510428e15ccSHeiko Stuebner 	.dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
511428e15ccSHeiko Stuebner 	.yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
512428e15ccSHeiko Stuebner 	.yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
513*d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 19),
514*d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 1),
515*d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29),
516428e15ccSHeiko Stuebner };
517428e15ccSHeiko Stuebner 
518428e15ccSHeiko Stuebner static const struct vop_modeset rk3188_modeset = {
519428e15ccSHeiko Stuebner 	.htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
520428e15ccSHeiko Stuebner 	.hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
521428e15ccSHeiko Stuebner 	.vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
522428e15ccSHeiko Stuebner 	.vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
523428e15ccSHeiko Stuebner };
524428e15ccSHeiko Stuebner 
525428e15ccSHeiko Stuebner static const struct vop_output rk3188_output = {
526428e15ccSHeiko Stuebner 	.pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
527428e15ccSHeiko Stuebner };
528428e15ccSHeiko Stuebner 
529428e15ccSHeiko Stuebner static const struct vop_common rk3188_common = {
530428e15ccSHeiko Stuebner 	.gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
531428e15ccSHeiko Stuebner 	.standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
532428e15ccSHeiko Stuebner 	.out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
533428e15ccSHeiko Stuebner 	.cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
534a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
535a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
536a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
537ab64b448SAlex Bee 	.dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24),
538ab64b448SAlex Bee 	.dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9),
539ab64b448SAlex Bee 	.dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28),
540ab64b448SAlex Bee 	.data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25),
541428e15ccSHeiko Stuebner };
542428e15ccSHeiko Stuebner 
543428e15ccSHeiko Stuebner static const struct vop_win_data rk3188_vop_win_data[] = {
544428e15ccSHeiko Stuebner 	{ .base = 0x00, .phy = &rk3188_win0_data,
545428e15ccSHeiko Stuebner 	  .type = DRM_PLANE_TYPE_PRIMARY },
546428e15ccSHeiko Stuebner 	{ .base = 0x00, .phy = &rk3188_win1_data,
547428e15ccSHeiko Stuebner 	  .type = DRM_PLANE_TYPE_CURSOR },
548428e15ccSHeiko Stuebner };
549428e15ccSHeiko Stuebner 
550428e15ccSHeiko Stuebner static const int rk3188_vop_intrs[] = {
5514f297df8SHeiko Stuebner 	/*
5524f297df8SHeiko Stuebner 	 * hs_start interrupt fires at frame-start, so serves
5534f297df8SHeiko Stuebner 	 * the same purpose as dsp_hold in the driver.
5544f297df8SHeiko Stuebner 	 */
5554f297df8SHeiko Stuebner 	DSP_HOLD_VALID_INTR,
556428e15ccSHeiko Stuebner 	FS_INTR,
557428e15ccSHeiko Stuebner 	LINE_FLAG_INTR,
558428e15ccSHeiko Stuebner 	BUS_ERROR_INTR,
559428e15ccSHeiko Stuebner };
560428e15ccSHeiko Stuebner 
561428e15ccSHeiko Stuebner static const struct vop_intr rk3188_vop_intr = {
562428e15ccSHeiko Stuebner 	.intrs = rk3188_vop_intrs,
563428e15ccSHeiko Stuebner 	.nintrs = ARRAY_SIZE(rk3188_vop_intrs),
564428e15ccSHeiko Stuebner 	.line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
565428e15ccSHeiko Stuebner 	.status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
566428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
567428e15ccSHeiko Stuebner 	.clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
568428e15ccSHeiko Stuebner };
569428e15ccSHeiko Stuebner 
570428e15ccSHeiko Stuebner static const struct vop_data rk3188_vop = {
571428e15ccSHeiko Stuebner 	.intr = &rk3188_vop_intr,
572428e15ccSHeiko Stuebner 	.common = &rk3188_common,
573428e15ccSHeiko Stuebner 	.modeset = &rk3188_modeset,
574428e15ccSHeiko Stuebner 	.output = &rk3188_output,
575428e15ccSHeiko Stuebner 	.win = rk3188_vop_win_data,
576428e15ccSHeiko Stuebner 	.win_size = ARRAY_SIZE(rk3188_vop_win_data),
577428e15ccSHeiko Stuebner 	.feature = VOP_FEATURE_INTERNAL_RGB,
578428e15ccSHeiko Stuebner };
579428e15ccSHeiko Stuebner 
580f7673453SMark Yao static const struct vop_scl_extension rk3288_win_full_scl_ext = {
581f7673453SMark Yao 	.cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
582f7673453SMark Yao 	.cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
583f7673453SMark Yao 	.cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
584f7673453SMark Yao 	.cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
585f7673453SMark Yao 	.cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
586f7673453SMark Yao 	.yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
587f7673453SMark Yao 	.yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
588f7673453SMark Yao 	.yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
589f7673453SMark Yao 	.yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
590f7673453SMark Yao 	.yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
591f7673453SMark Yao 	.line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
592f7673453SMark Yao 	.cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
593f7673453SMark Yao 	.yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
594f7673453SMark Yao 	.vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
595f7673453SMark Yao 	.vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
596f7673453SMark Yao 	.vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
597f7673453SMark Yao 	.vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
598f7673453SMark Yao 	.bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
599f7673453SMark Yao 	.cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
600f7673453SMark Yao 	.yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
601f7673453SMark Yao 	.lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
6021194fffbSMark Yao };
6031194fffbSMark Yao 
604f7673453SMark Yao static const struct vop_scl_regs rk3288_win_full_scl = {
605f7673453SMark Yao 	.ext = &rk3288_win_full_scl_ext,
606f7673453SMark Yao 	.scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
607f7673453SMark Yao 	.scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
608f7673453SMark Yao 	.scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
609f7673453SMark Yao 	.scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
610a67719d1SMark Yao };
611a67719d1SMark Yao 
612f7673453SMark Yao static const struct vop_win_phy rk3288_win01_data = {
613f7673453SMark Yao 	.scl = &rk3288_win_full_scl,
614f7673453SMark Yao 	.data_formats = formats_win_full,
615f7673453SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
6167707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
617f7673453SMark Yao 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
618f7673453SMark Yao 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
619f7673453SMark Yao 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
620f7673453SMark Yao 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
621f7673453SMark Yao 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
622f7673453SMark Yao 	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
623f7673453SMark Yao 	.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
624f7673453SMark Yao 	.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
625f7673453SMark Yao 	.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
626f7673453SMark Yao 	.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
627f7673453SMark Yao 	.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
628f7673453SMark Yao 	.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
6299dd2aca4SMark yao 	.channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
630a67719d1SMark Yao };
631a67719d1SMark Yao 
632f7673453SMark Yao static const struct vop_win_phy rk3288_win23_data = {
633f7673453SMark Yao 	.data_formats = formats_win_lite,
634f7673453SMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
6357707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
63660b7ae7fSMark yao 	.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
63760b7ae7fSMark yao 	.gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
638f7673453SMark Yao 	.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
639f7673453SMark Yao 	.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
640f7673453SMark Yao 	.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
641f7673453SMark Yao 	.dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
642f7673453SMark Yao 	.yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
643f7673453SMark Yao 	.yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
644f7673453SMark Yao 	.src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
645f7673453SMark Yao 	.dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
646a67719d1SMark Yao };
647a67719d1SMark Yao 
6489a61c54bSMark yao static const struct vop_modeset rk3288_modeset = {
649f7673453SMark Yao 	.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
650f7673453SMark Yao 	.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
651f7673453SMark Yao 	.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
652f7673453SMark Yao 	.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
653f7673453SMark Yao 	.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
654f7673453SMark Yao 	.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
6559a61c54bSMark yao };
6569a61c54bSMark yao 
6579a61c54bSMark yao static const struct vop_output rk3288_output = {
6589a61c54bSMark yao 	.pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
6599a61c54bSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
6609a61c54bSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
6619a61c54bSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
6629a61c54bSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
6639a61c54bSMark yao };
6649a61c54bSMark yao 
6659a61c54bSMark yao static const struct vop_common rk3288_common = {
6669a61c54bSMark yao 	.standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
6679a61c54bSMark yao 	.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
6689a61c54bSMark yao 	.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
669a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
670a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
671a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
6726bda8112SMark Yao 	.pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
6739a61c54bSMark yao 	.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
674b23ab6acSEzequiel Garcia 	.dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0),
6759a61c54bSMark yao 	.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
6769a61c54bSMark yao 	.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
6779a61c54bSMark yao 	.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
6789548e1b4SMark yao 	.cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
679a67719d1SMark Yao };
680a67719d1SMark Yao 
681a67719d1SMark Yao /*
682a67719d1SMark Yao  * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
683a67719d1SMark Yao  * special support to get alpha blending working.  For now, just use overlay
684a67719d1SMark Yao  * window 3 for the drm cursor.
685a67719d1SMark Yao  *
686a67719d1SMark Yao  */
687a67719d1SMark Yao static const struct vop_win_data rk3288_vop_win_data[] = {
688f7673453SMark Yao 	{ .base = 0x00, .phy = &rk3288_win01_data,
689f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
690f7673453SMark Yao 	{ .base = 0x40, .phy = &rk3288_win01_data,
691f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
692f7673453SMark Yao 	{ .base = 0x00, .phy = &rk3288_win23_data,
693f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
694f7673453SMark Yao 	{ .base = 0x50, .phy = &rk3288_win23_data,
695f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
696a67719d1SMark Yao };
697a67719d1SMark Yao 
698a67719d1SMark Yao static const int rk3288_vop_intrs[] = {
699a67719d1SMark Yao 	DSP_HOLD_VALID_INTR,
700a67719d1SMark Yao 	FS_INTR,
701a67719d1SMark Yao 	LINE_FLAG_INTR,
702a67719d1SMark Yao 	BUS_ERROR_INTR,
703a67719d1SMark Yao };
704a67719d1SMark Yao 
705a67719d1SMark Yao static const struct vop_intr rk3288_vop_intr = {
706a67719d1SMark Yao 	.intrs = rk3288_vop_intrs,
707a67719d1SMark Yao 	.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
708ac6560dfSMark yao 	.line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
709f7673453SMark Yao 	.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
710f7673453SMark Yao 	.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
711f7673453SMark Yao 	.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
712a67719d1SMark Yao };
713a67719d1SMark Yao 
714a67719d1SMark Yao static const struct vop_data rk3288_vop = {
715eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 1),
716efd11cc8SMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
717a67719d1SMark Yao 	.intr = &rk3288_vop_intr,
7189a61c54bSMark yao 	.common = &rk3288_common,
7199a61c54bSMark yao 	.modeset = &rk3288_modeset,
7209a61c54bSMark yao 	.output = &rk3288_output,
721a67719d1SMark Yao 	.win = rk3288_vop_win_data,
722a67719d1SMark Yao 	.win_size = ARRAY_SIZE(rk3288_vop_win_data),
723b23ab6acSEzequiel Garcia 	.lut_size = 1024,
724a67719d1SMark Yao };
725a67719d1SMark Yao 
726eb5cb6aaSMark yao static const int rk3368_vop_intrs[] = {
7270a63bfd0SMark Yao 	FS_INTR,
7280a63bfd0SMark Yao 	0, 0,
7290a63bfd0SMark Yao 	LINE_FLAG_INTR,
7300a63bfd0SMark Yao 	0,
7310a63bfd0SMark Yao 	BUS_ERROR_INTR,
7320a63bfd0SMark Yao 	0, 0, 0, 0, 0, 0, 0,
7330a63bfd0SMark Yao 	DSP_HOLD_VALID_INTR,
734f7673453SMark Yao };
735f7673453SMark Yao 
736eb5cb6aaSMark yao static const struct vop_intr rk3368_vop_intr = {
737eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
738eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
739eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
740eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
741eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
742eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
743eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
744eb5cb6aaSMark yao };
745eb5cb6aaSMark yao 
746fbb1c738SEzequiel Garcia static const struct vop_win_phy rk3368_win01_data = {
747fbb1c738SEzequiel Garcia 	.scl = &rk3288_win_full_scl,
748fbb1c738SEzequiel Garcia 	.data_formats = formats_win_full,
749fbb1c738SEzequiel Garcia 	.nformats = ARRAY_SIZE(formats_win_full),
7507707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
751fbb1c738SEzequiel Garcia 	.enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
752fbb1c738SEzequiel Garcia 	.format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
753fbb1c738SEzequiel Garcia 	.rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
754677e8bbcSDaniele Castagna 	.x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
755677e8bbcSDaniele Castagna 	.y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
756fbb1c738SEzequiel Garcia 	.act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
757fbb1c738SEzequiel Garcia 	.dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
758fbb1c738SEzequiel Garcia 	.dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
759fbb1c738SEzequiel Garcia 	.yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
760fbb1c738SEzequiel Garcia 	.uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
761fbb1c738SEzequiel Garcia 	.yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
762fbb1c738SEzequiel Garcia 	.uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
763fbb1c738SEzequiel Garcia 	.src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
764fbb1c738SEzequiel Garcia 	.dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
765fbb1c738SEzequiel Garcia 	.channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
766fbb1c738SEzequiel Garcia };
767fbb1c738SEzequiel Garcia 
768eb5cb6aaSMark yao static const struct vop_win_phy rk3368_win23_data = {
769eb5cb6aaSMark yao 	.data_formats = formats_win_lite,
770eb5cb6aaSMark yao 	.nformats = ARRAY_SIZE(formats_win_lite),
7717707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
772eb5cb6aaSMark yao 	.gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
773eb5cb6aaSMark yao 	.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
774eb5cb6aaSMark yao 	.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
775eb5cb6aaSMark yao 	.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
776677e8bbcSDaniele Castagna 	.y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
777eb5cb6aaSMark yao 	.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
778eb5cb6aaSMark yao 	.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
779eb5cb6aaSMark yao 	.yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
780eb5cb6aaSMark yao 	.yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
781eb5cb6aaSMark yao 	.src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
782eb5cb6aaSMark yao 	.dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
783eb5cb6aaSMark yao };
784eb5cb6aaSMark yao 
785eb5cb6aaSMark yao static const struct vop_win_data rk3368_vop_win_data[] = {
786fbb1c738SEzequiel Garcia 	{ .base = 0x00, .phy = &rk3368_win01_data,
787eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
788fbb1c738SEzequiel Garcia 	{ .base = 0x40, .phy = &rk3368_win01_data,
789eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
790eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3368_win23_data,
791eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
792eb5cb6aaSMark yao 	{ .base = 0x50, .phy = &rk3368_win23_data,
793eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
794eb5cb6aaSMark yao };
795eb5cb6aaSMark yao 
796eb5cb6aaSMark yao static const struct vop_output rk3368_output = {
7971f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
7981f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
7991f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
8001f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
8011f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
8021f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
8031f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
8041f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
805eb5cb6aaSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
806eb5cb6aaSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
807eb5cb6aaSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
808eb5cb6aaSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
809eb5cb6aaSMark yao };
810eb5cb6aaSMark yao 
811eb5cb6aaSMark yao static const struct vop_misc rk3368_misc = {
812eb5cb6aaSMark yao 	.global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
813eb5cb6aaSMark yao };
814eb5cb6aaSMark yao 
815eb5cb6aaSMark yao static const struct vop_data rk3368_vop = {
816eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 2),
817eb5cb6aaSMark yao 	.intr = &rk3368_vop_intr,
818eb5cb6aaSMark yao 	.common = &rk3288_common,
819eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
820eb5cb6aaSMark yao 	.output = &rk3368_output,
821eb5cb6aaSMark yao 	.misc = &rk3368_misc,
822eb5cb6aaSMark yao 	.win = rk3368_vop_win_data,
823eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3368_vop_win_data),
824eb5cb6aaSMark yao };
825eb5cb6aaSMark yao 
826eb5cb6aaSMark yao static const struct vop_intr rk3366_vop_intr = {
827eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
828eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
829eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
830eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
831eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
832eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
833eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
834eb5cb6aaSMark yao };
835eb5cb6aaSMark yao 
836eb5cb6aaSMark yao static const struct vop_data rk3366_vop = {
837eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 4),
838eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
839eb5cb6aaSMark yao 	.common = &rk3288_common,
840eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
841eb5cb6aaSMark yao 	.output = &rk3368_output,
842eb5cb6aaSMark yao 	.misc = &rk3368_misc,
843eb5cb6aaSMark yao 	.win = rk3368_vop_win_data,
844eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3368_vop_win_data),
845f7673453SMark Yao };
846f7673453SMark Yao 
8479a61c54bSMark yao static const struct vop_output rk3399_output = {
8481f6c62caSNickey Yang 	.dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19),
8491f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
8501f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
8511f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
8521f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
8531f6c62caSNickey Yang 	.dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16),
8541f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
8551f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
8561f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
8571f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
8589a61c54bSMark yao 	.dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
8599a61c54bSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
8609a61c54bSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
8619a61c54bSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
8629a61c54bSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
863cf6d100dSHeiko Stuebner 	.mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
8649a61c54bSMark yao };
8659a61c54bSMark yao 
8661c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
8671c21aa8fSDaniele Castagna 	.y2r_coefficients = {
8681c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
8691c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
8701c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
8711c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
8721c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
8731c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
8741c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
8751c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
8761c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
8771c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
8781c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
8791c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
8801c21aa8fSDaniele Castagna 	},
8811c21aa8fSDaniele Castagna };
8821c21aa8fSDaniele Castagna 
8831c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
8841c21aa8fSDaniele Castagna 
8851c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
8861c21aa8fSDaniele Castagna 	{ .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
8871c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
8881c21aa8fSDaniele Castagna 	{ .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
8891c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
8901c21aa8fSDaniele Castagna 	{ .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
8911c21aa8fSDaniele Castagna 	{ .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
8927707f722SAndrzej Pietrasiewicz 
8937707f722SAndrzej Pietrasiewicz };
8947707f722SAndrzej Pietrasiewicz 
8957707f722SAndrzej Pietrasiewicz static const struct vop_win_phy rk3399_win01_data = {
8967707f722SAndrzej Pietrasiewicz 	.scl = &rk3288_win_full_scl,
8977707f722SAndrzej Pietrasiewicz 	.data_formats = formats_win_full,
8987707f722SAndrzej Pietrasiewicz 	.nformats = ARRAY_SIZE(formats_win_full),
8997707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full_afbc,
9007707f722SAndrzej Pietrasiewicz 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
9017707f722SAndrzej Pietrasiewicz 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
9027707f722SAndrzej Pietrasiewicz 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
9037707f722SAndrzej Pietrasiewicz 	.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
9047707f722SAndrzej Pietrasiewicz 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
9057707f722SAndrzej Pietrasiewicz 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
9067707f722SAndrzej Pietrasiewicz 	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
9077707f722SAndrzej Pietrasiewicz 	.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
9087707f722SAndrzej Pietrasiewicz 	.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
9097707f722SAndrzej Pietrasiewicz 	.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
9107707f722SAndrzej Pietrasiewicz 	.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
9117707f722SAndrzej Pietrasiewicz 	.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
9127707f722SAndrzej Pietrasiewicz 	.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
9137707f722SAndrzej Pietrasiewicz };
9147707f722SAndrzej Pietrasiewicz 
9157707f722SAndrzej Pietrasiewicz /*
9167707f722SAndrzej Pietrasiewicz  * rk3399 vop big windows register layout is same as rk3288, but we
9177707f722SAndrzej Pietrasiewicz  * have a separate rk3399 win data array here so that we can advertise
9187707f722SAndrzej Pietrasiewicz  * AFBC on the primary plane.
9197707f722SAndrzej Pietrasiewicz  */
9207707f722SAndrzej Pietrasiewicz static const struct vop_win_data rk3399_vop_win_data[] = {
9217707f722SAndrzej Pietrasiewicz 	{ .base = 0x00, .phy = &rk3399_win01_data,
9227707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_PRIMARY },
9237707f722SAndrzej Pietrasiewicz 	{ .base = 0x40, .phy = &rk3288_win01_data,
9247707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_OVERLAY },
9257707f722SAndrzej Pietrasiewicz 	{ .base = 0x00, .phy = &rk3288_win23_data,
9267707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_OVERLAY },
9277707f722SAndrzej Pietrasiewicz 	{ .base = 0x50, .phy = &rk3288_win23_data,
9287707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_CURSOR },
9297707f722SAndrzej Pietrasiewicz };
9307707f722SAndrzej Pietrasiewicz 
9317707f722SAndrzej Pietrasiewicz static const struct vop_afbc rk3399_vop_afbc = {
9327707f722SAndrzej Pietrasiewicz 	.rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
9337707f722SAndrzej Pietrasiewicz 	.enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
9347707f722SAndrzej Pietrasiewicz 	.win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
9357707f722SAndrzej Pietrasiewicz 	.format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
9367707f722SAndrzej Pietrasiewicz 	.hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
9377707f722SAndrzej Pietrasiewicz 	.hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
9387707f722SAndrzej Pietrasiewicz 	.pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
9391c21aa8fSDaniele Castagna };
9401c21aa8fSDaniele Castagna 
9410a63bfd0SMark Yao static const struct vop_data rk3399_vop_big = {
942eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 5),
943efd11cc8SMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
944eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
9459a61c54bSMark yao 	.common = &rk3288_common,
9469a61c54bSMark yao 	.modeset = &rk3288_modeset,
9479a61c54bSMark yao 	.output = &rk3399_output,
9487707f722SAndrzej Pietrasiewicz 	.afbc = &rk3399_vop_afbc,
949eb5cb6aaSMark yao 	.misc = &rk3368_misc,
9507707f722SAndrzej Pietrasiewicz 	.win = rk3399_vop_win_data,
9517707f722SAndrzej Pietrasiewicz 	.win_size = ARRAY_SIZE(rk3399_vop_win_data),
9521c21aa8fSDaniele Castagna 	.win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
9530a63bfd0SMark Yao };
9540a63bfd0SMark Yao 
9550a63bfd0SMark Yao static const struct vop_win_data rk3399_vop_lit_win_data[] = {
956fbb1c738SEzequiel Garcia 	{ .base = 0x00, .phy = &rk3368_win01_data,
957f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
958eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3368_win23_data,
959f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR},
960f7673453SMark Yao };
961f7673453SMark Yao 
9621c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
9631c21aa8fSDaniele Castagna 	{ .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
9641c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
9651c21aa8fSDaniele Castagna 	{ .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
9661c21aa8fSDaniele Castagna };
9671c21aa8fSDaniele Castagna 
9680a63bfd0SMark Yao static const struct vop_data rk3399_vop_lit = {
969eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 6),
970eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
9719a61c54bSMark yao 	.common = &rk3288_common,
9729a61c54bSMark yao 	.modeset = &rk3288_modeset,
9739a61c54bSMark yao 	.output = &rk3399_output,
974eb5cb6aaSMark yao 	.misc = &rk3368_misc,
9750a63bfd0SMark Yao 	.win = rk3399_vop_lit_win_data,
9760a63bfd0SMark Yao 	.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
9771c21aa8fSDaniele Castagna 	.win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
978f7673453SMark Yao };
979f7673453SMark Yao 
980eb5cb6aaSMark yao static const struct vop_win_data rk3228_vop_win_data[] = {
981eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3288_win01_data,
982eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
983eb5cb6aaSMark yao 	{ .base = 0x40, .phy = &rk3288_win01_data,
984eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
985eb5cb6aaSMark yao };
986eb5cb6aaSMark yao 
987eb5cb6aaSMark yao static const struct vop_data rk3228_vop = {
988eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 7),
989eb5cb6aaSMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
990eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
991eb5cb6aaSMark yao 	.common = &rk3288_common,
992eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
993eb5cb6aaSMark yao 	.output = &rk3399_output,
994eb5cb6aaSMark yao 	.misc = &rk3368_misc,
995eb5cb6aaSMark yao 	.win = rk3228_vop_win_data,
996eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3228_vop_win_data),
997eb5cb6aaSMark yao };
998eb5cb6aaSMark yao 
999eb5cb6aaSMark yao static const struct vop_modeset rk3328_modeset = {
1000eb5cb6aaSMark yao 	.htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
1001eb5cb6aaSMark yao 	.hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
1002eb5cb6aaSMark yao 	.vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
1003eb5cb6aaSMark yao 	.vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
1004eb5cb6aaSMark yao 	.hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
1005eb5cb6aaSMark yao 	.vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
1006eb5cb6aaSMark yao };
1007eb5cb6aaSMark yao 
1008eb5cb6aaSMark yao static const struct vop_output rk3328_output = {
10091f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19),
10101f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23),
10111f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27),
10121f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31),
1013eb5cb6aaSMark yao 	.rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
1014eb5cb6aaSMark yao 	.hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
1015eb5cb6aaSMark yao 	.edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
1016eb5cb6aaSMark yao 	.mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
10171f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16),
10181f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20),
10191f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24),
10201f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28),
1021eb5cb6aaSMark yao };
1022eb5cb6aaSMark yao 
1023eb5cb6aaSMark yao static const struct vop_misc rk3328_misc = {
1024eb5cb6aaSMark yao 	.global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
1025eb5cb6aaSMark yao };
1026eb5cb6aaSMark yao 
1027eb5cb6aaSMark yao static const struct vop_common rk3328_common = {
1028eb5cb6aaSMark yao 	.standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
1029a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
1030a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
1031a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
1032a5c0fa44SUrja Rannikko 	.pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
1033eb5cb6aaSMark yao 	.dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
1034eb5cb6aaSMark yao 	.dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
1035eb5cb6aaSMark yao 	.out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
1036eb5cb6aaSMark yao 	.cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
1037eb5cb6aaSMark yao };
1038eb5cb6aaSMark yao 
1039eb5cb6aaSMark yao static const struct vop_intr rk3328_vop_intr = {
1040eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
1041eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
1042eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
1043eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
1044eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
1045eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
1046eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
1047eb5cb6aaSMark yao };
1048eb5cb6aaSMark yao 
1049eb5cb6aaSMark yao static const struct vop_win_data rk3328_vop_win_data[] = {
1050fbb1c738SEzequiel Garcia 	{ .base = 0xd0, .phy = &rk3368_win01_data,
1051eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
1052fbb1c738SEzequiel Garcia 	{ .base = 0x1d0, .phy = &rk3368_win01_data,
1053eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
1054fbb1c738SEzequiel Garcia 	{ .base = 0x2d0, .phy = &rk3368_win01_data,
1055eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
1056eb5cb6aaSMark yao };
1057eb5cb6aaSMark yao 
1058eb5cb6aaSMark yao static const struct vop_data rk3328_vop = {
1059eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 8),
1060eb5cb6aaSMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
1061eb5cb6aaSMark yao 	.intr = &rk3328_vop_intr,
1062eb5cb6aaSMark yao 	.common = &rk3328_common,
1063eb5cb6aaSMark yao 	.modeset = &rk3328_modeset,
1064eb5cb6aaSMark yao 	.output = &rk3328_output,
1065eb5cb6aaSMark yao 	.misc = &rk3328_misc,
1066eb5cb6aaSMark yao 	.win = rk3328_vop_win_data,
1067eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3328_vop_win_data),
1068eb5cb6aaSMark yao };
1069eb5cb6aaSMark yao 
1070a67719d1SMark Yao static const struct of_device_id vop_driver_dt_match[] = {
1071f7673453SMark Yao 	{ .compatible = "rockchip,rk3036-vop",
1072f7673453SMark Yao 	  .data = &rk3036_vop },
1073460c3b00SSandy Huang 	{ .compatible = "rockchip,rk3126-vop",
1074460c3b00SSandy Huang 	  .data = &rk3126_vop },
1075570913e0SSandy Huang 	{ .compatible = "rockchip,px30-vop-big",
1076570913e0SSandy Huang 	  .data = &px30_vop_big },
1077570913e0SSandy Huang 	{ .compatible = "rockchip,px30-vop-lit",
1078570913e0SSandy Huang 	  .data = &px30_vop_lit },
1079f4a6de85SMark Yao 	{ .compatible = "rockchip,rk3066-vop",
1080f4a6de85SMark Yao 	  .data = &rk3066_vop },
1081428e15ccSHeiko Stuebner 	{ .compatible = "rockchip,rk3188-vop",
1082428e15ccSHeiko Stuebner 	  .data = &rk3188_vop },
1083b51502adSMark Yao 	{ .compatible = "rockchip,rk3288-vop",
1084b51502adSMark Yao 	  .data = &rk3288_vop },
1085eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3368-vop",
1086eb5cb6aaSMark yao 	  .data = &rk3368_vop },
1087eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3366-vop",
1088eb5cb6aaSMark yao 	  .data = &rk3366_vop },
10890a63bfd0SMark Yao 	{ .compatible = "rockchip,rk3399-vop-big",
10900a63bfd0SMark Yao 	  .data = &rk3399_vop_big },
10910a63bfd0SMark Yao 	{ .compatible = "rockchip,rk3399-vop-lit",
10920a63bfd0SMark Yao 	  .data = &rk3399_vop_lit },
1093eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3228-vop",
1094eb5cb6aaSMark yao 	  .data = &rk3228_vop },
1095eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3328-vop",
1096eb5cb6aaSMark yao 	  .data = &rk3328_vop },
1097a67719d1SMark Yao 	{},
1098a67719d1SMark Yao };
1099a67719d1SMark Yao MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
1100a67719d1SMark Yao 
1101a67719d1SMark Yao static int vop_probe(struct platform_device *pdev)
1102a67719d1SMark Yao {
1103a67719d1SMark Yao 	struct device *dev = &pdev->dev;
1104a67719d1SMark Yao 
1105a67719d1SMark Yao 	if (!dev->of_node) {
1106d8dd6804SHaneen Mohammed 		DRM_DEV_ERROR(dev, "can't find vop devices\n");
1107a67719d1SMark Yao 		return -ENODEV;
1108a67719d1SMark Yao 	}
1109a67719d1SMark Yao 
1110a67719d1SMark Yao 	return component_add(dev, &vop_component_ops);
1111a67719d1SMark Yao }
1112a67719d1SMark Yao 
1113a67719d1SMark Yao static int vop_remove(struct platform_device *pdev)
1114a67719d1SMark Yao {
1115a67719d1SMark Yao 	component_del(&pdev->dev, &vop_component_ops);
1116a67719d1SMark Yao 
1117a67719d1SMark Yao 	return 0;
1118a67719d1SMark Yao }
1119a67719d1SMark Yao 
11208820b68bSJeffy Chen struct platform_driver vop_platform_driver = {
1121a67719d1SMark Yao 	.probe = vop_probe,
1122a67719d1SMark Yao 	.remove = vop_remove,
1123a67719d1SMark Yao 	.driver = {
1124a67719d1SMark Yao 		.name = "rockchip-vop",
1125a67719d1SMark Yao 		.of_match_table = of_match_ptr(vop_driver_dt_match),
1126a67719d1SMark Yao 	},
1127a67719d1SMark Yao };
1128