]>
Commit | Line | Data |
---|---|---|
9c92ab61 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
a67719d1 MY |
2 | /* |
3 | * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd | |
4 | * Author:Mark Yao <mark.yao@rock-chips.com> | |
a67719d1 MY |
5 | */ |
6 | ||
a67719d1 | 7 | #include <linux/component.h> |
c2156ccd SR |
8 | #include <linux/mod_devicetable.h> |
9 | #include <linux/module.h> | |
10 | #include <linux/of.h> | |
11 | #include <linux/platform_device.h> | |
12 | ||
13 | #include <drm/drm_fourcc.h> | |
14 | #include <drm/drm_plane.h> | |
15 | #include <drm/drm_print.h> | |
a67719d1 MY |
16 | |
17 | #include "rockchip_drm_vop.h" | |
18 | #include "rockchip_vop_reg.h" | |
b02516b6 | 19 | #include "rockchip_drm_drv.h" |
a67719d1 | 20 | |
9548e1b4 MY |
21 | #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \ |
22 | { \ | |
23 | .offset = off, \ | |
a67719d1 | 24 | .mask = _mask, \ |
9548e1b4 MY |
25 | .shift = _shift, \ |
26 | .write_mask = _write_mask, \ | |
27 | .relaxed = _relaxed, \ | |
28 | } | |
d49463ec | 29 | |
9548e1b4 MY |
30 | #define VOP_REG(off, _mask, _shift) \ |
31 | _VOP_REG(off, _mask, _shift, false, true) | |
32 | ||
33 | #define VOP_REG_SYNC(off, _mask, _shift) \ | |
34 | _VOP_REG(off, _mask, _shift, false, false) | |
35 | ||
36 | #define VOP_REG_MASK_SYNC(off, _mask, _shift) \ | |
37 | _VOP_REG(off, _mask, _shift, true, false) | |
a67719d1 | 38 | |
f7673453 | 39 | static const uint32_t formats_win_full[] = { |
a67719d1 MY |
40 | DRM_FORMAT_XRGB8888, |
41 | DRM_FORMAT_ARGB8888, | |
42 | DRM_FORMAT_XBGR8888, | |
43 | DRM_FORMAT_ABGR8888, | |
44 | DRM_FORMAT_RGB888, | |
45 | DRM_FORMAT_BGR888, | |
46 | DRM_FORMAT_RGB565, | |
47 | DRM_FORMAT_BGR565, | |
48 | DRM_FORMAT_NV12, | |
49 | DRM_FORMAT_NV16, | |
50 | DRM_FORMAT_NV24, | |
51 | }; | |
52 | ||
7707f722 AP |
53 | static const uint64_t format_modifiers_win_full[] = { |
54 | DRM_FORMAT_MOD_LINEAR, | |
55 | DRM_FORMAT_MOD_INVALID, | |
56 | }; | |
57 | ||
58 | static const uint64_t format_modifiers_win_full_afbc[] = { | |
59 | ROCKCHIP_AFBC_MOD, | |
60 | DRM_FORMAT_MOD_LINEAR, | |
61 | DRM_FORMAT_MOD_INVALID, | |
62 | }; | |
63 | ||
f7673453 | 64 | static const uint32_t formats_win_lite[] = { |
a67719d1 MY |
65 | DRM_FORMAT_XRGB8888, |
66 | DRM_FORMAT_ARGB8888, | |
67 | DRM_FORMAT_XBGR8888, | |
68 | DRM_FORMAT_ABGR8888, | |
69 | DRM_FORMAT_RGB888, | |
70 | DRM_FORMAT_BGR888, | |
71 | DRM_FORMAT_RGB565, | |
72 | DRM_FORMAT_BGR565, | |
73 | }; | |
74 | ||
7707f722 AP |
75 | static const uint64_t format_modifiers_win_lite[] = { |
76 | DRM_FORMAT_MOD_LINEAR, | |
77 | DRM_FORMAT_MOD_INVALID, | |
78 | }; | |
79 | ||
53c2710c | 80 | static const struct vop_scl_regs rk3036_win0_scl = { |
b51502ad MY |
81 | .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), |
82 | .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
83 | .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
84 | .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
85 | }; | |
86 | ||
53c2710c AB |
87 | static const struct vop_scl_regs rk3036_win1_scl = { |
88 | .scale_yrgb_x = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
89 | .scale_yrgb_y = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 16), | |
90 | }; | |
91 | ||
b51502ad | 92 | static const struct vop_win_phy rk3036_win0_data = { |
53c2710c | 93 | .scl = &rk3036_win0_scl, |
b51502ad MY |
94 | .data_formats = formats_win_full, |
95 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 96 | .format_modifiers = format_modifiers_win_full, |
b51502ad MY |
97 | .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0), |
98 | .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3), | |
99 | .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15), | |
100 | .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0), | |
101 | .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
102 | .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0), | |
103 | .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0), | |
104 | .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0), | |
105 | .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0), | |
106 | .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16), | |
d099fa67 AB |
107 | .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 18), |
108 | .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 0), | |
109 | .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29), | |
b51502ad MY |
110 | }; |
111 | ||
112 | static const struct vop_win_phy rk3036_win1_data = { | |
53c2710c | 113 | .scl = &rk3036_win1_scl, |
b51502ad MY |
114 | .data_formats = formats_win_lite, |
115 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 116 | .format_modifiers = format_modifiers_win_lite, |
b51502ad MY |
117 | .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), |
118 | .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), | |
119 | .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), | |
120 | .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0), | |
121 | .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0), | |
122 | .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0), | |
123 | .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0), | |
124 | .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0), | |
d099fa67 AB |
125 | .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19), |
126 | .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1), | |
127 | .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29), | |
b51502ad MY |
128 | }; |
129 | ||
130 | static const struct vop_win_data rk3036_vop_win_data[] = { | |
131 | { .base = 0x00, .phy = &rk3036_win0_data, | |
132 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
133 | { .base = 0x00, .phy = &rk3036_win1_data, | |
134 | .type = DRM_PLANE_TYPE_CURSOR }, | |
135 | }; | |
136 | ||
137 | static const int rk3036_vop_intrs[] = { | |
138 | DSP_HOLD_VALID_INTR, | |
139 | FS_INTR, | |
140 | LINE_FLAG_INTR, | |
141 | BUS_ERROR_INTR, | |
142 | }; | |
143 | ||
144 | static const struct vop_intr rk3036_intr = { | |
145 | .intrs = rk3036_vop_intrs, | |
146 | .nintrs = ARRAY_SIZE(rk3036_vop_intrs), | |
ac6560df | 147 | .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12), |
9a61c54b MY |
148 | .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0), |
149 | .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4), | |
150 | .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8), | |
b51502ad MY |
151 | }; |
152 | ||
9a61c54b | 153 | static const struct vop_modeset rk3036_modeset = { |
b51502ad MY |
154 | .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), |
155 | .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
156 | .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
157 | .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
9a61c54b MY |
158 | }; |
159 | ||
160 | static const struct vop_output rk3036_output = { | |
161 | .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4), | |
162 | }; | |
163 | ||
164 | static const struct vop_common rk3036_common = { | |
165 | .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30), | |
166 | .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0), | |
167 | .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24), | |
a5c0fa44 UR |
168 | .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27), |
169 | .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11), | |
170 | .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10), | |
9548e1b4 | 171 | .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0), |
b51502ad MY |
172 | }; |
173 | ||
b51502ad | 174 | static const struct vop_data rk3036_vop = { |
b51502ad | 175 | .intr = &rk3036_intr, |
9a61c54b MY |
176 | .common = &rk3036_common, |
177 | .modeset = &rk3036_modeset, | |
178 | .output = &rk3036_output, | |
b51502ad MY |
179 | .win = rk3036_vop_win_data, |
180 | .win_size = ARRAY_SIZE(rk3036_vop_win_data), | |
181 | }; | |
182 | ||
460c3b00 SH |
183 | static const struct vop_win_phy rk3126_win1_data = { |
184 | .data_formats = formats_win_lite, | |
185 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 186 | .format_modifiers = format_modifiers_win_lite, |
460c3b00 SH |
187 | .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), |
188 | .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), | |
189 | .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), | |
190 | .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0), | |
191 | .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0), | |
192 | .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0), | |
193 | .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0), | |
d099fa67 AB |
194 | .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19), |
195 | .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1), | |
196 | .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29), | |
460c3b00 SH |
197 | }; |
198 | ||
199 | static const struct vop_win_data rk3126_vop_win_data[] = { | |
200 | { .base = 0x00, .phy = &rk3036_win0_data, | |
201 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
202 | { .base = 0x00, .phy = &rk3126_win1_data, | |
203 | .type = DRM_PLANE_TYPE_CURSOR }, | |
204 | }; | |
205 | ||
206 | static const struct vop_data rk3126_vop = { | |
207 | .intr = &rk3036_intr, | |
208 | .common = &rk3036_common, | |
209 | .modeset = &rk3036_modeset, | |
210 | .output = &rk3036_output, | |
211 | .win = rk3126_vop_win_data, | |
212 | .win_size = ARRAY_SIZE(rk3126_vop_win_data), | |
213 | }; | |
214 | ||
570913e0 SH |
215 | static const int px30_vop_intrs[] = { |
216 | FS_INTR, | |
217 | 0, 0, | |
218 | LINE_FLAG_INTR, | |
219 | 0, | |
220 | BUS_ERROR_INTR, | |
221 | 0, 0, | |
222 | DSP_HOLD_VALID_INTR, | |
223 | }; | |
224 | ||
225 | static const struct vop_intr px30_intr = { | |
226 | .intrs = px30_vop_intrs, | |
227 | .nintrs = ARRAY_SIZE(px30_vop_intrs), | |
a6edf839 SH |
228 | .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0), |
229 | .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0), | |
230 | .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0), | |
231 | .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0), | |
570913e0 SH |
232 | }; |
233 | ||
234 | static const struct vop_common px30_common = { | |
235 | .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1), | |
236 | .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16), | |
237 | .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14), | |
a5c0fa44 UR |
238 | .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8), |
239 | .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7), | |
240 | .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6), | |
570913e0 SH |
241 | .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0), |
242 | }; | |
243 | ||
244 | static const struct vop_modeset px30_modeset = { | |
245 | .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), | |
246 | .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0), | |
247 | .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), | |
248 | .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0), | |
249 | }; | |
250 | ||
251 | static const struct vop_output px30_output = { | |
1f6c62ca NY |
252 | .rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1), |
253 | .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2), | |
570913e0 | 254 | .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0), |
1f6c62ca NY |
255 | .mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25), |
256 | .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26), | |
570913e0 SH |
257 | .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24), |
258 | }; | |
259 | ||
260 | static const struct vop_scl_regs px30_win_scl = { | |
261 | .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
262 | .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
263 | .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
264 | .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
265 | }; | |
266 | ||
267 | static const struct vop_win_phy px30_win0_data = { | |
268 | .scl = &px30_win_scl, | |
269 | .data_formats = formats_win_full, | |
270 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 271 | .format_modifiers = format_modifiers_win_full, |
570913e0 SH |
272 | .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0), |
273 | .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1), | |
274 | .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12), | |
275 | .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0), | |
276 | .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0), | |
277 | .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0), | |
278 | .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0), | |
279 | .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0), | |
280 | .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0), | |
281 | .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16), | |
2aae8ed1 PK |
282 | .alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2), |
283 | .alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1), | |
284 | .alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0), | |
570913e0 SH |
285 | }; |
286 | ||
287 | static const struct vop_win_phy px30_win1_data = { | |
288 | .data_formats = formats_win_lite, | |
289 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 290 | .format_modifiers = format_modifiers_win_lite, |
570913e0 SH |
291 | .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0), |
292 | .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4), | |
293 | .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12), | |
294 | .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0), | |
295 | .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0), | |
296 | .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0), | |
297 | .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0), | |
2aae8ed1 PK |
298 | .alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2), |
299 | .alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1), | |
300 | .alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0), | |
570913e0 SH |
301 | }; |
302 | ||
303 | static const struct vop_win_phy px30_win2_data = { | |
304 | .data_formats = formats_win_lite, | |
305 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 306 | .format_modifiers = format_modifiers_win_lite, |
a6edf839 SH |
307 | .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4), |
308 | .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0), | |
570913e0 SH |
309 | .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5), |
310 | .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20), | |
311 | .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0), | |
312 | .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0), | |
313 | .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0), | |
314 | .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0), | |
2aae8ed1 PK |
315 | .alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2), |
316 | .alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1), | |
317 | .alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0), | |
570913e0 SH |
318 | }; |
319 | ||
320 | static const struct vop_win_data px30_vop_big_win_data[] = { | |
321 | { .base = 0x00, .phy = &px30_win0_data, | |
322 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
323 | { .base = 0x00, .phy = &px30_win1_data, | |
324 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
325 | { .base = 0x00, .phy = &px30_win2_data, | |
326 | .type = DRM_PLANE_TYPE_CURSOR }, | |
327 | }; | |
328 | ||
329 | static const struct vop_data px30_vop_big = { | |
872b68e9 | 330 | .version = VOP_VERSION(2, 6), |
570913e0 | 331 | .intr = &px30_intr, |
8d544233 | 332 | .feature = VOP_FEATURE_INTERNAL_RGB, |
570913e0 SH |
333 | .common = &px30_common, |
334 | .modeset = &px30_modeset, | |
335 | .output = &px30_output, | |
336 | .win = px30_vop_big_win_data, | |
337 | .win_size = ARRAY_SIZE(px30_vop_big_win_data), | |
338 | }; | |
339 | ||
340 | static const struct vop_win_data px30_vop_lit_win_data[] = { | |
341 | { .base = 0x00, .phy = &px30_win1_data, | |
342 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
343 | }; | |
344 | ||
345 | static const struct vop_data px30_vop_lit = { | |
872b68e9 | 346 | .version = VOP_VERSION(2, 5), |
570913e0 | 347 | .intr = &px30_intr, |
8d544233 | 348 | .feature = VOP_FEATURE_INTERNAL_RGB, |
570913e0 SH |
349 | .common = &px30_common, |
350 | .modeset = &px30_modeset, | |
351 | .output = &px30_output, | |
352 | .win = px30_vop_lit_win_data, | |
353 | .win_size = ARRAY_SIZE(px30_vop_lit_win_data), | |
354 | }; | |
355 | ||
f4a6de85 MY |
356 | static const struct vop_scl_regs rk3066_win_scl = { |
357 | .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
358 | .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
359 | .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
360 | .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
361 | }; | |
362 | ||
363 | static const struct vop_win_phy rk3066_win0_data = { | |
364 | .scl = &rk3066_win_scl, | |
365 | .data_formats = formats_win_full, | |
366 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 367 | .format_modifiers = format_modifiers_win_full, |
f4a6de85 | 368 | .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0), |
742203cd AB |
369 | .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4), |
370 | .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19), | |
f4a6de85 MY |
371 | .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0), |
372 | .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
373 | .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0), | |
374 | .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0), | |
375 | .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0), | |
376 | .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0), | |
377 | .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16), | |
d099fa67 AB |
378 | .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 21), |
379 | .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 0), | |
f4a6de85 MY |
380 | }; |
381 | ||
382 | static const struct vop_win_phy rk3066_win1_data = { | |
f4a6de85 MY |
383 | .data_formats = formats_win_full, |
384 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 385 | .format_modifiers = format_modifiers_win_full, |
f4a6de85 | 386 | .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1), |
742203cd AB |
387 | .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7), |
388 | .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23), | |
f4a6de85 MY |
389 | .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0), |
390 | .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0), | |
391 | .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0), | |
392 | .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0), | |
393 | .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0), | |
394 | .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0), | |
395 | .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16), | |
d099fa67 AB |
396 | .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 22), |
397 | .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 1), | |
f4a6de85 MY |
398 | }; |
399 | ||
400 | static const struct vop_win_phy rk3066_win2_data = { | |
401 | .data_formats = formats_win_lite, | |
402 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 403 | .format_modifiers = format_modifiers_win_lite, |
f4a6de85 | 404 | .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2), |
742203cd AB |
405 | .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10), |
406 | .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27), | |
f4a6de85 MY |
407 | .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0), |
408 | .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0), | |
409 | .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0), | |
410 | .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0), | |
d099fa67 AB |
411 | .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 23), |
412 | .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 2), | |
f4a6de85 MY |
413 | }; |
414 | ||
415 | static const struct vop_modeset rk3066_modeset = { | |
416 | .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), | |
417 | .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
418 | .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
419 | .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
420 | }; | |
421 | ||
422 | static const struct vop_output rk3066_output = { | |
423 | .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4), | |
424 | }; | |
425 | ||
426 | static const struct vop_common rk3066_common = { | |
427 | .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1), | |
428 | .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0), | |
429 | .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0), | |
a5c0fa44 UR |
430 | .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11), |
431 | .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10), | |
f4a6de85 | 432 | .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24), |
742203cd AB |
433 | .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9), |
434 | .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31), | |
435 | .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25), | |
f4a6de85 MY |
436 | }; |
437 | ||
438 | static const struct vop_win_data rk3066_vop_win_data[] = { | |
439 | { .base = 0x00, .phy = &rk3066_win0_data, | |
440 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
441 | { .base = 0x00, .phy = &rk3066_win1_data, | |
442 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
443 | { .base = 0x00, .phy = &rk3066_win2_data, | |
444 | .type = DRM_PLANE_TYPE_CURSOR }, | |
445 | }; | |
446 | ||
447 | static const int rk3066_vop_intrs[] = { | |
448 | /* | |
449 | * hs_start interrupt fires at frame-start, so serves | |
450 | * the same purpose as dsp_hold in the driver. | |
451 | */ | |
452 | DSP_HOLD_VALID_INTR, | |
453 | FS_INTR, | |
454 | LINE_FLAG_INTR, | |
455 | BUS_ERROR_INTR, | |
456 | }; | |
457 | ||
458 | static const struct vop_intr rk3066_intr = { | |
459 | .intrs = rk3066_vop_intrs, | |
460 | .nintrs = ARRAY_SIZE(rk3066_vop_intrs), | |
461 | .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12), | |
462 | .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0), | |
463 | .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4), | |
464 | .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8), | |
465 | }; | |
466 | ||
467 | static const struct vop_data rk3066_vop = { | |
468 | .version = VOP_VERSION(2, 1), | |
469 | .intr = &rk3066_intr, | |
470 | .common = &rk3066_common, | |
471 | .modeset = &rk3066_modeset, | |
472 | .output = &rk3066_output, | |
473 | .win = rk3066_vop_win_data, | |
474 | .win_size = ARRAY_SIZE(rk3066_vop_win_data), | |
475 | }; | |
476 | ||
428e15cc HS |
477 | static const struct vop_scl_regs rk3188_win_scl = { |
478 | .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
479 | .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
480 | .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
481 | .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
482 | }; | |
483 | ||
484 | static const struct vop_win_phy rk3188_win0_data = { | |
485 | .scl = &rk3188_win_scl, | |
486 | .data_formats = formats_win_full, | |
487 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 488 | .format_modifiers = format_modifiers_win_full, |
428e15cc HS |
489 | .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0), |
490 | .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3), | |
491 | .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15), | |
492 | .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0), | |
493 | .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
494 | .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0), | |
495 | .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0), | |
496 | .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0), | |
497 | .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0), | |
d099fa67 AB |
498 | .alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 18), |
499 | .alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 0), | |
500 | .alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29), | |
428e15cc HS |
501 | }; |
502 | ||
503 | static const struct vop_win_phy rk3188_win1_data = { | |
504 | .data_formats = formats_win_lite, | |
505 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 506 | .format_modifiers = format_modifiers_win_lite, |
428e15cc HS |
507 | .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1), |
508 | .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6), | |
509 | .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19), | |
510 | /* no act_info on window1 */ | |
511 | .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0), | |
512 | .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0), | |
513 | .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0), | |
514 | .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16), | |
d099fa67 AB |
515 | .alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 19), |
516 | .alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 1), | |
517 | .alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29), | |
428e15cc HS |
518 | }; |
519 | ||
520 | static const struct vop_modeset rk3188_modeset = { | |
521 | .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), | |
522 | .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0), | |
523 | .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), | |
524 | .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0), | |
525 | }; | |
526 | ||
527 | static const struct vop_output rk3188_output = { | |
528 | .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4), | |
529 | }; | |
530 | ||
531 | static const struct vop_common rk3188_common = { | |
532 | .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31), | |
533 | .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30), | |
534 | .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0), | |
535 | .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0), | |
a5c0fa44 UR |
536 | .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27), |
537 | .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11), | |
538 | .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10), | |
ab64b448 AB |
539 | .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24), |
540 | .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9), | |
541 | .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28), | |
542 | .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25), | |
428e15cc HS |
543 | }; |
544 | ||
545 | static const struct vop_win_data rk3188_vop_win_data[] = { | |
546 | { .base = 0x00, .phy = &rk3188_win0_data, | |
547 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
548 | { .base = 0x00, .phy = &rk3188_win1_data, | |
549 | .type = DRM_PLANE_TYPE_CURSOR }, | |
550 | }; | |
551 | ||
552 | static const int rk3188_vop_intrs[] = { | |
4f297df8 HS |
553 | /* |
554 | * hs_start interrupt fires at frame-start, so serves | |
555 | * the same purpose as dsp_hold in the driver. | |
556 | */ | |
557 | DSP_HOLD_VALID_INTR, | |
428e15cc HS |
558 | FS_INTR, |
559 | LINE_FLAG_INTR, | |
560 | BUS_ERROR_INTR, | |
561 | }; | |
562 | ||
563 | static const struct vop_intr rk3188_vop_intr = { | |
564 | .intrs = rk3188_vop_intrs, | |
565 | .nintrs = ARRAY_SIZE(rk3188_vop_intrs), | |
566 | .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12), | |
567 | .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0), | |
568 | .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4), | |
569 | .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8), | |
570 | }; | |
571 | ||
572 | static const struct vop_data rk3188_vop = { | |
573 | .intr = &rk3188_vop_intr, | |
574 | .common = &rk3188_common, | |
575 | .modeset = &rk3188_modeset, | |
576 | .output = &rk3188_output, | |
577 | .win = rk3188_vop_win_data, | |
578 | .win_size = ARRAY_SIZE(rk3188_vop_win_data), | |
579 | .feature = VOP_FEATURE_INTERNAL_RGB, | |
580 | }; | |
581 | ||
f7673453 MY |
582 | static const struct vop_scl_extension rk3288_win_full_scl_ext = { |
583 | .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), | |
584 | .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), | |
585 | .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28), | |
586 | .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26), | |
587 | .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24), | |
588 | .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23), | |
589 | .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22), | |
590 | .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20), | |
591 | .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18), | |
592 | .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16), | |
593 | .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15), | |
594 | .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12), | |
595 | .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8), | |
596 | .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7), | |
597 | .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6), | |
598 | .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5), | |
599 | .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4), | |
600 | .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2), | |
601 | .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1), | |
602 | .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0), | |
603 | .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5), | |
604 | }; | |
605 | ||
606 | static const struct vop_scl_regs rk3288_win_full_scl = { | |
607 | .ext = &rk3288_win_full_scl_ext, | |
608 | .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
609 | .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
610 | .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
611 | .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
612 | }; | |
613 | ||
614 | static const struct vop_win_phy rk3288_win01_data = { | |
615 | .scl = &rk3288_win_full_scl, | |
616 | .data_formats = formats_win_full, | |
617 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 618 | .format_modifiers = format_modifiers_win_full, |
f7673453 MY |
619 | .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), |
620 | .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), | |
621 | .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), | |
622 | .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), | |
623 | .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
624 | .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), | |
625 | .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), | |
626 | .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), | |
627 | .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), | |
628 | .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), | |
629 | .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), | |
630 | .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), | |
9dd2aca4 | 631 | .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), |
f7673453 MY |
632 | }; |
633 | ||
634 | static const struct vop_win_phy rk3288_win23_data = { | |
635 | .data_formats = formats_win_lite, | |
636 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 637 | .format_modifiers = format_modifiers_win_lite, |
60b7ae7f MY |
638 | .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4), |
639 | .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0), | |
f7673453 MY |
640 | .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1), |
641 | .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12), | |
642 | .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0), | |
643 | .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0), | |
644 | .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0), | |
645 | .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0), | |
646 | .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0), | |
647 | .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0), | |
648 | }; | |
649 | ||
9a61c54b MY |
650 | static const struct vop_modeset rk3288_modeset = { |
651 | .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), | |
652 | .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
653 | .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
654 | .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
655 | .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0), | |
656 | .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0), | |
657 | }; | |
658 | ||
659 | static const struct vop_output rk3288_output = { | |
660 | .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4), | |
f7673453 MY |
661 | .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), |
662 | .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), | |
663 | .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), | |
664 | .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), | |
9a61c54b MY |
665 | }; |
666 | ||
667 | static const struct vop_common rk3288_common = { | |
668 | .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22), | |
669 | .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23), | |
670 | .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20), | |
a5c0fa44 UR |
671 | .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4), |
672 | .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3), | |
673 | .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2), | |
6bda8112 | 674 | .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1), |
f7673453 | 675 | .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6), |
b23ab6ac | 676 | .dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0), |
f7673453 | 677 | .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19), |
60b7ae7f | 678 | .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), |
f7673453 | 679 | .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0), |
9548e1b4 | 680 | .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), |
f7673453 MY |
681 | }; |
682 | ||
a67719d1 MY |
683 | /* |
684 | * Note: rk3288 has a dedicated 'cursor' window, however, that window requires | |
685 | * special support to get alpha blending working. For now, just use overlay | |
686 | * window 3 for the drm cursor. | |
687 | * | |
688 | */ | |
689 | static const struct vop_win_data rk3288_vop_win_data[] = { | |
f7673453 MY |
690 | { .base = 0x00, .phy = &rk3288_win01_data, |
691 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
692 | { .base = 0x40, .phy = &rk3288_win01_data, | |
693 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
694 | { .base = 0x00, .phy = &rk3288_win23_data, | |
695 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
696 | { .base = 0x50, .phy = &rk3288_win23_data, | |
697 | .type = DRM_PLANE_TYPE_CURSOR }, | |
a67719d1 MY |
698 | }; |
699 | ||
700 | static const int rk3288_vop_intrs[] = { | |
701 | DSP_HOLD_VALID_INTR, | |
702 | FS_INTR, | |
703 | LINE_FLAG_INTR, | |
704 | BUS_ERROR_INTR, | |
705 | }; | |
706 | ||
707 | static const struct vop_intr rk3288_vop_intr = { | |
708 | .intrs = rk3288_vop_intrs, | |
709 | .nintrs = ARRAY_SIZE(rk3288_vop_intrs), | |
ac6560df | 710 | .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12), |
f7673453 MY |
711 | .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0), |
712 | .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4), | |
713 | .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8), | |
a67719d1 MY |
714 | }; |
715 | ||
716 | static const struct vop_data rk3288_vop = { | |
eb5cb6aa | 717 | .version = VOP_VERSION(3, 1), |
efd11cc8 | 718 | .feature = VOP_FEATURE_OUTPUT_RGB10, |
a67719d1 | 719 | .intr = &rk3288_vop_intr, |
9a61c54b MY |
720 | .common = &rk3288_common, |
721 | .modeset = &rk3288_modeset, | |
722 | .output = &rk3288_output, | |
a67719d1 MY |
723 | .win = rk3288_vop_win_data, |
724 | .win_size = ARRAY_SIZE(rk3288_vop_win_data), | |
b23ab6ac | 725 | .lut_size = 1024, |
a67719d1 MY |
726 | }; |
727 | ||
eb5cb6aa | 728 | static const int rk3368_vop_intrs[] = { |
f7673453 | 729 | FS_INTR, |
0a63bfd0 | 730 | 0, 0, |
f7673453 | 731 | LINE_FLAG_INTR, |
0a63bfd0 | 732 | 0, |
f7673453 | 733 | BUS_ERROR_INTR, |
0a63bfd0 MY |
734 | 0, 0, 0, 0, 0, 0, 0, |
735 | DSP_HOLD_VALID_INTR, | |
f7673453 MY |
736 | }; |
737 | ||
eb5cb6aa MY |
738 | static const struct vop_intr rk3368_vop_intr = { |
739 | .intrs = rk3368_vop_intrs, | |
740 | .nintrs = ARRAY_SIZE(rk3368_vop_intrs), | |
741 | .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0), | |
742 | .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16), | |
743 | .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0), | |
744 | .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0), | |
745 | .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0), | |
746 | }; | |
747 | ||
fbb1c738 EG |
748 | static const struct vop_win_phy rk3368_win01_data = { |
749 | .scl = &rk3288_win_full_scl, | |
750 | .data_formats = formats_win_full, | |
751 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 752 | .format_modifiers = format_modifiers_win_full, |
fbb1c738 EG |
753 | .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0), |
754 | .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1), | |
755 | .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12), | |
677e8bbc DC |
756 | .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21), |
757 | .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22), | |
fbb1c738 EG |
758 | .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0), |
759 | .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
760 | .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0), | |
761 | .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0), | |
762 | .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0), | |
763 | .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0), | |
764 | .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16), | |
765 | .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0), | |
766 | .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0), | |
767 | .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0), | |
768 | }; | |
769 | ||
eb5cb6aa MY |
770 | static const struct vop_win_phy rk3368_win23_data = { |
771 | .data_formats = formats_win_lite, | |
772 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 773 | .format_modifiers = format_modifiers_win_lite, |
eb5cb6aa MY |
774 | .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0), |
775 | .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4), | |
776 | .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5), | |
777 | .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20), | |
677e8bbc | 778 | .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15), |
eb5cb6aa MY |
779 | .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0), |
780 | .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0), | |
781 | .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0), | |
782 | .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0), | |
783 | .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0), | |
784 | .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0), | |
785 | }; | |
786 | ||
787 | static const struct vop_win_data rk3368_vop_win_data[] = { | |
fbb1c738 | 788 | { .base = 0x00, .phy = &rk3368_win01_data, |
eb5cb6aa | 789 | .type = DRM_PLANE_TYPE_PRIMARY }, |
fbb1c738 | 790 | { .base = 0x40, .phy = &rk3368_win01_data, |
eb5cb6aa MY |
791 | .type = DRM_PLANE_TYPE_OVERLAY }, |
792 | { .base = 0x00, .phy = &rk3368_win23_data, | |
793 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
794 | { .base = 0x50, .phy = &rk3368_win23_data, | |
795 | .type = DRM_PLANE_TYPE_CURSOR }, | |
796 | }; | |
797 | ||
798 | static const struct vop_output rk3368_output = { | |
1f6c62ca NY |
799 | .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19), |
800 | .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23), | |
801 | .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27), | |
802 | .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31), | |
803 | .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16), | |
804 | .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20), | |
805 | .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24), | |
806 | .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28), | |
eb5cb6aa MY |
807 | .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), |
808 | .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), | |
809 | .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), | |
810 | .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), | |
811 | }; | |
812 | ||
813 | static const struct vop_misc rk3368_misc = { | |
814 | .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11), | |
815 | }; | |
816 | ||
817 | static const struct vop_data rk3368_vop = { | |
818 | .version = VOP_VERSION(3, 2), | |
819 | .intr = &rk3368_vop_intr, | |
820 | .common = &rk3288_common, | |
821 | .modeset = &rk3288_modeset, | |
822 | .output = &rk3368_output, | |
823 | .misc = &rk3368_misc, | |
824 | .win = rk3368_vop_win_data, | |
825 | .win_size = ARRAY_SIZE(rk3368_vop_win_data), | |
826 | }; | |
827 | ||
828 | static const struct vop_intr rk3366_vop_intr = { | |
829 | .intrs = rk3368_vop_intrs, | |
830 | .nintrs = ARRAY_SIZE(rk3368_vop_intrs), | |
831 | .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0), | |
832 | .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16), | |
833 | .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0), | |
834 | .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0), | |
835 | .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0), | |
836 | }; | |
837 | ||
838 | static const struct vop_data rk3366_vop = { | |
839 | .version = VOP_VERSION(3, 4), | |
840 | .intr = &rk3366_vop_intr, | |
841 | .common = &rk3288_common, | |
842 | .modeset = &rk3288_modeset, | |
843 | .output = &rk3368_output, | |
844 | .misc = &rk3368_misc, | |
845 | .win = rk3368_vop_win_data, | |
846 | .win_size = ARRAY_SIZE(rk3368_vop_win_data), | |
f7673453 MY |
847 | }; |
848 | ||
9a61c54b | 849 | static const struct vop_output rk3399_output = { |
1f6c62ca NY |
850 | .dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19), |
851 | .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19), | |
852 | .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23), | |
853 | .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27), | |
854 | .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31), | |
855 | .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16), | |
856 | .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16), | |
857 | .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20), | |
858 | .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24), | |
859 | .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28), | |
9a61c54b MY |
860 | .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11), |
861 | .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), | |
862 | .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), | |
863 | .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), | |
864 | .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), | |
cf6d100d | 865 | .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3), |
9a61c54b MY |
866 | }; |
867 | ||
1c21aa8f DC |
868 | static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = { |
869 | .y2r_coefficients = { | |
870 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0), | |
871 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16), | |
872 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0), | |
873 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16), | |
874 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0), | |
875 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16), | |
876 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0), | |
877 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16), | |
878 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0), | |
879 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0), | |
880 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0), | |
881 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0), | |
882 | }, | |
883 | }; | |
884 | ||
885 | static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { }; | |
886 | ||
887 | static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = { | |
888 | { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data, | |
889 | .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) }, | |
890 | { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data, | |
891 | .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) }, | |
892 | { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data }, | |
893 | { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data }, | |
7707f722 AP |
894 | |
895 | }; | |
896 | ||
897 | static const struct vop_win_phy rk3399_win01_data = { | |
898 | .scl = &rk3288_win_full_scl, | |
899 | .data_formats = formats_win_full, | |
900 | .nformats = ARRAY_SIZE(formats_win_full), | |
901 | .format_modifiers = format_modifiers_win_full_afbc, | |
902 | .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), | |
903 | .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), | |
904 | .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), | |
0c144079 | 905 | .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21), |
7707f722 AP |
906 | .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22), |
907 | .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), | |
908 | .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
909 | .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), | |
910 | .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), | |
911 | .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), | |
912 | .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), | |
913 | .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), | |
914 | .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), | |
915 | .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), | |
0c144079 | 916 | .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), |
7707f722 AP |
917 | }; |
918 | ||
919 | /* | |
920 | * rk3399 vop big windows register layout is same as rk3288, but we | |
921 | * have a separate rk3399 win data array here so that we can advertise | |
922 | * AFBC on the primary plane. | |
923 | */ | |
924 | static const struct vop_win_data rk3399_vop_win_data[] = { | |
925 | { .base = 0x00, .phy = &rk3399_win01_data, | |
926 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
0c144079 | 927 | { .base = 0x40, .phy = &rk3368_win01_data, |
7707f722 | 928 | .type = DRM_PLANE_TYPE_OVERLAY }, |
0c144079 | 929 | { .base = 0x00, .phy = &rk3368_win23_data, |
7707f722 | 930 | .type = DRM_PLANE_TYPE_OVERLAY }, |
0c144079 | 931 | { .base = 0x50, .phy = &rk3368_win23_data, |
7707f722 AP |
932 | .type = DRM_PLANE_TYPE_CURSOR }, |
933 | }; | |
934 | ||
935 | static const struct vop_afbc rk3399_vop_afbc = { | |
936 | .rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3), | |
937 | .enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0), | |
938 | .win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1), | |
939 | .format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16), | |
940 | .hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21), | |
941 | .hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0), | |
942 | .pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0), | |
1c21aa8f DC |
943 | }; |
944 | ||
0a63bfd0 | 945 | static const struct vop_data rk3399_vop_big = { |
eb5cb6aa | 946 | .version = VOP_VERSION(3, 5), |
efd11cc8 | 947 | .feature = VOP_FEATURE_OUTPUT_RGB10, |
eb5cb6aa | 948 | .intr = &rk3366_vop_intr, |
9a61c54b MY |
949 | .common = &rk3288_common, |
950 | .modeset = &rk3288_modeset, | |
951 | .output = &rk3399_output, | |
7707f722 | 952 | .afbc = &rk3399_vop_afbc, |
eb5cb6aa | 953 | .misc = &rk3368_misc, |
7707f722 AP |
954 | .win = rk3399_vop_win_data, |
955 | .win_size = ARRAY_SIZE(rk3399_vop_win_data), | |
1c21aa8f | 956 | .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data, |
f7673453 MY |
957 | }; |
958 | ||
0a63bfd0 | 959 | static const struct vop_win_data rk3399_vop_lit_win_data[] = { |
fbb1c738 | 960 | { .base = 0x00, .phy = &rk3368_win01_data, |
0a63bfd0 | 961 | .type = DRM_PLANE_TYPE_PRIMARY }, |
eb5cb6aa | 962 | { .base = 0x00, .phy = &rk3368_win23_data, |
0a63bfd0 MY |
963 | .type = DRM_PLANE_TYPE_CURSOR}, |
964 | }; | |
965 | ||
1c21aa8f DC |
966 | static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = { |
967 | { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data, | |
968 | .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)}, | |
969 | { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data }, | |
970 | }; | |
971 | ||
0a63bfd0 | 972 | static const struct vop_data rk3399_vop_lit = { |
eb5cb6aa MY |
973 | .version = VOP_VERSION(3, 6), |
974 | .intr = &rk3366_vop_intr, | |
9a61c54b MY |
975 | .common = &rk3288_common, |
976 | .modeset = &rk3288_modeset, | |
977 | .output = &rk3399_output, | |
eb5cb6aa | 978 | .misc = &rk3368_misc, |
0a63bfd0 MY |
979 | .win = rk3399_vop_lit_win_data, |
980 | .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data), | |
1c21aa8f | 981 | .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data, |
f7673453 MY |
982 | }; |
983 | ||
eb5cb6aa MY |
984 | static const struct vop_win_data rk3228_vop_win_data[] = { |
985 | { .base = 0x00, .phy = &rk3288_win01_data, | |
986 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
987 | { .base = 0x40, .phy = &rk3288_win01_data, | |
988 | .type = DRM_PLANE_TYPE_CURSOR }, | |
989 | }; | |
990 | ||
991 | static const struct vop_data rk3228_vop = { | |
992 | .version = VOP_VERSION(3, 7), | |
993 | .feature = VOP_FEATURE_OUTPUT_RGB10, | |
994 | .intr = &rk3366_vop_intr, | |
995 | .common = &rk3288_common, | |
996 | .modeset = &rk3288_modeset, | |
997 | .output = &rk3399_output, | |
998 | .misc = &rk3368_misc, | |
999 | .win = rk3228_vop_win_data, | |
1000 | .win_size = ARRAY_SIZE(rk3228_vop_win_data), | |
1001 | }; | |
1002 | ||
1003 | static const struct vop_modeset rk3328_modeset = { | |
1004 | .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), | |
1005 | .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
1006 | .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
1007 | .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
1008 | .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0), | |
1009 | .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0), | |
1010 | }; | |
1011 | ||
1012 | static const struct vop_output rk3328_output = { | |
1f6c62ca NY |
1013 | .rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19), |
1014 | .hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23), | |
1015 | .edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27), | |
1016 | .mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31), | |
eb5cb6aa MY |
1017 | .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12), |
1018 | .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13), | |
1019 | .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14), | |
1020 | .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15), | |
1f6c62ca NY |
1021 | .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16), |
1022 | .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20), | |
1023 | .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24), | |
1024 | .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28), | |
eb5cb6aa MY |
1025 | }; |
1026 | ||
1027 | static const struct vop_misc rk3328_misc = { | |
1028 | .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11), | |
1029 | }; | |
1030 | ||
1031 | static const struct vop_common rk3328_common = { | |
1032 | .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22), | |
a5c0fa44 UR |
1033 | .dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4), |
1034 | .dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3), | |
1035 | .dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2), | |
1036 | .pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1), | |
eb5cb6aa MY |
1037 | .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6), |
1038 | .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18), | |
1039 | .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), | |
1040 | .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), | |
1041 | }; | |
1042 | ||
1043 | static const struct vop_intr rk3328_vop_intr = { | |
1044 | .intrs = rk3368_vop_intrs, | |
1045 | .nintrs = ARRAY_SIZE(rk3368_vop_intrs), | |
1046 | .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0), | |
1047 | .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16), | |
1048 | .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0), | |
1049 | .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0), | |
1050 | .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0), | |
1051 | }; | |
1052 | ||
1053 | static const struct vop_win_data rk3328_vop_win_data[] = { | |
fbb1c738 | 1054 | { .base = 0xd0, .phy = &rk3368_win01_data, |
eb5cb6aa | 1055 | .type = DRM_PLANE_TYPE_PRIMARY }, |
fbb1c738 | 1056 | { .base = 0x1d0, .phy = &rk3368_win01_data, |
eb5cb6aa | 1057 | .type = DRM_PLANE_TYPE_OVERLAY }, |
fbb1c738 | 1058 | { .base = 0x2d0, .phy = &rk3368_win01_data, |
eb5cb6aa MY |
1059 | .type = DRM_PLANE_TYPE_CURSOR }, |
1060 | }; | |
1061 | ||
1062 | static const struct vop_data rk3328_vop = { | |
1063 | .version = VOP_VERSION(3, 8), | |
1064 | .feature = VOP_FEATURE_OUTPUT_RGB10, | |
1065 | .intr = &rk3328_vop_intr, | |
1066 | .common = &rk3328_common, | |
1067 | .modeset = &rk3328_modeset, | |
1068 | .output = &rk3328_output, | |
1069 | .misc = &rk3328_misc, | |
1070 | .win = rk3328_vop_win_data, | |
1071 | .win_size = ARRAY_SIZE(rk3328_vop_win_data), | |
1072 | }; | |
1073 | ||
a67719d1 | 1074 | static const struct of_device_id vop_driver_dt_match[] = { |
f7673453 MY |
1075 | { .compatible = "rockchip,rk3036-vop", |
1076 | .data = &rk3036_vop }, | |
460c3b00 SH |
1077 | { .compatible = "rockchip,rk3126-vop", |
1078 | .data = &rk3126_vop }, | |
570913e0 SH |
1079 | { .compatible = "rockchip,px30-vop-big", |
1080 | .data = &px30_vop_big }, | |
1081 | { .compatible = "rockchip,px30-vop-lit", | |
1082 | .data = &px30_vop_lit }, | |
f4a6de85 MY |
1083 | { .compatible = "rockchip,rk3066-vop", |
1084 | .data = &rk3066_vop }, | |
428e15cc HS |
1085 | { .compatible = "rockchip,rk3188-vop", |
1086 | .data = &rk3188_vop }, | |
b51502ad MY |
1087 | { .compatible = "rockchip,rk3288-vop", |
1088 | .data = &rk3288_vop }, | |
eb5cb6aa MY |
1089 | { .compatible = "rockchip,rk3368-vop", |
1090 | .data = &rk3368_vop }, | |
1091 | { .compatible = "rockchip,rk3366-vop", | |
1092 | .data = &rk3366_vop }, | |
0a63bfd0 MY |
1093 | { .compatible = "rockchip,rk3399-vop-big", |
1094 | .data = &rk3399_vop_big }, | |
1095 | { .compatible = "rockchip,rk3399-vop-lit", | |
1096 | .data = &rk3399_vop_lit }, | |
eb5cb6aa MY |
1097 | { .compatible = "rockchip,rk3228-vop", |
1098 | .data = &rk3228_vop }, | |
1099 | { .compatible = "rockchip,rk3328-vop", | |
1100 | .data = &rk3328_vop }, | |
a67719d1 MY |
1101 | {}, |
1102 | }; | |
1103 | MODULE_DEVICE_TABLE(of, vop_driver_dt_match); | |
1104 | ||
1105 | static int vop_probe(struct platform_device *pdev) | |
1106 | { | |
1107 | struct device *dev = &pdev->dev; | |
1108 | ||
1109 | if (!dev->of_node) { | |
d8dd6804 | 1110 | DRM_DEV_ERROR(dev, "can't find vop devices\n"); |
a67719d1 MY |
1111 | return -ENODEV; |
1112 | } | |
1113 | ||
1114 | return component_add(dev, &vop_component_ops); | |
1115 | } | |
1116 | ||
1117 | static int vop_remove(struct platform_device *pdev) | |
1118 | { | |
1119 | component_del(&pdev->dev, &vop_component_ops); | |
1120 | ||
1121 | return 0; | |
1122 | } | |
1123 | ||
8820b68b | 1124 | struct platform_driver vop_platform_driver = { |
a67719d1 MY |
1125 | .probe = vop_probe, |
1126 | .remove = vop_remove, | |
1127 | .driver = { | |
1128 | .name = "rockchip-vop", | |
a67719d1 MY |
1129 | .of_match_table = of_match_ptr(vop_driver_dt_match), |
1130 | }, | |
1131 | }; |