4ef23ac55eb114201740d4ba65a56320b4234c47
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / rockchip / rockchip_drm_vop.c
1 /*
2  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3  * Author:Mark Yao <mark.yao@rock-chips.com>
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <drm/drm.h>
16 #include <drm/drmP.h>
17 #include <drm/drm_atomic.h>
18 #include <drm/drm_crtc.h>
19 #include <drm/drm_crtc_helper.h>
20 #include <drm/drm_plane_helper.h>
21
22 #include <linux/devfreq.h>
23 #include <linux/iopoll.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/platform_device.h>
27 #include <linux/clk.h>
28 #include <linux/of.h>
29 #include <linux/of_device.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/component.h>
32
33 #include <linux/reset.h>
34 #include <linux/delay.h>
35 #include <linux/sort.h>
36 #include <uapi/drm/rockchip_drm.h>
37
38 #include "rockchip_drm_drv.h"
39 #include "rockchip_drm_gem.h"
40 #include "rockchip_drm_fb.h"
41 #include "rockchip_drm_vop.h"
42
43 #define VOP_REG_SUPPORT(vop, reg) \
44                 (!reg.major || (reg.major == VOP_MAJOR(vop->data->version) && \
45                 reg.begin_minor <= VOP_MINOR(vop->data->version) && \
46                 reg.end_minor >= VOP_MINOR(vop->data->version) && \
47                 reg.mask))
48
49 #define VOP_WIN_SUPPORT(vop, win, name) \
50                 VOP_REG_SUPPORT(vop, win->phy->name)
51
52 #define VOP_CTRL_SUPPORT(vop, name) \
53                 VOP_REG_SUPPORT(vop, vop->data->ctrl->name)
54
55 #define VOP_INTR_SUPPORT(vop, name) \
56                 VOP_REG_SUPPORT(vop, vop->data->intr->name)
57
58 #define __REG_SET(x, off, mask, shift, v, write_mask, relaxed) \
59                 vop_mask_write(x, off, mask, shift, v, write_mask, relaxed)
60
61 #define _REG_SET(vop, name, off, reg, mask, v, relaxed) \
62         do { \
63                 if (VOP_REG_SUPPORT(vop, reg)) \
64                         __REG_SET(vop, off + reg.offset, mask, reg.shift, \
65                                   v, reg.write_mask, relaxed); \
66                 else \
67                         dev_dbg(vop->dev, "Warning: not support "#name"\n"); \
68         } while(0)
69
70 #define REG_SET(x, name, off, reg, v, relaxed) \
71                 _REG_SET(x, name, off, reg, reg.mask, v, relaxed)
72 #define REG_SET_MASK(x, name, off, reg, mask, v, relaxed) \
73                 _REG_SET(x, name, off, reg, reg.mask & mask, v, relaxed)
74
75 #define VOP_WIN_SET(x, win, name, v) \
76                 REG_SET(x, name, win->offset, VOP_WIN_NAME(win, name), v, true)
77 #define VOP_WIN_SET_EXT(x, win, ext, name, v) \
78                 REG_SET(x, name, 0, win->ext->name, v, true)
79 #define VOP_SCL_SET(x, win, name, v) \
80                 REG_SET(x, name, win->offset, win->phy->scl->name, v, true)
81 #define VOP_SCL_SET_EXT(x, win, name, v) \
82                 REG_SET(x, name, win->offset, win->phy->scl->ext->name, v, true)
83
84 #define VOP_CTRL_SET(x, name, v) \
85                 REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
86
87 #define VOP_INTR_GET(vop, name) \
88                 vop_read_reg(vop, 0, &vop->data->ctrl->name)
89
90 #define VOP_INTR_SET(vop, name, v) \
91                 REG_SET(vop, name, 0, vop->data->intr->name, \
92                         v, false)
93 #define VOP_INTR_SET_MASK(vop, name, mask, v) \
94                 REG_SET_MASK(vop, name, 0, vop->data->intr->name, \
95                              mask, v, false)
96
97 #define VOP_INTR_SET_TYPE(vop, name, type, v) \
98         do { \
99                 int i, reg = 0, mask = 0; \
100                 for (i = 0; i < vop->data->intr->nintrs; i++) { \
101                         if (vop->data->intr->intrs[i] & type) { \
102                                 reg |= (v) << i; \
103                                 mask |= 1 << i; \
104                         } \
105                 } \
106                 VOP_INTR_SET_MASK(vop, name, mask, reg); \
107         } while (0)
108 #define VOP_INTR_GET_TYPE(vop, name, type) \
109                 vop_get_intr_type(vop, &vop->data->intr->name, type)
110
111 #define VOP_CTRL_GET(x, name) \
112                 vop_read_reg(x, 0, &vop->data->ctrl->name)
113
114 #define VOP_WIN_GET(x, win, name) \
115                 vop_read_reg(x, win->offset, &VOP_WIN_NAME(win, name))
116
117 #define VOP_WIN_NAME(win, name) \
118                 (vop_get_win_phy(win, &win->phy->name)->name)
119
120 #define VOP_WIN_GET_YRGBADDR(vop, win) \
121                 vop_readl(vop, win->offset + VOP_WIN_NAME(win, yrgb_mst).offset)
122
123 #define to_vop(x) container_of(x, struct vop, crtc)
124 #define to_vop_win(x) container_of(x, struct vop_win, base)
125 #define to_vop_plane_state(x) container_of(x, struct vop_plane_state, base)
126
127 struct vop_zpos {
128         int win_id;
129         int zpos;
130 };
131
132 struct vop_plane_state {
133         struct drm_plane_state base;
134         int format;
135         int zpos;
136         unsigned int logo_ymirror;
137         struct drm_rect src;
138         struct drm_rect dest;
139         dma_addr_t yrgb_mst;
140         dma_addr_t uv_mst;
141         const uint32_t *y2r_table;
142         const uint32_t *r2r_table;
143         const uint32_t *r2y_table;
144         bool enable;
145 };
146
147 struct vop_win {
148         struct vop_win *parent;
149         struct drm_plane base;
150
151         int win_id;
152         int area_id;
153         uint32_t offset;
154         enum drm_plane_type type;
155         const struct vop_win_phy *phy;
156         const struct vop_csc *csc;
157         const uint32_t *data_formats;
158         uint32_t nformats;
159         struct vop *vop;
160
161         struct drm_property *rotation_prop;
162         struct vop_plane_state state;
163 };
164
165 struct vop {
166         struct drm_crtc crtc;
167         struct device *dev;
168         struct drm_device *drm_dev;
169         struct drm_property *plane_zpos_prop;
170         struct drm_property *plane_feature_prop;
171         struct drm_property *feature_prop;
172         bool is_iommu_enabled;
173         bool is_iommu_needed;
174         bool is_enabled;
175
176         /* mutex vsync_ work */
177         struct mutex vsync_mutex;
178         bool vsync_work_pending;
179         bool loader_protect;
180         struct completion dsp_hold_completion;
181         struct completion wait_update_complete;
182         struct drm_pending_vblank_event *event;
183
184         struct completion line_flag_completion;
185
186         const struct vop_data *data;
187         int num_wins;
188
189         uint32_t *regsbak;
190         void __iomem *regs;
191
192         /* physical map length of vop register */
193         uint32_t len;
194
195         void __iomem *lut_regs;
196         u32 *lut;
197         u32 lut_len;
198         bool lut_active;
199
200         /* one time only one process allowed to config the register */
201         spinlock_t reg_lock;
202         /* lock vop irq reg */
203         spinlock_t irq_lock;
204         /* mutex vop enable and disable */
205         struct mutex vop_lock;
206
207         unsigned int irq;
208
209         /* vop AHP clk */
210         struct clk *hclk;
211         /* vop dclk */
212         struct clk *dclk;
213         /* vop share memory frequency */
214         struct clk *aclk;
215         /* vop source handling, optional */
216         struct clk *dclk_source;
217
218         /* vop dclk reset */
219         struct reset_control *dclk_rst;
220
221         struct devfreq *devfreq;
222         struct notifier_block dmc_nb;
223
224         struct vop_win win[];
225 };
226
227 struct vop *dmc_vop;
228
229 static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
230 {
231         writel(v, vop->regs + offset);
232         vop->regsbak[offset >> 2] = v;
233 }
234
235 static inline uint32_t vop_readl(struct vop *vop, uint32_t offset)
236 {
237         return readl(vop->regs + offset);
238 }
239
240 static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
241                                     const struct vop_reg *reg)
242 {
243         return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
244 }
245
246 static inline void vop_mask_write(struct vop *vop, uint32_t offset,
247                                   uint32_t mask, uint32_t shift, uint32_t v,
248                                   bool write_mask, bool relaxed)
249 {
250         if (!mask)
251                 return;
252
253         if (write_mask) {
254                 v = ((v & mask) << shift) | (mask << (shift + 16));
255         } else {
256                 uint32_t cached_val = vop->regsbak[offset >> 2];
257
258                 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
259                 vop->regsbak[offset >> 2] = v;
260         }
261
262         if (relaxed)
263                 writel_relaxed(v, vop->regs + offset);
264         else
265                 writel(v, vop->regs + offset);
266 }
267
268 static inline const struct vop_win_phy *
269 vop_get_win_phy(struct vop_win *win, const struct vop_reg *reg)
270 {
271         if (!reg->mask && win->parent)
272                 return win->parent->phy;
273
274         return win->phy;
275 }
276
277 static inline uint32_t vop_get_intr_type(struct vop *vop,
278                                          const struct vop_reg *reg, int type)
279 {
280         uint32_t i, ret = 0;
281         uint32_t regs = vop_read_reg(vop, 0, reg);
282
283         for (i = 0; i < vop->data->intr->nintrs; i++) {
284                 if ((type & vop->data->intr->intrs[i]) && (regs & 1 << i))
285                         ret |= vop->data->intr->intrs[i];
286         }
287
288         return ret;
289 }
290
291 static void vop_load_csc_table(struct vop *vop, u32 offset, const u32 *table)
292 {
293         int i;
294
295         if (!table)
296                 return;
297
298         for (i = 0; i < 8; i++)
299                 vop_writel(vop, offset + i * 4, table[i]);
300 }
301
302 static inline void vop_cfg_done(struct vop *vop)
303 {
304         VOP_CTRL_SET(vop, cfg_done, 1);
305 }
306
307 static bool vop_is_allwin_disabled(struct vop *vop)
308 {
309         int i;
310
311         for (i = 0; i < vop->num_wins; i++) {
312                 struct vop_win *win = &vop->win[i];
313
314                 if (VOP_WIN_GET(vop, win, enable) != 0)
315                         return false;
316         }
317
318         return true;
319 }
320
321 static bool vop_is_cfg_done_complete(struct vop *vop)
322 {
323         return VOP_CTRL_GET(vop, cfg_done) ? false : true;
324 }
325
326 static bool vop_fs_irq_is_active(struct vop *vop)
327 {
328         return VOP_INTR_GET_TYPE(vop, status, FS_INTR);
329 }
330
331 static bool vop_line_flag_is_active(struct vop *vop)
332 {
333         return VOP_INTR_GET_TYPE(vop, status, LINE_FLAG_INTR);
334 }
335
336 static inline void vop_write_lut(struct vop *vop, uint32_t offset, uint32_t v)
337 {
338         writel(v, vop->lut_regs + offset);
339 }
340
341 static inline uint32_t vop_read_lut(struct vop *vop, uint32_t offset)
342 {
343         return readl(vop->lut_regs + offset);
344 }
345
346 static bool has_rb_swapped(uint32_t format)
347 {
348         switch (format) {
349         case DRM_FORMAT_XBGR8888:
350         case DRM_FORMAT_ABGR8888:
351         case DRM_FORMAT_BGR888:
352         case DRM_FORMAT_BGR565:
353                 return true;
354         default:
355                 return false;
356         }
357 }
358
359 static enum vop_data_format vop_convert_format(uint32_t format)
360 {
361         switch (format) {
362         case DRM_FORMAT_XRGB8888:
363         case DRM_FORMAT_ARGB8888:
364         case DRM_FORMAT_XBGR8888:
365         case DRM_FORMAT_ABGR8888:
366                 return VOP_FMT_ARGB8888;
367         case DRM_FORMAT_RGB888:
368         case DRM_FORMAT_BGR888:
369                 return VOP_FMT_RGB888;
370         case DRM_FORMAT_RGB565:
371         case DRM_FORMAT_BGR565:
372                 return VOP_FMT_RGB565;
373         case DRM_FORMAT_NV12:
374         case DRM_FORMAT_NV12_10:
375                 return VOP_FMT_YUV420SP;
376         case DRM_FORMAT_NV16:
377         case DRM_FORMAT_NV16_10:
378                 return VOP_FMT_YUV422SP;
379         case DRM_FORMAT_NV24:
380         case DRM_FORMAT_NV24_10:
381                 return VOP_FMT_YUV444SP;
382         default:
383                 DRM_ERROR("unsupport format[%08x]\n", format);
384                 return -EINVAL;
385         }
386 }
387
388 static bool is_yuv_output(uint32_t bus_format)
389 {
390         switch (bus_format) {
391         case MEDIA_BUS_FMT_YUV8_1X24:
392         case MEDIA_BUS_FMT_YUV10_1X30:
393         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
394         case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
395                 return true;
396         default:
397                 return false;
398         }
399 }
400
401 static bool is_yuv_support(uint32_t format)
402 {
403         switch (format) {
404         case DRM_FORMAT_NV12:
405         case DRM_FORMAT_NV12_10:
406         case DRM_FORMAT_NV16:
407         case DRM_FORMAT_NV16_10:
408         case DRM_FORMAT_NV24:
409         case DRM_FORMAT_NV24_10:
410                 return true;
411         default:
412                 return false;
413         }
414 }
415
416 static bool is_yuv_10bit(uint32_t format)
417 {
418         switch (format) {
419         case DRM_FORMAT_NV12_10:
420         case DRM_FORMAT_NV16_10:
421         case DRM_FORMAT_NV24_10:
422                 return true;
423         default:
424                 return false;
425         }
426 }
427
428 static bool is_alpha_support(uint32_t format)
429 {
430         switch (format) {
431         case DRM_FORMAT_ARGB8888:
432         case DRM_FORMAT_ABGR8888:
433                 return true;
434         default:
435                 return false;
436         }
437 }
438
439 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
440                                   uint32_t dst, bool is_horizontal,
441                                   int vsu_mode, int *vskiplines)
442 {
443         uint16_t val = 1 << SCL_FT_DEFAULT_FIXPOINT_SHIFT;
444
445         if (is_horizontal) {
446                 if (mode == SCALE_UP)
447                         val = GET_SCL_FT_BIC(src, dst);
448                 else if (mode == SCALE_DOWN)
449                         val = GET_SCL_FT_BILI_DN(src, dst);
450         } else {
451                 if (mode == SCALE_UP) {
452                         if (vsu_mode == SCALE_UP_BIL)
453                                 val = GET_SCL_FT_BILI_UP(src, dst);
454                         else
455                                 val = GET_SCL_FT_BIC(src, dst);
456                 } else if (mode == SCALE_DOWN) {
457                         if (vskiplines) {
458                                 *vskiplines = scl_get_vskiplines(src, dst);
459                                 val = scl_get_bili_dn_vskip(src, dst,
460                                                             *vskiplines);
461                         } else {
462                                 val = GET_SCL_FT_BILI_DN(src, dst);
463                         }
464                 }
465         }
466
467         return val;
468 }
469
470 static void scl_vop_cal_scl_fac(struct vop *vop, struct vop_win *win,
471                                 uint32_t src_w, uint32_t src_h, uint32_t dst_w,
472                                 uint32_t dst_h, uint32_t pixel_format)
473 {
474         uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
475         uint16_t cbcr_hor_scl_mode = SCALE_NONE;
476         uint16_t cbcr_ver_scl_mode = SCALE_NONE;
477         int hsub = drm_format_horz_chroma_subsampling(pixel_format);
478         int vsub = drm_format_vert_chroma_subsampling(pixel_format);
479         bool is_yuv = is_yuv_support(pixel_format);
480         uint16_t cbcr_src_w = src_w / hsub;
481         uint16_t cbcr_src_h = src_h / vsub;
482         uint16_t vsu_mode;
483         uint16_t lb_mode;
484         uint32_t val;
485         int vskiplines = 0;
486
487         if (!win->phy->scl)
488                 return;
489
490         if (!win->phy->scl->ext) {
491                 VOP_SCL_SET(vop, win, scale_yrgb_x,
492                             scl_cal_scale2(src_w, dst_w));
493                 VOP_SCL_SET(vop, win, scale_yrgb_y,
494                             scl_cal_scale2(src_h, dst_h));
495                 if (is_yuv) {
496                         VOP_SCL_SET(vop, win, scale_cbcr_x,
497                                     scl_cal_scale2(cbcr_src_w, dst_w));
498                         VOP_SCL_SET(vop, win, scale_cbcr_y,
499                                     scl_cal_scale2(cbcr_src_h, dst_h));
500                 }
501                 return;
502         }
503
504         yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
505         yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
506
507         if (is_yuv) {
508                 cbcr_hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w);
509                 cbcr_ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h);
510                 if (cbcr_hor_scl_mode == SCALE_DOWN)
511                         lb_mode = scl_vop_cal_lb_mode(dst_w, true);
512                 else
513                         lb_mode = scl_vop_cal_lb_mode(cbcr_src_w, true);
514         } else {
515                 if (yrgb_hor_scl_mode == SCALE_DOWN)
516                         lb_mode = scl_vop_cal_lb_mode(dst_w, false);
517                 else
518                         lb_mode = scl_vop_cal_lb_mode(src_w, false);
519         }
520
521         VOP_SCL_SET_EXT(vop, win, lb_mode, lb_mode);
522         if (lb_mode == LB_RGB_3840X2) {
523                 if (yrgb_ver_scl_mode != SCALE_NONE) {
524                         DRM_ERROR("ERROR : not allow yrgb ver scale\n");
525                         return;
526                 }
527                 if (cbcr_ver_scl_mode != SCALE_NONE) {
528                         DRM_ERROR("ERROR : not allow cbcr ver scale\n");
529                         return;
530                 }
531                 vsu_mode = SCALE_UP_BIL;
532         } else if (lb_mode == LB_RGB_2560X4) {
533                 vsu_mode = SCALE_UP_BIL;
534         } else {
535                 vsu_mode = SCALE_UP_BIC;
536         }
537
538         val = scl_vop_cal_scale(yrgb_hor_scl_mode, src_w, dst_w,
539                                 true, 0, NULL);
540         VOP_SCL_SET(vop, win, scale_yrgb_x, val);
541         val = scl_vop_cal_scale(yrgb_ver_scl_mode, src_h, dst_h,
542                                 false, vsu_mode, &vskiplines);
543         VOP_SCL_SET(vop, win, scale_yrgb_y, val);
544
545         VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt4, vskiplines == 4);
546         VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt2, vskiplines == 2);
547
548         VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, yrgb_hor_scl_mode);
549         VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, yrgb_ver_scl_mode);
550         VOP_SCL_SET_EXT(vop, win, yrgb_hsd_mode, SCALE_DOWN_BIL);
551         VOP_SCL_SET_EXT(vop, win, yrgb_vsd_mode, SCALE_DOWN_BIL);
552         VOP_SCL_SET_EXT(vop, win, yrgb_vsu_mode, vsu_mode);
553         if (is_yuv) {
554                 vskiplines = 0;
555
556                 val = scl_vop_cal_scale(cbcr_hor_scl_mode, cbcr_src_w,
557                                         dst_w, true, 0, NULL);
558                 VOP_SCL_SET(vop, win, scale_cbcr_x, val);
559                 val = scl_vop_cal_scale(cbcr_ver_scl_mode, cbcr_src_h,
560                                         dst_h, false, vsu_mode, &vskiplines);
561                 VOP_SCL_SET(vop, win, scale_cbcr_y, val);
562
563                 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt4, vskiplines == 4);
564                 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt2, vskiplines == 2);
565                 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, cbcr_hor_scl_mode);
566                 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, cbcr_ver_scl_mode);
567                 VOP_SCL_SET_EXT(vop, win, cbcr_hsd_mode, SCALE_DOWN_BIL);
568                 VOP_SCL_SET_EXT(vop, win, cbcr_vsd_mode, SCALE_DOWN_BIL);
569                 VOP_SCL_SET_EXT(vop, win, cbcr_vsu_mode, vsu_mode);
570         }
571 }
572
573 /*
574  * rk3399 colorspace path:
575  *      Input        Win csc                     Output
576  * 1. YUV(2020)  --> Y2R->2020To709->R2Y   --> YUV_OUTPUT(601/709)
577  *    RGB        --> R2Y                  __/
578  *
579  * 2. YUV(2020)  --> bypasss               --> YUV_OUTPUT(2020)
580  *    RGB        --> 709To2020->R2Y       __/
581  *
582  * 3. YUV(2020)  --> Y2R->2020To709        --> RGB_OUTPUT(709)
583  *    RGB        --> R2Y                  __/
584  *
585  * 4. YUV(601/709)-> Y2R->709To2020->R2Y   --> YUV_OUTPUT(2020)
586  *    RGB        --> 709To2020->R2Y       __/
587  *
588  * 5. YUV(601/709)-> bypass                --> YUV_OUTPUT(709)
589  *    RGB        --> R2Y                  __/
590  *
591  * 6. YUV(601/709)-> bypass                --> YUV_OUTPUT(601)
592  *    RGB        --> R2Y(601)             __/
593  *
594  * 7. YUV        --> Y2R(709)              --> RGB_OUTPUT(709)
595  *    RGB        --> bypass               __/
596  *
597  * 8. RGB        --> 709To2020->R2Y        --> YUV_OUTPUT(2020)
598  *
599  * 9. RGB        --> R2Y(709)              --> YUV_OUTPUT(709)
600  *
601  * 10. RGB       --> R2Y(601)              --> YUV_OUTPUT(601)
602  *
603  * 11. RGB       --> bypass                --> RGB_OUTPUT(709)
604  */
605 static int vop_csc_setup(const struct vop_csc_table *csc_table,
606                          bool is_input_yuv, bool is_output_yuv,
607                          int input_csc, int output_csc,
608                          const uint32_t **y2r_table,
609                          const uint32_t **r2r_table,
610                          const uint32_t **r2y_table)
611 {
612         *y2r_table = NULL;
613         *r2r_table = NULL;
614         *r2y_table = NULL;
615
616         if (is_output_yuv) {
617                 if (output_csc == CSC_BT2020) {
618                         if (is_input_yuv) {
619                                 if (input_csc == CSC_BT2020)
620                                         return 0;
621                                 *y2r_table = csc_table->y2r_bt709;
622                         }
623                         if (input_csc != CSC_BT2020)
624                                 *r2r_table = csc_table->r2r_bt709_to_bt2020;
625                         *r2y_table = csc_table->r2y_bt2020;
626                 } else {
627                         if (is_input_yuv && input_csc == CSC_BT2020)
628                                 *y2r_table = csc_table->y2r_bt2020;
629                         if (input_csc == CSC_BT2020)
630                                 *r2r_table = csc_table->r2r_bt2020_to_bt709;
631                         if (!is_input_yuv || *y2r_table) {
632                                 if (output_csc == CSC_BT709)
633                                         *r2y_table = csc_table->r2y_bt709;
634                                 else
635                                         *r2y_table = csc_table->r2y_bt601;
636                         }
637                 }
638         } else {
639                 if (!is_input_yuv)
640                         return 0;
641
642                 /*
643                  * is possible use bt2020 on rgb mode?
644                  */
645                 if (WARN_ON(output_csc == CSC_BT2020))
646                         return -EINVAL;
647
648                 if (input_csc == CSC_BT2020)
649                         *y2r_table = csc_table->y2r_bt2020;
650                 else if (input_csc == CSC_BT709)
651                         *y2r_table = csc_table->y2r_bt709;
652                 else
653                         *y2r_table = csc_table->y2r_bt601;
654
655                 if (input_csc == CSC_BT2020)
656                         /*
657                          * We don't have bt601 to bt709 table, force use bt709.
658                          */
659                         *r2r_table = csc_table->r2r_bt2020_to_bt709;
660         }
661
662         return 0;
663 }
664
665 static int vop_csc_atomic_check(struct drm_crtc *crtc,
666                                 struct drm_crtc_state *crtc_state)
667 {
668         struct vop *vop = to_vop(crtc);
669         struct drm_atomic_state *state = crtc_state->state;
670         struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
671         const struct vop_csc_table *csc_table = vop->data->csc_table;
672         struct drm_plane_state *pstate;
673         struct drm_plane *plane;
674         bool is_input_yuv, is_output_yuv;
675         int ret;
676
677         if (!csc_table)
678                 return 0;
679
680         is_output_yuv = is_yuv_output(s->bus_format);
681
682         drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
683                 struct vop_plane_state *vop_plane_state;
684
685                 pstate = drm_atomic_get_plane_state(state, plane);
686                 if (IS_ERR(pstate))
687                         return PTR_ERR(pstate);
688                 vop_plane_state = to_vop_plane_state(pstate);
689
690                 if (!pstate->fb)
691                         continue;
692                 is_input_yuv = is_yuv_support(pstate->fb->pixel_format);
693
694                 /*
695                  * TODO: force set input and output csc mode.
696                  */
697                 ret = vop_csc_setup(csc_table, is_input_yuv, is_output_yuv,
698                                     CSC_BT709, CSC_BT709,
699                                     &vop_plane_state->y2r_table,
700                                     &vop_plane_state->r2r_table,
701                                     &vop_plane_state->r2y_table);
702                 if (ret)
703                         return ret;
704         }
705
706         return 0;
707 }
708
709 static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
710 {
711         unsigned long flags;
712
713         spin_lock_irqsave(&vop->irq_lock, flags);
714
715         VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1);
716         VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1);
717
718         spin_unlock_irqrestore(&vop->irq_lock, flags);
719 }
720
721 static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
722 {
723         unsigned long flags;
724
725         spin_lock_irqsave(&vop->irq_lock, flags);
726
727         VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0);
728
729         spin_unlock_irqrestore(&vop->irq_lock, flags);
730 }
731
732 /*
733  * (1) each frame starts at the start of the Vsync pulse which is signaled by
734  *     the "FRAME_SYNC" interrupt.
735  * (2) the active data region of each frame ends at dsp_vact_end
736  * (3) we should program this same number (dsp_vact_end) into dsp_line_frag_num,
737  *      to get "LINE_FLAG" interrupt at the end of the active on screen data.
738  *
739  * VOP_INTR_CTRL0.dsp_line_frag_num = VOP_DSP_VACT_ST_END.dsp_vact_end
740  * Interrupts
741  * LINE_FLAG -------------------------------+
742  * FRAME_SYNC ----+                         |
743  *                |                         |
744  *                v                         v
745  *                | Vsync | Vbp |  Vactive  | Vfp |
746  *                        ^     ^           ^     ^
747  *                        |     |           |     |
748  *                        |     |           |     |
749  * dsp_vs_end ------------+     |           |     |   VOP_DSP_VTOTAL_VS_END
750  * dsp_vact_start --------------+           |     |   VOP_DSP_VACT_ST_END
751  * dsp_vact_end ----------------------------+     |   VOP_DSP_VACT_ST_END
752  * dsp_total -------------------------------------+   VOP_DSP_VTOTAL_VS_END
753  */
754 static bool vop_line_flag_irq_is_enabled(struct vop *vop)
755 {
756         uint32_t line_flag_irq;
757         unsigned long flags;
758
759         spin_lock_irqsave(&vop->irq_lock, flags);
760
761         line_flag_irq = VOP_INTR_GET_TYPE(vop, enable, LINE_FLAG_INTR);
762
763         spin_unlock_irqrestore(&vop->irq_lock, flags);
764
765         return !!line_flag_irq;
766 }
767
768 static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
769 {
770         unsigned long flags;
771
772         if (WARN_ON(!vop->is_enabled))
773                 return;
774
775         spin_lock_irqsave(&vop->irq_lock, flags);
776
777         VOP_INTR_SET(vop, line_flag_num[0], line_num);
778         VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
779         VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
780
781         spin_unlock_irqrestore(&vop->irq_lock, flags);
782 }
783
784 static void vop_line_flag_irq_disable(struct vop *vop)
785 {
786         unsigned long flags;
787
788         if (WARN_ON(!vop->is_enabled))
789                 return;
790
791         spin_lock_irqsave(&vop->irq_lock, flags);
792
793         VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 0);
794
795         spin_unlock_irqrestore(&vop->irq_lock, flags);
796 }
797
798 static void vop_crtc_load_lut(struct drm_crtc *crtc)
799 {
800         struct vop *vop = to_vop(crtc);
801         int i, dle, lut_idx;
802
803         if (!vop->is_enabled || !vop->lut || !vop->lut_regs)
804                 return;
805
806         if (WARN_ON(!drm_modeset_is_locked(&crtc->mutex)))
807                 return;
808
809         if (!VOP_CTRL_SUPPORT(vop, update_gamma_lut)) {
810                 spin_lock(&vop->reg_lock);
811                 VOP_CTRL_SET(vop, dsp_lut_en, 0);
812                 vop_cfg_done(vop);
813                 spin_unlock(&vop->reg_lock);
814
815 #define CTRL_GET(name) VOP_CTRL_GET(vop, name)
816                 readx_poll_timeout(CTRL_GET, dsp_lut_en,
817                                 dle, !dle, 5, 33333);
818         } else {
819                 lut_idx = CTRL_GET(lut_buffer_index);
820         }
821
822         for (i = 0; i < vop->lut_len; i++)
823                 vop_write_lut(vop, i << 2, vop->lut[i]);
824
825         spin_lock(&vop->reg_lock);
826
827         VOP_CTRL_SET(vop, dsp_lut_en, 1);
828         VOP_CTRL_SET(vop, update_gamma_lut, 1);
829         vop_cfg_done(vop);
830         vop->lut_active = true;
831
832         spin_unlock(&vop->reg_lock);
833
834         if (VOP_CTRL_SUPPORT(vop, update_gamma_lut)) {
835                 readx_poll_timeout(CTRL_GET, lut_buffer_index,
836                                    dle, dle != lut_idx, 5, 33333);
837                 /* FIXME:
838                  * update_gamma value auto clean to 0 by HW, should not
839                  * bakeup it.
840                  */
841                 VOP_CTRL_SET(vop, update_gamma_lut, 0);
842         }
843 #undef CTRL_GET
844 }
845
846 void rockchip_vop_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
847                                     u16 blue, int regno)
848 {
849         struct vop *vop = to_vop(crtc);
850         u32 lut_len = vop->lut_len;
851         u32 r, g, b;
852
853         if (regno >= lut_len || !vop->lut)
854                 return;
855
856         r = red * (lut_len - 1) / 0xffff;
857         g = green * (lut_len - 1) / 0xffff;
858         b = blue * (lut_len - 1) / 0xffff;
859         vop->lut[regno] = r * lut_len * lut_len + g * lut_len + b;
860 }
861
862 void rockchip_vop_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
863                                     u16 *blue, int regno)
864 {
865         struct vop *vop = to_vop(crtc);
866         u32 lut_len = vop->lut_len;
867         u32 r, g, b;
868
869         if (regno >= lut_len || !vop->lut)
870                 return;
871
872         r = (vop->lut[regno] / lut_len / lut_len) & (lut_len - 1);
873         g = (vop->lut[regno] / lut_len) & (lut_len - 1);
874         b = vop->lut[regno] & (lut_len - 1);
875         *red = r * 0xffff / (lut_len - 1);
876         *green = g * 0xffff / (lut_len - 1);
877         *blue = b * 0xffff / (lut_len - 1);
878 }
879
880 static void vop_power_enable(struct drm_crtc *crtc)
881 {
882         struct vop *vop = to_vop(crtc);
883         int ret;
884
885         ret = clk_prepare_enable(vop->hclk);
886         if (ret < 0) {
887                 dev_err(vop->dev, "failed to enable hclk - %d\n", ret);
888                 return;
889         }
890
891         ret = clk_prepare_enable(vop->dclk);
892         if (ret < 0) {
893                 dev_err(vop->dev, "failed to enable dclk - %d\n", ret);
894                 goto err_disable_hclk;
895         }
896
897         ret = clk_prepare_enable(vop->aclk);
898         if (ret < 0) {
899                 dev_err(vop->dev, "failed to enable aclk - %d\n", ret);
900                 goto err_disable_dclk;
901         }
902
903         ret = pm_runtime_get_sync(vop->dev);
904         if (ret < 0) {
905                 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
906                 return;
907         }
908
909         memcpy(vop->regsbak, vop->regs, vop->len);
910
911         vop->is_enabled = true;
912
913         return;
914
915 err_disable_dclk:
916         clk_disable_unprepare(vop->dclk);
917 err_disable_hclk:
918         clk_disable_unprepare(vop->hclk);
919 }
920
921 static void vop_initial(struct drm_crtc *crtc)
922 {
923         struct vop *vop = to_vop(crtc);
924         int i;
925
926         vop_power_enable(crtc);
927
928         VOP_CTRL_SET(vop, global_regdone_en, 1);
929         VOP_CTRL_SET(vop, dsp_blank, 0);
930
931         /*
932          * restore the lut table.
933          */
934         if (vop->lut_active)
935                 vop_crtc_load_lut(crtc);
936
937         /*
938          * We need to make sure that all windows are disabled before resume
939          * the crtc. Otherwise we might try to scan from a destroyed
940          * buffer later.
941          */
942         for (i = 0; i < vop->num_wins; i++) {
943                 struct vop_win *win = &vop->win[i];
944                 int channel = i * 2 + 1;
945
946                 VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
947                 if (win->phy->scl && win->phy->scl->ext) {
948                         VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
949                         VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
950                         VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
951                         VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
952                 }
953                 VOP_WIN_SET(vop, win, enable, 0);
954                 VOP_WIN_SET(vop, win, gate, 1);
955         }
956         VOP_CTRL_SET(vop, afbdc_en, 0);
957 }
958
959 static void vop_crtc_disable(struct drm_crtc *crtc)
960 {
961         struct vop *vop = to_vop(crtc);
962
963         mutex_lock(&vop->vop_lock);
964         drm_crtc_vblank_off(crtc);
965
966         /*
967          * Vop standby will take effect at end of current frame,
968          * if dsp hold valid irq happen, it means standby complete.
969          *
970          * we must wait standby complete when we want to disable aclk,
971          * if not, memory bus maybe dead.
972          */
973         reinit_completion(&vop->dsp_hold_completion);
974         vop_dsp_hold_valid_irq_enable(vop);
975
976         spin_lock(&vop->reg_lock);
977
978         VOP_CTRL_SET(vop, standby, 1);
979
980         spin_unlock(&vop->reg_lock);
981
982         WARN_ON(!wait_for_completion_timeout(&vop->dsp_hold_completion,
983                                              msecs_to_jiffies(50)));
984
985         vop_dsp_hold_valid_irq_disable(vop);
986
987         disable_irq(vop->irq);
988
989         vop->is_enabled = false;
990         if (vop->is_iommu_enabled) {
991                 /*
992                  * vop standby complete, so iommu detach is safe.
993                  */
994                 rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
995                 vop->is_iommu_enabled = false;
996         }
997
998         pm_runtime_put(vop->dev);
999         clk_disable_unprepare(vop->dclk);
1000         clk_disable_unprepare(vop->aclk);
1001         clk_disable_unprepare(vop->hclk);
1002         mutex_unlock(&vop->vop_lock);
1003 }
1004
1005 static void vop_plane_destroy(struct drm_plane *plane)
1006 {
1007         drm_plane_cleanup(plane);
1008 }
1009
1010 static int vop_plane_prepare_fb(struct drm_plane *plane,
1011                                 const struct drm_plane_state *new_state)
1012 {
1013         if (plane->state->fb)
1014                 drm_framebuffer_reference(plane->state->fb);
1015
1016         return 0;
1017 }
1018
1019 static void vop_plane_cleanup_fb(struct drm_plane *plane,
1020                                  const struct drm_plane_state *old_state)
1021 {
1022         if (old_state->fb)
1023                 drm_framebuffer_unreference(old_state->fb);
1024 }
1025
1026 static int vop_plane_atomic_check(struct drm_plane *plane,
1027                            struct drm_plane_state *state)
1028 {
1029         struct drm_crtc *crtc = state->crtc;
1030         struct drm_framebuffer *fb = state->fb;
1031         struct vop_win *win = to_vop_win(plane);
1032         struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
1033         struct drm_crtc_state *crtc_state;
1034         const struct vop_data *vop_data;
1035         struct vop *vop;
1036         bool visible;
1037         int ret;
1038         struct drm_rect *dest = &vop_plane_state->dest;
1039         struct drm_rect *src = &vop_plane_state->src;
1040         struct drm_rect clip;
1041         int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
1042                                         DRM_PLANE_HELPER_NO_SCALING;
1043         int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
1044                                         DRM_PLANE_HELPER_NO_SCALING;
1045         unsigned long offset;
1046         dma_addr_t dma_addr;
1047         u16 vdisplay;
1048
1049         crtc = crtc ? crtc : plane->state->crtc;
1050         /*
1051          * Both crtc or plane->state->crtc can be null.
1052          */
1053         if (!crtc || !fb)
1054                 goto out_disable;
1055
1056         crtc_state = drm_atomic_get_crtc_state(state->state, crtc);
1057         if (IS_ERR(crtc_state))
1058                 return PTR_ERR(crtc_state);
1059
1060         src->x1 = state->src_x;
1061         src->y1 = state->src_y;
1062         src->x2 = state->src_x + state->src_w;
1063         src->y2 = state->src_y + state->src_h;
1064         dest->x1 = state->crtc_x;
1065         dest->y1 = state->crtc_y;
1066         dest->x2 = state->crtc_x + state->crtc_w;
1067         dest->y2 = state->crtc_y + state->crtc_h;
1068
1069         vdisplay = crtc_state->adjusted_mode.crtc_vdisplay;
1070         if (crtc_state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
1071                 vdisplay *= 2;
1072
1073         clip.x1 = 0;
1074         clip.y1 = 0;
1075         clip.x2 = crtc_state->adjusted_mode.crtc_hdisplay;
1076         clip.y2 = vdisplay;
1077
1078         ret = drm_plane_helper_check_update(plane, crtc, state->fb,
1079                                             src, dest, &clip,
1080                                             min_scale,
1081                                             max_scale,
1082                                             true, true, &visible);
1083         if (ret)
1084                 return ret;
1085
1086         if (!visible)
1087                 goto out_disable;
1088
1089         vop_plane_state->format = vop_convert_format(fb->pixel_format);
1090         if (vop_plane_state->format < 0)
1091                 return vop_plane_state->format;
1092
1093         vop = to_vop(crtc);
1094         vop_data = vop->data;
1095
1096         if (drm_rect_width(src) >> 16 > vop_data->max_input.width ||
1097             drm_rect_height(src) >> 16 > vop_data->max_input.height) {
1098                 DRM_ERROR("Invalid source: %dx%d. max input: %dx%d\n",
1099                           drm_rect_width(src) >> 16,
1100                           drm_rect_height(src) >> 16,
1101                           vop_data->max_input.width,
1102                           vop_data->max_input.height);
1103                 return -EINVAL;
1104         }
1105
1106         /*
1107          * Src.x1 can be odd when do clip, but yuv plane start point
1108          * need align with 2 pixel.
1109          */
1110         if (is_yuv_support(fb->pixel_format) && ((src->x1 >> 16) % 2)) {
1111                 DRM_ERROR("Invalid Source: Yuv format Can't support odd xpos\n");
1112                 return -EINVAL;
1113         }
1114
1115         offset = (src->x1 >> 16) * drm_format_plane_bpp(fb->pixel_format, 0) / 8;
1116         if (state->rotation & BIT(DRM_REFLECT_Y) ||
1117             (rockchip_fb_is_logo(fb) && vop_plane_state->logo_ymirror))
1118                 offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
1119         else
1120                 offset += (src->y1 >> 16) * fb->pitches[0];
1121
1122         dma_addr = rockchip_fb_get_dma_addr(fb, 0);
1123         vop_plane_state->yrgb_mst = dma_addr + offset + fb->offsets[0];
1124         if (is_yuv_support(fb->pixel_format)) {
1125                 int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
1126                 int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
1127                 int bpp = drm_format_plane_bpp(fb->pixel_format, 1);
1128
1129                 offset = (src->x1 >> 16) * bpp / hsub / 8;
1130                 offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
1131
1132                 dma_addr = rockchip_fb_get_dma_addr(fb, 1);
1133                 dma_addr += offset + fb->offsets[1];
1134                 vop_plane_state->uv_mst = dma_addr;
1135         }
1136
1137         vop_plane_state->enable = true;
1138
1139         return 0;
1140
1141 out_disable:
1142         vop_plane_state->enable = false;
1143         return 0;
1144 }
1145
1146 static void vop_plane_atomic_disable(struct drm_plane *plane,
1147                                      struct drm_plane_state *old_state)
1148 {
1149         struct vop_plane_state *vop_plane_state = to_vop_plane_state(old_state);
1150         struct vop_win *win = to_vop_win(plane);
1151         struct vop *vop = to_vop(old_state->crtc);
1152
1153         if (!old_state->crtc)
1154                 return;
1155
1156         spin_lock(&vop->reg_lock);
1157
1158         /*
1159          * FIXUP: some of the vop scale would be abnormal after windows power
1160          * on/off so deinit scale to scale_none mode.
1161          */
1162         if (win->phy->scl && win->phy->scl->ext) {
1163                 VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
1164                 VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
1165                 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
1166                 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
1167         }
1168         VOP_WIN_SET(vop, win, enable, 0);
1169
1170         spin_unlock(&vop->reg_lock);
1171
1172         vop_plane_state->enable = false;
1173 }
1174
1175 static void vop_plane_atomic_update(struct drm_plane *plane,
1176                 struct drm_plane_state *old_state)
1177 {
1178         struct drm_plane_state *state = plane->state;
1179         struct drm_crtc *crtc = state->crtc;
1180         struct vop_win *win = to_vop_win(plane);
1181         struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
1182         struct rockchip_crtc_state *s;
1183         struct vop *vop;
1184         struct drm_framebuffer *fb = state->fb;
1185         unsigned int actual_w, actual_h;
1186         unsigned int dsp_stx, dsp_sty;
1187         uint32_t act_info, dsp_info, dsp_st;
1188         struct drm_rect *src = &vop_plane_state->src;
1189         struct drm_rect *dest = &vop_plane_state->dest;
1190         const uint32_t *y2r_table = vop_plane_state->y2r_table;
1191         const uint32_t *r2r_table = vop_plane_state->r2r_table;
1192         const uint32_t *r2y_table = vop_plane_state->r2y_table;
1193         int ymirror, xmirror;
1194         uint32_t val;
1195         bool rb_swap;
1196
1197         /*
1198          * can't update plane when vop is disabled.
1199          */
1200         if (!crtc)
1201                 return;
1202
1203         if (!vop_plane_state->enable) {
1204                 vop_plane_atomic_disable(plane, old_state);
1205                 return;
1206         }
1207
1208         actual_w = drm_rect_width(src) >> 16;
1209         actual_h = drm_rect_height(src) >> 16;
1210         act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
1211
1212         dsp_info = (drm_rect_height(dest) - 1) << 16;
1213         dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
1214
1215         dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
1216         dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
1217         dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
1218
1219         ymirror = state->rotation & BIT(DRM_REFLECT_Y) ||
1220                   (rockchip_fb_is_logo(fb) && vop_plane_state->logo_ymirror);
1221         xmirror = !!(state->rotation & BIT(DRM_REFLECT_X));
1222
1223         vop = to_vop(state->crtc);
1224         s = to_rockchip_crtc_state(crtc->state);
1225
1226         spin_lock(&vop->reg_lock);
1227
1228         VOP_WIN_SET(vop, win, xmirror, xmirror);
1229         VOP_WIN_SET(vop, win, ymirror, ymirror);
1230         VOP_WIN_SET(vop, win, format, vop_plane_state->format);
1231         VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2);
1232         VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
1233         if (is_yuv_support(fb->pixel_format)) {
1234                 VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2);
1235                 VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst);
1236         }
1237         VOP_WIN_SET(vop, win, fmt_10, is_yuv_10bit(fb->pixel_format));
1238
1239         scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
1240                             drm_rect_width(dest), drm_rect_height(dest),
1241                             fb->pixel_format);
1242
1243         VOP_WIN_SET(vop, win, act_info, act_info);
1244         VOP_WIN_SET(vop, win, dsp_info, dsp_info);
1245         VOP_WIN_SET(vop, win, dsp_st, dsp_st);
1246
1247         rb_swap = has_rb_swapped(fb->pixel_format);
1248         VOP_WIN_SET(vop, win, rb_swap, rb_swap);
1249
1250         if (is_alpha_support(fb->pixel_format) &&
1251             (s->dsp_layer_sel & 0x3) != win->win_id) {
1252                 VOP_WIN_SET(vop, win, dst_alpha_ctl,
1253                             DST_FACTOR_M0(ALPHA_SRC_INVERSE));
1254                 val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
1255                         SRC_ALPHA_M0(ALPHA_STRAIGHT) |
1256                         SRC_BLEND_M0(ALPHA_PER_PIX) |
1257                         SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
1258                         SRC_FACTOR_M0(ALPHA_ONE);
1259                 VOP_WIN_SET(vop, win, src_alpha_ctl, val);
1260                 VOP_WIN_SET(vop, win, alpha_mode, 1);
1261                 VOP_WIN_SET(vop, win, alpha_en, 1);
1262         } else {
1263                 VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0));
1264                 VOP_WIN_SET(vop, win, alpha_en, 0);
1265         }
1266
1267         if (win->csc) {
1268                 vop_load_csc_table(vop, win->csc->y2r_offset, y2r_table);
1269                 vop_load_csc_table(vop, win->csc->r2r_offset, r2r_table);
1270                 vop_load_csc_table(vop, win->csc->r2y_offset, r2y_table);
1271                 VOP_WIN_SET_EXT(vop, win, csc, y2r_en, !!y2r_table);
1272                 VOP_WIN_SET_EXT(vop, win, csc, r2r_en, !!r2r_table);
1273                 VOP_WIN_SET_EXT(vop, win, csc, r2y_en, !!r2y_table);
1274         }
1275         VOP_WIN_SET(vop, win, enable, 1);
1276         spin_unlock(&vop->reg_lock);
1277         vop->is_iommu_needed = true;
1278 }
1279
1280 static const struct drm_plane_helper_funcs plane_helper_funcs = {
1281         .prepare_fb = vop_plane_prepare_fb,
1282         .cleanup_fb = vop_plane_cleanup_fb,
1283         .atomic_check = vop_plane_atomic_check,
1284         .atomic_update = vop_plane_atomic_update,
1285         .atomic_disable = vop_plane_atomic_disable,
1286 };
1287
1288 void vop_atomic_plane_reset(struct drm_plane *plane)
1289 {
1290         struct vop_win *win = to_vop_win(plane);
1291         struct vop_plane_state *vop_plane_state =
1292                                         to_vop_plane_state(plane->state);
1293
1294         if (plane->state && plane->state->fb)
1295                 drm_framebuffer_unreference(plane->state->fb);
1296
1297         kfree(vop_plane_state);
1298         vop_plane_state = kzalloc(sizeof(*vop_plane_state), GFP_KERNEL);
1299         if (!vop_plane_state)
1300                 return;
1301
1302         vop_plane_state->zpos = win->win_id;
1303         plane->state = &vop_plane_state->base;
1304         plane->state->plane = plane;
1305 }
1306
1307 struct drm_plane_state *
1308 vop_atomic_plane_duplicate_state(struct drm_plane *plane)
1309 {
1310         struct vop_plane_state *old_vop_plane_state;
1311         struct vop_plane_state *vop_plane_state;
1312
1313         if (WARN_ON(!plane->state))
1314                 return NULL;
1315
1316         old_vop_plane_state = to_vop_plane_state(plane->state);
1317         vop_plane_state = kmemdup(old_vop_plane_state,
1318                                   sizeof(*vop_plane_state), GFP_KERNEL);
1319         if (!vop_plane_state)
1320                 return NULL;
1321
1322         __drm_atomic_helper_plane_duplicate_state(plane,
1323                                                   &vop_plane_state->base);
1324
1325         return &vop_plane_state->base;
1326 }
1327
1328 static void vop_atomic_plane_destroy_state(struct drm_plane *plane,
1329                                            struct drm_plane_state *state)
1330 {
1331         struct vop_plane_state *vop_state = to_vop_plane_state(state);
1332
1333         __drm_atomic_helper_plane_destroy_state(plane, state);
1334
1335         kfree(vop_state);
1336 }
1337
1338 static int vop_atomic_plane_set_property(struct drm_plane *plane,
1339                                          struct drm_plane_state *state,
1340                                          struct drm_property *property,
1341                                          uint64_t val)
1342 {
1343         struct rockchip_drm_private *private = plane->dev->dev_private;
1344         struct vop_win *win = to_vop_win(plane);
1345         struct vop_plane_state *plane_state = to_vop_plane_state(state);
1346
1347         if (property == win->vop->plane_zpos_prop) {
1348                 plane_state->zpos = val;
1349                 return 0;
1350         }
1351
1352         if (property == win->rotation_prop) {
1353                 state->rotation = val;
1354                 return 0;
1355         }
1356
1357         if (property == private->logo_ymirror_prop) {
1358                 WARN_ON(!rockchip_fb_is_logo(state->fb));
1359                 plane_state->logo_ymirror = val;
1360                 return 0;
1361         }
1362
1363         DRM_ERROR("failed to set vop plane property\n");
1364         return -EINVAL;
1365 }
1366
1367 static int vop_atomic_plane_get_property(struct drm_plane *plane,
1368                                          const struct drm_plane_state *state,
1369                                          struct drm_property *property,
1370                                          uint64_t *val)
1371 {
1372         struct vop_win *win = to_vop_win(plane);
1373         struct vop_plane_state *plane_state = to_vop_plane_state(state);
1374
1375         if (property == win->vop->plane_zpos_prop) {
1376                 *val = plane_state->zpos;
1377                 return 0;
1378         }
1379
1380         if (property == win->rotation_prop) {
1381                 *val = state->rotation;
1382                 return 0;
1383         }
1384
1385         DRM_ERROR("failed to get vop plane property\n");
1386         return -EINVAL;
1387 }
1388
1389 static const struct drm_plane_funcs vop_plane_funcs = {
1390         .update_plane   = drm_atomic_helper_update_plane,
1391         .disable_plane  = drm_atomic_helper_disable_plane,
1392         .destroy = vop_plane_destroy,
1393         .reset = vop_atomic_plane_reset,
1394         .set_property = drm_atomic_helper_plane_set_property,
1395         .atomic_duplicate_state = vop_atomic_plane_duplicate_state,
1396         .atomic_destroy_state = vop_atomic_plane_destroy_state,
1397         .atomic_set_property = vop_atomic_plane_set_property,
1398         .atomic_get_property = vop_atomic_plane_get_property,
1399 };
1400
1401 static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
1402 {
1403         struct vop *vop = to_vop(crtc);
1404         unsigned long flags;
1405
1406         if (!vop->is_enabled)
1407                 return -EPERM;
1408
1409         spin_lock_irqsave(&vop->irq_lock, flags);
1410
1411         VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1);
1412         VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1);
1413
1414         spin_unlock_irqrestore(&vop->irq_lock, flags);
1415
1416         return 0;
1417 }
1418
1419 static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
1420 {
1421         struct vop *vop = to_vop(crtc);
1422         unsigned long flags;
1423
1424         if (!vop->is_enabled)
1425                 return;
1426
1427         spin_lock_irqsave(&vop->irq_lock, flags);
1428
1429         VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0);
1430
1431         spin_unlock_irqrestore(&vop->irq_lock, flags);
1432 }
1433
1434 static void vop_crtc_wait_for_update(struct drm_crtc *crtc)
1435 {
1436         struct vop *vop = to_vop(crtc);
1437
1438         reinit_completion(&vop->wait_update_complete);
1439         WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete,
1440                                              msecs_to_jiffies(1000)));
1441 }
1442
1443 static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
1444                                            struct drm_file *file_priv)
1445 {
1446         struct drm_device *drm = crtc->dev;
1447         struct vop *vop = to_vop(crtc);
1448         struct drm_pending_vblank_event *e;
1449         unsigned long flags;
1450
1451         spin_lock_irqsave(&drm->event_lock, flags);
1452         e = vop->event;
1453         if (e && e->base.file_priv == file_priv) {
1454                 vop->event = NULL;
1455
1456                 e->base.destroy(&e->base);
1457                 file_priv->event_space += sizeof(e->event);
1458         }
1459         spin_unlock_irqrestore(&drm->event_lock, flags);
1460 }
1461
1462 static int vop_crtc_loader_protect(struct drm_crtc *crtc, bool on)
1463 {
1464         struct vop *vop = to_vop(crtc);
1465
1466         if (on == vop->loader_protect)
1467                 return 0;
1468
1469         if (on) {
1470                 vop_power_enable(crtc);
1471                 enable_irq(vop->irq);
1472                 drm_crtc_vblank_on(crtc);
1473                 vop->loader_protect = true;
1474         } else {
1475                 vop_crtc_disable(crtc);
1476
1477                 vop->loader_protect = false;
1478         }
1479
1480         return 0;
1481 }
1482
1483 #define DEBUG_PRINT(args...) \
1484                 do { \
1485                         if (s) \
1486                                 seq_printf(s, args); \
1487                         else \
1488                                 printk(args); \
1489                 } while (0)
1490
1491 static int vop_plane_info_dump(struct seq_file *s, struct drm_plane *plane)
1492 {
1493         struct vop_win *win = to_vop_win(plane);
1494         struct drm_plane_state *state = plane->state;
1495         struct vop_plane_state *pstate = to_vop_plane_state(state);
1496         struct drm_rect *src, *dest;
1497         struct drm_framebuffer *fb = state->fb;
1498         int i;
1499
1500         DEBUG_PRINT("    win%d-%d: %s\n", win->win_id, win->area_id,
1501                     pstate->enable ? "ACTIVE" : "DISABLED");
1502         if (!fb)
1503                 return 0;
1504
1505         src = &pstate->src;
1506         dest = &pstate->dest;
1507
1508         DEBUG_PRINT("\tformat: %s%s\n", drm_get_format_name(fb->pixel_format),
1509                     fb->modifier[0] == DRM_FORMAT_MOD_ARM_AFBC ? "[AFBC]" : "");
1510         DEBUG_PRINT("\tzpos: %d\n", pstate->zpos);
1511         DEBUG_PRINT("\tsrc: pos[%dx%d] rect[%dx%d]\n", src->x1 >> 16,
1512                     src->y1 >> 16, drm_rect_width(src) >> 16,
1513                     drm_rect_height(src) >> 16);
1514         DEBUG_PRINT("\tdst: pos[%dx%d] rect[%dx%d]\n", dest->x1, dest->y1,
1515                     drm_rect_width(dest), drm_rect_height(dest));
1516
1517         for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
1518                 dma_addr_t fb_addr = rockchip_fb_get_dma_addr(fb, i);
1519                 DEBUG_PRINT("\tbuf[%d]: addr: %pad pitch: %d offset: %d\n",
1520                             i, &fb_addr, fb->pitches[i], fb->offsets[i]);
1521         }
1522
1523         return 0;
1524 }
1525
1526 static int vop_crtc_debugfs_dump(struct drm_crtc *crtc, struct seq_file *s)
1527 {
1528         struct vop *vop = to_vop(crtc);
1529         struct drm_crtc_state *crtc_state = crtc->state;
1530         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1531         struct rockchip_crtc_state *state = to_rockchip_crtc_state(crtc->state);
1532         bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
1533         struct drm_plane *plane;
1534         int i;
1535
1536         DEBUG_PRINT("VOP [%s]: %s\n", dev_name(vop->dev),
1537                     crtc_state->active ? "ACTIVE" : "DISABLED");
1538
1539         if (!crtc_state->active)
1540                 return 0;
1541
1542         DEBUG_PRINT("    Connector: %s\n",
1543                     drm_get_connector_name(state->output_type));
1544         DEBUG_PRINT("\tbus_format[%x] output_mode[%x]\n",
1545                     state->bus_format, state->output_mode);
1546         DEBUG_PRINT("    Display mode: %dx%d%s%d\n",
1547                     mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
1548                     drm_mode_vrefresh(mode));
1549         DEBUG_PRINT("\tclk[%d] real_clk[%d] type[%x] flag[%x]\n",
1550                     mode->clock, mode->crtc_clock, mode->type, mode->flags);
1551         DEBUG_PRINT("\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
1552                     mode->hsync_end, mode->htotal);
1553         DEBUG_PRINT("\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
1554                     mode->vsync_end, mode->vtotal);
1555
1556         for (i = 0; i < vop->num_wins; i++) {
1557                 plane = &vop->win[i].base;
1558                 vop_plane_info_dump(s, plane);
1559         }
1560
1561         return 0;
1562 }
1563
1564 static void vop_crtc_regs_dump(struct drm_crtc *crtc, struct seq_file *s)
1565 {
1566         struct vop *vop = to_vop(crtc);
1567         struct drm_crtc_state *crtc_state = crtc->state;
1568         int dump_len = vop->len > 0x400 ? 0x400 : vop->len;
1569         int i;
1570
1571         if (!crtc_state->active)
1572                 return;
1573
1574         for (i = 0; i < dump_len; i += 4) {
1575                 if (i % 16 == 0)
1576                         DEBUG_PRINT("\n0x%08x: ", i);
1577                 DEBUG_PRINT("%08x ", vop_readl(vop, i));
1578         }
1579 }
1580
1581 #undef DEBUG_PRINT
1582
1583 static enum drm_mode_status
1584 vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode,
1585                     int output_type)
1586 {
1587         struct vop *vop = to_vop(crtc);
1588         const struct vop_data *vop_data = vop->data;
1589         int request_clock = mode->clock;
1590         int clock;
1591
1592         if (mode->hdisplay > vop_data->max_output.width)
1593                 return MODE_BAD_HVALUE;
1594
1595         if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
1596             VOP_MAJOR(vop->data->version) == 3 &&
1597             VOP_MINOR(vop->data->version) <= 2)
1598                 return MODE_BAD;
1599
1600         if (mode->flags & DRM_MODE_FLAG_DBLCLK)
1601                 request_clock *= 2;
1602         clock = clk_round_rate(vop->dclk, request_clock * 1000) / 1000;
1603
1604         /*
1605          * Hdmi or DisplayPort request a Accurate clock.
1606          */
1607         if (output_type == DRM_MODE_CONNECTOR_HDMIA ||
1608             output_type == DRM_MODE_CONNECTOR_DisplayPort)
1609                 if (clock != request_clock)
1610                         return MODE_CLOCK_RANGE;
1611
1612         return MODE_OK;
1613 }
1614
1615 static const struct rockchip_crtc_funcs private_crtc_funcs = {
1616         .loader_protect = vop_crtc_loader_protect,
1617         .enable_vblank = vop_crtc_enable_vblank,
1618         .disable_vblank = vop_crtc_disable_vblank,
1619         .wait_for_update = vop_crtc_wait_for_update,
1620         .cancel_pending_vblank = vop_crtc_cancel_pending_vblank,
1621         .debugfs_dump = vop_crtc_debugfs_dump,
1622         .regs_dump = vop_crtc_regs_dump,
1623         .mode_valid = vop_crtc_mode_valid,
1624 };
1625
1626 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
1627                                 const struct drm_display_mode *mode,
1628                                 struct drm_display_mode *adj_mode)
1629 {
1630         struct vop *vop = to_vop(crtc);
1631         const struct vop_data *vop_data = vop->data;
1632
1633         if (mode->hdisplay > vop_data->max_output.width)
1634                 return false;
1635
1636         drm_mode_set_crtcinfo(adj_mode,
1637                               CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE);
1638
1639         if (mode->flags & DRM_MODE_FLAG_DBLCLK)
1640                 adj_mode->crtc_clock *= 2;
1641
1642         adj_mode->crtc_clock =
1643                 clk_round_rate(vop->dclk, adj_mode->crtc_clock * 1000) / 1000;
1644
1645         return true;
1646 }
1647
1648 static void vop_crtc_enable(struct drm_crtc *crtc)
1649 {
1650         struct vop *vop = to_vop(crtc);
1651         const struct vop_data *vop_data = vop->data;
1652         struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
1653         struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1654         u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
1655         u16 hdisplay = adjusted_mode->crtc_hdisplay;
1656         u16 htotal = adjusted_mode->crtc_htotal;
1657         u16 hact_st = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_start;
1658         u16 hact_end = hact_st + hdisplay;
1659         u16 vdisplay = adjusted_mode->crtc_vdisplay;
1660         u16 vtotal = adjusted_mode->crtc_vtotal;
1661         u16 vsync_len = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
1662         u16 vact_st = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
1663         u16 vact_end = vact_st + vdisplay;
1664         uint32_t val;
1665
1666         mutex_lock(&vop->vop_lock);
1667         vop_initial(crtc);
1668
1669         val = BIT(DCLK_INVERT);
1670         val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ?
1671                    0 : BIT(HSYNC_POSITIVE);
1672         val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ?
1673                    0 : BIT(VSYNC_POSITIVE);
1674         VOP_CTRL_SET(vop, pin_pol, val);
1675
1676         if (vop->dclk_source && s->pll && s->pll->pll) {
1677                 if (clk_set_parent(vop->dclk_source, s->pll->pll))
1678                         DRM_DEV_ERROR(vop->dev,
1679                                       "failed to set dclk's parents\n");
1680         }
1681
1682         switch (s->output_type) {
1683         case DRM_MODE_CONNECTOR_LVDS:
1684                 VOP_CTRL_SET(vop, rgb_en, 1);
1685                 VOP_CTRL_SET(vop, rgb_pin_pol, val);
1686                 break;
1687         case DRM_MODE_CONNECTOR_eDP:
1688                 VOP_CTRL_SET(vop, edp_en, 1);
1689                 VOP_CTRL_SET(vop, edp_pin_pol, val);
1690                 break;
1691         case DRM_MODE_CONNECTOR_HDMIA:
1692                 VOP_CTRL_SET(vop, hdmi_en, 1);
1693                 VOP_CTRL_SET(vop, hdmi_pin_pol, val);
1694                 break;
1695         case DRM_MODE_CONNECTOR_DSI:
1696                 VOP_CTRL_SET(vop, mipi_en, 1);
1697                 VOP_CTRL_SET(vop, mipi_pin_pol, val);
1698                 break;
1699         case DRM_MODE_CONNECTOR_DisplayPort:
1700                 val &= ~BIT(DCLK_INVERT);
1701                 VOP_CTRL_SET(vop, dp_pin_pol, val);
1702                 VOP_CTRL_SET(vop, dp_en, 1);
1703                 break;
1704         case DRM_MODE_CONNECTOR_TV:
1705                 if (vdisplay == CVBS_PAL_VDISPLAY)
1706                         VOP_CTRL_SET(vop, tve_sw_mode, 1);
1707                 else
1708                         VOP_CTRL_SET(vop, tve_sw_mode, 0);
1709
1710                 VOP_CTRL_SET(vop, tve_dclk_pol, 1);
1711                 VOP_CTRL_SET(vop, tve_dclk_en, 1);
1712                 /* use the same pol reg with hdmi */
1713                 VOP_CTRL_SET(vop, hdmi_pin_pol, val);
1714                 VOP_CTRL_SET(vop, sw_genlock, 1);
1715                 VOP_CTRL_SET(vop, sw_uv_offset_en, 1);
1716                 VOP_CTRL_SET(vop, dither_up, 1);
1717                 break;
1718         default:
1719                 DRM_ERROR("unsupport connector_type[%d]\n", s->output_type);
1720         }
1721
1722         if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
1723             !(vop_data->feature & VOP_FEATURE_OUTPUT_10BIT))
1724                 s->output_mode = ROCKCHIP_OUT_MODE_P888;
1725
1726         VOP_CTRL_SET(vop, out_mode, s->output_mode);
1727         switch (s->bus_format) {
1728         case MEDIA_BUS_FMT_RGB565_1X16:
1729                 val = DITHER_DOWN_EN(1) | DITHER_DOWN_MODE(RGB888_TO_RGB565);
1730                 break;
1731         case MEDIA_BUS_FMT_RGB666_1X18:
1732         case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
1733                 val = DITHER_DOWN_EN(1) | DITHER_DOWN_MODE(RGB888_TO_RGB666);
1734                 break;
1735         case MEDIA_BUS_FMT_YUV8_1X24:
1736         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1737                 val = DITHER_DOWN_EN(0) | PRE_DITHER_DOWN_EN(1);
1738                 break;
1739         case MEDIA_BUS_FMT_YUV10_1X30:
1740         case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1741                 val = DITHER_DOWN_EN(0) | PRE_DITHER_DOWN_EN(0);
1742                 break;
1743         case MEDIA_BUS_FMT_RGB888_1X24:
1744         default:
1745                 val = DITHER_DOWN_EN(0) | PRE_DITHER_DOWN_EN(0);
1746                 break;
1747         }
1748
1749         if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA)
1750                 val |= PRE_DITHER_DOWN_EN(0);
1751         else
1752                 val |= PRE_DITHER_DOWN_EN(1);
1753         val |= DITHER_DOWN_MODE_SEL(DITHER_DOWN_ALLEGRO);
1754         VOP_CTRL_SET(vop, dither_down, val);
1755         VOP_CTRL_SET(vop, dclk_ddr,
1756                      s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0);
1757         VOP_CTRL_SET(vop, overlay_mode, is_yuv_output(s->bus_format));
1758         VOP_CTRL_SET(vop, dsp_out_yuv, is_yuv_output(s->bus_format));
1759         VOP_CTRL_SET(vop, dsp_background,
1760                      is_yuv_output(s->bus_format) ? 0x20010200 : 0);
1761
1762         VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
1763         val = hact_st << 16;
1764         val |= hact_end;
1765         VOP_CTRL_SET(vop, hact_st_end, val);
1766         VOP_CTRL_SET(vop, hpost_st_end, val);
1767
1768         val = vact_st << 16;
1769         val |= vact_end;
1770         VOP_CTRL_SET(vop, vact_st_end, val);
1771         VOP_CTRL_SET(vop, vpost_st_end, val);
1772
1773         VOP_INTR_SET(vop, line_flag_num[0], vact_end);
1774         VOP_INTR_SET(vop, line_flag_num[1],
1775                      vact_end - us_to_vertical_line(adjusted_mode, 1000));
1776         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1777                 u16 vact_st_f1 = vtotal + vact_st + 1;
1778                 u16 vact_end_f1 = vact_st_f1 + vdisplay;
1779
1780                 val = vact_st_f1 << 16 | vact_end_f1;
1781                 VOP_CTRL_SET(vop, vact_st_end_f1, val);
1782                 VOP_CTRL_SET(vop, vpost_st_end_f1, val);
1783
1784                 val = vtotal << 16 | (vtotal + vsync_len);
1785                 VOP_CTRL_SET(vop, vs_st_end_f1, val);
1786                 VOP_CTRL_SET(vop, dsp_interlace, 1);
1787                 VOP_CTRL_SET(vop, p2i_en, 1);
1788                 vtotal += vtotal + 1;
1789         } else {
1790                 VOP_CTRL_SET(vop, dsp_interlace, 0);
1791                 VOP_CTRL_SET(vop, p2i_en, 0);
1792         }
1793         VOP_CTRL_SET(vop, vtotal_pw, vtotal << 16 | vsync_len);
1794
1795         VOP_CTRL_SET(vop, core_dclk_div,
1796                      !!(adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK));
1797
1798         clk_set_rate(vop->dclk, adjusted_mode->crtc_clock * 1000);
1799
1800         vop_cfg_done(vop);
1801         /*
1802          * enable vop, all the register would take effect when vop exit standby
1803          */
1804         VOP_CTRL_SET(vop, standby, 0);
1805
1806         enable_irq(vop->irq);
1807         drm_crtc_vblank_on(crtc);
1808         mutex_unlock(&vop->vop_lock);
1809 }
1810
1811 static int vop_zpos_cmp(const void *a, const void *b)
1812 {
1813         struct vop_zpos *pa = (struct vop_zpos *)a;
1814         struct vop_zpos *pb = (struct vop_zpos *)b;
1815
1816         return pa->zpos - pb->zpos;
1817 }
1818
1819 static int vop_afbdc_atomic_check(struct drm_crtc *crtc,
1820                                   struct drm_crtc_state *crtc_state)
1821 {
1822         struct vop *vop = to_vop(crtc);
1823         const struct vop_data *vop_data = vop->data;
1824         struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
1825         struct drm_atomic_state *state = crtc_state->state;
1826         struct drm_plane *plane;
1827         struct drm_plane_state *pstate;
1828         struct vop_plane_state *plane_state;
1829         struct vop_win *win;
1830         int afbdc_format;
1831         int i;
1832
1833         s->afbdc_en = 0;
1834
1835         for_each_plane_in_state(state, plane, pstate, i) {
1836                 struct drm_framebuffer *fb = pstate->fb;
1837                 struct drm_rect *src;
1838
1839                 win = to_vop_win(plane);
1840                 plane_state = to_vop_plane_state(pstate);
1841
1842                 if (pstate->crtc != crtc || !fb)
1843                         continue;
1844
1845                 if (fb->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC)
1846                         continue;
1847
1848                 if (!(vop_data->feature & VOP_FEATURE_AFBDC)) {
1849                         DRM_ERROR("not support afbdc\n");
1850                         return -EINVAL;
1851                 }
1852
1853                 switch (plane_state->format) {
1854                 case VOP_FMT_ARGB8888:
1855                         afbdc_format = AFBDC_FMT_U8U8U8U8;
1856                         break;
1857                 case VOP_FMT_RGB888:
1858                         afbdc_format = AFBDC_FMT_U8U8U8;
1859                         break;
1860                 case VOP_FMT_RGB565:
1861                         afbdc_format = AFBDC_FMT_RGB565;
1862                         break;
1863                 default:
1864                         return -EINVAL;
1865                 }
1866
1867                 if (s->afbdc_en) {
1868                         DRM_ERROR("vop only support one afbc layer\n");
1869                         return -EINVAL;
1870                 }
1871
1872                 src = &plane_state->src;
1873                 if (src->x1 || src->y1 || fb->offsets[0]) {
1874                         DRM_ERROR("win[%d] afbdc not support offset display\n",
1875                                   win->win_id);
1876                         DRM_ERROR("xpos=%d, ypos=%d, offset=%d\n",
1877                                   src->x1, src->y1, fb->offsets[0]);
1878                         return -EINVAL;
1879                 }
1880                 s->afbdc_win_format = afbdc_format;
1881                 s->afbdc_win_width = pstate->fb->width - 1;
1882                 s->afbdc_win_height = (drm_rect_height(src) >> 16) - 1;
1883                 s->afbdc_win_id = win->win_id;
1884                 s->afbdc_win_ptr = plane_state->yrgb_mst;
1885                 s->afbdc_en = 1;
1886         }
1887
1888         return 0;
1889 }
1890
1891 static void vop_dclk_source_generate(struct drm_crtc *crtc,
1892                                      struct drm_crtc_state *crtc_state)
1893 {
1894         struct rockchip_drm_private *private = crtc->dev->dev_private;
1895         struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
1896         struct rockchip_crtc_state *old_s = to_rockchip_crtc_state(crtc->state);
1897         struct vop *vop = to_vop(crtc);
1898
1899         if (!vop->dclk_source)
1900                 return;
1901
1902         if (crtc_state->active) {
1903                 WARN_ON(s->pll && !s->pll->use_count);
1904                 if (!s->pll || s->pll->use_count > 1 ||
1905                     s->output_type != old_s->output_type) {
1906                         if (s->pll)
1907                                 s->pll->use_count--;
1908
1909                         if (s->output_type != DRM_MODE_CONNECTOR_HDMIA &&
1910                             !private->default_pll.use_count)
1911                                 s->pll = &private->default_pll;
1912                         else
1913                                 s->pll = &private->hdmi_pll;
1914
1915                         s->pll->use_count++;
1916                 }
1917         } else if (s->pll) {
1918                 s->pll->use_count--;
1919                 s->pll = NULL;
1920         }
1921         if (s->pll && s->pll != old_s->pll)
1922                 crtc_state->mode_changed = true;
1923 }
1924
1925 static int vop_crtc_atomic_check(struct drm_crtc *crtc,
1926                                  struct drm_crtc_state *crtc_state)
1927 {
1928         struct drm_atomic_state *state = crtc_state->state;
1929         struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
1930         struct vop *vop = to_vop(crtc);
1931         const struct vop_data *vop_data = vop->data;
1932         struct drm_plane *plane;
1933         struct drm_plane_state *pstate;
1934         struct vop_plane_state *plane_state;
1935         struct vop_zpos *pzpos;
1936         int dsp_layer_sel = 0;
1937         int i, j, cnt = 0, ret = 0;
1938
1939         ret = vop_afbdc_atomic_check(crtc, crtc_state);
1940         if (ret)
1941                 return ret;
1942
1943         ret = vop_csc_atomic_check(crtc, crtc_state);
1944         if (ret)
1945                 return ret;
1946
1947         pzpos = kmalloc_array(vop_data->win_size, sizeof(*pzpos), GFP_KERNEL);
1948         if (!pzpos)
1949                 return -ENOMEM;
1950
1951         for (i = 0; i < vop_data->win_size; i++) {
1952                 const struct vop_win_data *win_data = &vop_data->win[i];
1953                 struct vop_win *win;
1954
1955                 if (!win_data->phy)
1956                         continue;
1957
1958                 for (j = 0; j < vop->num_wins; j++) {
1959                         win = &vop->win[j];
1960
1961                         if (win->win_id == i && !win->area_id)
1962                                 break;
1963                 }
1964                 if (WARN_ON(j >= vop->num_wins)) {
1965                         ret = -EINVAL;
1966                         goto err_free_pzpos;
1967                 }
1968
1969                 plane = &win->base;
1970                 pstate = state->plane_states[drm_plane_index(plane)];
1971                 /*
1972                  * plane might not have changed, in which case take
1973                  * current state:
1974                  */
1975                 if (!pstate)
1976                         pstate = plane->state;
1977                 plane_state = to_vop_plane_state(pstate);
1978                 pzpos[cnt].zpos = plane_state->zpos;
1979                 pzpos[cnt++].win_id = win->win_id;
1980         }
1981
1982         sort(pzpos, cnt, sizeof(pzpos[0]), vop_zpos_cmp, NULL);
1983
1984         for (i = 0, cnt = 0; i < vop_data->win_size; i++) {
1985                 const struct vop_win_data *win_data = &vop_data->win[i];
1986                 int shift = i * 2;
1987
1988                 if (win_data->phy) {
1989                         struct vop_zpos *zpos = &pzpos[cnt++];
1990
1991                         dsp_layer_sel |= zpos->win_id << shift;
1992                 } else {
1993                         dsp_layer_sel |= i << shift;
1994                 }
1995         }
1996
1997         s->dsp_layer_sel = dsp_layer_sel;
1998
1999         vop_dclk_source_generate(crtc, crtc_state);
2000
2001 err_free_pzpos:
2002         kfree(pzpos);
2003         return ret;
2004 }
2005
2006 static void vop_post_config(struct drm_crtc *crtc)
2007 {
2008         struct vop *vop = to_vop(crtc);
2009         struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
2010         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
2011         u16 vtotal = mode->crtc_vtotal;
2012         u16 hdisplay = mode->crtc_hdisplay;
2013         u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
2014         u16 vdisplay = mode->crtc_vdisplay;
2015         u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
2016         u16 hsize = hdisplay * (s->left_margin + s->right_margin) / 200;
2017         u16 vsize = vdisplay * (s->top_margin + s->bottom_margin) / 200;
2018         u16 hact_end, vact_end;
2019         u32 val;
2020
2021         hact_st += hdisplay * (100 - s->left_margin) / 200;
2022         hact_end = hact_st + hsize;
2023         val = hact_st << 16;
2024         val |= hact_end;
2025         VOP_CTRL_SET(vop, hpost_st_end, val);
2026         vact_st += vdisplay * (100 - s->top_margin) / 200;
2027         vact_end = vact_st + vsize;
2028         val = vact_st << 16;
2029         val |= vact_end;
2030         VOP_CTRL_SET(vop, vpost_st_end, val);
2031         val = scl_cal_scale2(vdisplay, vsize) << 16;
2032         val |= scl_cal_scale2(hdisplay, hsize);
2033         VOP_CTRL_SET(vop, post_scl_factor, val);
2034         VOP_CTRL_SET(vop, post_scl_ctrl, 0x3);
2035         if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
2036                 u16 vact_st_f1 = vtotal + vact_st + 1;
2037                 u16 vact_end_f1 = vact_st_f1 + vsize;
2038
2039                 val = vact_st_f1 << 16 | vact_end_f1;
2040                 VOP_CTRL_SET(vop, vpost_st_end_f1, val);
2041         }
2042 }
2043
2044 static void vop_cfg_update(struct drm_crtc *crtc,
2045                            struct drm_crtc_state *old_crtc_state)
2046 {
2047         struct rockchip_crtc_state *s =
2048                         to_rockchip_crtc_state(crtc->state);
2049         struct vop *vop = to_vop(crtc);
2050
2051         spin_lock(&vop->reg_lock);
2052
2053         if (s->afbdc_en) {
2054                 uint32_t pic_size;
2055
2056                 VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4);
2057                 VOP_CTRL_SET(vop, afbdc_hreg_block_split, 0);
2058                 VOP_CTRL_SET(vop, afbdc_sel, s->afbdc_win_id);
2059                 VOP_CTRL_SET(vop, afbdc_hdr_ptr, s->afbdc_win_ptr);
2060                 pic_size = (s->afbdc_win_width & 0xffff);
2061                 pic_size |= s->afbdc_win_height << 16;
2062                 VOP_CTRL_SET(vop, afbdc_pic_size, pic_size);
2063         }
2064
2065         VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
2066         VOP_CTRL_SET(vop, dsp_layer_sel, s->dsp_layer_sel);
2067         vop_post_config(crtc);
2068
2069         spin_unlock(&vop->reg_lock);
2070 }
2071
2072 static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
2073                                   struct drm_crtc_state *old_crtc_state)
2074 {
2075         struct vop *vop = to_vop(crtc);
2076
2077         vop_cfg_update(crtc, old_crtc_state);
2078
2079         if (!vop->is_iommu_enabled && vop->is_iommu_needed) {
2080                 bool need_wait_vblank = !vop_is_allwin_disabled(vop);
2081                 int ret;
2082
2083                 if (need_wait_vblank) {
2084                         bool active;
2085
2086                         disable_irq(vop->irq);
2087                         drm_crtc_vblank_get(crtc);
2088                         VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
2089
2090                         ret = readx_poll_timeout_atomic(vop_fs_irq_is_active,
2091                                                         vop, active, active,
2092                                                         0, 50 * 1000);
2093                         if (ret)
2094                                 dev_err(vop->dev, "wait fs irq timeout\n");
2095
2096                         VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
2097                         vop_cfg_done(vop);
2098
2099                         ret = readx_poll_timeout_atomic(vop_line_flag_is_active,
2100                                                         vop, active, active,
2101                                                         0, 50 * 1000);
2102                         if (ret)
2103                                 dev_err(vop->dev, "wait line flag timeout\n");
2104
2105                         enable_irq(vop->irq);
2106                 }
2107                 ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
2108                 if (ret)
2109                         dev_err(vop->dev, "failed to attach dma mapping, %d\n",
2110                                 ret);
2111
2112                 if (need_wait_vblank) {
2113                         VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 0);
2114                         drm_crtc_vblank_put(crtc);
2115                 }
2116
2117                 vop->is_iommu_enabled = true;
2118         }
2119
2120         vop_cfg_done(vop);
2121 }
2122
2123 static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
2124                                   struct drm_crtc_state *old_crtc_state)
2125 {
2126         struct vop *vop = to_vop(crtc);
2127
2128         if (crtc->state->event) {
2129                 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
2130
2131                 vop->event = crtc->state->event;
2132                 crtc->state->event = NULL;
2133         }
2134 }
2135
2136 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
2137         .load_lut = vop_crtc_load_lut,
2138         .enable = vop_crtc_enable,
2139         .disable = vop_crtc_disable,
2140         .mode_fixup = vop_crtc_mode_fixup,
2141         .atomic_check = vop_crtc_atomic_check,
2142         .atomic_flush = vop_crtc_atomic_flush,
2143         .atomic_begin = vop_crtc_atomic_begin,
2144 };
2145
2146 static void vop_crtc_destroy(struct drm_crtc *crtc)
2147 {
2148         drm_crtc_cleanup(crtc);
2149 }
2150
2151 static void vop_crtc_reset(struct drm_crtc *crtc)
2152 {
2153         struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
2154         struct rockchip_drm_private *private = crtc->dev->dev_private;
2155         struct vop *vop = to_vop(crtc);
2156
2157         if (crtc->state) {
2158                 __drm_atomic_helper_crtc_destroy_state(crtc, crtc->state);
2159                 kfree(s);
2160         }
2161
2162         s = kzalloc(sizeof(*s), GFP_KERNEL);
2163         if (!s)
2164                 return;
2165         crtc->state = &s->base;
2166         crtc->state->crtc = crtc;
2167
2168         if (vop->dclk_source) {
2169                 struct clk *parent;
2170
2171                 parent = clk_get_parent(vop->dclk_source);
2172                 if (parent) {
2173                         if (clk_is_match(private->default_pll.pll, parent))
2174                                 s->pll = &private->default_pll;
2175                         else if (clk_is_match(private->hdmi_pll.pll, parent))
2176                                 s->pll = &private->hdmi_pll;
2177                         if (s->pll)
2178                                 s->pll->use_count++;
2179                 }
2180         }
2181         s->left_margin = 100;
2182         s->right_margin = 100;
2183         s->top_margin = 100;
2184         s->bottom_margin = 100;
2185 }
2186
2187 static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
2188 {
2189         struct rockchip_crtc_state *rockchip_state, *old_state;
2190
2191         old_state = to_rockchip_crtc_state(crtc->state);
2192         rockchip_state = kmemdup(old_state, sizeof(*old_state), GFP_KERNEL);
2193         if (!rockchip_state)
2194                 return NULL;
2195
2196         __drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base);
2197         return &rockchip_state->base;
2198 }
2199
2200 static void vop_crtc_destroy_state(struct drm_crtc *crtc,
2201                                    struct drm_crtc_state *state)
2202 {
2203         struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
2204
2205         __drm_atomic_helper_crtc_destroy_state(crtc, &s->base);
2206         kfree(s);
2207 }
2208
2209 static int vop_crtc_atomic_get_property(struct drm_crtc *crtc,
2210                                         const struct drm_crtc_state *state,
2211                                         struct drm_property *property,
2212                                         uint64_t *val)
2213 {
2214         struct drm_device *drm_dev = crtc->dev;
2215         struct drm_mode_config *mode_config = &drm_dev->mode_config;
2216         struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
2217
2218         if (property == mode_config->tv_left_margin_property) {
2219                 *val = s->left_margin;
2220                 return 0;
2221         }
2222
2223         if (property == mode_config->tv_right_margin_property) {
2224                 *val = s->right_margin;
2225                 return 0;
2226         }
2227
2228         if (property == mode_config->tv_top_margin_property) {
2229                 *val = s->top_margin;
2230                 return 0;
2231         }
2232
2233         if (property == mode_config->tv_bottom_margin_property) {
2234                 *val = s->bottom_margin;
2235                 return 0;
2236         }
2237
2238         DRM_ERROR("failed to get vop crtc property\n");
2239         return -EINVAL;
2240 }
2241
2242 static int vop_crtc_atomic_set_property(struct drm_crtc *crtc,
2243                                         struct drm_crtc_state *state,
2244                                         struct drm_property *property,
2245                                         uint64_t val)
2246 {
2247         struct drm_device *drm_dev = crtc->dev;
2248         struct drm_mode_config *mode_config = &drm_dev->mode_config;
2249         struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
2250
2251         if (property == mode_config->tv_left_margin_property) {
2252                 s->left_margin = val;
2253                 return 0;
2254         }
2255
2256         if (property == mode_config->tv_right_margin_property) {
2257                 s->right_margin = val;
2258                 return 0;
2259         }
2260
2261         if (property == mode_config->tv_top_margin_property) {
2262                 s->top_margin = val;
2263                 return 0;
2264         }
2265
2266         if (property == mode_config->tv_bottom_margin_property) {
2267                 s->bottom_margin = val;
2268                 return 0;
2269         }
2270
2271         DRM_ERROR("failed to set vop crtc property\n");
2272         return -EINVAL;
2273 }
2274
2275 static void vop_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2276                                u16 *blue, uint32_t start, uint32_t size)
2277 {
2278         struct vop *vop = to_vop(crtc);
2279         int end = min_t(u32, start + size, vop->lut_len);
2280         int i;
2281
2282         if (!vop->lut)
2283                 return;
2284
2285         for (i = start; i < end; i++)
2286                 rockchip_vop_crtc_fb_gamma_set(crtc, red[i], green[i],
2287                                                blue[i], i);
2288
2289         vop_crtc_load_lut(crtc);
2290 }
2291
2292 static const struct drm_crtc_funcs vop_crtc_funcs = {
2293         .gamma_set = vop_crtc_gamma_set,
2294         .set_config = drm_atomic_helper_set_config,
2295         .page_flip = drm_atomic_helper_page_flip,
2296         .destroy = vop_crtc_destroy,
2297         .reset = vop_crtc_reset,
2298         .set_property = drm_atomic_helper_crtc_set_property,
2299         .atomic_get_property = vop_crtc_atomic_get_property,
2300         .atomic_set_property = vop_crtc_atomic_set_property,
2301         .atomic_duplicate_state = vop_crtc_duplicate_state,
2302         .atomic_destroy_state = vop_crtc_destroy_state,
2303 };
2304
2305 static void vop_handle_vblank(struct vop *vop)
2306 {
2307         struct drm_device *drm = vop->drm_dev;
2308         struct drm_crtc *crtc = &vop->crtc;
2309         unsigned long flags;
2310
2311         if (!vop_is_cfg_done_complete(vop))
2312                 return;
2313
2314         if (vop->event) {
2315                 spin_lock_irqsave(&drm->event_lock, flags);
2316
2317                 drm_crtc_send_vblank_event(crtc, vop->event);
2318                 drm_crtc_vblank_put(crtc);
2319                 vop->event = NULL;
2320
2321                 spin_unlock_irqrestore(&drm->event_lock, flags);
2322         }
2323         if (!completion_done(&vop->wait_update_complete))
2324                 complete(&vop->wait_update_complete);
2325 }
2326
2327 static irqreturn_t vop_isr(int irq, void *data)
2328 {
2329         struct vop *vop = data;
2330         struct drm_crtc *crtc = &vop->crtc;
2331         uint32_t active_irqs;
2332         unsigned long flags;
2333         int ret = IRQ_NONE;
2334
2335         /*
2336          * interrupt register has interrupt status, enable and clear bits, we
2337          * must hold irq_lock to avoid a race with enable/disable_vblank().
2338         */
2339         spin_lock_irqsave(&vop->irq_lock, flags);
2340
2341         active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK);
2342         /* Clear all active interrupt sources */
2343         if (active_irqs)
2344                 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1);
2345
2346         spin_unlock_irqrestore(&vop->irq_lock, flags);
2347
2348         /* This is expected for vop iommu irqs, since the irq is shared */
2349         if (!active_irqs)
2350                 return IRQ_NONE;
2351
2352         if (active_irqs & DSP_HOLD_VALID_INTR) {
2353                 complete(&vop->dsp_hold_completion);
2354                 active_irqs &= ~DSP_HOLD_VALID_INTR;
2355                 ret = IRQ_HANDLED;
2356         }
2357
2358         if (active_irqs & LINE_FLAG_INTR) {
2359                 complete(&vop->line_flag_completion);
2360                 active_irqs &= ~LINE_FLAG_INTR;
2361                 ret = IRQ_HANDLED;
2362         }
2363
2364         if (active_irqs & FS_INTR) {
2365                 drm_crtc_handle_vblank(crtc);
2366                 vop_handle_vblank(vop);
2367                 active_irqs &= ~FS_INTR;
2368                 ret = IRQ_HANDLED;
2369         }
2370
2371         /* Unhandled irqs are spurious. */
2372         if (active_irqs)
2373                 DRM_ERROR("Unknown VOP IRQs: %#02x\n", active_irqs);
2374
2375         return ret;
2376 }
2377
2378 static int vop_plane_init(struct vop *vop, struct vop_win *win,
2379                           unsigned long possible_crtcs)
2380 {
2381         struct rockchip_drm_private *private = vop->drm_dev->dev_private;
2382         struct drm_plane *share = NULL;
2383         unsigned int rotations = 0;
2384         struct drm_property *prop;
2385         uint64_t feature = 0;
2386         int ret;
2387
2388         if (win->parent)
2389                 share = &win->parent->base;
2390
2391         ret = drm_share_plane_init(vop->drm_dev, &win->base, share,
2392                                    possible_crtcs, &vop_plane_funcs,
2393                                    win->data_formats, win->nformats, win->type);
2394         if (ret) {
2395                 DRM_ERROR("failed to initialize plane\n");
2396                 return ret;
2397         }
2398         drm_plane_helper_add(&win->base, &plane_helper_funcs);
2399         drm_object_attach_property(&win->base.base,
2400                                    vop->plane_zpos_prop, win->win_id);
2401
2402         if (VOP_WIN_SUPPORT(vop, win, xmirror))
2403                 rotations |= BIT(DRM_REFLECT_X);
2404
2405         if (VOP_WIN_SUPPORT(vop, win, ymirror)) {
2406                 rotations |= BIT(DRM_REFLECT_Y);
2407
2408                 prop = drm_property_create_bool(vop->drm_dev,
2409                                                 DRM_MODE_PROP_ATOMIC,
2410                                                 "LOGO_YMIRROR");
2411                 if (!prop)
2412                         return -ENOMEM;
2413                 private->logo_ymirror_prop = prop;
2414         }
2415
2416         if (rotations) {
2417                 rotations |= BIT(DRM_ROTATE_0);
2418                 prop = drm_mode_create_rotation_property(vop->drm_dev,
2419                                                          rotations);
2420                 if (!prop) {
2421                         DRM_ERROR("failed to create zpos property\n");
2422                         return -EINVAL;
2423                 }
2424                 drm_object_attach_property(&win->base.base, prop,
2425                                            BIT(DRM_ROTATE_0));
2426                 win->rotation_prop = prop;
2427         }
2428         if (win->phy->scl)
2429                 feature |= BIT(ROCKCHIP_DRM_PLANE_FEATURE_SCALE);
2430         if (VOP_WIN_SUPPORT(vop, win, src_alpha_ctl) ||
2431             VOP_WIN_SUPPORT(vop, win, alpha_en))
2432                 feature |= BIT(ROCKCHIP_DRM_PLANE_FEATURE_ALPHA);
2433
2434         drm_object_attach_property(&win->base.base, vop->plane_feature_prop,
2435                                    feature);
2436
2437         return 0;
2438 }
2439
2440 static int vop_create_crtc(struct vop *vop)
2441 {
2442         struct device *dev = vop->dev;
2443         const struct vop_data *vop_data = vop->data;
2444         struct drm_device *drm_dev = vop->drm_dev;
2445         struct drm_plane *primary = NULL, *cursor = NULL, *plane, *tmp;
2446         struct drm_crtc *crtc = &vop->crtc;
2447         struct device_node *port;
2448         uint64_t feature = 0;
2449         int ret;
2450         int i;
2451
2452         /*
2453          * Create drm_plane for primary and cursor planes first, since we need
2454          * to pass them to drm_crtc_init_with_planes, which sets the
2455          * "possible_crtcs" to the newly initialized crtc.
2456          */
2457         for (i = 0; i < vop->num_wins; i++) {
2458                 struct vop_win *win = &vop->win[i];
2459
2460                 if (win->type != DRM_PLANE_TYPE_PRIMARY &&
2461                     win->type != DRM_PLANE_TYPE_CURSOR)
2462                         continue;
2463
2464                 ret = vop_plane_init(vop, win, 0);
2465                 if (ret)
2466                         goto err_cleanup_planes;
2467
2468                 plane = &win->base;
2469                 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
2470                         primary = plane;
2471                 else if (plane->type == DRM_PLANE_TYPE_CURSOR)
2472                         cursor = plane;
2473
2474         }
2475
2476         ret = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,
2477                                         &vop_crtc_funcs, NULL);
2478         if (ret)
2479                 goto err_cleanup_planes;
2480
2481         drm_crtc_helper_add(crtc, &vop_crtc_helper_funcs);
2482
2483         /*
2484          * Create drm_planes for overlay windows with possible_crtcs restricted
2485          * to the newly created crtc.
2486          */
2487         for (i = 0; i < vop->num_wins; i++) {
2488                 struct vop_win *win = &vop->win[i];
2489                 unsigned long possible_crtcs = 1 << drm_crtc_index(crtc);
2490
2491                 if (win->type != DRM_PLANE_TYPE_OVERLAY)
2492                         continue;
2493
2494                 ret = vop_plane_init(vop, win, possible_crtcs);
2495                 if (ret)
2496                         goto err_cleanup_crtc;
2497         }
2498
2499         port = of_get_child_by_name(dev->of_node, "port");
2500         if (!port) {
2501                 DRM_ERROR("no port node found in %s\n",
2502                           dev->of_node->full_name);
2503                 ret = -ENOENT;
2504                 goto err_cleanup_crtc;
2505         }
2506
2507         init_completion(&vop->dsp_hold_completion);
2508         init_completion(&vop->wait_update_complete);
2509         init_completion(&vop->line_flag_completion);
2510         crtc->port = port;
2511         rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
2512
2513         ret = drm_mode_create_tv_properties(drm_dev, 0, NULL);
2514         if (ret)
2515                 goto err_unregister_crtc_funcs;
2516 #define VOP_ATTACH_MODE_CONFIG_PROP(prop, v) \
2517         drm_object_attach_property(&crtc->base, drm_dev->mode_config.prop, v)
2518
2519         VOP_ATTACH_MODE_CONFIG_PROP(tv_left_margin_property, 100);
2520         VOP_ATTACH_MODE_CONFIG_PROP(tv_right_margin_property, 100);
2521         VOP_ATTACH_MODE_CONFIG_PROP(tv_top_margin_property, 100);
2522         VOP_ATTACH_MODE_CONFIG_PROP(tv_bottom_margin_property, 100);
2523 #undef VOP_ATTACH_MODE_CONFIG_PROP
2524
2525         if (vop_data->feature & VOP_FEATURE_AFBDC)
2526                 feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_AFBDC);
2527         drm_object_attach_property(&crtc->base, vop->feature_prop,
2528                                    feature);
2529         if (vop->lut_regs) {
2530                 u16 *r_base, *g_base, *b_base;
2531                 u32 lut_len = vop->lut_len;
2532
2533                 drm_mode_crtc_set_gamma_size(crtc, lut_len);
2534                 vop->lut = devm_kmalloc_array(dev, lut_len, sizeof(*vop->lut),
2535                                               GFP_KERNEL);
2536                 if (!vop->lut)
2537                         return -ENOMEM;
2538
2539                 r_base = crtc->gamma_store;
2540                 g_base = r_base + crtc->gamma_size;
2541                 b_base = g_base + crtc->gamma_size;
2542
2543                 for (i = 0; i < lut_len; i++) {
2544                         vop->lut[i] = i * lut_len * lut_len | i * lut_len | i;
2545                         rockchip_vop_crtc_fb_gamma_get(crtc, &r_base[i],
2546                                                        &g_base[i], &b_base[i],
2547                                                        i);
2548                 }
2549         }
2550
2551         return 0;
2552
2553 err_unregister_crtc_funcs:
2554         rockchip_unregister_crtc_funcs(crtc);
2555 err_cleanup_crtc:
2556         drm_crtc_cleanup(crtc);
2557 err_cleanup_planes:
2558         list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
2559                                  head)
2560                 drm_plane_cleanup(plane);
2561         return ret;
2562 }
2563
2564 static void vop_destroy_crtc(struct vop *vop)
2565 {
2566         struct drm_crtc *crtc = &vop->crtc;
2567         struct drm_device *drm_dev = vop->drm_dev;
2568         struct drm_plane *plane, *tmp;
2569
2570         rockchip_unregister_crtc_funcs(crtc);
2571         of_node_put(crtc->port);
2572
2573         /*
2574          * We need to cleanup the planes now.  Why?
2575          *
2576          * The planes are "&vop->win[i].base".  That means the memory is
2577          * all part of the big "struct vop" chunk of memory.  That memory
2578          * was devm allocated and associated with this component.  We need to
2579          * free it ourselves before vop_unbind() finishes.
2580          */
2581         list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
2582                                  head)
2583                 vop_plane_destroy(plane);
2584
2585         /*
2586          * Destroy CRTC after vop_plane_destroy() since vop_disable_plane()
2587          * references the CRTC.
2588          */
2589         drm_crtc_cleanup(crtc);
2590 }
2591
2592 /*
2593  * Initialize the vop->win array elements.
2594  */
2595 static int vop_win_init(struct vop *vop)
2596 {
2597         const struct vop_data *vop_data = vop->data;
2598         unsigned int i, j;
2599         unsigned int num_wins = 0;
2600         struct drm_property *prop;
2601         static const struct drm_prop_enum_list props[] = {
2602                 { ROCKCHIP_DRM_PLANE_FEATURE_SCALE, "scale" },
2603                 { ROCKCHIP_DRM_PLANE_FEATURE_ALPHA, "alpha" },
2604         };
2605         static const struct drm_prop_enum_list crtc_props[] = {
2606                 { ROCKCHIP_DRM_CRTC_FEATURE_AFBDC, "afbdc" },
2607         };
2608
2609         for (i = 0; i < vop_data->win_size; i++) {
2610                 struct vop_win *vop_win = &vop->win[num_wins];
2611                 const struct vop_win_data *win_data = &vop_data->win[i];
2612
2613                 if (!win_data->phy)
2614                         continue;
2615
2616                 vop_win->phy = win_data->phy;
2617                 vop_win->csc = win_data->csc;
2618                 vop_win->offset = win_data->base;
2619                 vop_win->type = win_data->type;
2620                 vop_win->data_formats = win_data->phy->data_formats;
2621                 vop_win->nformats = win_data->phy->nformats;
2622                 vop_win->vop = vop;
2623                 vop_win->win_id = i;
2624                 vop_win->area_id = 0;
2625                 num_wins++;
2626
2627                 for (j = 0; j < win_data->area_size; j++) {
2628                         struct vop_win *vop_area = &vop->win[num_wins];
2629                         const struct vop_win_phy *area = win_data->area[j];
2630
2631                         vop_area->parent = vop_win;
2632                         vop_area->offset = vop_win->offset;
2633                         vop_area->phy = area;
2634                         vop_area->type = DRM_PLANE_TYPE_OVERLAY;
2635                         vop_area->data_formats = vop_win->data_formats;
2636                         vop_area->nformats = vop_win->nformats;
2637                         vop_area->vop = vop;
2638                         vop_area->win_id = i;
2639                         vop_area->area_id = j;
2640                         num_wins++;
2641                 }
2642         }
2643
2644         vop->num_wins = num_wins;
2645
2646         prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_ATOMIC,
2647                                          "ZPOS", 0, vop->data->win_size);
2648         if (!prop) {
2649                 DRM_ERROR("failed to create zpos property\n");
2650                 return -EINVAL;
2651         }
2652         vop->plane_zpos_prop = prop;
2653
2654         vop->plane_feature_prop = drm_property_create_bitmask(vop->drm_dev,
2655                                 DRM_MODE_PROP_IMMUTABLE, "FEATURE",
2656                                 props, ARRAY_SIZE(props),
2657                                 BIT(ROCKCHIP_DRM_PLANE_FEATURE_SCALE) |
2658                                 BIT(ROCKCHIP_DRM_PLANE_FEATURE_ALPHA));
2659         if (!vop->plane_feature_prop) {
2660                 DRM_ERROR("failed to create feature property\n");
2661                 return -EINVAL;
2662         }
2663
2664         vop->feature_prop = drm_property_create_bitmask(vop->drm_dev,
2665                                 DRM_MODE_PROP_IMMUTABLE, "FEATURE",
2666                                 crtc_props, ARRAY_SIZE(crtc_props),
2667                                 BIT(ROCKCHIP_DRM_CRTC_FEATURE_AFBDC));
2668         if (!vop->feature_prop) {
2669                 DRM_ERROR("failed to create vop feature property\n");
2670                 return -EINVAL;
2671         }
2672
2673         return 0;
2674 }
2675
2676 /**
2677  * rockchip_drm_wait_line_flag - acqiure the give line flag event
2678  * @crtc: CRTC to enable line flag
2679  * @line_num: interested line number
2680  * @mstimeout: millisecond for timeout
2681  *
2682  * Driver would hold here until the interested line flag interrupt have
2683  * happened or timeout to wait.
2684  *
2685  * Returns:
2686  * Zero on success, negative errno on failure.
2687  */
2688 int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
2689                                 unsigned int mstimeout)
2690 {
2691         struct vop *vop = to_vop(crtc);
2692         unsigned long jiffies_left;
2693         int ret = 0;
2694
2695         if (!crtc || !vop->is_enabled)
2696                 return -ENODEV;
2697
2698         mutex_lock(&vop->vop_lock);
2699
2700         if (line_num > crtc->mode.vtotal || mstimeout <= 0) {
2701                 ret = -EINVAL;
2702                 goto out;
2703         }
2704
2705         if (vop_line_flag_irq_is_enabled(vop)) {
2706                 ret = -EBUSY;
2707                 goto out;
2708         }
2709
2710         reinit_completion(&vop->line_flag_completion);
2711         vop_line_flag_irq_enable(vop, line_num);
2712
2713         jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
2714                                                    msecs_to_jiffies(mstimeout));
2715         vop_line_flag_irq_disable(vop);
2716
2717         if (jiffies_left == 0) {
2718                 dev_err(vop->dev, "Timeout waiting for IRQ\n");
2719                 ret = -ETIMEDOUT;
2720                 goto out;
2721         }
2722
2723 out:
2724         mutex_unlock(&vop->vop_lock);
2725
2726         return ret;
2727 }
2728 EXPORT_SYMBOL(rockchip_drm_wait_line_flag);
2729
2730 static int dmc_notifier_call(struct notifier_block *nb, unsigned long event,
2731                              void *data)
2732 {
2733         if (event == DEVFREQ_PRECHANGE)
2734                 mutex_lock(&dmc_vop->vop_lock);
2735         else if (event == DEVFREQ_POSTCHANGE)
2736                 mutex_unlock(&dmc_vop->vop_lock);
2737
2738         return NOTIFY_OK;
2739 }
2740
2741 int rockchip_drm_register_notifier_to_dmc(struct devfreq *devfreq)
2742 {
2743         if (!dmc_vop)
2744                 return -ENOMEM;
2745
2746         dmc_vop->devfreq = devfreq;
2747         dmc_vop->dmc_nb.notifier_call = dmc_notifier_call;
2748         devfreq_register_notifier(dmc_vop->devfreq, &dmc_vop->dmc_nb,
2749                                   DEVFREQ_TRANSITION_NOTIFIER);
2750         return 0;
2751 }
2752 EXPORT_SYMBOL(rockchip_drm_register_notifier_to_dmc);
2753
2754 static int vop_bind(struct device *dev, struct device *master, void *data)
2755 {
2756         struct platform_device *pdev = to_platform_device(dev);
2757         const struct vop_data *vop_data;
2758         struct drm_device *drm_dev = data;
2759         struct vop *vop;
2760         struct resource *res;
2761         size_t alloc_size;
2762         int ret, irq, i;
2763         int num_wins = 0;
2764
2765         vop_data = of_device_get_match_data(dev);
2766         if (!vop_data)
2767                 return -ENODEV;
2768
2769         for (i = 0; i < vop_data->win_size; i++) {
2770                 const struct vop_win_data *win_data = &vop_data->win[i];
2771
2772                 num_wins += win_data->area_size + 1;
2773         }
2774
2775         /* Allocate vop struct and its vop_win array */
2776         alloc_size = sizeof(*vop) + sizeof(*vop->win) * num_wins;
2777         vop = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
2778         if (!vop)
2779                 return -ENOMEM;
2780
2781         vop->dev = dev;
2782         vop->data = vop_data;
2783         vop->drm_dev = drm_dev;
2784         vop->num_wins = num_wins;
2785         dev_set_drvdata(dev, vop);
2786
2787         ret = vop_win_init(vop);
2788         if (ret)
2789                 return ret;
2790
2791         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2792         vop->len = resource_size(res);
2793         vop->regs = devm_ioremap_resource(dev, res);
2794         if (IS_ERR(vop->regs))
2795                 return PTR_ERR(vop->regs);
2796
2797         vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
2798         if (!vop->regsbak)
2799                 return -ENOMEM;
2800
2801         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2802         vop->lut_regs = devm_ioremap_resource(dev, res);
2803         if (IS_ERR(vop->lut_regs)) {
2804                 dev_warn(vop->dev, "failed to get vop lut registers\n");
2805                 vop->lut_regs = NULL;
2806         }
2807         if (vop->lut_regs) {
2808                 vop->lut_len = resource_size(res) / sizeof(*vop->lut);
2809                 if (vop->lut_len != 256 && vop->lut_len != 1024) {
2810                         dev_err(vop->dev, "unsupport lut sizes %d\n",
2811                                 vop->lut_len);
2812                         return -EINVAL;
2813                 }
2814         }
2815
2816         vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
2817         if (IS_ERR(vop->hclk)) {
2818                 dev_err(vop->dev, "failed to get hclk source\n");
2819                 return PTR_ERR(vop->hclk);
2820         }
2821         vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
2822         if (IS_ERR(vop->aclk)) {
2823                 dev_err(vop->dev, "failed to get aclk source\n");
2824                 return PTR_ERR(vop->aclk);
2825         }
2826         vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
2827         if (IS_ERR(vop->dclk)) {
2828                 dev_err(vop->dev, "failed to get dclk source\n");
2829                 return PTR_ERR(vop->dclk);
2830         }
2831
2832         vop->dclk_source = devm_clk_get(vop->dev, "dclk_source");
2833         if (PTR_ERR(vop->dclk_source) == -ENOENT) {
2834                 vop->dclk_source = NULL;
2835         } else if (PTR_ERR(vop->dclk_source) == -EPROBE_DEFER) {
2836                 return -EPROBE_DEFER;
2837         } else if (IS_ERR(vop->dclk_source)) {
2838                 dev_err(vop->dev, "failed to get dclk source parent\n");
2839                 return PTR_ERR(vop->dclk_source);
2840         }
2841
2842         irq = platform_get_irq(pdev, 0);
2843         if (irq < 0) {
2844                 dev_err(dev, "cannot find irq for vop\n");
2845                 return irq;
2846         }
2847         vop->irq = (unsigned int)irq;
2848
2849         spin_lock_init(&vop->reg_lock);
2850         spin_lock_init(&vop->irq_lock);
2851         mutex_init(&vop->vop_lock);
2852
2853         mutex_init(&vop->vsync_mutex);
2854
2855         ret = devm_request_irq(dev, vop->irq, vop_isr,
2856                                IRQF_SHARED, dev_name(dev), vop);
2857         if (ret)
2858                 return ret;
2859
2860         /* IRQ is initially disabled; it gets enabled in power_on */
2861         disable_irq(vop->irq);
2862
2863         ret = vop_create_crtc(vop);
2864         if (ret)
2865                 return ret;
2866
2867         pm_runtime_enable(&pdev->dev);
2868
2869         dmc_vop = vop;
2870
2871         return 0;
2872 }
2873
2874 static void vop_unbind(struct device *dev, struct device *master, void *data)
2875 {
2876         struct vop *vop = dev_get_drvdata(dev);
2877
2878         pm_runtime_disable(dev);
2879         vop_destroy_crtc(vop);
2880 }
2881
2882 const struct component_ops vop_component_ops = {
2883         .bind = vop_bind,
2884         .unbind = vop_unbind,
2885 };
2886 EXPORT_SYMBOL_GPL(vop_component_ops);