video: rockchip: vop: 3399: add win2 and win3 when get dsp_info
[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, 3x3, 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, 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, R2Y, csc_y2r_bt2020, i);
672                                 LOAD_CSC(vop_dev, R2Y, csc_r2r_bt2020to709, i);
673                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt709_full, 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, R2Y, 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, R2Y, csc_y2r_bt709_full, i);
688                                 LOAD_CSC(vop_dev, R2Y, 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->state == 1) {
1552                 vop_axi_gather_cfg(vop_dev, win);
1553                 val = V_HWC_EN(1) | V_HWC_DATA_FMT(win->area[0].fmt_cfg) |
1554                     V_HWC_RB_SWAP(win->area[0].swap_rb);
1555                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1556
1557                 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
1558                         hwc_size = 0;
1559                 else if ((win->area[0].xsize == 64) &&
1560                          (win->area[0].ysize == 64))
1561                         hwc_size = 1;
1562                 else if ((win->area[0].xsize == 96) &&
1563                          (win->area[0].ysize == 96))
1564                         hwc_size = 2;
1565                 else if ((win->area[0].xsize == 128) &&
1566                          (win->area[0].ysize == 128))
1567                         hwc_size = 3;
1568                 else
1569                         dev_err(vop_dev->dev, "un supported hwc size[%dx%d]!\n",
1570                                 win->area[0].xsize, win->area[0].ysize);
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                         val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0);
1938                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1939                         break;
1940                 case SCREEN_RGB:
1941                 case SCREEN_LVDS:
1942                         val = V_RGB_OUT_EN(1);
1943                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1944                 case SCREEN_MIPI:
1945                         val = V_MIPI_OUT_EN(1);
1946                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1947                 case SCREEN_EDP:
1948                         val = V_EDP_OUT_EN(1);
1949                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1950                         break;
1951                 default:
1952                         dev_err(vop_dev->dev, "un supported interface[%d]!\n",
1953                                 screen->type);
1954                         break;
1955                 }
1956                 val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
1957                         V_HDMI_VSYNC_POL(screen->pin_vsync) |
1958                         V_HDMI_DEN_POL(screen->pin_den) |
1959                         V_HDMI_DCLK_POL(screen->pin_dclk);
1960                 /*hsync vsync den dclk polo,dither */
1961                 vop_msk_reg(vop_dev, DSP_CTRL1, val);
1962
1963                 if (screen->color_mode == COLOR_RGB)
1964                         dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1965                 else
1966                         dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1967
1968 #ifndef CONFIG_RK_FPGA
1969                 /*
1970                  * Todo:
1971                  * writel_relaxed(v, RK_GRF_VIRT + vop_GRF_SOC_CON7);
1972                  *  move to  lvds driver
1973                  */
1974                 /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
1975 #endif
1976                 val = V_DSP_OUT_MODE(face) | V_DSP_DCLK_DDR(dclk_ddr) |
1977                     V_DSP_BG_SWAP(screen->swap_gb) |
1978                     V_DSP_RB_SWAP(screen->swap_rb) |
1979                     V_DSP_RG_SWAP(screen->swap_rg) |
1980                     V_DSP_DELTA_SWAP(screen->swap_delta) |
1981                     V_DSP_DUMMY_SWAP(screen->swap_dumy) | V_DSP_OUT_ZERO(0) |
1982                     V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0) |
1983                     V_DSP_X_MIR_EN(screen->x_mirror) |
1984                     V_DSP_Y_MIR_EN(screen->y_mirror);
1985                 val |= V_SW_CORE_DCLK_SEL(!!screen->pixelrepeat);
1986                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
1987                         val |= V_SW_HDMI_CLK_I_SEL(1);
1988                 else
1989                         val |= V_SW_HDMI_CLK_I_SEL(0);
1990                 vop_msk_reg(vop_dev, DSP_CTRL0, val);
1991
1992                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
1993                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(1));
1994                 else
1995                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(0));
1996                 /* BG color */
1997                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1998                         val = V_DSP_OUT_RGB_YUV(1);
1999                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
2000                         val = V_DSP_BG_BLUE(0x200) | V_DSP_BG_GREEN(0x40) |
2001                                 V_DSP_BG_RED(0x200);
2002                         vop_msk_reg(vop_dev, DSP_BG, val);
2003                 } else {
2004                         val = V_DSP_OUT_RGB_YUV(0);
2005                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
2006                         val = V_DSP_BG_BLUE(0x55) | V_DSP_BG_GREEN(0x55) |
2007                                 V_DSP_BG_RED(0x55);
2008                         vop_msk_reg(vop_dev, DSP_BG, val);
2009                 }
2010                 dev_drv->output_color = screen->color_mode;
2011                 vop_bcsh_path_sel(dev_drv);
2012                 vop_config_timing(dev_drv);
2013                 vop_cfg_done(vop_dev);
2014         }
2015         spin_unlock(&vop_dev->reg_lock);
2016         vop_set_dclk(dev_drv, 1);
2017         if (screen->type != SCREEN_HDMI && screen->type != SCREEN_TVOUT &&
2018             dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2019                 dev_drv->trsm_ops->enable();
2020         if (screen->init)
2021                 screen->init();
2022
2023         return 0;
2024 }
2025
2026 /*enable layer,open:1,enable;0 disable*/
2027 static void vop_layer_enable(struct vop_device *vop_dev,
2028                              unsigned int win_id, bool open)
2029 {
2030         spin_lock(&vop_dev->reg_lock);
2031         if (likely(vop_dev->clk_on) &&
2032             vop_dev->driver.win[win_id]->state != open) {
2033                 if (open) {
2034                         if (!vop_dev->atv_layer_cnt) {
2035                                 dev_info(vop_dev->dev,
2036                                          "wakeup from standby!\n");
2037                                 vop_dev->standby = 0;
2038                         }
2039                         vop_dev->atv_layer_cnt |= (1 << win_id);
2040                 } else {
2041                         if (vop_dev->atv_layer_cnt & (1 << win_id))
2042                                 vop_dev->atv_layer_cnt &= ~(1 << win_id);
2043                 }
2044                 vop_dev->driver.win[win_id]->state = open;
2045                 if (!open) {
2046                         vop_layer_update_regs(vop_dev,
2047                                               vop_dev->driver.win[win_id]);
2048                         vop_cfg_done(vop_dev);
2049                 }
2050                 /* if no layer used,disable lcdc */
2051                 if (!vop_dev->atv_layer_cnt) {
2052                         dev_info(vop_dev->dev,
2053                                  "no layer is used,go to standby!\n");
2054                         vop_dev->standby = 1;
2055                 }
2056         }
2057         spin_unlock(&vop_dev->reg_lock);
2058 }
2059
2060 static int vop_enable_irq(struct rk_lcdc_driver *dev_drv)
2061 {
2062         struct vop_device *vop_dev = container_of(dev_drv,
2063                                                     struct vop_device, driver);
2064         u64 val;
2065         /* struct rk_screen *screen = dev_drv->cur_screen; */
2066
2067         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
2068
2069         val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1 |
2070                 INTR_WIN0_EMPTY | INTR_WIN1_EMPTY | INTR_HWC_EMPTY |
2071                 INTR_POST_BUF_EMPTY;
2072
2073         vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val);
2074
2075         return 0;
2076 }
2077
2078 static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id,
2079                     bool open)
2080 {
2081         struct vop_device *vop_dev =
2082             container_of(dev_drv, struct vop_device, driver);
2083
2084         /* enable clk,when first layer open */
2085         if ((open) && (!vop_dev->atv_layer_cnt)) {
2086                 /* rockchip_set_system_status(sys_status); */
2087                 vop_pre_init(dev_drv);
2088                 vop_clk_enable(vop_dev);
2089                 vop_enable_irq(dev_drv);
2090                 if (dev_drv->iommu_enabled) {
2091                         if (!dev_drv->mmu_dev) {
2092                                 dev_drv->mmu_dev =
2093                                     rk_fb_get_sysmmu_device_by_compatible
2094                                     (dev_drv->mmu_dts_name);
2095                                 if (dev_drv->mmu_dev) {
2096                                         rk_fb_platform_set_sysmmu
2097                                             (dev_drv->mmu_dev, dev_drv->dev);
2098                                 } else {
2099                                         dev_err(dev_drv->dev,
2100                                                 "fail get rk iommu device\n");
2101                                         return -1;
2102                                 }
2103                         }
2104                 }
2105                 if ((support_uboot_display() && (vop_dev->prop == PRMRY)))
2106                         vop_set_dclk(dev_drv, 0);
2107                 else
2108                         vop_load_screen(dev_drv, 1);
2109                 if (dev_drv->bcsh.enable)
2110                         vop_set_bcsh(dev_drv, 1);
2111                 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
2112                 vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
2113         }
2114
2115         if (win_id < dev_drv->lcdc_win_num)
2116                 vop_layer_enable(vop_dev, win_id, open);
2117         else
2118                 dev_err(vop_dev->dev, "invalid win id:%d\n", win_id);
2119
2120         dev_drv->first_frame = 0;
2121         return 0;
2122 }
2123
2124 static int win_0_1_display(struct vop_device *vop_dev,
2125                            struct rk_lcdc_win *win)
2126 {
2127         u32 y_addr;
2128         u32 uv_addr;
2129         unsigned int off;
2130
2131         off = win->id * 0x40;
2132         /*win->smem_start + win->y_offset; */
2133         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2134         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
2135         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
2136             vop_dev->id, win->id, y_addr, uv_addr);
2137         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
2138             win->area[0].y_offset, win->area[0].c_offset);
2139         spin_lock(&vop_dev->reg_lock);
2140         if (likely(vop_dev->clk_on)) {
2141                 win->area[0].y_addr = y_addr;
2142                 win->area[0].uv_addr = uv_addr;
2143                 vop_writel(vop_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
2144                 vop_writel(vop_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
2145                 if (win->area[0].fbdc_en == 1)
2146                         vop_writel(vop_dev, AFBCD0_HDR_PTR,
2147                                    win->area[0].y_addr);
2148         }
2149         spin_unlock(&vop_dev->reg_lock);
2150
2151         return 0;
2152 }
2153
2154 static int win_2_3_display(struct vop_device *vop_dev,
2155                            struct rk_lcdc_win *win)
2156 {
2157         u32 i, y_addr;
2158         unsigned int off;
2159
2160         off = (win->id - 2) * 0x50;
2161         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2162         DBG(2, "lcdc[%d]:win[%d]:", vop_dev->id, win->id);
2163
2164         if (likely(vop_dev->clk_on)) {
2165                 for (i = 0; i < win->area_num; i++) {
2166                         DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
2167                             i, win->area[i].y_addr, win->area[i].y_offset);
2168                         win->area[i].y_addr =
2169                             win->area[i].smem_start + win->area[i].y_offset;
2170                         }
2171                 spin_lock(&vop_dev->reg_lock);
2172                 vop_writel(vop_dev, WIN2_MST0 + off, win->area[0].y_addr);
2173                 vop_writel(vop_dev, WIN2_MST1 + off, win->area[1].y_addr);
2174                 vop_writel(vop_dev, WIN2_MST2 + off, win->area[2].y_addr);
2175                 vop_writel(vop_dev, WIN2_MST3 + off, win->area[3].y_addr);
2176                 if (win->area[0].fbdc_en == 1)
2177                         vop_writel(vop_dev, AFBCD0_HDR_PTR,
2178                                    win->area[0].y_addr);
2179                 spin_unlock(&vop_dev->reg_lock);
2180         }
2181         return 0;
2182 }
2183
2184 static int hwc_display(struct vop_device *vop_dev, struct rk_lcdc_win *win)
2185 {
2186         u32 y_addr;
2187
2188         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2189         DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
2190             vop_dev->id, __func__, y_addr);
2191         spin_lock(&vop_dev->reg_lock);
2192         if (likely(vop_dev->clk_on)) {
2193                 win->area[0].y_addr = y_addr;
2194                 vop_writel(vop_dev, HWC_MST, win->area[0].y_addr);
2195         }
2196         spin_unlock(&vop_dev->reg_lock);
2197
2198         return 0;
2199 }
2200
2201 static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
2202 {
2203         struct vop_device *vop_dev =
2204             container_of(dev_drv, struct vop_device, driver);
2205         struct rk_lcdc_win *win = NULL;
2206         struct rk_screen *screen = dev_drv->cur_screen;
2207
2208         win = dev_drv->win[win_id];
2209         if (!screen) {
2210                 dev_err(dev_drv->dev, "screen is null!\n");
2211                 return -ENOENT;
2212         }
2213         if (unlikely(!vop_dev->clk_on)) {
2214                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
2215                 return 0;
2216         }
2217         if (win_id == 0) {
2218                 win_0_1_display(vop_dev, win);
2219         } else if (win_id == 1) {
2220                 win_0_1_display(vop_dev, win);
2221         } else if (win_id == 2) {
2222                 win_2_3_display(vop_dev, win);
2223         } else if (win_id == 3) {
2224                 win_2_3_display(vop_dev, win);
2225         } else if (win_id == 4) {
2226                 hwc_display(vop_dev, win);
2227         } else {
2228                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
2229                 return -EINVAL;
2230         }
2231
2232         return 0;
2233 }
2234
2235 static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen)
2236 {
2237         u16 srcW;
2238         u16 srcH;
2239         u16 dstW;
2240         u16 dstH;
2241         u16 yrgb_srcW;
2242         u16 yrgb_srcH;
2243         u16 yrgb_dstW;
2244         u16 yrgb_dstH;
2245         u32 yrgb_vscalednmult;
2246         u32 yrgb_xscl_factor;
2247         u32 yrgb_yscl_factor;
2248         u8 yrgb_vsd_bil_gt2 = 0;
2249         u8 yrgb_vsd_bil_gt4 = 0;
2250
2251         u16 cbcr_srcW;
2252         u16 cbcr_srcH;
2253         u16 cbcr_dstW;
2254         u16 cbcr_dstH;
2255         u32 cbcr_vscalednmult;
2256         u32 cbcr_xscl_factor;
2257         u32 cbcr_yscl_factor;
2258         u8 cbcr_vsd_bil_gt2 = 0;
2259         u8 cbcr_vsd_bil_gt4 = 0;
2260         u8 yuv_fmt = 0;
2261
2262         srcW = win->area[0].xact;
2263         if ((screen->mode.vmode & FB_VMODE_INTERLACED) &&
2264             (win->area[0].yact == 2 * win->area[0].ysize)) {
2265                 srcH = win->area[0].yact / 2;
2266                 yrgb_vsd_bil_gt2 = 1;
2267                 cbcr_vsd_bil_gt2 = 1;
2268         } else {
2269                 srcH = win->area[0].yact;
2270         }
2271         dstW = win->area[0].xsize;
2272         dstH = win->area[0].ysize;
2273
2274         /*yrgb scl mode */
2275         yrgb_srcW = srcW;
2276         yrgb_srcH = srcH;
2277         yrgb_dstW = dstW;
2278         yrgb_dstH = dstH;
2279         if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
2280                 pr_err("ERROR: yrgb scale exceed 8,");
2281                 pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
2282                        yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
2283         }
2284         if (yrgb_srcW < yrgb_dstW)
2285                 win->yrgb_hor_scl_mode = SCALE_UP;
2286         else if (yrgb_srcW > yrgb_dstW)
2287                 win->yrgb_hor_scl_mode = SCALE_DOWN;
2288         else
2289                 win->yrgb_hor_scl_mode = SCALE_NONE;
2290
2291         if (yrgb_srcH < yrgb_dstH)
2292                 win->yrgb_ver_scl_mode = SCALE_UP;
2293         else if (yrgb_srcH > yrgb_dstH)
2294                 win->yrgb_ver_scl_mode = SCALE_DOWN;
2295         else
2296                 win->yrgb_ver_scl_mode = SCALE_NONE;
2297
2298         /*cbcr scl mode */
2299         switch (win->area[0].format) {
2300         case YUV422:
2301         case YUYV422:
2302         case UYVY422:
2303         case YUV422_A:
2304                 cbcr_srcW = srcW / 2;
2305                 cbcr_dstW = dstW;
2306                 cbcr_srcH = srcH;
2307                 cbcr_dstH = dstH;
2308                 yuv_fmt = 1;
2309                 break;
2310         case YUV420:
2311         case YUYV420:
2312         case UYVY420:
2313         case YUV420_A:
2314         case YUV420_NV21:
2315                 cbcr_srcW = srcW / 2;
2316                 cbcr_dstW = dstW;
2317                 cbcr_srcH = srcH / 2;
2318                 cbcr_dstH = dstH;
2319                 yuv_fmt = 1;
2320                 break;
2321         case YUV444:
2322         case YUV444_A:
2323                 cbcr_srcW = srcW;
2324                 cbcr_dstW = dstW;
2325                 cbcr_srcH = srcH;
2326                 cbcr_dstH = dstH;
2327                 yuv_fmt = 1;
2328                 break;
2329         default:
2330                 cbcr_srcW = 0;
2331                 cbcr_dstW = 0;
2332                 cbcr_srcH = 0;
2333                 cbcr_dstH = 0;
2334                 yuv_fmt = 0;
2335                 break;
2336         }
2337         if (yuv_fmt) {
2338                 if ((cbcr_dstW * 8 <= cbcr_srcW) ||
2339                     (cbcr_dstH * 8 <= cbcr_srcH)) {
2340                         pr_err("ERROR: cbcr scale exceed 8,");
2341                         pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
2342                                cbcr_srcH, cbcr_dstW, cbcr_dstH);
2343                 }
2344         }
2345
2346         if (cbcr_srcW < cbcr_dstW)
2347                 win->cbr_hor_scl_mode = SCALE_UP;
2348         else if (cbcr_srcW > cbcr_dstW)
2349                 win->cbr_hor_scl_mode = SCALE_DOWN;
2350         else
2351                 win->cbr_hor_scl_mode = SCALE_NONE;
2352
2353         if (cbcr_srcH < cbcr_dstH)
2354                 win->cbr_ver_scl_mode = SCALE_UP;
2355         else if (cbcr_srcH > cbcr_dstH)
2356                 win->cbr_ver_scl_mode = SCALE_DOWN;
2357         else
2358                 win->cbr_ver_scl_mode = SCALE_NONE;
2359
2360         /* line buffer mode */
2361         if ((win->area[0].format == YUV422) ||
2362             (win->area[0].format == YUV420) ||
2363             (win->area[0].format == YUYV422) ||
2364             (win->area[0].format == YUYV420) ||
2365             (win->area[0].format == UYVY422) ||
2366             (win->area[0].format == UYVY420) ||
2367             (win->area[0].format == YUV420_NV21) ||
2368             (win->area[0].format == YUV422_A) ||
2369             (win->area[0].format == YUV420_A)) {
2370                 if (win->cbr_hor_scl_mode == SCALE_DOWN) {
2371                         if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
2372                             (cbcr_dstW == 0))
2373                                 pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
2374                                        cbcr_dstW);
2375                         else if (cbcr_dstW > 1280)
2376                                 win->win_lb_mode = LB_YUV_3840X5;
2377                         else
2378                                 win->win_lb_mode = LB_YUV_2560X8;
2379                 } else {        /* SCALE_UP or SCALE_NONE */
2380                         if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
2381                             (cbcr_srcW == 0))
2382                                 pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
2383                                        cbcr_srcW);
2384                         else if (cbcr_srcW > 1280)
2385                                 win->win_lb_mode = LB_YUV_3840X5;
2386                         else
2387                                 win->win_lb_mode = LB_YUV_2560X8;
2388                 }
2389         } else {
2390                 if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
2391                         if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
2392                             (yrgb_dstW == 0))
2393                                 pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
2394                         else if (yrgb_dstW > 2560)
2395                                 win->win_lb_mode = LB_RGB_3840X2;
2396                         else if (yrgb_dstW > 1920)
2397                                 win->win_lb_mode = LB_RGB_2560X4;
2398                         else if (yrgb_dstW > 1280)
2399                                 win->win_lb_mode = LB_RGB_1920X5;
2400                         else
2401                                 win->win_lb_mode = LB_RGB_1280X8;
2402                 } else {        /* SCALE_UP or SCALE_NONE */
2403                         if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
2404                             (yrgb_srcW == 0))
2405                                 pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
2406                         else if (yrgb_srcW > 2560)
2407                                 win->win_lb_mode = LB_RGB_3840X2;
2408                         else if (yrgb_srcW > 1920)
2409                                 win->win_lb_mode = LB_RGB_2560X4;
2410                         else if (yrgb_srcW > 1280)
2411                                 win->win_lb_mode = LB_RGB_1920X5;
2412                         else
2413                                 win->win_lb_mode = LB_RGB_1280X8;
2414                 }
2415         }
2416         DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
2417
2418         /* vsd/vsu scale ALGORITHM */
2419         win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2420         win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2421         win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2422         win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2423
2424         /* if (VOP_CHIP(vop_dev) == VOP_RK3399) { */
2425         if ((win->area[0].format == YUYV422) ||
2426             (win->area[0].format == YUYV420) ||
2427             (win->area[0].format == UYVY422) ||
2428             (win->area[0].format == UYVY420)) {
2429                 yrgb_vscalednmult =
2430                         vop_get_hard_ware_vskiplines(yrgb_srcH, yrgb_dstH);
2431                 if (yrgb_vscalednmult == 4) {
2432                         yrgb_vsd_bil_gt4 = 1;
2433                         yrgb_vsd_bil_gt2 = 0;
2434                 } else if (yrgb_vscalednmult == 2) {
2435                         yrgb_vsd_bil_gt4 = 0;
2436                         yrgb_vsd_bil_gt2 = 1;
2437                 } else {
2438                         yrgb_vsd_bil_gt4 = 0;
2439                         yrgb_vsd_bil_gt2 = 0;
2440                 }
2441                 if ((win->area[0].format == YUYV420) ||
2442                     (win->area[0].format == UYVY420)) {
2443                         if ((yrgb_vsd_bil_gt4 == 1) || (yrgb_vsd_bil_gt2 == 1))
2444                                 win->yrgb_vsd_mode = SCALE_DOWN_AVG;
2445                 }
2446
2447                 cbcr_vscalednmult =
2448                         vop_get_hard_ware_vskiplines(cbcr_srcH, cbcr_dstH);
2449                 if (cbcr_vscalednmult == 4) {
2450                         cbcr_vsd_bil_gt4 = 1;
2451                         cbcr_vsd_bil_gt2 = 0;
2452                 } else if (cbcr_vscalednmult == 2) {
2453                         cbcr_vsd_bil_gt4 = 0;
2454                         cbcr_vsd_bil_gt2 = 1;
2455                 } else {
2456                         cbcr_vsd_bil_gt4 = 0;
2457                         cbcr_vsd_bil_gt2 = 0;
2458                 }
2459                 if ((win->area[0].format == YUYV420) ||
2460                     (win->area[0].format == UYVY420)) {
2461                         if ((cbcr_vsd_bil_gt4 == 1) || (cbcr_vsd_bil_gt2 == 1))
2462                                 win->cbr_vsd_mode = SCALE_DOWN_AVG;
2463                 }
2464                 /* CBCR vsd_mode must same to YRGB for YUYV when gt2 or gt4 */
2465                 if ((cbcr_vsd_bil_gt4 == 1) || (cbcr_vsd_bil_gt2 == 1)) {
2466                         if (win->yrgb_vsd_mode != win->cbr_vsd_mode)
2467                                 win->cbr_vsd_mode = win->yrgb_vsd_mode;
2468                 }
2469         }
2470         /* 3399 yuyv support*/
2471         if (win->ymirror == 1) {
2472                 if (win->yrgb_vsd_mode == SCALE_DOWN_AVG)
2473                         pr_info("y_mirror enable, y-vsd AVG mode unsupprot\n");
2474                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2475         }
2476         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
2477                 if (win->yrgb_vsd_mode == SCALE_DOWN_AVG)
2478                         pr_info("interlace mode, y-vsd AVG mode unsupprot\n");
2479                 /* interlace mode must bill */
2480                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2481                 win->cbr_vsd_mode = SCALE_DOWN_BIL;
2482         }
2483         switch (win->win_lb_mode) {
2484         case LB_YUV_3840X5:
2485         case LB_YUV_2560X8:
2486         case LB_RGB_1920X5:
2487         case LB_RGB_1280X8:
2488                 win->yrgb_vsu_mode = SCALE_UP_BIC;
2489                 win->cbr_vsu_mode = SCALE_UP_BIC;
2490                 break;
2491         case LB_RGB_3840X2:
2492                 if (win->yrgb_ver_scl_mode != SCALE_NONE)
2493                         pr_err("ERROR : not allow yrgb ver scale\n");
2494                 if (win->cbr_ver_scl_mode != SCALE_NONE)
2495                         pr_err("ERROR : not allow cbcr ver scale\n");
2496                 break;
2497         case LB_RGB_2560X4:
2498                 win->yrgb_vsu_mode = SCALE_UP_BIL;
2499                 win->cbr_vsu_mode = SCALE_UP_BIL;
2500                 break;
2501         default:
2502                 pr_info("%s:un supported win_lb_mode:%d\n",
2503                         __func__, win->win_lb_mode);
2504                 break;
2505         }
2506
2507         if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
2508             (win->area[0].fbdc_en == 1)) {
2509                 /* in this pattern,use bil mode,not support souble scd,
2510                  * use avg mode, support double scd, but aclk should be
2511                  * bigger than dclk.
2512                  */
2513                 if (yrgb_srcH >= 2 * yrgb_dstH) {
2514                         pr_err("ERROR : fbdc mode,not support y scale down:");
2515                         pr_err("srcH[%d] > 2 *dstH[%d]\n",
2516                                yrgb_srcH, yrgb_dstH);
2517                 }
2518         }
2519         DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
2520             win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
2521             win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
2522
2523         /* SCALE FACTOR */
2524
2525         /* (1.1)YRGB HOR SCALE FACTOR */
2526         switch (win->yrgb_hor_scl_mode) {
2527         case SCALE_NONE:
2528                 yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2529                 break;
2530         case SCALE_UP:
2531                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
2532                 break;
2533         case SCALE_DOWN:
2534                 switch (win->yrgb_hsd_mode) {
2535                 case SCALE_DOWN_BIL:
2536                         yrgb_xscl_factor =
2537                             GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
2538                         break;
2539                 case SCALE_DOWN_AVG:
2540                         yrgb_xscl_factor =
2541                             GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
2542                         break;
2543                 default:
2544                         pr_info("%s:un supported yrgb_hsd_mode:%d\n", __func__,
2545                                 win->yrgb_hsd_mode);
2546                         break;
2547                 }
2548                 break;
2549         default:
2550                 pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
2551                         __func__, win->yrgb_hor_scl_mode);
2552                 break;
2553         }
2554
2555         /* (1.2)YRGB VER SCALE FACTOR */
2556         switch (win->yrgb_ver_scl_mode) {
2557         case SCALE_NONE:
2558                 yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2559                 break;
2560         case SCALE_UP:
2561                 switch (win->yrgb_vsu_mode) {
2562                 case SCALE_UP_BIL:
2563                         yrgb_yscl_factor =
2564                             GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
2565                         break;
2566                 case SCALE_UP_BIC:
2567                         if (yrgb_srcH < 3) {
2568                                 pr_err("yrgb_srcH should be");
2569                                 pr_err(" greater than 3 !!!\n");
2570                         }
2571                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
2572                                                                 yrgb_dstH);
2573                         break;
2574                 default:
2575                         pr_info("%s:un support yrgb_vsu_mode:%d\n",
2576                                 __func__, win->yrgb_vsu_mode);
2577                         break;
2578                 }
2579                 break;
2580         case SCALE_DOWN:
2581                 switch (win->yrgb_vsd_mode) {
2582                 case SCALE_DOWN_BIL:
2583                         yrgb_vscalednmult =
2584                             vop_get_hard_ware_vskiplines(yrgb_srcH, yrgb_dstH);
2585                         yrgb_yscl_factor =
2586                             GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
2587                                                            yrgb_vscalednmult);
2588                         if (yrgb_yscl_factor >= 0x2000) {
2589                                 pr_err("yrgb_yscl_factor should less 0x2000");
2590                                 pr_err("yrgb_yscl_factor=%4x;\n",
2591                                        yrgb_yscl_factor);
2592                         }
2593                         if (yrgb_vscalednmult == 4) {
2594                                 yrgb_vsd_bil_gt4 = 1;
2595                                 yrgb_vsd_bil_gt2 = 0;
2596                         } else if (yrgb_vscalednmult == 2) {
2597                                 yrgb_vsd_bil_gt4 = 0;
2598                                 yrgb_vsd_bil_gt2 = 1;
2599                         } else {
2600                                 yrgb_vsd_bil_gt4 = 0;
2601                                 yrgb_vsd_bil_gt2 = 0;
2602                         }
2603                         break;
2604                 case SCALE_DOWN_AVG:
2605                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
2606                                                                  yrgb_dstH);
2607                         break;
2608                 default:
2609                         pr_info("%s:un support yrgb_vsd_mode:%d\n",
2610                                 __func__, win->yrgb_vsd_mode);
2611                         break;
2612                 }               /*win->yrgb_vsd_mode */
2613                 break;
2614         default:
2615                 pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
2616                         __func__, win->yrgb_ver_scl_mode);
2617                 break;
2618         }
2619         win->scale_yrgb_x = yrgb_xscl_factor;
2620         win->scale_yrgb_y = yrgb_yscl_factor;
2621         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
2622         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
2623         DBG(1, "yrgb:h_fac=%d, V_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
2624             yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
2625
2626         /*(2.1)CBCR HOR SCALE FACTOR */
2627         switch (win->cbr_hor_scl_mode) {
2628         case SCALE_NONE:
2629                 cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2630                 break;
2631         case SCALE_UP:
2632                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
2633                 break;
2634         case SCALE_DOWN:
2635                 switch (win->cbr_hsd_mode) {
2636                 case SCALE_DOWN_BIL:
2637                         cbcr_xscl_factor =
2638                             GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
2639                         break;
2640                 case SCALE_DOWN_AVG:
2641                         cbcr_xscl_factor =
2642                             GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
2643                         break;
2644                 default:
2645                         pr_info("%s:un support cbr_hsd_mode:%d\n",
2646                                 __func__, win->cbr_hsd_mode);
2647                         break;
2648                 }
2649                 break;
2650         default:
2651                 pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
2652                         __func__, win->cbr_hor_scl_mode);
2653                 break;
2654         }                       /*win->cbr_hor_scl_mode */
2655
2656         /* (2.2)CBCR VER SCALE FACTOR */
2657         switch (win->cbr_ver_scl_mode) {
2658         case SCALE_NONE:
2659                 cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2660                 break;
2661         case SCALE_UP:
2662                 switch (win->cbr_vsu_mode) {
2663                 case SCALE_UP_BIL:
2664                         cbcr_yscl_factor =
2665                             GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
2666                         break;
2667                 case SCALE_UP_BIC:
2668                         if (cbcr_srcH < 3) {
2669                                 pr_err("cbcr_srcH should be ");
2670                                 pr_err("greater than 3 !!!\n");
2671                         }
2672                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
2673                                                                 cbcr_dstH);
2674                         break;
2675                 default:
2676                         pr_info("%s:un support cbr_vsu_mode:%d\n",
2677                                 __func__, win->cbr_vsu_mode);
2678                         break;
2679                 }
2680                 break;
2681         case SCALE_DOWN:
2682                 switch (win->cbr_vsd_mode) {
2683                 case SCALE_DOWN_BIL:
2684                         cbcr_vscalednmult =
2685                             vop_get_hard_ware_vskiplines(cbcr_srcH, cbcr_dstH);
2686                         cbcr_yscl_factor =
2687                             GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
2688                                                            cbcr_vscalednmult);
2689                         if (cbcr_yscl_factor >= 0x2000) {
2690                                 pr_err("cbcr_yscl_factor should be less ");
2691                                 pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
2692                                        cbcr_yscl_factor);
2693                         }
2694
2695                         if (cbcr_vscalednmult == 4) {
2696                                 cbcr_vsd_bil_gt4 = 1;
2697                                 cbcr_vsd_bil_gt2 = 0;
2698                         } else if (cbcr_vscalednmult == 2) {
2699                                 cbcr_vsd_bil_gt4 = 0;
2700                                 cbcr_vsd_bil_gt2 = 1;
2701                         } else {
2702                                 cbcr_vsd_bil_gt4 = 0;
2703                                 cbcr_vsd_bil_gt2 = 0;
2704                         }
2705                         break;
2706                 case SCALE_DOWN_AVG:
2707                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
2708                                                                  cbcr_dstH);
2709                         break;
2710                 default:
2711                         pr_info("%s:un support cbr_vsd_mode:%d\n",
2712                                 __func__, win->cbr_vsd_mode);
2713                         break;
2714                 }
2715                 break;
2716         default:
2717                 pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
2718                         __func__, win->cbr_ver_scl_mode);
2719                 break;
2720         }
2721         win->scale_cbcr_x = cbcr_xscl_factor;
2722         win->scale_cbcr_y = cbcr_yscl_factor;
2723         win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
2724         win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
2725
2726         DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
2727             cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
2728         return 0;
2729 }
2730
2731 static int dsp_x_pos(int mirror_en, struct rk_screen *screen,
2732                      struct rk_lcdc_win_area *area)
2733 {
2734         int pos;
2735
2736         if (screen->x_mirror && mirror_en)
2737                 pr_err("not support both win and global mirror\n");
2738
2739         if ((!mirror_en) && (!screen->x_mirror))
2740                 pos = area->xpos + screen->mode.left_margin +
2741                         screen->mode.hsync_len;
2742         else
2743                 pos = screen->mode.xres - area->xpos -
2744                         area->xsize + screen->mode.left_margin +
2745                         screen->mode.hsync_len;
2746
2747         return pos;
2748 }
2749
2750 static int dsp_y_pos(int mirror_en, struct rk_screen *screen,
2751                      struct rk_lcdc_win_area *area)
2752 {
2753         int pos;
2754
2755         if (screen->y_mirror && mirror_en)
2756                 pr_err("not support both win and global mirror\n");
2757
2758         if ((!mirror_en) && (!screen->y_mirror))
2759                 pos = area->ypos + screen->mode.upper_margin +
2760                         screen->mode.vsync_len;
2761         else
2762                 pos = screen->mode.yres - area->ypos -
2763                         area->ysize + screen->mode.upper_margin +
2764                         screen->mode.vsync_len;
2765
2766         return pos;
2767 }
2768
2769 static int win_0_1_set_par(struct vop_device *vop_dev,
2770                            struct rk_screen *screen, struct rk_lcdc_win *win)
2771 {
2772         u32 xact, yact, xvir, yvir, xpos, ypos;
2773         u8 fmt_cfg = 0, swap_rb, swap_uv = 0;
2774         char fmt[9] = "NULL";
2775
2776         xpos = dsp_x_pos(win->xmirror, screen, &win->area[0]);
2777         ypos = dsp_y_pos(win->ymirror, screen, &win->area[0]);
2778
2779         spin_lock(&vop_dev->reg_lock);
2780         if (likely(vop_dev->clk_on)) {
2781                 vop_cal_scl_fac(win, screen);
2782                 switch (win->area[0].format) {
2783                 case FBDC_RGB_565:
2784                         fmt_cfg = 2;
2785                         swap_rb = 0;
2786                         win->fmt_10 = 0;
2787                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_RGB565;
2788                         break;
2789                 case FBDC_ARGB_888:
2790                         fmt_cfg = 0;
2791                         swap_rb = 1;
2792                         win->fmt_10 = 0;
2793                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
2794                         break;
2795                 case FBDC_ABGR_888:
2796                         fmt_cfg = 0;
2797                         swap_rb = 0;
2798                         win->fmt_10 = 0;
2799                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
2800                         break;
2801                 case FBDC_RGBX_888:
2802                         fmt_cfg = 0;
2803                         swap_rb = 0;
2804                         win->fmt_10 = 0;
2805                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
2806                         break;
2807                 case ARGB888:
2808                         fmt_cfg = 0;
2809                         swap_rb = 0;
2810                         win->fmt_10 = 0;
2811                         break;
2812                 case XBGR888:
2813                 case ABGR888:
2814                         fmt_cfg = 0;
2815                         swap_rb = 1;
2816                         win->fmt_10 = 0;
2817                         break;
2818                 case BGR888:
2819                         fmt_cfg = 1;
2820                         swap_rb = 1;
2821                         win->fmt_10 = 0;
2822                         break;
2823                 case RGB888:
2824                         fmt_cfg = 1;
2825                         swap_rb = 0;
2826                         win->fmt_10 = 0;
2827                         break;
2828                 case RGB565:
2829                         fmt_cfg = 2;
2830                         swap_rb = 0;
2831                         win->fmt_10 = 0;
2832                         break;
2833                 case YUV422:
2834                         fmt_cfg = 5;
2835                         swap_rb = 0;
2836                         win->fmt_10 = 0;
2837                         break;
2838                 case YUV420:
2839                         fmt_cfg = 4;
2840                         swap_rb = 0;
2841                         win->fmt_10 = 0;
2842                         break;
2843                 case YUV420_NV21:
2844                         fmt_cfg = 4;
2845                         swap_rb = 0;
2846                         swap_uv = 1;
2847                         win->fmt_10 = 0;
2848                         break;
2849                 case YUV444:
2850                         fmt_cfg = 6;
2851                         swap_rb = 0;
2852                         win->fmt_10 = 0;
2853                         break;
2854                 case YUV422_A:
2855                         fmt_cfg = 5;
2856                         swap_rb = 0;
2857                         win->fmt_10 = 1;
2858                         break;
2859                 case YUV420_A:
2860                         fmt_cfg = 4;
2861                         swap_rb = 0;
2862                         win->fmt_10 = 1;
2863                         break;
2864                 case YUV444_A:
2865                         fmt_cfg = 6;
2866                         swap_rb = 0;
2867                         win->fmt_10 = 1;
2868                         break;
2869                 case YUYV422:
2870                         fmt_cfg = 0;
2871                         swap_rb = 0;
2872                         win->fmt_10 = 0;
2873                         win->area[0].yuyv_fmt = 1;
2874                         break;
2875                 case YUYV420:
2876                         fmt_cfg = 1;
2877                         swap_rb = 0;
2878                         win->fmt_10 = 0;
2879                         win->area[0].yuyv_fmt = 1;
2880                         break;
2881                 case UYVY422:
2882                         fmt_cfg = 2;
2883                         swap_rb = 0;
2884                         win->fmt_10 = 0;
2885                         win->area[0].yuyv_fmt = 1;
2886                         break;
2887                 case UYVY420:
2888                         fmt_cfg = 3;
2889                         swap_rb = 0;
2890                         win->fmt_10 = 0;
2891                         win->area[0].yuyv_fmt = 1;
2892                         break;
2893                 default:
2894                         dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n",
2895                                 __func__, win->area[0].format);
2896                         break;
2897                 }
2898                 win->area[0].fmt_cfg = fmt_cfg;
2899                 win->area[0].swap_rb = swap_rb;
2900                 win->area[0].swap_uv = swap_uv;
2901                 win->area[0].dsp_stx = xpos;
2902                 win->area[0].dsp_sty = ypos;
2903                 xact = win->area[0].xact;
2904                 yact = win->area[0].yact;
2905                 xvir = win->area[0].xvir;
2906                 yvir = win->area[0].yvir;
2907         }
2908         if (win->area[0].fbdc_en)
2909                 vop_init_fbdc_config(vop_dev, win->id);
2910         vop_win_0_1_reg_update(&vop_dev->driver, win->id);
2911         spin_unlock(&vop_dev->reg_lock);
2912
2913         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2914             vop_dev->id, win->id, get_format_string(win->area[0].format, fmt),
2915             xact, yact, win->area[0].xsize);
2916         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
2917             win->area[0].ysize, xvir, yvir, xpos, ypos);
2918
2919         return 0;
2920 }
2921
2922 static int win_2_3_set_par(struct vop_device *vop_dev,
2923                            struct rk_screen *screen, struct rk_lcdc_win *win)
2924 {
2925         int i;
2926         u8 fmt_cfg, swap_rb;
2927         char fmt[9] = "NULL";
2928
2929         if (VOP_CHIP(vop_dev) == VOP_RK322X) {
2930                 pr_err("rk3228 not support win2/3 set par\n");
2931                 return -EINVAL;
2932         }
2933         if (win->ymirror) {
2934                 pr_err("win[%d] not support y mirror\n", win->id);
2935                 return -EINVAL;
2936         }
2937         spin_lock(&vop_dev->reg_lock);
2938         if (likely(vop_dev->clk_on)) {
2939                 DBG(2, "lcdc[%d]:win[%d]>>\n>\n", vop_dev->id, win->id);
2940                 for (i = 0; i < win->area_num; i++) {
2941                         switch (win->area[i].format) {
2942                         case FBDC_RGB_565:
2943                                 fmt_cfg = 2;
2944                                 swap_rb = 0;
2945                                 win->fmt_10 = 0;
2946                                 win->area[0].fbdc_fmt_cfg = 0x05;
2947                                 break;
2948                         case FBDC_ARGB_888:
2949                                 fmt_cfg = 0;
2950                                 swap_rb = 0;
2951                                 win->fmt_10 = 0;
2952                                 win->area[0].fbdc_fmt_cfg = 0x0c;
2953                                 break;
2954                         case FBDC_RGBX_888:
2955                                 fmt_cfg = 0;
2956                                 swap_rb = 0;
2957                                 win->fmt_10 = 0;
2958                                 win->area[0].fbdc_fmt_cfg = 0x3a;
2959                                 break;
2960                         case ARGB888:
2961                                 fmt_cfg = 0;
2962                                 swap_rb = 0;
2963                                 break;
2964                         case XBGR888:
2965                         case ABGR888:
2966                                 fmt_cfg = 0;
2967                                 swap_rb = 1;
2968                                 break;
2969                         case RGB888:
2970                                 fmt_cfg = 1;
2971                                 swap_rb = 0;
2972                                 break;
2973                         case RGB565:
2974                                 fmt_cfg = 2;
2975                                 swap_rb = 0;
2976                                 break;
2977                         default:
2978                                 dev_err(vop_dev->driver.dev,
2979                                         "%s:un supported format!\n", __func__);
2980                                 spin_unlock(&vop_dev->reg_lock);
2981                                 return -EINVAL;
2982                         }
2983                         win->area[i].fmt_cfg = fmt_cfg;
2984                         win->area[i].swap_rb = swap_rb;
2985                         win->area[i].dsp_stx = dsp_x_pos(win->xmirror, screen,
2986                                                          &win->area[i]);
2987                         win->area[i].dsp_sty = dsp_y_pos(win->ymirror, screen,
2988                                                          &win->area[i]);
2989                         if (((win->area[i].xact != win->area[i].xsize) ||
2990                              (win->area[i].yact != win->area[i].ysize)) &&
2991                             (screen->mode.vmode == FB_VMODE_NONINTERLACED)) {
2992                                 pr_err("win[%d]->area[%d],not support scale\n",
2993                                        win->id, i);
2994                                 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
2995                                        win->area[i].xact, win->area[i].yact,
2996                                        win->area[i].xsize, win->area[i].ysize);
2997                                 win->area[i].xsize = win->area[i].xact;
2998                                 win->area[i].ysize = win->area[i].yact;
2999                         }
3000                         DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
3001                             get_format_string(win->area[i].format, fmt),
3002                             win->area[i].xsize, win->area[i].ysize,
3003                             win->area[i].xpos, win->area[i].ypos);
3004                 }
3005         }
3006         if (win->area[0].fbdc_en)
3007                 vop_init_fbdc_config(vop_dev, win->id);
3008         vop_win_2_3_reg_update(&vop_dev->driver, win->id);
3009         spin_unlock(&vop_dev->reg_lock);
3010         return 0;
3011 }
3012
3013 static int hwc_set_par(struct vop_device *vop_dev,
3014                        struct rk_screen *screen, struct rk_lcdc_win *win)
3015 {
3016         u32 xact, yact, xvir, yvir, xpos, ypos;
3017         u8 fmt_cfg = 0, swap_rb;
3018         char fmt[9] = "NULL";
3019
3020         xpos = win->area[0].xpos + screen->mode.left_margin +
3021             screen->mode.hsync_len;
3022         ypos = win->area[0].ypos + screen->mode.upper_margin +
3023             screen->mode.vsync_len;
3024
3025         spin_lock(&vop_dev->reg_lock);
3026         if (likely(vop_dev->clk_on)) {
3027                 switch (win->area[0].format) {
3028                 case ARGB888:
3029                         fmt_cfg = 0;
3030                         swap_rb = 0;
3031                         break;
3032                 case XBGR888:
3033                 case ABGR888:
3034                         fmt_cfg = 0;
3035                         swap_rb = 1;
3036                         break;
3037                 case RGB888:
3038                         fmt_cfg = 1;
3039                         swap_rb = 0;
3040                         break;
3041                 case RGB565:
3042                         fmt_cfg = 2;
3043                         swap_rb = 0;
3044                         break;
3045                 default:
3046                         dev_err(vop_dev->dev, "%s:un supported format[%d]!\n",
3047                                 __func__, win->area[0].format);
3048                         break;
3049                 }
3050                 win->area[0].fmt_cfg = fmt_cfg;
3051                 win->area[0].swap_rb = swap_rb;
3052                 win->area[0].dsp_stx = xpos;
3053                 win->area[0].dsp_sty = ypos;
3054                 xact = win->area[0].xact;
3055                 yact = win->area[0].yact;
3056                 xvir = win->area[0].xvir;
3057                 yvir = win->area[0].yvir;
3058         }
3059         vop_hwc_reg_update(&vop_dev->driver, 4);
3060         spin_unlock(&vop_dev->reg_lock);
3061
3062         DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
3063             vop_dev->id, __func__, get_format_string(win->area[0].format, fmt),
3064             xact, yact, win->area[0].xsize);
3065         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
3066             win->area[0].ysize, xvir, yvir, xpos, ypos);
3067         return 0;
3068 }
3069
3070 static int vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
3071 {
3072         struct vop_device *vop_dev =
3073             container_of(dev_drv, struct vop_device, driver);
3074         struct rk_lcdc_win *win = NULL;
3075         struct rk_screen *screen = dev_drv->cur_screen;
3076
3077         if (unlikely(!vop_dev->clk_on)) {
3078                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
3079                 return 0;
3080         }
3081         win = dev_drv->win[win_id];
3082         if (win)
3083         switch (win_id) {
3084         case 0:
3085                 win_0_1_set_par(vop_dev, screen, win);
3086                 break;
3087         case 1:
3088                 win_0_1_set_par(vop_dev, screen, win);
3089                 break;
3090         case 2:
3091                 win_2_3_set_par(vop_dev, screen, win);
3092                 break;
3093         case 3:
3094                 win_2_3_set_par(vop_dev, screen, win);
3095                 break;
3096         case 4:
3097                 hwc_set_par(vop_dev, screen, win);
3098                 break;
3099         default:
3100                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
3101                 break;
3102         }
3103         return 0;
3104 }
3105
3106 static int vop_set_writeback(struct rk_lcdc_driver *dev_drv)
3107 {
3108         struct vop_device *vop_dev =
3109             container_of(dev_drv, struct vop_device, driver);
3110         int output_color = dev_drv->output_color;
3111         struct rk_screen *screen = dev_drv->cur_screen;
3112         struct rk_fb_reg_wb_data *wb_data;
3113         int xact = screen->mode.xres;
3114         int yact = screen->mode.yres;
3115         u32 fmt_cfg;
3116         int xsize, ysize;
3117         u64 v;
3118
3119         if (unlikely(!vop_dev->clk_on)) {
3120                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
3121                 return 0;
3122         }
3123         wb_data = &dev_drv->wb_data;
3124
3125         xsize = wb_data->xsize;
3126         ysize = wb_data->ysize;
3127
3128         /*
3129          * RGB overlay mode support ARGB888, RGB888, RGB565, NV12,
3130          * but YUV overlay mode only support NV12, it's hard to judge RGB
3131          * or YUV overlay mode by userspace, so here force only support
3132          * NV12 mode.
3133          */
3134         if (wb_data->data_format != YUV420 && output_color != COLOR_RGB) {
3135                 pr_err("writeback only support NV12 when overlay is not RGB\n");
3136                 return -EINVAL;
3137         }
3138
3139         if (ysize != yact && ysize != (yact / 2)) {
3140                 pr_err("WriteBack only support yact=%d, ysize=%d\n",
3141                        yact, ysize);
3142                 return -EINVAL;
3143         }
3144
3145         switch (wb_data->data_format) {
3146         case ARGB888:
3147                 fmt_cfg = 0;
3148                 break;
3149         case RGB888:
3150                 fmt_cfg = 1;
3151                 break;
3152         case RGB565:
3153                 fmt_cfg = 2;
3154                 break;
3155         case YUV420:
3156                 fmt_cfg = 8;
3157                 break;
3158         default:
3159                 pr_info("unsupport fmt: %d\n", wb_data->data_format);
3160                 return -EINVAL;
3161         }
3162
3163         v = V_WB_EN(wb_data->state) | V_WB_FMT(fmt_cfg) | V_WB_RGB2YUV_MODE(1) |
3164                 V_WB_XPSD_BIL_EN(xact != xsize) |
3165                 V_WB_YTHROW_EN(ysize == (yact / 2)) |
3166                 V_WB_YTHROW_MODE(0);
3167
3168         v |= V_WB_RGB2YUV_EN((output_color == COLOR_RGB) &&
3169                              (wb_data->data_format == YUV420));
3170
3171         vop_msk_reg(vop_dev, WB_CTRL0, v);
3172
3173         v = V_WB_WIDTH(xsize) | V_WB_XPSD_BIL_FACTOR((xact << 12) / xsize);
3174
3175         vop_msk_reg(vop_dev, WB_CTRL1, v);
3176
3177         vop_writel(vop_dev, WB_YRGB_MST, wb_data->smem_start);
3178         if (wb_data->data_format == YUV420)
3179                 vop_writel(vop_dev, WB_CBR_MST, wb_data->smem_start);
3180
3181         return 0;
3182 }
3183
3184 static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
3185                      unsigned long arg, int win_id)
3186 {
3187         struct vop_device *vop_dev =
3188                         container_of(dev_drv, struct vop_device, driver);
3189         u32 panel_size[2];
3190         void __user *argp = (void __user *)arg;
3191         struct color_key_cfg clr_key_cfg;
3192
3193         switch (cmd) {
3194         case RK_FBIOGET_PANEL_SIZE:
3195                 panel_size[0] = vop_dev->screen->mode.xres;
3196                 panel_size[1] = vop_dev->screen->mode.yres;
3197                 if (copy_to_user(argp, panel_size, 8))
3198                         return -EFAULT;
3199                 break;
3200         case RK_FBIOPUT_COLOR_KEY_CFG:
3201                 if (copy_from_user(&clr_key_cfg, argp, sizeof(clr_key_cfg)))
3202                         return -EFAULT;
3203                 vop_clr_key_cfg(dev_drv);
3204                 vop_writel(vop_dev, WIN0_COLOR_KEY,
3205                            clr_key_cfg.win0_color_key_cfg);
3206                 vop_writel(vop_dev, WIN1_COLOR_KEY,
3207                            clr_key_cfg.win1_color_key_cfg);
3208                 break;
3209
3210         default:
3211                 break;
3212         }
3213         return 0;
3214 }
3215
3216 static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv)
3217 {
3218         struct vop_device *vop_dev = container_of(dev_drv,
3219                                                     struct vop_device, driver);
3220         struct device_node *backlight;
3221         struct property *prop;
3222         u32 *brightness_levels;
3223         u32 length, max, last;
3224
3225         if (vop_dev->backlight)
3226                 return 0;
3227         backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0);
3228         if (backlight) {
3229                 vop_dev->backlight = of_find_backlight_by_node(backlight);
3230                 if (!vop_dev->backlight)
3231                         dev_info(vop_dev->dev, "No find backlight device\n");
3232         } else {
3233                 dev_info(vop_dev->dev, "No find backlight device node\n");
3234         }
3235         prop = of_find_property(backlight, "brightness-levels", &length);
3236         if (!prop)
3237                 return -EINVAL;
3238         max = length / sizeof(u32);
3239         last = max - 1;
3240         brightness_levels = kmalloc(256, GFP_KERNEL);
3241         if (brightness_levels)
3242                 return -ENOMEM;
3243
3244         if (!of_property_read_u32_array(backlight, "brightness-levels",
3245                                         brightness_levels, max)) {
3246                 if (brightness_levels[0] > brightness_levels[last])
3247                         dev_drv->cabc_pwm_pol = 1;/*negative*/
3248                 else
3249                         dev_drv->cabc_pwm_pol = 0;/*positive*/
3250         } else {
3251                 dev_info(vop_dev->dev,
3252                          "Can not read brightness-levels value\n");
3253         }
3254
3255         kfree(brightness_levels);
3256
3257         return 0;
3258 }
3259
3260 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv)
3261 {
3262         struct vop_device *vop_dev =
3263             container_of(dev_drv, struct vop_device, driver);
3264
3265         if (dev_drv->suspend_flag)
3266                 return 0;
3267
3268         dev_drv->suspend_flag = 1;
3269         /* ensure suspend_flag take effect on multi process */
3270         smp_wmb();
3271         flush_kthread_worker(&dev_drv->update_regs_worker);
3272
3273         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
3274                 dev_drv->trsm_ops->disable();
3275
3276         if (likely(vop_dev->clk_on)) {
3277                 spin_lock(&vop_dev->reg_lock);
3278                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(1));
3279                 vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
3280                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(1));
3281                 vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1));
3282                 vop_cfg_done(vop_dev);
3283
3284                 if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3285                         mdelay(50);
3286                         rockchip_iovmm_deactivate(dev_drv->dev);
3287                 }
3288
3289                 spin_unlock(&vop_dev->reg_lock);
3290         }
3291
3292         vop_clk_disable(vop_dev);
3293         rk_disp_pwr_disable(dev_drv);
3294
3295         return 0;
3296 }
3297
3298 static int vop_early_resume(struct rk_lcdc_driver *dev_drv)
3299 {
3300         struct vop_device *vop_dev =
3301             container_of(dev_drv, struct vop_device, driver);
3302
3303         if (!dev_drv->suspend_flag)
3304                 return 0;
3305         rk_disp_pwr_enable(dev_drv);
3306
3307         vop_clk_enable(vop_dev);
3308         spin_lock(&vop_dev->reg_lock);
3309         memcpy(vop_dev->regs, vop_dev->regsbak, vop_dev->len);
3310         spin_unlock(&vop_dev->reg_lock);
3311
3312         vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
3313         vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
3314         spin_lock(&vop_dev->reg_lock);
3315
3316         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(0));
3317         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(0));
3318         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(0));
3319         vop_cfg_done(vop_dev);
3320         spin_unlock(&vop_dev->reg_lock);
3321
3322         if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3323                 /* win address maybe effect after next frame start,
3324                  * but mmu maybe effect right now, so we delay 50ms
3325                  */
3326                 mdelay(50);
3327                 rockchip_iovmm_activate(dev_drv->dev);
3328         }
3329
3330         dev_drv->suspend_flag = 0;
3331
3332         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
3333                 dev_drv->trsm_ops->enable();
3334
3335         return 0;
3336 }
3337
3338 static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode)
3339 {
3340         switch (blank_mode) {
3341         case FB_BLANK_UNBLANK:
3342                 vop_early_resume(dev_drv);
3343                 break;
3344         case FB_BLANK_NORMAL:
3345                 vop_early_suspend(dev_drv);
3346                 break;
3347         default:
3348                 vop_early_suspend(dev_drv);
3349                 break;
3350         }
3351
3352         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
3353
3354         return 0;
3355 }
3356
3357 static int vop_get_win_state(struct rk_lcdc_driver *dev_drv,
3358                              int win_id, int area_id)
3359 {
3360         struct vop_device *vop_dev =
3361                         container_of(dev_drv, struct vop_device, driver);
3362         u32 area_status = 0, state = 0;
3363
3364         switch (win_id) {
3365         case 0:
3366                 area_status = vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
3367                 break;
3368         case 1:
3369                 area_status = vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
3370                 break;
3371         case 2:
3372                 if (area_id == 0)
3373                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3374                                                    V_WIN2_MST0_EN(0));
3375                 if (area_id == 1)
3376                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3377                                                    V_WIN2_MST1_EN(0));
3378                 if (area_id == 2)
3379                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3380                                                    V_WIN2_MST2_EN(0));
3381                 if (area_id == 3)
3382                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3383                                                    V_WIN2_MST3_EN(0));
3384                 break;
3385         case 3:
3386                 if (area_id == 0)
3387                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3388                                                    V_WIN3_MST0_EN(0));
3389                 if (area_id == 1)
3390                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3391                                                    V_WIN3_MST1_EN(0));
3392                 if (area_id == 2)
3393                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3394                                                    V_WIN3_MST2_EN(0));
3395                 if (area_id == 3)
3396                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3397                                                    V_WIN3_MST3_EN(0));
3398                 break;
3399         case 4:
3400                 area_status = vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0));
3401                 break;
3402         default:
3403                 pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n",
3404                        __func__, win_id, area_id);
3405                 break;
3406         }
3407
3408         state = (area_status > 0) ? 1 : 0;
3409         return state;
3410 }
3411
3412 static int vop_get_area_num(struct rk_lcdc_driver *dev_drv,
3413                             unsigned int *area_support)
3414 {
3415         struct vop_device *vop_dev =
3416             container_of(dev_drv, struct vop_device, driver);
3417
3418         area_support[0] = 1;
3419         area_support[1] = 1;
3420
3421         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
3422                 area_support[2] = 4;
3423                 area_support[3] = 4;
3424         }
3425
3426         return 0;
3427 }
3428
3429 /*overlay will be do at regupdate*/
3430 static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set)
3431 {
3432         struct vop_device *vop_dev =
3433             container_of(dev_drv, struct vop_device, driver);
3434         struct rk_lcdc_win *win = NULL;
3435         int i, ovl;
3436         u64 val;
3437         int z_order_num = 0;
3438         int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3439
3440         if (swap == 0) {
3441                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3442                         win = dev_drv->win[i];
3443                         if (win->state == 1)
3444                                 z_order_num++;
3445                 }
3446                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3447                         win = dev_drv->win[i];
3448                         if (win->state == 0)
3449                                 win->z_order = z_order_num++;
3450                         switch (win->z_order) {
3451                         case 0:
3452                                 layer0_sel = win->id;
3453                                 break;
3454                         case 1:
3455                                 layer1_sel = win->id;
3456                                 break;
3457                         case 2:
3458                                 layer2_sel = win->id;
3459                                 break;
3460                         case 3:
3461                                 layer3_sel = win->id;
3462                                 break;
3463                         default:
3464                                 break;
3465                         }
3466                 }
3467         } else {
3468                 layer0_sel = swap % 10;
3469                 layer1_sel = swap / 10 % 10;
3470                 layer2_sel = swap / 100 % 10;
3471                 layer3_sel = swap / 1000;
3472         }
3473
3474         spin_lock(&vop_dev->reg_lock);
3475         if (vop_dev->clk_on) {
3476                 if (set) {
3477                         val = V_DSP_LAYER0_SEL(layer0_sel) |
3478                             V_DSP_LAYER1_SEL(layer1_sel) |
3479                             V_DSP_LAYER2_SEL(layer2_sel) |
3480                             V_DSP_LAYER3_SEL(layer3_sel);
3481                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
3482                 } else {
3483                         layer0_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3484                                                   V_DSP_LAYER0_SEL(0));
3485                         layer1_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3486                                                   V_DSP_LAYER1_SEL(0));
3487                         layer2_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3488                                                   V_DSP_LAYER2_SEL(0));
3489                         layer3_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3490                                                   V_DSP_LAYER3_SEL(0));
3491                         ovl = layer3_sel * 1000 + layer2_sel * 100 +
3492                             layer1_sel * 10 + layer0_sel;
3493                 }
3494         } else {
3495                 ovl = -EPERM;
3496         }
3497         spin_unlock(&vop_dev->reg_lock);
3498
3499         return ovl;
3500 }
3501
3502 static char *vop_format_to_string(int format, char *fmt)
3503 {
3504         if (!fmt)
3505                 return NULL;
3506
3507         switch (format) {
3508         case 0:
3509                 strcpy(fmt, "ARGB888");
3510                 break;
3511         case 1:
3512                 strcpy(fmt, "RGB888");
3513                 break;
3514         case 2:
3515                 strcpy(fmt, "RGB565");
3516                 break;
3517         case 4:
3518                 strcpy(fmt, "YCbCr420");
3519                 break;
3520         case 5:
3521                 strcpy(fmt, "YCbCr422");
3522                 break;
3523         case 6:
3524                 strcpy(fmt, "YCbCr444");
3525         case 8:
3526                 strcpy(fmt, "YUYV422");
3527                 break;
3528         case 9:
3529                 strcpy(fmt, "YUYV420");
3530                 break;
3531         case 10:
3532                 strcpy(fmt, "UYVY422");
3533                 break;
3534         case 11:
3535                 strcpy(fmt, "UYVY420");
3536                 break;
3537         default:
3538                 strcpy(fmt, "invalid\n");
3539                 break;
3540         }
3541         return fmt;
3542 }
3543
3544 static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
3545                                  char *buf, int win_id)
3546 {
3547         struct vop_device *vop_dev =
3548             container_of(dev_drv, struct vop_device, driver);
3549         struct rk_screen *screen = dev_drv->cur_screen;
3550         u16 hsync_len = screen->mode.hsync_len;
3551         u16 left_margin = screen->mode.left_margin;
3552         u16 vsync_len = screen->mode.vsync_len;
3553         u16 upper_margin = screen->mode.upper_margin;
3554         u32 h_pw_bp = hsync_len + left_margin;
3555         u32 v_pw_bp = vsync_len + upper_margin;
3556         u32 fmt_id;
3557         char format_w0[9] = "NULL";
3558         char format_w1[9] = "NULL";
3559         char format_w2_0[9] = "NULL";
3560         char format_w2_1[9] = "NULL";
3561         char format_w2_2[9] = "NULL";
3562         char format_w2_3[9] = "NULL";
3563         char format_w3_0[9] = "NULL";
3564         char format_w3_1[9] = "NULL";
3565         char format_w3_2[9] = "NULL";
3566         char format_w3_3[9] = "NULL";
3567         char dsp_buf[100];
3568         u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
3569         u32 y_factor, uv_factor;
3570         u8 layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3571         u8 w0_state, w1_state, w2_state, w3_state;
3572         u8 w2_0_state, w2_1_state, w2_2_state, w2_3_state;
3573         u8 w3_0_state, w3_1_state, w3_2_state, w3_3_state;
3574
3575         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
3576         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
3577         u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
3578         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
3579         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
3580         u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
3581
3582         u32 w2_0_vir_y, w2_1_vir_y, w2_2_vir_y, w2_3_vir_y;
3583         u32 w2_0_dsp_x, w2_1_dsp_x, w2_2_dsp_x, w2_3_dsp_x;
3584         u32 w2_0_dsp_y, w2_1_dsp_y, w2_2_dsp_y, w2_3_dsp_y;
3585         u32 w2_0_st_x = h_pw_bp, w2_1_st_x = h_pw_bp;
3586         u32 w2_2_st_x = h_pw_bp, w2_3_st_x = h_pw_bp;
3587         u32 w2_0_st_y = v_pw_bp, w2_1_st_y = v_pw_bp;
3588         u32 w2_2_st_y = v_pw_bp, w2_3_st_y = v_pw_bp;
3589
3590         u32 w3_0_vir_y, w3_1_vir_y, w3_2_vir_y, w3_3_vir_y;
3591         u32 w3_0_dsp_x, w3_1_dsp_x, w3_2_dsp_x, w3_3_dsp_x;
3592         u32 w3_0_dsp_y, w3_1_dsp_y, w3_2_dsp_y, w3_3_dsp_y;
3593         u32 w3_0_st_x = h_pw_bp, w3_1_st_x = h_pw_bp;
3594         u32 w3_2_st_x = h_pw_bp, w3_3_st_x = h_pw_bp;
3595         u32 w3_0_st_y = v_pw_bp, w3_1_st_y = v_pw_bp;
3596         u32 w3_2_st_y = v_pw_bp, w3_3_st_y = v_pw_bp;
3597         u32 dclk_freq;
3598         int size = 0;
3599
3600         dclk_freq = screen->mode.pixclock;
3601         /*vop_reg_dump(dev_drv); */
3602
3603         spin_lock(&vop_dev->reg_lock);
3604         if (vop_dev->clk_on) {
3605                 zorder = vop_readl(vop_dev, DSP_CTRL1);
3606                 layer0_sel = (zorder & MASK(DSP_LAYER0_SEL)) >> 8;
3607                 layer1_sel = (zorder & MASK(DSP_LAYER1_SEL)) >> 10;
3608                 layer2_sel = (zorder & MASK(DSP_LAYER2_SEL)) >> 12;
3609                 layer3_sel = (zorder & MASK(DSP_LAYER3_SEL)) >> 14;
3610                 /* WIN0 */
3611                 win_ctrl = vop_readl(vop_dev, WIN0_CTRL0);
3612                 w0_state = win_ctrl & MASK(WIN0_EN);
3613                 fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1;
3614                 fmt_id |= (win_ctrl & MASK(WIN0_YUYV)) >> 14; /* yuyv*/
3615                 vop_format_to_string(fmt_id, format_w0);
3616                 vir_info = vop_readl(vop_dev, WIN0_VIR);
3617                 act_info = vop_readl(vop_dev, WIN0_ACT_INFO);
3618                 dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO);
3619                 dsp_st = vop_readl(vop_dev, WIN0_DSP_ST);
3620                 y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB);
3621                 uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR);
3622                 w0_vir_y = vir_info & MASK(WIN0_VIR_STRIDE);
3623                 w0_vir_uv = (vir_info & MASK(WIN0_VIR_STRIDE_UV)) >> 16;
3624                 w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1;
3625                 w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
3626                 w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1;
3627                 w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
3628                 if (w0_state) {
3629                         w0_st_x = dsp_st & MASK(WIN0_DSP_XST);
3630                         w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16;
3631                 }
3632                 w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB);
3633                 w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16;
3634                 w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR);
3635                 w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16;
3636
3637                 /* WIN1 */
3638                 win_ctrl = vop_readl(vop_dev, WIN1_CTRL0);
3639                 w1_state = win_ctrl & MASK(WIN1_EN);
3640                 fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1;
3641                 fmt_id |= (win_ctrl & MASK(WIN1_YUYV)) >> 14; /* yuyv*/
3642                 vop_format_to_string(fmt_id, format_w1);
3643                 vir_info = vop_readl(vop_dev, WIN1_VIR);
3644                 act_info = vop_readl(vop_dev, WIN1_ACT_INFO);
3645                 dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO);
3646                 dsp_st = vop_readl(vop_dev, WIN1_DSP_ST);
3647                 y_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_YRGB);
3648                 uv_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_CBR);
3649                 w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE);
3650                 w1_vir_uv = (vir_info & MASK(WIN1_VIR_STRIDE_UV)) >> 16;
3651                 w1_act_x = (act_info & MASK(WIN1_ACT_WIDTH)) + 1;
3652                 w1_act_y = ((act_info & MASK(WIN1_ACT_HEIGHT)) >> 16) + 1;
3653                 w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1;
3654                 w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1;
3655                 if (w1_state) {
3656                         w1_st_x = dsp_st & MASK(WIN1_DSP_XST);
3657                         w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16;
3658                 }
3659                 w1_y_h_fac = y_factor & MASK(WIN1_HS_FACTOR_YRGB);
3660                 w1_y_v_fac = (y_factor & MASK(WIN1_VS_FACTOR_YRGB)) >> 16;
3661                 w1_uv_h_fac = uv_factor & MASK(WIN1_HS_FACTOR_CBR);
3662                 w1_uv_v_fac = (uv_factor & MASK(WIN1_VS_FACTOR_CBR)) >> 16;
3663
3664                 /*WIN2 */
3665                 win_ctrl = vop_readl(vop_dev, WIN2_CTRL0);
3666                 w2_state = win_ctrl & MASK(WIN2_EN);
3667                 w2_0_state = (win_ctrl & 0x10) >> 4;
3668                 w2_1_state = (win_ctrl & 0x100) >> 8;
3669                 w2_2_state = (win_ctrl & 0x1000) >> 12;
3670                 w2_3_state = (win_ctrl & 0x10000) >> 16;
3671                 vir_info = vop_readl(vop_dev, WIN2_VIR0_1);
3672                 w2_0_vir_y = vir_info & MASK(WIN2_VIR_STRIDE0);
3673                 w2_1_vir_y = (vir_info & MASK(WIN2_VIR_STRIDE1)) >> 16;
3674                 vir_info = vop_readl(vop_dev, WIN2_VIR2_3);
3675                 w2_2_vir_y = vir_info & MASK(WIN2_VIR_STRIDE2);
3676                 w2_3_vir_y = (vir_info & MASK(WIN2_VIR_STRIDE3)) >> 16;
3677
3678                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT0)) >> 5;
3679                 vop_format_to_string(fmt_id, format_w2_0);
3680                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT1)) >> 9;
3681                 vop_format_to_string(fmt_id, format_w2_1);
3682                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT2)) >> 13;
3683                 vop_format_to_string(fmt_id, format_w2_2);
3684                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT3)) >> 17;
3685                 vop_format_to_string(fmt_id, format_w2_3);
3686
3687                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO0);
3688                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST0);
3689                 w2_0_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH0)) + 1;
3690                 w2_0_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT0)) >> 16) + 1;
3691                 if (w2_0_state) {
3692                         w2_0_st_x = dsp_st & MASK(WIN2_DSP_XST0);
3693                         w2_0_st_y = (dsp_st & MASK(WIN2_DSP_YST0)) >> 16;
3694                 }
3695                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO1);
3696                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST1);
3697                 w2_1_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH1)) + 1;
3698                 w2_1_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT1)) >> 16) + 1;
3699                 if (w2_1_state) {
3700                         w2_1_st_x = dsp_st & MASK(WIN2_DSP_XST1);
3701                         w2_1_st_y = (dsp_st & MASK(WIN2_DSP_YST1)) >> 16;
3702                 }
3703                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO2);
3704                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST2);
3705                 w2_2_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH2)) + 1;
3706                 w2_2_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT2)) >> 16) + 1;
3707                 if (w2_2_state) {
3708                         w2_2_st_x = dsp_st & MASK(WIN2_DSP_XST2);
3709                         w2_2_st_y = (dsp_st & MASK(WIN2_DSP_YST2)) >> 16;
3710                 }
3711                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO3);
3712                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST3);
3713                 w2_3_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH3)) + 1;
3714                 w2_3_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT3)) >> 16) + 1;
3715                 if (w2_3_state) {
3716                         w2_3_st_x = dsp_st & MASK(WIN2_DSP_XST3);
3717                         w2_3_st_y = (dsp_st & MASK(WIN2_DSP_YST3)) >> 16;
3718                 }
3719
3720                 /*WIN3 */
3721                 win_ctrl = vop_readl(vop_dev, WIN3_CTRL0);
3722                 w3_state = win_ctrl & MASK(WIN3_EN);
3723                 w3_0_state = (win_ctrl & 0x10) >> 4;
3724                 w3_1_state = (win_ctrl & 0x100) >> 8;
3725                 w3_2_state = (win_ctrl & 0x1000) >> 12;
3726                 w3_3_state = (win_ctrl & 0x10000) >> 16;
3727                 vir_info = vop_readl(vop_dev, WIN3_VIR0_1);
3728                 w3_0_vir_y = vir_info & MASK(WIN3_VIR_STRIDE0);
3729                 w3_1_vir_y = (vir_info & MASK(WIN3_VIR_STRIDE1)) >> 16;
3730                 vir_info = vop_readl(vop_dev, WIN3_VIR2_3);
3731                 w3_2_vir_y = vir_info & MASK(WIN3_VIR_STRIDE2);
3732                 w3_3_vir_y = (vir_info & MASK(WIN3_VIR_STRIDE3)) >> 16;
3733
3734                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT0)) >> 5;
3735                 vop_format_to_string(fmt_id, format_w3_0);
3736                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT1)) >> 9;
3737                 vop_format_to_string(fmt_id, format_w3_1);
3738                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT2)) >> 13;
3739                 vop_format_to_string(fmt_id, format_w3_2);
3740                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT3)) >> 17;
3741                 vop_format_to_string(fmt_id, format_w3_3);
3742
3743                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO0);
3744                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST0);
3745                 w3_0_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH0)) + 1;
3746                 w3_0_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT0)) >> 16) + 1;
3747                 if (w3_0_state) {
3748                         w3_0_st_x = dsp_st & MASK(WIN3_DSP_XST0);
3749                         w3_0_st_y = (dsp_st & MASK(WIN3_DSP_YST0)) >> 16;
3750                 }
3751                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO1);
3752                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST1);
3753                 w3_1_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH1)) + 1;
3754                 w3_1_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT1)) >> 16) + 1;
3755                 if (w3_1_state) {
3756                         w3_1_st_x = dsp_st & MASK(WIN3_DSP_XST1);
3757                         w3_1_st_y = (dsp_st & MASK(WIN3_DSP_YST1)) >> 16;
3758                 }
3759                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO2);
3760                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST2);
3761                 w3_2_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH2)) + 1;
3762                 w3_2_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT2)) >> 16) + 1;
3763                 if (w3_2_state) {
3764                         w3_2_st_x = dsp_st & MASK(WIN3_DSP_XST2);
3765                         w3_2_st_y = (dsp_st & MASK(WIN3_DSP_YST2)) >> 16;
3766                 }
3767                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO3);
3768                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST3);
3769                 w3_3_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH3)) + 1;
3770                 w3_3_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT3)) >> 16) + 1;
3771                 if (w3_3_state) {
3772                         w3_3_st_x = dsp_st & MASK(WIN3_DSP_XST3);
3773                         w3_3_st_y = (dsp_st & MASK(WIN3_DSP_YST3)) >> 16;
3774                 }
3775         } else {
3776                 spin_unlock(&vop_dev->reg_lock);
3777                 return -EPERM;
3778         }
3779         spin_unlock(&vop_dev->reg_lock);
3780         size += snprintf(dsp_buf, 80,
3781                 "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
3782                 layer1_sel, layer0_sel, layer2_sel, layer3_sel);
3783         strcat(buf, dsp_buf);
3784         memset(dsp_buf, 0, sizeof(dsp_buf));
3785         /* win0 */
3786         size += snprintf(dsp_buf, 80,
3787                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3788                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
3789         strcat(buf, dsp_buf);
3790         memset(dsp_buf, 0, sizeof(dsp_buf));
3791
3792         size += snprintf(dsp_buf, 80,
3793                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3794                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
3795         strcat(buf, dsp_buf);
3796         memset(dsp_buf, 0, sizeof(dsp_buf));
3797
3798         size += snprintf(dsp_buf, 80,
3799                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3800                  w0_st_x - h_pw_bp, w0_st_y - v_pw_bp, w0_y_h_fac, w0_y_v_fac);
3801         strcat(buf, dsp_buf);
3802         memset(dsp_buf, 0, sizeof(dsp_buf));
3803
3804         size += snprintf(dsp_buf, 80,
3805                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3806                  w0_uv_h_fac, w0_uv_v_fac, vop_readl(vop_dev, WIN0_YRGB_MST),
3807                  vop_readl(vop_dev, WIN0_CBR_MST));
3808         strcat(buf, dsp_buf);
3809         memset(dsp_buf, 0, sizeof(dsp_buf));
3810
3811         /* win1 */
3812         size += snprintf(dsp_buf, 80,
3813                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3814                  w1_state, format_w1, w1_vir_y, w1_vir_uv);
3815         strcat(buf, dsp_buf);
3816         memset(dsp_buf, 0, sizeof(dsp_buf));
3817
3818         size += snprintf(dsp_buf, 80,
3819                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3820                  w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
3821         strcat(buf, dsp_buf);
3822         memset(dsp_buf, 0, sizeof(dsp_buf));
3823
3824         size += snprintf(dsp_buf, 80,
3825                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3826                  w1_st_x - h_pw_bp, w1_st_y - v_pw_bp, w1_y_h_fac, w1_y_v_fac);
3827         strcat(buf, dsp_buf);
3828         memset(dsp_buf, 0, sizeof(dsp_buf));
3829
3830         size += snprintf(dsp_buf, 80,
3831                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3832                  w1_uv_h_fac, w1_uv_v_fac, vop_readl(vop_dev, WIN1_YRGB_MST),
3833                  vop_readl(vop_dev, WIN1_CBR_MST));
3834         strcat(buf, dsp_buf);
3835         memset(dsp_buf, 0, sizeof(dsp_buf));
3836
3837         /*win2*/
3838         size += snprintf(dsp_buf, 80,
3839                  "win2:\n  state:%d\n",
3840                  w2_state);
3841         strcat(buf, dsp_buf);
3842         memset(dsp_buf, 0, sizeof(dsp_buf));
3843         /*area 0*/
3844         size += snprintf(dsp_buf, 80,
3845                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3846                  w2_0_state, format_w2_0, w2_0_dsp_x, w2_0_dsp_y);
3847         strcat(buf, dsp_buf);
3848         memset(dsp_buf, 0, sizeof(dsp_buf));
3849         size += snprintf(dsp_buf, 80,
3850                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3851                  w2_0_st_x - h_pw_bp, w2_0_st_y - v_pw_bp,
3852                  vop_readl(vop_dev, WIN2_MST0));
3853         strcat(buf, dsp_buf);
3854         memset(dsp_buf, 0, sizeof(dsp_buf));
3855
3856         /*area 1*/
3857         size += snprintf(dsp_buf, 80,
3858                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3859                  w2_1_state, format_w2_1, w2_1_dsp_x, w2_1_dsp_y);
3860         strcat(buf, dsp_buf);
3861         memset(dsp_buf, 0, sizeof(dsp_buf));
3862         size += snprintf(dsp_buf, 80,
3863                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3864                  w2_1_st_x - h_pw_bp, w2_1_st_y - v_pw_bp,
3865                  vop_readl(vop_dev, WIN2_MST1));
3866         strcat(buf, dsp_buf);
3867         memset(dsp_buf, 0, sizeof(dsp_buf));
3868
3869         /*area 2*/
3870         size += snprintf(dsp_buf, 80,
3871                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3872                  w2_2_state, format_w2_2, w2_2_dsp_x, w2_2_dsp_y);
3873         strcat(buf, dsp_buf);
3874         memset(dsp_buf, 0, sizeof(dsp_buf));
3875         size += snprintf(dsp_buf, 80,
3876                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3877                  w2_2_st_x - h_pw_bp, w2_2_st_y - v_pw_bp,
3878                  vop_readl(vop_dev, WIN2_MST2));
3879         strcat(buf, dsp_buf);
3880         memset(dsp_buf, 0, sizeof(dsp_buf));
3881
3882         /*area 3*/
3883         size += snprintf(dsp_buf, 80,
3884                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3885                  w2_3_state, format_w2_3, w2_3_dsp_x, w2_3_dsp_y);
3886         strcat(buf, dsp_buf);
3887         memset(dsp_buf, 0, sizeof(dsp_buf));
3888         size += snprintf(dsp_buf, 80,
3889                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3890                  w2_3_st_x - h_pw_bp, w2_3_st_y - v_pw_bp,
3891                  vop_readl(vop_dev, WIN2_MST3));
3892         strcat(buf, dsp_buf);
3893         memset(dsp_buf, 0, sizeof(dsp_buf));
3894
3895         /*win3*/
3896         size += snprintf(dsp_buf, 80,
3897                  "win3:\n  state:%d\n",
3898                  w3_state);
3899         strcat(buf, dsp_buf);
3900         memset(dsp_buf, 0, sizeof(dsp_buf));
3901         /*area 0*/
3902         size += snprintf(dsp_buf, 80,
3903                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3904                  w3_0_state, format_w3_0, w3_0_dsp_x, w3_0_dsp_y);
3905         strcat(buf, dsp_buf);
3906         memset(dsp_buf, 0, sizeof(dsp_buf));
3907         size += snprintf(dsp_buf, 80,
3908                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3909                  w3_0_st_x - h_pw_bp, w3_0_st_y - v_pw_bp,
3910                  vop_readl(vop_dev, WIN3_MST0));
3911         strcat(buf, dsp_buf);
3912         memset(dsp_buf, 0, sizeof(dsp_buf));
3913
3914         /*area 1*/
3915         size += snprintf(dsp_buf, 80,
3916                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3917                  w3_1_state, format_w3_1, w3_1_dsp_x, w3_1_dsp_y);
3918         strcat(buf, dsp_buf);
3919         memset(dsp_buf, 0, sizeof(dsp_buf));
3920         size += snprintf(dsp_buf, 80,
3921                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3922                  w3_1_st_x - h_pw_bp, w3_1_st_y - v_pw_bp,
3923                  vop_readl(vop_dev, WIN3_MST1));
3924         strcat(buf, dsp_buf);
3925         memset(dsp_buf, 0, sizeof(dsp_buf));
3926
3927         /*area 2*/
3928         size += snprintf(dsp_buf, 80,
3929                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3930                  w3_2_state, format_w3_2, w3_2_dsp_x, w3_2_dsp_y);
3931         strcat(buf, dsp_buf);
3932         memset(dsp_buf, 0, sizeof(dsp_buf));
3933         size += snprintf(dsp_buf, 80,
3934                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3935                  w3_2_st_x - h_pw_bp, w3_2_st_y - v_pw_bp,
3936                  vop_readl(vop_dev, WIN3_MST2));
3937         strcat(buf, dsp_buf);
3938         memset(dsp_buf, 0, sizeof(dsp_buf));
3939
3940         /*area 3*/
3941         size += snprintf(dsp_buf, 80,
3942                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3943                  w3_3_state, format_w3_3, w3_3_dsp_x, w3_3_dsp_y);
3944         strcat(buf, dsp_buf);
3945         memset(dsp_buf, 0, sizeof(dsp_buf));
3946         size += snprintf(dsp_buf, 80,
3947                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3948                  w3_3_st_x - h_pw_bp, w3_3_st_y - v_pw_bp,
3949                  vop_readl(vop_dev, WIN3_MST3));
3950         strcat(buf, dsp_buf);
3951         memset(dsp_buf, 0, sizeof(dsp_buf));
3952
3953         return size;
3954 }
3955
3956 static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set)
3957 {
3958         struct vop_device *vop_dev =
3959             container_of(dev_drv, struct vop_device, driver);
3960         struct rk_screen *screen = dev_drv->cur_screen;
3961         u64 ft = 0;
3962         u32 dotclk;
3963         int ret;
3964         u32 pixclock;
3965         u32 x_total, y_total;
3966
3967         if (set) {
3968                 if (fps == 0) {
3969                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
3970                         return 0;
3971                 }
3972                 ft = div_u64(1000000000000llu, fps);
3973                 x_total =
3974                     screen->mode.upper_margin + screen->mode.lower_margin +
3975                     screen->mode.yres + screen->mode.vsync_len;
3976                 y_total =
3977                     screen->mode.left_margin + screen->mode.right_margin +
3978                     screen->mode.xres + screen->mode.hsync_len;
3979                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
3980                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
3981                 ret = clk_set_rate(vop_dev->dclk, dotclk);
3982         }
3983
3984         pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
3985         vop_dev->pixclock = pixclock;
3986         dev_drv->pixclock = vop_dev->pixclock;
3987         fps = rk_fb_calc_fps(screen, pixclock);
3988         screen->ft = 1000 / fps;        /*one frame time in ms */
3989
3990         if (set)
3991                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
3992                          clk_get_rate(vop_dev->dclk), fps);
3993
3994         return fps;
3995 }
3996
3997 static int vop_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
3998 {
3999         mutex_lock(&dev_drv->fb_win_id_mutex);
4000         if (order == FB_DEFAULT_ORDER)
4001                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
4002         dev_drv->fb4_win_id = order / 10000;
4003         dev_drv->fb3_win_id = (order / 1000) % 10;
4004         dev_drv->fb2_win_id = (order / 100) % 10;
4005         dev_drv->fb1_win_id = (order / 10) % 10;
4006         dev_drv->fb0_win_id = order % 10;
4007         mutex_unlock(&dev_drv->fb_win_id_mutex);
4008
4009         return 0;
4010 }
4011
4012 static int vop_get_win_id(struct rk_lcdc_driver *dev_drv, const char *id)
4013 {
4014         int win_id = 0;
4015
4016         mutex_lock(&dev_drv->fb_win_id_mutex);
4017         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
4018                 win_id = dev_drv->fb0_win_id;
4019         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
4020                 win_id = dev_drv->fb1_win_id;
4021         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
4022                 win_id = dev_drv->fb2_win_id;
4023         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
4024                 win_id = dev_drv->fb3_win_id;
4025         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
4026                 win_id = dev_drv->fb4_win_id;
4027         mutex_unlock(&dev_drv->fb_win_id_mutex);
4028
4029         return win_id;
4030 }
4031
4032 static int vop_config_done(struct rk_lcdc_driver *dev_drv)
4033 {
4034         struct vop_device *vop_dev =
4035             container_of(dev_drv, struct vop_device, driver);
4036         int i, fbdc_en = 0;
4037         u64 val;
4038         struct rk_lcdc_win *win = NULL;
4039
4040         spin_lock(&vop_dev->reg_lock);
4041         vop_post_cfg(dev_drv);
4042         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby));
4043         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
4044                 win = dev_drv->win[i];
4045                 fbdc_en |= win->area[0].fbdc_en;
4046                 if ((win->state == 0) && (win->last_state == 1)) {
4047                         switch (win->id) {
4048                         case 0:
4049                                 val = V_WIN0_EN(0);
4050                                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
4051                                 break;
4052                         case 1:
4053                                 val = V_WIN1_EN(0);
4054                                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
4055                                 break;
4056                         case 2:
4057                                 val = V_WIN2_EN(0) | V_WIN2_MST0_EN(0) |
4058                                     V_WIN2_MST1_EN(0) |
4059                                     V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
4060                                 vop_msk_reg(vop_dev, WIN2_CTRL0, val);
4061                                 break;
4062                         case 3:
4063                                 val = V_WIN3_EN(0) | V_WIN3_MST0_EN(0) |
4064                                     V_WIN3_MST1_EN(0) |
4065                                     V_WIN3_MST2_EN(0) | V_WIN3_MST3_EN(0);
4066                                 vop_msk_reg(vop_dev, WIN3_CTRL0, val);
4067                                 break;
4068                         case 4:
4069                                 val = V_HWC_EN(0);
4070                                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
4071                                 break;
4072                         default:
4073                                 break;
4074                         }
4075                 }
4076                 win->last_state = win->state;
4077         }
4078         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
4079                 val = V_VOP_FBDC_EN(fbdc_en);
4080                 vop_msk_reg(vop_dev, AFBCD0_CTRL, val);
4081         }
4082         vop_cfg_done(vop_dev);
4083         spin_unlock(&vop_dev->reg_lock);
4084         return 0;
4085 }
4086
4087 static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
4088 {
4089         struct vop_device *vop_dev =
4090             container_of(dev_drv, struct vop_device, driver);
4091         spin_lock(&vop_dev->reg_lock);
4092         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(open));
4093         vop_cfg_done(vop_dev);
4094         spin_unlock(&vop_dev->reg_lock);
4095         return 0;
4096 }
4097
4098 static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
4099 {
4100         struct vop_device *vop_dev = container_of(dev_drv,
4101                                                     struct vop_device, driver);
4102         spin_lock(&vop_dev->reg_lock);
4103         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_LAYER_SEL(win_id));
4104         vop_cfg_done(vop_dev);
4105         spin_unlock(&vop_dev->reg_lock);
4106         return 0;
4107 }
4108
4109 static int vop_dpi_status(struct rk_lcdc_driver *dev_drv)
4110 {
4111         struct vop_device *vop_dev =
4112             container_of(dev_drv, struct vop_device, driver);
4113         int ovl;
4114
4115         spin_lock(&vop_dev->reg_lock);
4116         ovl = vop_read_bit(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(0));
4117         spin_unlock(&vop_dev->reg_lock);
4118         return ovl;
4119 }
4120
4121 static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
4122 {
4123         struct vop_device *vop_dev =
4124                         container_of(dev_drv, struct vop_device, driver);
4125         if (enable)
4126                 enable_irq(vop_dev->irq);
4127         else
4128                 disable_irq(vop_dev->irq);
4129         return 0;
4130 }
4131
4132 int vop_poll_vblank(struct rk_lcdc_driver *dev_drv)
4133 {
4134         struct vop_device *vop_dev =
4135             container_of(dev_drv, struct vop_device, driver);
4136         u32 int_reg;
4137         int ret;
4138
4139         if (vop_dev->clk_on && (!dev_drv->suspend_flag)) {
4140                 int_reg = vop_readl(vop_dev, INTR_STATUS0);
4141                 if (int_reg & INTR_LINE_FLAG0) {
4142                         vop_dev->driver.frame_time.last_framedone_t =
4143                             vop_dev->driver.frame_time.framedone_t;
4144                         vop_dev->driver.frame_time.framedone_t = cpu_clock(0);
4145                         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_LINE_FLAG0,
4146                                         INTR_LINE_FLAG0);
4147                         ret = RK_LF_STATUS_FC;
4148                 } else {
4149                         ret = RK_LF_STATUS_FR;
4150                 }
4151         } else {
4152                 ret = RK_LF_STATUS_NC;
4153         }
4154
4155         return ret;
4156 }
4157
4158 static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
4159                             unsigned int dsp_addr[][4])
4160 {
4161         struct vop_device *vop_dev =
4162             container_of(dev_drv, struct vop_device, driver);
4163         spin_lock(&vop_dev->reg_lock);
4164         if (vop_dev->clk_on) {
4165                 dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST);
4166                 dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST);
4167                 dsp_addr[2][0] = vop_readl(vop_dev, WIN2_MST0);
4168                 dsp_addr[2][1] = vop_readl(vop_dev, WIN2_MST1);
4169                 dsp_addr[2][2] = vop_readl(vop_dev, WIN2_MST2);
4170                 dsp_addr[2][3] = vop_readl(vop_dev, WIN2_MST3);
4171                 dsp_addr[3][0] = vop_readl(vop_dev, WIN3_MST0);
4172                 dsp_addr[3][1] = vop_readl(vop_dev, WIN3_MST1);
4173                 dsp_addr[3][2] = vop_readl(vop_dev, WIN3_MST2);
4174                 dsp_addr[3][3] = vop_readl(vop_dev, WIN3_MST3);
4175                 dsp_addr[4][0] = vop_readl(vop_dev, HWC_MST);
4176         }
4177         spin_unlock(&vop_dev->reg_lock);
4178         return 0;
4179 }
4180
4181
4182 int vop_update_pwm(int bl_pwm_period, int bl_pwm_duty)
4183 {
4184         /*
4185          * TODO:
4186          * pwm_period_hpr = bl_pwm_period;
4187          * pwm_duty_lpr = bl_pwm_duty;
4188          * pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n",
4189          * bl_pwm_period, bl_pwm_duty);
4190          */
4191
4192         return 0;
4193 }
4194
4195 /*
4196  *  a:[-30~0]:
4197  *    sin_hue = sin(a)*256 +0x100;
4198  *    cos_hue = cos(a)*256;
4199  *  a:[0~30]
4200  *    sin_hue = sin(a)*256;
4201  *    cos_hue = cos(a)*256;
4202  */
4203 static int vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode)
4204 {
4205         struct vop_device *vop_dev =
4206             container_of(dev_drv, struct vop_device, driver);
4207         u32 val;
4208
4209         spin_lock(&vop_dev->reg_lock);
4210         if (vop_dev->clk_on) {
4211                 val = vop_readl(vop_dev, BCSH_H);
4212                 switch (mode) {
4213                 case H_SIN:
4214                         val &= MASK(SIN_HUE);
4215                         break;
4216                 case H_COS:
4217                         val &= MASK(COS_HUE);
4218                         val >>= 16;
4219                         break;
4220                 default:
4221                         break;
4222                 }
4223         }
4224         spin_unlock(&vop_dev->reg_lock);
4225
4226         return val;
4227 }
4228
4229 static int vop_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode,
4230                             int calc, int up, int down, int global)
4231 {
4232         struct vop_device *vop_dev =
4233                         container_of(dev_drv, struct vop_device, driver);
4234         struct rk_screen *screen = dev_drv->cur_screen;
4235         u32 total_pixel, calc_pixel, stage_up, stage_down;
4236         u32 pixel_num, global_dn;
4237
4238         if (!vop_dev->cabc_lut_addr_base) {
4239                 pr_err("vop chip[%d] not supoort cabc\n", VOP_CHIP(vop_dev));
4240                 return 0;
4241         }
4242
4243         if (!screen->cabc_lut) {
4244                 pr_err("screen cabc lut not config, so not open cabc\n");
4245                 return 0;
4246         }
4247
4248         dev_drv->cabc_mode = mode;
4249         if (!dev_drv->cabc_mode) {
4250                 spin_lock(&vop_dev->reg_lock);
4251                 if (vop_dev->clk_on) {
4252                         vop_msk_reg(vop_dev, CABC_CTRL0,
4253                                     V_CABC_EN(0) | V_CABC_HANDLE_EN(0));
4254                         vop_cfg_done(vop_dev);
4255                 }
4256                 pr_info("mode = 0, close cabc\n");
4257                 spin_unlock(&vop_dev->reg_lock);
4258                 return 0;
4259         }
4260
4261         total_pixel = screen->mode.xres * screen->mode.yres;
4262         pixel_num = 1000 - calc;
4263         calc_pixel = (total_pixel * pixel_num) / 1000;
4264         stage_up = up;
4265         stage_down = down;
4266         global_dn = global;
4267         pr_info("enable cabc:mode=%d, calc=%d, up=%d, down=%d, global=%d\n",
4268                 mode, calc, stage_up, stage_down, global_dn);
4269
4270         spin_lock(&vop_dev->reg_lock);
4271         if (vop_dev->clk_on) {
4272                 u64 val = 0;
4273
4274                 val = V_CABC_EN(1) | V_CABC_HANDLE_EN(1) |
4275                         V_PWM_CONFIG_MODE(STAGE_BY_STAGE) |
4276                         V_CABC_CALC_PIXEL_NUM(calc_pixel);
4277                 vop_msk_reg(vop_dev, CABC_CTRL0, val);
4278
4279                 val = V_CABC_LUT_EN(1) | V_CABC_TOTAL_NUM(total_pixel);
4280                 vop_msk_reg(vop_dev, CABC_CTRL1, val);
4281
4282                 val = V_CABC_STAGE_DOWN(stage_down) |
4283                         V_CABC_STAGE_UP(stage_up) |
4284                         V_CABC_STAGE_UP_MODE(0) | V_MAX_SCALE_CFG_VALUE(1) |
4285                         V_MAX_SCALE_CFG_ENABLE(0);
4286                 vop_msk_reg(vop_dev, CABC_CTRL2, val);
4287
4288                 val = V_CABC_GLOBAL_DN(global_dn) |
4289                         V_CABC_GLOBAL_DN_LIMIT_EN(1);
4290                 vop_msk_reg(vop_dev, CABC_CTRL3, val);
4291                 vop_cfg_done(vop_dev);
4292         }
4293         spin_unlock(&vop_dev->reg_lock);
4294
4295         return 0;
4296 }
4297
4298 static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4299                             int sin_hue, int cos_hue)
4300 {
4301         struct vop_device *vop_dev =
4302             container_of(dev_drv, struct vop_device, driver);
4303         u64 val;
4304
4305         spin_lock(&vop_dev->reg_lock);
4306         if (vop_dev->clk_on) {
4307                 val = V_SIN_HUE(sin_hue) | V_COS_HUE(cos_hue);
4308                 vop_msk_reg(vop_dev, BCSH_H, val);
4309                 vop_cfg_done(vop_dev);
4310         }
4311         spin_unlock(&vop_dev->reg_lock);
4312
4313         return 0;
4314 }
4315
4316 static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4317                             bcsh_bcs_mode mode, int value)
4318 {
4319         struct vop_device *vop_dev =
4320             container_of(dev_drv, struct vop_device, driver);
4321         u64 val;
4322
4323         spin_lock(&vop_dev->reg_lock);
4324         if (vop_dev->clk_on) {
4325                 switch (mode) {
4326                 case BRIGHTNESS:
4327                         /*from 0 to 255,typical is 128 */
4328                         if (value < 0x80)
4329                                 value += 0x80;
4330                         else if (value >= 0x80)
4331                                 value = value - 0x80;
4332                         val = V_BRIGHTNESS(value);
4333                         break;
4334                 case CONTRAST:
4335                         /*from 0 to 510,typical is 256 */
4336                         val = V_CONTRAST(value);
4337                         break;
4338                 case SAT_CON:
4339                         /*from 0 to 1015,typical is 256 */
4340                         val = V_SAT_CON(value);
4341                         break;
4342                 default:
4343                         break;
4344                 }
4345                 vop_msk_reg(vop_dev, BCSH_BCS, val);
4346                 vop_cfg_done(vop_dev);
4347         }
4348         spin_unlock(&vop_dev->reg_lock);
4349
4350         return val;
4351 }
4352
4353 static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode)
4354 {
4355         struct vop_device *vop_dev =
4356             container_of(dev_drv, struct vop_device, driver);
4357         u64 val;
4358
4359         spin_lock(&vop_dev->reg_lock);
4360         if (vop_dev->clk_on) {
4361                 val = vop_readl(vop_dev, BCSH_BCS);
4362                 switch (mode) {
4363                 case BRIGHTNESS:
4364                         val &= MASK(BRIGHTNESS);
4365                         if (val > 0x80)
4366                                 val -= 0x80;
4367                         else
4368                                 val += 0x80;
4369                         break;
4370                 case CONTRAST:
4371                         val &= MASK(CONTRAST);
4372                         val >>= 8;
4373                         break;
4374                 case SAT_CON:
4375                         val &= MASK(SAT_CON);
4376                         val >>= 20;
4377                         break;
4378                 default:
4379                         break;
4380                 }
4381         }
4382         spin_unlock(&vop_dev->reg_lock);
4383         return val;
4384 }
4385
4386 static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
4387 {
4388         struct vop_device *vop_dev =
4389             container_of(dev_drv, struct vop_device, driver);
4390
4391         spin_lock(&vop_dev->reg_lock);
4392         if (vop_dev->clk_on) {
4393                 if (open) {
4394                         vop_writel(vop_dev, BCSH_COLOR_BAR, 0x1);
4395                         vop_writel(vop_dev, BCSH_BCS, 0xd0010000);
4396                         vop_writel(vop_dev, BCSH_H, 0x01000000);
4397                         dev_drv->bcsh.enable = 1;
4398                 } else {
4399                         vop_msk_reg(vop_dev, BCSH_COLOR_BAR, V_BCSH_EN(0));
4400                         dev_drv->bcsh.enable = 0;
4401                 }
4402                 vop_bcsh_path_sel(dev_drv);
4403                 vop_cfg_done(vop_dev);
4404         }
4405         spin_unlock(&vop_dev->reg_lock);
4406
4407         return 0;
4408 }
4409
4410 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
4411 {
4412         if (!enable || !dev_drv->bcsh.enable) {
4413                 vop_open_bcsh(dev_drv, false);
4414                 return 0;
4415         }
4416
4417         if (dev_drv->bcsh.brightness <= 255 ||
4418             dev_drv->bcsh.contrast <= 510 ||
4419             dev_drv->bcsh.sat_con <= 1015 ||
4420             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
4421                 vop_open_bcsh(dev_drv, true);
4422                 if (dev_drv->bcsh.brightness <= 255)
4423                         vop_set_bcsh_bcs(dev_drv, BRIGHTNESS,
4424                                          dev_drv->bcsh.brightness);
4425                 if (dev_drv->bcsh.contrast <= 510)
4426                         vop_set_bcsh_bcs(dev_drv, CONTRAST,
4427                                          dev_drv->bcsh.contrast);
4428                 if (dev_drv->bcsh.sat_con <= 1015)
4429                         vop_set_bcsh_bcs(dev_drv, SAT_CON,
4430                                          dev_drv->bcsh.sat_con);
4431                 if (dev_drv->bcsh.sin_hue <= 511 &&
4432                     dev_drv->bcsh.cos_hue <= 511)
4433                         vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue,
4434                                          dev_drv->bcsh.cos_hue);
4435         }
4436
4437         return 0;
4438 }
4439
4440 static int __maybe_unused
4441 vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
4442 {
4443         struct vop_device *vop_dev =
4444             container_of(dev_drv, struct vop_device, driver);
4445
4446         if (enable) {
4447                 spin_lock(&vop_dev->reg_lock);
4448                 if (likely(vop_dev->clk_on)) {
4449                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1));
4450                         vop_cfg_done(vop_dev);
4451                 }
4452                 spin_unlock(&vop_dev->reg_lock);
4453         } else {
4454                 spin_lock(&vop_dev->reg_lock);
4455                 if (likely(vop_dev->clk_on)) {
4456                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0));
4457
4458                         vop_cfg_done(vop_dev);
4459                 }
4460                 spin_unlock(&vop_dev->reg_lock);
4461         }
4462
4463         return 0;
4464 }
4465
4466 static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable)
4467 {
4468         struct vop_device *vop_dev =
4469             container_of(dev_drv, struct vop_device, driver);
4470
4471         if (unlikely(!vop_dev->clk_on)) {
4472                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4473                 return 0;
4474         }
4475         vop_get_backlight_device(dev_drv);
4476
4477         if (enable) {
4478                 /* close the backlight */
4479                 if (vop_dev->backlight) {
4480                         vop_dev->backlight->props.power = FB_BLANK_POWERDOWN;
4481                         backlight_update_status(vop_dev->backlight);
4482                 }
4483                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4484                         dev_drv->trsm_ops->disable();
4485         } else {
4486                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
4487                         dev_drv->trsm_ops->enable();
4488                 msleep(100);
4489                 /* open the backlight */
4490                 if (vop_dev->backlight) {
4491                         vop_dev->backlight->props.power = FB_BLANK_UNBLANK;
4492                         backlight_update_status(vop_dev->backlight);
4493                 }
4494         }
4495
4496         return 0;
4497 }
4498
4499 static int vop_set_overscan(struct rk_lcdc_driver *dev_drv,
4500                             struct overscan *overscan)
4501 {
4502         struct vop_device *vop_dev =
4503             container_of(dev_drv, struct vop_device, driver);
4504
4505         if (unlikely(!vop_dev->clk_on)) {
4506                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4507                 return 0;
4508         }
4509         /*vop_post_cfg(dev_drv);*/
4510
4511         return 0;
4512 }
4513
4514 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
4515         .open = vop_open,
4516         .win_direct_en = vop_win_direct_en,
4517         .load_screen = vop_load_screen,
4518         .get_dspbuf_info = vop_get_dspbuf_info,
4519         .post_dspbuf = vop_post_dspbuf,
4520         .set_par = vop_set_par,
4521         .pan_display = vop_pan_display,
4522         .set_wb = vop_set_writeback,
4523         .direct_set_addr = vop_direct_set_win_addr,
4524         /*.lcdc_reg_update = vop_reg_update,*/
4525         .blank = vop_blank,
4526         .ioctl = vop_ioctl,
4527         .suspend = vop_early_suspend,
4528         .resume = vop_early_resume,
4529         .get_win_state = vop_get_win_state,
4530         .area_support_num = vop_get_area_num,
4531         .ovl_mgr = vop_ovl_mgr,
4532         .get_disp_info = vop_get_disp_info,
4533         .fps_mgr = vop_fps_mgr,
4534         .fb_get_win_id = vop_get_win_id,
4535         .fb_win_remap = vop_fb_win_remap,
4536         .poll_vblank = vop_poll_vblank,
4537         .dpi_open = vop_dpi_open,
4538         .dpi_win_sel = vop_dpi_win_sel,
4539         .dpi_status = vop_dpi_status,
4540         .get_dsp_addr = vop_get_dsp_addr,
4541         .set_dsp_lut = vop_set_lut,
4542         .set_cabc_lut = vop_set_cabc,
4543         .set_dsp_cabc = vop_set_dsp_cabc,
4544         .set_dsp_bcsh_hue = vop_set_bcsh_hue,
4545         .set_dsp_bcsh_bcs = vop_set_bcsh_bcs,
4546         .get_dsp_bcsh_hue = vop_get_bcsh_hue,
4547         .get_dsp_bcsh_bcs = vop_get_bcsh_bcs,
4548         .open_bcsh = vop_open_bcsh,
4549         .dump_reg = vop_reg_dump,
4550         .cfg_done = vop_config_done,
4551         .set_irq_to_cpu = vop_set_irq_to_cpu,
4552         /*.dsp_black = vop_dsp_black,*/
4553         .backlight_close = vop_backlight_close,
4554         .mmu_en    = vop_mmu_en,
4555         .set_overscan   = vop_set_overscan,
4556 };
4557
4558 static irqreturn_t vop_isr(int irq, void *dev_id)
4559 {
4560         struct vop_device *vop_dev = (struct vop_device *)dev_id;
4561         ktime_t timestamp = ktime_get();
4562         u32 intr_status;
4563         unsigned long flags;
4564
4565         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4566
4567         intr_status = vop_readl(vop_dev, INTR_STATUS0);
4568         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, intr_status);
4569
4570         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4571         /* This is expected for vop iommu irqs, since the irq is shared */
4572         if (!intr_status)
4573                 return IRQ_NONE;
4574
4575         if (intr_status & INTR_FS) {
4576                 timestamp = ktime_get();
4577                 if (vop_dev->wb_on) {
4578                         u32 wb_status;
4579
4580                         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4581                         wb_status = vop_read_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4582                         if (wb_status)
4583                                 vop_set_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4584
4585                         vop_cfg_done(vop_dev);
4586                         vop_dev->driver.wb_data.state = 0;
4587                         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4588                 }
4589                 vop_dev->driver.vsync_info.timestamp = timestamp;
4590                 wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait);
4591                 intr_status &= ~INTR_FS;
4592         }
4593
4594         if (intr_status & INTR_LINE_FLAG0)
4595                 intr_status &= ~INTR_LINE_FLAG0;
4596
4597         if (intr_status & INTR_LINE_FLAG1)
4598                 intr_status &= ~INTR_LINE_FLAG1;
4599
4600         if (intr_status & INTR_FS_NEW)
4601                 intr_status &= ~INTR_FS_NEW;
4602
4603         if (intr_status & INTR_BUS_ERROR) {
4604                 intr_status &= ~INTR_BUS_ERROR;
4605                 dev_warn_ratelimited(vop_dev->dev, "bus error!");
4606         }
4607
4608         if (intr_status & INTR_WIN0_EMPTY) {
4609                 intr_status &= ~INTR_WIN0_EMPTY;
4610                 dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!");
4611         }
4612
4613         if (intr_status & INTR_WIN1_EMPTY) {
4614                 intr_status &= ~INTR_WIN1_EMPTY;
4615                 dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!");
4616         }
4617
4618         if (intr_status & INTR_HWC_EMPTY) {
4619                 intr_status &= ~INTR_HWC_EMPTY;
4620                 dev_warn_ratelimited(vop_dev->dev, "intr hwc empty!");
4621         }
4622
4623         if (intr_status & INTR_POST_BUF_EMPTY) {
4624                 intr_status &= ~INTR_POST_BUF_EMPTY;
4625                 dev_warn_ratelimited(vop_dev->dev, "intr post buf empty!");
4626         }
4627
4628         if (intr_status)
4629                 dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status);
4630
4631         return IRQ_HANDLED;
4632 }
4633
4634 #if defined(CONFIG_PM)
4635 static int vop_suspend(struct platform_device *pdev, pm_message_t state)
4636 {
4637         return 0;
4638 }
4639
4640 static int vop_resume(struct platform_device *pdev)
4641 {
4642         return 0;
4643 }
4644 #else
4645 #define vop_suspend NULL
4646 #define vop_resume  NULL
4647 #endif
4648
4649 static int vop_parse_dt(struct vop_device *vop_dev)
4650 {
4651         struct device_node *np = vop_dev->dev->of_node;
4652         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
4653         int val;
4654
4655         if (of_property_read_u32(np, "rockchip,prop", &val))
4656                 vop_dev->prop = PRMRY;  /*default set it as primary */
4657         else
4658                 vop_dev->prop = val;
4659
4660         if (of_property_read_u32(np, "rockchip,mirror", &val))
4661                 dev_drv->rotate_mode = NO_MIRROR;
4662         else
4663                 dev_drv->rotate_mode = val;
4664
4665         if (of_property_read_u32(np, "rockchip,pwr18", &val))
4666                 /*default set it as 3.xv power supply */
4667                 vop_dev->pwr18 = false;
4668         else
4669                 vop_dev->pwr18 = (val ? true : false);
4670
4671         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
4672                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
4673         else
4674                 dev_drv->fb_win_map = val;
4675
4676         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
4677                 dev_drv->bcsh.enable = false;
4678         else
4679                 dev_drv->bcsh.enable = (val ? true : false);
4680
4681         if (of_property_read_u32(np, "rockchip,brightness", &val))
4682                 dev_drv->bcsh.brightness = 0xffff;
4683         else
4684                 dev_drv->bcsh.brightness = val;
4685
4686         if (of_property_read_u32(np, "rockchip,contrast", &val))
4687                 dev_drv->bcsh.contrast = 0xffff;
4688         else
4689                 dev_drv->bcsh.contrast = val;
4690
4691         if (of_property_read_u32(np, "rockchip,sat-con", &val))
4692                 dev_drv->bcsh.sat_con = 0xffff;
4693         else
4694                 dev_drv->bcsh.sat_con = val;
4695
4696         if (of_property_read_u32(np, "rockchip,hue", &val)) {
4697                 dev_drv->bcsh.sin_hue = 0xffff;
4698                 dev_drv->bcsh.cos_hue = 0xffff;
4699         } else {
4700                 dev_drv->bcsh.sin_hue = val & 0xff;
4701                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
4702         }
4703
4704         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
4705                 dev_drv->iommu_enabled = 0;
4706         else
4707                 dev_drv->iommu_enabled = val;
4708         return 0;
4709 }
4710
4711 static int vop_probe(struct platform_device *pdev)
4712 {
4713         struct vop_device *vop_dev = NULL;
4714         struct rk_lcdc_driver *dev_drv;
4715         const struct of_device_id *of_id;
4716         struct device *dev = &pdev->dev;
4717         struct resource *res;
4718         struct device_node *np = pdev->dev.of_node;
4719         int prop;
4720         int ret = 0;
4721
4722         /* if the primary lcdc has not registered ,the extend
4723          * lcdc register later
4724          */
4725         of_property_read_u32(np, "rockchip,prop", &prop);
4726         if (prop == EXTEND) {
4727                 if (!is_prmry_rk_lcdc_registered())
4728                         return -EPROBE_DEFER;
4729         }
4730         vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL);
4731         if (!vop_dev)
4732                 return -ENOMEM;
4733         of_id = of_match_device(vop_dt_ids, dev);
4734         vop_dev->data = of_id->data;
4735         if (VOP_CHIP(vop_dev) != VOP_RK322X && VOP_CHIP(vop_dev) != VOP_RK3399)
4736                 return -ENODEV;
4737         platform_set_drvdata(pdev, vop_dev);
4738         vop_dev->dev = dev;
4739         vop_parse_dt(vop_dev);
4740         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4741         vop_dev->reg_phy_base = res->start;
4742         vop_dev->len = resource_size(res);
4743         vop_dev->regs = devm_ioremap_resource(dev, res);
4744         if (IS_ERR(vop_dev->regs))
4745                 return PTR_ERR(vop_dev->regs);
4746
4747         dev_info(dev, "vop_dev->regs=0x%lx\n", (long)vop_dev->regs);
4748
4749         vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL);
4750         if (IS_ERR(vop_dev->regsbak))
4751                 return PTR_ERR(vop_dev->regsbak);
4752         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
4753                 vop_dev->dsp_lut_addr_base = vop_dev->regs + GAMMA_LUT_ADDR;
4754                 vop_dev->cabc_lut_addr_base = vop_dev->regs +
4755                                                 CABC_GAMMA_LUT_ADDR;
4756         }
4757         vop_dev->grf_base =
4758                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
4759         if (IS_ERR(vop_dev->grf_base)) {
4760                 dev_err(&pdev->dev, "can't find lcdc grf property\n");
4761                 vop_dev->grf_base = NULL;
4762         }
4763
4764         vop_dev->id = vop_get_id(vop_dev, vop_dev->reg_phy_base);
4765         dev_set_name(vop_dev->dev, "vop%d", vop_dev->id);
4766         dev_drv = &vop_dev->driver;
4767         dev_drv->dev = dev;
4768         dev_drv->prop = prop;
4769         dev_drv->id = vop_dev->id;
4770         dev_drv->ops = &lcdc_drv_ops;
4771         dev_drv->lcdc_win_num = vop_dev->data->n_wins;
4772         dev_drv->reserved_fb = 0;
4773         spin_lock_init(&vop_dev->reg_lock);
4774         spin_lock_init(&vop_dev->irq_lock);
4775         vop_dev->irq = platform_get_irq(pdev, 0);
4776         if (vop_dev->irq < 0) {
4777                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
4778                         vop_dev->id);
4779                 return -ENXIO;
4780         }
4781
4782         ret = devm_request_irq(dev, vop_dev->irq, vop_isr,
4783                                IRQF_SHARED, dev_name(dev), vop_dev);
4784         if (ret) {
4785                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
4786                         vop_dev->irq, ret);
4787                 return ret;
4788         }
4789         if (dev_drv->iommu_enabled)
4790                 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
4791         ret = rk_fb_register(dev_drv, vop_dev->data->win, vop_dev->id);
4792         if (ret < 0) {
4793                 dev_err(dev, "register fb for lcdc%d failed!\n", vop_dev->id);
4794                 return ret;
4795         }
4796         vop_dev->screen = dev_drv->screen0;
4797         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
4798                  vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
4799
4800         return 0;
4801 }
4802
4803 static int vop_remove(struct platform_device *pdev)
4804 {
4805         return 0;
4806 }
4807
4808 static void vop_shutdown(struct platform_device *pdev)
4809 {
4810         struct vop_device *vop_dev = platform_get_drvdata(pdev);
4811         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
4812
4813         dev_drv->suspend_flag = 1;
4814         /* ensure suspend_flag take effect on multi process */
4815         smp_wmb();
4816         flush_kthread_worker(&dev_drv->update_regs_worker);
4817         kthread_stop(dev_drv->update_regs_thread);
4818         vop_deint(vop_dev);
4819
4820         vop_clk_disable(vop_dev);
4821         rk_disp_pwr_disable(dev_drv);
4822 }
4823
4824 static struct platform_driver vop_driver = {
4825         .probe = vop_probe,
4826         .remove = vop_remove,
4827         .driver = {
4828                    .name = "rk322x-lcdc",
4829                    .owner = THIS_MODULE,
4830                    .of_match_table = of_match_ptr(vop_dt_ids),
4831                    },
4832         .suspend = vop_suspend,
4833         .resume = vop_resume,
4834         .shutdown = vop_shutdown,
4835 };
4836
4837 static int __init vop_module_init(void)
4838 {
4839         return platform_driver_register(&vop_driver);
4840 }
4841
4842 static void __exit vop_module_exit(void)
4843 {
4844         platform_driver_unregister(&vop_driver);
4845 }
4846
4847 fs_initcall(vop_module_init);
4848 module_exit(vop_module_exit);