]> Git Repo - linux.git/blob - drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[linux.git] / drivers / gpu / drm / rockchip / rockchip_drm_vop2.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4  * Author: Andy Yan <[email protected]>
5  */
6 #include <linux/bitfield.h>
7 #include <linux/clk.h>
8 #include <linux/component.h>
9 #include <linux/delay.h>
10 #include <linux/iopoll.h>
11 #include <linux/kernel.h>
12 #include <linux/media-bus-format.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_device.h>
17 #include <linux/of_graph.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
21 #include <linux/swab.h>
22
23 #include <drm/drm.h>
24 #include <drm/drm_atomic.h>
25 #include <drm/drm_atomic_uapi.h>
26 #include <drm/drm_blend.h>
27 #include <drm/drm_crtc.h>
28 #include <drm/drm_debugfs.h>
29 #include <drm/drm_flip_work.h>
30 #include <drm/drm_framebuffer.h>
31 #include <drm/drm_probe_helper.h>
32 #include <drm/drm_vblank.h>
33
34 #include <uapi/linux/videodev2.h>
35 #include <dt-bindings/soc/rockchip,vop2.h>
36
37 #include "rockchip_drm_drv.h"
38 #include "rockchip_drm_gem.h"
39 #include "rockchip_drm_fb.h"
40 #include "rockchip_drm_vop2.h"
41 #include "rockchip_rgb.h"
42
43 /*
44  * VOP2 architecture
45  *
46  +----------+   +-------------+                                                        +-----------+
47  |  Cluster |   | Sel 1 from 6|                                                        | 1 from 3  |
48  |  window0 |   |    Layer0   |                                                        |    RGB    |
49  +----------+   +-------------+              +---------------+    +-------------+      +-----------+
50  +----------+   +-------------+              |N from 6 layers|    |             |
51  |  Cluster |   | Sel 1 from 6|              |   Overlay0    +--->| Video Port0 |      +-----------+
52  |  window1 |   |    Layer1   |              |               |    |             |      | 1 from 3  |
53  +----------+   +-------------+              +---------------+    +-------------+      |   LVDS    |
54  +----------+   +-------------+                                                        +-----------+
55  |  Esmart  |   | Sel 1 from 6|
56  |  window0 |   |   Layer2    |              +---------------+    +-------------+      +-----------+
57  +----------+   +-------------+              |N from 6 Layers|    |             | +--> | 1 from 3  |
58  +----------+   +-------------+   -------->  |   Overlay1    +--->| Video Port1 |      |   MIPI    |
59  |  Esmart  |   | Sel 1 from 6|   -------->  |               |    |             |      +-----------+
60  |  Window1 |   |   Layer3    |              +---------------+    +-------------+
61  +----------+   +-------------+                                                        +-----------+
62  +----------+   +-------------+                                                        | 1 from 3  |
63  |  Smart   |   | Sel 1 from 6|              +---------------+    +-------------+      |   HDMI    |
64  |  Window0 |   |    Layer4   |              |N from 6 Layers|    |             |      +-----------+
65  +----------+   +-------------+              |   Overlay2    +--->| Video Port2 |
66  +----------+   +-------------+              |               |    |             |      +-----------+
67  |  Smart   |   | Sel 1 from 6|              +---------------+    +-------------+      |  1 from 3 |
68  |  Window1 |   |    Layer5   |                                                        |    eDP    |
69  +----------+   +-------------+                                                        +-----------+
70  *
71  */
72
73 enum vop2_data_format {
74         VOP2_FMT_ARGB8888 = 0,
75         VOP2_FMT_RGB888,
76         VOP2_FMT_RGB565,
77         VOP2_FMT_XRGB101010,
78         VOP2_FMT_YUV420SP,
79         VOP2_FMT_YUV422SP,
80         VOP2_FMT_YUV444SP,
81         VOP2_FMT_YUYV422 = 8,
82         VOP2_FMT_YUYV420,
83         VOP2_FMT_VYUY422,
84         VOP2_FMT_VYUY420,
85         VOP2_FMT_YUV420SP_TILE_8x4 = 0x10,
86         VOP2_FMT_YUV420SP_TILE_16x2,
87         VOP2_FMT_YUV422SP_TILE_8x4,
88         VOP2_FMT_YUV422SP_TILE_16x2,
89         VOP2_FMT_YUV420SP_10,
90         VOP2_FMT_YUV422SP_10,
91         VOP2_FMT_YUV444SP_10,
92 };
93
94 enum vop2_afbc_format {
95         VOP2_AFBC_FMT_RGB565,
96         VOP2_AFBC_FMT_ARGB2101010 = 2,
97         VOP2_AFBC_FMT_YUV420_10BIT,
98         VOP2_AFBC_FMT_RGB888,
99         VOP2_AFBC_FMT_ARGB8888,
100         VOP2_AFBC_FMT_YUV420 = 9,
101         VOP2_AFBC_FMT_YUV422 = 0xb,
102         VOP2_AFBC_FMT_YUV422_10BIT = 0xe,
103         VOP2_AFBC_FMT_INVALID = -1,
104 };
105
106 union vop2_alpha_ctrl {
107         u32 val;
108         struct {
109                 /* [0:1] */
110                 u32 color_mode:1;
111                 u32 alpha_mode:1;
112                 /* [2:3] */
113                 u32 blend_mode:2;
114                 u32 alpha_cal_mode:1;
115                 /* [5:7] */
116                 u32 factor_mode:3;
117                 /* [8:9] */
118                 u32 alpha_en:1;
119                 u32 src_dst_swap:1;
120                 u32 reserved:6;
121                 /* [16:23] */
122                 u32 glb_alpha:8;
123         } bits;
124 };
125
126 struct vop2_alpha {
127         union vop2_alpha_ctrl src_color_ctrl;
128         union vop2_alpha_ctrl dst_color_ctrl;
129         union vop2_alpha_ctrl src_alpha_ctrl;
130         union vop2_alpha_ctrl dst_alpha_ctrl;
131 };
132
133 struct vop2_alpha_config {
134         bool src_premulti_en;
135         bool dst_premulti_en;
136         bool src_pixel_alpha_en;
137         bool dst_pixel_alpha_en;
138         u16 src_glb_alpha_value;
139         u16 dst_glb_alpha_value;
140 };
141
142 struct vop2_win {
143         struct vop2 *vop2;
144         struct drm_plane base;
145         const struct vop2_win_data *data;
146         struct regmap_field *reg[VOP2_WIN_MAX_REG];
147
148         /**
149          * @win_id: graphic window id, a cluster may be split into two
150          * graphics windows.
151          */
152         u8 win_id;
153         u8 delay;
154         u32 offset;
155
156         enum drm_plane_type type;
157 };
158
159 struct vop2_video_port {
160         struct drm_crtc crtc;
161         struct vop2 *vop2;
162         struct clk *dclk;
163         unsigned int id;
164         const struct vop2_video_port_regs *regs;
165         const struct vop2_video_port_data *data;
166
167         struct completion dsp_hold_completion;
168
169         /**
170          * @win_mask: Bitmask of windows attached to the video port;
171          */
172         u32 win_mask;
173
174         struct vop2_win *primary_plane;
175         struct drm_pending_vblank_event *event;
176
177         unsigned int nlayers;
178 };
179
180 struct vop2 {
181         struct device *dev;
182         struct drm_device *drm;
183         struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
184
185         const struct vop2_data *data;
186         /*
187          * Number of windows that are registered as plane, may be less than the
188          * total number of hardware windows.
189          */
190         u32 registered_num_wins;
191
192         void __iomem *regs;
193         struct regmap *map;
194
195         struct regmap *grf;
196
197         /* physical map length of vop2 register */
198         u32 len;
199
200         void __iomem *lut_regs;
201
202         /* protects crtc enable/disable */
203         struct mutex vop2_lock;
204
205         int irq;
206
207         /*
208          * Some global resources are shared between all video ports(crtcs), so
209          * we need a ref counter here.
210          */
211         unsigned int enable_count;
212         struct clk *hclk;
213         struct clk *aclk;
214
215         /* optional internal rgb encoder */
216         struct rockchip_rgb *rgb;
217
218         /* must be put at the end of the struct */
219         struct vop2_win win[];
220 };
221
222 static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
223 {
224         return container_of(crtc, struct vop2_video_port, crtc);
225 }
226
227 static struct vop2_win *to_vop2_win(struct drm_plane *p)
228 {
229         return container_of(p, struct vop2_win, base);
230 }
231
232 static void vop2_lock(struct vop2 *vop2)
233 {
234         mutex_lock(&vop2->vop2_lock);
235 }
236
237 static void vop2_unlock(struct vop2 *vop2)
238 {
239         mutex_unlock(&vop2->vop2_lock);
240 }
241
242 static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
243 {
244         regmap_write(vop2->map, offset, v);
245 }
246
247 static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
248 {
249         regmap_write(vp->vop2->map, vp->data->offset + offset, v);
250 }
251
252 static u32 vop2_readl(struct vop2 *vop2, u32 offset)
253 {
254         u32 val;
255
256         regmap_read(vop2->map, offset, &val);
257
258         return val;
259 }
260
261 static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
262 {
263         regmap_field_write(win->reg[reg], v);
264 }
265
266 static bool vop2_cluster_window(const struct vop2_win *win)
267 {
268         return win->data->feature & WIN_FEATURE_CLUSTER;
269 }
270
271 static void vop2_cfg_done(struct vop2_video_port *vp)
272 {
273         struct vop2 *vop2 = vp->vop2;
274
275         regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE,
276                         BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
277 }
278
279 static void vop2_win_disable(struct vop2_win *win)
280 {
281         vop2_win_write(win, VOP2_WIN_ENABLE, 0);
282
283         if (vop2_cluster_window(win))
284                 vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0);
285 }
286
287 static enum vop2_data_format vop2_convert_format(u32 format)
288 {
289         switch (format) {
290         case DRM_FORMAT_XRGB8888:
291         case DRM_FORMAT_ARGB8888:
292         case DRM_FORMAT_XBGR8888:
293         case DRM_FORMAT_ABGR8888:
294                 return VOP2_FMT_ARGB8888;
295         case DRM_FORMAT_RGB888:
296         case DRM_FORMAT_BGR888:
297                 return VOP2_FMT_RGB888;
298         case DRM_FORMAT_RGB565:
299         case DRM_FORMAT_BGR565:
300                 return VOP2_FMT_RGB565;
301         case DRM_FORMAT_NV12:
302                 return VOP2_FMT_YUV420SP;
303         case DRM_FORMAT_NV16:
304                 return VOP2_FMT_YUV422SP;
305         case DRM_FORMAT_NV24:
306                 return VOP2_FMT_YUV444SP;
307         case DRM_FORMAT_YUYV:
308         case DRM_FORMAT_YVYU:
309                 return VOP2_FMT_VYUY422;
310         case DRM_FORMAT_VYUY:
311         case DRM_FORMAT_UYVY:
312                 return VOP2_FMT_YUYV422;
313         default:
314                 DRM_ERROR("unsupported format[%08x]\n", format);
315                 return -EINVAL;
316         }
317 }
318
319 static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
320 {
321         switch (format) {
322         case DRM_FORMAT_XRGB8888:
323         case DRM_FORMAT_ARGB8888:
324         case DRM_FORMAT_XBGR8888:
325         case DRM_FORMAT_ABGR8888:
326                 return VOP2_AFBC_FMT_ARGB8888;
327         case DRM_FORMAT_RGB888:
328         case DRM_FORMAT_BGR888:
329                 return VOP2_AFBC_FMT_RGB888;
330         case DRM_FORMAT_RGB565:
331         case DRM_FORMAT_BGR565:
332                 return VOP2_AFBC_FMT_RGB565;
333         case DRM_FORMAT_NV12:
334                 return VOP2_AFBC_FMT_YUV420;
335         case DRM_FORMAT_NV16:
336                 return VOP2_AFBC_FMT_YUV422;
337         default:
338                 return VOP2_AFBC_FMT_INVALID;
339         }
340
341         return VOP2_AFBC_FMT_INVALID;
342 }
343
344 static bool vop2_win_rb_swap(u32 format)
345 {
346         switch (format) {
347         case DRM_FORMAT_XBGR8888:
348         case DRM_FORMAT_ABGR8888:
349         case DRM_FORMAT_BGR888:
350         case DRM_FORMAT_BGR565:
351                 return true;
352         default:
353                 return false;
354         }
355 }
356
357 static bool vop2_afbc_rb_swap(u32 format)
358 {
359         switch (format) {
360         case DRM_FORMAT_NV24:
361                 return true;
362         default:
363                 return false;
364         }
365 }
366
367 static bool vop2_afbc_uv_swap(u32 format)
368 {
369         switch (format) {
370         case DRM_FORMAT_NV12:
371         case DRM_FORMAT_NV16:
372                 return true;
373         default:
374                 return false;
375         }
376 }
377
378 static bool vop2_win_uv_swap(u32 format)
379 {
380         switch (format) {
381         case DRM_FORMAT_NV12:
382         case DRM_FORMAT_NV16:
383         case DRM_FORMAT_NV24:
384                 return true;
385         default:
386                 return false;
387         }
388 }
389
390 static bool vop2_win_dither_up(u32 format)
391 {
392         switch (format) {
393         case DRM_FORMAT_BGR565:
394         case DRM_FORMAT_RGB565:
395                 return true;
396         default:
397                 return false;
398         }
399 }
400
401 static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
402 {
403         /*
404          * FIXME:
405          *
406          * There is no media type for YUV444 output,
407          * so when out_mode is AAAA or P888, assume output is YUV444 on
408          * yuv format.
409          *
410          * From H/W testing, YUV444 mode need a rb swap.
411          */
412         if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
413             bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
414             bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
415             bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
416             ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
417               bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
418              (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
419               output_mode == ROCKCHIP_OUT_MODE_P888)))
420                 return true;
421         else
422                 return false;
423 }
424
425 static bool is_yuv_output(u32 bus_format)
426 {
427         switch (bus_format) {
428         case MEDIA_BUS_FMT_YUV8_1X24:
429         case MEDIA_BUS_FMT_YUV10_1X30:
430         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
431         case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
432         case MEDIA_BUS_FMT_YUYV8_2X8:
433         case MEDIA_BUS_FMT_YVYU8_2X8:
434         case MEDIA_BUS_FMT_UYVY8_2X8:
435         case MEDIA_BUS_FMT_VYUY8_2X8:
436         case MEDIA_BUS_FMT_YUYV8_1X16:
437         case MEDIA_BUS_FMT_YVYU8_1X16:
438         case MEDIA_BUS_FMT_UYVY8_1X16:
439         case MEDIA_BUS_FMT_VYUY8_1X16:
440                 return true;
441         default:
442                 return false;
443         }
444 }
445
446 static bool rockchip_afbc(struct drm_plane *plane, u64 modifier)
447 {
448         int i;
449
450         if (modifier == DRM_FORMAT_MOD_LINEAR)
451                 return false;
452
453         for (i = 0 ; i < plane->modifier_count; i++)
454                 if (plane->modifiers[i] == modifier)
455                         return true;
456
457         return false;
458 }
459
460 static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
461                                         u64 modifier)
462 {
463         struct vop2_win *win = to_vop2_win(plane);
464         struct vop2 *vop2 = win->vop2;
465
466         if (modifier == DRM_FORMAT_MOD_INVALID)
467                 return false;
468
469         if (modifier == DRM_FORMAT_MOD_LINEAR)
470                 return true;
471
472         if (!rockchip_afbc(plane, modifier)) {
473                 drm_err(vop2->drm, "Unsupported format modifier 0x%llx\n",
474                         modifier);
475
476                 return false;
477         }
478
479         return vop2_convert_afbc_format(format) >= 0;
480 }
481
482 static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate,
483                                       bool afbc_half_block_en)
484 {
485         struct drm_rect *src = &pstate->src;
486         struct drm_framebuffer *fb = pstate->fb;
487         u32 bpp = fb->format->cpp[0] * 8;
488         u32 vir_width = (fb->pitches[0] << 3) / bpp;
489         u32 width = drm_rect_width(src) >> 16;
490         u32 height = drm_rect_height(src) >> 16;
491         u32 act_xoffset = src->x1 >> 16;
492         u32 act_yoffset = src->y1 >> 16;
493         u32 align16_crop = 0;
494         u32 align64_crop = 0;
495         u32 height_tmp;
496         u8 tx, ty;
497         u8 bottom_crop_line_num = 0;
498
499         /* 16 pixel align */
500         if (height & 0xf)
501                 align16_crop = 16 - (height & 0xf);
502
503         height_tmp = height + align16_crop;
504
505         /* 64 pixel align */
506         if (height_tmp & 0x3f)
507                 align64_crop = 64 - (height_tmp & 0x3f);
508
509         bottom_crop_line_num = align16_crop + align64_crop;
510
511         switch (pstate->rotation &
512                 (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y |
513                  DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270)) {
514         case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y:
515                 tx = 16 - ((act_xoffset + width) & 0xf);
516                 ty = bottom_crop_line_num - act_yoffset;
517                 break;
518         case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90:
519                 tx = bottom_crop_line_num - act_yoffset;
520                 ty = vir_width - width - act_xoffset;
521                 break;
522         case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270:
523                 tx = act_yoffset;
524                 ty = act_xoffset;
525                 break;
526         case DRM_MODE_REFLECT_X:
527                 tx = 16 - ((act_xoffset + width) & 0xf);
528                 ty = act_yoffset;
529                 break;
530         case DRM_MODE_REFLECT_Y:
531                 tx = act_xoffset;
532                 ty = bottom_crop_line_num - act_yoffset;
533                 break;
534         case DRM_MODE_ROTATE_90:
535                 tx = bottom_crop_line_num - act_yoffset;
536                 ty = act_xoffset;
537                 break;
538         case DRM_MODE_ROTATE_270:
539                 tx = act_yoffset;
540                 ty = vir_width - width - act_xoffset;
541                 break;
542         case 0:
543                 tx = act_xoffset;
544                 ty = act_yoffset;
545                 break;
546         }
547
548         if (afbc_half_block_en)
549                 ty &= 0x7f;
550
551 #define TRANSFORM_XOFFSET GENMASK(7, 0)
552 #define TRANSFORM_YOFFSET GENMASK(23, 16)
553         return FIELD_PREP(TRANSFORM_XOFFSET, tx) |
554                 FIELD_PREP(TRANSFORM_YOFFSET, ty);
555 }
556
557 /*
558  * A Cluster window has 2048 x 16 line buffer, which can
559  * works at 2048 x 16(Full) or 4096 x 8 (Half) mode.
560  * for Cluster_lb_mode register:
561  * 0: half mode, for plane input width range 2048 ~ 4096
562  * 1: half mode, for cluster work at 2 * 2048 plane mode
563  * 2: half mode, for rotate_90/270 mode
564  *
565  */
566 static int vop2_get_cluster_lb_mode(struct vop2_win *win,
567                                     struct drm_plane_state *pstate)
568 {
569         if ((pstate->rotation & DRM_MODE_ROTATE_270) ||
570             (pstate->rotation & DRM_MODE_ROTATE_90))
571                 return 2;
572         else
573                 return 0;
574 }
575
576 static u16 vop2_scale_factor(u32 src, u32 dst)
577 {
578         u32 fac;
579         int shift;
580
581         if (src == dst)
582                 return 0;
583
584         if (dst < 2)
585                 return U16_MAX;
586
587         if (src < 2)
588                 return 0;
589
590         if (src > dst)
591                 shift = 12;
592         else
593                 shift = 16;
594
595         src--;
596         dst--;
597
598         fac = DIV_ROUND_UP(src << shift, dst) - 1;
599
600         if (fac > U16_MAX)
601                 return U16_MAX;
602
603         return fac;
604 }
605
606 static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win,
607                              u32 src_w, u32 src_h, u32 dst_w,
608                              u32 dst_h, u32 pixel_format)
609 {
610         const struct drm_format_info *info;
611         u16 hor_scl_mode, ver_scl_mode;
612         u16 hscl_filter_mode, vscl_filter_mode;
613         u8 gt2 = 0;
614         u8 gt4 = 0;
615         u32 val;
616
617         info = drm_format_info(pixel_format);
618
619         if (src_h >= (4 * dst_h)) {
620                 gt4 = 1;
621                 src_h >>= 2;
622         } else if (src_h >= (2 * dst_h)) {
623                 gt2 = 1;
624                 src_h >>= 1;
625         }
626
627         hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
628         ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
629
630         if (hor_scl_mode == SCALE_UP)
631                 hscl_filter_mode = VOP2_SCALE_UP_BIC;
632         else
633                 hscl_filter_mode = VOP2_SCALE_DOWN_BIL;
634
635         if (ver_scl_mode == SCALE_UP)
636                 vscl_filter_mode = VOP2_SCALE_UP_BIL;
637         else
638                 vscl_filter_mode = VOP2_SCALE_DOWN_BIL;
639
640         /*
641          * RK3568 VOP Esmart/Smart dsp_w should be even pixel
642          * at scale down mode
643          */
644         if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
645                 if ((hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) {
646                         drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n",
647                                 win->data->name, dst_w);
648                         dst_w++;
649                 }
650         }
651
652         val = vop2_scale_factor(src_w, dst_w);
653         vop2_win_write(win, VOP2_WIN_SCALE_YRGB_X, val);
654         val = vop2_scale_factor(src_h, dst_h);
655         vop2_win_write(win, VOP2_WIN_SCALE_YRGB_Y, val);
656
657         vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT4, gt4);
658         vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT2, gt2);
659
660         vop2_win_write(win, VOP2_WIN_YRGB_HOR_SCL_MODE, hor_scl_mode);
661         vop2_win_write(win, VOP2_WIN_YRGB_VER_SCL_MODE, ver_scl_mode);
662
663         if (vop2_cluster_window(win))
664                 return;
665
666         vop2_win_write(win, VOP2_WIN_YRGB_HSCL_FILTER_MODE, hscl_filter_mode);
667         vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode);
668
669         if (info->is_yuv) {
670                 src_w /= info->hsub;
671                 src_h /= info->vsub;
672
673                 gt4 = 0;
674                 gt2 = 0;
675
676                 if (src_h >= (4 * dst_h)) {
677                         gt4 = 1;
678                         src_h >>= 2;
679                 } else if (src_h >= (2 * dst_h)) {
680                         gt2 = 1;
681                         src_h >>= 1;
682                 }
683
684                 hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
685                 ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
686
687                 val = vop2_scale_factor(src_w, dst_w);
688                 vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val);
689
690                 val = vop2_scale_factor(src_h, dst_h);
691                 vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val);
692
693                 vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4);
694                 vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT2, gt2);
695                 vop2_win_write(win, VOP2_WIN_CBCR_HOR_SCL_MODE, hor_scl_mode);
696                 vop2_win_write(win, VOP2_WIN_CBCR_VER_SCL_MODE, ver_scl_mode);
697                 vop2_win_write(win, VOP2_WIN_CBCR_HSCL_FILTER_MODE, hscl_filter_mode);
698                 vop2_win_write(win, VOP2_WIN_CBCR_VSCL_FILTER_MODE, vscl_filter_mode);
699         }
700 }
701
702 static int vop2_convert_csc_mode(int csc_mode)
703 {
704         switch (csc_mode) {
705         case V4L2_COLORSPACE_SMPTE170M:
706         case V4L2_COLORSPACE_470_SYSTEM_M:
707         case V4L2_COLORSPACE_470_SYSTEM_BG:
708                 return CSC_BT601L;
709         case V4L2_COLORSPACE_REC709:
710         case V4L2_COLORSPACE_SMPTE240M:
711         case V4L2_COLORSPACE_DEFAULT:
712                 return CSC_BT709L;
713         case V4L2_COLORSPACE_JPEG:
714                 return CSC_BT601F;
715         case V4L2_COLORSPACE_BT2020:
716                 return CSC_BT2020;
717         default:
718                 return CSC_BT709L;
719         }
720 }
721
722 /*
723  * colorspace path:
724  *      Input        Win csc                     Output
725  * 1. YUV(2020)  --> Y2R->2020To709->R2Y   --> YUV_OUTPUT(601/709)
726  *    RGB        --> R2Y                  __/
727  *
728  * 2. YUV(2020)  --> bypasss               --> YUV_OUTPUT(2020)
729  *    RGB        --> 709To2020->R2Y       __/
730  *
731  * 3. YUV(2020)  --> Y2R->2020To709        --> RGB_OUTPUT(709)
732  *    RGB        --> R2Y                  __/
733  *
734  * 4. YUV(601/709)-> Y2R->709To2020->R2Y   --> YUV_OUTPUT(2020)
735  *    RGB        --> 709To2020->R2Y       __/
736  *
737  * 5. YUV(601/709)-> bypass                --> YUV_OUTPUT(709)
738  *    RGB        --> R2Y                  __/
739  *
740  * 6. YUV(601/709)-> bypass                --> YUV_OUTPUT(601)
741  *    RGB        --> R2Y(601)             __/
742  *
743  * 7. YUV        --> Y2R(709)              --> RGB_OUTPUT(709)
744  *    RGB        --> bypass               __/
745  *
746  * 8. RGB        --> 709To2020->R2Y        --> YUV_OUTPUT(2020)
747  *
748  * 9. RGB        --> R2Y(709)              --> YUV_OUTPUT(709)
749  *
750  * 10. RGB       --> R2Y(601)              --> YUV_OUTPUT(601)
751  *
752  * 11. RGB       --> bypass                --> RGB_OUTPUT(709)
753  */
754
755 static void vop2_setup_csc_mode(struct vop2_video_port *vp,
756                                 struct vop2_win *win,
757                                 struct drm_plane_state *pstate)
758 {
759         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
760         int is_input_yuv = pstate->fb->format->is_yuv;
761         int is_output_yuv = is_yuv_output(vcstate->bus_format);
762         int input_csc = V4L2_COLORSPACE_DEFAULT;
763         int output_csc = vcstate->color_space;
764         bool r2y_en, y2r_en;
765         int csc_mode;
766
767         if (is_input_yuv && !is_output_yuv) {
768                 y2r_en = true;
769                 r2y_en = false;
770                 csc_mode = vop2_convert_csc_mode(input_csc);
771         } else if (!is_input_yuv && is_output_yuv) {
772                 y2r_en = false;
773                 r2y_en = true;
774                 csc_mode = vop2_convert_csc_mode(output_csc);
775         } else {
776                 y2r_en = false;
777                 r2y_en = false;
778                 csc_mode = false;
779         }
780
781         vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en);
782         vop2_win_write(win, VOP2_WIN_R2Y_EN, r2y_en);
783         vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode);
784 }
785
786 static void vop2_crtc_enable_irq(struct vop2_video_port *vp, u32 irq)
787 {
788         struct vop2 *vop2 = vp->vop2;
789
790         vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq);
791         vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq);
792 }
793
794 static void vop2_crtc_disable_irq(struct vop2_video_port *vp, u32 irq)
795 {
796         struct vop2 *vop2 = vp->vop2;
797
798         vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16);
799 }
800
801 static int vop2_core_clks_prepare_enable(struct vop2 *vop2)
802 {
803         int ret;
804
805         ret = clk_prepare_enable(vop2->hclk);
806         if (ret < 0) {
807                 drm_err(vop2->drm, "failed to enable hclk - %d\n", ret);
808                 return ret;
809         }
810
811         ret = clk_prepare_enable(vop2->aclk);
812         if (ret < 0) {
813                 drm_err(vop2->drm, "failed to enable aclk - %d\n", ret);
814                 goto err;
815         }
816
817         return 0;
818 err:
819         clk_disable_unprepare(vop2->hclk);
820
821         return ret;
822 }
823
824 static void vop2_enable(struct vop2 *vop2)
825 {
826         int ret;
827
828         ret = pm_runtime_resume_and_get(vop2->dev);
829         if (ret < 0) {
830                 drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
831                 return;
832         }
833
834         ret = vop2_core_clks_prepare_enable(vop2);
835         if (ret) {
836                 pm_runtime_put_sync(vop2->dev);
837                 return;
838         }
839
840         ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev);
841         if (ret) {
842                 drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret);
843                 return;
844         }
845
846         regcache_sync(vop2->map);
847
848         if (vop2->data->soc_id == 3566)
849                 vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
850
851         vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
852
853         /*
854          * Disable auto gating, this is a workaround to
855          * avoid display image shift when a window enabled.
856          */
857         regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL,
858                           RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN);
859
860         vop2_writel(vop2, RK3568_SYS0_INT_CLR,
861                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
862         vop2_writel(vop2, RK3568_SYS0_INT_EN,
863                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
864         vop2_writel(vop2, RK3568_SYS1_INT_CLR,
865                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
866         vop2_writel(vop2, RK3568_SYS1_INT_EN,
867                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
868 }
869
870 static void vop2_disable(struct vop2 *vop2)
871 {
872         rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
873
874         pm_runtime_put_sync(vop2->dev);
875
876         regcache_mark_dirty(vop2->map);
877
878         clk_disable_unprepare(vop2->aclk);
879         clk_disable_unprepare(vop2->hclk);
880 }
881
882 static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
883                                      struct drm_atomic_state *state)
884 {
885         struct vop2_video_port *vp = to_vop2_video_port(crtc);
886         struct vop2 *vop2 = vp->vop2;
887         struct drm_crtc_state *old_crtc_state;
888         int ret;
889
890         vop2_lock(vop2);
891
892         old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
893         drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
894
895         drm_crtc_vblank_off(crtc);
896
897         /*
898          * Vop standby will take effect at end of current frame,
899          * if dsp hold valid irq happen, it means standby complete.
900          *
901          * we must wait standby complete when we want to disable aclk,
902          * if not, memory bus maybe dead.
903          */
904         reinit_completion(&vp->dsp_hold_completion);
905
906         vop2_crtc_enable_irq(vp, VP_INT_DSP_HOLD_VALID);
907
908         vop2_vp_write(vp, RK3568_VP_DSP_CTRL, RK3568_VP_DSP_CTRL__STANDBY);
909
910         ret = wait_for_completion_timeout(&vp->dsp_hold_completion,
911                                           msecs_to_jiffies(50));
912         if (!ret)
913                 drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id);
914
915         vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
916
917         clk_disable_unprepare(vp->dclk);
918
919         vop2->enable_count--;
920
921         if (!vop2->enable_count)
922                 vop2_disable(vop2);
923
924         vop2_unlock(vop2);
925
926         if (crtc->state->event && !crtc->state->active) {
927                 spin_lock_irq(&crtc->dev->event_lock);
928                 drm_crtc_send_vblank_event(crtc, crtc->state->event);
929                 spin_unlock_irq(&crtc->dev->event_lock);
930
931                 crtc->state->event = NULL;
932         }
933 }
934
935 static int vop2_plane_atomic_check(struct drm_plane *plane,
936                                    struct drm_atomic_state *astate)
937 {
938         struct drm_plane_state *pstate = drm_atomic_get_new_plane_state(astate, plane);
939         struct drm_framebuffer *fb = pstate->fb;
940         struct drm_crtc *crtc = pstate->crtc;
941         struct drm_crtc_state *cstate;
942         struct vop2_video_port *vp;
943         struct vop2 *vop2;
944         const struct vop2_data *vop2_data;
945         struct drm_rect *dest = &pstate->dst;
946         struct drm_rect *src = &pstate->src;
947         int min_scale = FRAC_16_16(1, 8);
948         int max_scale = FRAC_16_16(8, 1);
949         int format;
950         int ret;
951
952         if (!crtc)
953                 return 0;
954
955         vp = to_vop2_video_port(crtc);
956         vop2 = vp->vop2;
957         vop2_data = vop2->data;
958
959         cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc);
960         if (WARN_ON(!cstate))
961                 return -EINVAL;
962
963         ret = drm_atomic_helper_check_plane_state(pstate, cstate,
964                                                   min_scale, max_scale,
965                                                   true, true);
966         if (ret)
967                 return ret;
968
969         if (!pstate->visible)
970                 return 0;
971
972         format = vop2_convert_format(fb->format->format);
973         if (format < 0)
974                 return format;
975
976         if (drm_rect_width(src) >> 16 < 4 || drm_rect_height(src) >> 16 < 4 ||
977             drm_rect_width(dest) < 4 || drm_rect_width(dest) < 4) {
978                 drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n",
979                         drm_rect_width(src) >> 16, drm_rect_height(src) >> 16,
980                         drm_rect_width(dest), drm_rect_height(dest));
981                 pstate->visible = false;
982                 return 0;
983         }
984
985         if (drm_rect_width(src) >> 16 > vop2_data->max_input.width ||
986             drm_rect_height(src) >> 16 > vop2_data->max_input.height) {
987                 drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n",
988                         drm_rect_width(src) >> 16,
989                         drm_rect_height(src) >> 16,
990                         vop2_data->max_input.width,
991                         vop2_data->max_input.height);
992                 return -EINVAL;
993         }
994
995         /*
996          * Src.x1 can be odd when do clip, but yuv plane start point
997          * need align with 2 pixel.
998          */
999         if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) {
1000                 drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n");
1001                 return -EINVAL;
1002         }
1003
1004         return 0;
1005 }
1006
1007 static void vop2_plane_atomic_disable(struct drm_plane *plane,
1008                                       struct drm_atomic_state *state)
1009 {
1010         struct drm_plane_state *old_pstate = NULL;
1011         struct vop2_win *win = to_vop2_win(plane);
1012         struct vop2 *vop2 = win->vop2;
1013
1014         drm_dbg(vop2->drm, "%s disable\n", win->data->name);
1015
1016         if (state)
1017                 old_pstate = drm_atomic_get_old_plane_state(state, plane);
1018         if (old_pstate && !old_pstate->crtc)
1019                 return;
1020
1021         vop2_win_disable(win);
1022         vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0);
1023 }
1024
1025 /*
1026  * The color key is 10 bit, so all format should
1027  * convert to 10 bit here.
1028  */
1029 static void vop2_plane_setup_color_key(struct drm_plane *plane, u32 color_key)
1030 {
1031         struct drm_plane_state *pstate = plane->state;
1032         struct drm_framebuffer *fb = pstate->fb;
1033         struct vop2_win *win = to_vop2_win(plane);
1034         u32 color_key_en = 0;
1035         u32 r = 0;
1036         u32 g = 0;
1037         u32 b = 0;
1038
1039         if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) {
1040                 vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, 0);
1041                 return;
1042         }
1043
1044         switch (fb->format->format) {
1045         case DRM_FORMAT_RGB565:
1046         case DRM_FORMAT_BGR565:
1047                 r = (color_key & 0xf800) >> 11;
1048                 g = (color_key & 0x7e0) >> 5;
1049                 b = (color_key & 0x1f);
1050                 r <<= 5;
1051                 g <<= 4;
1052                 b <<= 5;
1053                 color_key_en = 1;
1054                 break;
1055         case DRM_FORMAT_XRGB8888:
1056         case DRM_FORMAT_ARGB8888:
1057         case DRM_FORMAT_XBGR8888:
1058         case DRM_FORMAT_ABGR8888:
1059         case DRM_FORMAT_RGB888:
1060         case DRM_FORMAT_BGR888:
1061                 r = (color_key & 0xff0000) >> 16;
1062                 g = (color_key & 0xff00) >> 8;
1063                 b = (color_key & 0xff);
1064                 r <<= 2;
1065                 g <<= 2;
1066                 b <<= 2;
1067                 color_key_en = 1;
1068                 break;
1069         }
1070
1071         vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, color_key_en);
1072         vop2_win_write(win, VOP2_WIN_COLOR_KEY, (r << 20) | (g << 10) | b);
1073 }
1074
1075 static void vop2_plane_atomic_update(struct drm_plane *plane,
1076                                      struct drm_atomic_state *state)
1077 {
1078         struct drm_plane_state *pstate = plane->state;
1079         struct drm_crtc *crtc = pstate->crtc;
1080         struct vop2_win *win = to_vop2_win(plane);
1081         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1082         struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1083         struct vop2 *vop2 = win->vop2;
1084         struct drm_framebuffer *fb = pstate->fb;
1085         u32 bpp = fb->format->cpp[0] * 8;
1086         u32 actual_w, actual_h, dsp_w, dsp_h;
1087         u32 act_info, dsp_info;
1088         u32 format;
1089         u32 afbc_format;
1090         u32 rb_swap;
1091         u32 uv_swap;
1092         struct drm_rect *src = &pstate->src;
1093         struct drm_rect *dest = &pstate->dst;
1094         u32 afbc_tile_num;
1095         u32 transform_offset;
1096         bool dither_up;
1097         bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
1098         bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
1099         bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
1100         bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
1101         struct rockchip_gem_object *rk_obj;
1102         unsigned long offset;
1103         bool afbc_en;
1104         dma_addr_t yrgb_mst;
1105         dma_addr_t uv_mst;
1106
1107         /*
1108          * can't update plane when vop2 is disabled.
1109          */
1110         if (WARN_ON(!crtc))
1111                 return;
1112
1113         if (!pstate->visible) {
1114                 vop2_plane_atomic_disable(plane, state);
1115                 return;
1116         }
1117
1118         afbc_en = rockchip_afbc(plane, fb->modifier);
1119
1120         offset = (src->x1 >> 16) * fb->format->cpp[0];
1121
1122         /*
1123          * AFBC HDR_PTR must set to the zero offset of the framebuffer.
1124          */
1125         if (afbc_en)
1126                 offset = 0;
1127         else if (pstate->rotation & DRM_MODE_REFLECT_Y)
1128                 offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
1129         else
1130                 offset += (src->y1 >> 16) * fb->pitches[0];
1131
1132         rk_obj = to_rockchip_obj(fb->obj[0]);
1133
1134         yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
1135         if (fb->format->is_yuv) {
1136                 int hsub = fb->format->hsub;
1137                 int vsub = fb->format->vsub;
1138
1139                 offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub;
1140                 offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
1141
1142                 if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en)
1143                         offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub;
1144
1145                 rk_obj = to_rockchip_obj(fb->obj[0]);
1146                 uv_mst = rk_obj->dma_addr + offset + fb->offsets[1];
1147         }
1148
1149         actual_w = drm_rect_width(src) >> 16;
1150         actual_h = drm_rect_height(src) >> 16;
1151         dsp_w = drm_rect_width(dest);
1152
1153         if (dest->x1 + dsp_w > adjusted_mode->hdisplay) {
1154                 drm_err(vop2->drm, "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
1155                         vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay);
1156                 dsp_w = adjusted_mode->hdisplay - dest->x1;
1157                 if (dsp_w < 4)
1158                         dsp_w = 4;
1159                 actual_w = dsp_w * actual_w / drm_rect_width(dest);
1160         }
1161
1162         dsp_h = drm_rect_height(dest);
1163
1164         if (dest->y1 + dsp_h > adjusted_mode->vdisplay) {
1165                 drm_err(vop2->drm, "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
1166                         vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay);
1167                 dsp_h = adjusted_mode->vdisplay - dest->y1;
1168                 if (dsp_h < 4)
1169                         dsp_h = 4;
1170                 actual_h = dsp_h * actual_h / drm_rect_height(dest);
1171         }
1172
1173         /*
1174          * This is workaround solution for IC design:
1175          * esmart can't support scale down when actual_w % 16 == 1.
1176          */
1177         if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
1178                 if (actual_w > dsp_w && (actual_w & 0xf) == 1) {
1179                         drm_err(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n",
1180                                 vp->id, win->data->name, actual_w);
1181                         actual_w -= 1;
1182                 }
1183         }
1184
1185         if (afbc_en && actual_w % 4) {
1186                 drm_err(vop2->drm, "vp%d %s actual_w[%d] not 4 pixel aligned\n",
1187                         vp->id, win->data->name, actual_w);
1188                 actual_w = ALIGN_DOWN(actual_w, 4);
1189         }
1190
1191         act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
1192         dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff);
1193
1194         format = vop2_convert_format(fb->format->format);
1195
1196         drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n",
1197                 vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h,
1198                 dest->x1, dest->y1,
1199                 &fb->format->format,
1200                 afbc_en ? "AFBC" : "", &yrgb_mst);
1201
1202         if (afbc_en) {
1203                 u32 stride;
1204
1205                 /* the afbc superblock is 16 x 16 */
1206                 afbc_format = vop2_convert_afbc_format(fb->format->format);
1207
1208                 /* Enable color transform for YTR */
1209                 if (fb->modifier & AFBC_FORMAT_MOD_YTR)
1210                         afbc_format |= (1 << 4);
1211
1212                 afbc_tile_num = ALIGN(actual_w, 16) >> 4;
1213
1214                 /*
1215                  * AFBC pic_vir_width is count by pixel, this is different
1216                  * with WIN_VIR_STRIDE.
1217                  */
1218                 stride = (fb->pitches[0] << 3) / bpp;
1219                 if ((stride & 0x3f) && (xmirror || rotate_90 || rotate_270))
1220                         drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
1221                                 vp->id, win->data->name, stride);
1222
1223                 rb_swap = vop2_afbc_rb_swap(fb->format->format);
1224                 uv_swap = vop2_afbc_uv_swap(fb->format->format);
1225                 /*
1226                  * This is a workaround for crazy IC design, Cluster
1227                  * and Esmart/Smart use different format configuration map:
1228                  * YUV420_10BIT: 0x10 for Cluster, 0x14 for Esmart/Smart.
1229                  *
1230                  * This is one thing we can make the convert simple:
1231                  * AFBCD decode all the YUV data to YUV444. So we just
1232                  * set all the yuv 10 bit to YUV444_10.
1233                  */
1234                 if (fb->format->is_yuv && bpp == 10)
1235                         format = VOP2_CLUSTER_YUV444_10;
1236
1237                 if (vop2_cluster_window(win))
1238                         vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1);
1239                 vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format);
1240                 vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap);
1241                 vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap);
1242                 vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
1243                 vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
1244                 if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) {
1245                         vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 0);
1246                         transform_offset = vop2_afbc_transform_offset(pstate, false);
1247                 } else {
1248                         vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 1);
1249                         transform_offset = vop2_afbc_transform_offset(pstate, true);
1250                 }
1251                 vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
1252                 vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
1253                 vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, transform_offset);
1254                 vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1));
1255                 vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16)));
1256                 vop2_win_write(win, VOP2_WIN_AFBC_PIC_VIR_WIDTH, stride);
1257                 vop2_win_write(win, VOP2_WIN_AFBC_TILE_NUM, afbc_tile_num);
1258                 vop2_win_write(win, VOP2_WIN_XMIRROR, xmirror);
1259                 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270);
1260                 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90);
1261         } else {
1262                 vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4));
1263         }
1264
1265         vop2_win_write(win, VOP2_WIN_YMIRROR, ymirror);
1266
1267         if (rotate_90 || rotate_270) {
1268                 act_info = swahw32(act_info);
1269                 actual_w = drm_rect_height(src) >> 16;
1270                 actual_h = drm_rect_width(src) >> 16;
1271         }
1272
1273         vop2_win_write(win, VOP2_WIN_FORMAT, format);
1274         vop2_win_write(win, VOP2_WIN_YRGB_MST, yrgb_mst);
1275
1276         rb_swap = vop2_win_rb_swap(fb->format->format);
1277         vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap);
1278         if (!vop2_cluster_window(win)) {
1279                 uv_swap = vop2_win_uv_swap(fb->format->format);
1280                 vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
1281         }
1282
1283         if (fb->format->is_yuv) {
1284                 vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4));
1285                 vop2_win_write(win, VOP2_WIN_UV_MST, uv_mst);
1286         }
1287
1288         vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format);
1289         if (!vop2_cluster_window(win))
1290                 vop2_plane_setup_color_key(plane, 0);
1291         vop2_win_write(win, VOP2_WIN_ACT_INFO, act_info);
1292         vop2_win_write(win, VOP2_WIN_DSP_INFO, dsp_info);
1293         vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff));
1294
1295         vop2_setup_csc_mode(vp, win, pstate);
1296
1297         dither_up = vop2_win_dither_up(fb->format->format);
1298         vop2_win_write(win, VOP2_WIN_DITHER_UP, dither_up);
1299
1300         vop2_win_write(win, VOP2_WIN_ENABLE, 1);
1301
1302         if (vop2_cluster_window(win)) {
1303                 int lb_mode = vop2_get_cluster_lb_mode(win, pstate);
1304
1305                 vop2_win_write(win, VOP2_WIN_CLUSTER_LB_MODE, lb_mode);
1306                 vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 1);
1307         }
1308 }
1309
1310 static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = {
1311         .atomic_check = vop2_plane_atomic_check,
1312         .atomic_update = vop2_plane_atomic_update,
1313         .atomic_disable = vop2_plane_atomic_disable,
1314 };
1315
1316 static const struct drm_plane_funcs vop2_plane_funcs = {
1317         .update_plane   = drm_atomic_helper_update_plane,
1318         .disable_plane  = drm_atomic_helper_disable_plane,
1319         .destroy = drm_plane_cleanup,
1320         .reset = drm_atomic_helper_plane_reset,
1321         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
1322         .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
1323         .format_mod_supported = rockchip_vop2_mod_supported,
1324 };
1325
1326 static int vop2_crtc_enable_vblank(struct drm_crtc *crtc)
1327 {
1328         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1329
1330         vop2_crtc_enable_irq(vp, VP_INT_FS_FIELD);
1331
1332         return 0;
1333 }
1334
1335 static void vop2_crtc_disable_vblank(struct drm_crtc *crtc)
1336 {
1337         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1338
1339         vop2_crtc_disable_irq(vp, VP_INT_FS_FIELD);
1340 }
1341
1342 static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc,
1343                                  const struct drm_display_mode *mode,
1344                                  struct drm_display_mode *adj_mode)
1345 {
1346         drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V |
1347                                         CRTC_STEREO_DOUBLE);
1348
1349         return true;
1350 }
1351
1352 static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
1353 {
1354         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1355
1356         switch (vcstate->bus_format) {
1357         case MEDIA_BUS_FMT_RGB565_1X16:
1358                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN;
1359                 break;
1360         case MEDIA_BUS_FMT_RGB666_1X18:
1361         case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
1362         case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
1363                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN;
1364                 *dsp_ctrl |= RGB888_TO_RGB666;
1365                 break;
1366         case MEDIA_BUS_FMT_YUV8_1X24:
1367         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1368                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN;
1369                 break;
1370         default:
1371                 break;
1372         }
1373
1374         if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA)
1375                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN;
1376
1377         *dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL,
1378                                 DITHER_DOWN_ALLEGRO);
1379 }
1380
1381 static void vop2_post_config(struct drm_crtc *crtc)
1382 {
1383         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1384         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1385         u16 vtotal = mode->crtc_vtotal;
1386         u16 hdisplay = mode->crtc_hdisplay;
1387         u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1388         u16 vdisplay = mode->crtc_vdisplay;
1389         u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1390         u32 left_margin = 100, right_margin = 100;
1391         u32 top_margin = 100, bottom_margin = 100;
1392         u16 hsize = hdisplay * (left_margin + right_margin) / 200;
1393         u16 vsize = vdisplay * (top_margin + bottom_margin) / 200;
1394         u16 hact_end, vact_end;
1395         u32 val;
1396
1397         vsize = rounddown(vsize, 2);
1398         hsize = rounddown(hsize, 2);
1399         hact_st += hdisplay * (100 - left_margin) / 200;
1400         hact_end = hact_st + hsize;
1401         val = hact_st << 16;
1402         val |= hact_end;
1403         vop2_vp_write(vp, RK3568_VP_POST_DSP_HACT_INFO, val);
1404         vact_st += vdisplay * (100 - top_margin) / 200;
1405         vact_end = vact_st + vsize;
1406         val = vact_st << 16;
1407         val |= vact_end;
1408         vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO, val);
1409         val = scl_cal_scale2(vdisplay, vsize) << 16;
1410         val |= scl_cal_scale2(hdisplay, hsize);
1411         vop2_vp_write(vp, RK3568_VP_POST_SCL_FACTOR_YRGB, val);
1412
1413         val = 0;
1414         if (hdisplay != hsize)
1415                 val |= RK3568_VP_POST_SCL_CTRL__HSCALEDOWN;
1416         if (vdisplay != vsize)
1417                 val |= RK3568_VP_POST_SCL_CTRL__VSCALEDOWN;
1418         vop2_vp_write(vp, RK3568_VP_POST_SCL_CTRL, val);
1419
1420         if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1421                 u16 vact_st_f1 = vtotal + vact_st + 1;
1422                 u16 vact_end_f1 = vact_st_f1 + vsize;
1423
1424                 val = vact_st_f1 << 16 | vact_end_f1;
1425                 vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
1426         }
1427
1428         vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
1429 }
1430
1431 static void rk3568_set_intf_mux(struct vop2_video_port *vp, int id,
1432                                 u32 polflags)
1433 {
1434         struct vop2 *vop2 = vp->vop2;
1435         u32 die, dip;
1436
1437         die = vop2_readl(vop2, RK3568_DSP_IF_EN);
1438         dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
1439
1440         switch (id) {
1441         case ROCKCHIP_VOP2_EP_RGB0:
1442                 die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
1443                 die |= RK3568_SYS_DSP_INFACE_EN_RGB |
1444                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
1445                 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1446                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1447                 if (polflags & POLFLAG_DCLK_INV)
1448                         regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
1449                 else
1450                         regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
1451                 break;
1452         case ROCKCHIP_VOP2_EP_HDMI0:
1453                 die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
1454                 die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
1455                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
1456                 dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
1457                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
1458                 break;
1459         case ROCKCHIP_VOP2_EP_EDP0:
1460                 die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
1461                 die |= RK3568_SYS_DSP_INFACE_EN_EDP |
1462                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
1463                 dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
1464                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
1465                 break;
1466         case ROCKCHIP_VOP2_EP_MIPI0:
1467                 die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
1468                 die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
1469                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
1470                 dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
1471                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
1472                 break;
1473         case ROCKCHIP_VOP2_EP_MIPI1:
1474                 die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
1475                 die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
1476                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
1477                 dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
1478                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
1479                 break;
1480         case ROCKCHIP_VOP2_EP_LVDS0:
1481                 die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
1482                 die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
1483                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
1484                 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1485                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1486                 break;
1487         case ROCKCHIP_VOP2_EP_LVDS1:
1488                 die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
1489                 die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
1490                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
1491                 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1492                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1493                 break;
1494         default:
1495                 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
1496                 return;
1497         }
1498
1499         dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
1500
1501         vop2_writel(vop2, RK3568_DSP_IF_EN, die);
1502         vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
1503 }
1504
1505 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
1506 {
1507         return us * mode->clock / mode->htotal / 1000;
1508 }
1509
1510 static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
1511                                     struct drm_atomic_state *state)
1512 {
1513         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1514         struct vop2 *vop2 = vp->vop2;
1515         const struct vop2_data *vop2_data = vop2->data;
1516         const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
1517         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1518         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1519         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1520         unsigned long clock = mode->crtc_clock * 1000;
1521         u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
1522         u16 hdisplay = mode->crtc_hdisplay;
1523         u16 htotal = mode->crtc_htotal;
1524         u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1525         u16 hact_end = hact_st + hdisplay;
1526         u16 vdisplay = mode->crtc_vdisplay;
1527         u16 vtotal = mode->crtc_vtotal;
1528         u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
1529         u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1530         u16 vact_end = vact_st + vdisplay;
1531         u8 out_mode;
1532         u32 dsp_ctrl = 0;
1533         int act_end;
1534         u32 val, polflags;
1535         int ret;
1536         struct drm_encoder *encoder;
1537
1538         drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n",
1539                 hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
1540                 drm_mode_vrefresh(mode), vcstate->output_type, vp->id);
1541
1542         vop2_lock(vop2);
1543
1544         ret = clk_prepare_enable(vp->dclk);
1545         if (ret < 0) {
1546                 drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n",
1547                         vp->id, ret);
1548                 vop2_unlock(vop2);
1549                 return;
1550         }
1551
1552         if (!vop2->enable_count)
1553                 vop2_enable(vop2);
1554
1555         vop2->enable_count++;
1556
1557         vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY);
1558
1559         polflags = 0;
1560         if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
1561                 polflags |= POLFLAG_DCLK_INV;
1562         if (mode->flags & DRM_MODE_FLAG_PHSYNC)
1563                 polflags |= BIT(HSYNC_POSITIVE);
1564         if (mode->flags & DRM_MODE_FLAG_PVSYNC)
1565                 polflags |= BIT(VSYNC_POSITIVE);
1566
1567         drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
1568                 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
1569
1570                 rk3568_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
1571         }
1572
1573         if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
1574             !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT))
1575                 out_mode = ROCKCHIP_OUT_MODE_P888;
1576         else
1577                 out_mode = vcstate->output_mode;
1578
1579         dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__OUT_MODE, out_mode);
1580
1581         if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode))
1582                 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP;
1583
1584         if (is_yuv_output(vcstate->bus_format))
1585                 dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y;
1586
1587         vop2_dither_setup(crtc, &dsp_ctrl);
1588
1589         vop2_vp_write(vp, RK3568_VP_DSP_HTOTAL_HS_END, (htotal << 16) | hsync_len);
1590         val = hact_st << 16;
1591         val |= hact_end;
1592         vop2_vp_write(vp, RK3568_VP_DSP_HACT_ST_END, val);
1593
1594         val = vact_st << 16;
1595         val |= vact_end;
1596         vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END, val);
1597
1598         if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1599                 u16 vact_st_f1 = vtotal + vact_st + 1;
1600                 u16 vact_end_f1 = vact_st_f1 + vdisplay;
1601
1602                 val = vact_st_f1 << 16 | vact_end_f1;
1603                 vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END_F1, val);
1604
1605                 val = vtotal << 16 | (vtotal + vsync_len);
1606                 vop2_vp_write(vp, RK3568_VP_DSP_VS_ST_END_F1, val);
1607                 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_INTERLACE;
1608                 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_FILED_POL;
1609                 dsp_ctrl |= RK3568_VP_DSP_CTRL__P2I_EN;
1610                 vtotal += vtotal + 1;
1611                 act_end = vact_end_f1;
1612         } else {
1613                 act_end = vact_end;
1614         }
1615
1616         vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id),
1617                     (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end);
1618
1619         vop2_vp_write(vp, RK3568_VP_DSP_VTOTAL_VS_END, vtotal << 16 | vsync_len);
1620
1621         if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
1622                 dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV;
1623                 clock *= 2;
1624         }
1625
1626         vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
1627
1628         clk_set_rate(vp->dclk, clock);
1629
1630         vop2_post_config(crtc);
1631
1632         vop2_cfg_done(vp);
1633
1634         vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
1635
1636         drm_crtc_vblank_on(crtc);
1637
1638         vop2_unlock(vop2);
1639 }
1640
1641 static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
1642                                   struct drm_atomic_state *state)
1643 {
1644         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1645         struct drm_plane *plane;
1646         int nplanes = 0;
1647         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1648
1649         drm_atomic_crtc_state_for_each_plane(plane, crtc_state)
1650                 nplanes++;
1651
1652         if (nplanes > vp->nlayers)
1653                 return -EINVAL;
1654
1655         return 0;
1656 }
1657
1658 static bool is_opaque(u16 alpha)
1659 {
1660         return (alpha >> 8) == 0xff;
1661 }
1662
1663 static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
1664                              struct vop2_alpha *alpha)
1665 {
1666         int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
1667         int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
1668         int src_color_mode = alpha_config->src_premulti_en ?
1669                                 ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
1670         int dst_color_mode = alpha_config->dst_premulti_en ?
1671                                 ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
1672
1673         alpha->src_color_ctrl.val = 0;
1674         alpha->dst_color_ctrl.val = 0;
1675         alpha->src_alpha_ctrl.val = 0;
1676         alpha->dst_alpha_ctrl.val = 0;
1677
1678         if (!alpha_config->src_pixel_alpha_en)
1679                 alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
1680         else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
1681                 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
1682         else
1683                 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
1684
1685         alpha->src_color_ctrl.bits.alpha_en = 1;
1686
1687         if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
1688                 alpha->src_color_ctrl.bits.color_mode = src_color_mode;
1689                 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
1690         } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
1691                 alpha->src_color_ctrl.bits.color_mode = src_color_mode;
1692                 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
1693         } else {
1694                 alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
1695                 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
1696         }
1697         alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
1698         alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1699         alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1700
1701         alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1702         alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1703         alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
1704         alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
1705         alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
1706         alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
1707
1708         alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1709         alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
1710         alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1711         alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
1712
1713         alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1714         if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
1715                 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
1716         else
1717                 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
1718         alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
1719         alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
1720 }
1721
1722 static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
1723 {
1724         struct vop2_video_port *vp;
1725         int used_layer = 0;
1726         int i;
1727
1728         for (i = 0; i < port_id; i++) {
1729                 vp = &vop2->vps[i];
1730                 used_layer += hweight32(vp->win_mask);
1731         }
1732
1733         return used_layer;
1734 }
1735
1736 static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
1737 {
1738         u32 offset = (main_win->data->phys_id * 0x10);
1739         struct vop2_alpha_config alpha_config;
1740         struct vop2_alpha alpha;
1741         struct drm_plane_state *bottom_win_pstate;
1742         bool src_pixel_alpha_en = false;
1743         u16 src_glb_alpha_val, dst_glb_alpha_val;
1744         bool premulti_en = false;
1745         bool swap = false;
1746
1747         /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
1748         bottom_win_pstate = main_win->base.state;
1749         src_glb_alpha_val = 0;
1750         dst_glb_alpha_val = main_win->base.state->alpha;
1751
1752         if (!bottom_win_pstate->fb)
1753                 return;
1754
1755         alpha_config.src_premulti_en = premulti_en;
1756         alpha_config.dst_premulti_en = false;
1757         alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
1758         alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
1759         alpha_config.src_glb_alpha_value = src_glb_alpha_val;
1760         alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
1761         vop2_parse_alpha(&alpha_config, &alpha);
1762
1763         alpha.src_color_ctrl.bits.src_dst_swap = swap;
1764         vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
1765                     alpha.src_color_ctrl.val);
1766         vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
1767                     alpha.dst_color_ctrl.val);
1768         vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
1769                     alpha.src_alpha_ctrl.val);
1770         vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
1771                     alpha.dst_alpha_ctrl.val);
1772 }
1773
1774 static void vop2_setup_alpha(struct vop2_video_port *vp)
1775 {
1776         struct vop2 *vop2 = vp->vop2;
1777         struct drm_framebuffer *fb;
1778         struct vop2_alpha_config alpha_config;
1779         struct vop2_alpha alpha;
1780         struct drm_plane *plane;
1781         int pixel_alpha_en;
1782         int premulti_en, gpremulti_en = 0;
1783         int mixer_id;
1784         u32 offset;
1785         bool bottom_layer_alpha_en = false;
1786         u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
1787
1788         mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
1789         alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
1790
1791         drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
1792                 struct vop2_win *win = to_vop2_win(plane);
1793
1794                 if (plane->state->normalized_zpos == 0 &&
1795                     !is_opaque(plane->state->alpha) &&
1796                     !vop2_cluster_window(win)) {
1797                         /*
1798                          * If bottom layer have global alpha effect [except cluster layer,
1799                          * because cluster have deal with bottom layer global alpha value
1800                          * at cluster mix], bottom layer mix need deal with global alpha.
1801                          */
1802                         bottom_layer_alpha_en = true;
1803                         dst_global_alpha = plane->state->alpha;
1804                 }
1805         }
1806
1807         drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
1808                 struct vop2_win *win = to_vop2_win(plane);
1809                 int zpos = plane->state->normalized_zpos;
1810
1811                 if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
1812                         premulti_en = 1;
1813                 else
1814                         premulti_en = 0;
1815
1816                 plane = &win->base;
1817                 fb = plane->state->fb;
1818
1819                 pixel_alpha_en = fb->format->has_alpha;
1820
1821                 alpha_config.src_premulti_en = premulti_en;
1822
1823                 if (bottom_layer_alpha_en && zpos == 1) {
1824                         gpremulti_en = premulti_en;
1825                         /* Cd = Cs + (1 - As) * Cd * Agd */
1826                         alpha_config.dst_premulti_en = false;
1827                         alpha_config.src_pixel_alpha_en = pixel_alpha_en;
1828                         alpha_config.src_glb_alpha_value = plane->state->alpha;
1829                         alpha_config.dst_glb_alpha_value = dst_global_alpha;
1830                 } else if (vop2_cluster_window(win)) {
1831                         /* Mix output data only have pixel alpha */
1832                         alpha_config.dst_premulti_en = true;
1833                         alpha_config.src_pixel_alpha_en = true;
1834                         alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1835                         alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1836                 } else {
1837                         /* Cd = Cs + (1 - As) * Cd */
1838                         alpha_config.dst_premulti_en = true;
1839                         alpha_config.src_pixel_alpha_en = pixel_alpha_en;
1840                         alpha_config.src_glb_alpha_value = plane->state->alpha;
1841                         alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1842                 }
1843
1844                 vop2_parse_alpha(&alpha_config, &alpha);
1845
1846                 offset = (mixer_id + zpos - 1) * 0x10;
1847                 vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
1848                             alpha.src_color_ctrl.val);
1849                 vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
1850                             alpha.dst_color_ctrl.val);
1851                 vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
1852                             alpha.src_alpha_ctrl.val);
1853                 vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
1854                             alpha.dst_alpha_ctrl.val);
1855         }
1856
1857         if (vp->id == 0) {
1858                 if (bottom_layer_alpha_en) {
1859                         /* Transfer pixel alpha to hdr mix */
1860                         alpha_config.src_premulti_en = gpremulti_en;
1861                         alpha_config.dst_premulti_en = true;
1862                         alpha_config.src_pixel_alpha_en = true;
1863                         alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1864                         alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1865                         vop2_parse_alpha(&alpha_config, &alpha);
1866
1867                         vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
1868                                     alpha.src_color_ctrl.val);
1869                         vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
1870                                     alpha.dst_color_ctrl.val);
1871                         vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
1872                                     alpha.src_alpha_ctrl.val);
1873                         vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
1874                                     alpha.dst_alpha_ctrl.val);
1875                 } else {
1876                         vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
1877                 }
1878         }
1879 }
1880
1881 static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
1882 {
1883         struct vop2 *vop2 = vp->vop2;
1884         struct drm_plane *plane;
1885         u32 layer_sel = 0;
1886         u32 port_sel;
1887         unsigned int nlayer, ofs;
1888         struct drm_display_mode *adjusted_mode;
1889         u16 hsync_len;
1890         u16 hdisplay;
1891         u32 bg_dly;
1892         u32 pre_scan_dly;
1893         int i;
1894         struct vop2_video_port *vp0 = &vop2->vps[0];
1895         struct vop2_video_port *vp1 = &vop2->vps[1];
1896         struct vop2_video_port *vp2 = &vop2->vps[2];
1897
1898         adjusted_mode = &vp->crtc.state->adjusted_mode;
1899         hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
1900         hdisplay = adjusted_mode->crtc_hdisplay;
1901
1902         bg_dly = vp->data->pre_scan_max_dly[3];
1903         vop2_writel(vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
1904                     FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
1905
1906         pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
1907         vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
1908
1909         vop2_writel(vop2, RK3568_OVL_CTRL, 0);
1910         port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
1911         port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
1912
1913         if (vp0->nlayers)
1914                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
1915                                      vp0->nlayers - 1);
1916         else
1917                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
1918
1919         if (vp1->nlayers)
1920                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
1921                                      (vp0->nlayers + vp1->nlayers - 1));
1922         else
1923                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
1924
1925         if (vp2->nlayers)
1926                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
1927                         (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
1928         else
1929                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
1930
1931         layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
1932
1933         ofs = 0;
1934         for (i = 0; i < vp->id; i++)
1935                 ofs += vop2->vps[i].nlayers;
1936
1937         nlayer = 0;
1938         drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
1939                 struct vop2_win *win = to_vop2_win(plane);
1940
1941                 switch (win->data->phys_id) {
1942                 case ROCKCHIP_VOP2_CLUSTER0:
1943                         port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
1944                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
1945                         break;
1946                 case ROCKCHIP_VOP2_CLUSTER1:
1947                         port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
1948                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
1949                         break;
1950                 case ROCKCHIP_VOP2_ESMART0:
1951                         port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
1952                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
1953                         break;
1954                 case ROCKCHIP_VOP2_ESMART1:
1955                         port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
1956                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
1957                         break;
1958                 case ROCKCHIP_VOP2_SMART0:
1959                         port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
1960                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
1961                         break;
1962                 case ROCKCHIP_VOP2_SMART1:
1963                         port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
1964                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
1965                         break;
1966                 }
1967
1968                 layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
1969                                                           0x7);
1970                 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
1971                                                          win->data->layer_sel_id);
1972                 nlayer++;
1973         }
1974
1975         /* configure unused layers to 0x5 (reserved) */
1976         for (; nlayer < vp->nlayers; nlayer++) {
1977                 layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7);
1978                 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5);
1979         }
1980
1981         vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
1982         vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
1983         vop2_writel(vop2, RK3568_OVL_CTRL, RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD);
1984 }
1985
1986 static void vop2_setup_dly_for_windows(struct vop2 *vop2)
1987 {
1988         struct vop2_win *win;
1989         int i = 0;
1990         u32 cdly = 0, sdly = 0;
1991
1992         for (i = 0; i < vop2->data->win_size; i++) {
1993                 u32 dly;
1994
1995                 win = &vop2->win[i];
1996                 dly = win->delay;
1997
1998                 switch (win->data->phys_id) {
1999                 case ROCKCHIP_VOP2_CLUSTER0:
2000                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
2001                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
2002                         break;
2003                 case ROCKCHIP_VOP2_CLUSTER1:
2004                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
2005                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
2006                         break;
2007                 case ROCKCHIP_VOP2_ESMART0:
2008                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
2009                         break;
2010                 case ROCKCHIP_VOP2_ESMART1:
2011                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
2012                         break;
2013                 case ROCKCHIP_VOP2_SMART0:
2014                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
2015                         break;
2016                 case ROCKCHIP_VOP2_SMART1:
2017                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
2018                         break;
2019                 }
2020         }
2021
2022         vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
2023         vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
2024 }
2025
2026 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
2027                                    struct drm_atomic_state *state)
2028 {
2029         struct vop2_video_port *vp = to_vop2_video_port(crtc);
2030         struct vop2 *vop2 = vp->vop2;
2031         struct drm_plane *plane;
2032
2033         vp->win_mask = 0;
2034
2035         drm_atomic_crtc_for_each_plane(plane, crtc) {
2036                 struct vop2_win *win = to_vop2_win(plane);
2037
2038                 win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
2039
2040                 vp->win_mask |= BIT(win->data->phys_id);
2041
2042                 if (vop2_cluster_window(win))
2043                         vop2_setup_cluster_alpha(vop2, win);
2044         }
2045
2046         if (!vp->win_mask)
2047                 return;
2048
2049         vop2_setup_layer_mixer(vp);
2050         vop2_setup_alpha(vp);
2051         vop2_setup_dly_for_windows(vop2);
2052 }
2053
2054 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
2055                                    struct drm_atomic_state *state)
2056 {
2057         struct vop2_video_port *vp = to_vop2_video_port(crtc);
2058
2059         vop2_post_config(crtc);
2060
2061         vop2_cfg_done(vp);
2062
2063         spin_lock_irq(&crtc->dev->event_lock);
2064
2065         if (crtc->state->event) {
2066                 WARN_ON(drm_crtc_vblank_get(crtc));
2067                 vp->event = crtc->state->event;
2068                 crtc->state->event = NULL;
2069         }
2070
2071         spin_unlock_irq(&crtc->dev->event_lock);
2072 }
2073
2074 static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
2075         .mode_fixup = vop2_crtc_mode_fixup,
2076         .atomic_check = vop2_crtc_atomic_check,
2077         .atomic_begin = vop2_crtc_atomic_begin,
2078         .atomic_flush = vop2_crtc_atomic_flush,
2079         .atomic_enable = vop2_crtc_atomic_enable,
2080         .atomic_disable = vop2_crtc_atomic_disable,
2081 };
2082
2083 static void vop2_crtc_reset(struct drm_crtc *crtc)
2084 {
2085         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
2086
2087         if (crtc->state) {
2088                 __drm_atomic_helper_crtc_destroy_state(crtc->state);
2089                 kfree(vcstate);
2090         }
2091
2092         vcstate = kzalloc(sizeof(*vcstate), GFP_KERNEL);
2093         if (!vcstate)
2094                 return;
2095
2096         crtc->state = &vcstate->base;
2097         crtc->state->crtc = crtc;
2098 }
2099
2100 static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
2101 {
2102         struct rockchip_crtc_state *vcstate, *old_vcstate;
2103
2104         old_vcstate = to_rockchip_crtc_state(crtc->state);
2105
2106         vcstate = kmemdup(old_vcstate, sizeof(*old_vcstate), GFP_KERNEL);
2107         if (!vcstate)
2108                 return NULL;
2109
2110         __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base);
2111
2112         return &vcstate->base;
2113 }
2114
2115 static void vop2_crtc_destroy_state(struct drm_crtc *crtc,
2116                                     struct drm_crtc_state *state)
2117 {
2118         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state);
2119
2120         __drm_atomic_helper_crtc_destroy_state(&vcstate->base);
2121         kfree(vcstate);
2122 }
2123
2124 static const struct drm_crtc_funcs vop2_crtc_funcs = {
2125         .set_config = drm_atomic_helper_set_config,
2126         .page_flip = drm_atomic_helper_page_flip,
2127         .destroy = drm_crtc_cleanup,
2128         .reset = vop2_crtc_reset,
2129         .atomic_duplicate_state = vop2_crtc_duplicate_state,
2130         .atomic_destroy_state = vop2_crtc_destroy_state,
2131         .enable_vblank = vop2_crtc_enable_vblank,
2132         .disable_vblank = vop2_crtc_disable_vblank,
2133 };
2134
2135 static irqreturn_t vop2_isr(int irq, void *data)
2136 {
2137         struct vop2 *vop2 = data;
2138         const struct vop2_data *vop2_data = vop2->data;
2139         u32 axi_irqs[VOP2_SYS_AXI_BUS_NUM];
2140         int ret = IRQ_NONE;
2141         int i;
2142
2143         /*
2144          * The irq is shared with the iommu. If the runtime-pm state of the
2145          * vop2-device is disabled the irq has to be targeted at the iommu.
2146          */
2147         if (!pm_runtime_get_if_in_use(vop2->dev))
2148                 return IRQ_NONE;
2149
2150         for (i = 0; i < vop2_data->nr_vps; i++) {
2151                 struct vop2_video_port *vp = &vop2->vps[i];
2152                 struct drm_crtc *crtc = &vp->crtc;
2153                 u32 irqs;
2154
2155                 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
2156                 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
2157
2158                 if (irqs & VP_INT_DSP_HOLD_VALID) {
2159                         complete(&vp->dsp_hold_completion);
2160                         ret = IRQ_HANDLED;
2161                 }
2162
2163                 if (irqs & VP_INT_FS_FIELD) {
2164                         drm_crtc_handle_vblank(crtc);
2165                         spin_lock(&crtc->dev->event_lock);
2166                         if (vp->event) {
2167                                 u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
2168
2169                                 if (!(val & BIT(vp->id))) {
2170                                         drm_crtc_send_vblank_event(crtc, vp->event);
2171                                         vp->event = NULL;
2172                                         drm_crtc_vblank_put(crtc);
2173                                 }
2174                         }
2175                         spin_unlock(&crtc->dev->event_lock);
2176
2177                         ret = IRQ_HANDLED;
2178                 }
2179
2180                 if (irqs & VP_INT_POST_BUF_EMPTY) {
2181                         drm_err_ratelimited(vop2->drm,
2182                                             "POST_BUF_EMPTY irq err at vp%d\n",
2183                                             vp->id);
2184                         ret = IRQ_HANDLED;
2185                 }
2186         }
2187
2188         axi_irqs[0] = vop2_readl(vop2, RK3568_SYS0_INT_STATUS);
2189         vop2_writel(vop2, RK3568_SYS0_INT_CLR, axi_irqs[0] << 16 | axi_irqs[0]);
2190         axi_irqs[1] = vop2_readl(vop2, RK3568_SYS1_INT_STATUS);
2191         vop2_writel(vop2, RK3568_SYS1_INT_CLR, axi_irqs[1] << 16 | axi_irqs[1]);
2192
2193         for (i = 0; i < ARRAY_SIZE(axi_irqs); i++) {
2194                 if (axi_irqs[i] & VOP2_INT_BUS_ERRPR) {
2195                         drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n");
2196                         ret = IRQ_HANDLED;
2197                 }
2198         }
2199
2200         pm_runtime_put(vop2->dev);
2201
2202         return ret;
2203 }
2204
2205 static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
2206                            unsigned long possible_crtcs)
2207 {
2208         const struct vop2_win_data *win_data = win->data;
2209         unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2210                                   BIT(DRM_MODE_BLEND_PREMULTI) |
2211                                   BIT(DRM_MODE_BLEND_COVERAGE);
2212         int ret;
2213
2214         ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs,
2215                                        &vop2_plane_funcs, win_data->formats,
2216                                        win_data->nformats,
2217                                        win_data->format_modifiers,
2218                                        win->type, win_data->name);
2219         if (ret) {
2220                 drm_err(vop2->drm, "failed to initialize plane %d\n", ret);
2221                 return ret;
2222         }
2223
2224         drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs);
2225
2226         if (win->data->supported_rotations)
2227                 drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0,
2228                                                    DRM_MODE_ROTATE_0 |
2229                                                    win->data->supported_rotations);
2230         drm_plane_create_alpha_property(&win->base);
2231         drm_plane_create_blend_mode_property(&win->base, blend_caps);
2232         drm_plane_create_zpos_property(&win->base, win->win_id, 0,
2233                                        vop2->registered_num_wins - 1);
2234
2235         return 0;
2236 }
2237
2238 static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
2239 {
2240         int i;
2241
2242         for (i = 0; i < vop2->data->nr_vps; i++) {
2243                 struct vop2_video_port *vp = &vop2->vps[i];
2244
2245                 if (!vp->crtc.port)
2246                         continue;
2247                 if (vp->primary_plane)
2248                         continue;
2249
2250                 return vp;
2251         }
2252
2253         return NULL;
2254 }
2255
2256 #define NR_LAYERS 6
2257
2258 static int vop2_create_crtcs(struct vop2 *vop2)
2259 {
2260         const struct vop2_data *vop2_data = vop2->data;
2261         struct drm_device *drm = vop2->drm;
2262         struct device *dev = vop2->dev;
2263         struct drm_plane *plane;
2264         struct device_node *port;
2265         struct vop2_video_port *vp;
2266         int i, nvp, nvps = 0;
2267         int ret;
2268
2269         for (i = 0; i < vop2_data->nr_vps; i++) {
2270                 const struct vop2_video_port_data *vp_data;
2271                 struct device_node *np;
2272                 char dclk_name[9];
2273
2274                 vp_data = &vop2_data->vp[i];
2275                 vp = &vop2->vps[i];
2276                 vp->vop2 = vop2;
2277                 vp->id = vp_data->id;
2278                 vp->regs = vp_data->regs;
2279                 vp->data = vp_data;
2280
2281                 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id);
2282                 vp->dclk = devm_clk_get(vop2->dev, dclk_name);
2283                 if (IS_ERR(vp->dclk)) {
2284                         drm_err(vop2->drm, "failed to get %s\n", dclk_name);
2285                         return PTR_ERR(vp->dclk);
2286                 }
2287
2288                 np = of_graph_get_remote_node(dev->of_node, i, -1);
2289                 if (!np) {
2290                         drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i);
2291                         continue;
2292                 }
2293                 of_node_put(np);
2294
2295                 port = of_graph_get_port_by_id(dev->of_node, i);
2296                 if (!port) {
2297                         drm_err(vop2->drm, "no port node found for video_port%d\n", i);
2298                         return -ENOENT;
2299                 }
2300
2301                 vp->crtc.port = port;
2302                 nvps++;
2303         }
2304
2305         nvp = 0;
2306         for (i = 0; i < vop2->registered_num_wins; i++) {
2307                 struct vop2_win *win = &vop2->win[i];
2308                 u32 possible_crtcs = 0;
2309
2310                 if (vop2->data->soc_id == 3566) {
2311                         /*
2312                          * On RK3566 these windows don't have an independent
2313                          * framebuffer. They share the framebuffer with smart0,
2314                          * esmart0 and cluster0 respectively.
2315                          */
2316                         switch (win->data->phys_id) {
2317                         case ROCKCHIP_VOP2_SMART1:
2318                         case ROCKCHIP_VOP2_ESMART1:
2319                         case ROCKCHIP_VOP2_CLUSTER1:
2320                                 continue;
2321                         }
2322                 }
2323
2324                 if (win->type == DRM_PLANE_TYPE_PRIMARY) {
2325                         vp = find_vp_without_primary(vop2);
2326                         if (vp) {
2327                                 possible_crtcs = BIT(nvp);
2328                                 vp->primary_plane = win;
2329                                 nvp++;
2330                         } else {
2331                                 /* change the unused primary window to overlay window */
2332                                 win->type = DRM_PLANE_TYPE_OVERLAY;
2333                         }
2334                 }
2335
2336                 if (win->type == DRM_PLANE_TYPE_OVERLAY)
2337                         possible_crtcs = (1 << nvps) - 1;
2338
2339                 ret = vop2_plane_init(vop2, win, possible_crtcs);
2340                 if (ret) {
2341                         drm_err(vop2->drm, "failed to init plane %s: %d\n",
2342                                 win->data->name, ret);
2343                         return ret;
2344                 }
2345         }
2346
2347         for (i = 0; i < vop2_data->nr_vps; i++) {
2348                 vp = &vop2->vps[i];
2349
2350                 if (!vp->crtc.port)
2351                         continue;
2352
2353                 plane = &vp->primary_plane->base;
2354
2355                 ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL,
2356                                                 &vop2_crtc_funcs,
2357                                                 "video_port%d", vp->id);
2358                 if (ret) {
2359                         drm_err(vop2->drm, "crtc init for video_port%d failed\n", i);
2360                         return ret;
2361                 }
2362
2363                 drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs);
2364
2365                 init_completion(&vp->dsp_hold_completion);
2366         }
2367
2368         /*
2369          * On the VOP2 it's very hard to change the number of layers on a VP
2370          * during runtime, so we distribute the layers equally over the used
2371          * VPs
2372          */
2373         for (i = 0; i < vop2->data->nr_vps; i++) {
2374                 struct vop2_video_port *vp = &vop2->vps[i];
2375
2376                 if (vp->crtc.port)
2377                         vp->nlayers = NR_LAYERS / nvps;
2378         }
2379
2380         return 0;
2381 }
2382
2383 static void vop2_destroy_crtcs(struct vop2 *vop2)
2384 {
2385         struct drm_device *drm = vop2->drm;
2386         struct list_head *crtc_list = &drm->mode_config.crtc_list;
2387         struct list_head *plane_list = &drm->mode_config.plane_list;
2388         struct drm_crtc *crtc, *tmpc;
2389         struct drm_plane *plane, *tmpp;
2390
2391         list_for_each_entry_safe(plane, tmpp, plane_list, head)
2392                 drm_plane_cleanup(plane);
2393
2394         /*
2395          * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane()
2396          * references the CRTC.
2397          */
2398         list_for_each_entry_safe(crtc, tmpc, crtc_list, head) {
2399                 of_node_put(crtc->port);
2400                 drm_crtc_cleanup(crtc);
2401         }
2402 }
2403
2404 static int vop2_find_rgb_encoder(struct vop2 *vop2)
2405 {
2406         struct device_node *node = vop2->dev->of_node;
2407         struct device_node *endpoint;
2408         int i;
2409
2410         for (i = 0; i < vop2->data->nr_vps; i++) {
2411                 endpoint = of_graph_get_endpoint_by_regs(node, i,
2412                                                          ROCKCHIP_VOP2_EP_RGB0);
2413                 if (!endpoint)
2414                         continue;
2415
2416                 of_node_put(endpoint);
2417                 return i;
2418         }
2419
2420         return -ENOENT;
2421 }
2422
2423 static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
2424         [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
2425         [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
2426         [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
2427         [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
2428         [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
2429         [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
2430         [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
2431         [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
2432         [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
2433         [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
2434         [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
2435         [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
2436         [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
2437         [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
2438         [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
2439
2440         /* Scale */
2441         [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
2442         [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
2443         [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
2444         [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
2445         [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
2446         [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
2447         [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
2448
2449         /* cluster regs */
2450         [VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
2451         [VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
2452         [VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
2453
2454         /* afbc regs */
2455         [VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
2456         [VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
2457         [VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
2458         [VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
2459         [VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
2460         [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
2461         [VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
2462         [VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
2463         [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
2464         [VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
2465         [VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
2466         [VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
2467         [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
2468         [VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
2469         [VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
2470         [VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
2471         [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
2472         [VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
2473         [VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
2474         [VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
2475         [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
2476         [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
2477         [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
2478         [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
2479         [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
2480         [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
2481         [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
2482         [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
2483         [VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
2484         [VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
2485 };
2486
2487 static int vop2_cluster_init(struct vop2_win *win)
2488 {
2489         struct vop2 *vop2 = win->vop2;
2490         struct reg_field *cluster_regs;
2491         int ret, i;
2492
2493         cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs),
2494                                GFP_KERNEL);
2495         if (!cluster_regs)
2496                 return -ENOMEM;
2497
2498         for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++)
2499                 if (cluster_regs[i].reg != 0xffffffff)
2500                         cluster_regs[i].reg += win->offset;
2501
2502         ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
2503                                            cluster_regs,
2504                                            ARRAY_SIZE(vop2_cluster_regs));
2505
2506         kfree(cluster_regs);
2507
2508         return ret;
2509 };
2510
2511 static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
2512         [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
2513         [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
2514         [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
2515         [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
2516         [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
2517         [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
2518         [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
2519         [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
2520         [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
2521         [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
2522         [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
2523         [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
2524         [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
2525         [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
2526         [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
2527         [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
2528         [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
2529         [VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
2530         [VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
2531
2532         /* Scale */
2533         [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
2534         [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
2535         [VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
2536         [VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
2537         [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
2538         [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
2539         [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
2540         [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
2541         [VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
2542         [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
2543         [VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
2544         [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
2545         [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
2546         [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
2547         [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
2548         [VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
2549         [VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
2550         [VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
2551         [VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
2552         [VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
2553         [VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
2554         [VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
2555         [VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
2556         [VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
2557         [VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
2558         [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
2559         [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
2560         [VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
2561         [VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
2562         [VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
2563         [VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
2564         [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
2565         [VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
2566         [VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
2567         [VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
2568         [VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
2569 };
2570
2571 static int vop2_esmart_init(struct vop2_win *win)
2572 {
2573         struct vop2 *vop2 = win->vop2;
2574         struct reg_field *esmart_regs;
2575         int ret, i;
2576
2577         esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs),
2578                               GFP_KERNEL);
2579         if (!esmart_regs)
2580                 return -ENOMEM;
2581
2582         for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++)
2583                 if (esmart_regs[i].reg != 0xffffffff)
2584                         esmart_regs[i].reg += win->offset;
2585
2586         ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
2587                                            esmart_regs,
2588                                            ARRAY_SIZE(vop2_esmart_regs));
2589
2590         kfree(esmart_regs);
2591
2592         return ret;
2593 };
2594
2595 static int vop2_win_init(struct vop2 *vop2)
2596 {
2597         const struct vop2_data *vop2_data = vop2->data;
2598         struct vop2_win *win;
2599         int i, ret;
2600
2601         for (i = 0; i < vop2_data->win_size; i++) {
2602                 const struct vop2_win_data *win_data = &vop2_data->win[i];
2603
2604                 win = &vop2->win[i];
2605                 win->data = win_data;
2606                 win->type = win_data->type;
2607                 win->offset = win_data->base;
2608                 win->win_id = i;
2609                 win->vop2 = vop2;
2610                 if (vop2_cluster_window(win))
2611                         ret = vop2_cluster_init(win);
2612                 else
2613                         ret = vop2_esmart_init(win);
2614                 if (ret)
2615                         return ret;
2616         }
2617
2618         vop2->registered_num_wins = vop2_data->win_size;
2619
2620         return 0;
2621 }
2622
2623 /*
2624  * The window registers are only updated when config done is written.
2625  * Until that they read back the old value. As we read-modify-write
2626  * these registers mark them as non-volatile. This makes sure we read
2627  * the new values from the regmap register cache.
2628  */
2629 static const struct regmap_range vop2_nonvolatile_range[] = {
2630         regmap_reg_range(0x1000, 0x23ff),
2631 };
2632
2633 static const struct regmap_access_table vop2_volatile_table = {
2634         .no_ranges = vop2_nonvolatile_range,
2635         .n_no_ranges = ARRAY_SIZE(vop2_nonvolatile_range),
2636 };
2637
2638 static const struct regmap_config vop2_regmap_config = {
2639         .reg_bits       = 32,
2640         .val_bits       = 32,
2641         .reg_stride     = 4,
2642         .max_register   = 0x3000,
2643         .name           = "vop2",
2644         .volatile_table = &vop2_volatile_table,
2645         .cache_type     = REGCACHE_RBTREE,
2646 };
2647
2648 static int vop2_bind(struct device *dev, struct device *master, void *data)
2649 {
2650         struct platform_device *pdev = to_platform_device(dev);
2651         const struct vop2_data *vop2_data;
2652         struct drm_device *drm = data;
2653         struct vop2 *vop2;
2654         struct resource *res;
2655         size_t alloc_size;
2656         int ret;
2657
2658         vop2_data = of_device_get_match_data(dev);
2659         if (!vop2_data)
2660                 return -ENODEV;
2661
2662         /* Allocate vop2 struct and its vop2_win array */
2663         alloc_size = struct_size(vop2, win, vop2_data->win_size);
2664         vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
2665         if (!vop2)
2666                 return -ENOMEM;
2667
2668         vop2->dev = dev;
2669         vop2->data = vop2_data;
2670         vop2->drm = drm;
2671
2672         dev_set_drvdata(dev, vop2);
2673
2674         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vop");
2675         if (!res) {
2676                 drm_err(vop2->drm, "failed to get vop2 register byname\n");
2677                 return -EINVAL;
2678         }
2679
2680         vop2->regs = devm_ioremap_resource(dev, res);
2681         if (IS_ERR(vop2->regs))
2682                 return PTR_ERR(vop2->regs);
2683         vop2->len = resource_size(res);
2684
2685         vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config);
2686         if (IS_ERR(vop2->map))
2687                 return PTR_ERR(vop2->map);
2688
2689         ret = vop2_win_init(vop2);
2690         if (ret)
2691                 return ret;
2692
2693         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma-lut");
2694         if (res) {
2695                 vop2->lut_regs = devm_ioremap_resource(dev, res);
2696                 if (IS_ERR(vop2->lut_regs))
2697                         return PTR_ERR(vop2->lut_regs);
2698         }
2699
2700         vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
2701
2702         vop2->hclk = devm_clk_get(vop2->dev, "hclk");
2703         if (IS_ERR(vop2->hclk)) {
2704                 drm_err(vop2->drm, "failed to get hclk source\n");
2705                 return PTR_ERR(vop2->hclk);
2706         }
2707
2708         vop2->aclk = devm_clk_get(vop2->dev, "aclk");
2709         if (IS_ERR(vop2->aclk)) {
2710                 drm_err(vop2->drm, "failed to get aclk source\n");
2711                 return PTR_ERR(vop2->aclk);
2712         }
2713
2714         vop2->irq = platform_get_irq(pdev, 0);
2715         if (vop2->irq < 0) {
2716                 drm_err(vop2->drm, "cannot find irq for vop2\n");
2717                 return vop2->irq;
2718         }
2719
2720         mutex_init(&vop2->vop2_lock);
2721
2722         ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2);
2723         if (ret)
2724                 return ret;
2725
2726         ret = vop2_create_crtcs(vop2);
2727         if (ret)
2728                 return ret;
2729
2730         ret = vop2_find_rgb_encoder(vop2);
2731         if (ret >= 0) {
2732                 vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
2733                                               vop2->drm, ret);
2734                 if (IS_ERR(vop2->rgb)) {
2735                         if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) {
2736                                 ret = PTR_ERR(vop2->rgb);
2737                                 goto err_crtcs;
2738                         }
2739                         vop2->rgb = NULL;
2740                 }
2741         }
2742
2743         rockchip_drm_dma_init_device(vop2->drm, vop2->dev);
2744
2745         pm_runtime_enable(&pdev->dev);
2746
2747         return 0;
2748
2749 err_crtcs:
2750         vop2_destroy_crtcs(vop2);
2751
2752         return ret;
2753 }
2754
2755 static void vop2_unbind(struct device *dev, struct device *master, void *data)
2756 {
2757         struct vop2 *vop2 = dev_get_drvdata(dev);
2758
2759         pm_runtime_disable(dev);
2760
2761         if (vop2->rgb)
2762                 rockchip_rgb_fini(vop2->rgb);
2763
2764         vop2_destroy_crtcs(vop2);
2765 }
2766
2767 const struct component_ops vop2_component_ops = {
2768         .bind = vop2_bind,
2769         .unbind = vop2_unbind,
2770 };
2771 EXPORT_SYMBOL_GPL(vop2_component_ops);
This page took 0.203737 seconds and 4 git commands to generate.