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,
493fa50896SChen-Yu Tsai 	DRM_FORMAT_NV21,
50a67719d1SMark Yao 	DRM_FORMAT_NV16,
513fa50896SChen-Yu Tsai 	DRM_FORMAT_NV61,
52a67719d1SMark Yao 	DRM_FORMAT_NV24,
533fa50896SChen-Yu Tsai 	DRM_FORMAT_NV42,
54a67719d1SMark Yao };
55a67719d1SMark Yao 
567707f722SAndrzej Pietrasiewicz static const uint64_t format_modifiers_win_full[] = {
577707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_LINEAR,
587707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_INVALID,
597707f722SAndrzej Pietrasiewicz };
607707f722SAndrzej Pietrasiewicz 
617707f722SAndrzej Pietrasiewicz static const uint64_t format_modifiers_win_full_afbc[] = {
627707f722SAndrzej Pietrasiewicz 	ROCKCHIP_AFBC_MOD,
637707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_LINEAR,
647707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_INVALID,
657707f722SAndrzej Pietrasiewicz };
667707f722SAndrzej Pietrasiewicz 
67f7673453SMark Yao static const uint32_t formats_win_lite[] = {
68a67719d1SMark Yao 	DRM_FORMAT_XRGB8888,
69a67719d1SMark Yao 	DRM_FORMAT_ARGB8888,
70a67719d1SMark Yao 	DRM_FORMAT_XBGR8888,
71a67719d1SMark Yao 	DRM_FORMAT_ABGR8888,
72a67719d1SMark Yao 	DRM_FORMAT_RGB888,
73a67719d1SMark Yao 	DRM_FORMAT_BGR888,
74a67719d1SMark Yao 	DRM_FORMAT_RGB565,
75a67719d1SMark Yao 	DRM_FORMAT_BGR565,
76a67719d1SMark Yao };
77a67719d1SMark Yao 
787707f722SAndrzej Pietrasiewicz static const uint64_t format_modifiers_win_lite[] = {
797707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_LINEAR,
807707f722SAndrzej Pietrasiewicz 	DRM_FORMAT_MOD_INVALID,
817707f722SAndrzej Pietrasiewicz };
827707f722SAndrzej Pietrasiewicz 
8353c2710cSAlex Bee static const struct vop_scl_regs rk3036_win0_scl = {
84b51502adSMark Yao 	.scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
85b51502adSMark Yao 	.scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
86b51502adSMark Yao 	.scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
87b51502adSMark Yao 	.scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
88b51502adSMark Yao };
89b51502adSMark Yao 
9053c2710cSAlex Bee static const struct vop_scl_regs rk3036_win1_scl = {
9153c2710cSAlex Bee 	.scale_yrgb_x = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 0x0),
9253c2710cSAlex Bee 	.scale_yrgb_y = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 16),
9353c2710cSAlex Bee };
9453c2710cSAlex Bee 
95b51502adSMark Yao static const struct vop_win_phy rk3036_win0_data = {
9653c2710cSAlex Bee 	.scl = &rk3036_win0_scl,
97b51502adSMark Yao 	.data_formats = formats_win_full,
98b51502adSMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
997707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
100b51502adSMark Yao 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
101b51502adSMark Yao 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
102b51502adSMark Yao 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
103b51502adSMark Yao 	.act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
104b51502adSMark Yao 	.dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
105b51502adSMark Yao 	.dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
106b51502adSMark Yao 	.yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
107b51502adSMark Yao 	.uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
108b51502adSMark Yao 	.yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
109b51502adSMark Yao 	.uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
110d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 18),
111d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 0),
112d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
113b51502adSMark Yao };
114b51502adSMark Yao 
115b51502adSMark Yao static const struct vop_win_phy rk3036_win1_data = {
11653c2710cSAlex Bee 	.scl = &rk3036_win1_scl,
117b51502adSMark Yao 	.data_formats = formats_win_lite,
118b51502adSMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
1197707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
120b51502adSMark Yao 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
121b51502adSMark Yao 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
122b51502adSMark Yao 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
123b51502adSMark Yao 	.act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
124b51502adSMark Yao 	.dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
125b51502adSMark Yao 	.dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
126b51502adSMark Yao 	.yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
127b51502adSMark Yao 	.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
128d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
129d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1),
130d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
131b51502adSMark Yao };
132b51502adSMark Yao 
133b51502adSMark Yao static const struct vop_win_data rk3036_vop_win_data[] = {
134b51502adSMark Yao 	{ .base = 0x00, .phy = &rk3036_win0_data,
135b51502adSMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
136b51502adSMark Yao 	{ .base = 0x00, .phy = &rk3036_win1_data,
137b51502adSMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
138b51502adSMark Yao };
139b51502adSMark Yao 
140b51502adSMark Yao static const int rk3036_vop_intrs[] = {
141b51502adSMark Yao 	DSP_HOLD_VALID_INTR,
142b51502adSMark Yao 	FS_INTR,
143b51502adSMark Yao 	LINE_FLAG_INTR,
144b51502adSMark Yao 	BUS_ERROR_INTR,
145b51502adSMark Yao };
146b51502adSMark Yao 
147b51502adSMark Yao static const struct vop_intr rk3036_intr = {
148b51502adSMark Yao 	.intrs = rk3036_vop_intrs,
149b51502adSMark Yao 	.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
150ac6560dfSMark yao 	.line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
1519a61c54bSMark yao 	.status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
1529a61c54bSMark yao 	.enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
1539a61c54bSMark yao 	.clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
154b51502adSMark Yao };
155b51502adSMark Yao 
1569a61c54bSMark yao static const struct vop_modeset rk3036_modeset = {
157b51502adSMark Yao 	.htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
158b51502adSMark Yao 	.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
159b51502adSMark Yao 	.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
160b51502adSMark Yao 	.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
1619a61c54bSMark yao };
1629a61c54bSMark yao 
1639a61c54bSMark yao static const struct vop_output rk3036_output = {
1649a61c54bSMark yao 	.pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
1659a61c54bSMark yao };
1669a61c54bSMark yao 
1679a61c54bSMark yao static const struct vop_common rk3036_common = {
1689a61c54bSMark yao 	.standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
1699a61c54bSMark yao 	.out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
1709a61c54bSMark yao 	.dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
171a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
172a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
173a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
1749548e1b4SMark yao 	.cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
175b51502adSMark Yao };
176b51502adSMark Yao 
177b51502adSMark Yao static const struct vop_data rk3036_vop = {
178b51502adSMark Yao 	.intr = &rk3036_intr,
1799a61c54bSMark yao 	.common = &rk3036_common,
1809a61c54bSMark yao 	.modeset = &rk3036_modeset,
1819a61c54bSMark yao 	.output = &rk3036_output,
182b51502adSMark Yao 	.win = rk3036_vop_win_data,
183b51502adSMark Yao 	.win_size = ARRAY_SIZE(rk3036_vop_win_data),
1848e140cb6SSascha Hauer 	.max_output = { 1920, 1080 },
185b51502adSMark Yao };
186b51502adSMark Yao 
187460c3b00SSandy Huang static const struct vop_win_phy rk3126_win1_data = {
188460c3b00SSandy Huang 	.data_formats = formats_win_lite,
189460c3b00SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
1907707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
191460c3b00SSandy Huang 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
192460c3b00SSandy Huang 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
193460c3b00SSandy Huang 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
194460c3b00SSandy Huang 	.dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
195460c3b00SSandy Huang 	.dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
196460c3b00SSandy Huang 	.yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
197460c3b00SSandy Huang 	.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
198d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
199d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1),
200d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
201460c3b00SSandy Huang };
202460c3b00SSandy Huang 
203460c3b00SSandy Huang static const struct vop_win_data rk3126_vop_win_data[] = {
204460c3b00SSandy Huang 	{ .base = 0x00, .phy = &rk3036_win0_data,
205460c3b00SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
206460c3b00SSandy Huang 	{ .base = 0x00, .phy = &rk3126_win1_data,
207460c3b00SSandy Huang 	  .type = DRM_PLANE_TYPE_CURSOR },
208460c3b00SSandy Huang };
209460c3b00SSandy Huang 
210460c3b00SSandy Huang static const struct vop_data rk3126_vop = {
211460c3b00SSandy Huang 	.intr = &rk3036_intr,
212460c3b00SSandy Huang 	.common = &rk3036_common,
213460c3b00SSandy Huang 	.modeset = &rk3036_modeset,
214460c3b00SSandy Huang 	.output = &rk3036_output,
215460c3b00SSandy Huang 	.win = rk3126_vop_win_data,
216460c3b00SSandy Huang 	.win_size = ARRAY_SIZE(rk3126_vop_win_data),
2178e140cb6SSascha Hauer 	.max_output = { 1920, 1080 },
218460c3b00SSandy Huang };
219460c3b00SSandy Huang 
220570913e0SSandy Huang static const int px30_vop_intrs[] = {
221570913e0SSandy Huang 	FS_INTR,
222570913e0SSandy Huang 	0, 0,
223570913e0SSandy Huang 	LINE_FLAG_INTR,
224570913e0SSandy Huang 	0,
225570913e0SSandy Huang 	BUS_ERROR_INTR,
226570913e0SSandy Huang 	0, 0,
227570913e0SSandy Huang 	DSP_HOLD_VALID_INTR,
228570913e0SSandy Huang };
229570913e0SSandy Huang 
230570913e0SSandy Huang static const struct vop_intr px30_intr = {
231570913e0SSandy Huang 	.intrs = px30_vop_intrs,
232570913e0SSandy Huang 	.nintrs = ARRAY_SIZE(px30_vop_intrs),
233a6edf839SSandy Huang 	.line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
234a6edf839SSandy Huang 	.status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
235a6edf839SSandy Huang 	.enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
236a6edf839SSandy Huang 	.clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
237570913e0SSandy Huang };
238570913e0SSandy Huang 
239570913e0SSandy Huang static const struct vop_common px30_common = {
240570913e0SSandy Huang 	.standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
241570913e0SSandy Huang 	.out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
242570913e0SSandy Huang 	.dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
243a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
244a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
245a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
246570913e0SSandy Huang 	.cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
247570913e0SSandy Huang };
248570913e0SSandy Huang 
249570913e0SSandy Huang static const struct vop_modeset px30_modeset = {
250570913e0SSandy Huang 	.htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
251570913e0SSandy Huang 	.hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
252570913e0SSandy Huang 	.vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
253570913e0SSandy Huang 	.vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
254570913e0SSandy Huang };
255570913e0SSandy Huang 
256570913e0SSandy Huang static const struct vop_output px30_output = {
2571f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1),
2581f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2),
259570913e0SSandy Huang 	.rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
2601f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25),
2611f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26),
262570913e0SSandy Huang 	.mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
263570913e0SSandy Huang };
264570913e0SSandy Huang 
265570913e0SSandy Huang static const struct vop_scl_regs px30_win_scl = {
266570913e0SSandy Huang 	.scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
267570913e0SSandy Huang 	.scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
268570913e0SSandy Huang 	.scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
269570913e0SSandy Huang 	.scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
270570913e0SSandy Huang };
271570913e0SSandy Huang 
272570913e0SSandy Huang static const struct vop_win_phy px30_win0_data = {
273570913e0SSandy Huang 	.scl = &px30_win_scl,
274570913e0SSandy Huang 	.data_formats = formats_win_full,
275570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_full),
2767707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
277570913e0SSandy Huang 	.enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
278570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
279570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
2803fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 15),
281570913e0SSandy Huang 	.act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
282570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
283570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
284570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
285570913e0SSandy Huang 	.uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
286570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
287570913e0SSandy Huang 	.uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
2882aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2),
2892aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1),
2902aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0),
291570913e0SSandy Huang };
292570913e0SSandy Huang 
293570913e0SSandy Huang static const struct vop_win_phy px30_win1_data = {
294570913e0SSandy Huang 	.data_formats = formats_win_lite,
295570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
2967707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
297570913e0SSandy Huang 	.enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
298570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
299570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
3003fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 15),
301570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
302570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
303570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
304570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
3052aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2),
3062aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1),
3072aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0),
308570913e0SSandy Huang };
309570913e0SSandy Huang 
310570913e0SSandy Huang static const struct vop_win_phy px30_win2_data = {
311570913e0SSandy Huang 	.data_formats = formats_win_lite,
312570913e0SSandy Huang 	.nformats = ARRAY_SIZE(formats_win_lite),
3137707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
314a6edf839SSandy Huang 	.gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
315a6edf839SSandy Huang 	.enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
316570913e0SSandy Huang 	.format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
317570913e0SSandy Huang 	.rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
318570913e0SSandy Huang 	.dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
319570913e0SSandy Huang 	.dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
320570913e0SSandy Huang 	.yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
321570913e0SSandy Huang 	.yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
3222aae8ed1SPaul Kocialkowski 	.alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2),
3232aae8ed1SPaul Kocialkowski 	.alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1),
3242aae8ed1SPaul Kocialkowski 	.alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0),
325570913e0SSandy Huang };
326570913e0SSandy Huang 
327570913e0SSandy Huang static const struct vop_win_data px30_vop_big_win_data[] = {
328570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win0_data,
329570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
330570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win1_data,
331570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_OVERLAY },
332570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win2_data,
333570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_CURSOR },
334570913e0SSandy Huang };
335570913e0SSandy Huang 
336570913e0SSandy Huang static const struct vop_data px30_vop_big = {
337872b68e9SJohan Jonker 	.version = VOP_VERSION(2, 6),
338570913e0SSandy Huang 	.intr = &px30_intr,
3398d544233SSandy Huang 	.feature = VOP_FEATURE_INTERNAL_RGB,
340570913e0SSandy Huang 	.common = &px30_common,
341570913e0SSandy Huang 	.modeset = &px30_modeset,
342570913e0SSandy Huang 	.output = &px30_output,
343570913e0SSandy Huang 	.win = px30_vop_big_win_data,
344570913e0SSandy Huang 	.win_size = ARRAY_SIZE(px30_vop_big_win_data),
3458e140cb6SSascha Hauer 	.max_output = { 1920, 1080 },
346570913e0SSandy Huang };
347570913e0SSandy Huang 
348570913e0SSandy Huang static const struct vop_win_data px30_vop_lit_win_data[] = {
349570913e0SSandy Huang 	{ .base = 0x00, .phy = &px30_win1_data,
350570913e0SSandy Huang 	  .type = DRM_PLANE_TYPE_PRIMARY },
351570913e0SSandy Huang };
352570913e0SSandy Huang 
353570913e0SSandy Huang static const struct vop_data px30_vop_lit = {
354872b68e9SJohan Jonker 	.version = VOP_VERSION(2, 5),
355570913e0SSandy Huang 	.intr = &px30_intr,
3568d544233SSandy Huang 	.feature = VOP_FEATURE_INTERNAL_RGB,
357570913e0SSandy Huang 	.common = &px30_common,
358570913e0SSandy Huang 	.modeset = &px30_modeset,
359570913e0SSandy Huang 	.output = &px30_output,
360570913e0SSandy Huang 	.win = px30_vop_lit_win_data,
361570913e0SSandy Huang 	.win_size = ARRAY_SIZE(px30_vop_lit_win_data),
3628e140cb6SSascha Hauer 	.max_output = { 1920, 1080 },
363570913e0SSandy Huang };
364570913e0SSandy Huang 
365f4a6de85SMark Yao static const struct vop_scl_regs rk3066_win_scl = {
366f4a6de85SMark Yao 	.scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
367f4a6de85SMark Yao 	.scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
368f4a6de85SMark Yao 	.scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
369f4a6de85SMark Yao 	.scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
370f4a6de85SMark Yao };
371f4a6de85SMark Yao 
372f4a6de85SMark Yao static const struct vop_win_phy rk3066_win0_data = {
373f4a6de85SMark Yao 	.scl = &rk3066_win_scl,
374f4a6de85SMark Yao 	.data_formats = formats_win_full,
375f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
3767707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
377f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
378742203cdSAlex Bee 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4),
379742203cdSAlex Bee 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19),
3803fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 22),
381f4a6de85SMark Yao 	.act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
382f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
383f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
384f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
385f4a6de85SMark Yao 	.uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
386f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
387f4a6de85SMark Yao 	.uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
388d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 21),
389d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 0),
390f4a6de85SMark Yao };
391f4a6de85SMark Yao 
392f4a6de85SMark Yao static const struct vop_win_phy rk3066_win1_data = {
393f4a6de85SMark Yao 	.data_formats = formats_win_full,
394f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
3957707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
396f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
397742203cdSAlex Bee 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7),
398742203cdSAlex Bee 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23),
3993fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 26),
400f4a6de85SMark Yao 	.act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
401f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
402f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
403f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
404f4a6de85SMark Yao 	.uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
405f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
406f4a6de85SMark Yao 	.uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
407d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 22),
408d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 1),
409f4a6de85SMark Yao };
410f4a6de85SMark Yao 
411f4a6de85SMark Yao static const struct vop_win_phy rk3066_win2_data = {
412f4a6de85SMark Yao 	.data_formats = formats_win_lite,
413f4a6de85SMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
4147707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
415f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
416742203cdSAlex Bee 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10),
417742203cdSAlex Bee 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27),
418f4a6de85SMark Yao 	.dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
419f4a6de85SMark Yao 	.dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
420f4a6de85SMark Yao 	.yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
421f4a6de85SMark Yao 	.yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
422d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 23),
423d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 2),
424f4a6de85SMark Yao };
425f4a6de85SMark Yao 
426f4a6de85SMark Yao static const struct vop_modeset rk3066_modeset = {
427f4a6de85SMark Yao 	.htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
428f4a6de85SMark Yao 	.hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
429f4a6de85SMark Yao 	.vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
430f4a6de85SMark Yao 	.vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
431f4a6de85SMark Yao };
432f4a6de85SMark Yao 
433f4a6de85SMark Yao static const struct vop_output rk3066_output = {
434f4a6de85SMark Yao 	.pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
435f4a6de85SMark Yao };
436f4a6de85SMark Yao 
437f4a6de85SMark Yao static const struct vop_common rk3066_common = {
438f4a6de85SMark Yao 	.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
439f4a6de85SMark Yao 	.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
440f4a6de85SMark Yao 	.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
441a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
442a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
443f4a6de85SMark Yao 	.dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
444742203cdSAlex Bee 	.dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9),
445742203cdSAlex Bee 	.dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31),
446742203cdSAlex Bee 	.data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25),
447f4a6de85SMark Yao };
448f4a6de85SMark Yao 
449f4a6de85SMark Yao static const struct vop_win_data rk3066_vop_win_data[] = {
450f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win0_data,
451f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
452f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win1_data,
453f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
454f4a6de85SMark Yao 	{ .base = 0x00, .phy = &rk3066_win2_data,
455f4a6de85SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
456f4a6de85SMark Yao };
457f4a6de85SMark Yao 
458f4a6de85SMark Yao static const int rk3066_vop_intrs[] = {
459f4a6de85SMark Yao 	/*
460f4a6de85SMark Yao 	 * hs_start interrupt fires at frame-start, so serves
461f4a6de85SMark Yao 	 * the same purpose as dsp_hold in the driver.
462f4a6de85SMark Yao 	 */
463f4a6de85SMark Yao 	DSP_HOLD_VALID_INTR,
464f4a6de85SMark Yao 	FS_INTR,
465f4a6de85SMark Yao 	LINE_FLAG_INTR,
466f4a6de85SMark Yao 	BUS_ERROR_INTR,
467f4a6de85SMark Yao };
468f4a6de85SMark Yao 
469f4a6de85SMark Yao static const struct vop_intr rk3066_intr = {
470f4a6de85SMark Yao 	.intrs = rk3066_vop_intrs,
471f4a6de85SMark Yao 	.nintrs = ARRAY_SIZE(rk3066_vop_intrs),
472f4a6de85SMark Yao 	.line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
473f4a6de85SMark Yao 	.status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
474f4a6de85SMark Yao 	.enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
475f4a6de85SMark Yao 	.clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
476f4a6de85SMark Yao };
477f4a6de85SMark Yao 
478f4a6de85SMark Yao static const struct vop_data rk3066_vop = {
479f4a6de85SMark Yao 	.version = VOP_VERSION(2, 1),
480f4a6de85SMark Yao 	.intr = &rk3066_intr,
481f4a6de85SMark Yao 	.common = &rk3066_common,
482f4a6de85SMark Yao 	.modeset = &rk3066_modeset,
483f4a6de85SMark Yao 	.output = &rk3066_output,
484f4a6de85SMark Yao 	.win = rk3066_vop_win_data,
485f4a6de85SMark Yao 	.win_size = ARRAY_SIZE(rk3066_vop_win_data),
4868e140cb6SSascha Hauer 	.max_output = { 1920, 1080 },
487f4a6de85SMark Yao };
488f4a6de85SMark Yao 
489428e15ccSHeiko Stuebner static const struct vop_scl_regs rk3188_win_scl = {
490428e15ccSHeiko Stuebner 	.scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
491428e15ccSHeiko Stuebner 	.scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
492428e15ccSHeiko Stuebner 	.scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
493428e15ccSHeiko Stuebner 	.scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
494428e15ccSHeiko Stuebner };
495428e15ccSHeiko Stuebner 
496428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win0_data = {
497428e15ccSHeiko Stuebner 	.scl = &rk3188_win_scl,
498428e15ccSHeiko Stuebner 	.data_formats = formats_win_full,
499428e15ccSHeiko Stuebner 	.nformats = ARRAY_SIZE(formats_win_full),
5007707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
501428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
502428e15ccSHeiko Stuebner 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
503428e15ccSHeiko Stuebner 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
5043fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 18),
505428e15ccSHeiko Stuebner 	.act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
506428e15ccSHeiko Stuebner 	.dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
507428e15ccSHeiko Stuebner 	.dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
508428e15ccSHeiko Stuebner 	.yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
509428e15ccSHeiko Stuebner 	.uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
510428e15ccSHeiko Stuebner 	.yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
511d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 18),
512d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 0),
513d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29),
514428e15ccSHeiko Stuebner };
515428e15ccSHeiko Stuebner 
516428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win1_data = {
517428e15ccSHeiko Stuebner 	.data_formats = formats_win_lite,
518428e15ccSHeiko Stuebner 	.nformats = ARRAY_SIZE(formats_win_lite),
5197707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
520428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
521428e15ccSHeiko Stuebner 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
522428e15ccSHeiko Stuebner 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
523428e15ccSHeiko Stuebner 	/* no act_info on window1 */
524428e15ccSHeiko Stuebner 	.dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
525428e15ccSHeiko Stuebner 	.dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
526428e15ccSHeiko Stuebner 	.yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
527428e15ccSHeiko Stuebner 	.yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
528d099fa67SAlex Bee 	.alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 19),
529d099fa67SAlex Bee 	.alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 1),
530d099fa67SAlex Bee 	.alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29),
531428e15ccSHeiko Stuebner };
532428e15ccSHeiko Stuebner 
533428e15ccSHeiko Stuebner static const struct vop_modeset rk3188_modeset = {
534428e15ccSHeiko Stuebner 	.htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
535428e15ccSHeiko Stuebner 	.hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
536428e15ccSHeiko Stuebner 	.vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
537428e15ccSHeiko Stuebner 	.vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
538428e15ccSHeiko Stuebner };
539428e15ccSHeiko Stuebner 
540428e15ccSHeiko Stuebner static const struct vop_output rk3188_output = {
541428e15ccSHeiko Stuebner 	.pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
542428e15ccSHeiko Stuebner };
543428e15ccSHeiko Stuebner 
544428e15ccSHeiko Stuebner static const struct vop_common rk3188_common = {
545428e15ccSHeiko Stuebner 	.gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
546428e15ccSHeiko Stuebner 	.standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
547428e15ccSHeiko Stuebner 	.out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
548428e15ccSHeiko Stuebner 	.cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
549a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
550a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
551a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
552ab64b448SAlex Bee 	.dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24),
553ab64b448SAlex Bee 	.dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9),
554ab64b448SAlex Bee 	.dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28),
555ab64b448SAlex Bee 	.data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25),
556428e15ccSHeiko Stuebner };
557428e15ccSHeiko Stuebner 
558428e15ccSHeiko Stuebner static const struct vop_win_data rk3188_vop_win_data[] = {
559428e15ccSHeiko Stuebner 	{ .base = 0x00, .phy = &rk3188_win0_data,
560428e15ccSHeiko Stuebner 	  .type = DRM_PLANE_TYPE_PRIMARY },
561428e15ccSHeiko Stuebner 	{ .base = 0x00, .phy = &rk3188_win1_data,
562428e15ccSHeiko Stuebner 	  .type = DRM_PLANE_TYPE_CURSOR },
563428e15ccSHeiko Stuebner };
564428e15ccSHeiko Stuebner 
565428e15ccSHeiko Stuebner static const int rk3188_vop_intrs[] = {
5664f297df8SHeiko Stuebner 	/*
5674f297df8SHeiko Stuebner 	 * hs_start interrupt fires at frame-start, so serves
5684f297df8SHeiko Stuebner 	 * the same purpose as dsp_hold in the driver.
5694f297df8SHeiko Stuebner 	 */
5704f297df8SHeiko Stuebner 	DSP_HOLD_VALID_INTR,
571428e15ccSHeiko Stuebner 	FS_INTR,
572428e15ccSHeiko Stuebner 	LINE_FLAG_INTR,
573428e15ccSHeiko Stuebner 	BUS_ERROR_INTR,
574428e15ccSHeiko Stuebner };
575428e15ccSHeiko Stuebner 
576428e15ccSHeiko Stuebner static const struct vop_intr rk3188_vop_intr = {
577428e15ccSHeiko Stuebner 	.intrs = rk3188_vop_intrs,
578428e15ccSHeiko Stuebner 	.nintrs = ARRAY_SIZE(rk3188_vop_intrs),
579428e15ccSHeiko Stuebner 	.line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
580428e15ccSHeiko Stuebner 	.status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
581428e15ccSHeiko Stuebner 	.enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
582428e15ccSHeiko Stuebner 	.clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
583428e15ccSHeiko Stuebner };
584428e15ccSHeiko Stuebner 
585428e15ccSHeiko Stuebner static const struct vop_data rk3188_vop = {
586428e15ccSHeiko Stuebner 	.intr = &rk3188_vop_intr,
587428e15ccSHeiko Stuebner 	.common = &rk3188_common,
588428e15ccSHeiko Stuebner 	.modeset = &rk3188_modeset,
589428e15ccSHeiko Stuebner 	.output = &rk3188_output,
590428e15ccSHeiko Stuebner 	.win = rk3188_vop_win_data,
591428e15ccSHeiko Stuebner 	.win_size = ARRAY_SIZE(rk3188_vop_win_data),
592428e15ccSHeiko Stuebner 	.feature = VOP_FEATURE_INTERNAL_RGB,
5938e140cb6SSascha Hauer 	.max_output = { 2048, 1536 },
594428e15ccSHeiko Stuebner };
595428e15ccSHeiko Stuebner 
596f7673453SMark Yao static const struct vop_scl_extension rk3288_win_full_scl_ext = {
597f7673453SMark Yao 	.cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
598f7673453SMark Yao 	.cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
599f7673453SMark Yao 	.cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
600f7673453SMark Yao 	.cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
601f7673453SMark Yao 	.cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
602f7673453SMark Yao 	.yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
603f7673453SMark Yao 	.yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
604f7673453SMark Yao 	.yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
605f7673453SMark Yao 	.yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
606f7673453SMark Yao 	.yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
607f7673453SMark Yao 	.line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
608f7673453SMark Yao 	.cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
609f7673453SMark Yao 	.yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
610f7673453SMark Yao 	.vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
611f7673453SMark Yao 	.vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
612f7673453SMark Yao 	.vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
613f7673453SMark Yao 	.vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
614f7673453SMark Yao 	.bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
615f7673453SMark Yao 	.cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
616f7673453SMark Yao 	.yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
617f7673453SMark Yao 	.lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
6181194fffbSMark Yao };
6191194fffbSMark Yao 
620f7673453SMark Yao static const struct vop_scl_regs rk3288_win_full_scl = {
621f7673453SMark Yao 	.ext = &rk3288_win_full_scl_ext,
622f7673453SMark Yao 	.scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
623f7673453SMark Yao 	.scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
624f7673453SMark Yao 	.scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
625f7673453SMark Yao 	.scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
626a67719d1SMark Yao };
627a67719d1SMark Yao 
628f7673453SMark Yao static const struct vop_win_phy rk3288_win01_data = {
629f7673453SMark Yao 	.scl = &rk3288_win_full_scl,
630f7673453SMark Yao 	.data_formats = formats_win_full,
631f7673453SMark Yao 	.nformats = ARRAY_SIZE(formats_win_full),
6327707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
633f7673453SMark Yao 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
634f7673453SMark Yao 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
635f7673453SMark Yao 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
6363fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
637f7673453SMark Yao 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
638f7673453SMark Yao 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
639f7673453SMark Yao 	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
640f7673453SMark Yao 	.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
641f7673453SMark Yao 	.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
642f7673453SMark Yao 	.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
643f7673453SMark Yao 	.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
644f7673453SMark Yao 	.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
645f7673453SMark Yao 	.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
6469dd2aca4SMark yao 	.channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
647a67719d1SMark Yao };
648a67719d1SMark Yao 
649f7673453SMark Yao static const struct vop_win_phy rk3288_win23_data = {
650f7673453SMark Yao 	.data_formats = formats_win_lite,
651f7673453SMark Yao 	.nformats = ARRAY_SIZE(formats_win_lite),
6527707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
65360b7ae7fSMark yao 	.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
65460b7ae7fSMark yao 	.gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
655f7673453SMark Yao 	.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
656f7673453SMark Yao 	.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
657f7673453SMark Yao 	.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
658f7673453SMark Yao 	.dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
659f7673453SMark Yao 	.yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
660f7673453SMark Yao 	.yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
661f7673453SMark Yao 	.src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
662f7673453SMark Yao 	.dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
663a67719d1SMark Yao };
664a67719d1SMark Yao 
6659a61c54bSMark yao static const struct vop_modeset rk3288_modeset = {
666f7673453SMark Yao 	.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
667f7673453SMark Yao 	.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
668f7673453SMark Yao 	.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
669f7673453SMark Yao 	.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
670f7673453SMark Yao 	.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
671f7673453SMark Yao 	.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
6729a61c54bSMark yao };
6739a61c54bSMark yao 
6749a61c54bSMark yao static const struct vop_output rk3288_output = {
6759a61c54bSMark yao 	.pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
6769a61c54bSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
6779a61c54bSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
6789a61c54bSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
6799a61c54bSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
6809a61c54bSMark yao };
6819a61c54bSMark yao 
6829a61c54bSMark yao static const struct vop_common rk3288_common = {
6839a61c54bSMark yao 	.standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
6849a61c54bSMark yao 	.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
6859a61c54bSMark yao 	.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
686a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
687a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
688a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
6896bda8112SMark Yao 	.pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
6909a61c54bSMark yao 	.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
691b23ab6acSEzequiel Garcia 	.dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0),
6929a61c54bSMark yao 	.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
6939a61c54bSMark yao 	.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
6949a61c54bSMark yao 	.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
6959548e1b4SMark yao 	.cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
696a67719d1SMark Yao };
697a67719d1SMark Yao 
698a67719d1SMark Yao /*
699a67719d1SMark Yao  * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
700a67719d1SMark Yao  * special support to get alpha blending working.  For now, just use overlay
701a67719d1SMark Yao  * window 3 for the drm cursor.
702a67719d1SMark Yao  *
703a67719d1SMark Yao  */
704a67719d1SMark Yao static const struct vop_win_data rk3288_vop_win_data[] = {
705f7673453SMark Yao 	{ .base = 0x00, .phy = &rk3288_win01_data,
706f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
707f7673453SMark Yao 	{ .base = 0x40, .phy = &rk3288_win01_data,
708f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
709f7673453SMark Yao 	{ .base = 0x00, .phy = &rk3288_win23_data,
710f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
711f7673453SMark Yao 	{ .base = 0x50, .phy = &rk3288_win23_data,
712f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR },
713a67719d1SMark Yao };
714a67719d1SMark Yao 
715a67719d1SMark Yao static const int rk3288_vop_intrs[] = {
716a67719d1SMark Yao 	DSP_HOLD_VALID_INTR,
717a67719d1SMark Yao 	FS_INTR,
718a67719d1SMark Yao 	LINE_FLAG_INTR,
719a67719d1SMark Yao 	BUS_ERROR_INTR,
720a67719d1SMark Yao };
721a67719d1SMark Yao 
722a67719d1SMark Yao static const struct vop_intr rk3288_vop_intr = {
723a67719d1SMark Yao 	.intrs = rk3288_vop_intrs,
724a67719d1SMark Yao 	.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
725ac6560dfSMark yao 	.line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
726f7673453SMark Yao 	.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
727f7673453SMark Yao 	.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
728f7673453SMark Yao 	.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
729a67719d1SMark Yao };
730a67719d1SMark Yao 
731a67719d1SMark Yao static const struct vop_data rk3288_vop = {
732eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 1),
733efd11cc8SMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
734a67719d1SMark Yao 	.intr = &rk3288_vop_intr,
7359a61c54bSMark yao 	.common = &rk3288_common,
7369a61c54bSMark yao 	.modeset = &rk3288_modeset,
7379a61c54bSMark yao 	.output = &rk3288_output,
738a67719d1SMark Yao 	.win = rk3288_vop_win_data,
739a67719d1SMark Yao 	.win_size = ARRAY_SIZE(rk3288_vop_win_data),
740b23ab6acSEzequiel Garcia 	.lut_size = 1024,
7418e140cb6SSascha Hauer 	/*
7428e140cb6SSascha Hauer 	 * This is the maximum resolution for the VOPB, the VOPL can only do
7438e140cb6SSascha Hauer 	 * 2560x1600, but we can't distinguish them as they have the same
7448e140cb6SSascha Hauer 	 * compatible.
7458e140cb6SSascha Hauer 	 */
7468e140cb6SSascha Hauer 	.max_output = { 3840, 2160 },
747a67719d1SMark Yao };
748a67719d1SMark Yao 
749eb5cb6aaSMark yao static const int rk3368_vop_intrs[] = {
7500a63bfd0SMark Yao 	FS_INTR,
7510a63bfd0SMark Yao 	0, 0,
7520a63bfd0SMark Yao 	LINE_FLAG_INTR,
7530a63bfd0SMark Yao 	0,
7540a63bfd0SMark Yao 	BUS_ERROR_INTR,
7550a63bfd0SMark Yao 	0, 0, 0, 0, 0, 0, 0,
7560a63bfd0SMark Yao 	DSP_HOLD_VALID_INTR,
757f7673453SMark Yao };
758f7673453SMark Yao 
759eb5cb6aaSMark yao static const struct vop_intr rk3368_vop_intr = {
760eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
761eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
762eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
763eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
764eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
765eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
766eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
767eb5cb6aaSMark yao };
768eb5cb6aaSMark yao 
769fbb1c738SEzequiel Garcia static const struct vop_win_phy rk3368_win01_data = {
770fbb1c738SEzequiel Garcia 	.scl = &rk3288_win_full_scl,
771fbb1c738SEzequiel Garcia 	.data_formats = formats_win_full,
772fbb1c738SEzequiel Garcia 	.nformats = ARRAY_SIZE(formats_win_full),
7737707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full,
774fbb1c738SEzequiel Garcia 	.enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
775fbb1c738SEzequiel Garcia 	.format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
776fbb1c738SEzequiel Garcia 	.rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
7773fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 15),
778677e8bbcSDaniele Castagna 	.x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
779677e8bbcSDaniele Castagna 	.y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
780fbb1c738SEzequiel Garcia 	.act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
781fbb1c738SEzequiel Garcia 	.dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
782fbb1c738SEzequiel Garcia 	.dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
783fbb1c738SEzequiel Garcia 	.yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
784fbb1c738SEzequiel Garcia 	.uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
785fbb1c738SEzequiel Garcia 	.yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
786fbb1c738SEzequiel Garcia 	.uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
787fbb1c738SEzequiel Garcia 	.src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
788fbb1c738SEzequiel Garcia 	.dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
789fbb1c738SEzequiel Garcia 	.channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
790fbb1c738SEzequiel Garcia };
791fbb1c738SEzequiel Garcia 
792eb5cb6aaSMark yao static const struct vop_win_phy rk3368_win23_data = {
793eb5cb6aaSMark yao 	.data_formats = formats_win_lite,
794eb5cb6aaSMark yao 	.nformats = ARRAY_SIZE(formats_win_lite),
7957707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_lite,
796eb5cb6aaSMark yao 	.gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
797eb5cb6aaSMark yao 	.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
798eb5cb6aaSMark yao 	.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
799eb5cb6aaSMark yao 	.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
800677e8bbcSDaniele Castagna 	.y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
801eb5cb6aaSMark yao 	.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
802eb5cb6aaSMark yao 	.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
803eb5cb6aaSMark yao 	.yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
804eb5cb6aaSMark yao 	.yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
805eb5cb6aaSMark yao 	.src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
806eb5cb6aaSMark yao 	.dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
807eb5cb6aaSMark yao };
808eb5cb6aaSMark yao 
809eb5cb6aaSMark yao static const struct vop_win_data rk3368_vop_win_data[] = {
810fbb1c738SEzequiel Garcia 	{ .base = 0x00, .phy = &rk3368_win01_data,
811eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
812fbb1c738SEzequiel Garcia 	{ .base = 0x40, .phy = &rk3368_win01_data,
813eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
814eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3368_win23_data,
815eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
816eb5cb6aaSMark yao 	{ .base = 0x50, .phy = &rk3368_win23_data,
817eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
818eb5cb6aaSMark yao };
819eb5cb6aaSMark yao 
820eb5cb6aaSMark yao static const struct vop_output rk3368_output = {
8211f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
8221f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
8231f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
8241f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
8251f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
8261f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
8271f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
8281f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
829eb5cb6aaSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
830eb5cb6aaSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
831eb5cb6aaSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
832eb5cb6aaSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
833eb5cb6aaSMark yao };
834eb5cb6aaSMark yao 
835eb5cb6aaSMark yao static const struct vop_misc rk3368_misc = {
836eb5cb6aaSMark yao 	.global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
837eb5cb6aaSMark yao };
838eb5cb6aaSMark yao 
839eb5cb6aaSMark yao static const struct vop_data rk3368_vop = {
840eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 2),
841eb5cb6aaSMark yao 	.intr = &rk3368_vop_intr,
842eb5cb6aaSMark yao 	.common = &rk3288_common,
843eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
844eb5cb6aaSMark yao 	.output = &rk3368_output,
845eb5cb6aaSMark yao 	.misc = &rk3368_misc,
846eb5cb6aaSMark yao 	.win = rk3368_vop_win_data,
847eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3368_vop_win_data),
8488e140cb6SSascha Hauer 	.max_output = { 4096, 2160 },
849eb5cb6aaSMark yao };
850eb5cb6aaSMark yao 
851eb5cb6aaSMark yao static const struct vop_intr rk3366_vop_intr = {
852eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
853eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
854eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
855eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
856eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
857eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
858eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
859eb5cb6aaSMark yao };
860eb5cb6aaSMark yao 
861eb5cb6aaSMark yao static const struct vop_data rk3366_vop = {
862eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 4),
863eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
864eb5cb6aaSMark yao 	.common = &rk3288_common,
865eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
866eb5cb6aaSMark yao 	.output = &rk3368_output,
867eb5cb6aaSMark yao 	.misc = &rk3368_misc,
868eb5cb6aaSMark yao 	.win = rk3368_vop_win_data,
869eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3368_vop_win_data),
8708e140cb6SSascha Hauer 	.max_output = { 4096, 2160 },
871f7673453SMark Yao };
872f7673453SMark Yao 
8739a61c54bSMark yao static const struct vop_output rk3399_output = {
8741f6c62caSNickey Yang 	.dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19),
8751f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
8761f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
8771f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
8781f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
8791f6c62caSNickey Yang 	.dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16),
8801f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
8811f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
8821f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
8831f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
8849a61c54bSMark yao 	.dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
8859a61c54bSMark yao 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
8869a61c54bSMark yao 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
8879a61c54bSMark yao 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
8889a61c54bSMark yao 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
889cf6d100dSHeiko Stuebner 	.mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
8909a61c54bSMark yao };
8919a61c54bSMark yao 
8923ba000d6SHugh Cole-Baker static const struct vop_common rk3399_common = {
8933ba000d6SHugh Cole-Baker 	.standby = VOP_REG_SYNC(RK3399_SYS_CTRL, 0x1, 22),
8943ba000d6SHugh Cole-Baker 	.gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
8953ba000d6SHugh Cole-Baker 	.mmu_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 20),
8963ba000d6SHugh Cole-Baker 	.dither_down_sel = VOP_REG(RK3399_DSP_CTRL1, 0x1, 4),
8973ba000d6SHugh Cole-Baker 	.dither_down_mode = VOP_REG(RK3399_DSP_CTRL1, 0x1, 3),
8983ba000d6SHugh Cole-Baker 	.dither_down_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 2),
8993ba000d6SHugh Cole-Baker 	.pre_dither_down = VOP_REG(RK3399_DSP_CTRL1, 0x1, 1),
9003ba000d6SHugh Cole-Baker 	.dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
9013ba000d6SHugh Cole-Baker 	.dsp_lut_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 0),
9023ba000d6SHugh Cole-Baker 	.update_gamma_lut = VOP_REG(RK3399_DSP_CTRL1, 0x1, 7),
9033ba000d6SHugh Cole-Baker 	.lut_buffer_index = VOP_REG(RK3399_DBG_POST_REG1, 0x1, 1),
9043ba000d6SHugh Cole-Baker 	.data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
9053ba000d6SHugh Cole-Baker 	.dsp_blank = VOP_REG(RK3399_DSP_CTRL0, 0x3, 18),
9063ba000d6SHugh Cole-Baker 	.out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
9073ba000d6SHugh Cole-Baker 	.cfg_done = VOP_REG_SYNC(RK3399_REG_CFG_DONE, 0x1, 0),
9083ba000d6SHugh Cole-Baker };
9093ba000d6SHugh Cole-Baker 
9101c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
9111c21aa8fSDaniele Castagna 	.y2r_coefficients = {
9121c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
9131c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
9141c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
9151c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
9161c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
9171c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
9181c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
9191c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
9201c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
9211c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
9221c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
9231c21aa8fSDaniele Castagna 		VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
9241c21aa8fSDaniele Castagna 	},
9251c21aa8fSDaniele Castagna };
9261c21aa8fSDaniele Castagna 
9271c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
9281c21aa8fSDaniele Castagna 
9291c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
9301c21aa8fSDaniele Castagna 	{ .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
9311c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
9321c21aa8fSDaniele Castagna 	{ .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
9331c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
9341c21aa8fSDaniele Castagna 	{ .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
9351c21aa8fSDaniele Castagna 	{ .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
9367707f722SAndrzej Pietrasiewicz 
9377707f722SAndrzej Pietrasiewicz };
9387707f722SAndrzej Pietrasiewicz 
9397707f722SAndrzej Pietrasiewicz static const struct vop_win_phy rk3399_win01_data = {
9407707f722SAndrzej Pietrasiewicz 	.scl = &rk3288_win_full_scl,
9417707f722SAndrzej Pietrasiewicz 	.data_formats = formats_win_full,
9427707f722SAndrzej Pietrasiewicz 	.nformats = ARRAY_SIZE(formats_win_full),
9437707f722SAndrzej Pietrasiewicz 	.format_modifiers = format_modifiers_win_full_afbc,
9447707f722SAndrzej Pietrasiewicz 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
9457707f722SAndrzej Pietrasiewicz 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
9467707f722SAndrzej Pietrasiewicz 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
9473fa50896SChen-Yu Tsai 	.uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
9489da1e9abSBrian Norris 	.x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21),
9497707f722SAndrzej Pietrasiewicz 	.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
9507707f722SAndrzej Pietrasiewicz 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
9517707f722SAndrzej Pietrasiewicz 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
9527707f722SAndrzej Pietrasiewicz 	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
9537707f722SAndrzej Pietrasiewicz 	.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
9547707f722SAndrzej Pietrasiewicz 	.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
9557707f722SAndrzej Pietrasiewicz 	.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
9567707f722SAndrzej Pietrasiewicz 	.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
9577707f722SAndrzej Pietrasiewicz 	.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
9587707f722SAndrzej Pietrasiewicz 	.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
9599da1e9abSBrian Norris 	.channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
9607707f722SAndrzej Pietrasiewicz };
9617707f722SAndrzej Pietrasiewicz 
9627707f722SAndrzej Pietrasiewicz /*
9637707f722SAndrzej Pietrasiewicz  * rk3399 vop big windows register layout is same as rk3288, but we
9647707f722SAndrzej Pietrasiewicz  * have a separate rk3399 win data array here so that we can advertise
9657707f722SAndrzej Pietrasiewicz  * AFBC on the primary plane.
9667707f722SAndrzej Pietrasiewicz  */
9677707f722SAndrzej Pietrasiewicz static const struct vop_win_data rk3399_vop_win_data[] = {
9687707f722SAndrzej Pietrasiewicz 	{ .base = 0x00, .phy = &rk3399_win01_data,
9697707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_PRIMARY },
9709da1e9abSBrian Norris 	{ .base = 0x40, .phy = &rk3368_win01_data,
9717707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_OVERLAY },
9729da1e9abSBrian Norris 	{ .base = 0x00, .phy = &rk3368_win23_data,
9737707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_OVERLAY },
9749da1e9abSBrian Norris 	{ .base = 0x50, .phy = &rk3368_win23_data,
9757707f722SAndrzej Pietrasiewicz 	  .type = DRM_PLANE_TYPE_CURSOR },
9767707f722SAndrzej Pietrasiewicz };
9777707f722SAndrzej Pietrasiewicz 
9787707f722SAndrzej Pietrasiewicz static const struct vop_afbc rk3399_vop_afbc = {
9797707f722SAndrzej Pietrasiewicz 	.rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
9807707f722SAndrzej Pietrasiewicz 	.enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
9817707f722SAndrzej Pietrasiewicz 	.win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
9827707f722SAndrzej Pietrasiewicz 	.format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
9837707f722SAndrzej Pietrasiewicz 	.hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
9847707f722SAndrzej Pietrasiewicz 	.hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
9857707f722SAndrzej Pietrasiewicz 	.pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
9861c21aa8fSDaniele Castagna };
9871c21aa8fSDaniele Castagna 
9880a63bfd0SMark Yao static const struct vop_data rk3399_vop_big = {
989eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 5),
990efd11cc8SMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
991eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
9923ba000d6SHugh Cole-Baker 	.common = &rk3399_common,
9939a61c54bSMark yao 	.modeset = &rk3288_modeset,
9949a61c54bSMark yao 	.output = &rk3399_output,
9957707f722SAndrzej Pietrasiewicz 	.afbc = &rk3399_vop_afbc,
996eb5cb6aaSMark yao 	.misc = &rk3368_misc,
9977707f722SAndrzej Pietrasiewicz 	.win = rk3399_vop_win_data,
9987707f722SAndrzej Pietrasiewicz 	.win_size = ARRAY_SIZE(rk3399_vop_win_data),
9991c21aa8fSDaniele Castagna 	.win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
10003ba000d6SHugh Cole-Baker 	.lut_size = 1024,
10018e140cb6SSascha Hauer 	.max_output = { 4096, 2160 },
10020a63bfd0SMark Yao };
10030a63bfd0SMark Yao 
10040a63bfd0SMark Yao static const struct vop_win_data rk3399_vop_lit_win_data[] = {
1005fbb1c738SEzequiel Garcia 	{ .base = 0x00, .phy = &rk3368_win01_data,
1006f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
1007eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3368_win23_data,
1008f7673453SMark Yao 	  .type = DRM_PLANE_TYPE_CURSOR},
1009f7673453SMark Yao };
1010f7673453SMark Yao 
10111c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
10121c21aa8fSDaniele Castagna 	{ .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
10131c21aa8fSDaniele Castagna 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
10141c21aa8fSDaniele Castagna 	{ .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
10151c21aa8fSDaniele Castagna };
10161c21aa8fSDaniele Castagna 
10170a63bfd0SMark Yao static const struct vop_data rk3399_vop_lit = {
1018eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 6),
1019eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
10203ba000d6SHugh Cole-Baker 	.common = &rk3399_common,
10219a61c54bSMark yao 	.modeset = &rk3288_modeset,
10229a61c54bSMark yao 	.output = &rk3399_output,
1023eb5cb6aaSMark yao 	.misc = &rk3368_misc,
10240a63bfd0SMark Yao 	.win = rk3399_vop_lit_win_data,
10250a63bfd0SMark Yao 	.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
10261c21aa8fSDaniele Castagna 	.win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
10273ba000d6SHugh Cole-Baker 	.lut_size = 256,
10288e140cb6SSascha Hauer 	.max_output = { 2560, 1600 },
1029f7673453SMark Yao };
1030f7673453SMark Yao 
1031eb5cb6aaSMark yao static const struct vop_win_data rk3228_vop_win_data[] = {
1032eb5cb6aaSMark yao 	{ .base = 0x00, .phy = &rk3288_win01_data,
1033eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
1034eb5cb6aaSMark yao 	{ .base = 0x40, .phy = &rk3288_win01_data,
1035eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
1036eb5cb6aaSMark yao };
1037eb5cb6aaSMark yao 
1038eb5cb6aaSMark yao static const struct vop_data rk3228_vop = {
1039eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 7),
1040eb5cb6aaSMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
1041eb5cb6aaSMark yao 	.intr = &rk3366_vop_intr,
1042eb5cb6aaSMark yao 	.common = &rk3288_common,
1043eb5cb6aaSMark yao 	.modeset = &rk3288_modeset,
1044eb5cb6aaSMark yao 	.output = &rk3399_output,
1045eb5cb6aaSMark yao 	.misc = &rk3368_misc,
1046eb5cb6aaSMark yao 	.win = rk3228_vop_win_data,
1047eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3228_vop_win_data),
10488e140cb6SSascha Hauer 	.max_output = { 4096, 2160 },
1049eb5cb6aaSMark yao };
1050eb5cb6aaSMark yao 
1051eb5cb6aaSMark yao static const struct vop_modeset rk3328_modeset = {
1052eb5cb6aaSMark yao 	.htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
1053eb5cb6aaSMark yao 	.hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
1054eb5cb6aaSMark yao 	.vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
1055eb5cb6aaSMark yao 	.vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
1056eb5cb6aaSMark yao 	.hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
1057eb5cb6aaSMark yao 	.vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
1058eb5cb6aaSMark yao };
1059eb5cb6aaSMark yao 
1060eb5cb6aaSMark yao static const struct vop_output rk3328_output = {
10611f6c62caSNickey Yang 	.rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19),
10621f6c62caSNickey Yang 	.hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23),
10631f6c62caSNickey Yang 	.edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27),
10641f6c62caSNickey Yang 	.mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31),
1065eb5cb6aaSMark yao 	.rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
1066eb5cb6aaSMark yao 	.hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
1067eb5cb6aaSMark yao 	.edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
1068eb5cb6aaSMark yao 	.mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
10691f6c62caSNickey Yang 	.rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16),
10701f6c62caSNickey Yang 	.hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20),
10711f6c62caSNickey Yang 	.edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24),
10721f6c62caSNickey Yang 	.mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28),
1073eb5cb6aaSMark yao };
1074eb5cb6aaSMark yao 
1075eb5cb6aaSMark yao static const struct vop_misc rk3328_misc = {
1076eb5cb6aaSMark yao 	.global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
1077eb5cb6aaSMark yao };
1078eb5cb6aaSMark yao 
1079eb5cb6aaSMark yao static const struct vop_common rk3328_common = {
1080eb5cb6aaSMark yao 	.standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
1081a5c0fa44SUrja Rannikko 	.dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
1082a5c0fa44SUrja Rannikko 	.dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
1083a5c0fa44SUrja Rannikko 	.dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
1084a5c0fa44SUrja Rannikko 	.pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
1085eb5cb6aaSMark yao 	.dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
1086eb5cb6aaSMark yao 	.dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
1087eb5cb6aaSMark yao 	.out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
1088eb5cb6aaSMark yao 	.cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
1089eb5cb6aaSMark yao };
1090eb5cb6aaSMark yao 
1091eb5cb6aaSMark yao static const struct vop_intr rk3328_vop_intr = {
1092eb5cb6aaSMark yao 	.intrs = rk3368_vop_intrs,
1093eb5cb6aaSMark yao 	.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
1094eb5cb6aaSMark yao 	.line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
1095eb5cb6aaSMark yao 	.line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
1096eb5cb6aaSMark yao 	.status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
1097eb5cb6aaSMark yao 	.enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
1098eb5cb6aaSMark yao 	.clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
1099eb5cb6aaSMark yao };
1100eb5cb6aaSMark yao 
1101eb5cb6aaSMark yao static const struct vop_win_data rk3328_vop_win_data[] = {
1102fbb1c738SEzequiel Garcia 	{ .base = 0xd0, .phy = &rk3368_win01_data,
1103eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_PRIMARY },
1104fbb1c738SEzequiel Garcia 	{ .base = 0x1d0, .phy = &rk3368_win01_data,
1105eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_OVERLAY },
1106fbb1c738SEzequiel Garcia 	{ .base = 0x2d0, .phy = &rk3368_win01_data,
1107eb5cb6aaSMark yao 	  .type = DRM_PLANE_TYPE_CURSOR },
1108eb5cb6aaSMark yao };
1109eb5cb6aaSMark yao 
1110eb5cb6aaSMark yao static const struct vop_data rk3328_vop = {
1111eb5cb6aaSMark yao 	.version = VOP_VERSION(3, 8),
1112eb5cb6aaSMark yao 	.feature = VOP_FEATURE_OUTPUT_RGB10,
1113eb5cb6aaSMark yao 	.intr = &rk3328_vop_intr,
1114eb5cb6aaSMark yao 	.common = &rk3328_common,
1115eb5cb6aaSMark yao 	.modeset = &rk3328_modeset,
1116eb5cb6aaSMark yao 	.output = &rk3328_output,
1117eb5cb6aaSMark yao 	.misc = &rk3328_misc,
1118eb5cb6aaSMark yao 	.win = rk3328_vop_win_data,
1119eb5cb6aaSMark yao 	.win_size = ARRAY_SIZE(rk3328_vop_win_data),
11208e140cb6SSascha Hauer 	.max_output = { 4096, 2160 },
1121eb5cb6aaSMark yao };
1122eb5cb6aaSMark yao 
1123a67719d1SMark Yao static const struct of_device_id vop_driver_dt_match[] = {
1124f7673453SMark Yao 	{ .compatible = "rockchip,rk3036-vop",
1125f7673453SMark Yao 	  .data = &rk3036_vop },
1126460c3b00SSandy Huang 	{ .compatible = "rockchip,rk3126-vop",
1127460c3b00SSandy Huang 	  .data = &rk3126_vop },
1128570913e0SSandy Huang 	{ .compatible = "rockchip,px30-vop-big",
1129570913e0SSandy Huang 	  .data = &px30_vop_big },
1130570913e0SSandy Huang 	{ .compatible = "rockchip,px30-vop-lit",
1131570913e0SSandy Huang 	  .data = &px30_vop_lit },
1132f4a6de85SMark Yao 	{ .compatible = "rockchip,rk3066-vop",
1133f4a6de85SMark Yao 	  .data = &rk3066_vop },
1134428e15ccSHeiko Stuebner 	{ .compatible = "rockchip,rk3188-vop",
1135428e15ccSHeiko Stuebner 	  .data = &rk3188_vop },
1136b51502adSMark Yao 	{ .compatible = "rockchip,rk3288-vop",
1137b51502adSMark Yao 	  .data = &rk3288_vop },
1138eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3368-vop",
1139eb5cb6aaSMark yao 	  .data = &rk3368_vop },
1140eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3366-vop",
1141eb5cb6aaSMark yao 	  .data = &rk3366_vop },
11420a63bfd0SMark Yao 	{ .compatible = "rockchip,rk3399-vop-big",
11430a63bfd0SMark Yao 	  .data = &rk3399_vop_big },
11440a63bfd0SMark Yao 	{ .compatible = "rockchip,rk3399-vop-lit",
11450a63bfd0SMark Yao 	  .data = &rk3399_vop_lit },
1146eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3228-vop",
1147eb5cb6aaSMark yao 	  .data = &rk3228_vop },
1148eb5cb6aaSMark yao 	{ .compatible = "rockchip,rk3328-vop",
1149eb5cb6aaSMark yao 	  .data = &rk3328_vop },
1150a67719d1SMark Yao 	{},
1151a67719d1SMark Yao };
1152a67719d1SMark Yao MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
1153a67719d1SMark Yao 
vop_probe(struct platform_device * pdev)1154a67719d1SMark Yao static int vop_probe(struct platform_device *pdev)
1155a67719d1SMark Yao {
1156a67719d1SMark Yao 	struct device *dev = &pdev->dev;
1157a67719d1SMark Yao 
1158a67719d1SMark Yao 	if (!dev->of_node) {
1159d8dd6804SHaneen Mohammed 		DRM_DEV_ERROR(dev, "can't find vop devices\n");
1160a67719d1SMark Yao 		return -ENODEV;
1161a67719d1SMark Yao 	}
1162a67719d1SMark Yao 
1163a67719d1SMark Yao 	return component_add(dev, &vop_component_ops);
1164a67719d1SMark Yao }
1165a67719d1SMark Yao 
vop_remove(struct platform_device * pdev)1166*3c855610SUwe Kleine-König static void vop_remove(struct platform_device *pdev)
1167a67719d1SMark Yao {
1168a67719d1SMark Yao 	component_del(&pdev->dev, &vop_component_ops);
1169a67719d1SMark Yao }
1170a67719d1SMark Yao 
11718820b68bSJeffy Chen struct platform_driver vop_platform_driver = {
1172a67719d1SMark Yao 	.probe = vop_probe,
1173*3c855610SUwe Kleine-König 	.remove_new = vop_remove,
1174a67719d1SMark Yao 	.driver = {
1175a67719d1SMark Yao 		.name = "rockchip-vop",
117687185cc8SSouptick Joarder 		.of_match_table = vop_driver_dt_match,
1177a67719d1SMark Yao 	},
1178a67719d1SMark Yao };
1179