video: rockchip: vop: 3399: add support rk3399
[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 && !IS_YUV(win->area[0].fmt_cfg))
642                         goto post;
643
644                 if (output_color == COLOR_RGB) {
645                         val |= V_WIN0_YUV2YUV_Y2R_EN(1);
646                         if (win->colorspace == CSC_BT601) {
647                                 /*
648                                  * Win Y2Y moudle always use 10bit mode.
649                                  */
650                                 LOAD_CSC(vop_dev, Y2R,
651                                          csc_y2r_bt601_full_10, i);
652                         } else if (win->colorspace == CSC_BT709) {
653                                 LOAD_CSC(vop_dev, Y2R,
654                                          csc_y2r_bt709_full_10, i);
655                         } else if (win->colorspace == CSC_BT2020) {
656                                 val |= V_WIN0_YUV2YUV_EN(1);
657                                 LOAD_CSC(vop_dev, Y2R, csc_y2r_bt2020, i);
658                                 LOAD_CSC(vop_dev, 3x3, csc_r2r_bt2020to709, i);
659                         }
660                 } else if (output_color == COLOR_YCBCR ||
661                                 output_color == COLOR_YCBCR_BT709) {
662                         if (!IS_YUV(win->area[0].fmt_cfg)) {
663                                 val |= V_WIN0_YUV2YUV_R2Y_EN(1);
664                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt709_full, i);
665                         } else if (win->colorspace == CSC_BT2020) {
666                                 val |= V_WIN0_YUV2YUV_EN(1) |
667                                         V_WIN0_YUV2YUV_Y2R_EN(1) |
668                                         V_WIN0_YUV2YUV_R2Y_EN(1);
669                                 LOAD_CSC(vop_dev, R2Y, csc_y2r_bt2020, i);
670                                 LOAD_CSC(vop_dev, R2Y, csc_r2r_bt2020to709, i);
671                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt709_full, i);
672                         }
673                 } else if (output_color == COLOR_YCBCR_BT2020) {
674                         if (!IS_YUV(win->area[0].fmt_cfg)) {
675                                 val |= V_WIN0_YUV2YUV_R2Y_EN(1) |
676                                         V_WIN0_YUV2YUV_EN(1);
677                                 LOAD_CSC(vop_dev, R2Y, csc_r2r_bt709to2020, i);
678                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt2020, i);
679                         } else if (win->colorspace == CSC_BT601 ||
680                                         win->colorspace == CSC_BT709) {
681                                 val |= V_WIN0_YUV2YUV_Y2R_EN(1) |
682                                         V_WIN0_YUV2YUV_R2Y_EN(1) |
683                                         V_WIN0_YUV2YUV_EN(1);
684                                 LOAD_CSC(vop_dev, R2Y, csc_y2r_bt709_full, i);
685                                 LOAD_CSC(vop_dev, R2Y, csc_r2r_bt709to2020, i);
686                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt2020, i);
687                         }
688                 }
689 post:
690                 vop_msk_reg(vop_dev, YUV2YUV_WIN, val << shift);
691         }
692
693         return output_color;
694 }
695
696 /*
697  * colorspace path:
698  *      Input        Win csc            Post csc              Output
699  * 1. YUV(2020)  --> bypass   ---+ Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
700  *    RGB        --> R2Y(709) __/
701  *
702  * 2. YUV(2020)  --> bypass   ---+       bypass        --> YUV_OUTPUT(2020)
703  *    RGB        --> R2Y(709) __/
704  *
705  * 3. YUV(2020)  --> bypass   ---+    Y2R->2020To709   --> RGB_OUTPUT(709)
706  *    RGB        --> R2Y(709) __/
707  *
708  * 4. YUV(601/709)-> bypass   ---+ Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
709  *    RGB        --> R2Y(709) __/
710  *
711  * 5. YUV(601/709)-> bypass   ---+       bypass        --> YUV_OUTPUT(709)
712  *    RGB        --> R2Y(709) __/
713  *
714  * 6. YUV(601/709)-> bypass   ---+       bypass        --> YUV_OUTPUT(601)
715  *    RGB        --> R2Y(601) __/
716  *
717  * 7. YUV(601)   --> Y2R(601/mpeg)-+     bypass        --> RGB_OUTPUT(709)
718  *    RGB        --> bypass   ____/
719  *
720  * 8. YUV(709)   --> Y2R(709/hd) --+     bypass        --> RGB_OUTPUT(709)
721  *    RGB        --> bypass   ____/
722  *
723  * 9. RGB        --> bypass   --->    709To2020->R2Y   --> YUV_OUTPUT(2020)
724  *
725  * 10. RGB       --> R2Y(709) --->      bypass        --> YUV_OUTPUT(709)
726  *
727  * 11. RGB       --> R2Y(601) --->       bypass        --> YUV_OUTPUT(601)
728  *
729  * 12. RGB       --> bypass   --->       bypass        --> RGB_OUTPUT(709)
730  */
731 static int rk3228_vop_win_csc_cfg(struct rk_lcdc_driver *dev_drv)
732 {
733         struct vop_device *vop_dev =
734             container_of(dev_drv, struct vop_device, driver);
735         struct rk_lcdc_win *win;
736         int output_color = dev_drv->output_color;
737         int win_csc = COLOR_RGB;
738         int r2y_mode = VOP_R2Y_CSC_BT709;
739         int i;
740
741         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
742                 win = dev_drv->win[i];
743                 if (!win->state)
744                         continue;
745
746                 if (IS_YUV(win->area[0].fmt_cfg)) {
747                         if (win->colorspace == CSC_BT2020 &&
748                             win_csc < COLOR_YCBCR_BT2020) {
749                                 r2y_mode = VOP_R2Y_CSC_BT709;
750                                 win_csc = COLOR_YCBCR_BT2020;
751                         }
752
753                         if (win->colorspace == CSC_BT709 &&
754                             win_csc < COLOR_YCBCR_BT709) {
755                                 r2y_mode = VOP_R2Y_CSC_BT709;
756                                 win_csc = COLOR_YCBCR_BT709;
757                         }
758
759                         if (win->colorspace == CSC_BT601 &&
760                             win_csc < COLOR_YCBCR) {
761                                 r2y_mode = VOP_R2Y_CSC_BT709;
762                                 win_csc = COLOR_YCBCR;
763                         }
764                 }
765         }
766
767         if (win_csc == COLOR_RGB) {
768                 if (output_color == COLOR_YCBCR_BT709) {
769                         r2y_mode = VOP_R2Y_CSC_BT709;
770                         win_csc = COLOR_YCBCR_BT709;
771                 } else if (output_color == COLOR_YCBCR) {
772                         r2y_mode = VOP_R2Y_CSC_BT601;
773                         win_csc = COLOR_YCBCR;
774                 }
775         }
776
777         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
778                 win = dev_drv->win[i];
779                 if (!win->state)
780                         continue;
781
782                 if (win_csc != COLOR_RGB && !IS_YUV(win->area[0].fmt_cfg))
783                         vop_win_csc_mode(vop_dev, win, r2y_mode);
784
785                 if (IS_YUV(win->area[0].fmt_cfg)) {
786                         if (win_csc == COLOR_YCBCR)
787                                 vop_win_csc_mode(vop_dev, win,
788                                                  VOP_Y2R_CSC_MPEG);
789                         else if (win_csc == COLOR_YCBCR_BT709)
790                                 vop_win_csc_mode(vop_dev, win, VOP_Y2R_CSC_HD);
791                 }
792         }
793
794         return win_csc;
795 }
796
797 static int vop_post_csc_cfg(struct rk_lcdc_driver *dev_drv)
798 {
799         struct vop_device *vop_dev =
800             container_of(dev_drv, struct vop_device, driver);
801         int output_color = dev_drv->output_color;
802         int win_csc, overlay_mode;
803         u64 val;
804
805         if (VOP_CHIP(vop_dev) == VOP_RK322X) {
806                 win_csc = rk3228_vop_win_csc_cfg(dev_drv);
807         } else if (VOP_CHIP(vop_dev) == VOP_RK3399) {
808                 win_csc = rk3399_vop_win_csc_cfg(dev_drv);
809
810                 /*
811                  * RK3399 not support post csc config.
812                  */
813                 goto done;
814         }
815
816         val = V_YUV2YUV_POST_Y2R_EN(0) | V_YUV2YUV_POST_EN(0) |
817                 V_YUV2YUV_POST_R2Y_EN(0);
818         /* Y2R */
819         if (win_csc == COLOR_YCBCR && output_color == COLOR_YCBCR_BT2020) {
820                 val |= V_YUV2YUV_POST_Y2R_EN(1);
821                 vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE,
822                                    csc_y2r_bt709_full);
823         }
824         if (win_csc == COLOR_YCBCR_BT2020 &&
825             output_color != COLOR_YCBCR_BT2020) {
826                 val |= V_YUV2YUV_POST_Y2R_EN(1);
827                 vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE,
828                                    csc_y2r_bt2020);
829         }
830
831         /* R2R */
832         if ((win_csc == COLOR_YCBCR ||
833              win_csc == COLOR_YCBCR_BT709 ||
834              win_csc == COLOR_RGB) && output_color == COLOR_YCBCR_BT2020) {
835                 val |= V_YUV2YUV_POST_EN(1);
836                 vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE,
837                                    csc_r2r_bt709to2020);
838         }
839         if (win_csc == COLOR_YCBCR_BT2020 &&
840             (output_color == COLOR_YCBCR ||
841              output_color == COLOR_YCBCR_BT709 ||
842              output_color == COLOR_RGB)) {
843                 val |= V_YUV2YUV_POST_EN(1);
844                 vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE,
845                                    csc_r2r_bt2020to709);
846         }
847
848         /* Y2R */
849         if (output_color != COLOR_RGB) {
850                 val |= V_YUV2YUV_POST_R2Y_EN(1);
851
852                 if (output_color == COLOR_YCBCR_BT2020)
853                         vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE,
854                                            csc_r2y_bt2020);
855                 else
856                         vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE,
857                                            csc_r2y_bt709_full);
858         }
859
860         DBG(1, "win_csc=%d output_color=%d val=%llx\n",
861             win_csc, output_color, val);
862         vop_msk_reg(vop_dev, YUV2YUV_POST, val);
863 done:
864         overlay_mode = (win_csc != COLOR_RGB) ? VOP_YUV_DOMAIN : VOP_RGB_DOMAIN;
865         vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(overlay_mode));
866
867         return 0;
868 }
869
870 static int vop_post_cfg(struct rk_lcdc_driver *dev_drv)
871 {
872         struct vop_device *vop_dev =
873             container_of(dev_drv, struct vop_device, driver);
874         struct rk_screen *screen = dev_drv->cur_screen;
875         u16 x_res = screen->mode.xres;
876         u16 y_res = screen->mode.yres;
877         u64 val;
878         u16 h_total, v_total;
879         u16 post_hsd_en, post_vsd_en;
880         u16 post_dsp_hact_st, post_dsp_hact_end;
881         u16 post_dsp_vact_st, post_dsp_vact_end;
882         u16 post_dsp_vact_st_f1, post_dsp_vact_end_f1;
883         u16 post_h_fac, post_v_fac;
884
885         screen->post_dsp_stx = x_res * (100 - dev_drv->overscan.left) / 200;
886         screen->post_dsp_sty = y_res * (100 - dev_drv->overscan.top) / 200;
887         screen->post_xsize = x_res *
888             (dev_drv->overscan.left + dev_drv->overscan.right) / 200;
889         screen->post_ysize = y_res *
890             (dev_drv->overscan.top + dev_drv->overscan.bottom) / 200;
891
892         h_total = screen->mode.hsync_len + screen->mode.left_margin +
893             x_res + screen->mode.right_margin;
894         v_total = screen->mode.vsync_len + screen->mode.upper_margin +
895             y_res + screen->mode.lower_margin;
896
897         if (screen->post_dsp_stx + screen->post_xsize > x_res) {
898                 dev_warn(vop_dev->dev, "post:stx[%d]+xsize[%d]>x_res[%d]\n",
899                          screen->post_dsp_stx, screen->post_xsize, x_res);
900                 screen->post_dsp_stx = x_res - screen->post_xsize;
901         }
902         if (screen->x_mirror == 0) {
903                 post_dsp_hact_st = screen->post_dsp_stx +
904                     screen->mode.hsync_len + screen->mode.left_margin;
905                 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
906         } else {
907                 post_dsp_hact_end = h_total - screen->mode.right_margin -
908                     screen->post_dsp_stx;
909                 post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
910         }
911         if ((screen->post_xsize < x_res) && (screen->post_xsize != 0)) {
912                 post_hsd_en = 1;
913                 post_h_fac =
914                     GET_SCALE_FACTOR_BILI_DN(x_res, screen->post_xsize);
915         } else {
916                 post_hsd_en = 0;
917                 post_h_fac = 0x1000;
918         }
919
920         if (screen->post_dsp_sty + screen->post_ysize > y_res) {
921                 dev_warn(vop_dev->dev, "post:sty[%d]+ysize[%d]> y_res[%d]\n",
922                          screen->post_dsp_sty, screen->post_ysize, y_res);
923                 screen->post_dsp_sty = y_res - screen->post_ysize;
924         }
925
926         if ((screen->post_ysize < y_res) && (screen->post_ysize != 0)) {
927                 post_vsd_en = 1;
928                 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res,
929                                                       screen->post_ysize);
930         } else {
931                 post_vsd_en = 0;
932                 post_v_fac = 0x1000;
933         }
934
935         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
936                 post_dsp_vact_st = screen->post_dsp_sty / 2 +
937                                         screen->mode.vsync_len +
938                                         screen->mode.upper_margin;
939                 post_dsp_vact_end = post_dsp_vact_st +
940                                         screen->post_ysize / 2;
941
942                 post_dsp_vact_st_f1 = screen->mode.vsync_len +
943                                         screen->mode.upper_margin +
944                                         y_res / 2 +
945                                         screen->mode.lower_margin +
946                                         screen->mode.vsync_len +
947                                         screen->mode.upper_margin +
948                                         screen->post_dsp_sty / 2 +
949                                         1;
950                 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 +
951                                         screen->post_ysize / 2;
952         } else {
953                 if (screen->y_mirror == 0) {
954                         post_dsp_vact_st = screen->post_dsp_sty +
955                             screen->mode.vsync_len +
956                             screen->mode.upper_margin;
957                         post_dsp_vact_end = post_dsp_vact_st +
958                                 screen->post_ysize;
959                 } else {
960                         post_dsp_vact_end = v_total -
961                                 screen->mode.lower_margin -
962                             screen->post_dsp_sty;
963                         post_dsp_vact_st = post_dsp_vact_end -
964                                 screen->post_ysize;
965                 }
966                 post_dsp_vact_st_f1 = 0;
967                 post_dsp_vact_end_f1 = 0;
968         }
969         DBG(1, "post:xsize=%d,ysize=%d,xpos=%d",
970             screen->post_xsize, screen->post_ysize, screen->xpos);
971         DBG(1, ",ypos=%d,hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
972             screen->ypos, post_hsd_en, post_h_fac, post_vsd_en, post_v_fac);
973         val = V_DSP_HACT_END_POST(post_dsp_hact_end) |
974             V_DSP_HACT_ST_POST(post_dsp_hact_st);
975         vop_msk_reg(vop_dev, POST_DSP_HACT_INFO, val);
976
977         val = V_DSP_VACT_END_POST(post_dsp_vact_end) |
978             V_DSP_VACT_ST_POST(post_dsp_vact_st);
979         vop_msk_reg(vop_dev, POST_DSP_VACT_INFO, val);
980
981         val = V_POST_HS_FACTOR_YRGB(post_h_fac) |
982             V_POST_VS_FACTOR_YRGB(post_v_fac);
983         vop_msk_reg(vop_dev, POST_SCL_FACTOR_YRGB, val);
984         val = V_DSP_VACT_END_POST(post_dsp_vact_end_f1) |
985             V_DSP_VACT_ST_POST(post_dsp_vact_st_f1);
986         vop_msk_reg(vop_dev, POST_DSP_VACT_INFO_F1, val);
987         val = V_POST_HOR_SD_EN(post_hsd_en) | V_POST_VER_SD_EN(post_vsd_en);
988         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
989
990         vop_post_csc_cfg(dev_drv);
991
992         return 0;
993 }
994
995 static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
996 {
997         struct vop_device *vop_dev =
998             container_of(dev_drv, struct vop_device, driver);
999         struct rk_lcdc_win *win;
1000         u32 colorkey_r, colorkey_g, colorkey_b;
1001         int i, key_val;
1002
1003         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1004                 win = dev_drv->win[i];
1005                 key_val = win->color_key_val;
1006                 colorkey_r = (key_val & 0xff) << 2;
1007                 colorkey_g = ((key_val >> 8) & 0xff) << 12;
1008                 colorkey_b = ((key_val >> 16) & 0xff) << 22;
1009                 /* color key dither 565/888->aaa */
1010                 key_val = colorkey_r | colorkey_g | colorkey_b;
1011                 switch (i) {
1012                 case 0:
1013                         vop_writel(vop_dev, WIN0_COLOR_KEY, key_val);
1014                         break;
1015                 case 1:
1016                         vop_writel(vop_dev, WIN1_COLOR_KEY, key_val);
1017                         break;
1018                 case 2:
1019                         vop_writel(vop_dev, WIN2_COLOR_KEY, key_val);
1020                         break;
1021                 case 3:
1022                         vop_writel(vop_dev, WIN3_COLOR_KEY, key_val);
1023                         break;
1024                 default:
1025                         pr_info("%s:un support win num:%d\n",
1026                                 __func__, i);
1027                         break;
1028                 }
1029         }
1030         return 0;
1031 }
1032
1033 static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
1034 {
1035         struct vop_device *vop_dev =
1036             container_of(dev_drv, struct vop_device, driver);
1037         struct rk_lcdc_win *win = dev_drv->win[win_id];
1038         struct alpha_config alpha_config;
1039         u64 val;
1040         int ppixel_alpha = 0, global_alpha = 0, i;
1041         u32 src_alpha_ctl, dst_alpha_ctl;
1042         int alpha_en = 1;
1043
1044         for (i = 0; i < win->area_num; i++) {
1045                 ppixel_alpha |= ((win->area[i].format == ARGB888) ||
1046                                  (win->area[i].format == FBDC_ARGB_888) ||
1047                                  (win->area[i].format == FBDC_ABGR_888) ||
1048                                  (win->area[i].format == ABGR888)) ? 1 : 0;
1049         }
1050
1051         global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
1052
1053         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1054                 if (!dev_drv->win[i]->state)
1055                         continue;
1056                 if (win->z_order > dev_drv->win[i]->z_order)
1057                         break;
1058         }
1059
1060         /*
1061          * The bottom layer not support ppixel_alpha mode.
1062          */
1063         if (i == dev_drv->lcdc_win_num)
1064                 ppixel_alpha = 0;
1065         alpha_config.src_global_alpha_val = win->g_alpha_val;
1066         win->alpha_mode = AB_SRC_OVER;
1067
1068         switch (win->alpha_mode) {
1069         case AB_USER_DEFINE:
1070                 break;
1071         case AB_CLEAR:
1072                 alpha_config.src_factor_mode = AA_ZERO;
1073                 alpha_config.dst_factor_mode = AA_ZERO;
1074                 break;
1075         case AB_SRC:
1076                 alpha_config.src_factor_mode = AA_ONE;
1077                 alpha_config.dst_factor_mode = AA_ZERO;
1078                 break;
1079         case AB_DST:
1080                 alpha_config.src_factor_mode = AA_ZERO;
1081                 alpha_config.dst_factor_mode = AA_ONE;
1082                 break;
1083         case AB_SRC_OVER:
1084                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1085                 if (global_alpha)
1086                         alpha_config.src_factor_mode = AA_SRC_GLOBAL;
1087                 else
1088                         alpha_config.src_factor_mode = AA_ONE;
1089                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1090                 break;
1091         case AB_DST_OVER:
1092                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1093                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1094                 alpha_config.dst_factor_mode = AA_ONE;
1095                 break;
1096         case AB_SRC_IN:
1097                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1098                 alpha_config.src_factor_mode = AA_SRC;
1099                 alpha_config.dst_factor_mode = AA_ZERO;
1100                 break;
1101         case AB_DST_IN:
1102                 alpha_config.src_factor_mode = AA_ZERO;
1103                 alpha_config.dst_factor_mode = AA_SRC;
1104                 break;
1105         case AB_SRC_OUT:
1106                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1107                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1108                 alpha_config.dst_factor_mode = AA_ZERO;
1109                 break;
1110         case AB_DST_OUT:
1111                 alpha_config.src_factor_mode = AA_ZERO;
1112                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1113                 break;
1114         case AB_SRC_ATOP:
1115                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1116                 alpha_config.src_factor_mode = AA_SRC;
1117                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1118                 break;
1119         case AB_DST_ATOP:
1120                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1121                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1122                 alpha_config.dst_factor_mode = AA_SRC;
1123                 break;
1124         case XOR:
1125                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1126                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1127                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1128                 break;
1129         case AB_SRC_OVER_GLOBAL:
1130                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
1131                 alpha_config.src_color_mode = AA_SRC_NO_PRE_MUL;
1132                 alpha_config.src_factor_mode = AA_SRC_GLOBAL;
1133                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1134                 break;
1135         default:
1136                 pr_err("alpha mode error\n");
1137                 break;
1138         }
1139         if ((ppixel_alpha == 1) && (global_alpha == 1))
1140                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
1141         else if (ppixel_alpha == 1)
1142                 alpha_config.src_global_alpha_mode = AA_PER_PIX;
1143         else if (global_alpha == 1)
1144                 alpha_config.src_global_alpha_mode = AA_GLOBAL;
1145         else
1146                 alpha_en = 0;
1147         alpha_config.src_alpha_mode = AA_STRAIGHT;
1148         alpha_config.src_alpha_cal_m0 = AA_NO_SAT;
1149
1150         switch (win_id) {
1151         case 0:
1152                 src_alpha_ctl = 0x60;
1153                 dst_alpha_ctl = 0x64;
1154                 break;
1155         case 1:
1156                 src_alpha_ctl = 0xa0;
1157                 dst_alpha_ctl = 0xa4;
1158                 break;
1159         case 2:
1160                 src_alpha_ctl = 0xdc;
1161                 dst_alpha_ctl = 0xec;
1162                 break;
1163         case 3:
1164                 src_alpha_ctl = 0x12c;
1165                 dst_alpha_ctl = 0x13c;
1166                 break;
1167         case 4:
1168                 src_alpha_ctl = 0x160;
1169                 dst_alpha_ctl = 0x164;
1170                 break;
1171         }
1172         val = V_WIN0_DST_FACTOR_MODE(alpha_config.dst_factor_mode);
1173         vop_msk_reg(vop_dev, dst_alpha_ctl, val);
1174         val = V_WIN0_SRC_ALPHA_EN(alpha_en) |
1175             V_WIN0_SRC_COLOR_MODE(alpha_config.src_color_mode) |
1176             V_WIN0_SRC_ALPHA_MODE(alpha_config.src_alpha_mode) |
1177             V_WIN0_SRC_BLEND_MODE(alpha_config.src_global_alpha_mode) |
1178             V_WIN0_SRC_ALPHA_CAL_MODE(alpha_config.src_alpha_cal_m0) |
1179             V_WIN0_SRC_FACTOR_MODE(alpha_config.src_factor_mode) |
1180             V_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
1181
1182         vop_msk_reg(vop_dev, src_alpha_ctl, val);
1183
1184         return 0;
1185 }
1186
1187 static int vop_axi_gather_cfg(struct vop_device *vop_dev,
1188                               struct rk_lcdc_win *win)
1189 {
1190         u64 val;
1191         u16 yrgb_gather_num = 3;
1192         u16 cbcr_gather_num = 1;
1193
1194         switch (win->area[0].format) {
1195         case ARGB888:
1196         case XBGR888:
1197         case ABGR888:
1198                 yrgb_gather_num = 3;
1199                 break;
1200         case RGB888:
1201         case RGB565:
1202                 yrgb_gather_num = 2;
1203                 break;
1204         case YUV444:
1205         case YUV422:
1206         case YUV420:
1207         case YUV420_A:
1208         case YUV422_A:
1209         case YUV444_A:
1210         case YUV420_NV21:
1211                 yrgb_gather_num = 1;
1212                 cbcr_gather_num = 2;
1213                 break;
1214         default:
1215                 dev_err(vop_dev->driver.dev, "%s:un supported format[%d]\n",
1216                         __func__, win->area[0].format);
1217                 return -EINVAL;
1218         }
1219
1220         if ((win->id == VOP_WIN0) || (win->id == VOP_WIN1)) {
1221                 val = V_WIN0_YRGB_AXI_GATHER_EN(1) |
1222                         V_WIN0_CBR_AXI_GATHER_EN(1) |
1223                         V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) |
1224                         V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num);
1225                 vop_msk_reg(vop_dev, WIN0_CTRL1 + (win->id * 0x40), val);
1226         } else if ((win->id == VOP_WIN2) || (win->id == VOP_WIN3)) {
1227                 val = V_WIN2_AXI_GATHER_EN(1) |
1228                         V_WIN2_AXI_GATHER_NUM(yrgb_gather_num);
1229                 vop_msk_reg(vop_dev, WIN2_CTRL1 + ((win->id - 2) * 0x50), val);
1230         } else if (win->id == VOP_HWC) {
1231                 val = V_HWC_AXI_GATHER_EN(1) |
1232                         V_HWC_AXI_GATHER_NUM(yrgb_gather_num);
1233                 vop_msk_reg(vop_dev, HWC_CTRL1, val);
1234         }
1235         return 0;
1236 }
1237
1238 static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1239 {
1240         struct vop_device *vop_dev =
1241             container_of(dev_drv, struct vop_device, driver);
1242         struct rk_lcdc_win *win = dev_drv->win[win_id];
1243         u64 val;
1244         u32 off;
1245         int format;
1246
1247         off = win_id * 0x40;
1248
1249         if (win->state == 1) {
1250                 vop_axi_gather_cfg(vop_dev, win);
1251
1252                 /*
1253                  * rk322x have a bug on windows 0 and 1:
1254                  *
1255                  * When switch win format from RGB to YUV, would flash
1256                  * some green lines on the top of the windows.
1257                  *
1258                  * Use bg_en show one blank frame to skip the error frame.
1259                  */
1260                 if (IS_YUV(win->area[0].fmt_cfg)) {
1261                         val = vop_readl(vop_dev, WIN0_CTRL0);
1262                         format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1263
1264                         if (!IS_YUV(format)) {
1265                                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1266                                         val = V_WIN0_DSP_BG_RED(0x200) |
1267                                                 V_WIN0_DSP_BG_GREEN(0x40) |
1268                                                 V_WIN0_DSP_BG_BLUE(0x200) |
1269                                                 V_WIN0_BG_EN(1);
1270                                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off,
1271                                                     val);
1272                                 } else {
1273                                         val = V_WIN0_DSP_BG_RED(0) |
1274                                                 V_WIN0_DSP_BG_GREEN(0) |
1275                                                 V_WIN0_DSP_BG_BLUE(0) |
1276                                                 V_WIN0_BG_EN(1);
1277                                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off,
1278                                                     val);
1279                                 }
1280                         } else {
1281                                 val = V_WIN0_BG_EN(0);
1282                                 vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val);
1283                         }
1284                 } else {
1285                         val = V_WIN0_BG_EN(0);
1286                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val);
1287                 }
1288
1289                 val = V_WIN0_EN(win->state) |
1290                         V_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
1291                         V_WIN0_FMT_10(win->fmt_10) |
1292                         V_WIN0_LB_MODE(win->win_lb_mode) |
1293                         V_WIN0_RB_SWAP(win->area[0].swap_rb) |
1294                         V_WIN0_X_MIR_EN(win->xmirror) |
1295                         V_WIN0_Y_MIR_EN(win->ymirror) |
1296                         V_WIN0_UV_SWAP(win->area[0].swap_uv);
1297                 vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
1298                 val = V_WIN0_BIC_COE_SEL(win->bic_coe_el) |
1299                     V_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
1300                     V_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
1301                     V_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
1302                     V_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
1303                     V_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
1304                     V_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
1305                     V_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
1306                     V_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
1307                     V_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
1308                     V_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
1309                     V_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
1310                     V_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
1311                     V_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
1312                     V_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
1313                 vop_msk_reg(vop_dev, WIN0_CTRL1 + off, val);
1314                 val = V_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
1315                     V_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
1316                 vop_writel(vop_dev, WIN0_VIR + off, val);
1317                 val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) |
1318                     V_WIN0_ACT_HEIGHT(win->area[0].yact - 1);
1319                 vop_writel(vop_dev, WIN0_ACT_INFO + off, val);
1320
1321                 val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) |
1322                     V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1);
1323                 vop_writel(vop_dev, WIN0_DSP_INFO + off, val);
1324
1325                 val = V_WIN0_DSP_XST(win->area[0].dsp_stx) |
1326                     V_WIN0_DSP_YST(win->area[0].dsp_sty);
1327                 vop_writel(vop_dev, WIN0_DSP_ST + off, val);
1328
1329                 val = V_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
1330                     V_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
1331                 vop_writel(vop_dev, WIN0_SCL_FACTOR_YRGB + off, val);
1332
1333                 val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
1334                     V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
1335                 vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR + off, val);
1336                 if (win->alpha_en == 1) {
1337                         vop_alpha_cfg(dev_drv, win_id);
1338                 } else {
1339                         val = V_WIN0_SRC_ALPHA_EN(0);
1340                         vop_msk_reg(vop_dev, WIN0_SRC_ALPHA_CTRL + off, val);
1341                 }
1342
1343         } else {
1344                 val = V_WIN0_EN(win->state);
1345                 vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
1346         }
1347
1348         return 0;
1349 }
1350
1351 static int area_xst(struct rk_lcdc_win *win, int area_num)
1352 {
1353         struct rk_lcdc_win_area area_temp;
1354         int i, j;
1355
1356         for (i = 0; i < area_num; i++) {
1357                 for (j = i + 1; j < area_num; j++) {
1358                         if (win->area[i].dsp_stx >  win->area[j].dsp_stx) {
1359                                 memcpy(&area_temp, &win->area[i],
1360                                        sizeof(struct rk_lcdc_win_area));
1361                                 memcpy(&win->area[i], &win->area[j],
1362                                        sizeof(struct rk_lcdc_win_area));
1363                                 memcpy(&win->area[j], &area_temp,
1364                                        sizeof(struct rk_lcdc_win_area));
1365                         }
1366                 }
1367         }
1368
1369         return 0;
1370 }
1371
1372 static int vop_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1373 {
1374         struct vop_device *vop_dev =
1375                         container_of(dev_drv, struct vop_device, driver);
1376         struct rk_lcdc_win *win = dev_drv->win[win_id];
1377         unsigned int off;
1378         u64 val;
1379
1380         off = (win_id - 2) * 0x50;
1381         area_xst(win, win->area_num);
1382
1383         if (win->state == 1) {
1384                 vop_axi_gather_cfg(vop_dev, win);
1385                 val = V_WIN2_EN(1) | V_WIN1_CSC_MODE(win->csc_mode);
1386                 vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1387                 /* area 0 */
1388                 if (win->area[0].state == 1) {
1389                         val = V_WIN2_MST0_EN(win->area[0].state) |
1390                             V_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
1391                             V_WIN2_RB_SWAP0(win->area[0].swap_rb);
1392                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1393
1394                         val = V_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
1395                         vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
1396
1397                         val = V_WIN2_DSP_WIDTH0(win->area[0].xsize) |
1398                             V_WIN2_DSP_HEIGHT0(win->area[0].ysize);
1399                         vop_writel(vop_dev, WIN2_DSP_INFO0 + off, val);
1400                         val = V_WIN2_DSP_XST0(win->area[0].dsp_stx) |
1401                             V_WIN2_DSP_YST0(win->area[0].dsp_sty);
1402                         vop_writel(vop_dev, WIN2_DSP_ST0 + off, val);
1403                 } else {
1404                         val = V_WIN2_MST0_EN(0);
1405                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1406                 }
1407                 /* area 1 */
1408                 if (win->area[1].state == 1) {
1409                         val = V_WIN2_MST1_EN(win->area[1].state) |
1410                             V_WIN2_DATA_FMT1(win->area[1].fmt_cfg) |
1411                             V_WIN2_RB_SWAP1(win->area[1].swap_rb);
1412                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1413
1414                         val = V_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
1415                         vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
1416
1417                         val = V_WIN2_DSP_WIDTH1(win->area[1].xsize) |
1418                             V_WIN2_DSP_HEIGHT1(win->area[1].ysize);
1419                         vop_writel(vop_dev, WIN2_DSP_INFO1 + off, val);
1420                         val = V_WIN2_DSP_XST1(win->area[1].dsp_stx) |
1421                             V_WIN2_DSP_YST1(win->area[1].dsp_sty);
1422                         vop_writel(vop_dev, WIN2_DSP_ST1 + off, val);
1423                 } else {
1424                         val = V_WIN2_MST1_EN(0);
1425                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1426                 }
1427                 /* area 2 */
1428                 if (win->area[2].state == 1) {
1429                         val = V_WIN2_MST2_EN(win->area[2].state) |
1430                             V_WIN2_DATA_FMT2(win->area[2].fmt_cfg) |
1431                             V_WIN2_RB_SWAP2(win->area[2].swap_rb);
1432                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1433
1434                         val = V_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
1435                         vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
1436
1437                         val = V_WIN2_DSP_WIDTH2(win->area[2].xsize) |
1438                             V_WIN2_DSP_HEIGHT2(win->area[2].ysize);
1439                         vop_writel(vop_dev, WIN2_DSP_INFO2 + off, val);
1440                         val = V_WIN2_DSP_XST2(win->area[2].dsp_stx) |
1441                             V_WIN2_DSP_YST2(win->area[2].dsp_sty);
1442                         vop_writel(vop_dev, WIN2_DSP_ST2 + off, val);
1443                 } else {
1444                         val = V_WIN2_MST2_EN(0);
1445                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1446                 }
1447                 /* area 3 */
1448                 if (win->area[3].state == 1) {
1449                         val = V_WIN2_MST3_EN(win->area[3].state) |
1450                             V_WIN2_DATA_FMT3(win->area[3].fmt_cfg) |
1451                             V_WIN2_RB_SWAP3(win->area[3].swap_rb);
1452                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1453
1454                         val = V_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
1455                         vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
1456
1457                         val = V_WIN2_DSP_WIDTH3(win->area[3].xsize) |
1458                             V_WIN2_DSP_HEIGHT3(win->area[3].ysize);
1459                         vop_writel(vop_dev, WIN2_DSP_INFO3 + off, val);
1460                         val = V_WIN2_DSP_XST3(win->area[3].dsp_stx) |
1461                             V_WIN2_DSP_YST3(win->area[3].dsp_sty);
1462                         vop_writel(vop_dev, WIN2_DSP_ST3 + off, val);
1463                 } else {
1464                         val = V_WIN2_MST3_EN(0);
1465                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1466                 }
1467
1468                 if (win->alpha_en == 1) {
1469                         vop_alpha_cfg(dev_drv, win_id);
1470                 } else {
1471                         val = V_WIN2_SRC_ALPHA_EN(0);
1472                         vop_msk_reg(vop_dev, WIN2_SRC_ALPHA_CTRL + off, val);
1473                 }
1474         } else {
1475                 val = V_WIN2_EN(win->state) | V_WIN2_MST0_EN(0) |
1476                     V_WIN2_MST1_EN(0) | V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
1477                 vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1478         }
1479
1480         return 0;
1481 }
1482
1483 static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1484 {
1485         struct vop_device *vop_dev =
1486             container_of(dev_drv, struct vop_device, driver);
1487         struct rk_lcdc_win *win = dev_drv->win[win_id];
1488         unsigned int hwc_size = 0;
1489         u64 val;
1490
1491         if (win->state == 1) {
1492                 vop_axi_gather_cfg(vop_dev, win);
1493                 val = V_HWC_EN(1) | V_HWC_DATA_FMT(win->area[0].fmt_cfg) |
1494                     V_HWC_RB_SWAP(win->area[0].swap_rb);
1495                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1496
1497                 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
1498                         hwc_size = 0;
1499                 else if ((win->area[0].xsize == 64) &&
1500                          (win->area[0].ysize == 64))
1501                         hwc_size = 1;
1502                 else if ((win->area[0].xsize == 96) &&
1503                          (win->area[0].ysize == 96))
1504                         hwc_size = 2;
1505                 else if ((win->area[0].xsize == 128) &&
1506                          (win->area[0].ysize == 128))
1507                         hwc_size = 3;
1508                 else
1509                         dev_err(vop_dev->dev, "un supported hwc size[%dx%d]!\n",
1510                                 win->area[0].xsize, win->area[0].ysize);
1511
1512                 val = V_HWC_SIZE(hwc_size);
1513                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1514
1515                 val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
1516                     V_HWC_DSP_YST(win->area[0].dsp_sty);
1517                 vop_msk_reg(vop_dev, HWC_DSP_ST, val);
1518
1519                 if (win->alpha_en == 1) {
1520                         vop_alpha_cfg(dev_drv, win_id);
1521                 } else {
1522                         val = V_WIN2_SRC_ALPHA_EN(0);
1523                         vop_msk_reg(vop_dev, HWC_SRC_ALPHA_CTRL, val);
1524                 }
1525         } else {
1526                 val = V_HWC_EN(win->state);
1527                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1528         }
1529
1530         return 0;
1531 }
1532
1533 static int vop_layer_update_regs(struct vop_device *vop_dev,
1534                                  struct rk_lcdc_win *win)
1535 {
1536         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
1537
1538         if (likely(vop_dev->clk_on)) {
1539                 vop_msk_reg(vop_dev, SYS_CTRL,
1540                             V_VOP_STANDBY_EN(vop_dev->standby));
1541                 if ((win->id == VOP_WIN0) || (win->id == VOP_WIN1))
1542                         vop_win_0_1_reg_update(dev_drv, win->id);
1543                 else if ((win->id == VOP_WIN2) || (win->id == VOP_WIN3))
1544                         vop_win_2_3_reg_update(dev_drv, win->id);
1545                 else if (win->id == VOP_HWC)
1546                         vop_hwc_reg_update(dev_drv, win->id);
1547                 vop_cfg_done(vop_dev);
1548         }
1549
1550         DBG(2, "%s for lcdc%d\n", __func__, vop_dev->id);
1551         return 0;
1552 }
1553
1554 static int __maybe_unused vop_mmu_en(struct rk_lcdc_driver *dev_drv)
1555 {
1556         u64 val;
1557         struct vop_device *vop_dev =
1558             container_of(dev_drv, struct vop_device, driver);
1559
1560         if (unlikely(!vop_dev->clk_on)) {
1561                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
1562                 return 0;
1563         }
1564         if (dev_drv->iommu_enabled) {
1565                 if (!vop_dev->iommu_status && dev_drv->mmu_dev) {
1566                         if (likely(vop_dev->clk_on)) {
1567                                 val = V_VOP_MMU_EN(1);
1568                                 vop_msk_reg(vop_dev, SYS_CTRL, val);
1569                                 val = V_AXI_OUTSTANDING_MAX_NUM(31) |
1570                                         V_AXI_MAX_OUTSTANDING_EN(1);
1571                                 vop_msk_reg(vop_dev, SYS_CTRL1, val);
1572                         }
1573                         vop_dev->iommu_status = 1;
1574                         rockchip_iovmm_activate(dev_drv->dev);
1575                 }
1576         }
1577         return 0;
1578 }
1579
1580 static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
1581 {
1582         int ret = 0, fps = 0;
1583         struct vop_device *vop_dev =
1584             container_of(dev_drv, struct vop_device, driver);
1585         struct rk_screen *screen = dev_drv->cur_screen;
1586 #ifdef CONFIG_RK_FPGA
1587         return 0;
1588 #endif
1589         if (reset_rate)
1590                 ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock);
1591         if (ret)
1592                 dev_err(dev_drv->dev, "set lcdc%d dclk[%d] failed\n",
1593                         vop_dev->id, screen->mode.pixclock);
1594         vop_dev->pixclock =
1595             div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
1596         vop_dev->driver.pixclock = vop_dev->pixclock;
1597
1598         fps = rk_fb_calc_fps(screen, vop_dev->pixclock);
1599         screen->ft = 1000 / fps;
1600         dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ",
1601                  vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps);
1602         return 0;
1603 }
1604
1605 static int vop_config_timing(struct rk_lcdc_driver *dev_drv)
1606 {
1607         struct vop_device *vop_dev =
1608             container_of(dev_drv, struct vop_device, driver);
1609         struct rk_screen *screen = dev_drv->cur_screen;
1610         u16 hsync_len = screen->mode.hsync_len;
1611         u16 left_margin = screen->mode.left_margin;
1612         u16 right_margin = screen->mode.right_margin;
1613         u16 vsync_len = screen->mode.vsync_len;
1614         u16 upper_margin = screen->mode.upper_margin;
1615         u16 lower_margin = screen->mode.lower_margin;
1616         u16 x_res = screen->mode.xres;
1617         u16 y_res = screen->mode.yres;
1618         u64 val;
1619         u16 h_total, v_total;
1620         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
1621
1622         h_total = hsync_len + left_margin + x_res + right_margin;
1623         v_total = vsync_len + upper_margin + y_res + lower_margin;
1624
1625         val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total);
1626         vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val);
1627
1628         val = V_DSP_HACT_END(hsync_len + left_margin + x_res) |
1629             V_DSP_HACT_ST(hsync_len + left_margin);
1630         vop_msk_reg(vop_dev, DSP_HACT_ST_END, val);
1631
1632         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1633                 /* First Field Timing */
1634                 val = V_DSP_VS_END(vsync_len) |
1635                     V_DSP_VTOTAL(2 * (vsync_len + upper_margin +
1636                                       lower_margin) + y_res + 1);
1637                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
1638
1639                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
1640                     V_DSP_VACT_ST(vsync_len + upper_margin);
1641                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
1642
1643                 /* Second Field Timing */
1644                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
1645                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
1646                     lower_margin;
1647                 val = V_DSP_VS_ST_F1(vs_st_f1) | V_DSP_VS_END_F1(vs_end_f1);
1648                 vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val);
1649
1650                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
1651                     lower_margin + 1;
1652                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
1653                     lower_margin + 1;
1654                 val = V_DSP_VACT_END_F1(vact_end_f1) |
1655                         V_DSP_VACT_ST_F1(vact_st_f1);
1656                 vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val);
1657                 vop_msk_reg(vop_dev, DSP_CTRL0,
1658                             V_DSP_INTERLACE(1) | V_DSP_FIELD_POL(0));
1659
1660                 val = V_DSP_LINE_FLAG_NUM_0(lower_margin ?
1661                                             vact_end_f1 : vact_end_f1 - 1);
1662
1663                 val |= V_DSP_LINE_FLAG_NUM_1(lower_margin ?
1664                                              vact_end_f1 : vact_end_f1 - 1);
1665                 vop_msk_reg(vop_dev, LINE_FLAG, val);
1666         } else {
1667                 val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total);
1668                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
1669
1670                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) |
1671                     V_DSP_VACT_ST(vsync_len + upper_margin);
1672                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
1673
1674                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_INTERLACE(0) |
1675                             V_DSP_FIELD_POL(0));
1676
1677                 val = V_DSP_LINE_FLAG_NUM_0(vsync_len + upper_margin + y_res) |
1678                         V_DSP_LINE_FLAG_NUM_1(vsync_len + upper_margin + y_res);
1679                 vop_msk_reg(vop_dev, LINE_FLAG, val);
1680         }
1681         vop_post_cfg(dev_drv);
1682
1683         return 0;
1684 }
1685
1686 static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1687 {
1688         struct vop_device *vop_dev =
1689             container_of(dev_drv, struct vop_device, driver);
1690         u32 bcsh_ctrl;
1691
1692         vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(dev_drv->overlay_mode));
1693         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1694                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1695                         vop_msk_reg(vop_dev, BCSH_CTRL,
1696                                     V_BCSH_Y2R_EN(0) | V_BCSH_R2Y_EN(0));
1697                 else            /* YUV2RGB */
1698                         vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_Y2R_EN(1) |
1699                                     V_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1700                                     V_BCSH_R2Y_EN(0));
1701         } else {
1702                 /* overlay_mode=VOP_RGB_DOMAIN */
1703                 /* bypass  --need check,if bcsh close? */
1704                 if (dev_drv->output_color == COLOR_RGB) {
1705                         bcsh_ctrl = vop_readl(vop_dev, BCSH_CTRL);
1706                         if (((bcsh_ctrl & MASK(BCSH_EN)) == 1) ||
1707                             (dev_drv->bcsh.enable == 1))/*bcsh enabled */
1708                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1709                                             V_BCSH_R2Y_EN(1) |
1710                                             V_BCSH_Y2R_EN(1));
1711                         else
1712                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1713                                             V_BCSH_R2Y_EN(0) |
1714                                             V_BCSH_Y2R_EN(0));
1715                 } else {
1716                         /* RGB2YUV */
1717                         vop_msk_reg(vop_dev, BCSH_CTRL,
1718                                     V_BCSH_R2Y_EN(1) |
1719                                     V_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1720                                     V_BCSH_Y2R_EN(0));
1721                 }
1722         }
1723 }
1724
1725 static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1726                                u16 *yact, int *format, u32 *dsp_addr,
1727                                int *ymirror)
1728 {
1729         struct vop_device *vop_dev =
1730                         container_of(dev_drv, struct vop_device, driver);
1731         u32 val;
1732
1733         spin_lock(&vop_dev->reg_lock);
1734
1735         val = vop_readl(vop_dev, WIN0_ACT_INFO);
1736         *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
1737         *yact = ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1738
1739         val = vop_readl(vop_dev, WIN0_CTRL0);
1740         *format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1741         *ymirror = (val & MASK(WIN0_Y_MIR_EN)) >> 22;
1742         *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST);
1743
1744         spin_unlock(&vop_dev->reg_lock);
1745
1746         return 0;
1747 }
1748
1749 static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1750                            int format, u16 xact, u16 yact, u16 xvir,
1751                            int ymirror)
1752 {
1753         struct vop_device *vop_dev =
1754                         container_of(dev_drv, struct vop_device, driver);
1755         int swap = (format == RGB888) ? 1 : 0;
1756         struct rk_lcdc_win *win = dev_drv->win[0];
1757         u64 val;
1758
1759         val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap) |
1760                 V_WIN0_Y_MIR_EN(ymirror);
1761         vop_msk_reg(vop_dev, WIN0_CTRL0, val);
1762
1763         vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_VIR_STRIDE(xvir));
1764         vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) |
1765                    V_WIN0_ACT_HEIGHT(yact - 1));
1766
1767         vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst);
1768
1769         vop_cfg_done(vop_dev);
1770
1771         if (format == RGB888)
1772                 win->area[0].format = BGR888;
1773         else
1774                 win->area[0].format = format;
1775
1776         win->ymirror = ymirror;
1777         win->state = 1;
1778         win->last_state = 1;
1779
1780         return 0;
1781 }
1782
1783 static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1784 {
1785         u16 face = 0;
1786         u16 dclk_ddr = 0;
1787         struct vop_device *vop_dev =
1788             container_of(dev_drv, struct vop_device, driver);
1789         struct rk_screen *screen = dev_drv->cur_screen;
1790         u64 val;
1791
1792         if (unlikely(!vop_dev->clk_on)) {
1793                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
1794                 return 0;
1795         }
1796
1797         if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1))
1798                 flush_kthread_worker(&dev_drv->update_regs_worker);
1799
1800         spin_lock(&vop_dev->reg_lock);
1801         if (likely(vop_dev->clk_on)) {
1802                 switch (screen->face) {
1803                 case OUT_P565:
1804                         face = OUT_P565;
1805                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1806                                 V_PRE_DITHER_DOWN_EN(1) |
1807                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(0);
1808                         break;
1809                 case OUT_P666:
1810                         face = OUT_P666;
1811                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1812                                 V_PRE_DITHER_DOWN_EN(1) |
1813                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(1);
1814                         break;
1815                 case OUT_D888_P565:
1816                         face = OUT_P888;
1817                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1818                                 V_PRE_DITHER_DOWN_EN(1) |
1819                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(0);
1820                         break;
1821                 case OUT_D888_P666:
1822                         face = OUT_P888;
1823                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1824                                 V_PRE_DITHER_DOWN_EN(1) |
1825                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(1);
1826                         break;
1827                 case OUT_P888:
1828                         face = OUT_P888;
1829                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1)
1830                                 | V_PRE_DITHER_DOWN_EN(1) |
1831                                 V_DITHER_DOWN_SEL(0) | V_DITHER_DOWN_MODE(0);
1832                         break;
1833                 case OUT_YUV_420:
1834                         face = OUT_YUV_420;
1835                         dclk_ddr = 1;
1836                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1837                                 V_PRE_DITHER_DOWN_EN(1) |
1838                                 V_DITHER_DOWN_SEL(0) |
1839                                 V_DITHER_DOWN_MODE(0);
1840                         break;
1841                 case OUT_YUV_420_10BIT:
1842                         face = OUT_YUV_420;
1843                         dclk_ddr = 1;
1844                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1845                                 V_PRE_DITHER_DOWN_EN(0) |
1846                                 V_DITHER_DOWN_SEL(0) |
1847                                 V_DITHER_DOWN_MODE(0);
1848                         break;
1849                 case OUT_P101010:
1850                         face = OUT_P101010;
1851                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1852                                 V_PRE_DITHER_DOWN_EN(0) |
1853                                 V_DITHER_DOWN_SEL(0) |
1854                                 V_DITHER_DOWN_MODE(0);
1855                         break;
1856                 default:
1857                         dev_err(vop_dev->dev, "un supported screen face[%d]!\n",
1858                                 screen->face);
1859                         break;
1860                 }
1861
1862                 vop_msk_reg(vop_dev, DSP_CTRL1, val);
1863                 switch (screen->type) {
1864                 case SCREEN_TVOUT:
1865                         val = V_SW_UV_OFFSET_EN(1) | V_SW_IMD_TVE_DCLK_EN(1) |
1866                                 V_SW_IMD_TVE_DCLK_EN(1) |
1867                                 V_SW_IMD_TVE_DCLK_POL(1) |
1868                                 V_SW_GENLOCK(1) | V_SW_DAC_SEL(1);
1869                         if (screen->mode.xres == 720 &&
1870                             screen->mode.yres == 576)
1871                                 val |= V_SW_TVE_MODE(1);
1872                         else
1873                                 val |= V_SW_TVE_MODE(0);
1874                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1875                         break;
1876                 case SCREEN_HDMI:
1877                         val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0);
1878                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1879                         break;
1880                 case SCREEN_RGB:
1881                 case SCREEN_LVDS:
1882                         val = V_RGB_OUT_EN(1);
1883                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1884                 case SCREEN_MIPI:
1885                         val = V_MIPI_OUT_EN(1);
1886                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1887                 case SCREEN_EDP:
1888                         val = V_EDP_OUT_EN(1);
1889                         vop_msk_reg(vop_dev, SYS_CTRL, val);
1890                         break;
1891                 default:
1892                         dev_err(vop_dev->dev, "un supported interface[%d]!\n",
1893                                 screen->type);
1894                         break;
1895                 }
1896                 val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
1897                         V_HDMI_VSYNC_POL(screen->pin_vsync) |
1898                         V_HDMI_DEN_POL(screen->pin_den) |
1899                         V_HDMI_DCLK_POL(screen->pin_dclk);
1900                 /*hsync vsync den dclk polo,dither */
1901                 vop_msk_reg(vop_dev, DSP_CTRL1, val);
1902
1903                 if (screen->color_mode == COLOR_RGB)
1904                         dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1905                 else
1906                         dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1907
1908 #ifndef CONFIG_RK_FPGA
1909                 /*
1910                  * Todo:
1911                  * writel_relaxed(v, RK_GRF_VIRT + vop_GRF_SOC_CON7);
1912                  *  move to  lvds driver
1913                  */
1914                 /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
1915 #endif
1916                 val = V_DSP_OUT_MODE(face) | V_DSP_DCLK_DDR(dclk_ddr) |
1917                     V_DSP_BG_SWAP(screen->swap_gb) |
1918                     V_DSP_RB_SWAP(screen->swap_rb) |
1919                     V_DSP_RG_SWAP(screen->swap_rg) |
1920                     V_DSP_DELTA_SWAP(screen->swap_delta) |
1921                     V_DSP_DUMMY_SWAP(screen->swap_dumy) | V_DSP_OUT_ZERO(0) |
1922                     V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0) |
1923                     V_DSP_X_MIR_EN(screen->x_mirror) |
1924                     V_DSP_Y_MIR_EN(screen->y_mirror);
1925                 val |= V_SW_CORE_DCLK_SEL(!!screen->pixelrepeat);
1926                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
1927                         val |= V_SW_HDMI_CLK_I_SEL(1);
1928                 else
1929                         val |= V_SW_HDMI_CLK_I_SEL(0);
1930                 vop_msk_reg(vop_dev, DSP_CTRL0, val);
1931
1932                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
1933                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(1));
1934                 else
1935                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(0));
1936                 /* BG color */
1937                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1938                         val = V_DSP_OUT_RGB_YUV(1);
1939                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
1940                         val = V_DSP_BG_BLUE(0x200) | V_DSP_BG_GREEN(0x40) |
1941                                 V_DSP_BG_RED(0x200);
1942                         vop_msk_reg(vop_dev, DSP_BG, val);
1943                 } else {
1944                         val = V_DSP_OUT_RGB_YUV(0);
1945                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
1946                         val = V_DSP_BG_BLUE(0x55) | V_DSP_BG_GREEN(0x55) |
1947                                 V_DSP_BG_RED(0x55);
1948                         vop_msk_reg(vop_dev, DSP_BG, val);
1949                 }
1950                 dev_drv->output_color = screen->color_mode;
1951                 vop_bcsh_path_sel(dev_drv);
1952                 vop_config_timing(dev_drv);
1953                 vop_cfg_done(vop_dev);
1954         }
1955         spin_unlock(&vop_dev->reg_lock);
1956         vop_set_dclk(dev_drv, 1);
1957         if (screen->type != SCREEN_HDMI && screen->type != SCREEN_TVOUT &&
1958             dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1959                 dev_drv->trsm_ops->enable();
1960         if (screen->init)
1961                 screen->init();
1962
1963         return 0;
1964 }
1965
1966 /*enable layer,open:1,enable;0 disable*/
1967 static void vop_layer_enable(struct vop_device *vop_dev,
1968                              unsigned int win_id, bool open)
1969 {
1970         spin_lock(&vop_dev->reg_lock);
1971         if (likely(vop_dev->clk_on) &&
1972             vop_dev->driver.win[win_id]->state != open) {
1973                 if (open) {
1974                         if (!vop_dev->atv_layer_cnt) {
1975                                 dev_info(vop_dev->dev,
1976                                          "wakeup from standby!\n");
1977                                 vop_dev->standby = 0;
1978                         }
1979                         vop_dev->atv_layer_cnt |= (1 << win_id);
1980                 } else {
1981                         if (vop_dev->atv_layer_cnt & (1 << win_id))
1982                                 vop_dev->atv_layer_cnt &= ~(1 << win_id);
1983                 }
1984                 vop_dev->driver.win[win_id]->state = open;
1985                 if (!open) {
1986                         vop_layer_update_regs(vop_dev,
1987                                               vop_dev->driver.win[win_id]);
1988                         vop_cfg_done(vop_dev);
1989                 }
1990                 /* if no layer used,disable lcdc */
1991                 if (!vop_dev->atv_layer_cnt) {
1992                         dev_info(vop_dev->dev,
1993                                  "no layer is used,go to standby!\n");
1994                         vop_dev->standby = 1;
1995                 }
1996         }
1997         spin_unlock(&vop_dev->reg_lock);
1998 }
1999
2000 static int vop_enable_irq(struct rk_lcdc_driver *dev_drv)
2001 {
2002         struct vop_device *vop_dev = container_of(dev_drv,
2003                                                     struct vop_device, driver);
2004         u64 val;
2005         /* struct rk_screen *screen = dev_drv->cur_screen; */
2006
2007         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
2008
2009         val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1 |
2010                 INTR_WIN0_EMPTY | INTR_WIN1_EMPTY | INTR_HWC_EMPTY |
2011                 INTR_POST_BUF_EMPTY;
2012
2013         vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val);
2014
2015         return 0;
2016 }
2017
2018 static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id,
2019                     bool open)
2020 {
2021         struct vop_device *vop_dev =
2022             container_of(dev_drv, struct vop_device, driver);
2023
2024         /* enable clk,when first layer open */
2025         if ((open) && (!vop_dev->atv_layer_cnt)) {
2026                 /* rockchip_set_system_status(sys_status); */
2027                 vop_pre_init(dev_drv);
2028                 vop_clk_enable(vop_dev);
2029                 vop_enable_irq(dev_drv);
2030                 if (dev_drv->iommu_enabled) {
2031                         if (!dev_drv->mmu_dev) {
2032                                 dev_drv->mmu_dev =
2033                                     rk_fb_get_sysmmu_device_by_compatible
2034                                     (dev_drv->mmu_dts_name);
2035                                 if (dev_drv->mmu_dev) {
2036                                         rk_fb_platform_set_sysmmu
2037                                             (dev_drv->mmu_dev, dev_drv->dev);
2038                                 } else {
2039                                         dev_err(dev_drv->dev,
2040                                                 "fail get rk iommu device\n");
2041                                         return -1;
2042                                 }
2043                         }
2044                 }
2045                 if ((support_uboot_display() && (vop_dev->prop == PRMRY)))
2046                         vop_set_dclk(dev_drv, 0);
2047                 else
2048                         vop_load_screen(dev_drv, 1);
2049                 if (dev_drv->bcsh.enable)
2050                         vop_set_bcsh(dev_drv, 1);
2051                 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
2052                 vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
2053         }
2054
2055         if (win_id < dev_drv->lcdc_win_num)
2056                 vop_layer_enable(vop_dev, win_id, open);
2057         else
2058                 dev_err(vop_dev->dev, "invalid win id:%d\n", win_id);
2059
2060         dev_drv->first_frame = 0;
2061         return 0;
2062 }
2063
2064 static int win_0_1_display(struct vop_device *vop_dev,
2065                            struct rk_lcdc_win *win)
2066 {
2067         u32 y_addr;
2068         u32 uv_addr;
2069         unsigned int off;
2070
2071         off = win->id * 0x40;
2072         /*win->smem_start + win->y_offset; */
2073         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2074         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
2075         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
2076             vop_dev->id, win->id, y_addr, uv_addr);
2077         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
2078             win->area[0].y_offset, win->area[0].c_offset);
2079         spin_lock(&vop_dev->reg_lock);
2080         if (likely(vop_dev->clk_on)) {
2081                 win->area[0].y_addr = y_addr;
2082                 win->area[0].uv_addr = uv_addr;
2083                 vop_writel(vop_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
2084                 vop_writel(vop_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
2085         }
2086         spin_unlock(&vop_dev->reg_lock);
2087
2088         return 0;
2089 }
2090
2091 static int win_2_3_display(struct vop_device *vop_dev,
2092                            struct rk_lcdc_win *win)
2093 {
2094         u32 i, y_addr;
2095         unsigned int off;
2096
2097         off = (win->id - 2) * 0x50;
2098         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2099         DBG(2, "lcdc[%d]:win[%d]:", vop_dev->id, win->id);
2100
2101         if (likely(vop_dev->clk_on)) {
2102                 for (i = 0; i < win->area_num; i++) {
2103                         DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
2104                             i, win->area[i].y_addr, win->area[i].y_offset);
2105                         win->area[i].y_addr =
2106                             win->area[i].smem_start + win->area[i].y_offset;
2107                         }
2108                 spin_lock(&vop_dev->reg_lock);
2109                 vop_writel(vop_dev, WIN2_MST0 + off, win->area[0].y_addr);
2110                 vop_writel(vop_dev, WIN2_MST1 + off, win->area[1].y_addr);
2111                 vop_writel(vop_dev, WIN2_MST2 + off, win->area[2].y_addr);
2112                 vop_writel(vop_dev, WIN2_MST3 + off, win->area[3].y_addr);
2113                 spin_unlock(&vop_dev->reg_lock);
2114         }
2115         return 0;
2116 }
2117
2118 static int hwc_display(struct vop_device *vop_dev, struct rk_lcdc_win *win)
2119 {
2120         u32 y_addr;
2121
2122         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2123         DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
2124             vop_dev->id, __func__, y_addr);
2125         spin_lock(&vop_dev->reg_lock);
2126         if (likely(vop_dev->clk_on)) {
2127                 win->area[0].y_addr = y_addr;
2128                 vop_writel(vop_dev, HWC_MST, win->area[0].y_addr);
2129         }
2130         spin_unlock(&vop_dev->reg_lock);
2131
2132         return 0;
2133 }
2134
2135 static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
2136 {
2137         struct vop_device *vop_dev =
2138             container_of(dev_drv, struct vop_device, driver);
2139         struct rk_lcdc_win *win = NULL;
2140         struct rk_screen *screen = dev_drv->cur_screen;
2141
2142         win = dev_drv->win[win_id];
2143         if (!screen) {
2144                 dev_err(dev_drv->dev, "screen is null!\n");
2145                 return -ENOENT;
2146         }
2147         if (unlikely(!vop_dev->clk_on)) {
2148                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
2149                 return 0;
2150         }
2151         if (win_id == 0) {
2152                 win_0_1_display(vop_dev, win);
2153         } else if (win_id == 1) {
2154                 win_0_1_display(vop_dev, win);
2155         } else if (win_id == 2) {
2156                 win_2_3_display(vop_dev, win);
2157         } else if (win_id == 3) {
2158                 win_2_3_display(vop_dev, win);
2159         } else if (win_id == 4) {
2160                 hwc_display(vop_dev, win);
2161         } else {
2162                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
2163                 return -EINVAL;
2164         }
2165
2166         return 0;
2167 }
2168
2169 static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen)
2170 {
2171         u16 srcW;
2172         u16 srcH;
2173         u16 dstW;
2174         u16 dstH;
2175         u16 yrgb_srcW;
2176         u16 yrgb_srcH;
2177         u16 yrgb_dstW;
2178         u16 yrgb_dstH;
2179         u32 yrgb_vscalednmult;
2180         u32 yrgb_xscl_factor;
2181         u32 yrgb_yscl_factor;
2182         u8 yrgb_vsd_bil_gt2 = 0;
2183         u8 yrgb_vsd_bil_gt4 = 0;
2184
2185         u16 cbcr_srcW;
2186         u16 cbcr_srcH;
2187         u16 cbcr_dstW;
2188         u16 cbcr_dstH;
2189         u32 cbcr_vscalednmult;
2190         u32 cbcr_xscl_factor;
2191         u32 cbcr_yscl_factor;
2192         u8 cbcr_vsd_bil_gt2 = 0;
2193         u8 cbcr_vsd_bil_gt4 = 0;
2194         u8 yuv_fmt = 0;
2195
2196         srcW = win->area[0].xact;
2197         if ((screen->mode.vmode & FB_VMODE_INTERLACED) &&
2198             (win->area[0].yact == 2 * win->area[0].ysize)) {
2199                 srcH = win->area[0].yact / 2;
2200                 yrgb_vsd_bil_gt2 = 1;
2201                 cbcr_vsd_bil_gt2 = 1;
2202         } else {
2203                 srcH = win->area[0].yact;
2204         }
2205         dstW = win->area[0].xsize;
2206         dstH = win->area[0].ysize;
2207
2208         /*yrgb scl mode */
2209         yrgb_srcW = srcW;
2210         yrgb_srcH = srcH;
2211         yrgb_dstW = dstW;
2212         yrgb_dstH = dstH;
2213         if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
2214                 pr_err("ERROR: yrgb scale exceed 8,");
2215                 pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
2216                        yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
2217         }
2218         if (yrgb_srcW < yrgb_dstW)
2219                 win->yrgb_hor_scl_mode = SCALE_UP;
2220         else if (yrgb_srcW > yrgb_dstW)
2221                 win->yrgb_hor_scl_mode = SCALE_DOWN;
2222         else
2223                 win->yrgb_hor_scl_mode = SCALE_NONE;
2224
2225         if (yrgb_srcH < yrgb_dstH)
2226                 win->yrgb_ver_scl_mode = SCALE_UP;
2227         else if (yrgb_srcH > yrgb_dstH)
2228                 win->yrgb_ver_scl_mode = SCALE_DOWN;
2229         else
2230                 win->yrgb_ver_scl_mode = SCALE_NONE;
2231
2232         /*cbcr scl mode */
2233         switch (win->area[0].format) {
2234         case YUV422:
2235         case YUV422_A:
2236                 cbcr_srcW = srcW / 2;
2237                 cbcr_dstW = dstW;
2238                 cbcr_srcH = srcH;
2239                 cbcr_dstH = dstH;
2240                 yuv_fmt = 1;
2241                 break;
2242         case YUV420:
2243         case YUV420_A:
2244         case YUV420_NV21:
2245                 cbcr_srcW = srcW / 2;
2246                 cbcr_dstW = dstW;
2247                 cbcr_srcH = srcH / 2;
2248                 cbcr_dstH = dstH;
2249                 yuv_fmt = 1;
2250                 break;
2251         case YUV444:
2252         case YUV444_A:
2253                 cbcr_srcW = srcW;
2254                 cbcr_dstW = dstW;
2255                 cbcr_srcH = srcH;
2256                 cbcr_dstH = dstH;
2257                 yuv_fmt = 1;
2258                 break;
2259         default:
2260                 cbcr_srcW = 0;
2261                 cbcr_dstW = 0;
2262                 cbcr_srcH = 0;
2263                 cbcr_dstH = 0;
2264                 yuv_fmt = 0;
2265                 break;
2266         }
2267         if (yuv_fmt) {
2268                 if ((cbcr_dstW * 8 <= cbcr_srcW) ||
2269                     (cbcr_dstH * 8 <= cbcr_srcH)) {
2270                         pr_err("ERROR: cbcr scale exceed 8,");
2271                         pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
2272                                cbcr_srcH, cbcr_dstW, cbcr_dstH);
2273                 }
2274         }
2275
2276         if (cbcr_srcW < cbcr_dstW)
2277                 win->cbr_hor_scl_mode = SCALE_UP;
2278         else if (cbcr_srcW > cbcr_dstW)
2279                 win->cbr_hor_scl_mode = SCALE_DOWN;
2280         else
2281                 win->cbr_hor_scl_mode = SCALE_NONE;
2282
2283         if (cbcr_srcH < cbcr_dstH)
2284                 win->cbr_ver_scl_mode = SCALE_UP;
2285         else if (cbcr_srcH > cbcr_dstH)
2286                 win->cbr_ver_scl_mode = SCALE_DOWN;
2287         else
2288                 win->cbr_ver_scl_mode = SCALE_NONE;
2289
2290         /* line buffer mode */
2291         if ((win->area[0].format == YUV422) ||
2292             (win->area[0].format == YUV420) ||
2293             (win->area[0].format == YUV420_NV21) ||
2294             (win->area[0].format == YUV422_A) ||
2295             (win->area[0].format == YUV420_A)) {
2296                 if (win->cbr_hor_scl_mode == SCALE_DOWN) {
2297                         if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
2298                             (cbcr_dstW == 0))
2299                                 pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
2300                                        cbcr_dstW);
2301                         else if (cbcr_dstW > 1280)
2302                                 win->win_lb_mode = LB_YUV_3840X5;
2303                         else
2304                                 win->win_lb_mode = LB_YUV_2560X8;
2305                 } else {        /* SCALE_UP or SCALE_NONE */
2306                         if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
2307                             (cbcr_srcW == 0))
2308                                 pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
2309                                        cbcr_srcW);
2310                         else if (cbcr_srcW > 1280)
2311                                 win->win_lb_mode = LB_YUV_3840X5;
2312                         else
2313                                 win->win_lb_mode = LB_YUV_2560X8;
2314                 }
2315         } else {
2316                 if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
2317                         if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
2318                             (yrgb_dstW == 0))
2319                                 pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
2320                         else if (yrgb_dstW > 2560)
2321                                 win->win_lb_mode = LB_RGB_3840X2;
2322                         else if (yrgb_dstW > 1920)
2323                                 win->win_lb_mode = LB_RGB_2560X4;
2324                         else if (yrgb_dstW > 1280)
2325                                 win->win_lb_mode = LB_RGB_1920X5;
2326                         else
2327                                 win->win_lb_mode = LB_RGB_1280X8;
2328                 } else {        /* SCALE_UP or SCALE_NONE */
2329                         if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
2330                             (yrgb_srcW == 0))
2331                                 pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
2332                         else if (yrgb_srcW > 2560)
2333                                 win->win_lb_mode = LB_RGB_3840X2;
2334                         else if (yrgb_srcW > 1920)
2335                                 win->win_lb_mode = LB_RGB_2560X4;
2336                         else if (yrgb_srcW > 1280)
2337                                 win->win_lb_mode = LB_RGB_1920X5;
2338                         else
2339                                 win->win_lb_mode = LB_RGB_1280X8;
2340                 }
2341         }
2342         DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
2343
2344         /* vsd/vsu scale ALGORITHM */
2345         win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2346         win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2347         win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2348         win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2349         switch (win->win_lb_mode) {
2350         case LB_YUV_3840X5:
2351         case LB_YUV_2560X8:
2352         case LB_RGB_1920X5:
2353         case LB_RGB_1280X8:
2354                 win->yrgb_vsu_mode = SCALE_UP_BIC;
2355                 win->cbr_vsu_mode = SCALE_UP_BIC;
2356                 break;
2357         case LB_RGB_3840X2:
2358                 if (win->yrgb_ver_scl_mode != SCALE_NONE)
2359                         pr_err("ERROR : not allow yrgb ver scale\n");
2360                 if (win->cbr_ver_scl_mode != SCALE_NONE)
2361                         pr_err("ERROR : not allow cbcr ver scale\n");
2362                 break;
2363         case LB_RGB_2560X4:
2364                 win->yrgb_vsu_mode = SCALE_UP_BIL;
2365                 win->cbr_vsu_mode = SCALE_UP_BIL;
2366                 break;
2367         default:
2368                 pr_info("%s:un supported win_lb_mode:%d\n",
2369                         __func__, win->win_lb_mode);
2370                 break;
2371         }
2372
2373         if (win->ymirror == 1)
2374                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2375         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
2376                 /* interlace mode must bill */
2377                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2378                 win->cbr_vsd_mode = SCALE_DOWN_BIL;
2379         }
2380         if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
2381             (win->area[0].fbdc_en == 1)) {
2382                 /* in this pattern,use bil mode,not support souble scd,
2383                  * use avg mode, support double scd, but aclk should be
2384                  * bigger than dclk.
2385                  */
2386                 if (yrgb_srcH >= 2 * yrgb_dstH) {
2387                         pr_err("ERROR : fbdc mode,not support y scale down:");
2388                         pr_err("srcH[%d] > 2 *dstH[%d]\n",
2389                                yrgb_srcH, yrgb_dstH);
2390                 }
2391         }
2392         DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
2393             win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
2394             win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
2395
2396         /* SCALE FACTOR */
2397
2398         /* (1.1)YRGB HOR SCALE FACTOR */
2399         switch (win->yrgb_hor_scl_mode) {
2400         case SCALE_NONE:
2401                 yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2402                 break;
2403         case SCALE_UP:
2404                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
2405                 break;
2406         case SCALE_DOWN:
2407                 switch (win->yrgb_hsd_mode) {
2408                 case SCALE_DOWN_BIL:
2409                         yrgb_xscl_factor =
2410                             GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
2411                         break;
2412                 case SCALE_DOWN_AVG:
2413                         yrgb_xscl_factor =
2414                             GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
2415                         break;
2416                 default:
2417                         pr_info("%s:un supported yrgb_hsd_mode:%d\n", __func__,
2418                                 win->yrgb_hsd_mode);
2419                         break;
2420                 }
2421                 break;
2422         default:
2423                 pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
2424                         __func__, win->yrgb_hor_scl_mode);
2425                 break;
2426         }
2427
2428         /* (1.2)YRGB VER SCALE FACTOR */
2429         switch (win->yrgb_ver_scl_mode) {
2430         case SCALE_NONE:
2431                 yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2432                 break;
2433         case SCALE_UP:
2434                 switch (win->yrgb_vsu_mode) {
2435                 case SCALE_UP_BIL:
2436                         yrgb_yscl_factor =
2437                             GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
2438                         break;
2439                 case SCALE_UP_BIC:
2440                         if (yrgb_srcH < 3) {
2441                                 pr_err("yrgb_srcH should be");
2442                                 pr_err(" greater than 3 !!!\n");
2443                         }
2444                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
2445                                                                 yrgb_dstH);
2446                         break;
2447                 default:
2448                         pr_info("%s:un support yrgb_vsu_mode:%d\n",
2449                                 __func__, win->yrgb_vsu_mode);
2450                         break;
2451                 }
2452                 break;
2453         case SCALE_DOWN:
2454                 switch (win->yrgb_vsd_mode) {
2455                 case SCALE_DOWN_BIL:
2456                         yrgb_vscalednmult =
2457                             vop_get_hard_ware_vskiplines(yrgb_srcH, yrgb_dstH);
2458                         yrgb_yscl_factor =
2459                             GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
2460                                                            yrgb_vscalednmult);
2461                         if (yrgb_yscl_factor >= 0x2000) {
2462                                 pr_err("yrgb_yscl_factor should less 0x2000");
2463                                 pr_err("yrgb_yscl_factor=%4x;\n",
2464                                        yrgb_yscl_factor);
2465                         }
2466                         if (yrgb_vscalednmult == 4) {
2467                                 yrgb_vsd_bil_gt4 = 1;
2468                                 yrgb_vsd_bil_gt2 = 0;
2469                         } else if (yrgb_vscalednmult == 2) {
2470                                 yrgb_vsd_bil_gt4 = 0;
2471                                 yrgb_vsd_bil_gt2 = 1;
2472                         } else {
2473                                 yrgb_vsd_bil_gt4 = 0;
2474                                 yrgb_vsd_bil_gt2 = 0;
2475                         }
2476                         break;
2477                 case SCALE_DOWN_AVG:
2478                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
2479                                                                  yrgb_dstH);
2480                         break;
2481                 default:
2482                         pr_info("%s:un support yrgb_vsd_mode:%d\n",
2483                                 __func__, win->yrgb_vsd_mode);
2484                         break;
2485                 }               /*win->yrgb_vsd_mode */
2486                 break;
2487         default:
2488                 pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
2489                         __func__, win->yrgb_ver_scl_mode);
2490                 break;
2491         }
2492         win->scale_yrgb_x = yrgb_xscl_factor;
2493         win->scale_yrgb_y = yrgb_yscl_factor;
2494         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
2495         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
2496         DBG(1, "yrgb:h_fac=%d, V_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
2497             yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
2498
2499         /*(2.1)CBCR HOR SCALE FACTOR */
2500         switch (win->cbr_hor_scl_mode) {
2501         case SCALE_NONE:
2502                 cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2503                 break;
2504         case SCALE_UP:
2505                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
2506                 break;
2507         case SCALE_DOWN:
2508                 switch (win->cbr_hsd_mode) {
2509                 case SCALE_DOWN_BIL:
2510                         cbcr_xscl_factor =
2511                             GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
2512                         break;
2513                 case SCALE_DOWN_AVG:
2514                         cbcr_xscl_factor =
2515                             GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
2516                         break;
2517                 default:
2518                         pr_info("%s:un support cbr_hsd_mode:%d\n",
2519                                 __func__, win->cbr_hsd_mode);
2520                         break;
2521                 }
2522                 break;
2523         default:
2524                 pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
2525                         __func__, win->cbr_hor_scl_mode);
2526                 break;
2527         }                       /*win->cbr_hor_scl_mode */
2528
2529         /* (2.2)CBCR VER SCALE FACTOR */
2530         switch (win->cbr_ver_scl_mode) {
2531         case SCALE_NONE:
2532                 cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2533                 break;
2534         case SCALE_UP:
2535                 switch (win->cbr_vsu_mode) {
2536                 case SCALE_UP_BIL:
2537                         cbcr_yscl_factor =
2538                             GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
2539                         break;
2540                 case SCALE_UP_BIC:
2541                         if (cbcr_srcH < 3) {
2542                                 pr_err("cbcr_srcH should be ");
2543                                 pr_err("greater than 3 !!!\n");
2544                         }
2545                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
2546                                                                 cbcr_dstH);
2547                         break;
2548                 default:
2549                         pr_info("%s:un support cbr_vsu_mode:%d\n",
2550                                 __func__, win->cbr_vsu_mode);
2551                         break;
2552                 }
2553                 break;
2554         case SCALE_DOWN:
2555                 switch (win->cbr_vsd_mode) {
2556                 case SCALE_DOWN_BIL:
2557                         cbcr_vscalednmult =
2558                             vop_get_hard_ware_vskiplines(cbcr_srcH, cbcr_dstH);
2559                         cbcr_yscl_factor =
2560                             GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
2561                                                            cbcr_vscalednmult);
2562                         if (cbcr_yscl_factor >= 0x2000) {
2563                                 pr_err("cbcr_yscl_factor should be less ");
2564                                 pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
2565                                        cbcr_yscl_factor);
2566                         }
2567
2568                         if (cbcr_vscalednmult == 4) {
2569                                 cbcr_vsd_bil_gt4 = 1;
2570                                 cbcr_vsd_bil_gt2 = 0;
2571                         } else if (cbcr_vscalednmult == 2) {
2572                                 cbcr_vsd_bil_gt4 = 0;
2573                                 cbcr_vsd_bil_gt2 = 1;
2574                         } else {
2575                                 cbcr_vsd_bil_gt4 = 0;
2576                                 cbcr_vsd_bil_gt2 = 0;
2577                         }
2578                         break;
2579                 case SCALE_DOWN_AVG:
2580                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
2581                                                                  cbcr_dstH);
2582                         break;
2583                 default:
2584                         pr_info("%s:un support cbr_vsd_mode:%d\n",
2585                                 __func__, win->cbr_vsd_mode);
2586                         break;
2587                 }
2588                 break;
2589         default:
2590                 pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
2591                         __func__, win->cbr_ver_scl_mode);
2592                 break;
2593         }
2594         win->scale_cbcr_x = cbcr_xscl_factor;
2595         win->scale_cbcr_y = cbcr_yscl_factor;
2596         win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
2597         win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
2598
2599         DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
2600             cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
2601         return 0;
2602 }
2603
2604 static int dsp_x_pos(int mirror_en, struct rk_screen *screen,
2605                      struct rk_lcdc_win_area *area)
2606 {
2607         int pos;
2608
2609         if (screen->x_mirror && mirror_en)
2610                 pr_err("not support both win and global mirror\n");
2611
2612         if ((!mirror_en) && (!screen->x_mirror))
2613                 pos = area->xpos + screen->mode.left_margin +
2614                         screen->mode.hsync_len;
2615         else
2616                 pos = screen->mode.xres - area->xpos -
2617                         area->xsize + screen->mode.left_margin +
2618                         screen->mode.hsync_len;
2619
2620         return pos;
2621 }
2622
2623 static int dsp_y_pos(int mirror_en, struct rk_screen *screen,
2624                      struct rk_lcdc_win_area *area)
2625 {
2626         int pos;
2627
2628         if (screen->y_mirror && mirror_en)
2629                 pr_err("not support both win and global mirror\n");
2630
2631         if ((!mirror_en) && (!screen->y_mirror))
2632                 pos = area->ypos + screen->mode.upper_margin +
2633                         screen->mode.vsync_len;
2634         else
2635                 pos = screen->mode.yres - area->ypos -
2636                         area->ysize + screen->mode.upper_margin +
2637                         screen->mode.vsync_len;
2638
2639         return pos;
2640 }
2641
2642 static int win_0_1_set_par(struct vop_device *vop_dev,
2643                            struct rk_screen *screen, struct rk_lcdc_win *win)
2644 {
2645         u32 xact, yact, xvir, yvir, xpos, ypos;
2646         u8 fmt_cfg = 0, swap_rb, swap_uv = 0;
2647         char fmt[9] = "NULL";
2648
2649         xpos = dsp_x_pos(win->xmirror, screen, &win->area[0]);
2650         ypos = dsp_y_pos(win->ymirror, screen, &win->area[0]);
2651
2652         spin_lock(&vop_dev->reg_lock);
2653         if (likely(vop_dev->clk_on)) {
2654                 vop_cal_scl_fac(win, screen);
2655                 switch (win->area[0].format) {
2656                 case FBDC_RGB_565:
2657                         fmt_cfg = 2;
2658                         swap_rb = 0;
2659                         win->fmt_10 = 0;
2660                         win->area[0].fbdc_fmt_cfg = 0x05;
2661                         break;
2662                 case FBDC_ARGB_888:
2663                         fmt_cfg = 0;
2664                         swap_rb = 0;
2665                         win->fmt_10 = 0;
2666                         win->area[0].fbdc_fmt_cfg = 0x0c;
2667                         break;
2668                 case FBDC_ABGR_888:
2669                         fmt_cfg = 0;
2670                         swap_rb = 1;
2671                         win->fmt_10 = 0;
2672                         win->area[0].fbdc_fmt_cfg = 0x0c;
2673                         break;
2674                 case FBDC_RGBX_888:
2675                         fmt_cfg = 0;
2676                         swap_rb = 0;
2677                         win->fmt_10 = 0;
2678                         win->area[0].fbdc_fmt_cfg = 0x3a;
2679                         break;
2680                 case ARGB888:
2681                         fmt_cfg = 0;
2682                         swap_rb = 0;
2683                         win->fmt_10 = 0;
2684                         break;
2685                 case XBGR888:
2686                 case ABGR888:
2687                         fmt_cfg = 0;
2688                         swap_rb = 1;
2689                         win->fmt_10 = 0;
2690                         break;
2691                 case BGR888:
2692                         fmt_cfg = 1;
2693                         swap_rb = 1;
2694                         win->fmt_10 = 0;
2695                         break;
2696                 case RGB888:
2697                         fmt_cfg = 1;
2698                         swap_rb = 0;
2699                         win->fmt_10 = 0;
2700                         break;
2701                 case RGB565:
2702                         fmt_cfg = 2;
2703                         swap_rb = 0;
2704                         win->fmt_10 = 0;
2705                         break;
2706                 case YUV422:
2707                         fmt_cfg = 5;
2708                         swap_rb = 0;
2709                         win->fmt_10 = 0;
2710                         break;
2711                 case YUV420:
2712                         fmt_cfg = 4;
2713                         swap_rb = 0;
2714                         win->fmt_10 = 0;
2715                         break;
2716                 case YUV420_NV21:
2717                         fmt_cfg = 4;
2718                         swap_rb = 0;
2719                         swap_uv = 1;
2720                         win->fmt_10 = 0;
2721                         break;
2722                 case YUV444:
2723                         fmt_cfg = 6;
2724                         swap_rb = 0;
2725                         win->fmt_10 = 0;
2726                         break;
2727                 case YUV422_A:
2728                         fmt_cfg = 5;
2729                         swap_rb = 0;
2730                         win->fmt_10 = 1;
2731                         break;
2732                 case YUV420_A:
2733                         fmt_cfg = 4;
2734                         swap_rb = 0;
2735                         win->fmt_10 = 1;
2736                         break;
2737                 case YUV444_A:
2738                         fmt_cfg = 6;
2739                         swap_rb = 0;
2740                         win->fmt_10 = 1;
2741                         break;
2742                 default:
2743                         dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n",
2744                                 __func__, win->area[0].format);
2745                         break;
2746                 }
2747                 win->area[0].fmt_cfg = fmt_cfg;
2748                 win->area[0].swap_rb = swap_rb;
2749                 win->area[0].swap_uv = swap_uv;
2750                 win->area[0].dsp_stx = xpos;
2751                 win->area[0].dsp_sty = ypos;
2752                 xact = win->area[0].xact;
2753                 yact = win->area[0].yact;
2754                 xvir = win->area[0].xvir;
2755                 yvir = win->area[0].yvir;
2756         }
2757         vop_win_0_1_reg_update(&vop_dev->driver, win->id);
2758         spin_unlock(&vop_dev->reg_lock);
2759
2760         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2761             vop_dev->id, win->id, get_format_string(win->area[0].format, fmt),
2762             xact, yact, win->area[0].xsize);
2763         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
2764             win->area[0].ysize, xvir, yvir, xpos, ypos);
2765
2766         return 0;
2767 }
2768
2769 static int win_2_3_set_par(struct vop_device *vop_dev,
2770                            struct rk_screen *screen, struct rk_lcdc_win *win)
2771 {
2772         int i;
2773         u8 fmt_cfg, swap_rb;
2774         char fmt[9] = "NULL";
2775
2776         if (VOP_CHIP(vop_dev) == VOP_RK322X) {
2777                 pr_err("rk3228 not support win2/3 set par\n");
2778                 return -EINVAL;
2779         }
2780         if (win->ymirror) {
2781                 pr_err("win[%d] not support y mirror\n", win->id);
2782                 return -EINVAL;
2783         }
2784         spin_lock(&vop_dev->reg_lock);
2785         if (likely(vop_dev->clk_on)) {
2786                 DBG(2, "lcdc[%d]:win[%d]>>\n>\n", vop_dev->id, win->id);
2787                 for (i = 0; i < win->area_num; i++) {
2788                         switch (win->area[i].format) {
2789                         case FBDC_RGB_565:
2790                                 fmt_cfg = 2;
2791                                 swap_rb = 0;
2792                                 win->fmt_10 = 0;
2793                                 win->area[0].fbdc_fmt_cfg = 0x05;
2794                                 break;
2795                         case FBDC_ARGB_888:
2796                                 fmt_cfg = 0;
2797                                 swap_rb = 0;
2798                                 win->fmt_10 = 0;
2799                                 win->area[0].fbdc_fmt_cfg = 0x0c;
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 = 0x3a;
2806                                 break;
2807                         case ARGB888:
2808                                 fmt_cfg = 0;
2809                                 swap_rb = 0;
2810                                 break;
2811                         case XBGR888:
2812                         case ABGR888:
2813                                 fmt_cfg = 0;
2814                                 swap_rb = 1;
2815                                 break;
2816                         case RGB888:
2817                                 fmt_cfg = 1;
2818                                 swap_rb = 0;
2819                                 break;
2820                         case RGB565:
2821                                 fmt_cfg = 2;
2822                                 swap_rb = 0;
2823                                 break;
2824                         default:
2825                                 dev_err(vop_dev->driver.dev,
2826                                         "%s:un supported format!\n", __func__);
2827                                 spin_unlock(&vop_dev->reg_lock);
2828                                 return -EINVAL;
2829                         }
2830                         win->area[i].fmt_cfg = fmt_cfg;
2831                         win->area[i].swap_rb = swap_rb;
2832                         win->area[i].dsp_stx = dsp_x_pos(win->xmirror, screen,
2833                                                          &win->area[i]);
2834                         win->area[i].dsp_sty = dsp_y_pos(win->ymirror, screen,
2835                                                          &win->area[i]);
2836                         if (((win->area[i].xact != win->area[i].xsize) ||
2837                              (win->area[i].yact != win->area[i].ysize)) &&
2838                             (screen->mode.vmode == FB_VMODE_NONINTERLACED)) {
2839                                 pr_err("win[%d]->area[%d],not support scale\n",
2840                                        win->id, i);
2841                                 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
2842                                        win->area[i].xact, win->area[i].yact,
2843                                        win->area[i].xsize, win->area[i].ysize);
2844                                 win->area[i].xsize = win->area[i].xact;
2845                                 win->area[i].ysize = win->area[i].yact;
2846                         }
2847                         DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
2848                             get_format_string(win->area[i].format, fmt),
2849                             win->area[i].xsize, win->area[i].ysize,
2850                             win->area[i].xpos, win->area[i].ypos);
2851                 }
2852         }
2853         vop_win_2_3_reg_update(&vop_dev->driver, win->id);
2854         spin_unlock(&vop_dev->reg_lock);
2855         return 0;
2856 }
2857
2858 static int hwc_set_par(struct vop_device *vop_dev,
2859                        struct rk_screen *screen, struct rk_lcdc_win *win)
2860 {
2861         u32 xact, yact, xvir, yvir, xpos, ypos;
2862         u8 fmt_cfg = 0, swap_rb;
2863         char fmt[9] = "NULL";
2864
2865         xpos = win->area[0].xpos + screen->mode.left_margin +
2866             screen->mode.hsync_len;
2867         ypos = win->area[0].ypos + screen->mode.upper_margin +
2868             screen->mode.vsync_len;
2869
2870         spin_lock(&vop_dev->reg_lock);
2871         if (likely(vop_dev->clk_on)) {
2872                 switch (win->area[0].format) {
2873                 case ARGB888:
2874                         fmt_cfg = 0;
2875                         swap_rb = 0;
2876                         break;
2877                 case XBGR888:
2878                 case ABGR888:
2879                         fmt_cfg = 0;
2880                         swap_rb = 1;
2881                         break;
2882                 case RGB888:
2883                         fmt_cfg = 1;
2884                         swap_rb = 0;
2885                         break;
2886                 case RGB565:
2887                         fmt_cfg = 2;
2888                         swap_rb = 0;
2889                         break;
2890                 default:
2891                         dev_err(vop_dev->dev, "%s:un supported format[%d]!\n",
2892                                 __func__, win->area[0].format);
2893                         break;
2894                 }
2895                 win->area[0].fmt_cfg = fmt_cfg;
2896                 win->area[0].swap_rb = swap_rb;
2897                 win->area[0].dsp_stx = xpos;
2898                 win->area[0].dsp_sty = ypos;
2899                 xact = win->area[0].xact;
2900                 yact = win->area[0].yact;
2901                 xvir = win->area[0].xvir;
2902                 yvir = win->area[0].yvir;
2903         }
2904         vop_hwc_reg_update(&vop_dev->driver, 4);
2905         spin_unlock(&vop_dev->reg_lock);
2906
2907         DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2908             vop_dev->id, __func__, get_format_string(win->area[0].format, fmt),
2909             xact, yact, win->area[0].xsize);
2910         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
2911             win->area[0].ysize, xvir, yvir, xpos, ypos);
2912         return 0;
2913 }
2914
2915 static int vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
2916 {
2917         struct vop_device *vop_dev =
2918             container_of(dev_drv, struct vop_device, driver);
2919         struct rk_lcdc_win *win = NULL;
2920         struct rk_screen *screen = dev_drv->cur_screen;
2921
2922         if (unlikely(!vop_dev->clk_on)) {
2923                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
2924                 return 0;
2925         }
2926         win = dev_drv->win[win_id];
2927         if (win)
2928         switch (win_id) {
2929         case 0:
2930                 win_0_1_set_par(vop_dev, screen, win);
2931                 break;
2932         case 1:
2933                 win_0_1_set_par(vop_dev, screen, win);
2934                 break;
2935         case 2:
2936                 win_2_3_set_par(vop_dev, screen, win);
2937                 break;
2938         case 3:
2939                 win_2_3_set_par(vop_dev, screen, win);
2940                 break;
2941         case 4:
2942                 hwc_set_par(vop_dev, screen, win);
2943                 break;
2944         default:
2945                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
2946                 break;
2947         }
2948         return 0;
2949 }
2950
2951 static int vop_set_writeback(struct rk_lcdc_driver *dev_drv)
2952 {
2953         struct vop_device *vop_dev =
2954             container_of(dev_drv, struct vop_device, driver);
2955         int output_color = dev_drv->output_color;
2956         struct rk_screen *screen = dev_drv->cur_screen;
2957         struct rk_fb_reg_wb_data *wb_data;
2958         int xact = screen->mode.xres;
2959         int yact = screen->mode.yres;
2960         u32 fmt_cfg;
2961         int xsize, ysize;
2962         u64 v;
2963
2964         if (unlikely(!vop_dev->clk_on)) {
2965                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
2966                 return 0;
2967         }
2968         wb_data = &dev_drv->wb_data;
2969
2970         xsize = wb_data->xsize;
2971         ysize = wb_data->ysize;
2972
2973         /*
2974          * RGB overlay mode support ARGB888, RGB888, RGB565, NV12,
2975          * but YUV overlay mode only support NV12, it's hard to judge RGB
2976          * or YUV overlay mode by userspace, so here force only support
2977          * NV12 mode.
2978          */
2979         if (wb_data->data_format != YUV420 && output_color != COLOR_RGB) {
2980                 pr_err("writeback only support NV12 when overlay is not RGB\n");
2981                 return -EINVAL;
2982         }
2983
2984         if (ysize != yact && ysize != (yact / 2)) {
2985                 pr_err("WriteBack only support yact=%d, ysize=%d\n",
2986                        yact, ysize);
2987                 return -EINVAL;
2988         }
2989
2990         switch (wb_data->data_format) {
2991         case ARGB888:
2992                 fmt_cfg = 0;
2993                 break;
2994         case RGB888:
2995                 fmt_cfg = 1;
2996                 break;
2997         case RGB565:
2998                 fmt_cfg = 2;
2999                 break;
3000         case YUV420:
3001                 fmt_cfg = 8;
3002                 break;
3003         default:
3004                 pr_info("unsupport fmt: %d\n", wb_data->data_format);
3005                 return -EINVAL;
3006         }
3007
3008         v = V_WB_EN(wb_data->state) | V_WB_FMT(fmt_cfg) | V_WB_RGB2YUV_MODE(1) |
3009                 V_WB_XPSD_BIL_EN(xact != xsize) |
3010                 V_WB_YTHROW_EN(ysize == (yact / 2)) |
3011                 V_WB_YTHROW_MODE(0);
3012
3013         v |= V_WB_RGB2YUV_EN((output_color == COLOR_RGB) &&
3014                              (wb_data->data_format == YUV420));
3015
3016         vop_msk_reg(vop_dev, WB_CTRL0, v);
3017
3018         v = V_WB_WIDTH(xsize) | V_WB_XPSD_BIL_FACTOR((xact << 12) / xsize);
3019
3020         vop_msk_reg(vop_dev, WB_CTRL1, v);
3021
3022         vop_writel(vop_dev, WB_YRGB_MST, wb_data->smem_start);
3023         if (wb_data->data_format == YUV420)
3024                 vop_writel(vop_dev, WB_CBR_MST, wb_data->smem_start);
3025
3026         return 0;
3027 }
3028
3029 static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
3030                      unsigned long arg, int win_id)
3031 {
3032         struct vop_device *vop_dev =
3033                         container_of(dev_drv, struct vop_device, driver);
3034         u32 panel_size[2];
3035         void __user *argp = (void __user *)arg;
3036         struct color_key_cfg clr_key_cfg;
3037
3038         switch (cmd) {
3039         case RK_FBIOGET_PANEL_SIZE:
3040                 panel_size[0] = vop_dev->screen->mode.xres;
3041                 panel_size[1] = vop_dev->screen->mode.yres;
3042                 if (copy_to_user(argp, panel_size, 8))
3043                         return -EFAULT;
3044                 break;
3045         case RK_FBIOPUT_COLOR_KEY_CFG:
3046                 if (copy_from_user(&clr_key_cfg, argp, sizeof(clr_key_cfg)))
3047                         return -EFAULT;
3048                 vop_clr_key_cfg(dev_drv);
3049                 vop_writel(vop_dev, WIN0_COLOR_KEY,
3050                            clr_key_cfg.win0_color_key_cfg);
3051                 vop_writel(vop_dev, WIN1_COLOR_KEY,
3052                            clr_key_cfg.win1_color_key_cfg);
3053                 break;
3054
3055         default:
3056                 break;
3057         }
3058         return 0;
3059 }
3060
3061 static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv)
3062 {
3063         struct vop_device *vop_dev = container_of(dev_drv,
3064                                                     struct vop_device, driver);
3065         struct device_node *backlight;
3066         struct property *prop;
3067         u32 *brightness_levels;
3068         u32 length, max, last;
3069
3070         if (vop_dev->backlight)
3071                 return 0;
3072         backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0);
3073         if (backlight) {
3074                 vop_dev->backlight = of_find_backlight_by_node(backlight);
3075                 if (!vop_dev->backlight)
3076                         dev_info(vop_dev->dev, "No find backlight device\n");
3077         } else {
3078                 dev_info(vop_dev->dev, "No find backlight device node\n");
3079         }
3080         prop = of_find_property(backlight, "brightness-levels", &length);
3081         if (!prop)
3082                 return -EINVAL;
3083         max = length / sizeof(u32);
3084         last = max - 1;
3085         brightness_levels = kmalloc(256, GFP_KERNEL);
3086         if (brightness_levels)
3087                 return -ENOMEM;
3088
3089         if (!of_property_read_u32_array(backlight, "brightness-levels",
3090                                         brightness_levels, max)) {
3091                 if (brightness_levels[0] > brightness_levels[last])
3092                         dev_drv->cabc_pwm_pol = 1;/*negative*/
3093                 else
3094                         dev_drv->cabc_pwm_pol = 0;/*positive*/
3095         } else {
3096                 dev_info(vop_dev->dev,
3097                          "Can not read brightness-levels value\n");
3098         }
3099
3100         kfree(brightness_levels);
3101
3102         return 0;
3103 }
3104
3105 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv)
3106 {
3107         struct vop_device *vop_dev =
3108             container_of(dev_drv, struct vop_device, driver);
3109
3110         if (dev_drv->suspend_flag)
3111                 return 0;
3112
3113         dev_drv->suspend_flag = 1;
3114         /* ensure suspend_flag take effect on multi process */
3115         smp_wmb();
3116         flush_kthread_worker(&dev_drv->update_regs_worker);
3117
3118         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
3119                 dev_drv->trsm_ops->disable();
3120
3121         if (likely(vop_dev->clk_on)) {
3122                 spin_lock(&vop_dev->reg_lock);
3123                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(1));
3124                 vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
3125                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(1));
3126                 vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1));
3127                 vop_cfg_done(vop_dev);
3128
3129                 if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3130                         mdelay(50);
3131                         rockchip_iovmm_deactivate(dev_drv->dev);
3132                 }
3133
3134                 spin_unlock(&vop_dev->reg_lock);
3135         }
3136
3137         vop_clk_disable(vop_dev);
3138         rk_disp_pwr_disable(dev_drv);
3139
3140         return 0;
3141 }
3142
3143 static int vop_early_resume(struct rk_lcdc_driver *dev_drv)
3144 {
3145         struct vop_device *vop_dev =
3146             container_of(dev_drv, struct vop_device, driver);
3147
3148         if (!dev_drv->suspend_flag)
3149                 return 0;
3150         rk_disp_pwr_enable(dev_drv);
3151
3152         vop_clk_enable(vop_dev);
3153         spin_lock(&vop_dev->reg_lock);
3154         memcpy(vop_dev->regs, vop_dev->regsbak, vop_dev->len);
3155         spin_unlock(&vop_dev->reg_lock);
3156
3157         vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
3158         vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
3159         spin_lock(&vop_dev->reg_lock);
3160
3161         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(0));
3162         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(0));
3163         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(0));
3164         vop_cfg_done(vop_dev);
3165         spin_unlock(&vop_dev->reg_lock);
3166
3167         if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3168                 /* win address maybe effect after next frame start,
3169                  * but mmu maybe effect right now, so we delay 50ms
3170                  */
3171                 mdelay(50);
3172                 rockchip_iovmm_activate(dev_drv->dev);
3173         }
3174
3175         dev_drv->suspend_flag = 0;
3176
3177         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
3178                 dev_drv->trsm_ops->enable();
3179
3180         return 0;
3181 }
3182
3183 static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode)
3184 {
3185         switch (blank_mode) {
3186         case FB_BLANK_UNBLANK:
3187                 vop_early_resume(dev_drv);
3188                 break;
3189         case FB_BLANK_NORMAL:
3190                 vop_early_suspend(dev_drv);
3191                 break;
3192         default:
3193                 vop_early_suspend(dev_drv);
3194                 break;
3195         }
3196
3197         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
3198
3199         return 0;
3200 }
3201
3202 static int vop_get_win_state(struct rk_lcdc_driver *dev_drv,
3203                              int win_id, int area_id)
3204 {
3205         struct vop_device *vop_dev =
3206                         container_of(dev_drv, struct vop_device, driver);
3207         u32 area_status = 0, state = 0;
3208
3209         switch (win_id) {
3210         case 0:
3211                 area_status = vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
3212                 break;
3213         case 1:
3214                 area_status = vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
3215                 break;
3216         case 2:
3217                 if (area_id == 0)
3218                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3219                                                    V_WIN2_MST0_EN(0));
3220                 if (area_id == 1)
3221                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3222                                                    V_WIN2_MST1_EN(0));
3223                 if (area_id == 2)
3224                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3225                                                    V_WIN2_MST2_EN(0));
3226                 if (area_id == 3)
3227                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3228                                                    V_WIN2_MST3_EN(0));
3229                 break;
3230         case 3:
3231                 if (area_id == 0)
3232                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3233                                                    V_WIN3_MST0_EN(0));
3234                 if (area_id == 1)
3235                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3236                                                    V_WIN3_MST1_EN(0));
3237                 if (area_id == 2)
3238                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3239                                                    V_WIN3_MST2_EN(0));
3240                 if (area_id == 3)
3241                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3242                                                    V_WIN3_MST3_EN(0));
3243                 break;
3244         case 4:
3245                 area_status = vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0));
3246                 break;
3247         default:
3248                 pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n",
3249                        __func__, win_id, area_id);
3250                 break;
3251         }
3252
3253         state = (area_status > 0) ? 1 : 0;
3254         return state;
3255 }
3256
3257 static int vop_get_area_num(struct rk_lcdc_driver *dev_drv,
3258                             unsigned int *area_support)
3259 {
3260         struct vop_device *vop_dev =
3261             container_of(dev_drv, struct vop_device, driver);
3262
3263         area_support[0] = 1;
3264         area_support[1] = 1;
3265
3266         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
3267                 area_support[2] = 4;
3268                 area_support[3] = 4;
3269         }
3270
3271         return 0;
3272 }
3273
3274 /*overlay will be do at regupdate*/
3275 static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set)
3276 {
3277         struct vop_device *vop_dev =
3278             container_of(dev_drv, struct vop_device, driver);
3279         struct rk_lcdc_win *win = NULL;
3280         int i, ovl;
3281         u64 val;
3282         int z_order_num = 0;
3283         int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3284
3285         if (swap == 0) {
3286                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3287                         win = dev_drv->win[i];
3288                         if (win->state == 1)
3289                                 z_order_num++;
3290                 }
3291                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3292                         win = dev_drv->win[i];
3293                         if (win->state == 0)
3294                                 win->z_order = z_order_num++;
3295                         switch (win->z_order) {
3296                         case 0:
3297                                 layer0_sel = win->id;
3298                                 break;
3299                         case 1:
3300                                 layer1_sel = win->id;
3301                                 break;
3302                         case 2:
3303                                 layer2_sel = win->id;
3304                                 break;
3305                         case 3:
3306                                 layer3_sel = win->id;
3307                                 break;
3308                         default:
3309                                 break;
3310                         }
3311                 }
3312         } else {
3313                 layer0_sel = swap % 10;
3314                 layer1_sel = swap / 10 % 10;
3315                 layer2_sel = swap / 100 % 10;
3316                 layer3_sel = swap / 1000;
3317         }
3318
3319         spin_lock(&vop_dev->reg_lock);
3320         if (vop_dev->clk_on) {
3321                 if (set) {
3322                         val = V_DSP_LAYER0_SEL(layer0_sel) |
3323                             V_DSP_LAYER1_SEL(layer1_sel) |
3324                             V_DSP_LAYER2_SEL(layer2_sel) |
3325                             V_DSP_LAYER3_SEL(layer3_sel);
3326                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
3327                 } else {
3328                         layer0_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3329                                                   V_DSP_LAYER0_SEL(0));
3330                         layer1_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3331                                                   V_DSP_LAYER1_SEL(0));
3332                         layer2_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3333                                                   V_DSP_LAYER2_SEL(0));
3334                         layer3_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3335                                                   V_DSP_LAYER3_SEL(0));
3336                         ovl = layer3_sel * 1000 + layer2_sel * 100 +
3337                             layer1_sel * 10 + layer0_sel;
3338                 }
3339         } else {
3340                 ovl = -EPERM;
3341         }
3342         spin_unlock(&vop_dev->reg_lock);
3343
3344         return ovl;
3345 }
3346
3347 static char *vop_format_to_string(int format, char *fmt)
3348 {
3349         if (!fmt)
3350                 return NULL;
3351
3352         switch (format) {
3353         case 0:
3354                 strcpy(fmt, "ARGB888");
3355                 break;
3356         case 1:
3357                 strcpy(fmt, "RGB888");
3358                 break;
3359         case 2:
3360                 strcpy(fmt, "RGB565");
3361                 break;
3362         case 4:
3363                 strcpy(fmt, "YCbCr420");
3364                 break;
3365         case 5:
3366                 strcpy(fmt, "YCbCr422");
3367                 break;
3368         case 6:
3369                 strcpy(fmt, "YCbCr444");
3370                 break;
3371         default:
3372                 strcpy(fmt, "invalid\n");
3373                 break;
3374         }
3375         return fmt;
3376 }
3377
3378 static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
3379                                  char *buf, int win_id)
3380 {
3381         struct vop_device *vop_dev =
3382             container_of(dev_drv, struct vop_device, driver);
3383         struct rk_screen *screen = dev_drv->cur_screen;
3384         u16 hsync_len = screen->mode.hsync_len;
3385         u16 left_margin = screen->mode.left_margin;
3386         u16 vsync_len = screen->mode.vsync_len;
3387         u16 upper_margin = screen->mode.upper_margin;
3388         u32 h_pw_bp = hsync_len + left_margin;
3389         u32 v_pw_bp = vsync_len + upper_margin;
3390         u32 fmt_id;
3391         char format_w0[9] = "NULL";
3392         char format_w1[9] = "NULL";
3393         char dsp_buf[100];
3394         u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
3395         u32 y_factor, uv_factor;
3396         u8 layer0_sel, layer1_sel;
3397         u8 w0_state, w1_state;
3398
3399         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
3400         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
3401         u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
3402         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
3403         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
3404         u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
3405
3406         u32 dclk_freq;
3407         int size = 0;
3408
3409         dclk_freq = screen->mode.pixclock;
3410         /*vop_reg_dump(dev_drv); */
3411
3412         spin_lock(&vop_dev->reg_lock);
3413         if (vop_dev->clk_on) {
3414                 zorder = vop_readl(vop_dev, DSP_CTRL1);
3415                 layer0_sel = (zorder & MASK(DSP_LAYER0_SEL)) >> 8;
3416                 layer1_sel = (zorder & MASK(DSP_LAYER1_SEL)) >> 10;
3417                 /* WIN0 */
3418                 win_ctrl = vop_readl(vop_dev, WIN0_CTRL0);
3419                 w0_state = win_ctrl & MASK(WIN0_EN);
3420                 fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1;
3421                 vop_format_to_string(fmt_id, format_w0);
3422                 vir_info = vop_readl(vop_dev, WIN0_VIR);
3423                 act_info = vop_readl(vop_dev, WIN0_ACT_INFO);
3424                 dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO);
3425                 dsp_st = vop_readl(vop_dev, WIN0_DSP_ST);
3426                 y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB);
3427                 uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR);
3428                 w0_vir_y = vir_info & MASK(WIN0_VIR_STRIDE);
3429                 w0_vir_uv = (vir_info & MASK(WIN0_VIR_STRIDE_UV)) >> 16;
3430                 w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1;
3431                 w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
3432                 w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1;
3433                 w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
3434                 if (w0_state) {
3435                         w0_st_x = dsp_st & MASK(WIN0_DSP_XST);
3436                         w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16;
3437                 }
3438                 w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB);
3439                 w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16;
3440                 w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR);
3441                 w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16;
3442
3443                 /* WIN1 */
3444                 win_ctrl = vop_readl(vop_dev, WIN1_CTRL0);
3445                 w1_state = win_ctrl & MASK(WIN1_EN);
3446                 fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1;
3447                 vop_format_to_string(fmt_id, format_w1);
3448                 vir_info = vop_readl(vop_dev, WIN1_VIR);
3449                 act_info = vop_readl(vop_dev, WIN1_ACT_INFO);
3450                 dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO);
3451                 dsp_st = vop_readl(vop_dev, WIN1_DSP_ST);
3452                 y_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_YRGB);
3453                 uv_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_CBR);
3454                 w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE);
3455                 w1_vir_uv = (vir_info & MASK(WIN1_VIR_STRIDE_UV)) >> 16;
3456                 w1_act_x = (act_info & MASK(WIN1_ACT_WIDTH)) + 1;
3457                 w1_act_y = ((act_info & MASK(WIN1_ACT_HEIGHT)) >> 16) + 1;
3458                 w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1;
3459                 w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1;
3460                 if (w1_state) {
3461                         w1_st_x = dsp_st & MASK(WIN1_DSP_XST);
3462                         w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16;
3463                 }
3464                 w1_y_h_fac = y_factor & MASK(WIN1_HS_FACTOR_YRGB);
3465                 w1_y_v_fac = (y_factor & MASK(WIN1_VS_FACTOR_YRGB)) >> 16;
3466                 w1_uv_h_fac = uv_factor & MASK(WIN1_HS_FACTOR_CBR);
3467                 w1_uv_v_fac = (uv_factor & MASK(WIN1_VS_FACTOR_CBR)) >> 16;
3468         } else {
3469                 spin_unlock(&vop_dev->reg_lock);
3470                 return -EPERM;
3471         }
3472         spin_unlock(&vop_dev->reg_lock);
3473         size += snprintf(dsp_buf, 80,
3474                 "z-order:\n  win[%d]\n  win[%d]\n",
3475                 layer1_sel, layer0_sel);
3476         strcat(buf, dsp_buf);
3477         memset(dsp_buf, 0, sizeof(dsp_buf));
3478         /* win0 */
3479         size += snprintf(dsp_buf, 80,
3480                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3481                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
3482         strcat(buf, dsp_buf);
3483         memset(dsp_buf, 0, sizeof(dsp_buf));
3484
3485         size += snprintf(dsp_buf, 80,
3486                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3487                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
3488         strcat(buf, dsp_buf);
3489         memset(dsp_buf, 0, sizeof(dsp_buf));
3490
3491         size += snprintf(dsp_buf, 80,
3492                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3493                  w0_st_x - h_pw_bp, w0_st_y - v_pw_bp, w0_y_h_fac, w0_y_v_fac);
3494         strcat(buf, dsp_buf);
3495         memset(dsp_buf, 0, sizeof(dsp_buf));
3496
3497         size += snprintf(dsp_buf, 80,
3498                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3499                  w0_uv_h_fac, w0_uv_v_fac, vop_readl(vop_dev, WIN0_YRGB_MST),
3500                  vop_readl(vop_dev, WIN0_CBR_MST));
3501         strcat(buf, dsp_buf);
3502         memset(dsp_buf, 0, sizeof(dsp_buf));
3503
3504         /* win1 */
3505         size += snprintf(dsp_buf, 80,
3506                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3507                  w1_state, format_w1, w1_vir_y, w1_vir_uv);
3508         strcat(buf, dsp_buf);
3509         memset(dsp_buf, 0, sizeof(dsp_buf));
3510
3511         size += snprintf(dsp_buf, 80,
3512                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3513                  w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
3514         strcat(buf, dsp_buf);
3515         memset(dsp_buf, 0, sizeof(dsp_buf));
3516
3517         size += snprintf(dsp_buf, 80,
3518                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3519                  w1_st_x - h_pw_bp, w1_st_y - v_pw_bp, w1_y_h_fac, w1_y_v_fac);
3520         strcat(buf, dsp_buf);
3521         memset(dsp_buf, 0, sizeof(dsp_buf));
3522
3523         size += snprintf(dsp_buf, 80,
3524                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3525                  w1_uv_h_fac, w1_uv_v_fac, vop_readl(vop_dev, WIN1_YRGB_MST),
3526                  vop_readl(vop_dev, WIN1_CBR_MST));
3527         strcat(buf, dsp_buf);
3528         memset(dsp_buf, 0, sizeof(dsp_buf));
3529
3530         return size;
3531 }
3532
3533 static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set)
3534 {
3535         struct vop_device *vop_dev =
3536             container_of(dev_drv, struct vop_device, driver);
3537         struct rk_screen *screen = dev_drv->cur_screen;
3538         u64 ft = 0;
3539         u32 dotclk;
3540         int ret;
3541         u32 pixclock;
3542         u32 x_total, y_total;
3543
3544         if (set) {
3545                 if (fps == 0) {
3546                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
3547                         return 0;
3548                 }
3549                 ft = div_u64(1000000000000llu, fps);
3550                 x_total =
3551                     screen->mode.upper_margin + screen->mode.lower_margin +
3552                     screen->mode.yres + screen->mode.vsync_len;
3553                 y_total =
3554                     screen->mode.left_margin + screen->mode.right_margin +
3555                     screen->mode.xres + screen->mode.hsync_len;
3556                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
3557                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
3558                 ret = clk_set_rate(vop_dev->dclk, dotclk);
3559         }
3560
3561         pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
3562         vop_dev->pixclock = pixclock;
3563         dev_drv->pixclock = vop_dev->pixclock;
3564         fps = rk_fb_calc_fps(screen, pixclock);
3565         screen->ft = 1000 / fps;        /*one frame time in ms */
3566
3567         if (set)
3568                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
3569                          clk_get_rate(vop_dev->dclk), fps);
3570
3571         return fps;
3572 }
3573
3574 static int vop_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
3575 {
3576         mutex_lock(&dev_drv->fb_win_id_mutex);
3577         if (order == FB_DEFAULT_ORDER)
3578                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
3579         dev_drv->fb4_win_id = order / 10000;
3580         dev_drv->fb3_win_id = (order / 1000) % 10;
3581         dev_drv->fb2_win_id = (order / 100) % 10;
3582         dev_drv->fb1_win_id = (order / 10) % 10;
3583         dev_drv->fb0_win_id = order % 10;
3584         mutex_unlock(&dev_drv->fb_win_id_mutex);
3585
3586         return 0;
3587 }
3588
3589 static int vop_get_win_id(struct rk_lcdc_driver *dev_drv, const char *id)
3590 {
3591         int win_id = 0;
3592
3593         mutex_lock(&dev_drv->fb_win_id_mutex);
3594         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
3595                 win_id = dev_drv->fb0_win_id;
3596         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
3597                 win_id = dev_drv->fb1_win_id;
3598         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
3599                 win_id = dev_drv->fb2_win_id;
3600         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
3601                 win_id = dev_drv->fb3_win_id;
3602         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
3603                 win_id = dev_drv->fb4_win_id;
3604         mutex_unlock(&dev_drv->fb_win_id_mutex);
3605
3606         return win_id;
3607 }
3608
3609 static int vop_config_done(struct rk_lcdc_driver *dev_drv)
3610 {
3611         struct vop_device *vop_dev =
3612             container_of(dev_drv, struct vop_device, driver);
3613         int i;
3614         u64 val;
3615         struct rk_lcdc_win *win = NULL;
3616
3617         spin_lock(&vop_dev->reg_lock);
3618         vop_post_cfg(dev_drv);
3619         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby));
3620         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3621                 win = dev_drv->win[i];
3622                 if ((win->state == 0) && (win->last_state == 1)) {
3623                         switch (win->id) {
3624                         case 0:
3625                                 val = V_WIN0_EN(0);
3626                                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
3627                                 break;
3628                         case 1:
3629                                 val = V_WIN1_EN(0);
3630                                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
3631                                 break;
3632                         case 2:
3633                                 val = V_WIN2_EN(0) | V_WIN2_MST0_EN(0) |
3634                                     V_WIN2_MST1_EN(0) |
3635                                     V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
3636                                 vop_msk_reg(vop_dev, WIN2_CTRL0, val);
3637                                 break;
3638                         case 3:
3639                                 val = V_WIN3_EN(0) | V_WIN3_MST0_EN(0) |
3640                                     V_WIN3_MST1_EN(0) |
3641                                     V_WIN3_MST2_EN(0) | V_WIN3_MST3_EN(0);
3642                                 vop_msk_reg(vop_dev, WIN3_CTRL0, val);
3643                                 break;
3644                         case 4:
3645                                 val = V_HWC_EN(0);
3646                                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
3647                                 break;
3648                         default:
3649                                 break;
3650                         }
3651                 }
3652                 win->last_state = win->state;
3653         }
3654         vop_cfg_done(vop_dev);
3655         spin_unlock(&vop_dev->reg_lock);
3656         return 0;
3657 }
3658
3659 static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
3660 {
3661         struct vop_device *vop_dev =
3662             container_of(dev_drv, struct vop_device, driver);
3663         spin_lock(&vop_dev->reg_lock);
3664         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(open));
3665         vop_cfg_done(vop_dev);
3666         spin_unlock(&vop_dev->reg_lock);
3667         return 0;
3668 }
3669
3670 static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
3671 {
3672         struct vop_device *vop_dev = container_of(dev_drv,
3673                                                     struct vop_device, driver);
3674         spin_lock(&vop_dev->reg_lock);
3675         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_LAYER_SEL(win_id));
3676         vop_cfg_done(vop_dev);
3677         spin_unlock(&vop_dev->reg_lock);
3678         return 0;
3679 }
3680
3681 static int vop_dpi_status(struct rk_lcdc_driver *dev_drv)
3682 {
3683         struct vop_device *vop_dev =
3684             container_of(dev_drv, struct vop_device, driver);
3685         int ovl;
3686
3687         spin_lock(&vop_dev->reg_lock);
3688         ovl = vop_read_bit(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(0));
3689         spin_unlock(&vop_dev->reg_lock);
3690         return ovl;
3691 }
3692
3693 static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
3694 {
3695         struct vop_device *vop_dev =
3696                         container_of(dev_drv, struct vop_device, driver);
3697         if (enable)
3698                 enable_irq(vop_dev->irq);
3699         else
3700                 disable_irq(vop_dev->irq);
3701         return 0;
3702 }
3703
3704 int vop_poll_vblank(struct rk_lcdc_driver *dev_drv)
3705 {
3706         struct vop_device *vop_dev =
3707             container_of(dev_drv, struct vop_device, driver);
3708         u32 int_reg;
3709         int ret;
3710
3711         if (vop_dev->clk_on && (!dev_drv->suspend_flag)) {
3712                 int_reg = vop_readl(vop_dev, INTR_STATUS0);
3713                 if (int_reg & INTR_LINE_FLAG0) {
3714                         vop_dev->driver.frame_time.last_framedone_t =
3715                             vop_dev->driver.frame_time.framedone_t;
3716                         vop_dev->driver.frame_time.framedone_t = cpu_clock(0);
3717                         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_LINE_FLAG0,
3718                                         INTR_LINE_FLAG0);
3719                         ret = RK_LF_STATUS_FC;
3720                 } else {
3721                         ret = RK_LF_STATUS_FR;
3722                 }
3723         } else {
3724                 ret = RK_LF_STATUS_NC;
3725         }
3726
3727         return ret;
3728 }
3729
3730 static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
3731                             unsigned int dsp_addr[][4])
3732 {
3733         struct vop_device *vop_dev =
3734             container_of(dev_drv, struct vop_device, driver);
3735         spin_lock(&vop_dev->reg_lock);
3736         if (vop_dev->clk_on) {
3737                 dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST);
3738                 dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST);
3739                 dsp_addr[2][0] = vop_readl(vop_dev, WIN2_MST0);
3740                 dsp_addr[2][1] = vop_readl(vop_dev, WIN2_MST1);
3741                 dsp_addr[2][2] = vop_readl(vop_dev, WIN2_MST2);
3742                 dsp_addr[2][3] = vop_readl(vop_dev, WIN2_MST3);
3743                 dsp_addr[3][0] = vop_readl(vop_dev, WIN3_MST0);
3744                 dsp_addr[3][1] = vop_readl(vop_dev, WIN3_MST1);
3745                 dsp_addr[3][2] = vop_readl(vop_dev, WIN3_MST2);
3746                 dsp_addr[3][3] = vop_readl(vop_dev, WIN3_MST3);
3747                 dsp_addr[4][0] = vop_readl(vop_dev, HWC_MST);
3748         }
3749         spin_unlock(&vop_dev->reg_lock);
3750         return 0;
3751 }
3752
3753
3754 int vop_update_pwm(int bl_pwm_period, int bl_pwm_duty)
3755 {
3756         /*
3757          * TODO:
3758          * pwm_period_hpr = bl_pwm_period;
3759          * pwm_duty_lpr = bl_pwm_duty;
3760          * pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n",
3761          * bl_pwm_period, bl_pwm_duty);
3762          */
3763
3764         return 0;
3765 }
3766
3767 /*
3768  *  a:[-30~0]:
3769  *    sin_hue = sin(a)*256 +0x100;
3770  *    cos_hue = cos(a)*256;
3771  *  a:[0~30]
3772  *    sin_hue = sin(a)*256;
3773  *    cos_hue = cos(a)*256;
3774  */
3775 static int vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode)
3776 {
3777         struct vop_device *vop_dev =
3778             container_of(dev_drv, struct vop_device, driver);
3779         u32 val;
3780
3781         spin_lock(&vop_dev->reg_lock);
3782         if (vop_dev->clk_on) {
3783                 val = vop_readl(vop_dev, BCSH_H);
3784                 switch (mode) {
3785                 case H_SIN:
3786                         val &= MASK(SIN_HUE);
3787                         break;
3788                 case H_COS:
3789                         val &= MASK(COS_HUE);
3790                         val >>= 16;
3791                         break;
3792                 default:
3793                         break;
3794                 }
3795         }
3796         spin_unlock(&vop_dev->reg_lock);
3797
3798         return val;
3799 }
3800
3801 static int vop_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode,
3802                             int calc, int up, int down, int global)
3803 {
3804         struct vop_device *vop_dev =
3805                         container_of(dev_drv, struct vop_device, driver);
3806         struct rk_screen *screen = dev_drv->cur_screen;
3807         u32 total_pixel, calc_pixel, stage_up, stage_down;
3808         u32 pixel_num, global_dn;
3809
3810         if (!vop_dev->cabc_lut_addr_base) {
3811                 pr_err("vop chip[%d] not supoort cabc\n", VOP_CHIP(vop_dev));
3812                 return 0;
3813         }
3814
3815         if (!screen->cabc_lut) {
3816                 pr_err("screen cabc lut not config, so not open cabc\n");
3817                 return 0;
3818         }
3819
3820         dev_drv->cabc_mode = mode;
3821         if (!dev_drv->cabc_mode) {
3822                 spin_lock(&vop_dev->reg_lock);
3823                 if (vop_dev->clk_on) {
3824                         vop_msk_reg(vop_dev, CABC_CTRL0,
3825                                     V_CABC_EN(0) | V_CABC_HANDLE_EN(0));
3826                         vop_cfg_done(vop_dev);
3827                 }
3828                 pr_info("mode = 0, close cabc\n");
3829                 spin_unlock(&vop_dev->reg_lock);
3830                 return 0;
3831         }
3832
3833         total_pixel = screen->mode.xres * screen->mode.yres;
3834         pixel_num = 1000 - calc;
3835         calc_pixel = (total_pixel * pixel_num) / 1000;
3836         stage_up = up;
3837         stage_down = down;
3838         global_dn = global;
3839         pr_info("enable cabc:mode=%d, calc=%d, up=%d, down=%d, global=%d\n",
3840                 mode, calc, stage_up, stage_down, global_dn);
3841
3842         spin_lock(&vop_dev->reg_lock);
3843         if (vop_dev->clk_on) {
3844                 u64 val = 0;
3845
3846                 val = V_CABC_EN(1) | V_CABC_HANDLE_EN(1) |
3847                         V_PWM_CONFIG_MODE(STAGE_BY_STAGE) |
3848                         V_CABC_CALC_PIXEL_NUM(calc_pixel);
3849                 vop_msk_reg(vop_dev, CABC_CTRL0, val);
3850
3851                 val = V_CABC_LUT_EN(1) | V_CABC_TOTAL_NUM(total_pixel);
3852                 vop_msk_reg(vop_dev, CABC_CTRL1, val);
3853
3854                 val = V_CABC_STAGE_DOWN(stage_down) |
3855                         V_CABC_STAGE_UP(stage_up) |
3856                         V_CABC_STAGE_UP_MODE(0) | V_MAX_SCALE_CFG_VALUE(1) |
3857                         V_MAX_SCALE_CFG_ENABLE(0);
3858                 vop_msk_reg(vop_dev, CABC_CTRL2, val);
3859
3860                 val = V_CABC_GLOBAL_DN(global_dn) |
3861                         V_CABC_GLOBAL_DN_LIMIT_EN(1);
3862                 vop_msk_reg(vop_dev, CABC_CTRL3, val);
3863                 vop_cfg_done(vop_dev);
3864         }
3865         spin_unlock(&vop_dev->reg_lock);
3866
3867         return 0;
3868 }
3869
3870 static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
3871                             int sin_hue, int cos_hue)
3872 {
3873         struct vop_device *vop_dev =
3874             container_of(dev_drv, struct vop_device, driver);
3875         u64 val;
3876
3877         spin_lock(&vop_dev->reg_lock);
3878         if (vop_dev->clk_on) {
3879                 val = V_SIN_HUE(sin_hue) | V_COS_HUE(cos_hue);
3880                 vop_msk_reg(vop_dev, BCSH_H, val);
3881                 vop_cfg_done(vop_dev);
3882         }
3883         spin_unlock(&vop_dev->reg_lock);
3884
3885         return 0;
3886 }
3887
3888 static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
3889                             bcsh_bcs_mode mode, int value)
3890 {
3891         struct vop_device *vop_dev =
3892             container_of(dev_drv, struct vop_device, driver);
3893         u64 val;
3894
3895         spin_lock(&vop_dev->reg_lock);
3896         if (vop_dev->clk_on) {
3897                 switch (mode) {
3898                 case BRIGHTNESS:
3899                         /*from 0 to 255,typical is 128 */
3900                         if (value < 0x80)
3901                                 value += 0x80;
3902                         else if (value >= 0x80)
3903                                 value = value - 0x80;
3904                         val = V_BRIGHTNESS(value);
3905                         break;
3906                 case CONTRAST:
3907                         /*from 0 to 510,typical is 256 */
3908                         val = V_CONTRAST(value);
3909                         break;
3910                 case SAT_CON:
3911                         /*from 0 to 1015,typical is 256 */
3912                         val = V_SAT_CON(value);
3913                         break;
3914                 default:
3915                         break;
3916                 }
3917                 vop_msk_reg(vop_dev, BCSH_BCS, val);
3918                 vop_cfg_done(vop_dev);
3919         }
3920         spin_unlock(&vop_dev->reg_lock);
3921
3922         return val;
3923 }
3924
3925 static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode)
3926 {
3927         struct vop_device *vop_dev =
3928             container_of(dev_drv, struct vop_device, driver);
3929         u64 val;
3930
3931         spin_lock(&vop_dev->reg_lock);
3932         if (vop_dev->clk_on) {
3933                 val = vop_readl(vop_dev, BCSH_BCS);
3934                 switch (mode) {
3935                 case BRIGHTNESS:
3936                         val &= MASK(BRIGHTNESS);
3937                         if (val > 0x80)
3938                                 val -= 0x80;
3939                         else
3940                                 val += 0x80;
3941                         break;
3942                 case CONTRAST:
3943                         val &= MASK(CONTRAST);
3944                         val >>= 8;
3945                         break;
3946                 case SAT_CON:
3947                         val &= MASK(SAT_CON);
3948                         val >>= 20;
3949                         break;
3950                 default:
3951                         break;
3952                 }
3953         }
3954         spin_unlock(&vop_dev->reg_lock);
3955         return val;
3956 }
3957
3958 static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
3959 {
3960         struct vop_device *vop_dev =
3961             container_of(dev_drv, struct vop_device, driver);
3962
3963         spin_lock(&vop_dev->reg_lock);
3964         if (vop_dev->clk_on) {
3965                 if (open) {
3966                         vop_writel(vop_dev, BCSH_COLOR_BAR, 0x1);
3967                         vop_writel(vop_dev, BCSH_BCS, 0xd0010000);
3968                         vop_writel(vop_dev, BCSH_H, 0x01000000);
3969                         dev_drv->bcsh.enable = 1;
3970                 } else {
3971                         vop_msk_reg(vop_dev, BCSH_COLOR_BAR, V_BCSH_EN(0));
3972                         dev_drv->bcsh.enable = 0;
3973                 }
3974                 vop_bcsh_path_sel(dev_drv);
3975                 vop_cfg_done(vop_dev);
3976         }
3977         spin_unlock(&vop_dev->reg_lock);
3978
3979         return 0;
3980 }
3981
3982 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
3983 {
3984         if (!enable || !dev_drv->bcsh.enable) {
3985                 vop_open_bcsh(dev_drv, false);
3986                 return 0;
3987         }
3988
3989         if (dev_drv->bcsh.brightness <= 255 ||
3990             dev_drv->bcsh.contrast <= 510 ||
3991             dev_drv->bcsh.sat_con <= 1015 ||
3992             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
3993                 vop_open_bcsh(dev_drv, true);
3994                 if (dev_drv->bcsh.brightness <= 255)
3995                         vop_set_bcsh_bcs(dev_drv, BRIGHTNESS,
3996                                          dev_drv->bcsh.brightness);
3997                 if (dev_drv->bcsh.contrast <= 510)
3998                         vop_set_bcsh_bcs(dev_drv, CONTRAST,
3999                                          dev_drv->bcsh.contrast);
4000                 if (dev_drv->bcsh.sat_con <= 1015)
4001                         vop_set_bcsh_bcs(dev_drv, SAT_CON,
4002                                          dev_drv->bcsh.sat_con);
4003                 if (dev_drv->bcsh.sin_hue <= 511 &&
4004                     dev_drv->bcsh.cos_hue <= 511)
4005                         vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue,
4006                                          dev_drv->bcsh.cos_hue);
4007         }
4008
4009         return 0;
4010 }
4011
4012 static int __maybe_unused
4013 vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
4014 {
4015         struct vop_device *vop_dev =
4016             container_of(dev_drv, struct vop_device, driver);
4017
4018         if (enable) {
4019                 spin_lock(&vop_dev->reg_lock);
4020                 if (likely(vop_dev->clk_on)) {
4021                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1));
4022                         vop_cfg_done(vop_dev);
4023                 }
4024                 spin_unlock(&vop_dev->reg_lock);
4025         } else {
4026                 spin_lock(&vop_dev->reg_lock);
4027                 if (likely(vop_dev->clk_on)) {
4028                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0));
4029
4030                         vop_cfg_done(vop_dev);
4031                 }
4032                 spin_unlock(&vop_dev->reg_lock);
4033         }
4034
4035         return 0;
4036 }
4037
4038 static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable)
4039 {
4040         struct vop_device *vop_dev =
4041             container_of(dev_drv, struct vop_device, driver);
4042
4043         if (unlikely(!vop_dev->clk_on)) {
4044                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4045                 return 0;
4046         }
4047         vop_get_backlight_device(dev_drv);
4048
4049         if (enable) {
4050                 /* close the backlight */
4051                 if (vop_dev->backlight) {
4052                         vop_dev->backlight->props.power = FB_BLANK_POWERDOWN;
4053                         backlight_update_status(vop_dev->backlight);
4054                 }
4055                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4056                         dev_drv->trsm_ops->disable();
4057         } else {
4058                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
4059                         dev_drv->trsm_ops->enable();
4060                 msleep(100);
4061                 /* open the backlight */
4062                 if (vop_dev->backlight) {
4063                         vop_dev->backlight->props.power = FB_BLANK_UNBLANK;
4064                         backlight_update_status(vop_dev->backlight);
4065                 }
4066         }
4067
4068         return 0;
4069 }
4070
4071 static int vop_set_overscan(struct rk_lcdc_driver *dev_drv,
4072                             struct overscan *overscan)
4073 {
4074         struct vop_device *vop_dev =
4075             container_of(dev_drv, struct vop_device, driver);
4076
4077         if (unlikely(!vop_dev->clk_on)) {
4078                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4079                 return 0;
4080         }
4081         /*vop_post_cfg(dev_drv);*/
4082
4083         return 0;
4084 }
4085
4086 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
4087         .open = vop_open,
4088         .win_direct_en = vop_win_direct_en,
4089         .load_screen = vop_load_screen,
4090         .get_dspbuf_info = vop_get_dspbuf_info,
4091         .post_dspbuf = vop_post_dspbuf,
4092         .set_par = vop_set_par,
4093         .pan_display = vop_pan_display,
4094         .set_wb = vop_set_writeback,
4095         .direct_set_addr = vop_direct_set_win_addr,
4096         /*.lcdc_reg_update = vop_reg_update,*/
4097         .blank = vop_blank,
4098         .ioctl = vop_ioctl,
4099         .suspend = vop_early_suspend,
4100         .resume = vop_early_resume,
4101         .get_win_state = vop_get_win_state,
4102         .area_support_num = vop_get_area_num,
4103         .ovl_mgr = vop_ovl_mgr,
4104         .get_disp_info = vop_get_disp_info,
4105         .fps_mgr = vop_fps_mgr,
4106         .fb_get_win_id = vop_get_win_id,
4107         .fb_win_remap = vop_fb_win_remap,
4108         .poll_vblank = vop_poll_vblank,
4109         .dpi_open = vop_dpi_open,
4110         .dpi_win_sel = vop_dpi_win_sel,
4111         .dpi_status = vop_dpi_status,
4112         .get_dsp_addr = vop_get_dsp_addr,
4113         .set_dsp_lut = vop_set_lut,
4114         .set_cabc_lut = vop_set_cabc,
4115         .set_dsp_cabc = vop_set_dsp_cabc,
4116         .set_dsp_bcsh_hue = vop_set_bcsh_hue,
4117         .set_dsp_bcsh_bcs = vop_set_bcsh_bcs,
4118         .get_dsp_bcsh_hue = vop_get_bcsh_hue,
4119         .get_dsp_bcsh_bcs = vop_get_bcsh_bcs,
4120         .open_bcsh = vop_open_bcsh,
4121         .dump_reg = vop_reg_dump,
4122         .cfg_done = vop_config_done,
4123         .set_irq_to_cpu = vop_set_irq_to_cpu,
4124         /*.dsp_black = vop_dsp_black,*/
4125         .backlight_close = vop_backlight_close,
4126         .mmu_en    = vop_mmu_en,
4127         .set_overscan   = vop_set_overscan,
4128 };
4129
4130 static irqreturn_t vop_isr(int irq, void *dev_id)
4131 {
4132         struct vop_device *vop_dev = (struct vop_device *)dev_id;
4133         ktime_t timestamp = ktime_get();
4134         u32 intr_status;
4135         unsigned long flags;
4136
4137         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4138
4139         intr_status = vop_readl(vop_dev, INTR_STATUS0);
4140         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, intr_status);
4141
4142         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4143         /* This is expected for vop iommu irqs, since the irq is shared */
4144         if (!intr_status)
4145                 return IRQ_NONE;
4146
4147         if (intr_status & INTR_FS) {
4148                 timestamp = ktime_get();
4149                 if (vop_dev->wb_on) {
4150                         u32 wb_status;
4151
4152                         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4153                         wb_status = vop_read_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4154                         if (wb_status)
4155                                 vop_set_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4156
4157                         vop_cfg_done(vop_dev);
4158                         vop_dev->driver.wb_data.state = 0;
4159                         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4160                 }
4161                 vop_dev->driver.vsync_info.timestamp = timestamp;
4162                 wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait);
4163                 intr_status &= ~INTR_FS;
4164         }
4165
4166         if (intr_status & INTR_LINE_FLAG0)
4167                 intr_status &= ~INTR_LINE_FLAG0;
4168
4169         if (intr_status & INTR_LINE_FLAG1)
4170                 intr_status &= ~INTR_LINE_FLAG1;
4171
4172         if (intr_status & INTR_FS_NEW)
4173                 intr_status &= ~INTR_FS_NEW;
4174
4175         if (intr_status & INTR_BUS_ERROR) {
4176                 intr_status &= ~INTR_BUS_ERROR;
4177                 dev_warn_ratelimited(vop_dev->dev, "bus error!");
4178         }
4179
4180         if (intr_status & INTR_WIN0_EMPTY) {
4181                 intr_status &= ~INTR_WIN0_EMPTY;
4182                 dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!");
4183         }
4184
4185         if (intr_status & INTR_WIN1_EMPTY) {
4186                 intr_status &= ~INTR_WIN1_EMPTY;
4187                 dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!");
4188         }
4189
4190         if (intr_status & INTR_HWC_EMPTY) {
4191                 intr_status &= ~INTR_HWC_EMPTY;
4192                 dev_warn_ratelimited(vop_dev->dev, "intr hwc empty!");
4193         }
4194
4195         if (intr_status & INTR_POST_BUF_EMPTY) {
4196                 intr_status &= ~INTR_POST_BUF_EMPTY;
4197                 dev_warn_ratelimited(vop_dev->dev, "intr post buf empty!");
4198         }
4199
4200         if (intr_status)
4201                 dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status);
4202
4203         return IRQ_HANDLED;
4204 }
4205
4206 #if defined(CONFIG_PM)
4207 static int vop_suspend(struct platform_device *pdev, pm_message_t state)
4208 {
4209         return 0;
4210 }
4211
4212 static int vop_resume(struct platform_device *pdev)
4213 {
4214         return 0;
4215 }
4216 #else
4217 #define vop_suspend NULL
4218 #define vop_resume  NULL
4219 #endif
4220
4221 static int vop_parse_dt(struct vop_device *vop_dev)
4222 {
4223         struct device_node *np = vop_dev->dev->of_node;
4224         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
4225         int val;
4226
4227         if (of_property_read_u32(np, "rockchip,prop", &val))
4228                 vop_dev->prop = PRMRY;  /*default set it as primary */
4229         else
4230                 vop_dev->prop = val;
4231
4232         if (of_property_read_u32(np, "rockchip,mirror", &val))
4233                 dev_drv->rotate_mode = NO_MIRROR;
4234         else
4235                 dev_drv->rotate_mode = val;
4236
4237         if (of_property_read_u32(np, "rockchip,pwr18", &val))
4238                 /*default set it as 3.xv power supply */
4239                 vop_dev->pwr18 = false;
4240         else
4241                 vop_dev->pwr18 = (val ? true : false);
4242
4243         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
4244                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
4245         else
4246                 dev_drv->fb_win_map = val;
4247
4248         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
4249                 dev_drv->bcsh.enable = false;
4250         else
4251                 dev_drv->bcsh.enable = (val ? true : false);
4252
4253         if (of_property_read_u32(np, "rockchip,brightness", &val))
4254                 dev_drv->bcsh.brightness = 0xffff;
4255         else
4256                 dev_drv->bcsh.brightness = val;
4257
4258         if (of_property_read_u32(np, "rockchip,contrast", &val))
4259                 dev_drv->bcsh.contrast = 0xffff;
4260         else
4261                 dev_drv->bcsh.contrast = val;
4262
4263         if (of_property_read_u32(np, "rockchip,sat-con", &val))
4264                 dev_drv->bcsh.sat_con = 0xffff;
4265         else
4266                 dev_drv->bcsh.sat_con = val;
4267
4268         if (of_property_read_u32(np, "rockchip,hue", &val)) {
4269                 dev_drv->bcsh.sin_hue = 0xffff;
4270                 dev_drv->bcsh.cos_hue = 0xffff;
4271         } else {
4272                 dev_drv->bcsh.sin_hue = val & 0xff;
4273                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
4274         }
4275
4276         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
4277                 dev_drv->iommu_enabled = 0;
4278         else
4279                 dev_drv->iommu_enabled = val;
4280         return 0;
4281 }
4282
4283 static int vop_probe(struct platform_device *pdev)
4284 {
4285         struct vop_device *vop_dev = NULL;
4286         struct rk_lcdc_driver *dev_drv;
4287         const struct of_device_id *of_id;
4288         struct device *dev = &pdev->dev;
4289         struct resource *res;
4290         struct device_node *np = pdev->dev.of_node;
4291         int prop;
4292         int ret = 0;
4293
4294         /* if the primary lcdc has not registered ,the extend
4295          * lcdc register later
4296          */
4297         of_property_read_u32(np, "rockchip,prop", &prop);
4298         if (prop == EXTEND) {
4299                 if (!is_prmry_rk_lcdc_registered())
4300                         return -EPROBE_DEFER;
4301         }
4302         vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL);
4303         if (!vop_dev)
4304                 return -ENOMEM;
4305         of_id = of_match_device(vop_dt_ids, dev);
4306         vop_dev->data = of_id->data;
4307         if (VOP_CHIP(vop_dev) != VOP_RK322X && VOP_CHIP(vop_dev) != VOP_RK3399)
4308                 return -ENODEV;
4309         platform_set_drvdata(pdev, vop_dev);
4310         vop_dev->dev = dev;
4311         vop_parse_dt(vop_dev);
4312         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4313         vop_dev->reg_phy_base = res->start;
4314         vop_dev->len = resource_size(res);
4315         vop_dev->regs = devm_ioremap_resource(dev, res);
4316         if (IS_ERR(vop_dev->regs))
4317                 return PTR_ERR(vop_dev->regs);
4318
4319         dev_info(dev, "vop_dev->regs=0x%lx\n", (long)vop_dev->regs);
4320
4321         vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL);
4322         if (IS_ERR(vop_dev->regsbak))
4323                 return PTR_ERR(vop_dev->regsbak);
4324         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
4325                 vop_dev->dsp_lut_addr_base = vop_dev->regs + GAMMA_LUT_ADDR;
4326                 vop_dev->cabc_lut_addr_base = vop_dev->regs +
4327                                                 CABC_GAMMA_LUT_ADDR;
4328         }
4329         vop_dev->grf_base =
4330                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
4331         if (IS_ERR(vop_dev->grf_base)) {
4332                 dev_err(&pdev->dev, "can't find lcdc grf property\n");
4333                 vop_dev->grf_base = NULL;
4334         }
4335
4336         vop_dev->id = vop_get_id(vop_dev, vop_dev->reg_phy_base);
4337         dev_set_name(vop_dev->dev, "vop%d", vop_dev->id);
4338         dev_drv = &vop_dev->driver;
4339         dev_drv->dev = dev;
4340         dev_drv->prop = prop;
4341         dev_drv->id = vop_dev->id;
4342         dev_drv->ops = &lcdc_drv_ops;
4343         dev_drv->lcdc_win_num = vop_dev->data->n_wins;
4344         dev_drv->reserved_fb = 0;
4345         spin_lock_init(&vop_dev->reg_lock);
4346         spin_lock_init(&vop_dev->irq_lock);
4347         vop_dev->irq = platform_get_irq(pdev, 0);
4348         if (vop_dev->irq < 0) {
4349                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
4350                         vop_dev->id);
4351                 return -ENXIO;
4352         }
4353
4354         ret = devm_request_irq(dev, vop_dev->irq, vop_isr,
4355                                IRQF_SHARED, dev_name(dev), vop_dev);
4356         if (ret) {
4357                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
4358                         vop_dev->irq, ret);
4359                 return ret;
4360         }
4361         if (dev_drv->iommu_enabled)
4362                 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
4363         ret = rk_fb_register(dev_drv, vop_dev->data->win, vop_dev->id);
4364         if (ret < 0) {
4365                 dev_err(dev, "register fb for lcdc%d failed!\n", vop_dev->id);
4366                 return ret;
4367         }
4368         vop_dev->screen = dev_drv->screen0;
4369         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
4370                  vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
4371
4372         return 0;
4373 }
4374
4375 static int vop_remove(struct platform_device *pdev)
4376 {
4377         return 0;
4378 }
4379
4380 static void vop_shutdown(struct platform_device *pdev)
4381 {
4382         struct vop_device *vop_dev = platform_get_drvdata(pdev);
4383         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
4384
4385         dev_drv->suspend_flag = 1;
4386         /* ensure suspend_flag take effect on multi process */
4387         smp_wmb();
4388         flush_kthread_worker(&dev_drv->update_regs_worker);
4389         kthread_stop(dev_drv->update_regs_thread);
4390         vop_deint(vop_dev);
4391
4392         vop_clk_disable(vop_dev);
4393         rk_disp_pwr_disable(dev_drv);
4394 }
4395
4396 static struct platform_driver vop_driver = {
4397         .probe = vop_probe,
4398         .remove = vop_remove,
4399         .driver = {
4400                    .name = "rk322x-lcdc",
4401                    .owner = THIS_MODULE,
4402                    .of_match_table = of_match_ptr(vop_dt_ids),
4403                    },
4404         .suspend = vop_suspend,
4405         .resume = vop_resume,
4406         .shutdown = vop_shutdown,
4407 };
4408
4409 static int __init vop_module_init(void)
4410 {
4411         return platform_driver_register(&vop_driver);
4412 }
4413
4414 static void __exit vop_module_exit(void)
4415 {
4416         platform_driver_unregister(&vop_driver);
4417 }
4418
4419 fs_initcall(vop_module_init);
4420 module_exit(vop_module_exit);