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