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