video: rockchip: vop: 3399: update for write back function
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk322x_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk322x_lcdc.c
3  *
4  * Copyright (C) 2015 ROCKCHIP, Inc.
5  * Author: Mark Yao <mark.yao@rock-chips.com>
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/of_device.h>
28 #include <linux/platform_device.h>
29 #include <linux/clk.h>
30 #include <linux/rockchip-iovmm.h>
31 #include <asm/div64.h>
32 #include <linux/uaccess.h>
33 #include <linux/rockchip/iomap.h>
34 #include <linux/rockchip/grf.h>
35 #include <linux/rockchip/common.h>
36 #include <dt-bindings/clock/rk_system_status.h>
37
38 #include "rk322x_lcdc.h"
39
40 /*#define CONFIG_RK_FPGA 1*/
41 #define VOP_CHIP(dev)   (dev->data->chip_type)
42
43 static int dbg_thresd;
44 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
45
46 #define DBG(level, x...) do {                   \
47         if (unlikely(dbg_thresd >= level))      \
48                 pr_info(x);\
49         } while (0)
50
51 static struct rk_lcdc_win rk322x_vop_win[] = {
52         { .name = "win0", .id = VOP_WIN0},
53         { .name = "win1", .id = VOP_WIN1},
54         { .name = "hwc",  .id = VOP_HWC}
55 };
56
57 static struct rk_lcdc_win rk3399_vop_win[] = {
58         { .name = "win0", .id = VOP_WIN0},
59         { .name = "win1", .id = VOP_WIN1},
60         { .name = "win2", .id = VOP_WIN2},
61         { .name = "win3", .id = VOP_WIN3},
62         { .name = "hwc",  .id = VOP_HWC}
63 };
64
65 static const struct vop_data rk322x_data = {
66         .chip_type = VOP_RK322X,
67         .win = rk322x_vop_win,
68         .n_wins = ARRAY_SIZE(rk322x_vop_win),
69 };
70
71 static const struct vop_data rk3399_data = {
72         .chip_type = VOP_RK3399,
73         .win = rk3399_vop_win,
74         .n_wins = ARRAY_SIZE(rk3399_vop_win),
75 };
76
77 #if defined(CONFIG_OF)
78 static const struct of_device_id vop_dt_ids[] = {
79         {.compatible = "rockchip,rk322x-lcdc",
80          .data = &rk322x_data, },
81         {.compatible = "rockchip,rk3399-lcdc",
82          .data = &rk3399_data, },
83         {}
84 };
85 #endif
86
87 static const u32 csc_y2r_bt601_limit[12] = {
88         0x04a8,      0,  0x0662, 0xfffc8654,
89         0x04a8, 0xfe6f,  0xfcbf, 0x00022056,
90         0x04a8, 0x0812,       0, 0xfffbaeac,
91 };
92
93 static const u32 csc_y2r_bt709_full[12] = {
94         0x04a8,      0,  0x072c, 0xfffc219e,
95         0x04a8, 0xff26,  0xfdde, 0x0001357b,
96         0x04a8, 0x0873,       0, 0xfffb7dee,
97 };
98
99 static const u32 csc_y2r_bt601_full[12] = {
100         0x0400,      0,  0x059c, 0xfffd342d,
101         0x0400, 0xfea0,  0xfd25, 0x00021fcc,
102         0x0400, 0x0717,       0, 0xfffc76bc,
103 };
104
105 static const u32 csc_y2r_bt601_limit_10[12] = {
106         0x04a8,      0,  0x0662, 0xfff2134e,
107         0x04a8, 0xfe6f,  0xfcbf, 0x00087b58,
108         0x04a8, 0x0812,       0, 0xffeeb4b0,
109 };
110
111 static const u32 csc_y2r_bt709_full_10[12] = {
112         0x04a8,      0,  0x072c, 0xfff08077,
113         0x04a8, 0xff26,  0xfdde, 0x0004cfed,
114         0x04a8, 0x0873,       0, 0xffedf1b8,
115 };
116
117 static const u32 csc_y2r_bt601_full_10[12] = {
118         0x0400,      0,  0x059c, 0xfff4cab4,
119         0x0400, 0xfea0,  0xfd25, 0x00087932,
120         0x0400, 0x0717,       0, 0xfff1d4f2,
121 };
122
123 static const u32 csc_y2r_bt2020[12] = {
124         0x04a8,      0, 0x06b6, 0xfff16bfc,
125         0x04a8, 0xff40, 0xfd66, 0x58ae9,
126         0x04a8, 0x0890,      0, 0xffedb828,
127 };
128
129 static const u32 csc_r2y_bt601_limit[12] = {
130         0x0107, 0x0204, 0x0064, 0x04200,
131         0xff68, 0xfed6, 0x01c2, 0x20200,
132         0x01c2, 0xfe87, 0xffb7, 0x20200,
133 };
134
135 static const u32 csc_r2y_bt709_full[12] = {
136         0x00bb, 0x0275, 0x003f, 0x04200,
137         0xff99, 0xfea5, 0x01c2, 0x20200,
138         0x01c2, 0xfe68, 0xffd7, 0x20200,
139 };
140
141 static const u32 csc_r2y_bt601_full[12] = {
142         0x0132, 0x0259, 0x0075, 0x200,
143         0xff53, 0xfead, 0x0200, 0x20200,
144         0x0200, 0xfe53, 0xffad, 0x20200,
145 };
146
147 static const u32 csc_r2y_bt601_limit_10[12] = {
148         0x0107, 0x0204, 0x0064, 0x10200,
149         0xff68, 0xfed6, 0x01c2, 0x80200,
150         0x01c2, 0xfe87, 0xffb7, 0x80200,
151 };
152
153 static const u32 csc_r2y_bt709_full_10[12] = {
154         0x00bb, 0x0275, 0x003f, 0x10200,
155         0xff99, 0xfea5, 0x01c2, 0x80200,
156         0x01c2, 0xfe68, 0xffd7, 0x80200,
157 };
158
159 static const u32 csc_r2y_bt601_full_10[12] = {
160         0x0132, 0x0259, 0x0075, 0x200,
161         0xff53, 0xfead, 0x0200, 0x80200,
162         0x0200, 0xfe53, 0xffad, 0x80200,
163 };
164
165 static const u32 csc_r2y_bt2020[12] = {
166         0x00e6, 0x0253, 0x0034, 0x10200,
167         0xff83, 0xfebd, 0x01c1, 0x80200,
168         0x01c1, 0xfe64, 0xffdc, 0x80200,
169 };
170
171 static const u32 csc_r2r_bt2020to709[12] = {
172         0x06a4, 0xfda6, 0xffb5, 0x200,
173         0xff80, 0x0488, 0xfff8, 0x200,
174         0xffed, 0xff99, 0x047a, 0x200,
175 };
176
177 static const u32 csc_r2r_bt709to2020[12] = {
178         0x282, 0x151, 0x02c, 0x200,
179         0x047, 0x3ae, 0x00c, 0x200,
180         0x011, 0x05a, 0x395, 0x200,
181 };
182
183 static int vop_get_id(struct vop_device *vop_dev, u32 phy_base)
184 {
185         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
186                 if (phy_base == 0xff900000) /* vop big */
187                         return 0;
188                 else if (phy_base == 0xff8f0000) /* vop lit */
189                         return 1;
190                 else
191                         return -EINVAL;
192         } else {
193                 return 0;
194         }
195 }
196
197 static void vop_load_csc_table(struct vop_device *vop_dev, u32 offset,
198                                const u32 *table)
199 {
200         u32 csc_val;
201
202         csc_val = table[1] << 16 | table[0];
203         vop_writel(vop_dev, offset, csc_val);
204         csc_val = table[4] << 16 | table[2];
205         vop_writel(vop_dev, offset + 4, csc_val);
206         csc_val = table[6] << 16 | table[5];
207         vop_writel(vop_dev, offset + 8, csc_val);
208         csc_val = table[9] << 16 | table[8];
209         vop_writel(vop_dev, offset + 0xc, csc_val);
210         csc_val = table[10];
211         vop_writel(vop_dev, offset + 0x10, csc_val);
212         csc_val = table[3];
213         vop_writel(vop_dev, offset + 0x14, csc_val);
214         csc_val = table[7];
215         vop_writel(vop_dev, offset + 0x18, csc_val);
216         csc_val = table[11];
217         vop_writel(vop_dev, offset + 0x1c, csc_val);
218 }
219
220 #define LOAD_CSC(dev, mode, table, win_id) \
221                 vop_load_csc_table(dev, \
222                                    WIN0_YUV2YUV_##mode + 0x60 * win_id, \
223                                    table)
224
225 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
226
227 static int vop_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
228 {
229         struct vop_device *vop_dev =
230                         container_of(dev_drv, struct vop_device, driver);
231         int i, j;
232
233         if (!vop_dev->dsp_lut_addr_base) {
234                 dev_warn(vop_dev->dev, "not support dsp lut config\n");
235                 return 0;
236         }
237
238         if (!dsp_lut) {
239                 dev_err(vop_dev->dev, "dsp lut table is null\n");
240                 return -EINVAL;
241         }
242
243         spin_lock(&vop_dev->reg_lock);
244         for (i = 0; i < 256; i++) {
245                 u32 v, r, g, b;
246                 int __iomem *c;
247
248                 v = dsp_lut[i];
249                 c = vop_dev->dsp_lut_addr_base + (i << 2);
250                 b = (v & 0xff) << 2;
251                 g = (v & 0xff00) << 4;
252                 r = (v & 0xff0000) << 6;
253                 v = r + g + b;
254                 for (j = 0; j < 4; j++) {
255                         writel_relaxed(v, c);
256                         v += (1 + (1 << 10) + (1 << 20));
257                         c++;
258                 }
259         }
260         vop_msk_reg(vop_dev, DSP_CTRL1, V_DSP_LUT_EN(1));
261         /*
262          * update_gamma value auto clean to 0 by HW, should not
263          * bakeup it.
264          */
265         vop_msk_reg_nobak(vop_dev, DSP_CTRL1, V_UPDATE_GAMMA_LUT(1));
266
267         vop_cfg_done(vop_dev);
268         spin_unlock(&vop_dev->reg_lock);
269
270         return 0;
271 }
272
273 static int vop_set_cabc(struct rk_lcdc_driver *dev_drv, int *cabc_lut)
274 {
275         struct vop_device *vop_dev =
276                         container_of(dev_drv, struct vop_device, driver);
277         int i;
278
279         if (!vop_dev->cabc_lut_addr_base) {
280                 dev_warn(vop_dev->dev, "not support cabc config\n");
281                 return 0;
282         }
283
284         if (!cabc_lut) {
285                 dev_err(vop_dev->dev, "cabc lut table is null\n");
286                 return -EINVAL;
287         }
288         spin_lock(&vop_dev->reg_lock);
289         vop_msk_reg(vop_dev, CABC_CTRL1, V_CABC_LUT_EN(0));
290         vop_cfg_done(vop_dev);
291         spin_unlock(&vop_dev->reg_lock);
292
293         mdelay(25);
294
295         spin_lock(&vop_dev->reg_lock);
296         for (i = 0; i < 128; i++) {
297                 u32 v;
298
299                 v = cabc_lut[i];
300
301                 writel_relaxed(v, vop_dev->cabc_lut_addr_base + i);
302         }
303         vop_msk_reg(vop_dev, CABC_CTRL1, V_CABC_LUT_EN(1));
304         spin_unlock(&vop_dev->reg_lock);
305
306         return 0;
307 }
308
309 static int vop_clk_enable(struct vop_device *vop_dev)
310 {
311         if (!vop_dev->clk_on) {
312                 clk_prepare_enable(vop_dev->hclk);
313                 clk_prepare_enable(vop_dev->dclk);
314                 clk_prepare_enable(vop_dev->aclk);
315                 if (vop_dev->hclk_noc)
316                         clk_prepare_enable(vop_dev->hclk_noc);
317                 if (vop_dev->aclk_noc)
318                         clk_prepare_enable(vop_dev->aclk_noc);
319                 spin_lock(&vop_dev->reg_lock);
320                 vop_dev->clk_on = 1;
321                 spin_unlock(&vop_dev->reg_lock);
322         }
323
324         return 0;
325 }
326
327 static int vop_clk_disable(struct vop_device *vop_dev)
328 {
329         if (vop_dev->clk_on) {
330                 spin_lock(&vop_dev->reg_lock);
331                 vop_dev->clk_on = 0;
332                 spin_unlock(&vop_dev->reg_lock);
333                 mdelay(25);
334                 clk_disable_unprepare(vop_dev->dclk);
335                 clk_disable_unprepare(vop_dev->hclk);
336                 clk_disable_unprepare(vop_dev->aclk);
337                 if (vop_dev->hclk_noc)
338                         clk_disable_unprepare(vop_dev->hclk_noc);
339                 if (vop_dev->aclk_noc)
340                         clk_disable_unprepare(vop_dev->aclk_noc);
341         }
342
343         return 0;
344 }
345
346 static int __maybe_unused vop_disable_irq(struct vop_device *vop_dev)
347 {
348         if (likely(vop_dev->clk_on)) {
349                 spin_lock(&vop_dev->reg_lock);
350                 vop_writel(vop_dev, INTR_EN0, 0xffff0000);
351                 vop_writel(vop_dev, INTR_EN1, 0xffff0000);
352                 vop_writel(vop_dev, INTR_CLEAR0, 0xffffffff);
353                 vop_writel(vop_dev, INTR_CLEAR1, 0xffffffff);
354                 vop_cfg_done(vop_dev);
355                 spin_unlock(&vop_dev->reg_lock);
356         };
357
358         return 0;
359 }
360
361 static int vop_reg_dump(struct rk_lcdc_driver *dev_drv)
362 {
363         struct vop_device *vop_dev =
364             container_of(dev_drv, struct vop_device, driver);
365         int *cbase = (int *)vop_dev->regs;
366         int *regsbak = (int *)vop_dev->regsbak;
367         int i, j, val;
368         char dbg_message[30];
369         char buf[10];
370
371         pr_info("lcd back up reg:\n");
372         memset(dbg_message, 0, sizeof(dbg_message));
373         memset(buf, 0, sizeof(buf));
374         for (i = 0; i <= (0x200 >> 4); i++) {
375                 val = sprintf(dbg_message, "0x%04x: ", i * 16);
376                 for (j = 0; j < 4; j++) {
377                         val = sprintf(buf, "%08x  ", *(regsbak + i * 4 + j));
378                         strcat(dbg_message, buf);
379                 }
380                 pr_info("%s\n", dbg_message);
381                 memset(dbg_message, 0, sizeof(dbg_message));
382                 memset(buf, 0, sizeof(buf));
383         }
384
385         pr_info("lcdc reg:\n");
386         for (i = 0; i <= (0x200 >> 4); i++) {
387                 val = sprintf(dbg_message, "0x%04x: ", i * 16);
388                 for (j = 0; j < 4; j++) {
389                         sprintf(buf, "%08x  ",
390                                 readl_relaxed(cbase + i * 4 + j));
391                         strcat(dbg_message, buf);
392                 }
393                 pr_info("%s\n", dbg_message);
394                 memset(dbg_message, 0, sizeof(dbg_message));
395                 memset(buf, 0, sizeof(buf));
396         }
397
398         return 0;
399 }
400
401 #define WIN_EN(id)              \
402 static int win##id##_enable(struct vop_device *vop_dev, int en) \
403 { \
404         spin_lock(&vop_dev->reg_lock);                                  \
405         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN((u64)en)); \
406         vop_cfg_done(vop_dev);                                          \
407         spin_unlock(&vop_dev->reg_lock);                                \
408         return 0;                                                       \
409 }
410
411 WIN_EN(0);
412 WIN_EN(1);
413 WIN_EN(2);
414 WIN_EN(3);
415
416 /*enable/disable win directly*/
417 static int vop_win_direct_en(struct rk_lcdc_driver *drv,
418                              int win_id, int en)
419 {
420         struct vop_device *vop_dev =
421             container_of(drv, struct vop_device, driver);
422         if (win_id == 0)
423                 win0_enable(vop_dev, en);
424         else if (win_id == 1)
425                 win1_enable(vop_dev, en);
426         else if (win_id == 2)
427                 win2_enable(vop_dev, en);
428         else if (win_id == 3)
429                 win3_enable(vop_dev, en);
430         else
431                 dev_err(vop_dev->dev, "invalid win number:%d\n", win_id);
432         return 0;
433 }
434
435 #define SET_WIN_ADDR(id) \
436 static int set_win##id##_addr(struct vop_device *vop_dev, u32 addr) \
437 {                                                       \
438         spin_lock(&vop_dev->reg_lock);                  \
439         vop_writel(vop_dev, WIN##id##_YRGB_MST, addr);  \
440         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN(1));       \
441         vop_cfg_done(vop_dev);                  \
442         spin_unlock(&vop_dev->reg_lock);                \
443         return 0;                                       \
444 }
445
446 SET_WIN_ADDR(0);
447 SET_WIN_ADDR(1);
448 int vop_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
449                             int win_id, u32 addr)
450 {
451         struct vop_device *vop_dev =
452             container_of(dev_drv, struct vop_device, driver);
453         if (win_id == 0)
454                 set_win0_addr(vop_dev, addr);
455         else
456                 set_win1_addr(vop_dev, addr);
457
458         return 0;
459 }
460
461 static void lcdc_read_reg_defalut_cfg(struct vop_device *vop_dev)
462 {
463         int reg = 0;
464         u32 val = 0;
465         struct rk_screen *screen = vop_dev->driver.cur_screen;
466         u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
467         u32 V_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
468         u32 st_x, st_y;
469         struct rk_lcdc_win *win0 = vop_dev->driver.win[0];
470
471         spin_lock(&vop_dev->reg_lock);
472         for (reg = 0; reg < vop_dev->len; reg += 4) {
473                 val = vop_readl_backup(vop_dev, reg);
474                 switch (reg) {
475                 case WIN0_ACT_INFO:
476                         win0->area[0].xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
477                         win0->area[0].yact =
478                                 ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
479                         break;
480                 case WIN0_DSP_INFO:
481                         win0->area[0].xsize = (val & MASK(WIN0_DSP_WIDTH)) + 1;
482                         win0->area[0].ysize =
483                             ((val & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
484                         break;
485                 case WIN0_DSP_ST:
486                         st_x = val & MASK(WIN0_DSP_XST);
487                         st_y = (val & MASK(WIN0_DSP_YST)) >> 16;
488                         win0->area[0].xpos = st_x - h_pw_bp;
489                         win0->area[0].ypos = st_y - V_pw_bp;
490                         break;
491                 case WIN0_CTRL0:
492                         win0->state = val & MASK(WIN0_EN);
493                         win0->area[0].fmt_cfg =
494                                         (val & MASK(WIN0_DATA_FMT)) >> 1;
495                         win0->fmt_10 = (val & MASK(WIN0_FMT_10)) >> 4;
496                         win0->area[0].format = win0->area[0].fmt_cfg;
497                         break;
498                 case WIN0_VIR:
499                         win0->area[0].y_vir_stride =
500                                         val & MASK(WIN0_VIR_STRIDE);
501                         win0->area[0].uv_vir_stride =
502                             (val & MASK(WIN0_VIR_STRIDE_UV)) >> 16;
503                         if (win0->area[0].format == ARGB888)
504                                 win0->area[0].xvir = win0->area[0].y_vir_stride;
505                         else if (win0->area[0].format == RGB888)
506                                 win0->area[0].xvir =
507                                     win0->area[0].y_vir_stride * 4 / 3;
508                         else if (win0->area[0].format == RGB565)
509                                 win0->area[0].xvir =
510                                     2 * win0->area[0].y_vir_stride;
511                         else
512                                 win0->area[0].xvir =
513                                     4 * win0->area[0].y_vir_stride;
514                         break;
515                 case WIN0_YRGB_MST:
516                         win0->area[0].smem_start = val;
517                         break;
518                 case WIN0_CBR_MST:
519                         win0->area[0].cbr_start = val;
520                         break;
521                 default:
522                         break;
523                 }
524         }
525         spin_unlock(&vop_dev->reg_lock);
526 }
527
528 /********do basic init*********/
529 static int vop_pre_init(struct rk_lcdc_driver *dev_drv)
530 {
531         struct vop_device *vop_dev =
532             container_of(dev_drv, struct vop_device, driver);
533         if (vop_dev->pre_init)
534                 return 0;
535         vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_lcdc");
536         vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_lcdc");
537         vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_lcdc");
538         if (IS_ERR(vop_dev->aclk) || IS_ERR(vop_dev->dclk) ||
539             IS_ERR(vop_dev->hclk))
540                 dev_err(vop_dev->dev, "failed to get clk source\n");
541         vop_dev->hclk_noc = devm_clk_get(vop_dev->dev, "hclk_vop_noc");
542         if (IS_ERR(vop_dev->hclk_noc)) {
543                 vop_dev->hclk_noc = NULL;
544                 dev_err(vop_dev->dev, "failed to get clk source\n");
545         }
546         vop_dev->aclk_noc = devm_clk_get(vop_dev->dev, "aclk_vop_noc");
547         if (IS_ERR(vop_dev->aclk_noc)) {
548                 vop_dev->aclk_noc = NULL;
549                 dev_err(vop_dev->dev, "failed to get clk source\n");
550         }
551         if (!support_uboot_display())
552                 rk_disp_pwr_enable(dev_drv);
553         vop_clk_enable(vop_dev);
554
555         memcpy(vop_dev->regsbak, vop_dev->regs, vop_dev->len);
556         /*backup reg config at uboot */
557         lcdc_read_reg_defalut_cfg(vop_dev);
558         #ifndef CONFIG_RK_FPGA
559         /*
560          * Todo, not verified
561          *
562         if (vop_dev->pwr18 == 1) {
563                 v = 0x00200020;
564                 vop_grf_writel(vop_dev->pmugrf_base,
565                                 PMUGRF_SOC_CON0_VOP, v);
566         } else {
567                 v = 0x00200000;
568                 vop_grf_writel(vop_dev->pmugrf_base,
569                                 PMUGRF_SOC_CON0_VOP, v);
570         }
571         */
572         #endif
573         vop_writel(vop_dev, FRC_LOWER01_0, 0x12844821);
574         vop_writel(vop_dev, FRC_LOWER01_1, 0x21488412);
575         vop_writel(vop_dev, FRC_LOWER10_0, 0xa55a9696);
576         vop_writel(vop_dev, FRC_LOWER10_1, 0x5aa56969);
577         vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb);
578         vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de);
579
580         vop_msk_reg(vop_dev, SYS_CTRL, V_AUTO_GATING_EN(0));
581         vop_msk_reg(vop_dev, DSP_CTRL1, V_DITHER_UP_EN(1));
582         vop_cfg_done(vop_dev);
583         vop_dev->pre_init = true;
584
585         return 0;
586 }
587
588 static void vop_deint(struct vop_device *vop_dev)
589 {
590         if (vop_dev->clk_on) {
591                 u64 val;
592
593                 vop_disable_irq(vop_dev);
594                 spin_lock(&vop_dev->reg_lock);
595                 vop_msk_reg(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
596                 vop_msk_reg(vop_dev, WIN1_CTRL0, V_WIN0_EN(0));
597
598                 val = V_WIN2_EN(0) | V_WIN2_MST0_EN(0) | V_WIN2_MST1_EN(0) |
599                         V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
600                 vop_msk_reg(vop_dev, WIN2_CTRL0, val);
601                 vop_msk_reg(vop_dev, WIN3_CTRL0, val);
602                 vop_cfg_done(vop_dev);
603                 spin_unlock(&vop_dev->reg_lock);
604                 mdelay(50);
605         }
606 }
607
608 static void vop_win_csc_mode(struct vop_device *vop_dev,
609                              struct rk_lcdc_win *win,
610                              int csc_mode)
611 {
612         u64 val;
613
614         if (win->id == VOP_WIN0) {
615                 val = V_WIN0_CSC_MODE(csc_mode);
616                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
617         } else if (win->id == VOP_WIN1) {
618                 val = V_WIN1_CSC_MODE(csc_mode);
619                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
620         } else {
621                 val = V_HWC_CSC_MODE(csc_mode);
622                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
623         }
624 }
625
626 static int rk3399_vop_win_csc_cfg(struct rk_lcdc_driver *dev_drv)
627 {
628         struct vop_device *vop_dev =
629             container_of(dev_drv, struct vop_device, driver);
630         int output_color = dev_drv->output_color;
631         int i;
632
633         for (i = 0; i < dev_drv->lcdc_win_num && i <= 4; i++) {
634                 struct rk_lcdc_win *win = dev_drv->win[i];
635                 int shift = i * 8;
636                 u64 val = V_WIN0_YUV2YUV_EN(0) | V_WIN0_YUV2YUV_R2Y_EN(0) |
637                                 V_WIN0_YUV2YUV_Y2R_EN(0);
638
639                 if (!win->state)
640                         continue;
641                 if (output_color == COLOR_RGB &&
642                     !(IS_YUV(win->area[0].fmt_cfg) || win->area[0].yuyv_fmt))
643                         goto post;
644
645                 if (output_color == COLOR_RGB) {
646                         val |= V_WIN0_YUV2YUV_Y2R_EN(1);
647                         if (win->colorspace == CSC_BT601) {
648                                 /*
649                                  * Win Y2Y moudle always use 10bit mode.
650                                  */
651                                 LOAD_CSC(vop_dev, Y2R,
652                                          csc_y2r_bt601_full_10, i);
653                         } else if (win->colorspace == CSC_BT709) {
654                                 LOAD_CSC(vop_dev, Y2R,
655                                          csc_y2r_bt709_full_10, i);
656                         } else if (win->colorspace == CSC_BT2020) {
657                                 val |= V_WIN0_YUV2YUV_EN(1);
658                                 LOAD_CSC(vop_dev, Y2R, csc_y2r_bt2020, i);
659                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt2020to709, i);
660                         }
661                 } else if (output_color == COLOR_YCBCR ||
662                                 output_color == COLOR_YCBCR_BT709) {
663                         if (!(IS_YUV(win->area[0].fmt_cfg) ||
664                               win->area[0].yuyv_fmt)) {
665                                 val |= V_WIN0_YUV2YUV_R2Y_EN(1);
666                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt709_full_10, i);
667                         } else if (win->colorspace == CSC_BT2020) {
668                                 val |= V_WIN0_YUV2YUV_EN(1) |
669                                         V_WIN0_YUV2YUV_Y2R_EN(1) |
670                                         V_WIN0_YUV2YUV_R2Y_EN(1);
671                                 LOAD_CSC(vop_dev, Y2R, csc_y2r_bt2020, i);
672                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt2020to709, i);
673                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt709_full_10, i);
674                         }
675                 } else if (output_color == COLOR_YCBCR_BT2020) {
676                         if (!(IS_YUV(win->area[0].fmt_cfg) ||
677                               win->area[0].yuyv_fmt)) {
678                                 val |= V_WIN0_YUV2YUV_R2Y_EN(1) |
679                                         V_WIN0_YUV2YUV_EN(1);
680                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt709to2020, i);
681                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt2020, i);
682                         } else if (win->colorspace == CSC_BT601 ||
683                                         win->colorspace == CSC_BT709) {
684                                 val |= V_WIN0_YUV2YUV_Y2R_EN(1) |
685                                         V_WIN0_YUV2YUV_R2Y_EN(1) |
686                                         V_WIN0_YUV2YUV_EN(1);
687                                 LOAD_CSC(vop_dev, Y2R, csc_y2r_bt709_full_10, i);
688                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt709to2020, i);
689                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt2020, i);
690                         }
691                 }
692 post:
693                 vop_msk_reg(vop_dev, YUV2YUV_WIN, val << shift);
694         }
695
696         return output_color;
697 }
698
699 /*
700  * colorspace path:
701  *      Input        Win csc            Post csc              Output
702  * 1. YUV(2020)  --> bypass   ---+ Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
703  *    RGB        --> R2Y(709) __/
704  *
705  * 2. YUV(2020)  --> bypass   ---+       bypass        --> YUV_OUTPUT(2020)
706  *    RGB        --> R2Y(709) __/
707  *
708  * 3. YUV(2020)  --> bypass   ---+    Y2R->2020To709   --> RGB_OUTPUT(709)
709  *    RGB        --> R2Y(709) __/
710  *
711  * 4. YUV(601/709)-> bypass   ---+ Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
712  *    RGB        --> R2Y(709) __/
713  *
714  * 5. YUV(601/709)-> bypass   ---+       bypass        --> YUV_OUTPUT(709)
715  *    RGB        --> R2Y(709) __/
716  *
717  * 6. YUV(601/709)-> bypass   ---+       bypass        --> YUV_OUTPUT(601)
718  *    RGB        --> R2Y(601) __/
719  *
720  * 7. YUV(601)   --> Y2R(601/mpeg)-+     bypass        --> RGB_OUTPUT(709)
721  *    RGB        --> bypass   ____/
722  *
723  * 8. YUV(709)   --> Y2R(709/hd) --+     bypass        --> RGB_OUTPUT(709)
724  *    RGB        --> bypass   ____/
725  *
726  * 9. RGB        --> bypass   --->    709To2020->R2Y   --> YUV_OUTPUT(2020)
727  *
728  * 10. RGB       --> R2Y(709) --->      bypass        --> YUV_OUTPUT(709)
729  *
730  * 11. RGB       --> R2Y(601) --->       bypass        --> YUV_OUTPUT(601)
731  *
732  * 12. RGB       --> bypass   --->       bypass        --> RGB_OUTPUT(709)
733  */
734 static int rk3228_vop_win_csc_cfg(struct rk_lcdc_driver *dev_drv)
735 {
736         struct vop_device *vop_dev =
737             container_of(dev_drv, struct vop_device, driver);
738         struct rk_lcdc_win *win;
739         int output_color = dev_drv->output_color;
740         int win_csc = COLOR_RGB;
741         int r2y_mode = VOP_R2Y_CSC_BT709;
742         int i;
743
744         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
745                 win = dev_drv->win[i];
746                 if (!win->state)
747                         continue;
748
749                 if (IS_YUV(win->area[0].fmt_cfg)) {
750                         if (win->colorspace == CSC_BT2020 &&
751                             win_csc < COLOR_YCBCR_BT2020) {
752                                 r2y_mode = VOP_R2Y_CSC_BT709;
753                                 win_csc = COLOR_YCBCR_BT2020;
754                         }
755
756                         if (win->colorspace == CSC_BT709 &&
757                             win_csc < COLOR_YCBCR_BT709) {
758                                 r2y_mode = VOP_R2Y_CSC_BT709;
759                                 win_csc = COLOR_YCBCR_BT709;
760                         }
761
762                         if (win->colorspace == CSC_BT601 &&
763                             win_csc < COLOR_YCBCR) {
764                                 r2y_mode = VOP_R2Y_CSC_BT709;
765                                 win_csc = COLOR_YCBCR;
766                         }
767                 }
768         }
769
770         if (win_csc == COLOR_RGB) {
771                 if (output_color == COLOR_YCBCR_BT709) {
772                         r2y_mode = VOP_R2Y_CSC_BT709;
773                         win_csc = COLOR_YCBCR_BT709;
774                 } else if (output_color == COLOR_YCBCR) {
775                         r2y_mode = VOP_R2Y_CSC_BT601;
776                         win_csc = COLOR_YCBCR;
777                 }
778         }
779
780         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
781                 win = dev_drv->win[i];
782                 if (!win->state)
783                         continue;
784
785                 if (win_csc != COLOR_RGB && !IS_YUV(win->area[0].fmt_cfg))
786                         vop_win_csc_mode(vop_dev, win, r2y_mode);
787
788                 if (IS_YUV(win->area[0].fmt_cfg)) {
789                         if (win_csc == COLOR_YCBCR)
790                                 vop_win_csc_mode(vop_dev, win,
791                                                  VOP_Y2R_CSC_MPEG);
792                         else if (win_csc == COLOR_YCBCR_BT709)
793                                 vop_win_csc_mode(vop_dev, win, VOP_Y2R_CSC_HD);
794                 }
795         }
796
797         return win_csc;
798 }
799
800 static int vop_post_csc_cfg(struct rk_lcdc_driver *dev_drv)
801 {
802         struct vop_device *vop_dev =
803             container_of(dev_drv, struct vop_device, driver);
804         int output_color = dev_drv->output_color;
805         int win_csc, overlay_mode;
806         u64 val;
807
808         if (VOP_CHIP(vop_dev) == VOP_RK322X) {
809                 win_csc = rk3228_vop_win_csc_cfg(dev_drv);
810         } else if (VOP_CHIP(vop_dev) == VOP_RK3399) {
811                 win_csc = rk3399_vop_win_csc_cfg(dev_drv);
812
813                 /*
814                  * RK3399 not support post csc config.
815                  */
816                 goto done;
817         }
818
819         val = V_YUV2YUV_POST_Y2R_EN(0) | V_YUV2YUV_POST_EN(0) |
820                 V_YUV2YUV_POST_R2Y_EN(0);
821         /* Y2R */
822         if (win_csc == COLOR_YCBCR && output_color == COLOR_YCBCR_BT2020) {
823                 val |= V_YUV2YUV_POST_Y2R_EN(1);
824                 vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE,
825                                    csc_y2r_bt709_full);
826         }
827         if (win_csc == COLOR_YCBCR_BT2020 &&
828             output_color != COLOR_YCBCR_BT2020) {
829                 val |= V_YUV2YUV_POST_Y2R_EN(1);
830                 vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE,
831                                    csc_y2r_bt2020);
832         }
833
834         /* R2R */
835         if ((win_csc == COLOR_YCBCR ||
836              win_csc == COLOR_YCBCR_BT709 ||
837              win_csc == COLOR_RGB) && output_color == COLOR_YCBCR_BT2020) {
838                 val |= V_YUV2YUV_POST_EN(1);
839                 vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE,
840                                    csc_r2r_bt709to2020);
841         }
842         if (win_csc == COLOR_YCBCR_BT2020 &&
843             (output_color == COLOR_YCBCR ||
844              output_color == COLOR_YCBCR_BT709 ||
845              output_color == COLOR_RGB)) {
846                 val |= V_YUV2YUV_POST_EN(1);
847                 vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE,
848                                    csc_r2r_bt2020to709);
849         }
850
851         /* Y2R */
852         if (output_color != COLOR_RGB) {
853                 val |= V_YUV2YUV_POST_R2Y_EN(1);
854
855                 if (output_color == COLOR_YCBCR_BT2020)
856                         vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE,
857                                            csc_r2y_bt2020);
858                 else
859                         vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE,
860                                            csc_r2y_bt709_full);
861         }
862
863         DBG(1, "win_csc=%d output_color=%d val=%llx\n",
864             win_csc, output_color, val);
865         vop_msk_reg(vop_dev, YUV2YUV_POST, val);
866 done:
867         overlay_mode = (win_csc != COLOR_RGB) ? VOP_YUV_DOMAIN : VOP_RGB_DOMAIN;
868         vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(overlay_mode));
869
870         return 0;
871 }
872
873 static int vop_post_cfg(struct rk_lcdc_driver *dev_drv)
874 {
875         struct vop_device *vop_dev =
876             container_of(dev_drv, struct vop_device, driver);
877         struct rk_screen *screen = dev_drv->cur_screen;
878         u16 x_res = screen->mode.xres;
879         u16 y_res = screen->mode.yres;
880         u64 val;
881         u16 h_total, v_total;
882         u16 post_hsd_en, post_vsd_en;
883         u16 post_dsp_hact_st, post_dsp_hact_end;
884         u16 post_dsp_vact_st, post_dsp_vact_end;
885         u16 post_dsp_vact_st_f1, post_dsp_vact_end_f1;
886         u16 post_h_fac, post_v_fac;
887
888         screen->post_dsp_stx = x_res * (100 - dev_drv->overscan.left) / 200;
889         screen->post_dsp_sty = y_res * (100 - dev_drv->overscan.top) / 200;
890         screen->post_xsize = x_res *
891             (dev_drv->overscan.left + dev_drv->overscan.right) / 200;
892         screen->post_ysize = y_res *
893             (dev_drv->overscan.top + dev_drv->overscan.bottom) / 200;
894
895         h_total = screen->mode.hsync_len + screen->mode.left_margin +
896             x_res + screen->mode.right_margin;
897         v_total = screen->mode.vsync_len + screen->mode.upper_margin +
898             y_res + screen->mode.lower_margin;
899
900         if (screen->post_dsp_stx + screen->post_xsize > x_res) {
901                 dev_warn(vop_dev->dev, "post:stx[%d]+xsize[%d]>x_res[%d]\n",
902                          screen->post_dsp_stx, screen->post_xsize, x_res);
903                 screen->post_dsp_stx = x_res - screen->post_xsize;
904         }
905         if (screen->x_mirror == 0) {
906                 post_dsp_hact_st = screen->post_dsp_stx +
907                     screen->mode.hsync_len + screen->mode.left_margin;
908                 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
909         } else {
910                 post_dsp_hact_end = h_total - screen->mode.right_margin -
911                     screen->post_dsp_stx;
912                 post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
913         }
914         if ((screen->post_xsize < x_res) && (screen->post_xsize != 0)) {
915                 post_hsd_en = 1;
916                 post_h_fac =
917                     GET_SCALE_FACTOR_BILI_DN(x_res, screen->post_xsize);
918         } else {
919                 post_hsd_en = 0;
920                 post_h_fac = 0x1000;
921         }
922
923         if (screen->post_dsp_sty + screen->post_ysize > y_res) {
924                 dev_warn(vop_dev->dev, "post:sty[%d]+ysize[%d]> y_res[%d]\n",
925                          screen->post_dsp_sty, screen->post_ysize, y_res);
926                 screen->post_dsp_sty = y_res - screen->post_ysize;
927         }
928
929         if ((screen->post_ysize < y_res) && (screen->post_ysize != 0)) {
930                 post_vsd_en = 1;
931                 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res,
932                                                       screen->post_ysize);
933         } else {
934                 post_vsd_en = 0;
935                 post_v_fac = 0x1000;
936         }
937
938         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
939                 post_dsp_vact_st = screen->post_dsp_sty / 2 +
940                                         screen->mode.vsync_len +
941                                         screen->mode.upper_margin;
942                 post_dsp_vact_end = post_dsp_vact_st +
943                                         screen->post_ysize / 2;
944
945                 post_dsp_vact_st_f1 = screen->mode.vsync_len +
946                                         screen->mode.upper_margin +
947                                         y_res / 2 +
948                                         screen->mode.lower_margin +
949                                         screen->mode.vsync_len +
950                                         screen->mode.upper_margin +
951                                         screen->post_dsp_sty / 2 +
952                                         1;
953                 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 +
954                                         screen->post_ysize / 2;
955         } else {
956                 if (screen->y_mirror == 0) {
957                         post_dsp_vact_st = screen->post_dsp_sty +
958                             screen->mode.vsync_len +
959                             screen->mode.upper_margin;
960                         post_dsp_vact_end = post_dsp_vact_st +
961                                 screen->post_ysize;
962                 } else {
963                         post_dsp_vact_end = v_total -
964                                 screen->mode.lower_margin -
965                             screen->post_dsp_sty;
966                         post_dsp_vact_st = post_dsp_vact_end -
967                                 screen->post_ysize;
968                 }
969                 post_dsp_vact_st_f1 = 0;
970                 post_dsp_vact_end_f1 = 0;
971         }
972         DBG(1, "post:xsize=%d,ysize=%d,xpos=%d",
973             screen->post_xsize, screen->post_ysize, screen->xpos);
974         DBG(1, ",ypos=%d,hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
975             screen->ypos, post_hsd_en, post_h_fac, post_vsd_en, post_v_fac);
976         val = V_DSP_HACT_END_POST(post_dsp_hact_end) |
977             V_DSP_HACT_ST_POST(post_dsp_hact_st);
978         vop_msk_reg(vop_dev, POST_DSP_HACT_INFO, val);
979
980         val = V_DSP_VACT_END_POST(post_dsp_vact_end) |
981             V_DSP_VACT_ST_POST(post_dsp_vact_st);
982         vop_msk_reg(vop_dev, POST_DSP_VACT_INFO, val);
983
984         val = V_POST_HS_FACTOR_YRGB(post_h_fac) |
985             V_POST_VS_FACTOR_YRGB(post_v_fac);
986         vop_msk_reg(vop_dev, POST_SCL_FACTOR_YRGB, val);
987         val = V_DSP_VACT_END_POST(post_dsp_vact_end_f1) |
988             V_DSP_VACT_ST_POST(post_dsp_vact_st_f1);
989         vop_msk_reg(vop_dev, POST_DSP_VACT_INFO_F1, val);
990         val = V_POST_HOR_SD_EN(post_hsd_en) | V_POST_VER_SD_EN(post_vsd_en);
991         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
992
993         vop_post_csc_cfg(dev_drv);
994
995         return 0;
996 }
997
998 static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
999 {
1000         struct vop_device *vop_dev =
1001             container_of(dev_drv, struct vop_device, driver);
1002         struct rk_lcdc_win *win;
1003         u32 colorkey_r, colorkey_g, colorkey_b;
1004         int i, key_val;
1005
1006         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1007                 win = dev_drv->win[i];
1008                 key_val = win->color_key_val;
1009                 colorkey_r = (key_val & 0xff) << 2;
1010                 colorkey_g = ((key_val >> 8) & 0xff) << 12;
1011                 colorkey_b = ((key_val >> 16) & 0xff) << 22;
1012                 /* color key dither 565/888->aaa */
1013                 key_val = colorkey_r | colorkey_g | colorkey_b;
1014                 switch (i) {
1015                 case 0:
1016                         vop_writel(vop_dev, WIN0_COLOR_KEY, key_val);
1017                         break;
1018                 case 1:
1019                         vop_writel(vop_dev, WIN1_COLOR_KEY, key_val);
1020                         break;
1021                 case 2:
1022                         vop_writel(vop_dev, WIN2_COLOR_KEY, key_val);
1023                         break;
1024                 case 3:
1025                         vop_writel(vop_dev, WIN3_COLOR_KEY, key_val);
1026                         break;
1027                 default:
1028                         pr_info("%s:un support win num:%d\n",
1029                                 __func__, i);
1030                         break;
1031                 }
1032         }
1033         return 0;
1034 }
1035
1036 static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
1037 {
1038         struct vop_device *vop_dev =
1039             container_of(dev_drv, struct vop_device, driver);
1040         struct rk_lcdc_win *win = dev_drv->win[win_id];
1041         struct alpha_config alpha_config;
1042         u64 val;
1043         int ppixel_alpha = 0, global_alpha = 0, i;
1044         u32 src_alpha_ctl, dst_alpha_ctl;
1045         int alpha_en = 1;
1046
1047         for (i = 0; i < win->area_num; i++) {
1048                 ppixel_alpha |= ((win->area[i].format == ARGB888) ||
1049                                  (win->area[i].format == FBDC_ARGB_888) ||
1050                                  (win->area[i].format == FBDC_ABGR_888) ||
1051                                  (win->area[i].format == ABGR888)) ? 1 : 0;
1052         }
1053
1054         global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
1055
1056         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1057                 if (!dev_drv->win[i]->state)
1058                         continue;
1059                 if (win->z_order > dev_drv->win[i]->z_order)
1060                         break;
1061         }
1062
1063         /*
1064          * The bottom layer not support ppixel_alpha mode.
1065          */
1066         if (i == dev_drv->lcdc_win_num)
1067                 ppixel_alpha = 0;
1068         alpha_config.src_global_alpha_val = win->g_alpha_val;
1069         win->alpha_mode = AB_SRC_OVER;
1070
1071         switch (win->alpha_mode) {
1072         case AB_USER_DEFINE:
1073                 break;
1074         case AB_CLEAR:
1075                 alpha_config.src_factor_mode = AA_ZERO;
1076                 alpha_config.dst_factor_mode = AA_ZERO;
1077                 break;
1078         case AB_SRC:
1079                 alpha_config.src_factor_mode = AA_ONE;
1080                 alpha_config.dst_factor_mode = AA_ZERO;
1081                 break;
1082         case AB_DST:
1083                 alpha_config.src_factor_mode = AA_ZERO;
1084                 alpha_config.dst_factor_mode = AA_ONE;
1085                 break;
1086         case AB_SRC_OVER:
1087                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1088                 if (global_alpha)
1089                         alpha_config.src_factor_mode = AA_SRC_GLOBAL;
1090                 else
1091                         alpha_config.src_factor_mode = AA_ONE;
1092                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1093                 break;
1094         case AB_DST_OVER:
1095                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1096                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1097                 alpha_config.dst_factor_mode = AA_ONE;
1098                 break;
1099         case AB_SRC_IN:
1100                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1101                 alpha_config.src_factor_mode = AA_SRC;
1102                 alpha_config.dst_factor_mode = AA_ZERO;
1103                 break;
1104         case AB_DST_IN:
1105                 alpha_config.src_factor_mode = AA_ZERO;
1106                 alpha_config.dst_factor_mode = AA_SRC;
1107                 break;
1108         case AB_SRC_OUT:
1109                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1110                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1111                 alpha_config.dst_factor_mode = AA_ZERO;
1112                 break;
1113         case AB_DST_OUT:
1114                 alpha_config.src_factor_mode = AA_ZERO;
1115                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1116                 break;
1117         case AB_SRC_ATOP:
1118                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1119                 alpha_config.src_factor_mode = AA_SRC;
1120                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1121                 break;
1122         case AB_DST_ATOP:
1123                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1124                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1125                 alpha_config.dst_factor_mode = AA_SRC;
1126                 break;
1127         case XOR:
1128                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1129                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1130                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1131                 break;
1132         case AB_SRC_OVER_GLOBAL:
1133                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
1134                 alpha_config.src_color_mode = AA_SRC_NO_PRE_MUL;
1135                 alpha_config.src_factor_mode = AA_SRC_GLOBAL;
1136                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1137                 break;
1138         default:
1139                 pr_err("alpha mode error\n");
1140                 break;
1141         }
1142         if ((ppixel_alpha == 1) && (global_alpha == 1))
1143                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
1144         else if (ppixel_alpha == 1)
1145                 alpha_config.src_global_alpha_mode = AA_PER_PIX;
1146         else if (global_alpha == 1)
1147                 alpha_config.src_global_alpha_mode = AA_GLOBAL;
1148         else
1149                 alpha_en = 0;
1150         alpha_config.src_alpha_mode = AA_STRAIGHT;
1151         alpha_config.src_alpha_cal_m0 = AA_NO_SAT;
1152
1153         switch (win_id) {
1154         case 0:
1155                 src_alpha_ctl = 0x60;
1156                 dst_alpha_ctl = 0x64;
1157                 break;
1158         case 1:
1159                 src_alpha_ctl = 0xa0;
1160                 dst_alpha_ctl = 0xa4;
1161                 break;
1162         case 2:
1163                 src_alpha_ctl = 0xdc;
1164                 dst_alpha_ctl = 0xec;
1165                 break;
1166         case 3:
1167                 src_alpha_ctl = 0x12c;
1168                 dst_alpha_ctl = 0x13c;
1169                 break;
1170         case 4:
1171                 src_alpha_ctl = 0x160;
1172                 dst_alpha_ctl = 0x164;
1173                 break;
1174         }
1175         val = V_WIN0_DST_FACTOR_MODE(alpha_config.dst_factor_mode);
1176         vop_msk_reg(vop_dev, dst_alpha_ctl, val);
1177         val = V_WIN0_SRC_ALPHA_EN(alpha_en) |
1178             V_WIN0_SRC_COLOR_MODE(alpha_config.src_color_mode) |
1179             V_WIN0_SRC_ALPHA_MODE(alpha_config.src_alpha_mode) |
1180             V_WIN0_SRC_BLEND_MODE(alpha_config.src_global_alpha_mode) |
1181             V_WIN0_SRC_ALPHA_CAL_MODE(alpha_config.src_alpha_cal_m0) |
1182             V_WIN0_SRC_FACTOR_MODE(alpha_config.src_factor_mode) |
1183             V_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
1184
1185         vop_msk_reg(vop_dev, src_alpha_ctl, val);
1186
1187         return 0;
1188 }
1189
1190 static int vop_axi_gather_cfg(struct vop_device *vop_dev,
1191                               struct rk_lcdc_win *win)
1192 {
1193         u64 val;
1194         u16 yrgb_gather_num = 3;
1195         u16 cbcr_gather_num = 1;
1196
1197         switch (win->area[0].format) {
1198         case ARGB888:
1199         case XBGR888:
1200         case ABGR888:
1201         case FBDC_ARGB_888:
1202         case FBDC_RGBX_888:
1203         case FBDC_ABGR_888:
1204                 yrgb_gather_num = 3;
1205                 break;
1206         case RGB888:
1207         case RGB565:
1208         case FBDC_RGB_565:
1209                 yrgb_gather_num = 2;
1210                 break;
1211         case YUV444:
1212         case YUV422:
1213         case YUV420:
1214         case YUV420_A:
1215         case YUV422_A:
1216         case YUV444_A:
1217         case YUV420_NV21:
1218         case YUYV420:
1219         case UYVY420:
1220                 yrgb_gather_num = 1;
1221                 cbcr_gather_num = 2;
1222                 break;
1223         case YUYV422:
1224         case UYVY422:
1225                 yrgb_gather_num = 2;
1226                 cbcr_gather_num = 2;
1227                 break;
1228         default:
1229                 dev_err(vop_dev->driver.dev, "%s:un supported format[%d]\n",
1230                         __func__, win->area[0].format);
1231                 return -EINVAL;
1232         }
1233
1234         if ((win->id == VOP_WIN0) || (win->id == VOP_WIN1)) {
1235                 val = V_WIN0_YRGB_AXI_GATHER_EN(1) |
1236                         V_WIN0_CBR_AXI_GATHER_EN(1) |
1237                         V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) |
1238                         V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num);
1239                 vop_msk_reg(vop_dev, WIN0_CTRL1 + (win->id * 0x40), val);
1240         } else if ((win->id == VOP_WIN2) || (win->id == VOP_WIN3)) {
1241                 val = V_WIN2_AXI_GATHER_EN(1) |
1242                         V_WIN2_AXI_GATHER_NUM(yrgb_gather_num);
1243                 vop_msk_reg(vop_dev, WIN2_CTRL1 + ((win->id - 2) * 0x50), val);
1244         } else if (win->id == VOP_HWC) {
1245                 val = V_HWC_AXI_GATHER_EN(1) |
1246                         V_HWC_AXI_GATHER_NUM(yrgb_gather_num);
1247                 vop_msk_reg(vop_dev, HWC_CTRL1, val);
1248         }
1249         return 0;
1250 }
1251
1252 static int vop_fbdc_reg_update(struct vop_device *vop_dev, int win_id)
1253 {
1254         struct rk_lcdc_win *win = vop_dev->driver.win[win_id];
1255         u32 val;
1256
1257         val = V_VOP_FBDC_WIN_SEL(win_id) |
1258                 V_AFBCD_HREG_PIXEL_PACKING_FMT(win->area[0].fbdc_fmt_cfg) |
1259                 V_AFBCD_HREG_BLOCK_SPLIT(win->area[0].fbdc_cor_en);
1260         vop_msk_reg(vop_dev, AFBCD0_CTRL, val);
1261
1262         val = V_AFBCD_HREG_PIC_WIDTH(win->area[0].fbdc_mb_width - 1) |
1263                 V_AFBCD_HREG_PIC_HEIGHT(win->area[0].fbdc_mb_height - 1);
1264         vop_msk_reg(vop_dev, AFBCD0_PIC_SIZE, val);
1265
1266         return 0;
1267 }
1268
1269 static int vop_init_fbdc_config(struct vop_device *vop_dev, int win_id)
1270 {
1271         struct rk_lcdc_driver *vop_drv = &vop_dev->driver;
1272         struct rk_lcdc_win *win = vop_drv->win[win_id];
1273         struct rk_screen *screen = vop_drv->cur_screen;
1274
1275         if (screen->mode.flag & FB_VMODE_INTERLACED) {
1276                 dev_err(vop_dev->dev, "unsupport fbdc+interlace!\n");
1277                 return 0;
1278         }
1279
1280         if (VOP_CHIP(vop_dev) != VOP_RK3399) {
1281                 pr_err("soc: 0x%08x not support FBDC\n", VOP_CHIP(vop_dev));
1282                 return 0;
1283         }
1284
1285         win->area[0].fbdc_mb_width = win->area[0].xact;
1286         win->area[0].fbdc_mb_height = win->area[0].yact;
1287         win->area[0].fbdc_cor_en = 0; /* hreg_block_split */
1288         win->area[0].fbdc_fmt_cfg |= 0 << 4;
1289
1290         return 0;
1291 }
1292
1293 static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1294 {
1295         struct vop_device *vop_dev =
1296             container_of(dev_drv, struct vop_device, driver);
1297         struct rk_lcdc_win *win = dev_drv->win[win_id];
1298         u64 val;
1299         u32 off;
1300         int format;
1301
1302         off = win_id * 0x40;
1303
1304         if (win->state == 1) {
1305                 vop_axi_gather_cfg(vop_dev, win);
1306                 if (win->area[0].fbdc_en)
1307                         vop_fbdc_reg_update(vop_dev, win_id);
1308                 /*
1309                  * rk322x have a bug on windows 0 and 1:
1310                  *
1311                  * When switch win format from RGB to YUV, would flash
1312                  * some green lines on the top of the windows.
1313                  *
1314                  * Use bg_en show one blank frame to skip the error frame.
1315                  */
1316                 if (IS_YUV(win->area[0].fmt_cfg)) {
1317                         val = vop_readl(vop_dev, WIN0_CTRL0);
1318                         format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1319
1320                         if (!IS_YUV(format)) {
1321                                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1322                                         val = V_WIN0_DSP_BG_RED(0x200) |
1323                                                 V_WIN0_DSP_BG_GREEN(0x40) |
1324                                                 V_WIN0_DSP_BG_BLUE(0x200) |
1325                                                 V_WIN0_BG_EN(1);
1326                                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off,
1327                                                     val);
1328                                 } else {
1329                                         val = V_WIN0_DSP_BG_RED(0) |
1330                                                 V_WIN0_DSP_BG_GREEN(0) |
1331                                                 V_WIN0_DSP_BG_BLUE(0) |
1332                                                 V_WIN0_BG_EN(1);
1333                                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off,
1334                                                     val);
1335                                 }
1336                         } else {
1337                                 val = V_WIN0_BG_EN(0);
1338                                 vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val);
1339                         }
1340                 } else {
1341                         val = V_WIN0_BG_EN(0);
1342                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val);
1343                 }
1344
1345                 val = V_WIN0_EN(win->state) |
1346                         V_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
1347                         V_WIN0_FMT_10(win->fmt_10) |
1348                         V_WIN0_LB_MODE(win->win_lb_mode) |
1349                         V_WIN0_RB_SWAP(win->area[0].swap_rb) |
1350                         V_WIN0_X_MIR_EN(win->xmirror) |
1351                         V_WIN0_Y_MIR_EN(win->ymirror) |
1352                         V_WIN0_UV_SWAP(win->area[0].swap_uv);
1353                 if (VOP_CHIP(vop_dev) == VOP_RK3399)
1354                         val |= V_WIN0_YUYV(win->area[0].yuyv_fmt);
1355                 vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
1356                 val = V_WIN0_BIC_COE_SEL(win->bic_coe_el) |
1357                     V_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
1358                     V_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
1359                     V_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
1360                     V_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
1361                     V_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
1362                     V_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
1363                     V_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
1364                     V_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
1365                     V_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
1366                     V_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
1367                     V_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
1368                     V_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
1369                     V_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
1370                     V_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
1371                 vop_msk_reg(vop_dev, WIN0_CTRL1 + off, val);
1372                 val = V_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
1373                     V_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
1374                 vop_writel(vop_dev, WIN0_VIR + off, val);
1375                 val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) |
1376                     V_WIN0_ACT_HEIGHT(win->area[0].yact - 1);
1377                 vop_writel(vop_dev, WIN0_ACT_INFO + off, val);
1378
1379                 val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) |
1380                     V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1);
1381                 vop_writel(vop_dev, WIN0_DSP_INFO + off, val);
1382
1383                 val = V_WIN0_DSP_XST(win->area[0].dsp_stx) |
1384                     V_WIN0_DSP_YST(win->area[0].dsp_sty);
1385                 vop_writel(vop_dev, WIN0_DSP_ST + off, val);
1386
1387                 val = V_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
1388                     V_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
1389                 vop_writel(vop_dev, WIN0_SCL_FACTOR_YRGB + off, val);
1390
1391                 val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
1392                     V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
1393                 vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR + off, val);
1394                 if (win->alpha_en == 1) {
1395                         vop_alpha_cfg(dev_drv, win_id);
1396                 } else {
1397                         val = V_WIN0_SRC_ALPHA_EN(0);
1398                         vop_msk_reg(vop_dev, WIN0_SRC_ALPHA_CTRL + off, val);
1399                 }
1400
1401         } else {
1402                 val = V_WIN0_EN(win->state);
1403                 vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
1404         }
1405
1406         return 0;
1407 }
1408
1409 static int area_xst(struct rk_lcdc_win *win, int area_num)
1410 {
1411         struct rk_lcdc_win_area area_temp;
1412         int i, j;
1413
1414         for (i = 0; i < area_num; i++) {
1415                 for (j = i + 1; j < area_num; j++) {
1416                         if (win->area[i].dsp_stx >  win->area[j].dsp_stx) {
1417                                 memcpy(&area_temp, &win->area[i],
1418                                        sizeof(struct rk_lcdc_win_area));
1419                                 memcpy(&win->area[i], &win->area[j],
1420                                        sizeof(struct rk_lcdc_win_area));
1421                                 memcpy(&win->area[j], &area_temp,
1422                                        sizeof(struct rk_lcdc_win_area));
1423                         }
1424                 }
1425         }
1426
1427         return 0;
1428 }
1429
1430 static int vop_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1431 {
1432         struct vop_device *vop_dev =
1433                         container_of(dev_drv, struct vop_device, driver);
1434         struct rk_lcdc_win *win = dev_drv->win[win_id];
1435         unsigned int off;
1436         u64 val;
1437
1438         off = (win_id - 2) * 0x50;
1439         area_xst(win, win->area_num);
1440
1441         if (win->state == 1) {
1442                 vop_axi_gather_cfg(vop_dev, win);
1443                 if (win->area[0].fbdc_en)
1444                         vop_fbdc_reg_update(vop_dev, win_id);
1445                 val = V_WIN2_EN(1) | V_WIN1_CSC_MODE(win->csc_mode);
1446                 vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1447                 /* area 0 */
1448                 if (win->area[0].state == 1) {
1449                         val = V_WIN2_MST0_EN(win->area[0].state) |
1450                             V_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
1451                             V_WIN2_RB_SWAP0(win->area[0].swap_rb);
1452                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1453
1454                         val = V_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
1455                         vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
1456
1457                         val = V_WIN2_DSP_WIDTH0(win->area[0].xsize) |
1458                             V_WIN2_DSP_HEIGHT0(win->area[0].ysize);
1459                         vop_writel(vop_dev, WIN2_DSP_INFO0 + off, val);
1460                         val = V_WIN2_DSP_XST0(win->area[0].dsp_stx) |
1461                             V_WIN2_DSP_YST0(win->area[0].dsp_sty);
1462                         vop_writel(vop_dev, WIN2_DSP_ST0 + off, val);
1463                 } else {
1464                         val = V_WIN2_MST0_EN(0);
1465                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1466                 }
1467                 /* area 1 */
1468                 if (win->area[1].state == 1) {
1469                         val = V_WIN2_MST1_EN(win->area[1].state) |
1470                             V_WIN2_DATA_FMT1(win->area[1].fmt_cfg) |
1471                             V_WIN2_RB_SWAP1(win->area[1].swap_rb);
1472                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1473
1474                         val = V_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
1475                         vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
1476
1477                         val = V_WIN2_DSP_WIDTH1(win->area[1].xsize) |
1478                             V_WIN2_DSP_HEIGHT1(win->area[1].ysize);
1479                         vop_writel(vop_dev, WIN2_DSP_INFO1 + off, val);
1480                         val = V_WIN2_DSP_XST1(win->area[1].dsp_stx) |
1481                             V_WIN2_DSP_YST1(win->area[1].dsp_sty);
1482                         vop_writel(vop_dev, WIN2_DSP_ST1 + off, val);
1483                 } else {
1484                         val = V_WIN2_MST1_EN(0);
1485                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1486                 }
1487                 /* area 2 */
1488                 if (win->area[2].state == 1) {
1489                         val = V_WIN2_MST2_EN(win->area[2].state) |
1490                             V_WIN2_DATA_FMT2(win->area[2].fmt_cfg) |
1491                             V_WIN2_RB_SWAP2(win->area[2].swap_rb);
1492                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1493
1494                         val = V_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
1495                         vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
1496
1497                         val = V_WIN2_DSP_WIDTH2(win->area[2].xsize) |
1498                             V_WIN2_DSP_HEIGHT2(win->area[2].ysize);
1499                         vop_writel(vop_dev, WIN2_DSP_INFO2 + off, val);
1500                         val = V_WIN2_DSP_XST2(win->area[2].dsp_stx) |
1501                             V_WIN2_DSP_YST2(win->area[2].dsp_sty);
1502                         vop_writel(vop_dev, WIN2_DSP_ST2 + off, val);
1503                 } else {
1504                         val = V_WIN2_MST2_EN(0);
1505                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1506                 }
1507                 /* area 3 */
1508                 if (win->area[3].state == 1) {
1509                         val = V_WIN2_MST3_EN(win->area[3].state) |
1510                             V_WIN2_DATA_FMT3(win->area[3].fmt_cfg) |
1511                             V_WIN2_RB_SWAP3(win->area[3].swap_rb);
1512                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1513
1514                         val = V_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
1515                         vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
1516
1517                         val = V_WIN2_DSP_WIDTH3(win->area[3].xsize) |
1518                             V_WIN2_DSP_HEIGHT3(win->area[3].ysize);
1519                         vop_writel(vop_dev, WIN2_DSP_INFO3 + off, val);
1520                         val = V_WIN2_DSP_XST3(win->area[3].dsp_stx) |
1521                             V_WIN2_DSP_YST3(win->area[3].dsp_sty);
1522                         vop_writel(vop_dev, WIN2_DSP_ST3 + off, val);
1523                 } else {
1524                         val = V_WIN2_MST3_EN(0);
1525                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1526                 }
1527
1528                 if (win->alpha_en == 1) {
1529                         vop_alpha_cfg(dev_drv, win_id);
1530                 } else {
1531                         val = V_WIN2_SRC_ALPHA_EN(0);
1532                         vop_msk_reg(vop_dev, WIN2_SRC_ALPHA_CTRL + off, val);
1533                 }
1534         } else {
1535                 val = V_WIN2_EN(win->state) | V_WIN2_MST0_EN(0) |
1536                     V_WIN2_MST1_EN(0) | V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
1537                 vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1538         }
1539
1540         return 0;
1541 }
1542
1543 static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1544 {
1545         struct vop_device *vop_dev =
1546             container_of(dev_drv, struct vop_device, driver);
1547         struct rk_lcdc_win *win = dev_drv->win[win_id];
1548         unsigned int hwc_size = 0;
1549         u64 val;
1550
1551         if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32)) {
1552                 hwc_size = 0;
1553         } else if ((win->area[0].xsize == 64) && (win->area[0].ysize == 64)) {
1554                 hwc_size = 1;
1555         } else if ((win->area[0].xsize == 96) && (win->area[0].ysize == 96)) {
1556                 hwc_size = 2;
1557         } else if ((win->area[0].xsize == 128) &&
1558                    (win->area[0].ysize == 128)) {
1559                 hwc_size = 3;
1560         } else {
1561                 dev_err(vop_dev->dev, "un supported hwc size[%dx%d]!\n",
1562                                 win->area[0].xsize, win->area[0].ysize);
1563                 return -EINVAL;
1564         }
1565
1566         if (win->state == 1) {
1567                 vop_axi_gather_cfg(vop_dev, win);
1568                 val = V_HWC_EN(1) | V_HWC_DATA_FMT(win->area[0].fmt_cfg) |
1569                     V_HWC_RB_SWAP(win->area[0].swap_rb);
1570                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1571
1572                 val = V_HWC_SIZE(hwc_size);
1573                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1574
1575                 val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
1576                     V_HWC_DSP_YST(win->area[0].dsp_sty);
1577                 vop_msk_reg(vop_dev, HWC_DSP_ST, val);
1578
1579                 if (win->alpha_en == 1) {
1580                         vop_alpha_cfg(dev_drv, win_id);
1581                 } else {
1582                         val = V_WIN2_SRC_ALPHA_EN(0);
1583                         vop_msk_reg(vop_dev, HWC_SRC_ALPHA_CTRL, val);
1584                 }
1585         } else {
1586                 val = V_HWC_EN(win->state);
1587                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1588         }
1589
1590         return 0;
1591 }
1592
1593 static int vop_layer_update_regs(struct vop_device *vop_dev,
1594                                  struct rk_lcdc_win *win)
1595 {
1596         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
1597
1598         if (likely(vop_dev->clk_on)) {
1599                 vop_msk_reg(vop_dev, SYS_CTRL,
1600                             V_VOP_STANDBY_EN(vop_dev->standby));
1601                 if ((win->id == VOP_WIN0) || (win->id == VOP_WIN1))
1602                         vop_win_0_1_reg_update(dev_drv, win->id);
1603                 else if ((win->id == VOP_WIN2) || (win->id == VOP_WIN3))
1604                         vop_win_2_3_reg_update(dev_drv, win->id);
1605                 else if (win->id == VOP_HWC)
1606                         vop_hwc_reg_update(dev_drv, win->id);
1607                 vop_cfg_done(vop_dev);
1608         }
1609
1610         DBG(2, "%s for lcdc%d\n", __func__, vop_dev->id);
1611         return 0;
1612 }
1613
1614 static int __maybe_unused vop_mmu_en(struct rk_lcdc_driver *dev_drv)
1615 {
1616         u64 val;
1617         struct vop_device *vop_dev =
1618             container_of(dev_drv, struct vop_device, driver);
1619
1620         if (unlikely(!vop_dev->clk_on)) {
1621                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
1622                 return 0;
1623         }
1624         if (dev_drv->iommu_enabled) {
1625                 if (!vop_dev->iommu_status && dev_drv->mmu_dev) {
1626                         if (likely(vop_dev->clk_on)) {
1627                                 val = V_VOP_MMU_EN(1);
1628                                 vop_msk_reg(vop_dev, SYS_CTRL, val);
1629                                 val = V_AXI_OUTSTANDING_MAX_NUM(31) |
1630                                         V_AXI_MAX_OUTSTANDING_EN(1);
1631                                 vop_msk_reg(vop_dev, SYS_CTRL1, val);
1632                         }
1633                         vop_dev->iommu_status = 1;
1634                         rockchip_iovmm_activate(dev_drv->dev);
1635                 }
1636         }
1637         return 0;
1638 }
1639
1640 static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
1641 {
1642         int ret = 0, fps = 0;
1643         struct vop_device *vop_dev =
1644             container_of(dev_drv, struct vop_device, driver);
1645         struct rk_screen *screen = dev_drv->cur_screen;
1646 #ifdef CONFIG_RK_FPGA
1647         return 0;
1648 #endif
1649         if (reset_rate)
1650                 ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock);
1651         if (ret)
1652                 dev_err(dev_drv->dev, "set lcdc%d dclk[%d] failed\n",
1653                         vop_dev->id, screen->mode.pixclock);
1654         vop_dev->pixclock =
1655             div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
1656         vop_dev->driver.pixclock = vop_dev->pixclock;
1657
1658         fps = rk_fb_calc_fps(screen, vop_dev->pixclock);
1659         screen->ft = 1000 / fps;
1660         dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ",
1661                  vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps);
1662         return 0;
1663 }
1664
1665 static int vop_config_timing(struct rk_lcdc_driver *dev_drv)
1666 {
1667         struct vop_device *vop_dev =
1668             container_of(dev_drv, struct vop_device, driver);
1669         struct rk_screen *screen = dev_drv->cur_screen;
1670         u16 hsync_len = screen->mode.hsync_len;
1671         u16 left_margin = screen->mode.left_margin;
1672         u16 right_margin = screen->mode.right_margin;
1673         u16 vsync_len = screen->mode.vsync_len;
1674         u16 upper_margin = screen->mode.upper_margin;
1675         u16 lower_margin = screen->mode.lower_margin;
1676         u16 x_res = screen->mode.xres;
1677         u16 y_res = screen->mode.yres;
1678         u64 val;
1679         u16 h_total, v_total;
1680         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
1681
1682         h_total = hsync_len + left_margin + x_res + right_margin;
1683         v_total = vsync_len + upper_margin + y_res + lower_margin;
1684
1685         val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total);
1686         vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val);
1687
1688         val = V_DSP_HACT_END(hsync_len + left_margin + x_res) |
1689             V_DSP_HACT_ST(hsync_len + left_margin);
1690         vop_msk_reg(vop_dev, DSP_HACT_ST_END, val);
1691
1692         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1693                 /* First Field Timing */
1694                 val = V_DSP_VS_END(vsync_len) |
1695                     V_DSP_VTOTAL(2 * (vsync_len + upper_margin +
1696                                       lower_margin) + y_res + 1);
1697                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
1698
1699                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
1700                     V_DSP_VACT_ST(vsync_len + upper_margin);
1701                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
1702
1703                 /* Second Field Timing */
1704                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
1705                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
1706                     lower_margin;
1707                 val = V_DSP_VS_ST_F1(vs_st_f1) | V_DSP_VS_END_F1(vs_end_f1);
1708                 vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val);
1709
1710                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
1711                     lower_margin + 1;
1712                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
1713                     lower_margin + 1;
1714                 val = V_DSP_VACT_END_F1(vact_end_f1) |
1715                         V_DSP_VACT_ST_F1(vact_st_f1);
1716                 vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val);
1717                 vop_msk_reg(vop_dev, DSP_CTRL0,
1718                             V_DSP_INTERLACE(1) | V_DSP_FIELD_POL(0));
1719
1720                 val = V_DSP_LINE_FLAG_NUM_0(lower_margin ?
1721                                             vact_end_f1 : vact_end_f1 - 1);
1722
1723                 val |= V_DSP_LINE_FLAG_NUM_1(lower_margin ?
1724                                              vact_end_f1 : vact_end_f1 - 1);
1725                 vop_msk_reg(vop_dev, LINE_FLAG, val);
1726         } else {
1727                 val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total);
1728                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
1729
1730                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) |
1731                     V_DSP_VACT_ST(vsync_len + upper_margin);
1732                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
1733
1734                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_INTERLACE(0) |
1735                             V_DSP_FIELD_POL(0));
1736
1737                 val = V_DSP_LINE_FLAG_NUM_0(vsync_len + upper_margin + y_res) |
1738                         V_DSP_LINE_FLAG_NUM_1(vsync_len + upper_margin + y_res);
1739                 vop_msk_reg(vop_dev, LINE_FLAG, val);
1740         }
1741         vop_post_cfg(dev_drv);
1742
1743         return 0;
1744 }
1745
1746 static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1747 {
1748         struct vop_device *vop_dev =
1749             container_of(dev_drv, struct vop_device, driver);
1750         u32 bcsh_ctrl;
1751
1752         vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(dev_drv->overlay_mode));
1753         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1754                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1755                         vop_msk_reg(vop_dev, BCSH_CTRL,
1756                                     V_BCSH_Y2R_EN(0) | V_BCSH_R2Y_EN(0));
1757                 else            /* YUV2RGB */
1758                         vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_Y2R_EN(1) |
1759                                     V_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1760                                     V_BCSH_R2Y_EN(0));
1761         } else {
1762                 /* overlay_mode=VOP_RGB_DOMAIN */
1763                 /* bypass  --need check,if bcsh close? */
1764                 if (dev_drv->output_color == COLOR_RGB) {
1765                         bcsh_ctrl = vop_readl(vop_dev, BCSH_CTRL);
1766                         if (((bcsh_ctrl & MASK(BCSH_EN)) == 1) ||
1767                             (dev_drv->bcsh.enable == 1))/*bcsh enabled */
1768                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1769                                             V_BCSH_R2Y_EN(1) |
1770                                             V_BCSH_Y2R_EN(1));
1771                         else
1772                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1773                                             V_BCSH_R2Y_EN(0) |
1774                                             V_BCSH_Y2R_EN(0));
1775                 } else {
1776                         /* RGB2YUV */
1777                         vop_msk_reg(vop_dev, BCSH_CTRL,
1778                                     V_BCSH_R2Y_EN(1) |
1779                                     V_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1780                                     V_BCSH_Y2R_EN(0));
1781                 }
1782         }
1783 }
1784
1785 static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1786                                u16 *yact, int *format, u32 *dsp_addr,
1787                                int *ymirror)
1788 {
1789         struct vop_device *vop_dev =
1790                         container_of(dev_drv, struct vop_device, driver);
1791         u32 val;
1792
1793         spin_lock(&vop_dev->reg_lock);
1794
1795         val = vop_readl(vop_dev, WIN0_ACT_INFO);
1796         *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
1797         *yact = ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1798
1799         val = vop_readl(vop_dev, WIN0_CTRL0);
1800         *format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1801         *ymirror = (val & MASK(WIN0_Y_MIR_EN)) >> 22;
1802         *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST);
1803
1804         spin_unlock(&vop_dev->reg_lock);
1805
1806         return 0;
1807 }
1808
1809 static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1810                            int format, u16 xact, u16 yact, u16 xvir,
1811                            int ymirror)
1812 {
1813         struct vop_device *vop_dev =
1814                         container_of(dev_drv, struct vop_device, driver);
1815         int swap = (format == RGB888) ? 1 : 0;
1816         struct rk_lcdc_win *win = dev_drv->win[0];
1817         u64 val;
1818
1819         val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap) |
1820                 V_WIN0_Y_MIR_EN(ymirror);
1821         vop_msk_reg(vop_dev, WIN0_CTRL0, val);
1822
1823         vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_VIR_STRIDE(xvir));
1824         vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) |
1825                    V_WIN0_ACT_HEIGHT(yact - 1));
1826
1827         vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst);
1828
1829         vop_cfg_done(vop_dev);
1830
1831         if (format == RGB888)
1832                 win->area[0].format = BGR888;
1833         else
1834                 win->area[0].format = format;
1835
1836         win->ymirror = ymirror;
1837         win->state = 1;
1838         win->last_state = 1;
1839
1840         return 0;
1841 }
1842
1843 static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1844 {
1845         u16 face = 0;
1846         u16 dclk_ddr = 0;
1847         struct vop_device *vop_dev =
1848             container_of(dev_drv, struct vop_device, driver);
1849         struct rk_screen *screen = dev_drv->cur_screen;
1850         u64 val;
1851
1852         if (unlikely(!vop_dev->clk_on)) {
1853                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
1854                 return 0;
1855         }
1856
1857         if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1))
1858                 flush_kthread_worker(&dev_drv->update_regs_worker);
1859
1860         spin_lock(&vop_dev->reg_lock);
1861         if (likely(vop_dev->clk_on)) {
1862                 switch (screen->face) {
1863                 case OUT_P565:
1864                         face = OUT_P565;
1865                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1866                                 V_PRE_DITHER_DOWN_EN(1) |
1867                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(0);
1868                         break;
1869                 case OUT_P666:
1870                         face = OUT_P666;
1871                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1872                                 V_PRE_DITHER_DOWN_EN(1) |
1873                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(1);
1874                         break;
1875                 case OUT_D888_P565:
1876                         face = OUT_P888;
1877                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1878                                 V_PRE_DITHER_DOWN_EN(1) |
1879                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(0);
1880                         break;
1881                 case OUT_D888_P666:
1882                         face = OUT_P888;
1883                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1884                                 V_PRE_DITHER_DOWN_EN(1) |
1885                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(1);
1886                         break;
1887                 case OUT_P888:
1888                         face = OUT_P888;
1889                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1)
1890                                 | V_PRE_DITHER_DOWN_EN(1) |
1891                                 V_DITHER_DOWN_SEL(0) | V_DITHER_DOWN_MODE(0);
1892                         break;
1893                 case OUT_YUV_420:
1894                         face = OUT_YUV_420;
1895                         dclk_ddr = 1;
1896                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1897                                 V_PRE_DITHER_DOWN_EN(1) |
1898                                 V_DITHER_DOWN_SEL(0) |
1899                                 V_DITHER_DOWN_MODE(0);
1900                         break;
1901                 case OUT_YUV_420_10BIT:
1902                         face = OUT_YUV_420;
1903                         dclk_ddr = 1;
1904                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1905                                 V_PRE_DITHER_DOWN_EN(0) |
1906                                 V_DITHER_DOWN_SEL(0) |
1907                                 V_DITHER_DOWN_MODE(0);
1908                         break;
1909                 case OUT_P101010:
1910                         face = OUT_P101010;
1911                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1912                                 V_PRE_DITHER_DOWN_EN(0) |
1913                                 V_DITHER_DOWN_SEL(0) |
1914                                 V_DITHER_DOWN_MODE(0);
1915                         break;
1916                 default:
1917                         dev_err(vop_dev->dev, "un supported screen face[%d]!\n",
1918                                 screen->face);
1919                         break;
1920                 }
1921
1922                 vop_msk_reg(vop_dev, DSP_CTRL1, val);
1923                 switch (screen->type) {
1924                 case SCREEN_TVOUT:
1925                         val = V_SW_UV_OFFSET_EN(1) | V_SW_IMD_TVE_DCLK_EN(1) |
1926                                 V_SW_IMD_TVE_DCLK_EN(1) |
1927                                 V_SW_IMD_TVE_DCLK_POL(1) |
1928                                 V_SW_GENLOCK(1) | V_SW_DAC_SEL(1);
1929                         if (screen->mode.xres == 720 &&
1930                             screen->mode.yres == 576)
1931                                 val |= V_SW_TVE_MODE(1);
1932                         else
1933                                 val |= V_SW_TVE_MODE(0);
1934                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1935                         break;
1936                 case SCREEN_HDMI:
1937                         if ((screen->face == OUT_P888) ||
1938                             (screen->face == OUT_P101010))
1939                                 face = OUT_P101010; /*RGB 101010 output*/
1940                         val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0);
1941                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1942                         break;
1943                 case SCREEN_RGB:
1944                 case SCREEN_LVDS:
1945                         val = V_RGB_OUT_EN(1);
1946                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1947                 case SCREEN_MIPI:
1948                         val = V_MIPI_OUT_EN(1);
1949                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1950                 case SCREEN_EDP:
1951                         val = V_EDP_OUT_EN(1);
1952                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1953                         break;
1954                 default:
1955                         dev_err(vop_dev->dev, "un supported interface[%d]!\n",
1956                                 screen->type);
1957                         break;
1958                 }
1959                 val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
1960                         V_HDMI_VSYNC_POL(screen->pin_vsync) |
1961                         V_HDMI_DEN_POL(screen->pin_den) |
1962                         V_HDMI_DCLK_POL(screen->pin_dclk);
1963                 /*hsync vsync den dclk polo,dither */
1964                 vop_msk_reg(vop_dev, DSP_CTRL1, val);
1965
1966                 if (screen->color_mode == COLOR_RGB)
1967                         dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1968                 else
1969                         dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1970
1971 #ifndef CONFIG_RK_FPGA
1972                 /*
1973                  * Todo:
1974                  * writel_relaxed(v, RK_GRF_VIRT + vop_GRF_SOC_CON7);
1975                  *  move to  lvds driver
1976                  */
1977                 /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
1978 #endif
1979                 val = V_DSP_OUT_MODE(face) | V_DSP_DCLK_DDR(dclk_ddr) |
1980                     V_DSP_BG_SWAP(screen->swap_gb) |
1981                     V_DSP_RB_SWAP(screen->swap_rb) |
1982                     V_DSP_RG_SWAP(screen->swap_rg) |
1983                     V_DSP_DELTA_SWAP(screen->swap_delta) |
1984                     V_DSP_DUMMY_SWAP(screen->swap_dumy) | V_DSP_OUT_ZERO(0) |
1985                     V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0) |
1986                     V_DSP_X_MIR_EN(screen->x_mirror) |
1987                     V_DSP_Y_MIR_EN(screen->y_mirror);
1988                 val |= V_SW_CORE_DCLK_SEL(!!screen->pixelrepeat);
1989                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
1990                         val |= V_SW_HDMI_CLK_I_SEL(1);
1991                 else
1992                         val |= V_SW_HDMI_CLK_I_SEL(0);
1993                 vop_msk_reg(vop_dev, DSP_CTRL0, val);
1994
1995                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
1996                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(1));
1997                 else
1998                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(0));
1999                 /* BG color */
2000                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
2001                         val = V_DSP_OUT_RGB_YUV(1);
2002                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
2003                         val = V_DSP_BG_BLUE(0x200) | V_DSP_BG_GREEN(0x40) |
2004                                 V_DSP_BG_RED(0x200);
2005                         vop_msk_reg(vop_dev, DSP_BG, val);
2006                 } else {
2007                         val = V_DSP_OUT_RGB_YUV(0);
2008                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
2009                         val = V_DSP_BG_BLUE(0x55) | V_DSP_BG_GREEN(0x55) |
2010                                 V_DSP_BG_RED(0x55);
2011                         vop_msk_reg(vop_dev, DSP_BG, val);
2012                 }
2013                 dev_drv->output_color = screen->color_mode;
2014                 vop_bcsh_path_sel(dev_drv);
2015                 vop_config_timing(dev_drv);
2016                 vop_cfg_done(vop_dev);
2017         }
2018         spin_unlock(&vop_dev->reg_lock);
2019         vop_set_dclk(dev_drv, 1);
2020         if (screen->type != SCREEN_HDMI && screen->type != SCREEN_TVOUT &&
2021             dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2022                 dev_drv->trsm_ops->enable();
2023         if (screen->init)
2024                 screen->init();
2025
2026         return 0;
2027 }
2028
2029 /*enable layer,open:1,enable;0 disable*/
2030 static void vop_layer_enable(struct vop_device *vop_dev,
2031                              unsigned int win_id, bool open)
2032 {
2033         spin_lock(&vop_dev->reg_lock);
2034         if (likely(vop_dev->clk_on) &&
2035             vop_dev->driver.win[win_id]->state != open) {
2036                 if (open) {
2037                         if (!vop_dev->atv_layer_cnt) {
2038                                 dev_info(vop_dev->dev,
2039                                          "wakeup from standby!\n");
2040                                 vop_dev->standby = 0;
2041                         }
2042                         vop_dev->atv_layer_cnt |= (1 << win_id);
2043                 } else {
2044                         if (vop_dev->atv_layer_cnt & (1 << win_id))
2045                                 vop_dev->atv_layer_cnt &= ~(1 << win_id);
2046                 }
2047                 vop_dev->driver.win[win_id]->state = open;
2048                 if (!open) {
2049                         vop_layer_update_regs(vop_dev,
2050                                               vop_dev->driver.win[win_id]);
2051                         vop_cfg_done(vop_dev);
2052                 }
2053                 /* if no layer used,disable lcdc */
2054                 if (!vop_dev->atv_layer_cnt) {
2055                         dev_info(vop_dev->dev,
2056                                  "no layer is used,go to standby!\n");
2057                         vop_dev->standby = 1;
2058                 }
2059         }
2060         spin_unlock(&vop_dev->reg_lock);
2061 }
2062
2063 static int vop_enable_irq(struct rk_lcdc_driver *dev_drv)
2064 {
2065         struct vop_device *vop_dev = container_of(dev_drv,
2066                                                     struct vop_device, driver);
2067         u64 val;
2068         /* struct rk_screen *screen = dev_drv->cur_screen; */
2069
2070         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
2071
2072         val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1 |
2073                 INTR_WIN0_EMPTY | INTR_WIN1_EMPTY | INTR_HWC_EMPTY |
2074                 INTR_POST_BUF_EMPTY;
2075
2076         vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val);
2077
2078         return 0;
2079 }
2080
2081 static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id,
2082                     bool open)
2083 {
2084         struct vop_device *vop_dev =
2085             container_of(dev_drv, struct vop_device, driver);
2086
2087         /* enable clk,when first layer open */
2088         if ((open) && (!vop_dev->atv_layer_cnt)) {
2089                 /* rockchip_set_system_status(sys_status); */
2090                 vop_pre_init(dev_drv);
2091                 vop_clk_enable(vop_dev);
2092                 vop_enable_irq(dev_drv);
2093                 if (dev_drv->iommu_enabled) {
2094                         if (!dev_drv->mmu_dev) {
2095                                 dev_drv->mmu_dev =
2096                                     rk_fb_get_sysmmu_device_by_compatible
2097                                     (dev_drv->mmu_dts_name);
2098                                 if (dev_drv->mmu_dev) {
2099                                         rk_fb_platform_set_sysmmu
2100                                             (dev_drv->mmu_dev, dev_drv->dev);
2101                                 } else {
2102                                         dev_err(dev_drv->dev,
2103                                                 "fail get rk iommu device\n");
2104                                         return -1;
2105                                 }
2106                         }
2107                 }
2108                 if ((support_uboot_display() && (vop_dev->prop == PRMRY)))
2109                         vop_set_dclk(dev_drv, 0);
2110                 else
2111                         vop_load_screen(dev_drv, 1);
2112                 if (dev_drv->bcsh.enable)
2113                         vop_set_bcsh(dev_drv, 1);
2114                 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
2115                 vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
2116         }
2117
2118         if (win_id < dev_drv->lcdc_win_num)
2119                 vop_layer_enable(vop_dev, win_id, open);
2120         else
2121                 dev_err(vop_dev->dev, "invalid win id:%d\n", win_id);
2122
2123         dev_drv->first_frame = 0;
2124         return 0;
2125 }
2126
2127 static int win_0_1_display(struct vop_device *vop_dev,
2128                            struct rk_lcdc_win *win)
2129 {
2130         u32 y_addr;
2131         u32 uv_addr;
2132         unsigned int off;
2133
2134         off = win->id * 0x40;
2135         /*win->smem_start + win->y_offset; */
2136         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2137         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
2138         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
2139             vop_dev->id, win->id, y_addr, uv_addr);
2140         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
2141             win->area[0].y_offset, win->area[0].c_offset);
2142         spin_lock(&vop_dev->reg_lock);
2143         if (likely(vop_dev->clk_on)) {
2144                 win->area[0].y_addr = y_addr;
2145                 win->area[0].uv_addr = uv_addr;
2146                 vop_writel(vop_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
2147                 vop_writel(vop_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
2148                 if (win->area[0].fbdc_en == 1)
2149                         vop_writel(vop_dev, AFBCD0_HDR_PTR,
2150                                    win->area[0].y_addr);
2151         }
2152         spin_unlock(&vop_dev->reg_lock);
2153
2154         return 0;
2155 }
2156
2157 static int win_2_3_display(struct vop_device *vop_dev,
2158                            struct rk_lcdc_win *win)
2159 {
2160         u32 i, y_addr;
2161         unsigned int off;
2162
2163         off = (win->id - 2) * 0x50;
2164         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2165         DBG(2, "lcdc[%d]:win[%d]:", vop_dev->id, win->id);
2166
2167         if (likely(vop_dev->clk_on)) {
2168                 for (i = 0; i < win->area_num; i++) {
2169                         DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
2170                             i, win->area[i].y_addr, win->area[i].y_offset);
2171                         win->area[i].y_addr =
2172                             win->area[i].smem_start + win->area[i].y_offset;
2173                         }
2174                 spin_lock(&vop_dev->reg_lock);
2175                 vop_writel(vop_dev, WIN2_MST0 + off, win->area[0].y_addr);
2176                 vop_writel(vop_dev, WIN2_MST1 + off, win->area[1].y_addr);
2177                 vop_writel(vop_dev, WIN2_MST2 + off, win->area[2].y_addr);
2178                 vop_writel(vop_dev, WIN2_MST3 + off, win->area[3].y_addr);
2179                 if (win->area[0].fbdc_en == 1)
2180                         vop_writel(vop_dev, AFBCD0_HDR_PTR,
2181                                    win->area[0].y_addr);
2182                 spin_unlock(&vop_dev->reg_lock);
2183         }
2184         return 0;
2185 }
2186
2187 static int hwc_display(struct vop_device *vop_dev, struct rk_lcdc_win *win)
2188 {
2189         u32 y_addr;
2190
2191         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2192         DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
2193             vop_dev->id, __func__, y_addr);
2194         spin_lock(&vop_dev->reg_lock);
2195         if (likely(vop_dev->clk_on)) {
2196                 win->area[0].y_addr = y_addr;
2197                 vop_writel(vop_dev, HWC_MST, win->area[0].y_addr);
2198         }
2199         spin_unlock(&vop_dev->reg_lock);
2200
2201         return 0;
2202 }
2203
2204 static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
2205 {
2206         struct vop_device *vop_dev =
2207             container_of(dev_drv, struct vop_device, driver);
2208         struct rk_lcdc_win *win = NULL;
2209         struct rk_screen *screen = dev_drv->cur_screen;
2210
2211         win = dev_drv->win[win_id];
2212         if (!screen) {
2213                 dev_err(dev_drv->dev, "screen is null!\n");
2214                 return -ENOENT;
2215         }
2216         if (unlikely(!vop_dev->clk_on)) {
2217                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
2218                 return 0;
2219         }
2220         if (win_id == 0) {
2221                 win_0_1_display(vop_dev, win);
2222         } else if (win_id == 1) {
2223                 win_0_1_display(vop_dev, win);
2224         } else if (win_id == 2) {
2225                 win_2_3_display(vop_dev, win);
2226         } else if (win_id == 3) {
2227                 win_2_3_display(vop_dev, win);
2228         } else if (win_id == 4) {
2229                 hwc_display(vop_dev, win);
2230         } else {
2231                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
2232                 return -EINVAL;
2233         }
2234
2235         return 0;
2236 }
2237
2238 static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen)
2239 {
2240         u16 srcW;
2241         u16 srcH;
2242         u16 dstW;
2243         u16 dstH;
2244         u16 yrgb_srcW;
2245         u16 yrgb_srcH;
2246         u16 yrgb_dstW;
2247         u16 yrgb_dstH;
2248         u32 yrgb_vscalednmult;
2249         u32 yrgb_xscl_factor;
2250         u32 yrgb_yscl_factor;
2251         u8 yrgb_vsd_bil_gt2 = 0;
2252         u8 yrgb_vsd_bil_gt4 = 0;
2253
2254         u16 cbcr_srcW;
2255         u16 cbcr_srcH;
2256         u16 cbcr_dstW;
2257         u16 cbcr_dstH;
2258         u32 cbcr_vscalednmult;
2259         u32 cbcr_xscl_factor;
2260         u32 cbcr_yscl_factor;
2261         u8 cbcr_vsd_bil_gt2 = 0;
2262         u8 cbcr_vsd_bil_gt4 = 0;
2263         u8 yuv_fmt = 0;
2264
2265         srcW = win->area[0].xact;
2266         if ((screen->mode.vmode & FB_VMODE_INTERLACED) &&
2267             (win->area[0].yact == 2 * win->area[0].ysize)) {
2268                 srcH = win->area[0].yact / 2;
2269                 yrgb_vsd_bil_gt2 = 1;
2270                 cbcr_vsd_bil_gt2 = 1;
2271         } else {
2272                 srcH = win->area[0].yact;
2273         }
2274         dstW = win->area[0].xsize;
2275         dstH = win->area[0].ysize;
2276
2277         /*yrgb scl mode */
2278         yrgb_srcW = srcW;
2279         yrgb_srcH = srcH;
2280         yrgb_dstW = dstW;
2281         yrgb_dstH = dstH;
2282         if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
2283                 pr_err("ERROR: yrgb scale exceed 8,");
2284                 pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
2285                        yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
2286         }
2287         if (yrgb_srcW < yrgb_dstW)
2288                 win->yrgb_hor_scl_mode = SCALE_UP;
2289         else if (yrgb_srcW > yrgb_dstW)
2290                 win->yrgb_hor_scl_mode = SCALE_DOWN;
2291         else
2292                 win->yrgb_hor_scl_mode = SCALE_NONE;
2293
2294         if (yrgb_srcH < yrgb_dstH)
2295                 win->yrgb_ver_scl_mode = SCALE_UP;
2296         else if (yrgb_srcH > yrgb_dstH)
2297                 win->yrgb_ver_scl_mode = SCALE_DOWN;
2298         else
2299                 win->yrgb_ver_scl_mode = SCALE_NONE;
2300
2301         /*cbcr scl mode */
2302         switch (win->area[0].format) {
2303         case YUV422:
2304         case YUYV422:
2305         case UYVY422:
2306         case YUV422_A:
2307                 cbcr_srcW = srcW / 2;
2308                 cbcr_dstW = dstW;
2309                 cbcr_srcH = srcH;
2310                 cbcr_dstH = dstH;
2311                 yuv_fmt = 1;
2312                 break;
2313         case YUV420:
2314         case YUYV420:
2315         case UYVY420:
2316         case YUV420_A:
2317         case YUV420_NV21:
2318                 cbcr_srcW = srcW / 2;
2319                 cbcr_dstW = dstW;
2320                 cbcr_srcH = srcH / 2;
2321                 cbcr_dstH = dstH;
2322                 yuv_fmt = 1;
2323                 break;
2324         case YUV444:
2325         case YUV444_A:
2326                 cbcr_srcW = srcW;
2327                 cbcr_dstW = dstW;
2328                 cbcr_srcH = srcH;
2329                 cbcr_dstH = dstH;
2330                 yuv_fmt = 1;
2331                 break;
2332         default:
2333                 cbcr_srcW = 0;
2334                 cbcr_dstW = 0;
2335                 cbcr_srcH = 0;
2336                 cbcr_dstH = 0;
2337                 yuv_fmt = 0;
2338                 break;
2339         }
2340         if (yuv_fmt) {
2341                 if ((cbcr_dstW * 8 <= cbcr_srcW) ||
2342                     (cbcr_dstH * 8 <= cbcr_srcH)) {
2343                         pr_err("ERROR: cbcr scale exceed 8,");
2344                         pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
2345                                cbcr_srcH, cbcr_dstW, cbcr_dstH);
2346                 }
2347         }
2348
2349         if (cbcr_srcW < cbcr_dstW)
2350                 win->cbr_hor_scl_mode = SCALE_UP;
2351         else if (cbcr_srcW > cbcr_dstW)
2352                 win->cbr_hor_scl_mode = SCALE_DOWN;
2353         else
2354                 win->cbr_hor_scl_mode = SCALE_NONE;
2355
2356         if (cbcr_srcH < cbcr_dstH)
2357                 win->cbr_ver_scl_mode = SCALE_UP;
2358         else if (cbcr_srcH > cbcr_dstH)
2359                 win->cbr_ver_scl_mode = SCALE_DOWN;
2360         else
2361                 win->cbr_ver_scl_mode = SCALE_NONE;
2362
2363         /* line buffer mode */
2364         if ((win->area[0].format == YUV422) ||
2365             (win->area[0].format == YUV420) ||
2366             (win->area[0].format == YUYV422) ||
2367             (win->area[0].format == YUYV420) ||
2368             (win->area[0].format == UYVY422) ||
2369             (win->area[0].format == UYVY420) ||
2370             (win->area[0].format == YUV420_NV21) ||
2371             (win->area[0].format == YUV422_A) ||
2372             (win->area[0].format == YUV420_A)) {
2373                 if (win->cbr_hor_scl_mode == SCALE_DOWN) {
2374                         if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
2375                             (cbcr_dstW == 0))
2376                                 pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
2377                                        cbcr_dstW);
2378                         else if (cbcr_dstW > 1280)
2379                                 win->win_lb_mode = LB_YUV_3840X5;
2380                         else
2381                                 win->win_lb_mode = LB_YUV_2560X8;
2382                 } else {        /* SCALE_UP or SCALE_NONE */
2383                         if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
2384                             (cbcr_srcW == 0))
2385                                 pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
2386                                        cbcr_srcW);
2387                         else if (cbcr_srcW > 1280)
2388                                 win->win_lb_mode = LB_YUV_3840X5;
2389                         else
2390                                 win->win_lb_mode = LB_YUV_2560X8;
2391                 }
2392         } else {
2393                 if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
2394                         if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
2395                             (yrgb_dstW == 0))
2396                                 pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
2397                         else if (yrgb_dstW > 2560)
2398                                 win->win_lb_mode = LB_RGB_3840X2;
2399                         else if (yrgb_dstW > 1920)
2400                                 win->win_lb_mode = LB_RGB_2560X4;
2401                         else if (yrgb_dstW > 1280)
2402                                 win->win_lb_mode = LB_RGB_1920X5;
2403                         else
2404                                 win->win_lb_mode = LB_RGB_1280X8;
2405                 } else {        /* SCALE_UP or SCALE_NONE */
2406                         if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
2407                             (yrgb_srcW == 0))
2408                                 pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
2409                         else if (yrgb_srcW > 2560)
2410                                 win->win_lb_mode = LB_RGB_3840X2;
2411                         else if (yrgb_srcW > 1920)
2412                                 win->win_lb_mode = LB_RGB_2560X4;
2413                         else if (yrgb_srcW > 1280)
2414                                 win->win_lb_mode = LB_RGB_1920X5;
2415                         else
2416                                 win->win_lb_mode = LB_RGB_1280X8;
2417                 }
2418         }
2419         DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
2420
2421         /* vsd/vsu scale ALGORITHM */
2422         win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2423         win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2424         win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2425         win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2426
2427         /* if (VOP_CHIP(vop_dev) == VOP_RK3399) { */
2428         if ((win->area[0].format == YUYV422) ||
2429             (win->area[0].format == YUYV420) ||
2430             (win->area[0].format == UYVY422) ||
2431             (win->area[0].format == UYVY420)) {
2432                 yrgb_vscalednmult =
2433                         vop_get_hard_ware_vskiplines(yrgb_srcH, yrgb_dstH);
2434                 if (yrgb_vscalednmult == 4) {
2435                         yrgb_vsd_bil_gt4 = 1;
2436                         yrgb_vsd_bil_gt2 = 0;
2437                 } else if (yrgb_vscalednmult == 2) {
2438                         yrgb_vsd_bil_gt4 = 0;
2439                         yrgb_vsd_bil_gt2 = 1;
2440                 } else {
2441                         yrgb_vsd_bil_gt4 = 0;
2442                         yrgb_vsd_bil_gt2 = 0;
2443                 }
2444                 if ((win->area[0].format == YUYV420) ||
2445                     (win->area[0].format == UYVY420)) {
2446                         if ((yrgb_vsd_bil_gt4 == 1) || (yrgb_vsd_bil_gt2 == 1))
2447                                 win->yrgb_vsd_mode = SCALE_DOWN_AVG;
2448                 }
2449
2450                 cbcr_vscalednmult =
2451                         vop_get_hard_ware_vskiplines(cbcr_srcH, cbcr_dstH);
2452                 if (cbcr_vscalednmult == 4) {
2453                         cbcr_vsd_bil_gt4 = 1;
2454                         cbcr_vsd_bil_gt2 = 0;
2455                 } else if (cbcr_vscalednmult == 2) {
2456                         cbcr_vsd_bil_gt4 = 0;
2457                         cbcr_vsd_bil_gt2 = 1;
2458                 } else {
2459                         cbcr_vsd_bil_gt4 = 0;
2460                         cbcr_vsd_bil_gt2 = 0;
2461                 }
2462                 if ((win->area[0].format == YUYV420) ||
2463                     (win->area[0].format == UYVY420)) {
2464                         if ((cbcr_vsd_bil_gt4 == 1) || (cbcr_vsd_bil_gt2 == 1))
2465                                 win->cbr_vsd_mode = SCALE_DOWN_AVG;
2466                 }
2467                 /* CBCR vsd_mode must same to YRGB for YUYV when gt2 or gt4 */
2468                 if ((cbcr_vsd_bil_gt4 == 1) || (cbcr_vsd_bil_gt2 == 1)) {
2469                         if (win->yrgb_vsd_mode != win->cbr_vsd_mode)
2470                                 win->cbr_vsd_mode = win->yrgb_vsd_mode;
2471                 }
2472         }
2473         /* 3399 yuyv support*/
2474         if (win->ymirror == 1) {
2475                 if (win->yrgb_vsd_mode == SCALE_DOWN_AVG)
2476                         pr_info("y_mirror enable, y-vsd AVG mode unsupprot\n");
2477                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2478         }
2479         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
2480                 if (win->yrgb_vsd_mode == SCALE_DOWN_AVG)
2481                         pr_info("interlace mode, y-vsd AVG mode unsupprot\n");
2482                 /* interlace mode must bill */
2483                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2484                 win->cbr_vsd_mode = SCALE_DOWN_BIL;
2485         }
2486         switch (win->win_lb_mode) {
2487         case LB_YUV_3840X5:
2488         case LB_YUV_2560X8:
2489         case LB_RGB_1920X5:
2490         case LB_RGB_1280X8:
2491                 win->yrgb_vsu_mode = SCALE_UP_BIC;
2492                 win->cbr_vsu_mode = SCALE_UP_BIC;
2493                 break;
2494         case LB_RGB_3840X2:
2495                 if (win->yrgb_ver_scl_mode != SCALE_NONE)
2496                         pr_err("ERROR : not allow yrgb ver scale\n");
2497                 if (win->cbr_ver_scl_mode != SCALE_NONE)
2498                         pr_err("ERROR : not allow cbcr ver scale\n");
2499                 break;
2500         case LB_RGB_2560X4:
2501                 win->yrgb_vsu_mode = SCALE_UP_BIL;
2502                 win->cbr_vsu_mode = SCALE_UP_BIL;
2503                 break;
2504         default:
2505                 pr_info("%s:un supported win_lb_mode:%d\n",
2506                         __func__, win->win_lb_mode);
2507                 break;
2508         }
2509
2510         if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
2511             (win->area[0].fbdc_en == 1)) {
2512                 /* in this pattern,use bil mode,not support souble scd,
2513                  * use avg mode, support double scd, but aclk should be
2514                  * bigger than dclk.
2515                  */
2516                 if (yrgb_srcH >= 2 * yrgb_dstH) {
2517                         pr_err("ERROR : fbdc mode,not support y scale down:");
2518                         pr_err("srcH[%d] > 2 *dstH[%d]\n",
2519                                yrgb_srcH, yrgb_dstH);
2520                 }
2521         }
2522         DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
2523             win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
2524             win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
2525
2526         /* SCALE FACTOR */
2527
2528         /* (1.1)YRGB HOR SCALE FACTOR */
2529         switch (win->yrgb_hor_scl_mode) {
2530         case SCALE_NONE:
2531                 yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2532                 break;
2533         case SCALE_UP:
2534                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
2535                 break;
2536         case SCALE_DOWN:
2537                 switch (win->yrgb_hsd_mode) {
2538                 case SCALE_DOWN_BIL:
2539                         yrgb_xscl_factor =
2540                             GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
2541                         break;
2542                 case SCALE_DOWN_AVG:
2543                         yrgb_xscl_factor =
2544                             GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
2545                         break;
2546                 default:
2547                         pr_info("%s:un supported yrgb_hsd_mode:%d\n", __func__,
2548                                 win->yrgb_hsd_mode);
2549                         break;
2550                 }
2551                 break;
2552         default:
2553                 pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
2554                         __func__, win->yrgb_hor_scl_mode);
2555                 break;
2556         }
2557
2558         /* (1.2)YRGB VER SCALE FACTOR */
2559         switch (win->yrgb_ver_scl_mode) {
2560         case SCALE_NONE:
2561                 yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2562                 break;
2563         case SCALE_UP:
2564                 switch (win->yrgb_vsu_mode) {
2565                 case SCALE_UP_BIL:
2566                         yrgb_yscl_factor =
2567                             GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
2568                         break;
2569                 case SCALE_UP_BIC:
2570                         if (yrgb_srcH < 3) {
2571                                 pr_err("yrgb_srcH should be");
2572                                 pr_err(" greater than 3 !!!\n");
2573                         }
2574                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
2575                                                                 yrgb_dstH);
2576                         break;
2577                 default:
2578                         pr_info("%s:un support yrgb_vsu_mode:%d\n",
2579                                 __func__, win->yrgb_vsu_mode);
2580                         break;
2581                 }
2582                 break;
2583         case SCALE_DOWN:
2584                 switch (win->yrgb_vsd_mode) {
2585                 case SCALE_DOWN_BIL:
2586                         yrgb_vscalednmult =
2587                             vop_get_hard_ware_vskiplines(yrgb_srcH, yrgb_dstH);
2588                         yrgb_yscl_factor =
2589                             GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
2590                                                            yrgb_vscalednmult);
2591                         if (yrgb_yscl_factor >= 0x2000) {
2592                                 pr_err("yrgb_yscl_factor should less 0x2000");
2593                                 pr_err("yrgb_yscl_factor=%4x;\n",
2594                                        yrgb_yscl_factor);
2595                         }
2596                         if (yrgb_vscalednmult == 4) {
2597                                 yrgb_vsd_bil_gt4 = 1;
2598                                 yrgb_vsd_bil_gt2 = 0;
2599                         } else if (yrgb_vscalednmult == 2) {
2600                                 yrgb_vsd_bil_gt4 = 0;
2601                                 yrgb_vsd_bil_gt2 = 1;
2602                         } else {
2603                                 yrgb_vsd_bil_gt4 = 0;
2604                                 yrgb_vsd_bil_gt2 = 0;
2605                         }
2606                         break;
2607                 case SCALE_DOWN_AVG:
2608                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
2609                                                                  yrgb_dstH);
2610                         break;
2611                 default:
2612                         pr_info("%s:un support yrgb_vsd_mode:%d\n",
2613                                 __func__, win->yrgb_vsd_mode);
2614                         break;
2615                 }               /*win->yrgb_vsd_mode */
2616                 break;
2617         default:
2618                 pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
2619                         __func__, win->yrgb_ver_scl_mode);
2620                 break;
2621         }
2622         win->scale_yrgb_x = yrgb_xscl_factor;
2623         win->scale_yrgb_y = yrgb_yscl_factor;
2624         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
2625         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
2626         DBG(1, "yrgb:h_fac=%d, V_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
2627             yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
2628
2629         /*(2.1)CBCR HOR SCALE FACTOR */
2630         switch (win->cbr_hor_scl_mode) {
2631         case SCALE_NONE:
2632                 cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2633                 break;
2634         case SCALE_UP:
2635                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
2636                 break;
2637         case SCALE_DOWN:
2638                 switch (win->cbr_hsd_mode) {
2639                 case SCALE_DOWN_BIL:
2640                         cbcr_xscl_factor =
2641                             GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
2642                         break;
2643                 case SCALE_DOWN_AVG:
2644                         cbcr_xscl_factor =
2645                             GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
2646                         break;
2647                 default:
2648                         pr_info("%s:un support cbr_hsd_mode:%d\n",
2649                                 __func__, win->cbr_hsd_mode);
2650                         break;
2651                 }
2652                 break;
2653         default:
2654                 pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
2655                         __func__, win->cbr_hor_scl_mode);
2656                 break;
2657         }                       /*win->cbr_hor_scl_mode */
2658
2659         /* (2.2)CBCR VER SCALE FACTOR */
2660         switch (win->cbr_ver_scl_mode) {
2661         case SCALE_NONE:
2662                 cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2663                 break;
2664         case SCALE_UP:
2665                 switch (win->cbr_vsu_mode) {
2666                 case SCALE_UP_BIL:
2667                         cbcr_yscl_factor =
2668                             GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
2669                         break;
2670                 case SCALE_UP_BIC:
2671                         if (cbcr_srcH < 3) {
2672                                 pr_err("cbcr_srcH should be ");
2673                                 pr_err("greater than 3 !!!\n");
2674                         }
2675                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
2676                                                                 cbcr_dstH);
2677                         break;
2678                 default:
2679                         pr_info("%s:un support cbr_vsu_mode:%d\n",
2680                                 __func__, win->cbr_vsu_mode);
2681                         break;
2682                 }
2683                 break;
2684         case SCALE_DOWN:
2685                 switch (win->cbr_vsd_mode) {
2686                 case SCALE_DOWN_BIL:
2687                         cbcr_vscalednmult =
2688                             vop_get_hard_ware_vskiplines(cbcr_srcH, cbcr_dstH);
2689                         cbcr_yscl_factor =
2690                             GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
2691                                                            cbcr_vscalednmult);
2692                         if (cbcr_yscl_factor >= 0x2000) {
2693                                 pr_err("cbcr_yscl_factor should be less ");
2694                                 pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
2695                                        cbcr_yscl_factor);
2696                         }
2697
2698                         if (cbcr_vscalednmult == 4) {
2699                                 cbcr_vsd_bil_gt4 = 1;
2700                                 cbcr_vsd_bil_gt2 = 0;
2701                         } else if (cbcr_vscalednmult == 2) {
2702                                 cbcr_vsd_bil_gt4 = 0;
2703                                 cbcr_vsd_bil_gt2 = 1;
2704                         } else {
2705                                 cbcr_vsd_bil_gt4 = 0;
2706                                 cbcr_vsd_bil_gt2 = 0;
2707                         }
2708                         break;
2709                 case SCALE_DOWN_AVG:
2710                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
2711                                                                  cbcr_dstH);
2712                         break;
2713                 default:
2714                         pr_info("%s:un support cbr_vsd_mode:%d\n",
2715                                 __func__, win->cbr_vsd_mode);
2716                         break;
2717                 }
2718                 break;
2719         default:
2720                 pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
2721                         __func__, win->cbr_ver_scl_mode);
2722                 break;
2723         }
2724         win->scale_cbcr_x = cbcr_xscl_factor;
2725         win->scale_cbcr_y = cbcr_yscl_factor;
2726         win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
2727         win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
2728
2729         DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
2730             cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
2731         return 0;
2732 }
2733
2734 static int dsp_x_pos(int mirror_en, struct rk_screen *screen,
2735                      struct rk_lcdc_win_area *area)
2736 {
2737         int pos;
2738
2739         if (screen->x_mirror && mirror_en)
2740                 pr_err("not support both win and global mirror\n");
2741
2742         if ((!mirror_en) && (!screen->x_mirror))
2743                 pos = area->xpos + screen->mode.left_margin +
2744                         screen->mode.hsync_len;
2745         else
2746                 pos = screen->mode.xres - area->xpos -
2747                         area->xsize + screen->mode.left_margin +
2748                         screen->mode.hsync_len;
2749
2750         return pos;
2751 }
2752
2753 static int dsp_y_pos(int mirror_en, struct rk_screen *screen,
2754                      struct rk_lcdc_win_area *area)
2755 {
2756         int pos;
2757
2758         if (screen->y_mirror && mirror_en)
2759                 pr_err("not support both win and global mirror\n");
2760
2761         if ((!mirror_en) && (!screen->y_mirror))
2762                 pos = area->ypos + screen->mode.upper_margin +
2763                         screen->mode.vsync_len;
2764         else
2765                 pos = screen->mode.yres - area->ypos -
2766                         area->ysize + screen->mode.upper_margin +
2767                         screen->mode.vsync_len;
2768
2769         return pos;
2770 }
2771
2772 static int win_0_1_set_par(struct vop_device *vop_dev,
2773                            struct rk_screen *screen, struct rk_lcdc_win *win)
2774 {
2775         u32 xact, yact, xvir, yvir, xpos, ypos;
2776         u8 fmt_cfg = 0, swap_rb, swap_uv = 0;
2777         char fmt[9] = "NULL";
2778
2779         xpos = dsp_x_pos(win->xmirror, screen, &win->area[0]);
2780         ypos = dsp_y_pos(win->ymirror, screen, &win->area[0]);
2781
2782         spin_lock(&vop_dev->reg_lock);
2783         if (likely(vop_dev->clk_on)) {
2784                 vop_cal_scl_fac(win, screen);
2785                 switch (win->area[0].format) {
2786                 case FBDC_RGB_565:
2787                         fmt_cfg = 2;
2788                         swap_rb = 0;
2789                         win->fmt_10 = 0;
2790                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_RGB565;
2791                         break;
2792                 case FBDC_ARGB_888:
2793                         fmt_cfg = 0;
2794                         swap_rb = 1;
2795                         win->fmt_10 = 0;
2796                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
2797                         break;
2798                 case FBDC_ABGR_888:
2799                         fmt_cfg = 0;
2800                         swap_rb = 0;
2801                         win->fmt_10 = 0;
2802                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
2803                         break;
2804                 case FBDC_RGBX_888:
2805                         fmt_cfg = 0;
2806                         swap_rb = 0;
2807                         win->fmt_10 = 0;
2808                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
2809                         break;
2810                 case ARGB888:
2811                         fmt_cfg = 0;
2812                         swap_rb = 0;
2813                         win->fmt_10 = 0;
2814                         break;
2815                 case XBGR888:
2816                 case ABGR888:
2817                         fmt_cfg = 0;
2818                         swap_rb = 1;
2819                         win->fmt_10 = 0;
2820                         break;
2821                 case BGR888:
2822                         fmt_cfg = 1;
2823                         swap_rb = 1;
2824                         win->fmt_10 = 0;
2825                         break;
2826                 case RGB888:
2827                         fmt_cfg = 1;
2828                         swap_rb = 0;
2829                         win->fmt_10 = 0;
2830                         break;
2831                 case RGB565:
2832                         fmt_cfg = 2;
2833                         swap_rb = 0;
2834                         win->fmt_10 = 0;
2835                         break;
2836                 case YUV422:
2837                         fmt_cfg = 5;
2838                         swap_rb = 0;
2839                         win->fmt_10 = 0;
2840                         break;
2841                 case YUV420:
2842                         fmt_cfg = 4;
2843                         swap_rb = 0;
2844                         win->fmt_10 = 0;
2845                         break;
2846                 case YUV420_NV21:
2847                         fmt_cfg = 4;
2848                         swap_rb = 0;
2849                         swap_uv = 1;
2850                         win->fmt_10 = 0;
2851                         break;
2852                 case YUV444:
2853                         fmt_cfg = 6;
2854                         swap_rb = 0;
2855                         win->fmt_10 = 0;
2856                         break;
2857                 case YUV422_A:
2858                         fmt_cfg = 5;
2859                         swap_rb = 0;
2860                         win->fmt_10 = 1;
2861                         break;
2862                 case YUV420_A:
2863                         fmt_cfg = 4;
2864                         swap_rb = 0;
2865                         win->fmt_10 = 1;
2866                         break;
2867                 case YUV444_A:
2868                         fmt_cfg = 6;
2869                         swap_rb = 0;
2870                         win->fmt_10 = 1;
2871                         break;
2872                 case YUYV422:
2873                         fmt_cfg = 0;
2874                         swap_rb = 0;
2875                         win->fmt_10 = 0;
2876                         win->area[0].yuyv_fmt = 1;
2877                         break;
2878                 case YUYV420:
2879                         fmt_cfg = 1;
2880                         swap_rb = 0;
2881                         win->fmt_10 = 0;
2882                         win->area[0].yuyv_fmt = 1;
2883                         break;
2884                 case UYVY422:
2885                         fmt_cfg = 2;
2886                         swap_rb = 0;
2887                         win->fmt_10 = 0;
2888                         win->area[0].yuyv_fmt = 1;
2889                         break;
2890                 case UYVY420:
2891                         fmt_cfg = 3;
2892                         swap_rb = 0;
2893                         win->fmt_10 = 0;
2894                         win->area[0].yuyv_fmt = 1;
2895                         break;
2896                 default:
2897                         dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n",
2898                                 __func__, win->area[0].format);
2899                         break;
2900                 }
2901                 win->area[0].fmt_cfg = fmt_cfg;
2902                 win->area[0].swap_rb = swap_rb;
2903                 win->area[0].swap_uv = swap_uv;
2904                 win->area[0].dsp_stx = xpos;
2905                 win->area[0].dsp_sty = ypos;
2906                 xact = win->area[0].xact;
2907                 yact = win->area[0].yact;
2908                 xvir = win->area[0].xvir;
2909                 yvir = win->area[0].yvir;
2910         }
2911         if (win->area[0].fbdc_en)
2912                 vop_init_fbdc_config(vop_dev, win->id);
2913         vop_win_0_1_reg_update(&vop_dev->driver, win->id);
2914         spin_unlock(&vop_dev->reg_lock);
2915
2916         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2917             vop_dev->id, win->id, get_format_string(win->area[0].format, fmt),
2918             xact, yact, win->area[0].xsize);
2919         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
2920             win->area[0].ysize, xvir, yvir, xpos, ypos);
2921
2922         return 0;
2923 }
2924
2925 static int win_2_3_set_par(struct vop_device *vop_dev,
2926                            struct rk_screen *screen, struct rk_lcdc_win *win)
2927 {
2928         int i;
2929         u8 fmt_cfg, swap_rb;
2930         char fmt[9] = "NULL";
2931
2932         if (VOP_CHIP(vop_dev) == VOP_RK322X) {
2933                 pr_err("rk3228 not support win2/3 set par\n");
2934                 return -EINVAL;
2935         }
2936         if (win->ymirror) {
2937                 pr_err("win[%d] not support y mirror\n", win->id);
2938                 return -EINVAL;
2939         }
2940         spin_lock(&vop_dev->reg_lock);
2941         if (likely(vop_dev->clk_on)) {
2942                 DBG(2, "lcdc[%d]:win[%d]>>\n>\n", vop_dev->id, win->id);
2943                 for (i = 0; i < win->area_num; i++) {
2944                         switch (win->area[i].format) {
2945                         case FBDC_RGB_565:
2946                                 fmt_cfg = 2;
2947                                 swap_rb = 0;
2948                                 win->fmt_10 = 0;
2949                                 win->area[0].fbdc_fmt_cfg = 0x05;
2950                                 break;
2951                         case FBDC_ARGB_888:
2952                                 fmt_cfg = 0;
2953                                 swap_rb = 0;
2954                                 win->fmt_10 = 0;
2955                                 win->area[0].fbdc_fmt_cfg = 0x0c;
2956                                 break;
2957                         case FBDC_RGBX_888:
2958                                 fmt_cfg = 0;
2959                                 swap_rb = 0;
2960                                 win->fmt_10 = 0;
2961                                 win->area[0].fbdc_fmt_cfg = 0x3a;
2962                                 break;
2963                         case ARGB888:
2964                                 fmt_cfg = 0;
2965                                 swap_rb = 0;
2966                                 break;
2967                         case XBGR888:
2968                         case ABGR888:
2969                                 fmt_cfg = 0;
2970                                 swap_rb = 1;
2971                                 break;
2972                         case RGB888:
2973                                 fmt_cfg = 1;
2974                                 swap_rb = 0;
2975                                 break;
2976                         case RGB565:
2977                                 fmt_cfg = 2;
2978                                 swap_rb = 0;
2979                                 break;
2980                         default:
2981                                 dev_err(vop_dev->driver.dev,
2982                                         "%s:un supported format!\n", __func__);
2983                                 spin_unlock(&vop_dev->reg_lock);
2984                                 return -EINVAL;
2985                         }
2986                         win->area[i].fmt_cfg = fmt_cfg;
2987                         win->area[i].swap_rb = swap_rb;
2988                         win->area[i].dsp_stx = dsp_x_pos(win->xmirror, screen,
2989                                                          &win->area[i]);
2990                         win->area[i].dsp_sty = dsp_y_pos(win->ymirror, screen,
2991                                                          &win->area[i]);
2992                         if (((win->area[i].xact != win->area[i].xsize) ||
2993                              (win->area[i].yact != win->area[i].ysize)) &&
2994                             (screen->mode.vmode == FB_VMODE_NONINTERLACED)) {
2995                                 pr_err("win[%d]->area[%d],not support scale\n",
2996                                        win->id, i);
2997                                 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
2998                                        win->area[i].xact, win->area[i].yact,
2999                                        win->area[i].xsize, win->area[i].ysize);
3000                                 win->area[i].xsize = win->area[i].xact;
3001                                 win->area[i].ysize = win->area[i].yact;
3002                         }
3003                         DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
3004                             get_format_string(win->area[i].format, fmt),
3005                             win->area[i].xsize, win->area[i].ysize,
3006                             win->area[i].xpos, win->area[i].ypos);
3007                 }
3008         }
3009         if (win->area[0].fbdc_en)
3010                 vop_init_fbdc_config(vop_dev, win->id);
3011         vop_win_2_3_reg_update(&vop_dev->driver, win->id);
3012         spin_unlock(&vop_dev->reg_lock);
3013         return 0;
3014 }
3015
3016 static int hwc_set_par(struct vop_device *vop_dev,
3017                        struct rk_screen *screen, struct rk_lcdc_win *win)
3018 {
3019         u32 xact, yact, xvir, yvir, xpos, ypos;
3020         u8 fmt_cfg = 0, swap_rb;
3021         char fmt[9] = "NULL";
3022
3023         xpos = win->area[0].xpos + screen->mode.left_margin +
3024             screen->mode.hsync_len;
3025         ypos = win->area[0].ypos + screen->mode.upper_margin +
3026             screen->mode.vsync_len;
3027
3028         spin_lock(&vop_dev->reg_lock);
3029         if (likely(vop_dev->clk_on)) {
3030                 switch (win->area[0].format) {
3031                 case ARGB888:
3032                         fmt_cfg = 0;
3033                         swap_rb = 0;
3034                         break;
3035                 case XBGR888:
3036                 case ABGR888:
3037                         fmt_cfg = 0;
3038                         swap_rb = 1;
3039                         break;
3040                 case RGB888:
3041                         fmt_cfg = 1;
3042                         swap_rb = 0;
3043                         break;
3044                 case RGB565:
3045                         fmt_cfg = 2;
3046                         swap_rb = 0;
3047                         break;
3048                 default:
3049                         dev_err(vop_dev->dev, "%s:un supported format[%d]!\n",
3050                                 __func__, win->area[0].format);
3051                         break;
3052                 }
3053                 win->area[0].fmt_cfg = fmt_cfg;
3054                 win->area[0].swap_rb = swap_rb;
3055                 win->area[0].dsp_stx = xpos;
3056                 win->area[0].dsp_sty = ypos;
3057                 xact = win->area[0].xact;
3058                 yact = win->area[0].yact;
3059                 xvir = win->area[0].xvir;
3060                 yvir = win->area[0].yvir;
3061         }
3062         vop_hwc_reg_update(&vop_dev->driver, 4);
3063         spin_unlock(&vop_dev->reg_lock);
3064
3065         DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
3066             vop_dev->id, __func__, get_format_string(win->area[0].format, fmt),
3067             xact, yact, win->area[0].xsize);
3068         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
3069             win->area[0].ysize, xvir, yvir, xpos, ypos);
3070         return 0;
3071 }
3072
3073 static int vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
3074 {
3075         struct vop_device *vop_dev =
3076             container_of(dev_drv, struct vop_device, driver);
3077         struct rk_lcdc_win *win = NULL;
3078         struct rk_screen *screen = dev_drv->cur_screen;
3079
3080         if (unlikely(!vop_dev->clk_on)) {
3081                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
3082                 return 0;
3083         }
3084         win = dev_drv->win[win_id];
3085         if (win)
3086         switch (win_id) {
3087         case 0:
3088                 win_0_1_set_par(vop_dev, screen, win);
3089                 break;
3090         case 1:
3091                 win_0_1_set_par(vop_dev, screen, win);
3092                 break;
3093         case 2:
3094                 win_2_3_set_par(vop_dev, screen, win);
3095                 break;
3096         case 3:
3097                 win_2_3_set_par(vop_dev, screen, win);
3098                 break;
3099         case 4:
3100                 hwc_set_par(vop_dev, screen, win);
3101                 break;
3102         default:
3103                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
3104                 break;
3105         }
3106         return 0;
3107 }
3108
3109 static int vop_set_writeback(struct rk_lcdc_driver *dev_drv)
3110 {
3111         struct vop_device *vop_dev =
3112             container_of(dev_drv, struct vop_device, driver);
3113         int output_color = dev_drv->output_color;
3114         struct rk_screen *screen = dev_drv->cur_screen;
3115         struct rk_fb_reg_wb_data *wb_data;
3116         int xact = screen->mode.xres;
3117         int yact = screen->mode.yres;
3118         u32 fmt_cfg;
3119         int xsize, ysize;
3120         u64 v;
3121
3122         if (unlikely(!vop_dev->clk_on)) {
3123                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
3124                 return 0;
3125         }
3126         wb_data = &dev_drv->wb_data;
3127         if ((wb_data->xsize == 0) || (wb_data->ysize == 0))
3128                 return 0;
3129
3130         xsize = wb_data->xsize;
3131         ysize = wb_data->ysize;
3132
3133         /*
3134          * RGB overlay mode support ARGB888, RGB888, RGB565, NV12,
3135          * but YUV overlay mode only support NV12, it's hard to judge RGB
3136          * or YUV overlay mode by userspace, so here force only support
3137          * NV12 mode.
3138          */
3139         if (wb_data->data_format != YUV420 && output_color != COLOR_RGB) {
3140                 pr_err("writeback only support NV12 when overlay is not RGB\n");
3141                 return -EINVAL;
3142         }
3143
3144         if (ysize != yact && ysize != (yact / 2)) {
3145                 pr_err("WriteBack only support yact=%d, ysize=%d\n",
3146                        yact, ysize);
3147                 return -EINVAL;
3148         }
3149
3150         switch (wb_data->data_format) {
3151         case ARGB888:
3152         case ABGR888:
3153         case XRGB888:
3154         case XBGR888:
3155                 fmt_cfg = 0;
3156                 break;
3157         case RGB888:
3158         case BGR888:
3159                 fmt_cfg = 1;
3160                 break;
3161         case RGB565:
3162         case BGR565:
3163                 fmt_cfg = 2;
3164                 break;
3165         case YUV420:
3166                 fmt_cfg = 8;
3167                 break;
3168         default:
3169                 pr_info("unsupport fmt: %d\n", wb_data->data_format);
3170                 return -EINVAL;
3171         }
3172
3173         v = V_WB_EN(wb_data->state) | V_WB_FMT(fmt_cfg) | V_WB_RGB2YUV_MODE(1) |
3174                 V_WB_XPSD_BIL_EN(xact != xsize) |
3175                 V_WB_YTHROW_EN(ysize == (yact / 2)) |
3176                 V_WB_YTHROW_MODE(0);
3177
3178         v |= V_WB_RGB2YUV_EN((output_color == COLOR_RGB) &&
3179                              (wb_data->data_format == YUV420));
3180
3181         vop_msk_reg(vop_dev, WB_CTRL0, v);
3182
3183         v = V_WB_WIDTH(xsize) | V_WB_XPSD_BIL_FACTOR((xact << 12) / xsize);
3184
3185         vop_msk_reg(vop_dev, WB_CTRL1, v);
3186
3187         vop_writel(vop_dev, WB_YRGB_MST, wb_data->smem_start);
3188         if (wb_data->data_format == YUV420)
3189                 vop_writel(vop_dev, WB_CBR_MST, wb_data->smem_start);
3190
3191         return 0;
3192 }
3193
3194 static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
3195                      unsigned long arg, int win_id)
3196 {
3197         struct vop_device *vop_dev =
3198                         container_of(dev_drv, struct vop_device, driver);
3199         u32 panel_size[2];
3200         void __user *argp = (void __user *)arg;
3201         struct color_key_cfg clr_key_cfg;
3202
3203         switch (cmd) {
3204         case RK_FBIOGET_PANEL_SIZE:
3205                 panel_size[0] = vop_dev->screen->mode.xres;
3206                 panel_size[1] = vop_dev->screen->mode.yres;
3207                 if (copy_to_user(argp, panel_size, 8))
3208                         return -EFAULT;
3209                 break;
3210         case RK_FBIOPUT_COLOR_KEY_CFG:
3211                 if (copy_from_user(&clr_key_cfg, argp, sizeof(clr_key_cfg)))
3212                         return -EFAULT;
3213                 vop_clr_key_cfg(dev_drv);
3214                 vop_writel(vop_dev, WIN0_COLOR_KEY,
3215                            clr_key_cfg.win0_color_key_cfg);
3216                 vop_writel(vop_dev, WIN1_COLOR_KEY,
3217                            clr_key_cfg.win1_color_key_cfg);
3218                 break;
3219
3220         default:
3221                 break;
3222         }
3223         return 0;
3224 }
3225
3226 static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv)
3227 {
3228         struct vop_device *vop_dev = container_of(dev_drv,
3229                                                     struct vop_device, driver);
3230         struct device_node *backlight;
3231         struct property *prop;
3232         u32 *brightness_levels;
3233         u32 length, max, last;
3234
3235         if (vop_dev->backlight)
3236                 return 0;
3237         backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0);
3238         if (backlight) {
3239                 vop_dev->backlight = of_find_backlight_by_node(backlight);
3240                 if (!vop_dev->backlight)
3241                         dev_info(vop_dev->dev, "No find backlight device\n");
3242         } else {
3243                 dev_info(vop_dev->dev, "No find backlight device node\n");
3244         }
3245         prop = of_find_property(backlight, "brightness-levels", &length);
3246         if (!prop)
3247                 return -EINVAL;
3248         max = length / sizeof(u32);
3249         last = max - 1;
3250         brightness_levels = kmalloc(256, GFP_KERNEL);
3251         if (brightness_levels)
3252                 return -ENOMEM;
3253
3254         if (!of_property_read_u32_array(backlight, "brightness-levels",
3255                                         brightness_levels, max)) {
3256                 if (brightness_levels[0] > brightness_levels[last])
3257                         dev_drv->cabc_pwm_pol = 1;/*negative*/
3258                 else
3259                         dev_drv->cabc_pwm_pol = 0;/*positive*/
3260         } else {
3261                 dev_info(vop_dev->dev,
3262                          "Can not read brightness-levels value\n");
3263         }
3264
3265         kfree(brightness_levels);
3266
3267         return 0;
3268 }
3269
3270 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv)
3271 {
3272         struct vop_device *vop_dev =
3273             container_of(dev_drv, struct vop_device, driver);
3274
3275         if (dev_drv->suspend_flag)
3276                 return 0;
3277
3278         dev_drv->suspend_flag = 1;
3279         /* ensure suspend_flag take effect on multi process */
3280         smp_wmb();
3281         flush_kthread_worker(&dev_drv->update_regs_worker);
3282
3283         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
3284                 dev_drv->trsm_ops->disable();
3285
3286         if (likely(vop_dev->clk_on)) {
3287                 spin_lock(&vop_dev->reg_lock);
3288                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(1));
3289                 vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
3290                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(1));
3291                 vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1));
3292                 vop_cfg_done(vop_dev);
3293
3294                 if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3295                         mdelay(50);
3296                         rockchip_iovmm_deactivate(dev_drv->dev);
3297                 }
3298
3299                 spin_unlock(&vop_dev->reg_lock);
3300         }
3301
3302         vop_clk_disable(vop_dev);
3303         rk_disp_pwr_disable(dev_drv);
3304
3305         return 0;
3306 }
3307
3308 static int vop_early_resume(struct rk_lcdc_driver *dev_drv)
3309 {
3310         struct vop_device *vop_dev =
3311             container_of(dev_drv, struct vop_device, driver);
3312
3313         if (!dev_drv->suspend_flag)
3314                 return 0;
3315         rk_disp_pwr_enable(dev_drv);
3316
3317         vop_clk_enable(vop_dev);
3318         spin_lock(&vop_dev->reg_lock);
3319         memcpy(vop_dev->regs, vop_dev->regsbak, vop_dev->len);
3320         spin_unlock(&vop_dev->reg_lock);
3321
3322         vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
3323         vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
3324         spin_lock(&vop_dev->reg_lock);
3325
3326         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(0));
3327         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(0));
3328         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(0));
3329         vop_cfg_done(vop_dev);
3330         spin_unlock(&vop_dev->reg_lock);
3331
3332         if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3333                 /* win address maybe effect after next frame start,
3334                  * but mmu maybe effect right now, so we delay 50ms
3335                  */
3336                 mdelay(50);
3337                 rockchip_iovmm_activate(dev_drv->dev);
3338         }
3339
3340         dev_drv->suspend_flag = 0;
3341
3342         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
3343                 dev_drv->trsm_ops->enable();
3344
3345         return 0;
3346 }
3347
3348 static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode)
3349 {
3350         switch (blank_mode) {
3351         case FB_BLANK_UNBLANK:
3352                 vop_early_resume(dev_drv);
3353                 break;
3354         case FB_BLANK_NORMAL:
3355                 vop_early_suspend(dev_drv);
3356                 break;
3357         default:
3358                 vop_early_suspend(dev_drv);
3359                 break;
3360         }
3361
3362         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
3363
3364         return 0;
3365 }
3366
3367 static int vop_get_win_state(struct rk_lcdc_driver *dev_drv,
3368                              int win_id, int area_id)
3369 {
3370         struct vop_device *vop_dev =
3371                         container_of(dev_drv, struct vop_device, driver);
3372         u32 area_status = 0, state = 0;
3373
3374         switch (win_id) {
3375         case 0:
3376                 area_status = vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
3377                 break;
3378         case 1:
3379                 area_status = vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
3380                 break;
3381         case 2:
3382                 if (area_id == 0)
3383                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3384                                                    V_WIN2_MST0_EN(0));
3385                 if (area_id == 1)
3386                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3387                                                    V_WIN2_MST1_EN(0));
3388                 if (area_id == 2)
3389                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3390                                                    V_WIN2_MST2_EN(0));
3391                 if (area_id == 3)
3392                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3393                                                    V_WIN2_MST3_EN(0));
3394                 break;
3395         case 3:
3396                 if (area_id == 0)
3397                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3398                                                    V_WIN3_MST0_EN(0));
3399                 if (area_id == 1)
3400                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3401                                                    V_WIN3_MST1_EN(0));
3402                 if (area_id == 2)
3403                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3404                                                    V_WIN3_MST2_EN(0));
3405                 if (area_id == 3)
3406                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3407                                                    V_WIN3_MST3_EN(0));
3408                 break;
3409         case 4:
3410                 area_status = vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0));
3411                 break;
3412         default:
3413                 pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n",
3414                        __func__, win_id, area_id);
3415                 break;
3416         }
3417
3418         state = (area_status > 0) ? 1 : 0;
3419         return state;
3420 }
3421
3422 static int vop_get_area_num(struct rk_lcdc_driver *dev_drv,
3423                             unsigned int *area_support)
3424 {
3425         struct vop_device *vop_dev =
3426             container_of(dev_drv, struct vop_device, driver);
3427
3428         area_support[0] = 1;
3429         area_support[1] = 1;
3430
3431         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
3432                 area_support[2] = 4;
3433                 area_support[3] = 4;
3434         }
3435
3436         return 0;
3437 }
3438
3439 /*overlay will be do at regupdate*/
3440 static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set)
3441 {
3442         struct vop_device *vop_dev =
3443             container_of(dev_drv, struct vop_device, driver);
3444         struct rk_lcdc_win *win = NULL;
3445         int i, ovl;
3446         u64 val;
3447         int z_order_num = 0;
3448         int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3449
3450         if (swap == 0) {
3451                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3452                         win = dev_drv->win[i];
3453                         if (win->state == 1)
3454                                 z_order_num++;
3455                 }
3456                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3457                         win = dev_drv->win[i];
3458                         if (win->state == 0)
3459                                 win->z_order = z_order_num++;
3460                         switch (win->z_order) {
3461                         case 0:
3462                                 layer0_sel = win->id;
3463                                 break;
3464                         case 1:
3465                                 layer1_sel = win->id;
3466                                 break;
3467                         case 2:
3468                                 layer2_sel = win->id;
3469                                 break;
3470                         case 3:
3471                                 layer3_sel = win->id;
3472                                 break;
3473                         default:
3474                                 break;
3475                         }
3476                 }
3477         } else {
3478                 layer0_sel = swap % 10;
3479                 layer1_sel = swap / 10 % 10;
3480                 layer2_sel = swap / 100 % 10;
3481                 layer3_sel = swap / 1000;
3482         }
3483
3484         spin_lock(&vop_dev->reg_lock);
3485         if (vop_dev->clk_on) {
3486                 if (set) {
3487                         val = V_DSP_LAYER0_SEL(layer0_sel) |
3488                             V_DSP_LAYER1_SEL(layer1_sel) |
3489                             V_DSP_LAYER2_SEL(layer2_sel) |
3490                             V_DSP_LAYER3_SEL(layer3_sel);
3491                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
3492                 } else {
3493                         layer0_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3494                                                   V_DSP_LAYER0_SEL(0));
3495                         layer1_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3496                                                   V_DSP_LAYER1_SEL(0));
3497                         layer2_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3498                                                   V_DSP_LAYER2_SEL(0));
3499                         layer3_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3500                                                   V_DSP_LAYER3_SEL(0));
3501                         ovl = layer3_sel * 1000 + layer2_sel * 100 +
3502                             layer1_sel * 10 + layer0_sel;
3503                 }
3504         } else {
3505                 ovl = -EPERM;
3506         }
3507         spin_unlock(&vop_dev->reg_lock);
3508
3509         return ovl;
3510 }
3511
3512 static char *vop_format_to_string(int format, char *fmt)
3513 {
3514         if (!fmt)
3515                 return NULL;
3516
3517         switch (format) {
3518         case 0:
3519                 strcpy(fmt, "ARGB888");
3520                 break;
3521         case 1:
3522                 strcpy(fmt, "RGB888");
3523                 break;
3524         case 2:
3525                 strcpy(fmt, "RGB565");
3526                 break;
3527         case 4:
3528                 strcpy(fmt, "YCbCr420");
3529                 break;
3530         case 5:
3531                 strcpy(fmt, "YCbCr422");
3532                 break;
3533         case 6:
3534                 strcpy(fmt, "YCbCr444");
3535         case 8:
3536                 strcpy(fmt, "YUYV422");
3537                 break;
3538         case 9:
3539                 strcpy(fmt, "YUYV420");
3540                 break;
3541         case 10:
3542                 strcpy(fmt, "UYVY422");
3543                 break;
3544         case 11:
3545                 strcpy(fmt, "UYVY420");
3546                 break;
3547         default:
3548                 strcpy(fmt, "invalid\n");
3549                 break;
3550         }
3551         return fmt;
3552 }
3553
3554 static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
3555                                  char *buf, int win_id)
3556 {
3557         struct vop_device *vop_dev =
3558             container_of(dev_drv, struct vop_device, driver);
3559         struct rk_screen *screen = dev_drv->cur_screen;
3560         u16 hsync_len = screen->mode.hsync_len;
3561         u16 left_margin = screen->mode.left_margin;
3562         u16 vsync_len = screen->mode.vsync_len;
3563         u16 upper_margin = screen->mode.upper_margin;
3564         u32 h_pw_bp = hsync_len + left_margin;
3565         u32 v_pw_bp = vsync_len + upper_margin;
3566         u32 fmt_id;
3567         char format_w0[9] = "NULL";
3568         char format_w1[9] = "NULL";
3569         char format_w2_0[9] = "NULL";
3570         char format_w2_1[9] = "NULL";
3571         char format_w2_2[9] = "NULL";
3572         char format_w2_3[9] = "NULL";
3573         char format_w3_0[9] = "NULL";
3574         char format_w3_1[9] = "NULL";
3575         char format_w3_2[9] = "NULL";
3576         char format_w3_3[9] = "NULL";
3577         char dsp_buf[100];
3578         u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
3579         u32 y_factor, uv_factor;
3580         u8 layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3581         u8 w0_state, w1_state, w2_state, w3_state;
3582         u8 w2_0_state, w2_1_state, w2_2_state, w2_3_state;
3583         u8 w3_0_state, w3_1_state, w3_2_state, w3_3_state;
3584
3585         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
3586         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
3587         u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
3588         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
3589         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
3590         u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
3591
3592         u32 w2_0_vir_y, w2_1_vir_y, w2_2_vir_y, w2_3_vir_y;
3593         u32 w2_0_dsp_x, w2_1_dsp_x, w2_2_dsp_x, w2_3_dsp_x;
3594         u32 w2_0_dsp_y, w2_1_dsp_y, w2_2_dsp_y, w2_3_dsp_y;
3595         u32 w2_0_st_x = h_pw_bp, w2_1_st_x = h_pw_bp;
3596         u32 w2_2_st_x = h_pw_bp, w2_3_st_x = h_pw_bp;
3597         u32 w2_0_st_y = v_pw_bp, w2_1_st_y = v_pw_bp;
3598         u32 w2_2_st_y = v_pw_bp, w2_3_st_y = v_pw_bp;
3599
3600         u32 w3_0_vir_y, w3_1_vir_y, w3_2_vir_y, w3_3_vir_y;
3601         u32 w3_0_dsp_x, w3_1_dsp_x, w3_2_dsp_x, w3_3_dsp_x;
3602         u32 w3_0_dsp_y, w3_1_dsp_y, w3_2_dsp_y, w3_3_dsp_y;
3603         u32 w3_0_st_x = h_pw_bp, w3_1_st_x = h_pw_bp;
3604         u32 w3_2_st_x = h_pw_bp, w3_3_st_x = h_pw_bp;
3605         u32 w3_0_st_y = v_pw_bp, w3_1_st_y = v_pw_bp;
3606         u32 w3_2_st_y = v_pw_bp, w3_3_st_y = v_pw_bp;
3607         u32 dclk_freq;
3608         int size = 0;
3609
3610         dclk_freq = screen->mode.pixclock;
3611         /*vop_reg_dump(dev_drv); */
3612
3613         spin_lock(&vop_dev->reg_lock);
3614         if (vop_dev->clk_on) {
3615                 zorder = vop_readl(vop_dev, DSP_CTRL1);
3616                 layer0_sel = (zorder & MASK(DSP_LAYER0_SEL)) >> 8;
3617                 layer1_sel = (zorder & MASK(DSP_LAYER1_SEL)) >> 10;
3618                 layer2_sel = (zorder & MASK(DSP_LAYER2_SEL)) >> 12;
3619                 layer3_sel = (zorder & MASK(DSP_LAYER3_SEL)) >> 14;
3620                 /* WIN0 */
3621                 win_ctrl = vop_readl(vop_dev, WIN0_CTRL0);
3622                 w0_state = win_ctrl & MASK(WIN0_EN);
3623                 fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1;
3624                 fmt_id |= (win_ctrl & MASK(WIN0_YUYV)) >> 14; /* yuyv*/
3625                 vop_format_to_string(fmt_id, format_w0);
3626                 vir_info = vop_readl(vop_dev, WIN0_VIR);
3627                 act_info = vop_readl(vop_dev, WIN0_ACT_INFO);
3628                 dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO);
3629                 dsp_st = vop_readl(vop_dev, WIN0_DSP_ST);
3630                 y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB);
3631                 uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR);
3632                 w0_vir_y = vir_info & MASK(WIN0_VIR_STRIDE);
3633                 w0_vir_uv = (vir_info & MASK(WIN0_VIR_STRIDE_UV)) >> 16;
3634                 w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1;
3635                 w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
3636                 w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1;
3637                 w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
3638                 if (w0_state) {
3639                         w0_st_x = dsp_st & MASK(WIN0_DSP_XST);
3640                         w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16;
3641                 }
3642                 w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB);
3643                 w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16;
3644                 w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR);
3645                 w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16;
3646
3647                 /* WIN1 */
3648                 win_ctrl = vop_readl(vop_dev, WIN1_CTRL0);
3649                 w1_state = win_ctrl & MASK(WIN1_EN);
3650                 fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1;
3651                 fmt_id |= (win_ctrl & MASK(WIN1_YUYV)) >> 14; /* yuyv*/
3652                 vop_format_to_string(fmt_id, format_w1);
3653                 vir_info = vop_readl(vop_dev, WIN1_VIR);
3654                 act_info = vop_readl(vop_dev, WIN1_ACT_INFO);
3655                 dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO);
3656                 dsp_st = vop_readl(vop_dev, WIN1_DSP_ST);
3657                 y_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_YRGB);
3658                 uv_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_CBR);
3659                 w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE);
3660                 w1_vir_uv = (vir_info & MASK(WIN1_VIR_STRIDE_UV)) >> 16;
3661                 w1_act_x = (act_info & MASK(WIN1_ACT_WIDTH)) + 1;
3662                 w1_act_y = ((act_info & MASK(WIN1_ACT_HEIGHT)) >> 16) + 1;
3663                 w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1;
3664                 w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1;
3665                 if (w1_state) {
3666                         w1_st_x = dsp_st & MASK(WIN1_DSP_XST);
3667                         w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16;
3668                 }
3669                 w1_y_h_fac = y_factor & MASK(WIN1_HS_FACTOR_YRGB);
3670                 w1_y_v_fac = (y_factor & MASK(WIN1_VS_FACTOR_YRGB)) >> 16;
3671                 w1_uv_h_fac = uv_factor & MASK(WIN1_HS_FACTOR_CBR);
3672                 w1_uv_v_fac = (uv_factor & MASK(WIN1_VS_FACTOR_CBR)) >> 16;
3673
3674                 /*WIN2 */
3675                 win_ctrl = vop_readl(vop_dev, WIN2_CTRL0);
3676                 w2_state = win_ctrl & MASK(WIN2_EN);
3677                 w2_0_state = (win_ctrl & 0x10) >> 4;
3678                 w2_1_state = (win_ctrl & 0x100) >> 8;
3679                 w2_2_state = (win_ctrl & 0x1000) >> 12;
3680                 w2_3_state = (win_ctrl & 0x10000) >> 16;
3681                 vir_info = vop_readl(vop_dev, WIN2_VIR0_1);
3682                 w2_0_vir_y = vir_info & MASK(WIN2_VIR_STRIDE0);
3683                 w2_1_vir_y = (vir_info & MASK(WIN2_VIR_STRIDE1)) >> 16;
3684                 vir_info = vop_readl(vop_dev, WIN2_VIR2_3);
3685                 w2_2_vir_y = vir_info & MASK(WIN2_VIR_STRIDE2);
3686                 w2_3_vir_y = (vir_info & MASK(WIN2_VIR_STRIDE3)) >> 16;
3687
3688                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT0)) >> 5;
3689                 vop_format_to_string(fmt_id, format_w2_0);
3690                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT1)) >> 9;
3691                 vop_format_to_string(fmt_id, format_w2_1);
3692                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT2)) >> 13;
3693                 vop_format_to_string(fmt_id, format_w2_2);
3694                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT3)) >> 17;
3695                 vop_format_to_string(fmt_id, format_w2_3);
3696
3697                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO0);
3698                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST0);
3699                 w2_0_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH0)) + 1;
3700                 w2_0_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT0)) >> 16) + 1;
3701                 if (w2_0_state) {
3702                         w2_0_st_x = dsp_st & MASK(WIN2_DSP_XST0);
3703                         w2_0_st_y = (dsp_st & MASK(WIN2_DSP_YST0)) >> 16;
3704                 }
3705                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO1);
3706                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST1);
3707                 w2_1_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH1)) + 1;
3708                 w2_1_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT1)) >> 16) + 1;
3709                 if (w2_1_state) {
3710                         w2_1_st_x = dsp_st & MASK(WIN2_DSP_XST1);
3711                         w2_1_st_y = (dsp_st & MASK(WIN2_DSP_YST1)) >> 16;
3712                 }
3713                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO2);
3714                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST2);
3715                 w2_2_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH2)) + 1;
3716                 w2_2_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT2)) >> 16) + 1;
3717                 if (w2_2_state) {
3718                         w2_2_st_x = dsp_st & MASK(WIN2_DSP_XST2);
3719                         w2_2_st_y = (dsp_st & MASK(WIN2_DSP_YST2)) >> 16;
3720                 }
3721                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO3);
3722                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST3);
3723                 w2_3_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH3)) + 1;
3724                 w2_3_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT3)) >> 16) + 1;
3725                 if (w2_3_state) {
3726                         w2_3_st_x = dsp_st & MASK(WIN2_DSP_XST3);
3727                         w2_3_st_y = (dsp_st & MASK(WIN2_DSP_YST3)) >> 16;
3728                 }
3729
3730                 /*WIN3 */
3731                 win_ctrl = vop_readl(vop_dev, WIN3_CTRL0);
3732                 w3_state = win_ctrl & MASK(WIN3_EN);
3733                 w3_0_state = (win_ctrl & 0x10) >> 4;
3734                 w3_1_state = (win_ctrl & 0x100) >> 8;
3735                 w3_2_state = (win_ctrl & 0x1000) >> 12;
3736                 w3_3_state = (win_ctrl & 0x10000) >> 16;
3737                 vir_info = vop_readl(vop_dev, WIN3_VIR0_1);
3738                 w3_0_vir_y = vir_info & MASK(WIN3_VIR_STRIDE0);
3739                 w3_1_vir_y = (vir_info & MASK(WIN3_VIR_STRIDE1)) >> 16;
3740                 vir_info = vop_readl(vop_dev, WIN3_VIR2_3);
3741                 w3_2_vir_y = vir_info & MASK(WIN3_VIR_STRIDE2);
3742                 w3_3_vir_y = (vir_info & MASK(WIN3_VIR_STRIDE3)) >> 16;
3743
3744                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT0)) >> 5;
3745                 vop_format_to_string(fmt_id, format_w3_0);
3746                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT1)) >> 9;
3747                 vop_format_to_string(fmt_id, format_w3_1);
3748                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT2)) >> 13;
3749                 vop_format_to_string(fmt_id, format_w3_2);
3750                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT3)) >> 17;
3751                 vop_format_to_string(fmt_id, format_w3_3);
3752
3753                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO0);
3754                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST0);
3755                 w3_0_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH0)) + 1;
3756                 w3_0_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT0)) >> 16) + 1;
3757                 if (w3_0_state) {
3758                         w3_0_st_x = dsp_st & MASK(WIN3_DSP_XST0);
3759                         w3_0_st_y = (dsp_st & MASK(WIN3_DSP_YST0)) >> 16;
3760                 }
3761                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO1);
3762                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST1);
3763                 w3_1_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH1)) + 1;
3764                 w3_1_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT1)) >> 16) + 1;
3765                 if (w3_1_state) {
3766                         w3_1_st_x = dsp_st & MASK(WIN3_DSP_XST1);
3767                         w3_1_st_y = (dsp_st & MASK(WIN3_DSP_YST1)) >> 16;
3768                 }
3769                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO2);
3770                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST2);
3771                 w3_2_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH2)) + 1;
3772                 w3_2_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT2)) >> 16) + 1;
3773                 if (w3_2_state) {
3774                         w3_2_st_x = dsp_st & MASK(WIN3_DSP_XST2);
3775                         w3_2_st_y = (dsp_st & MASK(WIN3_DSP_YST2)) >> 16;
3776                 }
3777                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO3);
3778                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST3);
3779                 w3_3_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH3)) + 1;
3780                 w3_3_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT3)) >> 16) + 1;
3781                 if (w3_3_state) {
3782                         w3_3_st_x = dsp_st & MASK(WIN3_DSP_XST3);
3783                         w3_3_st_y = (dsp_st & MASK(WIN3_DSP_YST3)) >> 16;
3784                 }
3785         } else {
3786                 spin_unlock(&vop_dev->reg_lock);
3787                 return -EPERM;
3788         }
3789         spin_unlock(&vop_dev->reg_lock);
3790         size += snprintf(dsp_buf, 80,
3791                 "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
3792                 layer1_sel, layer0_sel, layer2_sel, layer3_sel);
3793         strcat(buf, dsp_buf);
3794         memset(dsp_buf, 0, sizeof(dsp_buf));
3795         /* win0 */
3796         size += snprintf(dsp_buf, 80,
3797                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3798                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
3799         strcat(buf, dsp_buf);
3800         memset(dsp_buf, 0, sizeof(dsp_buf));
3801
3802         size += snprintf(dsp_buf, 80,
3803                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3804                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
3805         strcat(buf, dsp_buf);
3806         memset(dsp_buf, 0, sizeof(dsp_buf));
3807
3808         size += snprintf(dsp_buf, 80,
3809                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3810                  w0_st_x - h_pw_bp, w0_st_y - v_pw_bp, w0_y_h_fac, w0_y_v_fac);
3811         strcat(buf, dsp_buf);
3812         memset(dsp_buf, 0, sizeof(dsp_buf));
3813
3814         size += snprintf(dsp_buf, 80,
3815                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3816                  w0_uv_h_fac, w0_uv_v_fac, vop_readl(vop_dev, WIN0_YRGB_MST),
3817                  vop_readl(vop_dev, WIN0_CBR_MST));
3818         strcat(buf, dsp_buf);
3819         memset(dsp_buf, 0, sizeof(dsp_buf));
3820
3821         /* win1 */
3822         size += snprintf(dsp_buf, 80,
3823                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3824                  w1_state, format_w1, w1_vir_y, w1_vir_uv);
3825         strcat(buf, dsp_buf);
3826         memset(dsp_buf, 0, sizeof(dsp_buf));
3827
3828         size += snprintf(dsp_buf, 80,
3829                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3830                  w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
3831         strcat(buf, dsp_buf);
3832         memset(dsp_buf, 0, sizeof(dsp_buf));
3833
3834         size += snprintf(dsp_buf, 80,
3835                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3836                  w1_st_x - h_pw_bp, w1_st_y - v_pw_bp, w1_y_h_fac, w1_y_v_fac);
3837         strcat(buf, dsp_buf);
3838         memset(dsp_buf, 0, sizeof(dsp_buf));
3839
3840         size += snprintf(dsp_buf, 80,
3841                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3842                  w1_uv_h_fac, w1_uv_v_fac, vop_readl(vop_dev, WIN1_YRGB_MST),
3843                  vop_readl(vop_dev, WIN1_CBR_MST));
3844         strcat(buf, dsp_buf);
3845         memset(dsp_buf, 0, sizeof(dsp_buf));
3846
3847         /*win2*/
3848         size += snprintf(dsp_buf, 80,
3849                  "win2:\n  state:%d\n",
3850                  w2_state);
3851         strcat(buf, dsp_buf);
3852         memset(dsp_buf, 0, sizeof(dsp_buf));
3853         /*area 0*/
3854         size += snprintf(dsp_buf, 80,
3855                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3856                  w2_0_state, format_w2_0, w2_0_dsp_x, w2_0_dsp_y);
3857         strcat(buf, dsp_buf);
3858         memset(dsp_buf, 0, sizeof(dsp_buf));
3859         size += snprintf(dsp_buf, 80,
3860                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3861                  w2_0_st_x - h_pw_bp, w2_0_st_y - v_pw_bp,
3862                  vop_readl(vop_dev, WIN2_MST0));
3863         strcat(buf, dsp_buf);
3864         memset(dsp_buf, 0, sizeof(dsp_buf));
3865
3866         /*area 1*/
3867         size += snprintf(dsp_buf, 80,
3868                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3869                  w2_1_state, format_w2_1, w2_1_dsp_x, w2_1_dsp_y);
3870         strcat(buf, dsp_buf);
3871         memset(dsp_buf, 0, sizeof(dsp_buf));
3872         size += snprintf(dsp_buf, 80,
3873                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3874                  w2_1_st_x - h_pw_bp, w2_1_st_y - v_pw_bp,
3875                  vop_readl(vop_dev, WIN2_MST1));
3876         strcat(buf, dsp_buf);
3877         memset(dsp_buf, 0, sizeof(dsp_buf));
3878
3879         /*area 2*/
3880         size += snprintf(dsp_buf, 80,
3881                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3882                  w2_2_state, format_w2_2, w2_2_dsp_x, w2_2_dsp_y);
3883         strcat(buf, dsp_buf);
3884         memset(dsp_buf, 0, sizeof(dsp_buf));
3885         size += snprintf(dsp_buf, 80,
3886                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3887                  w2_2_st_x - h_pw_bp, w2_2_st_y - v_pw_bp,
3888                  vop_readl(vop_dev, WIN2_MST2));
3889         strcat(buf, dsp_buf);
3890         memset(dsp_buf, 0, sizeof(dsp_buf));
3891
3892         /*area 3*/
3893         size += snprintf(dsp_buf, 80,
3894                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3895                  w2_3_state, format_w2_3, w2_3_dsp_x, w2_3_dsp_y);
3896         strcat(buf, dsp_buf);
3897         memset(dsp_buf, 0, sizeof(dsp_buf));
3898         size += snprintf(dsp_buf, 80,
3899                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3900                  w2_3_st_x - h_pw_bp, w2_3_st_y - v_pw_bp,
3901                  vop_readl(vop_dev, WIN2_MST3));
3902         strcat(buf, dsp_buf);
3903         memset(dsp_buf, 0, sizeof(dsp_buf));
3904
3905         /*win3*/
3906         size += snprintf(dsp_buf, 80,
3907                  "win3:\n  state:%d\n",
3908                  w3_state);
3909         strcat(buf, dsp_buf);
3910         memset(dsp_buf, 0, sizeof(dsp_buf));
3911         /*area 0*/
3912         size += snprintf(dsp_buf, 80,
3913                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3914                  w3_0_state, format_w3_0, w3_0_dsp_x, w3_0_dsp_y);
3915         strcat(buf, dsp_buf);
3916         memset(dsp_buf, 0, sizeof(dsp_buf));
3917         size += snprintf(dsp_buf, 80,
3918                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3919                  w3_0_st_x - h_pw_bp, w3_0_st_y - v_pw_bp,
3920                  vop_readl(vop_dev, WIN3_MST0));
3921         strcat(buf, dsp_buf);
3922         memset(dsp_buf, 0, sizeof(dsp_buf));
3923
3924         /*area 1*/
3925         size += snprintf(dsp_buf, 80,
3926                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3927                  w3_1_state, format_w3_1, w3_1_dsp_x, w3_1_dsp_y);
3928         strcat(buf, dsp_buf);
3929         memset(dsp_buf, 0, sizeof(dsp_buf));
3930         size += snprintf(dsp_buf, 80,
3931                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3932                  w3_1_st_x - h_pw_bp, w3_1_st_y - v_pw_bp,
3933                  vop_readl(vop_dev, WIN3_MST1));
3934         strcat(buf, dsp_buf);
3935         memset(dsp_buf, 0, sizeof(dsp_buf));
3936
3937         /*area 2*/
3938         size += snprintf(dsp_buf, 80,
3939                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3940                  w3_2_state, format_w3_2, w3_2_dsp_x, w3_2_dsp_y);
3941         strcat(buf, dsp_buf);
3942         memset(dsp_buf, 0, sizeof(dsp_buf));
3943         size += snprintf(dsp_buf, 80,
3944                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3945                  w3_2_st_x - h_pw_bp, w3_2_st_y - v_pw_bp,
3946                  vop_readl(vop_dev, WIN3_MST2));
3947         strcat(buf, dsp_buf);
3948         memset(dsp_buf, 0, sizeof(dsp_buf));
3949
3950         /*area 3*/
3951         size += snprintf(dsp_buf, 80,
3952                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3953                  w3_3_state, format_w3_3, w3_3_dsp_x, w3_3_dsp_y);
3954         strcat(buf, dsp_buf);
3955         memset(dsp_buf, 0, sizeof(dsp_buf));
3956         size += snprintf(dsp_buf, 80,
3957                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3958                  w3_3_st_x - h_pw_bp, w3_3_st_y - v_pw_bp,
3959                  vop_readl(vop_dev, WIN3_MST3));
3960         strcat(buf, dsp_buf);
3961         memset(dsp_buf, 0, sizeof(dsp_buf));
3962
3963         return size;
3964 }
3965
3966 static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set)
3967 {
3968         struct vop_device *vop_dev =
3969             container_of(dev_drv, struct vop_device, driver);
3970         struct rk_screen *screen = dev_drv->cur_screen;
3971         u64 ft = 0;
3972         u32 dotclk;
3973         int ret;
3974         u32 pixclock;
3975         u32 x_total, y_total;
3976
3977         if (set) {
3978                 if (fps == 0) {
3979                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
3980                         return 0;
3981                 }
3982                 ft = div_u64(1000000000000llu, fps);
3983                 x_total =
3984                     screen->mode.upper_margin + screen->mode.lower_margin +
3985                     screen->mode.yres + screen->mode.vsync_len;
3986                 y_total =
3987                     screen->mode.left_margin + screen->mode.right_margin +
3988                     screen->mode.xres + screen->mode.hsync_len;
3989                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
3990                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
3991                 ret = clk_set_rate(vop_dev->dclk, dotclk);
3992         }
3993
3994         pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
3995         vop_dev->pixclock = pixclock;
3996         dev_drv->pixclock = vop_dev->pixclock;
3997         fps = rk_fb_calc_fps(screen, pixclock);
3998         screen->ft = 1000 / fps;        /*one frame time in ms */
3999
4000         if (set)
4001                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
4002                          clk_get_rate(vop_dev->dclk), fps);
4003
4004         return fps;
4005 }
4006
4007 static int vop_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
4008 {
4009         mutex_lock(&dev_drv->fb_win_id_mutex);
4010         if (order == FB_DEFAULT_ORDER)
4011                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
4012         dev_drv->fb4_win_id = order / 10000;
4013         dev_drv->fb3_win_id = (order / 1000) % 10;
4014         dev_drv->fb2_win_id = (order / 100) % 10;
4015         dev_drv->fb1_win_id = (order / 10) % 10;
4016         dev_drv->fb0_win_id = order % 10;
4017         mutex_unlock(&dev_drv->fb_win_id_mutex);
4018
4019         return 0;
4020 }
4021
4022 static int vop_get_win_id(struct rk_lcdc_driver *dev_drv, const char *id)
4023 {
4024         int win_id = 0;
4025
4026         mutex_lock(&dev_drv->fb_win_id_mutex);
4027         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
4028                 win_id = dev_drv->fb0_win_id;
4029         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
4030                 win_id = dev_drv->fb1_win_id;
4031         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
4032                 win_id = dev_drv->fb2_win_id;
4033         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
4034                 win_id = dev_drv->fb3_win_id;
4035         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
4036                 win_id = dev_drv->fb4_win_id;
4037         mutex_unlock(&dev_drv->fb_win_id_mutex);
4038
4039         return win_id;
4040 }
4041
4042 static int vop_config_done(struct rk_lcdc_driver *dev_drv)
4043 {
4044         struct vop_device *vop_dev =
4045             container_of(dev_drv, struct vop_device, driver);
4046         int i, fbdc_en = 0;
4047         u64 val;
4048         struct rk_lcdc_win *win = NULL;
4049
4050         spin_lock(&vop_dev->reg_lock);
4051         vop_post_cfg(dev_drv);
4052         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby));
4053         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
4054                 win = dev_drv->win[i];
4055                 fbdc_en |= win->area[0].fbdc_en;
4056                 if ((win->state == 0) && (win->last_state == 1)) {
4057                         switch (win->id) {
4058                         case 0:
4059                                 val = V_WIN0_EN(0);
4060                                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
4061                                 break;
4062                         case 1:
4063                                 val = V_WIN1_EN(0);
4064                                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
4065                                 break;
4066                         case 2:
4067                                 val = V_WIN2_EN(0) | V_WIN2_MST0_EN(0) |
4068                                     V_WIN2_MST1_EN(0) |
4069                                     V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
4070                                 vop_msk_reg(vop_dev, WIN2_CTRL0, val);
4071                                 break;
4072                         case 3:
4073                                 val = V_WIN3_EN(0) | V_WIN3_MST0_EN(0) |
4074                                     V_WIN3_MST1_EN(0) |
4075                                     V_WIN3_MST2_EN(0) | V_WIN3_MST3_EN(0);
4076                                 vop_msk_reg(vop_dev, WIN3_CTRL0, val);
4077                                 break;
4078                         case 4:
4079                                 val = V_HWC_EN(0);
4080                                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
4081                                 break;
4082                         default:
4083                                 break;
4084                         }
4085                 }
4086                 win->last_state = win->state;
4087         }
4088         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
4089                 val = V_VOP_FBDC_EN(fbdc_en);
4090                 vop_msk_reg(vop_dev, AFBCD0_CTRL, val);
4091         }
4092         vop_cfg_done(vop_dev);
4093         spin_unlock(&vop_dev->reg_lock);
4094         return 0;
4095 }
4096
4097 static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
4098 {
4099         struct vop_device *vop_dev =
4100             container_of(dev_drv, struct vop_device, driver);
4101         spin_lock(&vop_dev->reg_lock);
4102         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(open));
4103         vop_cfg_done(vop_dev);
4104         spin_unlock(&vop_dev->reg_lock);
4105         return 0;
4106 }
4107
4108 static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
4109 {
4110         struct vop_device *vop_dev = container_of(dev_drv,
4111                                                     struct vop_device, driver);
4112         spin_lock(&vop_dev->reg_lock);
4113         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_LAYER_SEL(win_id));
4114         vop_cfg_done(vop_dev);
4115         spin_unlock(&vop_dev->reg_lock);
4116         return 0;
4117 }
4118
4119 static int vop_dpi_status(struct rk_lcdc_driver *dev_drv)
4120 {
4121         struct vop_device *vop_dev =
4122             container_of(dev_drv, struct vop_device, driver);
4123         int ovl;
4124
4125         spin_lock(&vop_dev->reg_lock);
4126         ovl = vop_read_bit(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(0));
4127         spin_unlock(&vop_dev->reg_lock);
4128         return ovl;
4129 }
4130
4131 static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
4132 {
4133         struct vop_device *vop_dev =
4134                         container_of(dev_drv, struct vop_device, driver);
4135         if (enable)
4136                 enable_irq(vop_dev->irq);
4137         else
4138                 disable_irq(vop_dev->irq);
4139         return 0;
4140 }
4141
4142 int vop_poll_vblank(struct rk_lcdc_driver *dev_drv)
4143 {
4144         struct vop_device *vop_dev =
4145             container_of(dev_drv, struct vop_device, driver);
4146         u32 int_reg;
4147         int ret;
4148
4149         if (vop_dev->clk_on && (!dev_drv->suspend_flag)) {
4150                 int_reg = vop_readl(vop_dev, INTR_STATUS0);
4151                 if (int_reg & INTR_LINE_FLAG0) {
4152                         vop_dev->driver.frame_time.last_framedone_t =
4153                             vop_dev->driver.frame_time.framedone_t;
4154                         vop_dev->driver.frame_time.framedone_t = cpu_clock(0);
4155                         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_LINE_FLAG0,
4156                                         INTR_LINE_FLAG0);
4157                         ret = RK_LF_STATUS_FC;
4158                 } else {
4159                         ret = RK_LF_STATUS_FR;
4160                 }
4161         } else {
4162                 ret = RK_LF_STATUS_NC;
4163         }
4164
4165         return ret;
4166 }
4167
4168 static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
4169                             unsigned int dsp_addr[][4])
4170 {
4171         struct vop_device *vop_dev =
4172             container_of(dev_drv, struct vop_device, driver);
4173         spin_lock(&vop_dev->reg_lock);
4174         if (vop_dev->clk_on) {
4175                 dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST);
4176                 dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST);
4177                 dsp_addr[2][0] = vop_readl(vop_dev, WIN2_MST0);
4178                 dsp_addr[2][1] = vop_readl(vop_dev, WIN2_MST1);
4179                 dsp_addr[2][2] = vop_readl(vop_dev, WIN2_MST2);
4180                 dsp_addr[2][3] = vop_readl(vop_dev, WIN2_MST3);
4181                 dsp_addr[3][0] = vop_readl(vop_dev, WIN3_MST0);
4182                 dsp_addr[3][1] = vop_readl(vop_dev, WIN3_MST1);
4183                 dsp_addr[3][2] = vop_readl(vop_dev, WIN3_MST2);
4184                 dsp_addr[3][3] = vop_readl(vop_dev, WIN3_MST3);
4185                 dsp_addr[4][0] = vop_readl(vop_dev, HWC_MST);
4186         }
4187         spin_unlock(&vop_dev->reg_lock);
4188         return 0;
4189 }
4190
4191
4192 int vop_update_pwm(int bl_pwm_period, int bl_pwm_duty)
4193 {
4194         /*
4195          * TODO:
4196          * pwm_period_hpr = bl_pwm_period;
4197          * pwm_duty_lpr = bl_pwm_duty;
4198          * pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n",
4199          * bl_pwm_period, bl_pwm_duty);
4200          */
4201
4202         return 0;
4203 }
4204
4205 /*
4206  *  a:[-30~0]:
4207  *    sin_hue = sin(a)*256 +0x100;
4208  *    cos_hue = cos(a)*256;
4209  *  a:[0~30]
4210  *    sin_hue = sin(a)*256;
4211  *    cos_hue = cos(a)*256;
4212  */
4213 static int vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode)
4214 {
4215         struct vop_device *vop_dev =
4216             container_of(dev_drv, struct vop_device, driver);
4217         u32 val;
4218
4219         spin_lock(&vop_dev->reg_lock);
4220         if (vop_dev->clk_on) {
4221                 val = vop_readl(vop_dev, BCSH_H);
4222                 switch (mode) {
4223                 case H_SIN:
4224                         val &= MASK(SIN_HUE);
4225                         break;
4226                 case H_COS:
4227                         val &= MASK(COS_HUE);
4228                         val >>= 16;
4229                         break;
4230                 default:
4231                         break;
4232                 }
4233         }
4234         spin_unlock(&vop_dev->reg_lock);
4235
4236         return val;
4237 }
4238
4239 static int vop_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode,
4240                             int calc, int up, int down, int global)
4241 {
4242         struct vop_device *vop_dev =
4243                         container_of(dev_drv, struct vop_device, driver);
4244         struct rk_screen *screen = dev_drv->cur_screen;
4245         u32 total_pixel, calc_pixel, stage_up, stage_down;
4246         u32 pixel_num, global_dn;
4247
4248         if (!vop_dev->cabc_lut_addr_base) {
4249                 pr_err("vop chip[%d] not supoort cabc\n", VOP_CHIP(vop_dev));
4250                 return 0;
4251         }
4252
4253         if (!screen->cabc_lut) {
4254                 pr_err("screen cabc lut not config, so not open cabc\n");
4255                 return 0;
4256         }
4257
4258         dev_drv->cabc_mode = mode;
4259         if (!dev_drv->cabc_mode) {
4260                 spin_lock(&vop_dev->reg_lock);
4261                 if (vop_dev->clk_on) {
4262                         vop_msk_reg(vop_dev, CABC_CTRL0,
4263                                     V_CABC_EN(0) | V_CABC_HANDLE_EN(0));
4264                         vop_cfg_done(vop_dev);
4265                 }
4266                 pr_info("mode = 0, close cabc\n");
4267                 spin_unlock(&vop_dev->reg_lock);
4268                 return 0;
4269         }
4270
4271         total_pixel = screen->mode.xres * screen->mode.yres;
4272         pixel_num = 1000 - calc;
4273         calc_pixel = (total_pixel * pixel_num) / 1000;
4274         stage_up = up;
4275         stage_down = down;
4276         global_dn = global;
4277         pr_info("enable cabc:mode=%d, calc=%d, up=%d, down=%d, global=%d\n",
4278                 mode, calc, stage_up, stage_down, global_dn);
4279
4280         spin_lock(&vop_dev->reg_lock);
4281         if (vop_dev->clk_on) {
4282                 u64 val = 0;
4283
4284                 val = V_CABC_EN(1) | V_CABC_HANDLE_EN(1) |
4285                         V_PWM_CONFIG_MODE(STAGE_BY_STAGE) |
4286                         V_CABC_CALC_PIXEL_NUM(calc_pixel);
4287                 vop_msk_reg(vop_dev, CABC_CTRL0, val);
4288
4289                 val = V_CABC_LUT_EN(1) | V_CABC_TOTAL_NUM(total_pixel);
4290                 vop_msk_reg(vop_dev, CABC_CTRL1, val);
4291
4292                 val = V_CABC_STAGE_DOWN(stage_down) |
4293                         V_CABC_STAGE_UP(stage_up) |
4294                         V_CABC_STAGE_UP_MODE(0) | V_MAX_SCALE_CFG_VALUE(1) |
4295                         V_MAX_SCALE_CFG_ENABLE(0);
4296                 vop_msk_reg(vop_dev, CABC_CTRL2, val);
4297
4298                 val = V_CABC_GLOBAL_DN(global_dn) |
4299                         V_CABC_GLOBAL_DN_LIMIT_EN(1);
4300                 vop_msk_reg(vop_dev, CABC_CTRL3, val);
4301                 vop_cfg_done(vop_dev);
4302         }
4303         spin_unlock(&vop_dev->reg_lock);
4304
4305         return 0;
4306 }
4307
4308 static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4309                             int sin_hue, int cos_hue)
4310 {
4311         struct vop_device *vop_dev =
4312             container_of(dev_drv, struct vop_device, driver);
4313         u64 val;
4314
4315         spin_lock(&vop_dev->reg_lock);
4316         if (vop_dev->clk_on) {
4317                 val = V_SIN_HUE(sin_hue) | V_COS_HUE(cos_hue);
4318                 vop_msk_reg(vop_dev, BCSH_H, val);
4319                 vop_cfg_done(vop_dev);
4320         }
4321         spin_unlock(&vop_dev->reg_lock);
4322
4323         return 0;
4324 }
4325
4326 static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4327                             bcsh_bcs_mode mode, int value)
4328 {
4329         struct vop_device *vop_dev =
4330             container_of(dev_drv, struct vop_device, driver);
4331         u64 val;
4332
4333         spin_lock(&vop_dev->reg_lock);
4334         if (vop_dev->clk_on) {
4335                 switch (mode) {
4336                 case BRIGHTNESS:
4337                         /*from 0 to 255,typical is 128 */
4338                         if (value < 0x80)
4339                                 value += 0x80;
4340                         else if (value >= 0x80)
4341                                 value = value - 0x80;
4342                         val = V_BRIGHTNESS(value);
4343                         break;
4344                 case CONTRAST:
4345                         /*from 0 to 510,typical is 256 */
4346                         val = V_CONTRAST(value);
4347                         break;
4348                 case SAT_CON:
4349                         /*from 0 to 1015,typical is 256 */
4350                         val = V_SAT_CON(value);
4351                         break;
4352                 default:
4353                         break;
4354                 }
4355                 vop_msk_reg(vop_dev, BCSH_BCS, val);
4356                 vop_cfg_done(vop_dev);
4357         }
4358         spin_unlock(&vop_dev->reg_lock);
4359
4360         return val;
4361 }
4362
4363 static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode)
4364 {
4365         struct vop_device *vop_dev =
4366             container_of(dev_drv, struct vop_device, driver);
4367         u64 val;
4368
4369         spin_lock(&vop_dev->reg_lock);
4370         if (vop_dev->clk_on) {
4371                 val = vop_readl(vop_dev, BCSH_BCS);
4372                 switch (mode) {
4373                 case BRIGHTNESS:
4374                         val &= MASK(BRIGHTNESS);
4375                         if (val > 0x80)
4376                                 val -= 0x80;
4377                         else
4378                                 val += 0x80;
4379                         break;
4380                 case CONTRAST:
4381                         val &= MASK(CONTRAST);
4382                         val >>= 8;
4383                         break;
4384                 case SAT_CON:
4385                         val &= MASK(SAT_CON);
4386                         val >>= 20;
4387                         break;
4388                 default:
4389                         break;
4390                 }
4391         }
4392         spin_unlock(&vop_dev->reg_lock);
4393         return val;
4394 }
4395
4396 static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
4397 {
4398         struct vop_device *vop_dev =
4399             container_of(dev_drv, struct vop_device, driver);
4400
4401         spin_lock(&vop_dev->reg_lock);
4402         if (vop_dev->clk_on) {
4403                 if (open) {
4404                         vop_writel(vop_dev, BCSH_COLOR_BAR, 0x1);
4405                         vop_writel(vop_dev, BCSH_BCS, 0xd0010000);
4406                         vop_writel(vop_dev, BCSH_H, 0x01000000);
4407                         dev_drv->bcsh.enable = 1;
4408                 } else {
4409                         vop_msk_reg(vop_dev, BCSH_COLOR_BAR, V_BCSH_EN(0));
4410                         dev_drv->bcsh.enable = 0;
4411                 }
4412                 vop_bcsh_path_sel(dev_drv);
4413                 vop_cfg_done(vop_dev);
4414         }
4415         spin_unlock(&vop_dev->reg_lock);
4416
4417         return 0;
4418 }
4419
4420 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
4421 {
4422         if (!enable || !dev_drv->bcsh.enable) {
4423                 vop_open_bcsh(dev_drv, false);
4424                 return 0;
4425         }
4426
4427         if (dev_drv->bcsh.brightness <= 255 ||
4428             dev_drv->bcsh.contrast <= 510 ||
4429             dev_drv->bcsh.sat_con <= 1015 ||
4430             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
4431                 vop_open_bcsh(dev_drv, true);
4432                 if (dev_drv->bcsh.brightness <= 255)
4433                         vop_set_bcsh_bcs(dev_drv, BRIGHTNESS,
4434                                          dev_drv->bcsh.brightness);
4435                 if (dev_drv->bcsh.contrast <= 510)
4436                         vop_set_bcsh_bcs(dev_drv, CONTRAST,
4437                                          dev_drv->bcsh.contrast);
4438                 if (dev_drv->bcsh.sat_con <= 1015)
4439                         vop_set_bcsh_bcs(dev_drv, SAT_CON,
4440                                          dev_drv->bcsh.sat_con);
4441                 if (dev_drv->bcsh.sin_hue <= 511 &&
4442                     dev_drv->bcsh.cos_hue <= 511)
4443                         vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue,
4444                                          dev_drv->bcsh.cos_hue);
4445         }
4446
4447         return 0;
4448 }
4449
4450 static int __maybe_unused
4451 vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
4452 {
4453         struct vop_device *vop_dev =
4454             container_of(dev_drv, struct vop_device, driver);
4455
4456         if (enable) {
4457                 spin_lock(&vop_dev->reg_lock);
4458                 if (likely(vop_dev->clk_on)) {
4459                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1));
4460                         vop_cfg_done(vop_dev);
4461                 }
4462                 spin_unlock(&vop_dev->reg_lock);
4463         } else {
4464                 spin_lock(&vop_dev->reg_lock);
4465                 if (likely(vop_dev->clk_on)) {
4466                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0));
4467
4468                         vop_cfg_done(vop_dev);
4469                 }
4470                 spin_unlock(&vop_dev->reg_lock);
4471         }
4472
4473         return 0;
4474 }
4475
4476 static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable)
4477 {
4478         struct vop_device *vop_dev =
4479             container_of(dev_drv, struct vop_device, driver);
4480
4481         if (unlikely(!vop_dev->clk_on)) {
4482                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4483                 return 0;
4484         }
4485         vop_get_backlight_device(dev_drv);
4486
4487         if (enable) {
4488                 /* close the backlight */
4489                 if (vop_dev->backlight) {
4490                         vop_dev->backlight->props.power = FB_BLANK_POWERDOWN;
4491                         backlight_update_status(vop_dev->backlight);
4492                 }
4493                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4494                         dev_drv->trsm_ops->disable();
4495         } else {
4496                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
4497                         dev_drv->trsm_ops->enable();
4498                 msleep(100);
4499                 /* open the backlight */
4500                 if (vop_dev->backlight) {
4501                         vop_dev->backlight->props.power = FB_BLANK_UNBLANK;
4502                         backlight_update_status(vop_dev->backlight);
4503                 }
4504         }
4505
4506         return 0;
4507 }
4508
4509 static int vop_set_overscan(struct rk_lcdc_driver *dev_drv,
4510                             struct overscan *overscan)
4511 {
4512         struct vop_device *vop_dev =
4513             container_of(dev_drv, struct vop_device, driver);
4514
4515         if (unlikely(!vop_dev->clk_on)) {
4516                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4517                 return 0;
4518         }
4519         /*vop_post_cfg(dev_drv);*/
4520
4521         return 0;
4522 }
4523
4524 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
4525         .open = vop_open,
4526         .win_direct_en = vop_win_direct_en,
4527         .load_screen = vop_load_screen,
4528         .get_dspbuf_info = vop_get_dspbuf_info,
4529         .post_dspbuf = vop_post_dspbuf,
4530         .set_par = vop_set_par,
4531         .pan_display = vop_pan_display,
4532         .set_wb = vop_set_writeback,
4533         .direct_set_addr = vop_direct_set_win_addr,
4534         /*.lcdc_reg_update = vop_reg_update,*/
4535         .blank = vop_blank,
4536         .ioctl = vop_ioctl,
4537         .suspend = vop_early_suspend,
4538         .resume = vop_early_resume,
4539         .get_win_state = vop_get_win_state,
4540         .area_support_num = vop_get_area_num,
4541         .ovl_mgr = vop_ovl_mgr,
4542         .get_disp_info = vop_get_disp_info,
4543         .fps_mgr = vop_fps_mgr,
4544         .fb_get_win_id = vop_get_win_id,
4545         .fb_win_remap = vop_fb_win_remap,
4546         .poll_vblank = vop_poll_vblank,
4547         .dpi_open = vop_dpi_open,
4548         .dpi_win_sel = vop_dpi_win_sel,
4549         .dpi_status = vop_dpi_status,
4550         .get_dsp_addr = vop_get_dsp_addr,
4551         .set_dsp_lut = vop_set_lut,
4552         .set_cabc_lut = vop_set_cabc,
4553         .set_dsp_cabc = vop_set_dsp_cabc,
4554         .set_dsp_bcsh_hue = vop_set_bcsh_hue,
4555         .set_dsp_bcsh_bcs = vop_set_bcsh_bcs,
4556         .get_dsp_bcsh_hue = vop_get_bcsh_hue,
4557         .get_dsp_bcsh_bcs = vop_get_bcsh_bcs,
4558         .open_bcsh = vop_open_bcsh,
4559         .dump_reg = vop_reg_dump,
4560         .cfg_done = vop_config_done,
4561         .set_irq_to_cpu = vop_set_irq_to_cpu,
4562         /*.dsp_black = vop_dsp_black,*/
4563         .backlight_close = vop_backlight_close,
4564         .mmu_en    = vop_mmu_en,
4565         .set_overscan   = vop_set_overscan,
4566 };
4567
4568 static irqreturn_t vop_isr(int irq, void *dev_id)
4569 {
4570         struct vop_device *vop_dev = (struct vop_device *)dev_id;
4571         ktime_t timestamp = ktime_get();
4572         u32 intr_status;
4573         unsigned long flags;
4574
4575         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4576
4577         intr_status = vop_readl(vop_dev, INTR_STATUS0);
4578         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, intr_status);
4579
4580         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4581         /* This is expected for vop iommu irqs, since the irq is shared */
4582         if (!intr_status)
4583                 return IRQ_NONE;
4584
4585         if (intr_status & INTR_FS) {
4586                 timestamp = ktime_get();
4587                 if (vop_dev->driver.wb_data.state) {
4588                         u32 wb_status;
4589
4590                         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4591                         wb_status = vop_read_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4592
4593                         if (wb_status)
4594                                 vop_clr_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4595
4596                         vop_cfg_done(vop_dev);
4597                         vop_dev->driver.wb_data.state = 0;
4598                         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4599                 }
4600                 vop_dev->driver.vsync_info.timestamp = timestamp;
4601                 wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait);
4602                 intr_status &= ~INTR_FS;
4603         }
4604
4605         if (intr_status & INTR_LINE_FLAG0)
4606                 intr_status &= ~INTR_LINE_FLAG0;
4607
4608         if (intr_status & INTR_LINE_FLAG1)
4609                 intr_status &= ~INTR_LINE_FLAG1;
4610
4611         if (intr_status & INTR_FS_NEW)
4612                 intr_status &= ~INTR_FS_NEW;
4613
4614         if (intr_status & INTR_BUS_ERROR) {
4615                 intr_status &= ~INTR_BUS_ERROR;
4616                 dev_warn_ratelimited(vop_dev->dev, "bus error!");
4617         }
4618
4619         if (intr_status & INTR_WIN0_EMPTY) {
4620                 intr_status &= ~INTR_WIN0_EMPTY;
4621                 dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!");
4622         }
4623
4624         if (intr_status & INTR_WIN1_EMPTY) {
4625                 intr_status &= ~INTR_WIN1_EMPTY;
4626                 dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!");
4627         }
4628
4629         if (intr_status & INTR_HWC_EMPTY) {
4630                 intr_status &= ~INTR_HWC_EMPTY;
4631                 dev_warn_ratelimited(vop_dev->dev, "intr hwc empty!");
4632         }
4633
4634         if (intr_status & INTR_POST_BUF_EMPTY) {
4635                 intr_status &= ~INTR_POST_BUF_EMPTY;
4636                 dev_warn_ratelimited(vop_dev->dev, "intr post buf empty!");
4637         }
4638
4639         if (intr_status)
4640                 dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status);
4641
4642         return IRQ_HANDLED;
4643 }
4644
4645 #if defined(CONFIG_PM)
4646 static int vop_suspend(struct platform_device *pdev, pm_message_t state)
4647 {
4648         return 0;
4649 }
4650
4651 static int vop_resume(struct platform_device *pdev)
4652 {
4653         return 0;
4654 }
4655 #else
4656 #define vop_suspend NULL
4657 #define vop_resume  NULL
4658 #endif
4659
4660 static int vop_parse_dt(struct vop_device *vop_dev)
4661 {
4662         struct device_node *np = vop_dev->dev->of_node;
4663         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
4664         int val;
4665
4666         if (of_property_read_u32(np, "rockchip,prop", &val))
4667                 vop_dev->prop = PRMRY;  /*default set it as primary */
4668         else
4669                 vop_dev->prop = val;
4670
4671         if (of_property_read_u32(np, "rockchip,mirror", &val))
4672                 dev_drv->rotate_mode = NO_MIRROR;
4673         else
4674                 dev_drv->rotate_mode = val;
4675
4676         if (of_property_read_u32(np, "rockchip,pwr18", &val))
4677                 /*default set it as 3.xv power supply */
4678                 vop_dev->pwr18 = false;
4679         else
4680                 vop_dev->pwr18 = (val ? true : false);
4681
4682         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
4683                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
4684         else
4685                 dev_drv->fb_win_map = val;
4686
4687         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
4688                 dev_drv->bcsh.enable = false;
4689         else
4690                 dev_drv->bcsh.enable = (val ? true : false);
4691
4692         if (of_property_read_u32(np, "rockchip,brightness", &val))
4693                 dev_drv->bcsh.brightness = 0xffff;
4694         else
4695                 dev_drv->bcsh.brightness = val;
4696
4697         if (of_property_read_u32(np, "rockchip,contrast", &val))
4698                 dev_drv->bcsh.contrast = 0xffff;
4699         else
4700                 dev_drv->bcsh.contrast = val;
4701
4702         if (of_property_read_u32(np, "rockchip,sat-con", &val))
4703                 dev_drv->bcsh.sat_con = 0xffff;
4704         else
4705                 dev_drv->bcsh.sat_con = val;
4706
4707         if (of_property_read_u32(np, "rockchip,hue", &val)) {
4708                 dev_drv->bcsh.sin_hue = 0xffff;
4709                 dev_drv->bcsh.cos_hue = 0xffff;
4710         } else {
4711                 dev_drv->bcsh.sin_hue = val & 0xff;
4712                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
4713         }
4714
4715         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
4716                 dev_drv->iommu_enabled = 0;
4717         else
4718                 dev_drv->iommu_enabled = val;
4719         return 0;
4720 }
4721
4722 static int vop_probe(struct platform_device *pdev)
4723 {
4724         struct vop_device *vop_dev = NULL;
4725         struct rk_lcdc_driver *dev_drv;
4726         const struct of_device_id *of_id;
4727         struct device *dev = &pdev->dev;
4728         struct resource *res;
4729         struct device_node *np = pdev->dev.of_node;
4730         int prop;
4731         int ret = 0;
4732
4733         /* if the primary lcdc has not registered ,the extend
4734          * lcdc register later
4735          */
4736         of_property_read_u32(np, "rockchip,prop", &prop);
4737         if (prop == EXTEND) {
4738                 if (!is_prmry_rk_lcdc_registered())
4739                         return -EPROBE_DEFER;
4740         }
4741         vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL);
4742         if (!vop_dev)
4743                 return -ENOMEM;
4744         of_id = of_match_device(vop_dt_ids, dev);
4745         vop_dev->data = of_id->data;
4746         if (VOP_CHIP(vop_dev) != VOP_RK322X && VOP_CHIP(vop_dev) != VOP_RK3399)
4747                 return -ENODEV;
4748         platform_set_drvdata(pdev, vop_dev);
4749         vop_dev->dev = dev;
4750         vop_parse_dt(vop_dev);
4751         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4752         vop_dev->reg_phy_base = res->start;
4753         vop_dev->len = resource_size(res);
4754         vop_dev->regs = devm_ioremap_resource(dev, res);
4755         if (IS_ERR(vop_dev->regs))
4756                 return PTR_ERR(vop_dev->regs);
4757
4758         dev_info(dev, "vop_dev->regs=0x%lx\n", (long)vop_dev->regs);
4759
4760         vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL);
4761         if (IS_ERR(vop_dev->regsbak))
4762                 return PTR_ERR(vop_dev->regsbak);
4763         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
4764                 vop_dev->dsp_lut_addr_base = vop_dev->regs + GAMMA_LUT_ADDR;
4765                 vop_dev->cabc_lut_addr_base = vop_dev->regs +
4766                                                 CABC_GAMMA_LUT_ADDR;
4767         }
4768         vop_dev->grf_base =
4769                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
4770         if (IS_ERR(vop_dev->grf_base)) {
4771                 dev_err(&pdev->dev, "can't find lcdc grf property\n");
4772                 vop_dev->grf_base = NULL;
4773         }
4774
4775         vop_dev->id = vop_get_id(vop_dev, vop_dev->reg_phy_base);
4776         dev_set_name(vop_dev->dev, "vop%d", vop_dev->id);
4777         dev_drv = &vop_dev->driver;
4778         dev_drv->dev = dev;
4779         dev_drv->prop = prop;
4780         dev_drv->id = vop_dev->id;
4781         dev_drv->ops = &lcdc_drv_ops;
4782         dev_drv->lcdc_win_num = vop_dev->data->n_wins;
4783         dev_drv->reserved_fb = 0;
4784         spin_lock_init(&vop_dev->reg_lock);
4785         spin_lock_init(&vop_dev->irq_lock);
4786         vop_dev->irq = platform_get_irq(pdev, 0);
4787         if (vop_dev->irq < 0) {
4788                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
4789                         vop_dev->id);
4790                 return -ENXIO;
4791         }
4792
4793         ret = devm_request_irq(dev, vop_dev->irq, vop_isr,
4794                                IRQF_SHARED, dev_name(dev), vop_dev);
4795         if (ret) {
4796                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
4797                         vop_dev->irq, ret);
4798                 return ret;
4799         }
4800         if (dev_drv->iommu_enabled) {
4801                 if (VOP_CHIP(vop_dev) == VOP_RK322X) {
4802                         strcpy(dev_drv->mmu_dts_name,
4803                                VOP_IOMMU_COMPATIBLE_NAME);
4804                 } else {
4805                         if (vop_dev->id == 0)
4806                                 strcpy(dev_drv->mmu_dts_name,
4807                                        VOPB_IOMMU_COMPATIBLE_NAME);
4808                         else
4809                                 strcpy(dev_drv->mmu_dts_name,
4810                                        VOPL_IOMMU_COMPATIBLE_NAME);
4811                 }
4812         }
4813         dev_drv->property.feature |= SUPPORT_WRITE_BACK;
4814         ret = rk_fb_register(dev_drv, vop_dev->data->win, vop_dev->id);
4815         if (ret < 0) {
4816                 dev_err(dev, "register fb for lcdc%d failed!\n", vop_dev->id);
4817                 return ret;
4818         }
4819         vop_dev->screen = dev_drv->screen0;
4820         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
4821                  vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
4822
4823         return 0;
4824 }
4825
4826 static int vop_remove(struct platform_device *pdev)
4827 {
4828         return 0;
4829 }
4830
4831 static void vop_shutdown(struct platform_device *pdev)
4832 {
4833         struct vop_device *vop_dev = platform_get_drvdata(pdev);
4834         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
4835
4836         dev_drv->suspend_flag = 1;
4837         /* ensure suspend_flag take effect on multi process */
4838         smp_wmb();
4839         flush_kthread_worker(&dev_drv->update_regs_worker);
4840         kthread_stop(dev_drv->update_regs_thread);
4841         vop_deint(vop_dev);
4842
4843         vop_clk_disable(vop_dev);
4844         rk_disp_pwr_disable(dev_drv);
4845 }
4846
4847 static struct platform_driver vop_driver = {
4848         .probe = vop_probe,
4849         .remove = vop_remove,
4850         .driver = {
4851                    .name = "rk322x-lcdc",
4852                    .owner = THIS_MODULE,
4853                    .of_match_table = of_match_ptr(vop_dt_ids),
4854                    },
4855         .suspend = vop_suspend,
4856         .resume = vop_resume,
4857         .shutdown = vop_shutdown,
4858 };
4859
4860 static int __init vop_module_init(void)
4861 {
4862         return platform_driver_register(&vop_driver);
4863 }
4864
4865 static void __exit vop_module_exit(void)
4866 {
4867         platform_driver_unregister(&vop_driver);
4868 }
4869
4870 fs_initcall(vop_module_init);
4871 module_exit(vop_module_exit);