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