drm/rockchip: Separate RK3288 from RK3368 win01 registers
[linux-2.6-microblaze.git] / drivers / gpu / drm / rockchip / rockchip_vop_reg.c
1 /*
2  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3  * Author:Mark Yao <mark.yao@rock-chips.com>
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <drm/drmP.h>
16
17 #include <linux/kernel.h>
18 #include <linux/component.h>
19
20 #include "rockchip_drm_vop.h"
21 #include "rockchip_vop_reg.h"
22
23 #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
24                 { \
25                  .offset = off, \
26                  .mask = _mask, \
27                  .shift = _shift, \
28                  .write_mask = _write_mask, \
29                  .relaxed = _relaxed, \
30                 }
31
32 #define VOP_REG(off, _mask, _shift) \
33                 _VOP_REG(off, _mask, _shift, false, true)
34
35 #define VOP_REG_SYNC(off, _mask, _shift) \
36                 _VOP_REG(off, _mask, _shift, false, false)
37
38 #define VOP_REG_MASK_SYNC(off, _mask, _shift) \
39                 _VOP_REG(off, _mask, _shift, true, false)
40
41 static const uint32_t formats_win_full[] = {
42         DRM_FORMAT_XRGB8888,
43         DRM_FORMAT_ARGB8888,
44         DRM_FORMAT_XBGR8888,
45         DRM_FORMAT_ABGR8888,
46         DRM_FORMAT_RGB888,
47         DRM_FORMAT_BGR888,
48         DRM_FORMAT_RGB565,
49         DRM_FORMAT_BGR565,
50         DRM_FORMAT_NV12,
51         DRM_FORMAT_NV16,
52         DRM_FORMAT_NV24,
53 };
54
55 static const uint32_t formats_win_lite[] = {
56         DRM_FORMAT_XRGB8888,
57         DRM_FORMAT_ARGB8888,
58         DRM_FORMAT_XBGR8888,
59         DRM_FORMAT_ABGR8888,
60         DRM_FORMAT_RGB888,
61         DRM_FORMAT_BGR888,
62         DRM_FORMAT_RGB565,
63         DRM_FORMAT_BGR565,
64 };
65
66 static const struct vop_scl_regs rk3036_win_scl = {
67         .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
68         .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
69         .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
70         .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
71 };
72
73 static const struct vop_win_phy rk3036_win0_data = {
74         .scl = &rk3036_win_scl,
75         .data_formats = formats_win_full,
76         .nformats = ARRAY_SIZE(formats_win_full),
77         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
78         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
79         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
80         .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
81         .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
82         .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
83         .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
84         .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
85         .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
86         .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
87 };
88
89 static const struct vop_win_phy rk3036_win1_data = {
90         .data_formats = formats_win_lite,
91         .nformats = ARRAY_SIZE(formats_win_lite),
92         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
93         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
94         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
95         .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
96         .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
97         .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
98         .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
99         .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
100 };
101
102 static const struct vop_win_data rk3036_vop_win_data[] = {
103         { .base = 0x00, .phy = &rk3036_win0_data,
104           .type = DRM_PLANE_TYPE_PRIMARY },
105         { .base = 0x00, .phy = &rk3036_win1_data,
106           .type = DRM_PLANE_TYPE_CURSOR },
107 };
108
109 static const int rk3036_vop_intrs[] = {
110         DSP_HOLD_VALID_INTR,
111         FS_INTR,
112         LINE_FLAG_INTR,
113         BUS_ERROR_INTR,
114 };
115
116 static const struct vop_intr rk3036_intr = {
117         .intrs = rk3036_vop_intrs,
118         .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
119         .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
120         .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
121         .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
122         .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
123 };
124
125 static const struct vop_modeset rk3036_modeset = {
126         .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
127         .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
128         .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
129         .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
130 };
131
132 static const struct vop_output rk3036_output = {
133         .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
134 };
135
136 static const struct vop_common rk3036_common = {
137         .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
138         .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
139         .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
140         .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
141 };
142
143 static const struct vop_data rk3036_vop = {
144         .intr = &rk3036_intr,
145         .common = &rk3036_common,
146         .modeset = &rk3036_modeset,
147         .output = &rk3036_output,
148         .win = rk3036_vop_win_data,
149         .win_size = ARRAY_SIZE(rk3036_vop_win_data),
150 };
151
152 static const struct vop_win_phy rk3126_win1_data = {
153         .data_formats = formats_win_lite,
154         .nformats = ARRAY_SIZE(formats_win_lite),
155         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
156         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
157         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
158         .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
159         .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
160         .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
161         .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
162 };
163
164 static const struct vop_win_data rk3126_vop_win_data[] = {
165         { .base = 0x00, .phy = &rk3036_win0_data,
166           .type = DRM_PLANE_TYPE_PRIMARY },
167         { .base = 0x00, .phy = &rk3126_win1_data,
168           .type = DRM_PLANE_TYPE_CURSOR },
169 };
170
171 static const struct vop_data rk3126_vop = {
172         .intr = &rk3036_intr,
173         .common = &rk3036_common,
174         .modeset = &rk3036_modeset,
175         .output = &rk3036_output,
176         .win = rk3126_vop_win_data,
177         .win_size = ARRAY_SIZE(rk3126_vop_win_data),
178 };
179
180 static const int px30_vop_intrs[] = {
181         FS_INTR,
182         0, 0,
183         LINE_FLAG_INTR,
184         0,
185         BUS_ERROR_INTR,
186         0, 0,
187         DSP_HOLD_VALID_INTR,
188 };
189
190 static const struct vop_intr px30_intr = {
191         .intrs = px30_vop_intrs,
192         .nintrs = ARRAY_SIZE(px30_vop_intrs),
193         .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
194         .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
195         .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
196         .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
197 };
198
199 static const struct vop_common px30_common = {
200         .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
201         .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
202         .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
203         .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
204 };
205
206 static const struct vop_modeset px30_modeset = {
207         .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
208         .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
209         .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
210         .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
211 };
212
213 static const struct vop_output px30_output = {
214         .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 1),
215         .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 25),
216         .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
217         .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
218 };
219
220 static const struct vop_scl_regs px30_win_scl = {
221         .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
222         .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
223         .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
224         .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
225 };
226
227 static const struct vop_win_phy px30_win0_data = {
228         .scl = &px30_win_scl,
229         .data_formats = formats_win_full,
230         .nformats = ARRAY_SIZE(formats_win_full),
231         .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
232         .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
233         .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
234         .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
235         .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
236         .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
237         .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
238         .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
239         .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
240         .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
241 };
242
243 static const struct vop_win_phy px30_win1_data = {
244         .data_formats = formats_win_lite,
245         .nformats = ARRAY_SIZE(formats_win_lite),
246         .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
247         .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
248         .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
249         .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
250         .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
251         .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
252         .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
253 };
254
255 static const struct vop_win_phy px30_win2_data = {
256         .data_formats = formats_win_lite,
257         .nformats = ARRAY_SIZE(formats_win_lite),
258         .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
259         .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
260         .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
261         .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
262         .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
263         .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
264         .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
265         .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
266 };
267
268 static const struct vop_win_data px30_vop_big_win_data[] = {
269         { .base = 0x00, .phy = &px30_win0_data,
270           .type = DRM_PLANE_TYPE_PRIMARY },
271         { .base = 0x00, .phy = &px30_win1_data,
272           .type = DRM_PLANE_TYPE_OVERLAY },
273         { .base = 0x00, .phy = &px30_win2_data,
274           .type = DRM_PLANE_TYPE_CURSOR },
275 };
276
277 static const struct vop_data px30_vop_big = {
278         .intr = &px30_intr,
279         .feature = VOP_FEATURE_INTERNAL_RGB,
280         .common = &px30_common,
281         .modeset = &px30_modeset,
282         .output = &px30_output,
283         .win = px30_vop_big_win_data,
284         .win_size = ARRAY_SIZE(px30_vop_big_win_data),
285 };
286
287 static const struct vop_win_data px30_vop_lit_win_data[] = {
288         { .base = 0x00, .phy = &px30_win1_data,
289           .type = DRM_PLANE_TYPE_PRIMARY },
290 };
291
292 static const struct vop_data px30_vop_lit = {
293         .intr = &px30_intr,
294         .feature = VOP_FEATURE_INTERNAL_RGB,
295         .common = &px30_common,
296         .modeset = &px30_modeset,
297         .output = &px30_output,
298         .win = px30_vop_lit_win_data,
299         .win_size = ARRAY_SIZE(px30_vop_lit_win_data),
300 };
301
302 static const struct vop_scl_regs rk3188_win_scl = {
303         .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
304         .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
305         .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
306         .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
307 };
308
309 static const struct vop_win_phy rk3188_win0_data = {
310         .scl = &rk3188_win_scl,
311         .data_formats = formats_win_full,
312         .nformats = ARRAY_SIZE(formats_win_full),
313         .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
314         .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
315         .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
316         .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
317         .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
318         .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
319         .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
320         .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
321         .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
322 };
323
324 static const struct vop_win_phy rk3188_win1_data = {
325         .data_formats = formats_win_lite,
326         .nformats = ARRAY_SIZE(formats_win_lite),
327         .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
328         .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
329         .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
330         /* no act_info on window1 */
331         .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
332         .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
333         .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
334         .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
335 };
336
337 static const struct vop_modeset rk3188_modeset = {
338         .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
339         .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
340         .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
341         .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
342 };
343
344 static const struct vop_output rk3188_output = {
345         .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
346 };
347
348 static const struct vop_common rk3188_common = {
349         .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
350         .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
351         .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
352         .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
353         .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24),
354 };
355
356 static const struct vop_win_data rk3188_vop_win_data[] = {
357         { .base = 0x00, .phy = &rk3188_win0_data,
358           .type = DRM_PLANE_TYPE_PRIMARY },
359         { .base = 0x00, .phy = &rk3188_win1_data,
360           .type = DRM_PLANE_TYPE_CURSOR },
361 };
362
363 static const int rk3188_vop_intrs[] = {
364         /*
365          * hs_start interrupt fires at frame-start, so serves
366          * the same purpose as dsp_hold in the driver.
367          */
368         DSP_HOLD_VALID_INTR,
369         FS_INTR,
370         LINE_FLAG_INTR,
371         BUS_ERROR_INTR,
372 };
373
374 static const struct vop_intr rk3188_vop_intr = {
375         .intrs = rk3188_vop_intrs,
376         .nintrs = ARRAY_SIZE(rk3188_vop_intrs),
377         .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
378         .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
379         .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
380         .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
381 };
382
383 static const struct vop_data rk3188_vop = {
384         .intr = &rk3188_vop_intr,
385         .common = &rk3188_common,
386         .modeset = &rk3188_modeset,
387         .output = &rk3188_output,
388         .win = rk3188_vop_win_data,
389         .win_size = ARRAY_SIZE(rk3188_vop_win_data),
390         .feature = VOP_FEATURE_INTERNAL_RGB,
391 };
392
393 static const struct vop_scl_extension rk3288_win_full_scl_ext = {
394         .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
395         .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
396         .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
397         .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
398         .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
399         .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
400         .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
401         .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
402         .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
403         .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
404         .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
405         .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
406         .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
407         .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
408         .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
409         .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
410         .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
411         .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
412         .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
413         .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
414         .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
415 };
416
417 static const struct vop_scl_regs rk3288_win_full_scl = {
418         .ext = &rk3288_win_full_scl_ext,
419         .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
420         .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
421         .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
422         .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
423 };
424
425 static const struct vop_win_phy rk3288_win01_data = {
426         .scl = &rk3288_win_full_scl,
427         .data_formats = formats_win_full,
428         .nformats = ARRAY_SIZE(formats_win_full),
429         .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
430         .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
431         .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
432         .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
433         .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
434         .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
435         .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
436         .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
437         .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
438         .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
439         .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
440         .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
441         .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
442 };
443
444 static const struct vop_win_phy rk3288_win23_data = {
445         .data_formats = formats_win_lite,
446         .nformats = ARRAY_SIZE(formats_win_lite),
447         .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
448         .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
449         .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
450         .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
451         .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
452         .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
453         .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
454         .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
455         .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
456         .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
457 };
458
459 static const struct vop_modeset rk3288_modeset = {
460         .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
461         .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
462         .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
463         .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
464         .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
465         .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
466 };
467
468 static const struct vop_output rk3288_output = {
469         .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
470         .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
471         .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
472         .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
473         .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
474 };
475
476 static const struct vop_common rk3288_common = {
477         .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
478         .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
479         .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
480         .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
481         .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
482         .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
483         .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
484         .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
485         .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
486         .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
487 };
488
489 /*
490  * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
491  * special support to get alpha blending working.  For now, just use overlay
492  * window 3 for the drm cursor.
493  *
494  */
495 static const struct vop_win_data rk3288_vop_win_data[] = {
496         { .base = 0x00, .phy = &rk3288_win01_data,
497           .type = DRM_PLANE_TYPE_PRIMARY },
498         { .base = 0x40, .phy = &rk3288_win01_data,
499           .type = DRM_PLANE_TYPE_OVERLAY },
500         { .base = 0x00, .phy = &rk3288_win23_data,
501           .type = DRM_PLANE_TYPE_OVERLAY },
502         { .base = 0x50, .phy = &rk3288_win23_data,
503           .type = DRM_PLANE_TYPE_CURSOR },
504 };
505
506 static const int rk3288_vop_intrs[] = {
507         DSP_HOLD_VALID_INTR,
508         FS_INTR,
509         LINE_FLAG_INTR,
510         BUS_ERROR_INTR,
511 };
512
513 static const struct vop_intr rk3288_vop_intr = {
514         .intrs = rk3288_vop_intrs,
515         .nintrs = ARRAY_SIZE(rk3288_vop_intrs),
516         .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
517         .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
518         .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
519         .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
520 };
521
522 static const struct vop_data rk3288_vop = {
523         .version = VOP_VERSION(3, 1),
524         .feature = VOP_FEATURE_OUTPUT_RGB10,
525         .intr = &rk3288_vop_intr,
526         .common = &rk3288_common,
527         .modeset = &rk3288_modeset,
528         .output = &rk3288_output,
529         .win = rk3288_vop_win_data,
530         .win_size = ARRAY_SIZE(rk3288_vop_win_data),
531 };
532
533 static const int rk3368_vop_intrs[] = {
534         FS_INTR,
535         0, 0,
536         LINE_FLAG_INTR,
537         0,
538         BUS_ERROR_INTR,
539         0, 0, 0, 0, 0, 0, 0,
540         DSP_HOLD_VALID_INTR,
541 };
542
543 static const struct vop_intr rk3368_vop_intr = {
544         .intrs = rk3368_vop_intrs,
545         .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
546         .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
547         .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
548         .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
549         .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
550         .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
551 };
552
553 static const struct vop_win_phy rk3368_win01_data = {
554         .scl = &rk3288_win_full_scl,
555         .data_formats = formats_win_full,
556         .nformats = ARRAY_SIZE(formats_win_full),
557         .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
558         .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
559         .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
560         .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
561         .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
562         .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
563         .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
564         .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
565         .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
566         .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
567         .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
568         .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
569         .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
570 };
571
572 static const struct vop_win_phy rk3368_win23_data = {
573         .data_formats = formats_win_lite,
574         .nformats = ARRAY_SIZE(formats_win_lite),
575         .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
576         .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
577         .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
578         .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
579         .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
580         .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
581         .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
582         .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
583         .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
584         .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
585 };
586
587 static const struct vop_win_data rk3368_vop_win_data[] = {
588         { .base = 0x00, .phy = &rk3368_win01_data,
589           .type = DRM_PLANE_TYPE_PRIMARY },
590         { .base = 0x40, .phy = &rk3368_win01_data,
591           .type = DRM_PLANE_TYPE_OVERLAY },
592         { .base = 0x00, .phy = &rk3368_win23_data,
593           .type = DRM_PLANE_TYPE_OVERLAY },
594         { .base = 0x50, .phy = &rk3368_win23_data,
595           .type = DRM_PLANE_TYPE_CURSOR },
596 };
597
598 static const struct vop_output rk3368_output = {
599         .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
600         .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
601         .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
602         .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
603         .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
604         .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
605         .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
606         .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
607 };
608
609 static const struct vop_misc rk3368_misc = {
610         .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
611 };
612
613 static const struct vop_data rk3368_vop = {
614         .version = VOP_VERSION(3, 2),
615         .intr = &rk3368_vop_intr,
616         .common = &rk3288_common,
617         .modeset = &rk3288_modeset,
618         .output = &rk3368_output,
619         .misc = &rk3368_misc,
620         .win = rk3368_vop_win_data,
621         .win_size = ARRAY_SIZE(rk3368_vop_win_data),
622 };
623
624 static const struct vop_intr rk3366_vop_intr = {
625         .intrs = rk3368_vop_intrs,
626         .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
627         .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
628         .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
629         .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
630         .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
631         .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
632 };
633
634 static const struct vop_data rk3366_vop = {
635         .version = VOP_VERSION(3, 4),
636         .intr = &rk3366_vop_intr,
637         .common = &rk3288_common,
638         .modeset = &rk3288_modeset,
639         .output = &rk3368_output,
640         .misc = &rk3368_misc,
641         .win = rk3368_vop_win_data,
642         .win_size = ARRAY_SIZE(rk3368_vop_win_data),
643 };
644
645 static const struct vop_output rk3399_output = {
646         .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
647         .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
648         .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
649         .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
650         .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
651         .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
652         .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
653         .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
654         .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
655         .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
656         .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
657 };
658
659 static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
660         .y2r_coefficients = {
661                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
662                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
663                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
664                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
665                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
666                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
667                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
668                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
669                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
670                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
671                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
672                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
673         },
674 };
675
676 static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
677
678 static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
679         { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
680           .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
681         { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
682           .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
683         { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
684         { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
685 };
686
687 static const struct vop_data rk3399_vop_big = {
688         .version = VOP_VERSION(3, 5),
689         .feature = VOP_FEATURE_OUTPUT_RGB10,
690         .intr = &rk3366_vop_intr,
691         .common = &rk3288_common,
692         .modeset = &rk3288_modeset,
693         .output = &rk3399_output,
694         .misc = &rk3368_misc,
695         .win = rk3368_vop_win_data,
696         .win_size = ARRAY_SIZE(rk3368_vop_win_data),
697         .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
698 };
699
700 static const struct vop_win_data rk3399_vop_lit_win_data[] = {
701         { .base = 0x00, .phy = &rk3368_win01_data,
702           .type = DRM_PLANE_TYPE_PRIMARY },
703         { .base = 0x00, .phy = &rk3368_win23_data,
704           .type = DRM_PLANE_TYPE_CURSOR},
705 };
706
707 static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
708         { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
709           .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
710         { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
711 };
712
713 static const struct vop_data rk3399_vop_lit = {
714         .version = VOP_VERSION(3, 6),
715         .intr = &rk3366_vop_intr,
716         .common = &rk3288_common,
717         .modeset = &rk3288_modeset,
718         .output = &rk3399_output,
719         .misc = &rk3368_misc,
720         .win = rk3399_vop_lit_win_data,
721         .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
722         .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
723 };
724
725 static const struct vop_win_data rk3228_vop_win_data[] = {
726         { .base = 0x00, .phy = &rk3288_win01_data,
727           .type = DRM_PLANE_TYPE_PRIMARY },
728         { .base = 0x40, .phy = &rk3288_win01_data,
729           .type = DRM_PLANE_TYPE_CURSOR },
730 };
731
732 static const struct vop_data rk3228_vop = {
733         .version = VOP_VERSION(3, 7),
734         .feature = VOP_FEATURE_OUTPUT_RGB10,
735         .intr = &rk3366_vop_intr,
736         .common = &rk3288_common,
737         .modeset = &rk3288_modeset,
738         .output = &rk3399_output,
739         .misc = &rk3368_misc,
740         .win = rk3228_vop_win_data,
741         .win_size = ARRAY_SIZE(rk3228_vop_win_data),
742 };
743
744 static const struct vop_modeset rk3328_modeset = {
745         .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
746         .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
747         .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
748         .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
749         .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
750         .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
751 };
752
753 static const struct vop_output rk3328_output = {
754         .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
755         .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
756         .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
757         .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
758         .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16),
759         .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20),
760         .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24),
761         .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28),
762 };
763
764 static const struct vop_misc rk3328_misc = {
765         .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
766 };
767
768 static const struct vop_common rk3328_common = {
769         .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
770         .dither_down = VOP_REG(RK3328_DSP_CTRL1, 0xf, 1),
771         .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
772         .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
773         .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
774         .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
775 };
776
777 static const struct vop_intr rk3328_vop_intr = {
778         .intrs = rk3368_vop_intrs,
779         .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
780         .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
781         .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
782         .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
783         .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
784         .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
785 };
786
787 static const struct vop_win_data rk3328_vop_win_data[] = {
788         { .base = 0xd0, .phy = &rk3368_win01_data,
789           .type = DRM_PLANE_TYPE_PRIMARY },
790         { .base = 0x1d0, .phy = &rk3368_win01_data,
791           .type = DRM_PLANE_TYPE_OVERLAY },
792         { .base = 0x2d0, .phy = &rk3368_win01_data,
793           .type = DRM_PLANE_TYPE_CURSOR },
794 };
795
796 static const struct vop_data rk3328_vop = {
797         .version = VOP_VERSION(3, 8),
798         .feature = VOP_FEATURE_OUTPUT_RGB10,
799         .intr = &rk3328_vop_intr,
800         .common = &rk3328_common,
801         .modeset = &rk3328_modeset,
802         .output = &rk3328_output,
803         .misc = &rk3328_misc,
804         .win = rk3328_vop_win_data,
805         .win_size = ARRAY_SIZE(rk3328_vop_win_data),
806 };
807
808 static const struct of_device_id vop_driver_dt_match[] = {
809         { .compatible = "rockchip,rk3036-vop",
810           .data = &rk3036_vop },
811         { .compatible = "rockchip,rk3126-vop",
812           .data = &rk3126_vop },
813         { .compatible = "rockchip,px30-vop-big",
814           .data = &px30_vop_big },
815         { .compatible = "rockchip,px30-vop-lit",
816           .data = &px30_vop_lit },
817         { .compatible = "rockchip,rk3188-vop",
818           .data = &rk3188_vop },
819         { .compatible = "rockchip,rk3288-vop",
820           .data = &rk3288_vop },
821         { .compatible = "rockchip,rk3368-vop",
822           .data = &rk3368_vop },
823         { .compatible = "rockchip,rk3366-vop",
824           .data = &rk3366_vop },
825         { .compatible = "rockchip,rk3399-vop-big",
826           .data = &rk3399_vop_big },
827         { .compatible = "rockchip,rk3399-vop-lit",
828           .data = &rk3399_vop_lit },
829         { .compatible = "rockchip,rk3228-vop",
830           .data = &rk3228_vop },
831         { .compatible = "rockchip,rk3328-vop",
832           .data = &rk3328_vop },
833         {},
834 };
835 MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
836
837 static int vop_probe(struct platform_device *pdev)
838 {
839         struct device *dev = &pdev->dev;
840
841         if (!dev->of_node) {
842                 DRM_DEV_ERROR(dev, "can't find vop devices\n");
843                 return -ENODEV;
844         }
845
846         return component_add(dev, &vop_component_ops);
847 }
848
849 static int vop_remove(struct platform_device *pdev)
850 {
851         component_del(&pdev->dev, &vop_component_ops);
852
853         return 0;
854 }
855
856 struct platform_driver vop_platform_driver = {
857         .probe = vop_probe,
858         .remove = vop_remove,
859         .driver = {
860                 .name = "rockchip-vop",
861                 .of_match_table = of_match_ptr(vop_driver_dt_match),
862         },
863 };