video: rockchip: tve: fix compile error and warning
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk_vop_lite.c
1 /*
2  * rockchip VOP(Video Output Processer) hardware driver.
3  *
4  * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
5  * Author: WenLong Zhuang <daisen.zhuang@rock-chips.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/string.h>
22 #include <linux/mm.h>
23 #include <linux/slab.h>
24 #include <linux/device.h>
25 #include <linux/delay.h>
26 #include <linux/init.h>
27 #include <linux/interrupt.h>
28 #include <linux/platform_device.h>
29 #include <linux/clk.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/rockchip-iovmm.h>
32 #include <asm/div64.h>
33 #include <linux/uaccess.h>
34 #include <linux/rockchip/cpu.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
40 #include "rk_vop_lite.h"
41
42 static int dbg_thresd;
43 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
44
45 #define DBG(level, x...) do {                   \
46         if (unlikely(dbg_thresd >= level))      \
47                 pr_info(x);\
48         } while (0)
49
50 #define to_vop_dev(drv) container_of(drv, struct vop_device, driver)
51
52 static struct rk_lcdc_win vop_win[] = {
53         { .name = "win0", .id = 0},
54         { .name = "win1", .id = 1},
55         { .name = "hwc",  .id = 2}
56 };
57
58 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
59
60 static int vop_clk_enable(struct vop_device *vop_dev)
61 {
62         if (!vop_dev->clk_on) {
63                 pm_runtime_get_sync(vop_dev->dev);
64
65                 clk_enable(vop_dev->hclk);
66                 clk_enable(vop_dev->aclk);
67                 clk_enable(vop_dev->dclk);
68                 spin_lock(&vop_dev->reg_lock);
69                 vop_dev->clk_on = 1;
70                 spin_unlock(&vop_dev->reg_lock);
71         }
72
73         return 0;
74 }
75
76 static int vop_clk_disable(struct vop_device *vop_dev)
77 {
78         if (vop_dev->clk_on) {
79                 spin_lock(&vop_dev->reg_lock);
80                 vop_dev->clk_on = 0;
81                 spin_unlock(&vop_dev->reg_lock);
82                 clk_disable(vop_dev->dclk);
83                 clk_disable(vop_dev->aclk);
84                 clk_disable(vop_dev->hclk);
85
86                 pm_runtime_put(vop_dev->dev);
87         }
88
89         return 0;
90 }
91
92 static int vop_irq_enable(struct vop_device *vop_dev)
93 {
94         u64 val;
95
96         spin_lock(&vop_dev->reg_lock);
97         if (likely(vop_dev->clk_on)) {
98                 vop_mask_writel(vop_dev, INTR_CLEAR, INTR_MASK, INTR_MASK);
99
100                 val = INTR_FS0 | INTR_FS1 | INTR_LINE_FLAG0 | INTR_LINE_FLAG1 |
101                         INTR_BUS_ERROR | INTR_WIN0_EMPTY | INTR_WIN1_EMPTY |
102                         INTR_DSP_HOLD_VALID;
103                 vop_mask_writel(vop_dev, INTR_EN, INTR_MASK, val);
104         }
105         spin_unlock(&vop_dev->reg_lock);
106
107         return 0;
108 }
109
110 static int vop_irq_disable(struct vop_device *vop_dev)
111 {
112         spin_lock(&vop_dev->reg_lock);
113         if (likely(vop_dev->clk_on)) {
114                 spin_lock(&vop_dev->reg_lock);
115                 vop_writel(vop_dev, INTR_EN, 0xffff0000);
116                 vop_writel(vop_dev, INTR_CLEAR, 0xffffffff);
117                 vop_cfg_done(vop_dev);
118         }
119         spin_unlock(&vop_dev->reg_lock);
120
121         return 0;
122 }
123
124 static int vop_standby_enable(struct vop_device *vop_dev)
125 {
126         u64 val;
127         int ret;
128
129         spin_lock(&vop_dev->reg_lock);
130         if (likely(vop_dev->clk_on)) {
131                 vop_dev->sync.stdbyfin.done = 0;
132
133                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_BLANK_EN(1));
134                 /*vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);*/
135                 val = V_IMD_VOP_STANDBY_EN(1) | V_IMD_VOP_DMA_STOP(1) |
136                         V_IMD_DSP_OUT_ZERO(1);
137                 vop_msk_reg(vop_dev, SYS_CTRL2, val);
138                 vop_cfg_done(vop_dev);
139                 spin_unlock(&vop_dev->reg_lock);
140
141                 /* wait for standby hold valid */
142                 ret = vop_completion_timeout_ms(&vop_dev->sync.stdbyfin,
143                                                 vop_dev->sync.stdbyfin_to);
144                 if (!ret) {
145                         dev_err(vop_dev->dev,
146                                 "wait standby hold valid timeout %dms\n",
147                                 vop_dev->sync.stdbyfin_to);
148                         return -ETIMEDOUT;
149                 }
150         } else {
151                 spin_unlock(&vop_dev->reg_lock);
152         }
153
154         return 0;
155 }
156
157 static int vop_standby_disable(struct vop_device *vop_dev)
158 {
159         u64 val;
160         int ret;
161
162         spin_lock(&vop_dev->reg_lock);
163         if (likely(vop_dev->clk_on)) {
164                 vop_dev->sync.frmst.done = 0;
165                 val = V_IMD_VOP_STANDBY_EN(0) | V_IMD_VOP_DMA_STOP(0) |
166                         V_IMD_DSP_OUT_ZERO(0);
167                 vop_msk_reg(vop_dev, SYS_CTRL2, val);
168                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_BLANK_EN(0));
169                 vop_cfg_done(vop_dev);
170                 spin_unlock(&vop_dev->reg_lock);
171
172                 /* win address maybe effect after next frame start,
173                  * but mmu maybe effect right now, so need wait frame start
174                  */
175                 ret = vop_completion_timeout_ms(&vop_dev->sync.frmst,
176                                                 vop_dev->sync.frmst_to);
177                 if (!ret) {
178                         dev_err(vop_dev->dev, "wait frame start timeout %dms\n",
179                                 vop_dev->sync.frmst_to);
180                         return -ETIMEDOUT;
181                 }
182         } else {
183                 spin_unlock(&vop_dev->reg_lock);
184         }
185
186         return 0;
187 }
188
189 static int vop_mmu_enable(struct rk_lcdc_driver *dev_drv)
190 {
191         struct vop_device *vop_dev = to_vop_dev(dev_drv);
192
193         if (!dev_drv->iommu_enabled || !dev_drv->mmu_dev) {
194                 pr_debug("%s: VOP iommu is disabled or not find mmu dev\n",
195                          __func__);
196                 return -ENODEV;
197         }
198
199         spin_lock(&vop_dev->reg_lock);
200         if (likely(vop_dev->clk_on)) {
201                 if (!vop_dev->iommu_status) {
202                         vop_dev->iommu_status = 1;
203                         rockchip_iovmm_activate(dev_drv->dev);
204                 }
205         }
206         spin_unlock(&vop_dev->reg_lock);
207
208         return 0;
209 }
210
211 static int vop_mmu_disable(struct rk_lcdc_driver *dev_drv)
212 {
213         struct vop_device *vop_dev = to_vop_dev(dev_drv);
214
215         if (!dev_drv->iommu_enabled || !dev_drv->mmu_dev) {
216                 pr_debug("%s: VOP iommu is disabled or not find mmu dev\n",
217                          __func__);
218                 return -ENODEV;
219         }
220
221         spin_lock(&vop_dev->reg_lock);
222         if (likely(vop_dev->clk_on)) {
223                 if (vop_dev->iommu_status) {
224                         vop_dev->iommu_status = 0;
225                         rockchip_iovmm_deactivate(dev_drv->dev);
226                 }
227         }
228         spin_unlock(&vop_dev->reg_lock);
229
230         return 0;
231 }
232
233 static int vop_reg_dump(struct rk_lcdc_driver *dev_drv)
234 {
235         struct vop_device *vop_dev = to_vop_dev(dev_drv);
236         int *cbase = (int *)vop_dev->regs;
237         int *regsbak = (int *)vop_dev->regsbak;
238         int i, j, val;
239         char dbg_message[30];
240         char buf[10];
241
242         spin_lock(&vop_dev->reg_lock);
243         if (likely(vop_dev->clk_on)) {
244                 pr_info("vop back up reg:\n");
245                 memset(dbg_message, 0, sizeof(dbg_message));
246                 memset(buf, 0, sizeof(buf));
247                 for (i = 0; i <= (0x200 >> 4); i++) {
248                         val = sprintf(dbg_message, "0x%04x: ", i * 16);
249                         for (j = 0; j < 4; j++) {
250                                 val = sprintf(buf, "%08x  ",
251                                               *(regsbak + i * 4 + j));
252                                 strcat(dbg_message, buf);
253                         }
254                         pr_info("%s\n", dbg_message);
255                         memset(dbg_message, 0, sizeof(dbg_message));
256                         memset(buf, 0, sizeof(buf));
257                 }
258
259                 pr_info("vop reg:\n");
260                 for (i = 0; i <= (0x200 >> 4); i++) {
261                         val = sprintf(dbg_message, "0x%04x: ", i * 16);
262                         for (j = 0; j < 4; j++) {
263                                 sprintf(buf, "%08x  ",
264                                         readl_relaxed(cbase + i * 4 + j));
265                                 strcat(dbg_message, buf);
266                         }
267                         pr_info("%s\n", dbg_message);
268                         memset(dbg_message, 0, sizeof(dbg_message));
269                         memset(buf, 0, sizeof(buf));
270                 }
271         }
272         spin_unlock(&vop_dev->reg_lock);
273
274         return 0;
275 }
276
277 #define WIN_EN(id)              \
278 static int win##id##_enable(struct vop_device *vop_dev, int en) \
279 { \
280         spin_lock(&vop_dev->reg_lock);                                  \
281         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN((u64)en)); \
282         vop_cfg_done(vop_dev);                                          \
283         spin_unlock(&vop_dev->reg_lock);                                \
284         return 0;                                                       \
285 }
286
287 WIN_EN(0);
288 WIN_EN(1);
289
290 /*
291  * enable/disable win directly
292  */
293 static int vop_win_direct_en(struct rk_lcdc_driver *drv,
294                              int win_id, int en)
295 {
296         struct vop_device *vop_dev = to_vop_dev(drv);
297
298         if (win_id == 0)
299                 win0_enable(vop_dev, en);
300         else if (win_id == 1)
301                 win1_enable(vop_dev, en);
302         else
303                 dev_err(vop_dev->dev, "invalid win number:%d\n", win_id);
304         return 0;
305 }
306
307 #define SET_WIN_ADDR(id) \
308 static int set_win##id##_addr(struct vop_device *vop_dev, u32 addr) \
309 {                                                       \
310         spin_lock(&vop_dev->reg_lock);                  \
311         vop_writel(vop_dev, WIN##id##_YRGB_MST, addr);  \
312         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN(1));       \
313         vop_cfg_done(vop_dev);                  \
314         spin_unlock(&vop_dev->reg_lock);                \
315         return 0;                                       \
316 }
317
318 SET_WIN_ADDR(0);
319 SET_WIN_ADDR(1);
320
321 static int vop_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
322                                    int win_id, u32 addr)
323 {
324         struct vop_device *vop_dev = to_vop_dev(dev_drv);
325
326         if (win_id == 0)
327                 set_win0_addr(vop_dev, addr);
328         else
329                 set_win1_addr(vop_dev, addr);
330
331         return 0;
332 }
333
334 static void vop_read_reg_default_cfg(struct vop_device *vop_dev)
335 {
336         int reg = 0;
337         u32 val = 0;
338         struct rk_screen *screen = vop_dev->driver.cur_screen;
339         u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
340         u32 V_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
341         u32 st_x, st_y;
342         struct rk_lcdc_win *win0 = vop_dev->driver.win[0];
343
344         spin_lock(&vop_dev->reg_lock);
345         for (reg = 0; reg < vop_dev->len; reg += 4) {
346                 val = vop_readl_backup(vop_dev, reg);
347                 switch (reg) {
348                 case WIN0_ACT_INFO:
349                         win0->area[0].xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
350                         win0->area[0].yact =
351                                 ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
352                         break;
353                 case WIN0_DSP_INFO:
354                         win0->area[0].xsize = (val & MASK(WIN0_DSP_WIDTH)) + 1;
355                         win0->area[0].ysize =
356                             ((val & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
357                         break;
358                 case WIN0_DSP_ST:
359                         st_x = val & MASK(WIN0_DSP_XST);
360                         st_y = (val & MASK(WIN0_DSP_YST)) >> 16;
361                         win0->area[0].xpos = st_x - h_pw_bp;
362                         win0->area[0].ypos = st_y - V_pw_bp;
363                         break;
364                 case WIN0_CTRL0:
365                         win0->state = val & MASK(WIN0_EN);
366                         win0->area[0].fmt_cfg =
367                                         (val & MASK(WIN0_DATA_FMT)) >> 1;
368                         win0->area[0].format = win0->area[0].fmt_cfg;
369                         break;
370                 case WIN0_VIR:
371                         win0->area[0].y_vir_stride =
372                                         val & MASK(WIN0_YRGB_VIR_STRIDE);
373                         win0->area[0].uv_vir_stride =
374                             (val & MASK(WIN0_CBR_VIR_STRIDE)) >> 16;
375                         if (win0->area[0].format == ARGB888)
376                                 win0->area[0].xvir = win0->area[0].y_vir_stride;
377                         else if (win0->area[0].format == RGB888)
378                                 win0->area[0].xvir =
379                                     win0->area[0].y_vir_stride * 4 / 3;
380                         else if (win0->area[0].format == RGB565)
381                                 win0->area[0].xvir =
382                                     2 * win0->area[0].y_vir_stride;
383                         else
384                                 win0->area[0].xvir =
385                                     4 * win0->area[0].y_vir_stride;
386                         break;
387                 case WIN0_YRGB_MST:
388                         win0->area[0].smem_start = val;
389                         break;
390                 case WIN0_CBR_MST:
391                         win0->area[0].cbr_start = val;
392                         break;
393                 default:
394                         break;
395                 }
396         }
397         spin_unlock(&vop_dev->reg_lock);
398 }
399
400 static int vop_pre_init(struct rk_lcdc_driver *dev_drv)
401 {
402         struct vop_device *vop_dev = to_vop_dev(dev_drv);
403
404         if (vop_dev->pre_init)
405                 return 0;
406
407         if (dev_drv->iommu_enabled) {
408                 dev_drv->mmu_dev = rk_fb_get_sysmmu_device_by_compatible(
409                                                         dev_drv->mmu_dts_name);
410                 if (dev_drv->mmu_dev)
411                         rk_fb_platform_set_sysmmu(
412                                 dev_drv->mmu_dev, dev_drv->dev);
413                 else
414                         dev_err(dev_drv->dev, "fail get rk iommu device\n");
415         }
416
417         if (!support_uboot_display())
418                 rk_disp_pwr_enable(dev_drv);
419
420         vop_clk_enable(vop_dev);
421
422         /* backup reg config at uboot */
423         vop_read_reg_default_cfg(vop_dev);
424
425         /* vop io voltage select-->0: 3.3v; 1: 1.8v */
426         if (vop_dev->pwr18 == 1)
427                 vop_grf_writel(vop_dev->grf_base, GRF_IO_VSEL,
428                                V_VOP_IOVOL_SEL(1));
429         else
430                 vop_grf_writel(vop_dev->grf_base, GRF_IO_VSEL,
431                                V_VOP_IOVOL_SEL(0));
432
433         vop_msk_reg(vop_dev, SYS_CTRL1, V_SW_AXI_MAX_OUTSTAND_EN(1) |
434                     V_SW_AXI_MAX_OUTSTAND_NUM(31));
435         vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_AUTO_GATING_EN(0));
436         vop_cfg_done(vop_dev);
437         vop_dev->pre_init = true;
438
439         return 0;
440 }
441
442 static void vop_deinit(struct vop_device *vop_dev)
443 {
444         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
445
446         vop_standby_enable(vop_dev);
447         vop_irq_disable(vop_dev);
448         vop_mmu_disable(dev_drv);
449         vop_clk_disable(vop_dev);
450         clk_unprepare(vop_dev->dclk);
451         clk_unprepare(vop_dev->aclk);
452         clk_unprepare(vop_dev->hclk);
453         pm_runtime_disable(vop_dev->dev);
454 }
455
456 static void __maybe_unused
457 vop_win_csc_mode(struct vop_device *vop_dev, struct rk_lcdc_win *win,
458                  int csc_mode)
459 {
460         u64 val;
461
462         spin_lock(&vop_dev->reg_lock);
463         if (likely(vop_dev->clk_on)) {
464                 if (win->id == 0) {
465                         val = V_WIN0_CSC_MODE(csc_mode);
466                         vop_msk_reg(vop_dev, WIN0_CTRL0, val);
467                 } else if (win->id == 1) {
468                         val = V_WIN1_CSC_MODE(csc_mode);
469                         vop_msk_reg(vop_dev, WIN1_CTRL0, val);
470                 } else {
471                         dev_err(vop_dev->dev, "%s win%d unsupport csc mode",
472                                 __func__, win->id);
473                 }
474         }
475         spin_unlock(&vop_dev->reg_lock);
476 }
477
478 static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
479 {
480         struct vop_device *vop_dev = to_vop_dev(dev_drv);
481         struct rk_lcdc_win *win;
482         int i;
483
484         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
485                 win = dev_drv->win[i];
486                 switch (i) {
487                 case 0:
488                         vop_writel(vop_dev, WIN0_COLOR_KEY, win->color_key_val);
489                         break;
490                 case 1:
491                         vop_writel(vop_dev, WIN1_COLOR_KEY, win->color_key_val);
492                         break;
493                 default:
494                         pr_info("%s:un support win num:%d\n",
495                                 __func__, i);
496                         break;
497                 }
498         }
499         return 0;
500 }
501
502 static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
503 {
504         struct vop_device *vop_dev = to_vop_dev(dev_drv);
505         struct rk_lcdc_win *win = dev_drv->win[win_id];
506         u64 val;
507         int ppixel_alpha = 0;
508         int alpha_en = win->alpha_en;
509         int i;
510
511         if (!alpha_en) {
512                 if (win_id == 0) {
513                         val = V_WIN0_ALPHA_EN(0);
514                         vop_msk_reg(vop_dev, WIN0_ALPHA_CTRL, val);
515                 } else {
516                         val = V_WIN1_ALPHA_EN(0);
517                         vop_msk_reg(vop_dev, WIN1_ALPHA_CTRL, val);
518                 }
519                 return 0;
520         }
521
522         ppixel_alpha = ((win->area[0].format == ARGB888) ||
523                         (win->area[0].format == ABGR888)) ? 1 : 0;
524
525         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
526                 if (!dev_drv->win[i]->state)
527                         continue;
528                 if (win->z_order > dev_drv->win[i]->z_order)
529                         break;
530         }
531
532         /*
533          * The bottom layer not support ppixel_alpha mode.
534          */
535         if (i == dev_drv->lcdc_win_num) {
536                 ppixel_alpha = 0;
537                 alpha_en = 0;
538         }
539
540         if (win_id == 0) {
541                 val = V_WIN0_ALPHA_EN(alpha_en) |
542                         V_WIN0_ALPHA_MODE(ppixel_alpha) |
543                         V_WIN0_ALPHA_PRE_MUL(ppixel_alpha) |
544                         V_WIN0_ALPHA_SAT_MODE(0);
545                 vop_msk_reg(vop_dev, WIN0_ALPHA_CTRL, val);
546         } else if (win_id == 1) {
547                 val = V_WIN1_ALPHA_EN(alpha_en) |
548                         V_WIN1_ALPHA_MODE(ppixel_alpha) |
549                         V_WIN1_ALPHA_PRE_MUL(ppixel_alpha) |
550                         V_WIN1_ALPHA_SAT_MODE(0);
551                 vop_msk_reg(vop_dev, WIN1_ALPHA_CTRL, val);
552         } else {
553                 dev_err(vop_dev->dev, "%s: invalid win id=%d or unsupport\n",
554                         __func__, win_id);
555         }
556
557         return 0;
558 }
559
560 static int vop_axi_gather_cfg(struct vop_device *vop_dev,
561                               struct rk_lcdc_win *win)
562 {
563         u64 val;
564         u16 yrgb_gather_num = 3;
565         u16 cbcr_gather_num = 1;
566
567         switch (win->area[0].format) {
568         case ARGB888:
569         case XBGR888:
570         case ABGR888:
571                 yrgb_gather_num = 3;
572                 break;
573         case RGB888:
574         case RGB565:
575                 yrgb_gather_num = 2;
576                 break;
577         case YUV444:
578         case YUV422:
579         case YUV420:
580         case YUV420_A:
581         case YUV422_A:
582         case YUV444_A:
583         case YUV420_NV21:
584                 yrgb_gather_num = 1;
585                 cbcr_gather_num = 2;
586                 break;
587         default:
588                 dev_err(vop_dev->driver.dev, "%s:un supported format[%d]\n",
589                         __func__, win->area[0].format);
590                 return -EINVAL;
591         }
592
593         if (win->id == 0) {
594                 val = V_WIN0_YRGB_AXI_GATHER_EN(1) |
595                         V_WIN0_CBR_AXI_GATHER_EN(1) |
596                         V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) |
597                         V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num);
598                 vop_msk_reg(vop_dev, WIN0_CTRL1, val);
599         } else if (win->id == 1) {
600                 val = V_WIN1_AXI_GATHER_EN(1) |
601                         V_WIN1_AXI_GATHER_NUM(yrgb_gather_num);
602                 vop_msk_reg(vop_dev, WIN1_CTRL1, val);
603         }
604         return 0;
605 }
606
607 static int vop_win0_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
608 {
609         struct vop_device *vop_dev = to_vop_dev(dev_drv);
610         struct rk_lcdc_win *win = dev_drv->win[win_id];
611         u64 val;
612
613         if (win->state == 1) {
614                 vop_axi_gather_cfg(vop_dev, win);
615                 val = V_WIN0_EN(win->state) |
616                         V_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
617                         V_WIN0_RB_SWAP(win->area[0].swap_rb) |
618                         V_WIN0_UV_SWAP(win->area[0].swap_uv);
619                 if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED)
620                         val |= V_WIN0_INTERLACE_READ(1);
621                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
622
623                 val = V_WIN0_YRGB_VIR_STRIDE(win->area[0].y_vir_stride) |
624                     V_WIN0_CBR_VIR_STRIDE(win->area[0].uv_vir_stride);
625                 vop_writel(vop_dev, WIN0_VIR, val);
626
627                 val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) |
628                     V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1);
629                 vop_writel(vop_dev, WIN0_DSP_INFO, val);
630
631                 val = V_WIN0_DSP_XST(win->area[0].dsp_stx) |
632                     V_WIN0_DSP_YST(win->area[0].dsp_sty);
633                 vop_writel(vop_dev, WIN0_DSP_ST, val);
634
635                 /* only win0 support scale and yuv */
636                 val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) |
637                         V_WIN0_ACT_HEIGHT(win->area[0].yact - 1);
638                 vop_writel(vop_dev, WIN0_ACT_INFO, val);
639
640                 val = V_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
641                         V_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
642                 vop_writel(vop_dev, WIN0_SCL_FACTOR_YRGB, val);
643
644                 val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
645                         V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
646                 vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR, val);
647
648                 if (win->area[0].y_addr > 0)
649                         vop_writel(vop_dev, WIN0_YRGB_MST, win->area[0].y_addr);
650                 if (win->area[0].uv_addr > 0)
651                         vop_writel(vop_dev, WIN0_CBR_MST, win->area[0].uv_addr);
652
653                 vop_alpha_cfg(dev_drv, win_id);
654         } else {
655                 val = V_WIN0_EN(win->state);
656                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
657         }
658
659         return 0;
660 }
661
662 static int vop_win1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
663 {
664         struct vop_device *vop_dev = to_vop_dev(dev_drv);
665         struct rk_lcdc_win *win = dev_drv->win[win_id];
666         u64 val;
667
668         if (win->state == 1) {
669                 vop_axi_gather_cfg(vop_dev, win);
670                 val = V_WIN1_EN(win->state) |
671                         V_WIN1_DATA_FMT(win->area[0].fmt_cfg) |
672                         V_WIN1_RB_SWAP(win->area[0].swap_rb);
673                 if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED)
674                         val |= V_WIN1_INTERLACE_READ(1);
675                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
676
677                 val = V_WIN1_VIR_STRIDE(win->area[0].y_vir_stride);
678                 vop_writel(vop_dev, WIN1_VIR, val);
679
680                 val = V_WIN1_DSP_WIDTH(win->area[0].xsize - 1) |
681                     V_WIN1_DSP_HEIGHT(win->area[0].ysize - 1);
682                 vop_writel(vop_dev, WIN1_DSP_INFO, val);
683
684                 val = V_WIN1_DSP_XST(win->area[0].dsp_stx) |
685                     V_WIN1_DSP_YST(win->area[0].dsp_sty);
686                 vop_writel(vop_dev, WIN1_DSP_ST, val);
687
688                 if (win->area[0].y_addr > 0)
689                         vop_writel(vop_dev, WIN1_YRGB_MST, win->area[0].y_addr);
690
691                 vop_alpha_cfg(dev_drv, win_id);
692         } else {
693                 val = V_WIN1_EN(win->state);
694                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
695         }
696
697         return 0;
698 }
699
700 static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
701 {
702         struct vop_device *vop_dev = to_vop_dev(dev_drv);
703         struct rk_lcdc_win *win = dev_drv->win[win_id];
704         unsigned int hwc_size = 0;
705         u64 val;
706
707         if (win->state == 1) {
708                 vop_axi_gather_cfg(vop_dev, win);
709
710                 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
711                         hwc_size = 0;
712                 else if ((win->area[0].xsize == 64) &&
713                          (win->area[0].ysize == 64))
714                         hwc_size = 1;
715                 else
716                         dev_err(vop_dev->dev, "unsupported hwc size[%dx%d]!\n",
717                                 win->area[0].xsize, win->area[0].ysize);
718
719                 val = V_HWC_EN(1) | V_HWC_SIZE(hwc_size);
720                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
721
722                 val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
723                     V_HWC_DSP_YST(win->area[0].dsp_sty);
724                 vop_msk_reg(vop_dev, HWC_DSP_ST, val);
725
726                 if (win->area[0].y_addr > 0)
727                         vop_writel(vop_dev, HWC_MST, win->area[0].y_addr);
728         } else {
729                 val = V_HWC_EN(win->state);
730                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
731         }
732
733         return 0;
734 }
735
736 static int vop_layer_update_regs(struct vop_device *vop_dev,
737                                  struct rk_lcdc_win *win)
738 {
739         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
740
741         vop_msk_reg(vop_dev, SYS_CTRL2,
742                     V_IMD_VOP_STANDBY_EN(vop_dev->standby));
743         if (win->id == 0)
744                 vop_win0_reg_update(dev_drv, win->id);
745         else if (win->id == 1)
746                 vop_win1_reg_update(dev_drv, win->id);
747         else if (win->id == 2)
748                 vop_hwc_reg_update(dev_drv, win->id);
749         vop_cfg_done(vop_dev);
750
751         DBG(2, "%s for vop%d\n", __func__, vop_dev->id);
752         return 0;
753 }
754
755 static int vop_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
756                            int *hwc_lut, int mode)
757 {
758         int i = 0;
759         int __iomem *c;
760         int v;
761         int len = 256 * sizeof(u32);
762         struct vop_device *vop_dev = to_vop_dev(dev_drv);
763
764         if (!dev_drv->hwc_lut)
765                 dev_drv->hwc_lut = devm_kzalloc(vop_dev->dev, len, GFP_KERNEL);
766
767         spin_lock(&vop_dev->reg_lock);
768         if (likely(vop_dev->clk_on)) {
769                 vop_msk_reg(vop_dev, HWC_CTRL0, V_HWC_LUT_EN(0));
770                 vop_cfg_done(vop_dev);
771                 mdelay(25);
772                 for (i = 0; i < 256; i++) {
773                         if (mode == 1)
774                                 dev_drv->hwc_lut[i] = hwc_lut[i];
775
776                         v = dev_drv->hwc_lut[i];
777                         c = vop_dev->hwc_lut_addr_base + i;
778                         writel_relaxed(v, c);
779                 }
780                 vop_msk_reg(vop_dev, HWC_CTRL0, V_HWC_LUT_EN(1));
781                 vop_cfg_done(vop_dev);
782         }
783         spin_unlock(&vop_dev->reg_lock);
784
785         return 0;
786 }
787
788 static int vop_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
789 {
790         int i = 0;
791         int __iomem *c;
792         int v;
793         struct vop_device *vop_dev = to_vop_dev(dev_drv);
794
795         if (!dsp_lut)
796                 return 0;
797
798         spin_lock(&vop_dev->reg_lock);
799         if (likely(vop_dev->clk_on)) {
800                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_LUT_EN(0));
801                 vop_cfg_done(vop_dev);
802                 mdelay(25);
803                 for (i = 0; i < 256; i++) {
804                         v = dsp_lut[i];
805                         c = vop_dev->dsp_lut_addr_base + i;
806                         writel_relaxed(v, c);
807                 }
808                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_LUT_EN(1));
809                 vop_cfg_done(vop_dev);
810         }
811         spin_unlock(&vop_dev->reg_lock);
812
813         return 0;
814 }
815
816 static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
817 {
818         int ret = 0, fps = 0;
819         struct vop_device *vop_dev = to_vop_dev(dev_drv);
820         struct rk_screen *screen = dev_drv->cur_screen;
821
822         if (reset_rate)
823                 ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock);
824         if (ret)
825                 dev_err(dev_drv->dev, "set lcdc%d dclk[%d] failed\n",
826                         vop_dev->id, screen->mode.pixclock);
827         vop_dev->pixclock =
828             div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
829         vop_dev->driver.pixclock = vop_dev->pixclock;
830
831         fps = rk_fb_calc_fps(screen, vop_dev->pixclock);
832         screen->ft = 1000 / fps;
833         dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ",
834                  vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps);
835         return 0;
836 }
837
838 static int vop_config_timing(struct rk_lcdc_driver *dev_drv)
839 {
840         struct vop_device *vop_dev = to_vop_dev(dev_drv);
841         struct rk_screen *screen = dev_drv->cur_screen;
842         u16 hsync_len = screen->mode.hsync_len;
843         u16 left_margin = screen->mode.left_margin;
844         u16 right_margin = screen->mode.right_margin;
845         u16 vsync_len = screen->mode.vsync_len;
846         u16 upper_margin = screen->mode.upper_margin;
847         u16 lower_margin = screen->mode.lower_margin;
848         u16 x_res = screen->mode.xres;
849         u16 y_res = screen->mode.yres;
850         u64 val;
851         u16 h_total, v_total;
852         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
853
854         /* config timing reg valid immediately or after frame start */
855         if (screen->mode.vmode & FB_VMODE_INTERLACED) /* after frame start */
856                 vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_DSP_TIMING_IMD(1));
857         else /* timing reg valid immediately */
858                 vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_DSP_TIMING_IMD(0));
859
860         h_total = hsync_len + left_margin + x_res + right_margin;
861         v_total = vsync_len + upper_margin + y_res + lower_margin;
862
863         val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total);
864         vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val);
865
866         val = V_DSP_HACT_END(hsync_len + left_margin + x_res) |
867             V_DSP_HACT_ST(hsync_len + left_margin);
868         vop_msk_reg(vop_dev, DSP_HACT_ST_END, val);
869
870         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
871                 /* First Field Timing */
872                 val = V_DSP_VS_END(vsync_len) |
873                     V_DSP_VTOTAL(2 * (vsync_len + upper_margin +
874                                       lower_margin) + y_res + 1);
875                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
876
877                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
878                     V_DSP_VACT_ST(vsync_len + upper_margin);
879                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
880
881                 /* Second Field Timing */
882                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
883                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
884                     lower_margin;
885                 val = V_DSP_VS_ST_F1(vs_st_f1) | V_DSP_VS_END_F1(vs_end_f1);
886                 vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val);
887
888                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
889                     lower_margin + 1;
890                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
891                     lower_margin + 1;
892                 val = V_DSP_VACT_END_F1(vact_end_f1) |
893                         V_DSP_VACT_ST_F1(vact_st_f1);
894                 vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val);
895
896                 val = V_DSP_LINE_FLAG0_NUM(lower_margin ?
897                                            vact_end_f1 : vact_end_f1 - 1);
898
899                 val |= V_DSP_LINE_FLAG1_NUM(lower_margin ?
900                                             vact_end_f1 : vact_end_f1 - 1);
901                 vop_msk_reg(vop_dev, LINE_FLAG, val);
902         } else {
903                 val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total);
904                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
905
906                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) |
907                     V_DSP_VACT_ST(vsync_len + upper_margin);
908                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
909
910                 val = V_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res) |
911                         V_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res);
912                 vop_msk_reg(vop_dev, LINE_FLAG, val);
913         }
914
915         return 0;
916 }
917
918 static int vop_config_source(struct rk_lcdc_driver *dev_drv)
919 {
920         struct vop_device *vop_dev = to_vop_dev(dev_drv);
921         struct rk_screen *screen = dev_drv->cur_screen;
922         u64 val = 0;
923
924         switch (screen->type) {
925         case SCREEN_RGB:
926                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON5,
927                                V_RGB_VOP_SEL(dev_drv->id));
928                 val = V_RGB_DCLK_EN(1) | V_RGB_DCLK_POL(screen->pin_dclk) |
929                         V_RGB_HSYNC_POL(screen->pin_hsync) |
930                         V_RGB_VSYNC_POL(screen->pin_vsync) |
931                         V_RGB_DEN_POL(screen->pin_den);
932                 break;
933         case SCREEN_HDMI:
934                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
935                                V_HDMI_VOP_SEL(dev_drv->id));
936                 val = V_HDMI_DCLK_EN(1) | V_HDMI_DCLK_POL(screen->pin_dclk) |
937                         V_HDMI_HSYNC_POL(screen->pin_hsync) |
938                         V_HDMI_VSYNC_POL(screen->pin_vsync) |
939                         V_HDMI_DEN_POL(screen->pin_den);
940                 break;
941         case SCREEN_LVDS:
942                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
943                                V_LVDS_VOP_SEL(dev_drv->id));
944                 val = V_LVDS_DCLK_EN(1) | V_LVDS_DCLK_POL(screen->pin_dclk) |
945                         V_LVDS_HSYNC_POL(screen->pin_hsync) |
946                         V_LVDS_VSYNC_POL(screen->pin_vsync) |
947                         V_LVDS_DEN_POL(screen->pin_den);
948                 break;
949         case SCREEN_MIPI:
950                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
951                                V_DSI0_VOP_SEL(dev_drv->id));
952                 val = V_MIPI_DCLK_EN(1) | V_MIPI_DCLK_POL(screen->pin_dclk) |
953                         V_MIPI_HSYNC_POL(screen->pin_hsync) |
954                         V_MIPI_VSYNC_POL(screen->pin_vsync) |
955                         V_MIPI_DEN_POL(screen->pin_den);
956                 break;
957         default:
958                 dev_err(vop_dev->dev, "un supported interface[%d]!\n",
959                         screen->type);
960                 break;
961         }
962
963         val |= V_SW_CORE_CLK_SEL(!!screen->pixelrepeat);
964         if (screen->mode.vmode & FB_VMODE_INTERLACED)
965                 val |= V_SW_HDMI_CLK_I_SEL(1);
966         else
967                 val |= V_SW_HDMI_CLK_I_SEL(0);
968         vop_msk_reg(vop_dev, DSP_CTRL0, val);
969
970         return 0;
971 }
972
973 static int vop_config_interface(struct rk_lcdc_driver *dev_drv)
974 {
975         struct vop_device *vop_dev = to_vop_dev(dev_drv);
976         struct rk_screen *screen = dev_drv->cur_screen;
977         u64 val = 0;
978
979         /* FRC dither down init */
980         if (screen->face != OUT_P888) {
981                 vop_writel(vop_dev, FRC_LOWER01_0, 0x12844821);
982                 vop_writel(vop_dev, FRC_LOWER01_1, 0x21488412);
983                 vop_writel(vop_dev, FRC_LOWER10_0, 0xa55a9696);
984                 vop_writel(vop_dev, FRC_LOWER10_1, 0x5aa56969);
985                 vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb);
986                 vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de);
987         }
988
989         switch (screen->face) {
990         case OUT_P888:
991                 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(0);
992                 break;
993         case OUT_P565:
994                 val = V_DSP_OUT_MODE(OUT_P565) | V_DITHER_DOWN(1) |
995                         V_DITHER_DOWN_MODE(DITHER_888_565) |
996                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
997                 break;
998         case OUT_P666:
999                 val = V_DSP_OUT_MODE(OUT_P666) | V_DITHER_DOWN(1) |
1000                         V_DITHER_DOWN_MODE(DITHER_888_666) |
1001                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1002                 break;
1003         case OUT_D888_P565:
1004                 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(1) |
1005                         V_DITHER_DOWN_MODE(DITHER_888_565) |
1006                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1007                 break;
1008         case OUT_D888_P666:
1009                 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(1) |
1010                         V_DITHER_DOWN_MODE(DITHER_888_666) |
1011                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1012                 break;
1013         default:
1014                 dev_err(vop_dev->dev, "un supported screen face[%d]!\n",
1015                         screen->face);
1016                 break;
1017         }
1018
1019         if (screen->mode.vmode & FB_VMODE_INTERLACED)
1020                 val |= V_DSP_INTERLACE(1) | V_INTERLACE_FIELD_POL(0);
1021
1022         dev_drv->output_color = screen->color_mode;
1023         if (screen->color_mode == COLOR_RGB)
1024                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1025         else
1026                 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1027
1028         val |= V_SW_OVERLAY_MODE(dev_drv->overlay_mode) |
1029                 V_DSP_BG_SWAP(screen->swap_gb) |
1030                 V_DSP_RB_SWAP(screen->swap_rb) |
1031                 V_DSP_RG_SWAP(screen->swap_rg) |
1032                 V_DSP_DELTA_SWAP(screen->swap_delta) |
1033                 V_DSP_DUMMY_SWAP(screen->swap_dumy) |
1034                 V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0);
1035         vop_msk_reg(vop_dev, DSP_CTRL2, val);
1036
1037         return 0;
1038 }
1039
1040 static void vop_config_background(struct rk_lcdc_driver *dev_drv, int rgb)
1041 {
1042         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1043         u64 val;
1044         int b = rgb & 0xff;
1045         int g = (rgb >> 8) & 0xff;
1046         int r = (rgb >> 16) & 0xff;
1047
1048         val = V_DSP_BG_BLUE(b) | V_DSP_BG_GREEN(g) | V_DSP_BG_RED(r);
1049         vop_msk_reg(vop_dev, DSP_BG, val);
1050 }
1051
1052 static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1053 {
1054         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1055
1056         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1057                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1058                         vop_msk_reg(vop_dev, BCSH_CTRL,
1059                                     V_SW_BCSH_Y2R_EN(0) | V_SW_BCSH_R2Y_EN(0));
1060                 else            /* YUV2RGB */
1061                         vop_msk_reg(vop_dev, BCSH_CTRL, V_SW_BCSH_Y2R_EN(1) |
1062                                     V_SW_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1063                                     V_SW_BCSH_R2Y_EN(0));
1064         } else {
1065                 /* overlay_mode=VOP_RGB_DOMAIN */
1066                 /* bypass  --need check,if bcsh close? */
1067                 if (dev_drv->output_color == COLOR_RGB) {
1068                         if (dev_drv->bcsh.enable == 1)
1069                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1070                                             V_SW_BCSH_R2Y_EN(1) |
1071                                             V_SW_BCSH_Y2R_EN(1));
1072                         else
1073                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1074                                             V_SW_BCSH_R2Y_EN(0) |
1075                                             V_SW_BCSH_Y2R_EN(0));
1076                 } else {
1077                         /* RGB2YUV */
1078                         vop_msk_reg(vop_dev, BCSH_CTRL,
1079                                     V_SW_BCSH_R2Y_EN(1) |
1080                                     V_SW_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1081                                     V_SW_BCSH_Y2R_EN(0));
1082                 }
1083         }
1084 }
1085
1086 static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1087                                u16 *yact, int *format, u32 *dsp_addr,
1088                                int *ymirror)
1089 {
1090         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1091         u32 val;
1092
1093         spin_lock(&vop_dev->reg_lock);
1094         if (likely(vop_dev->clk_on)) {
1095                 val = vop_readl(vop_dev, WIN0_ACT_INFO);
1096                 *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
1097                 *yact = ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1098
1099                 val = vop_readl(vop_dev, WIN0_CTRL0);
1100                 *format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1101                 *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST);
1102         }
1103         spin_unlock(&vop_dev->reg_lock);
1104
1105         return 0;
1106 }
1107
1108 static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1109                            int format, u16 xact, u16 yact, u16 xvir,
1110                            int ymirror)
1111 {
1112         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1113         int swap = (format == RGB888) ? 1 : 0;
1114         u64 val;
1115
1116         spin_lock(&vop_dev->reg_lock);
1117         if (likely(vop_dev->clk_on)) {
1118                 val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap);
1119                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
1120
1121                 vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_YRGB_VIR_STRIDE(xvir));
1122                 vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) |
1123                            V_WIN0_ACT_HEIGHT(yact - 1));
1124
1125                 vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst);
1126
1127                 vop_cfg_done(vop_dev);
1128         }
1129         spin_unlock(&vop_dev->reg_lock);
1130
1131         return 0;
1132 }
1133
1134 static void vop_reg_restore(struct rk_lcdc_driver *dev_drv)
1135 {
1136         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1137         int len = FLAG_REG;
1138
1139         spin_lock(&vop_dev->reg_lock);
1140
1141         if (likely(vop_dev->clk_on))
1142                 memcpy(vop_dev->regs, vop_dev->regsbak, len);
1143
1144         spin_unlock(&vop_dev->reg_lock);
1145
1146         /* set screen GAMMA lut */
1147         if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1148                 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
1149
1150         /* set hwc lut */
1151         vop_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1152 }
1153
1154 static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1155 {
1156         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1157         struct rk_screen *screen = dev_drv->cur_screen;
1158
1159         /*if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1))*/
1160         /*      flush_kthread_worker(&dev_drv->update_regs_worker);*/
1161
1162         spin_lock(&vop_dev->reg_lock);
1163         if (likely(vop_dev->clk_on)) {
1164                 vop_config_interface(dev_drv);
1165                 vop_config_source(dev_drv);
1166                 vop_config_timing(dev_drv);
1167                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN)
1168                         vop_config_background(dev_drv, 0x801080);
1169                 else
1170                         vop_config_background(dev_drv, 0x000000);
1171
1172                 vop_bcsh_path_sel(dev_drv);
1173                 vop_cfg_done(vop_dev);
1174         }
1175         spin_unlock(&vop_dev->reg_lock);
1176
1177         vop_set_dclk(dev_drv, 1);
1178         if (screen->init)
1179                 screen->init();
1180
1181         return 0;
1182 }
1183
1184 /*
1185  * enable or disable layer according to win id
1186  * @open: 1 enable; 0 disable
1187  */
1188 static void vop_layer_enable(struct vop_device *vop_dev,
1189                              unsigned int win_id, bool open)
1190 {
1191         spin_lock(&vop_dev->reg_lock);
1192         if (likely(vop_dev->clk_on) &&
1193             vop_dev->driver.win[win_id]->state != open) {
1194                 if (open) {
1195                         if (!vop_dev->atv_layer_cnt) {
1196                                 dev_info(vop_dev->dev,
1197                                          "wakeup from standby!\n");
1198                                 vop_dev->standby = 0;
1199                         }
1200                         vop_dev->atv_layer_cnt |= (1 << win_id);
1201                 } else {
1202                         if (vop_dev->atv_layer_cnt & (1 << win_id))
1203                                 vop_dev->atv_layer_cnt &= ~(1 << win_id);
1204                 }
1205                 vop_dev->driver.win[win_id]->state = open;
1206                 if (!open) {
1207                         vop_layer_update_regs(vop_dev,
1208                                               vop_dev->driver.win[win_id]);
1209                         vop_cfg_done(vop_dev);
1210                 }
1211                 /* if no layer used,disable lcdc */
1212                 if (!vop_dev->atv_layer_cnt) {
1213                         dev_info(vop_dev->dev,
1214                                  "no layer is used,go to standby!\n");
1215                         vop_dev->standby = 1;
1216                 }
1217         }
1218         spin_unlock(&vop_dev->reg_lock);
1219 }
1220
1221 static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id,
1222                     bool open)
1223 {
1224         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1225
1226         /* enable clk,when first layer open */
1227         if ((open) && (!vop_dev->atv_layer_cnt)) {
1228                 /* rockchip_set_system_status(sys_status); */
1229                 vop_pre_init(dev_drv);
1230                 vop_clk_enable(vop_dev);
1231                 vop_irq_enable(vop_dev);
1232
1233                 if (support_uboot_display() && (vop_dev->prop == PRMRY)) {
1234                         vop_set_dclk(dev_drv, 0);
1235                 } else {
1236                         vop_load_screen(dev_drv, 1);
1237                         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1238                                 dev_drv->trsm_ops->enable();
1239                 }
1240                 if (dev_drv->bcsh.enable)
1241                         vop_set_bcsh(dev_drv, 1);
1242
1243                 /* set screen GAMMA lut */
1244                 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1245                         vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
1246         }
1247
1248         if (win_id < ARRAY_SIZE(vop_win))
1249                 vop_layer_enable(vop_dev, win_id, open);
1250         else
1251                 dev_err(vop_dev->dev, "invalid win id:%d\n", win_id);
1252
1253         dev_drv->first_frame = 0;
1254         return 0;
1255 }
1256
1257 static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1258 {
1259         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1260         struct rk_lcdc_win *win = NULL;
1261         struct rk_screen *screen = dev_drv->cur_screen;
1262
1263         if (!screen) {
1264                 dev_err(dev_drv->dev, "screen is null!\n");
1265                 return -ENOENT;
1266         }
1267
1268         if (win_id >= dev_drv->lcdc_win_num) {
1269                 dev_err(dev_drv->dev, "invalid win id:%d!\n", win_id);
1270                 return -EINVAL;
1271         }
1272
1273         win = dev_drv->win[win_id];
1274         win->area[0].y_addr = win->area[0].smem_start + win->area[0].y_offset;
1275         /* only win0 support yuv format */
1276         if (win_id == 0)
1277                 win->area[0].uv_addr =
1278                         win->area[0].cbr_start + win->area[0].c_offset;
1279         else
1280                 win->area[0].uv_addr = 0;
1281
1282         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
1283             vop_dev->id, win->id, win->area[0].y_addr, win->area[0].uv_addr);
1284         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
1285             win->area[0].y_offset, win->area[0].c_offset);
1286         return 0;
1287 }
1288
1289 static int win_0_1_set_par(struct vop_device *vop_dev,
1290                            struct rk_screen *screen, struct rk_lcdc_win *win)
1291 {
1292         char fmt[9] = "NULL";
1293
1294         win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1295                                 screen->mode.hsync_len;
1296         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1297                 win->area[0].ysize /= 2;
1298                 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1299                         screen->mode.upper_margin + screen->mode.vsync_len;
1300         } else {
1301                 win->area[0].dsp_sty = win->area[0].ypos +
1302                         screen->mode.upper_margin + screen->mode.vsync_len;
1303         }
1304
1305         win->scale_yrgb_x = CALSCALE(win->area[0].xact, win->area[0].xsize);
1306         win->scale_yrgb_y = CALSCALE(win->area[0].yact, win->area[0].ysize);
1307
1308         switch (win->area[0].format) {
1309         case ARGB888:
1310                 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1311                 win->area[0].swap_rb = 0;
1312                 break;
1313         case XBGR888:
1314         case ABGR888:
1315                 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1316                 win->area[0].swap_rb = 1;
1317                 break;
1318         case RGB888:
1319                 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1320                 win->area[0].swap_rb = 0;
1321                 break;
1322         case RGB565:
1323                 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1324                 win->area[0].swap_rb = 0;
1325                 break;
1326         case YUV422:
1327                 if (win->id == 0) {
1328                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
1329                         win->area[0].swap_rb = 0;
1330                         win->area[0].swap_uv = 0;
1331                         win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1332                                                      win->area[0].xsize);
1333                         win->scale_cbcr_y = CALSCALE(win->area[0].yact,
1334                                                      win->area[0].ysize);
1335                 } else {
1336                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1337                                 __func__, win->id);
1338                 }
1339                 break;
1340         case YUV420:
1341                 if (win->id == 0) {
1342                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1343                         win->area[0].swap_rb = 0;
1344                         win->area[0].swap_uv = 0;
1345                         win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1346                                                      win->area[0].xsize);
1347                         win->scale_cbcr_y = CALSCALE(win->area[0].yact / 2,
1348                                                      win->area[0].ysize);
1349                 } else {
1350                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1351                                 __func__, win->id);
1352                 }
1353
1354                 break;
1355         case YUV420_NV21:
1356                 if (win->id == 0) {
1357                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1358                         win->area[0].swap_rb = 0;
1359                         win->area[0].swap_uv = 1;
1360                         win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1361                                                      win->area[0].xsize);
1362                         win->scale_cbcr_y = CALSCALE(win->area[0].yact / 2,
1363                                                      win->area[0].ysize);
1364                 } else {
1365                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1366                                 __func__, win->id);
1367                 }
1368                 break;
1369         case YUV444:
1370                 if (win->id == 0) {
1371                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
1372                         win->area[0].swap_rb = 0;
1373                         win->area[0].swap_uv = 0;
1374                         win->scale_cbcr_x =
1375                                 CALSCALE(win->area[0].xact, win->area[0].xsize);
1376                         win->scale_cbcr_y =
1377                                 CALSCALE(win->area[0].yact, win->area[0].ysize);
1378                 } else {
1379                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1380                                 __func__, win->id);
1381                 }
1382                 break;
1383         default:
1384                 dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n",
1385                         __func__, win->area[0].format);
1386                 break;
1387         }
1388
1389         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
1390             vop_dev->id, win->id, get_format_string(win->area[0].format, fmt),
1391             win->area[0].xact, win->area[0].yact, win->area[0].xsize);
1392         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
1393             win->area[0].ysize, win->area[0].xvir, win->area[0].yvir,
1394             win->area[0].xpos, win->area[0].ypos);
1395
1396         return 0;
1397 }
1398
1399 static int hwc_set_par(struct vop_device *vop_dev,
1400                        struct rk_screen *screen, struct rk_lcdc_win *win)
1401 {
1402         win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1403                                 screen->mode.hsync_len;
1404         win->area[0].dsp_sty = win->area[0].ypos + screen->mode.upper_margin +
1405                                 screen->mode.vsync_len;
1406
1407         DBG(1, "lcdc[%d]:hwc>>%s\n>>xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d",
1408             vop_dev->id, __func__, win->area[0].xsize, win->area[0].ysize,
1409             win->area[0].xpos, win->area[0].ypos);
1410         return 0;
1411 }
1412
1413 static int vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1414 {
1415         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1416         struct rk_screen *screen = dev_drv->cur_screen;
1417
1418         if (!screen) {
1419                 dev_err(dev_drv->dev, "screen is null!\n");
1420                 return -ENOENT;
1421         }
1422
1423         switch (win_id) {
1424         case 0:
1425                 win_0_1_set_par(vop_dev, screen, dev_drv->win[0]);
1426                 break;
1427         case 1:
1428                 win_0_1_set_par(vop_dev, screen, dev_drv->win[1]);
1429                 break;
1430         case 2:
1431                 hwc_set_par(vop_dev, screen, dev_drv->win[2]);
1432                 break;
1433         default:
1434                 dev_err(dev_drv->dev, "%s: unsupported win id:%d\n",
1435                         __func__, win_id);
1436                 break;
1437         }
1438         return 0;
1439 }
1440
1441 static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1442                      unsigned long arg, int win_id)
1443 {
1444         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1445         u32 panel_size[2];
1446         void __user *argp = (void __user *)arg;
1447         struct color_key_cfg clr_key_cfg;
1448
1449         switch (cmd) {
1450         case RK_FBIOGET_PANEL_SIZE:
1451                 panel_size[0] = vop_dev->screen->mode.xres;
1452                 panel_size[1] = vop_dev->screen->mode.yres;
1453                 if (copy_to_user(argp, panel_size, 8))
1454                         return -EFAULT;
1455                 break;
1456         case RK_FBIOPUT_COLOR_KEY_CFG:
1457                 if (copy_from_user(&clr_key_cfg, argp,
1458                                    sizeof(struct color_key_cfg)))
1459                         return -EFAULT;
1460                 vop_clr_key_cfg(dev_drv);
1461                 vop_writel(vop_dev, WIN0_COLOR_KEY,
1462                            clr_key_cfg.win0_color_key_cfg);
1463                 vop_writel(vop_dev, WIN1_COLOR_KEY,
1464                            clr_key_cfg.win1_color_key_cfg);
1465                 break;
1466
1467         default:
1468                 break;
1469         }
1470         return 0;
1471 }
1472
1473 static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1474 {
1475         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1476         struct device_node *backlight;
1477         struct property *prop;
1478         u32 *brightness_levels;
1479         u32 length, max, last;
1480
1481         if (vop_dev->backlight)
1482                 return 0;
1483         backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0);
1484         if (backlight) {
1485                 vop_dev->backlight = of_find_backlight_by_node(backlight);
1486                 if (!vop_dev->backlight)
1487                         dev_info(vop_dev->dev, "No find backlight device\n");
1488         } else {
1489                 dev_info(vop_dev->dev, "No find backlight device node\n");
1490         }
1491         prop = of_find_property(backlight, "brightness-levels", &length);
1492         if (!prop)
1493                 return -EINVAL;
1494         max = length / sizeof(u32);
1495         last = max - 1;
1496         brightness_levels = kmalloc(256, GFP_KERNEL);
1497         if (brightness_levels)
1498                 return -ENOMEM;
1499
1500         if (!of_property_read_u32_array(backlight, "brightness-levels",
1501                                         brightness_levels, max)) {
1502                 if (brightness_levels[0] > brightness_levels[last])
1503                         dev_drv->cabc_pwm_pol = 1;/*negative*/
1504                 else
1505                         dev_drv->cabc_pwm_pol = 0;/*positive*/
1506         } else {
1507                 dev_info(vop_dev->dev,
1508                          "Can not read brightness-levels value\n");
1509         }
1510
1511         kfree(brightness_levels);
1512
1513         return 0;
1514 }
1515
1516 static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable)
1517 {
1518         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1519
1520         if (dev_drv->suspend_flag)
1521                 return 0;
1522
1523         vop_get_backlight_device(dev_drv);
1524
1525         if (enable) {
1526                 /* close the backlight */
1527                 if (vop_dev->backlight) {
1528                         vop_dev->backlight->props.power = FB_BLANK_POWERDOWN;
1529                         backlight_update_status(vop_dev->backlight);
1530                 }
1531                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1532                         dev_drv->trsm_ops->disable();
1533         } else {
1534                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1535                         dev_drv->trsm_ops->enable();
1536                 msleep(100);
1537                 /* open the backlight */
1538                 if (vop_dev->backlight) {
1539                         vop_dev->backlight->props.power = FB_BLANK_UNBLANK;
1540                         backlight_update_status(vop_dev->backlight);
1541                 }
1542         }
1543
1544         return 0;
1545 }
1546
1547 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv)
1548 {
1549         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1550
1551         if (dev_drv->suspend_flag)
1552                 return 0;
1553
1554         dev_drv->suspend_flag = 1;
1555         smp_wmb();
1556         flush_kthread_worker(&dev_drv->update_regs_worker);
1557
1558         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1559                 dev_drv->trsm_ops->disable();
1560
1561         vop_standby_enable(vop_dev);
1562         vop_mmu_disable(dev_drv);
1563         vop_clk_disable(vop_dev);
1564         rk_disp_pwr_disable(dev_drv);
1565
1566         return 0;
1567 }
1568
1569 static int vop_early_resume(struct rk_lcdc_driver *dev_drv)
1570 {
1571         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1572
1573         if (!dev_drv->suspend_flag)
1574                 return 0;
1575
1576         rk_disp_pwr_enable(dev_drv);
1577         vop_clk_enable(vop_dev);
1578         vop_reg_restore(dev_drv);
1579         vop_standby_disable(vop_dev);
1580         vop_mmu_enable(dev_drv);
1581         dev_drv->suspend_flag = 0;
1582
1583         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1584                 dev_drv->trsm_ops->enable();
1585
1586         return 0;
1587 }
1588
1589 static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode)
1590 {
1591         switch (blank_mode) {
1592         case FB_BLANK_UNBLANK:
1593                 vop_early_resume(dev_drv);
1594                 break;
1595         case FB_BLANK_NORMAL:
1596                 vop_early_suspend(dev_drv);
1597                 break;
1598         default:
1599                 vop_early_suspend(dev_drv);
1600                 break;
1601         }
1602
1603         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1604
1605         return 0;
1606 }
1607
1608 static int vop_get_win_state(struct rk_lcdc_driver *dev_drv,
1609                              int win_id, int area_id)
1610 {
1611         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1612         u32 area_status = 0, state = 0;
1613
1614         spin_lock(&vop_dev->reg_lock);
1615         if (likely(vop_dev->clk_on)) {
1616                 switch (win_id) {
1617                 case 0:
1618                         area_status =
1619                                 vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
1620                         break;
1621                 case 1:
1622                         area_status =
1623                                 vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
1624                         break;
1625                 case 2:
1626                         area_status =
1627                                 vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0));
1628                         break;
1629                 default:
1630                         pr_err("%s: win[%d]area[%d],unsupport!!!\n",
1631                                __func__, win_id, area_id);
1632                         break;
1633                 }
1634         }
1635         spin_unlock(&vop_dev->reg_lock);
1636
1637         state = (area_status > 0) ? 1 : 0;
1638         return state;
1639 }
1640
1641 static int vop_get_area_num(struct rk_lcdc_driver *dev_drv,
1642                             unsigned int *area_support)
1643 {
1644         area_support[0] = 1;
1645         area_support[1] = 1;
1646
1647         return 0;
1648 }
1649
1650 static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set)
1651 {
1652         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1653         int ovl;
1654
1655         spin_lock(&vop_dev->reg_lock);
1656         if (likely(vop_dev->clk_on)) {
1657                 if (set) {
1658                         vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(swap));
1659                         ovl = swap;
1660                 } else {
1661                         ovl =
1662                             vop_read_bit(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(0));
1663                 }
1664         } else {
1665                 ovl = -EPERM;
1666         }
1667         spin_unlock(&vop_dev->reg_lock);
1668
1669         return ovl;
1670 }
1671
1672 static char *vop_format_to_string(int format, char *fmt)
1673 {
1674         if (!fmt)
1675                 return NULL;
1676
1677         switch (format) {
1678         case 0:
1679                 strcpy(fmt, "ARGB888");
1680                 break;
1681         case 1:
1682                 strcpy(fmt, "RGB888");
1683                 break;
1684         case 2:
1685                 strcpy(fmt, "RGB565");
1686                 break;
1687         case 4:
1688                 strcpy(fmt, "YCbCr420");
1689                 break;
1690         case 5:
1691                 strcpy(fmt, "YCbCr422");
1692                 break;
1693         case 6:
1694                 strcpy(fmt, "YCbCr444");
1695                 break;
1696         default:
1697                 strcpy(fmt, "invalid\n");
1698                 break;
1699         }
1700         return fmt;
1701 }
1702
1703 static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
1704                                  char *buf, int win_id)
1705 {
1706         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1707         struct rk_screen *screen = dev_drv->cur_screen;
1708         u16 hsync_len = screen->mode.hsync_len;
1709         u16 left_margin = screen->mode.left_margin;
1710         u16 vsync_len = screen->mode.vsync_len;
1711         u16 upper_margin = screen->mode.upper_margin;
1712         u32 h_pw_bp = hsync_len + left_margin;
1713         u32 v_pw_bp = vsync_len + upper_margin;
1714         u32 fmt_id;
1715         char format_w0[9] = "NULL";
1716         char format_w1[9] = "NULL";
1717         char dsp_buf[100];
1718         u32 win_ctrl, ovl, vir_info, act_info, dsp_info, dsp_st;
1719         u32 y_factor, uv_factor;
1720         u8 w0_state, w1_state;
1721
1722         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
1723         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
1724         u32 w1_vir_y, w1_dsp_x, w1_dsp_y;
1725         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
1726         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
1727
1728         u32 dclk_freq;
1729         int size = 0;
1730
1731         dclk_freq = screen->mode.pixclock;
1732         /*vop_reg_dump(dev_drv); */
1733
1734         spin_lock(&vop_dev->reg_lock);
1735         if (likely(vop_dev->clk_on)) {
1736                 ovl = vop_read_bit(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(0));
1737                 /* WIN0 */
1738                 win_ctrl = vop_readl(vop_dev, WIN0_CTRL0);
1739                 w0_state = win_ctrl & MASK(WIN0_EN);
1740                 fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1;
1741                 vop_format_to_string(fmt_id, format_w0);
1742                 vir_info = vop_readl(vop_dev, WIN0_VIR);
1743                 act_info = vop_readl(vop_dev, WIN0_ACT_INFO);
1744                 dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO);
1745                 dsp_st = vop_readl(vop_dev, WIN0_DSP_ST);
1746                 y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB);
1747                 uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR);
1748                 w0_vir_y = vir_info & MASK(WIN0_YRGB_VIR_STRIDE);
1749                 w0_vir_uv = (vir_info & MASK(WIN0_CBR_VIR_STRIDE)) >> 16;
1750                 w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1;
1751                 w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1752                 w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1;
1753                 w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
1754                 if (w0_state) {
1755                         w0_st_x = dsp_st & MASK(WIN0_DSP_XST);
1756                         w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16;
1757                 }
1758                 w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB);
1759                 w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16;
1760                 w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR);
1761                 w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16;
1762
1763                 /* WIN1 */
1764                 win_ctrl = vop_readl(vop_dev, WIN1_CTRL0);
1765                 w1_state = win_ctrl & MASK(WIN1_EN);
1766                 fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1;
1767                 vop_format_to_string(fmt_id, format_w1);
1768                 vir_info = vop_readl(vop_dev, WIN1_VIR);
1769                 dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO);
1770                 dsp_st = vop_readl(vop_dev, WIN1_DSP_ST);
1771                 w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE);
1772                 w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1;
1773                 w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1;
1774                 if (w1_state) {
1775                         w1_st_x = dsp_st & MASK(WIN1_DSP_XST);
1776                         w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16;
1777                 }
1778         } else {
1779                 spin_unlock(&vop_dev->reg_lock);
1780                 return -EPERM;
1781         }
1782         spin_unlock(&vop_dev->reg_lock);
1783         /* win0 */
1784         size += snprintf(dsp_buf, 80,
1785                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
1786                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
1787         strcat(buf, dsp_buf);
1788         memset(dsp_buf, 0, sizeof(dsp_buf));
1789
1790         size += snprintf(dsp_buf, 80,
1791                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
1792                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
1793         strcat(buf, dsp_buf);
1794         memset(dsp_buf, 0, sizeof(dsp_buf));
1795
1796         size += snprintf(dsp_buf, 80,
1797                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
1798                  w0_st_x - h_pw_bp, w0_st_y - v_pw_bp, w0_y_h_fac, w0_y_v_fac);
1799         strcat(buf, dsp_buf);
1800         memset(dsp_buf, 0, sizeof(dsp_buf));
1801
1802         size += snprintf(dsp_buf, 80,
1803                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
1804                  w0_uv_h_fac, w0_uv_v_fac, vop_readl(vop_dev, WIN0_YRGB_MST),
1805                  vop_readl(vop_dev, WIN0_CBR_MST));
1806         strcat(buf, dsp_buf);
1807         memset(dsp_buf, 0, sizeof(dsp_buf));
1808
1809         /* win1 */
1810         size += snprintf(dsp_buf, 80,
1811                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d,",
1812                  w1_state, format_w1, w1_vir_y);
1813         strcat(buf, dsp_buf);
1814         memset(dsp_buf, 0, sizeof(dsp_buf));
1815
1816         size += snprintf(dsp_buf, 80,
1817                  " dsp_x   :%5d, dsp_y   :%5d\n",
1818                  w1_dsp_x, w1_dsp_y);
1819         strcat(buf, dsp_buf);
1820         memset(dsp_buf, 0, sizeof(dsp_buf));
1821
1822         size += snprintf(dsp_buf, 80,
1823                  "  x_st :%4d, y_st  :%4d, ",
1824                  w1_st_x - h_pw_bp, w1_st_y - v_pw_bp);
1825         strcat(buf, dsp_buf);
1826         memset(dsp_buf, 0, sizeof(dsp_buf));
1827
1828         size += snprintf(dsp_buf, 80,
1829                  "y_addr:0x%08x\n",
1830                  vop_readl(vop_dev, WIN1_YRGB_MST));
1831         strcat(buf, dsp_buf);
1832         memset(dsp_buf, 0, sizeof(dsp_buf));
1833
1834         /* zorder */
1835         size += snprintf(dsp_buf, 80,
1836                          ovl ? "win0 on the top of win1\n" :
1837                                 "win1 on the top of win0\n");
1838         strcat(buf, dsp_buf);
1839         memset(dsp_buf, 0, sizeof(dsp_buf));
1840
1841         return size;
1842 }
1843
1844 static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set)
1845 {
1846         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1847         struct rk_screen *screen = dev_drv->cur_screen;
1848         u64 ft = 0;
1849         u32 dotclk;
1850         int ret;
1851         u32 pixclock;
1852         u32 x_total, y_total;
1853
1854         if (set) {
1855                 if (fps == 0) {
1856                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
1857                         return 0;
1858                 }
1859                 ft = div_u64(1000000000000llu, fps);
1860                 x_total =
1861                     screen->mode.upper_margin + screen->mode.lower_margin +
1862                     screen->mode.yres + screen->mode.vsync_len;
1863                 y_total =
1864                     screen->mode.left_margin + screen->mode.right_margin +
1865                     screen->mode.xres + screen->mode.hsync_len;
1866                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1867                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1868                 ret = clk_set_rate(vop_dev->dclk, dotclk);
1869         }
1870
1871         pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
1872         vop_dev->pixclock = pixclock;
1873         dev_drv->pixclock = vop_dev->pixclock;
1874         fps = rk_fb_calc_fps(screen, pixclock);
1875         screen->ft = 1000 / fps;        /*one frame time in ms */
1876
1877         if (set)
1878                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1879                          clk_get_rate(vop_dev->dclk), fps);
1880
1881         return fps;
1882 }
1883
1884 static int vop_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
1885 {
1886         mutex_lock(&dev_drv->fb_win_id_mutex);
1887         if (order == FB_DEFAULT_ORDER)
1888                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
1889         dev_drv->fb4_win_id = order / 10000;
1890         dev_drv->fb3_win_id = (order / 1000) % 10;
1891         dev_drv->fb2_win_id = (order / 100) % 10;
1892         dev_drv->fb1_win_id = (order / 10) % 10;
1893         dev_drv->fb0_win_id = order % 10;
1894         mutex_unlock(&dev_drv->fb_win_id_mutex);
1895
1896         return 0;
1897 }
1898
1899 static int vop_get_win_id(struct rk_lcdc_driver *dev_drv, const char *id)
1900 {
1901         int win_id = 0;
1902
1903         mutex_lock(&dev_drv->fb_win_id_mutex);
1904         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
1905                 win_id = dev_drv->fb0_win_id;
1906         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
1907                 win_id = dev_drv->fb1_win_id;
1908         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
1909                 win_id = dev_drv->fb2_win_id;
1910         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
1911                 win_id = dev_drv->fb3_win_id;
1912         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
1913                 win_id = dev_drv->fb4_win_id;
1914         mutex_unlock(&dev_drv->fb_win_id_mutex);
1915
1916         return win_id;
1917 }
1918
1919 static int vop_config_done(struct rk_lcdc_driver *dev_drv)
1920 {
1921         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1922         int i;
1923         struct rk_lcdc_win *win = NULL;
1924
1925         spin_lock(&vop_dev->reg_lock);
1926         if (likely(vop_dev->clk_on)) {
1927                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1928                         win = dev_drv->win[i];
1929                         vop_layer_update_regs(vop_dev, win);
1930                 }
1931                 vop_cfg_done(vop_dev);
1932         }
1933         spin_unlock(&vop_dev->reg_lock);
1934
1935         return 0;
1936 }
1937
1938 static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
1939 {
1940         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1941
1942         spin_lock(&vop_dev->reg_lock);
1943         if (likely(vop_dev->clk_on)) {
1944                 vop_msk_reg(vop_dev, SYS_CTRL0, V_DIRECT_PATH_EN(open));
1945                 vop_cfg_done(vop_dev);
1946         }
1947         spin_unlock(&vop_dev->reg_lock);
1948
1949         return 0;
1950 }
1951
1952 static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
1953 {
1954         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1955
1956         spin_lock(&vop_dev->reg_lock);
1957         if (likely(vop_dev->clk_on)) {
1958                 vop_msk_reg(vop_dev, SYS_CTRL0,
1959                             V_DIRECT_PATH_LAYER_SEL(win_id));
1960                 vop_cfg_done(vop_dev);
1961         }
1962         spin_unlock(&vop_dev->reg_lock);
1963         return 0;
1964 }
1965
1966 static int vop_dpi_status(struct rk_lcdc_driver *dev_drv)
1967 {
1968         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1969         int status;
1970
1971         spin_lock(&vop_dev->reg_lock);
1972
1973         if (likely(vop_dev->clk_on))
1974                 status = vop_read_bit(vop_dev, SYS_CTRL0, V_DIRECT_PATH_EN(0));
1975
1976         spin_unlock(&vop_dev->reg_lock);
1977
1978         return status;
1979 }
1980
1981 static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
1982 {
1983         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1984
1985         if (enable)
1986                 enable_irq(vop_dev->irq);
1987         else
1988                 disable_irq(vop_dev->irq);
1989         return 0;
1990 }
1991
1992 static int vop_poll_vblank(struct rk_lcdc_driver *dev_drv)
1993 {
1994         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1995         u32 int_reg;
1996         int ret;
1997
1998         if (vop_dev->clk_on && (!dev_drv->suspend_flag)) {
1999                 int_reg = vop_readl(vop_dev, INTR_STATUS);
2000                 if (int_reg & INTR_LINE_FLAG0) {
2001                         vop_dev->driver.frame_time.last_framedone_t =
2002                             vop_dev->driver.frame_time.framedone_t;
2003                         vop_dev->driver.frame_time.framedone_t = cpu_clock(0);
2004                         vop_mask_writel(vop_dev, INTR_CLEAR, INTR_LINE_FLAG0,
2005                                         INTR_LINE_FLAG0);
2006                         ret = RK_LF_STATUS_FC;
2007                 } else {
2008                         ret = RK_LF_STATUS_FR;
2009                 }
2010         } else {
2011                 ret = RK_LF_STATUS_NC;
2012         }
2013
2014         return ret;
2015 }
2016
2017 static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2018                             unsigned int dsp_addr[][4])
2019 {
2020         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2021
2022         spin_lock(&vop_dev->reg_lock);
2023         if (likely(vop_dev->clk_on)) {
2024                 dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST);
2025                 dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST);
2026                 dsp_addr[2][0] = vop_readl(vop_dev, HWC_MST);
2027         }
2028         spin_unlock(&vop_dev->reg_lock);
2029         return 0;
2030 }
2031
2032 /*
2033  * a:[-30~0]:
2034  *      sin_hue = sin(a)*256 +0x100;
2035  *      cos_hue = cos(a)*256;
2036  * a:[0~30]
2037  *      sin_hue = sin(a)*256;
2038  *      cos_hue = cos(a)*256;
2039  */
2040 static int vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode)
2041 {
2042         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2043         u32 val = 0;
2044
2045         spin_lock(&vop_dev->reg_lock);
2046         if (likely(vop_dev->clk_on)) {
2047                 val = vop_readl(vop_dev, BCSH_H);
2048                 switch (mode) {
2049                 case H_SIN:
2050                         val &= MASK(SIN_HUE);
2051                         val <<= 1;
2052                         break;
2053                 case H_COS:
2054                         val &= MASK(COS_HUE);
2055                         val >>= 8;
2056                         val <<= 1;
2057                         break;
2058                 default:
2059                         break;
2060                 }
2061         }
2062         spin_unlock(&vop_dev->reg_lock);
2063
2064         return val;
2065 }
2066
2067 static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
2068                             int sin_hue, int cos_hue)
2069 {
2070         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2071         u64 val;
2072
2073         spin_lock(&vop_dev->reg_lock);
2074         if (likely(vop_dev->clk_on)) {
2075                 /*
2076                  * config range is [0, 510), typical value is 256
2077                  * register range is [0, 255], cos_hue typical value is 128
2078                  * sin_hue typical value is 0
2079                  */
2080                 val = V_SIN_HUE(sin_hue >> 1) | V_COS_HUE(cos_hue >> 1);
2081                 vop_msk_reg(vop_dev, BCSH_H, val);
2082                 vop_cfg_done(vop_dev);
2083         }
2084         spin_unlock(&vop_dev->reg_lock);
2085
2086         return 0;
2087 }
2088
2089 static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
2090                             bcsh_bcs_mode mode, int value)
2091 {
2092         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2093         u64 val = 0;
2094
2095         spin_lock(&vop_dev->reg_lock);
2096         if (likely(vop_dev->clk_on)) {
2097                 switch (mode) {
2098                 case BRIGHTNESS:
2099                         /*
2100                          * user range is [0, 255], typical value is 128
2101                          * register range is [-32, 31], typical value is 0
2102                          */
2103                         value >>= 2; /* 0-->32-->63 for user, typical is 32 */
2104                         if (value < 0x20)
2105                                 value += 0x20;
2106                         else if (value >= 0x20)
2107                                 value = value - 0x20;
2108                         val = V_BRIGHTNESS(value);
2109                         break;
2110                 case CONTRAST:
2111                         /*
2112                          * config range is [0, 510), typical value is 256
2113                          * register range is [0, 255], typical value is 128
2114                          */
2115                         value >>= 1;
2116                         val = V_CONTRAST(value);
2117                         break;
2118                 case SAT_CON:
2119                         /*
2120                          * config range is [0, 1015], typical value is 512
2121                          * register range is [0, 255], typical value is 128
2122                          */
2123                         value >>= 2;
2124                         val = V_SAT_CON(value);
2125                         break;
2126                 default:
2127                         break;
2128                 }
2129                 vop_msk_reg(vop_dev, BCSH_BCS, val);
2130                 vop_cfg_done(vop_dev);
2131         }
2132         spin_unlock(&vop_dev->reg_lock);
2133
2134         return val;
2135 }
2136
2137 static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode)
2138 {
2139         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2140         u64 val = 0;
2141
2142         spin_lock(&vop_dev->reg_lock);
2143         if (likely(vop_dev->clk_on)) {
2144                 val = vop_readl(vop_dev, BCSH_BCS);
2145                 switch (mode) {
2146                 case BRIGHTNESS:
2147                         val &= MASK(BRIGHTNESS);
2148                         if (val >= 0x20)
2149                                 val -= 0x20;
2150                         else
2151                                 val += 0x20;
2152                         val <<= 2;
2153                         break;
2154                 case CONTRAST:
2155                         val &= MASK(CONTRAST);
2156                         val >>= 8;
2157                         val <<= 1;
2158                         break;
2159                 case SAT_CON:
2160                         val &= MASK(SAT_CON);
2161                         val >>= 16;
2162                         val <<= 2;
2163                         break;
2164                 default:
2165                         break;
2166                 }
2167         }
2168         spin_unlock(&vop_dev->reg_lock);
2169         return val;
2170 }
2171
2172 static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2173 {
2174         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2175
2176         spin_lock(&vop_dev->reg_lock);
2177         if (likely(vop_dev->clk_on)) {
2178                 if (open) {
2179                         vop_writel(vop_dev, BCSH_BCS,
2180                                    V_BRIGHTNESS(0x00) | V_CONTRAST(0x80) |
2181                                    V_SAT_CON(0x80));
2182                         vop_writel(vop_dev, BCSH_H,
2183                                    V_SIN_HUE(0x00) | V_COS_HUE(0x80));
2184                         vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_EN(1) |
2185                                     V_VIDEO_MODE(BCSH_MODE_VIDEO));
2186                         dev_drv->bcsh.enable = 1;
2187                 } else {
2188                         vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_EN(0));
2189                         dev_drv->bcsh.enable = 0;
2190                 }
2191                 vop_bcsh_path_sel(dev_drv);
2192                 vop_cfg_done(vop_dev);
2193         }
2194         spin_unlock(&vop_dev->reg_lock);
2195
2196         return 0;
2197 }
2198
2199 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
2200 {
2201         if (!enable || !dev_drv->bcsh.enable) {
2202                 vop_open_bcsh(dev_drv, false);
2203                 return 0;
2204         }
2205
2206         if (dev_drv->bcsh.brightness <= 255 ||
2207             dev_drv->bcsh.contrast < 510 ||
2208             dev_drv->bcsh.sat_con <= 1015 ||
2209             (dev_drv->bcsh.sin_hue < 510 && dev_drv->bcsh.cos_hue < 510)) {
2210                 vop_open_bcsh(dev_drv, true);
2211                 if (dev_drv->bcsh.brightness <= 255)
2212                         vop_set_bcsh_bcs(dev_drv, BRIGHTNESS,
2213                                          dev_drv->bcsh.brightness);
2214                 if (dev_drv->bcsh.contrast < 510)
2215                         vop_set_bcsh_bcs(dev_drv, CONTRAST,
2216                                          dev_drv->bcsh.contrast);
2217                 if (dev_drv->bcsh.sat_con <= 1015)
2218                         vop_set_bcsh_bcs(dev_drv, SAT_CON,
2219                                          dev_drv->bcsh.sat_con);
2220                 if (dev_drv->bcsh.sin_hue < 510 &&
2221                     dev_drv->bcsh.cos_hue < 510)
2222                         vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue,
2223                                          dev_drv->bcsh.cos_hue);
2224         }
2225
2226         return 0;
2227 }
2228
2229 static int __maybe_unused
2230 vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2231 {
2232         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2233
2234         if (enable) {
2235                 spin_lock(&vop_dev->reg_lock);
2236                 if (likely(vop_dev->clk_on)) {
2237                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1));
2238                         vop_cfg_done(vop_dev);
2239                 }
2240                 spin_unlock(&vop_dev->reg_lock);
2241         } else {
2242                 spin_lock(&vop_dev->reg_lock);
2243                 if (likely(vop_dev->clk_on)) {
2244                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0));
2245                         vop_cfg_done(vop_dev);
2246                 }
2247                 spin_unlock(&vop_dev->reg_lock);
2248         }
2249
2250         return 0;
2251 }
2252
2253 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2254         .open = vop_open,
2255         .win_direct_en = vop_win_direct_en,
2256         .load_screen = vop_load_screen,
2257         .get_dspbuf_info = vop_get_dspbuf_info,
2258         .post_dspbuf = vop_post_dspbuf,
2259         .set_par = vop_set_par,
2260         .pan_display = vop_pan_display,
2261         .direct_set_addr = vop_direct_set_win_addr,
2262         .blank = vop_blank,
2263         .ioctl = vop_ioctl,
2264         .suspend = vop_early_suspend,
2265         .resume = vop_early_resume,
2266         .get_win_state = vop_get_win_state,
2267         .area_support_num = vop_get_area_num,
2268         .ovl_mgr = vop_ovl_mgr,
2269         .get_disp_info = vop_get_disp_info,
2270         .fps_mgr = vop_fps_mgr,
2271         .fb_get_win_id = vop_get_win_id,
2272         .fb_win_remap = vop_fb_win_remap,
2273         .poll_vblank = vop_poll_vblank,
2274         .dpi_open = vop_dpi_open,
2275         .dpi_win_sel = vop_dpi_win_sel,
2276         .dpi_status = vop_dpi_status,
2277         .get_dsp_addr = vop_get_dsp_addr,
2278         .set_dsp_bcsh_hue = vop_set_bcsh_hue,
2279         .set_dsp_bcsh_bcs = vop_set_bcsh_bcs,
2280         .get_dsp_bcsh_hue = vop_get_bcsh_hue,
2281         .get_dsp_bcsh_bcs = vop_get_bcsh_bcs,
2282         .open_bcsh = vop_open_bcsh,
2283         .set_dsp_lut = vop_set_lut,
2284         .set_hwc_lut = vop_set_hwc_lut,
2285         .dump_reg = vop_reg_dump,
2286         .cfg_done = vop_config_done,
2287         .set_irq_to_cpu = vop_set_irq_to_cpu,
2288         /*.dsp_black = vop_dsp_black,*/
2289         .backlight_close = vop_backlight_close,
2290         .mmu_en = vop_mmu_enable,
2291 };
2292
2293 static irqreturn_t vop_isr(int irq, void *dev_id)
2294 {
2295         struct vop_device *vop_dev = (struct vop_device *)dev_id;
2296         ktime_t timestamp = ktime_get();
2297         u32 intr_status;
2298         unsigned long flags;
2299
2300         spin_lock_irqsave(&vop_dev->irq_lock, flags);
2301
2302         intr_status = vop_readl(vop_dev, INTR_STATUS);
2303         vop_mask_writel(vop_dev, INTR_CLEAR, INTR_MASK, intr_status);
2304
2305         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
2306
2307         intr_status &= 0xffff;  /* ignore raw status at 16~32bit */
2308         /* This is expected for vop iommu irqs, since the irq is shared */
2309         if (!intr_status)
2310                 return IRQ_NONE;
2311
2312         if (intr_status & INTR_FS0) {
2313                 timestamp = ktime_get();
2314                 vop_dev->driver.vsync_info.timestamp = timestamp;
2315                 wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait);
2316                 complete(&vop_dev->sync.frmst);
2317                 intr_status &= ~INTR_FS0;
2318         }
2319
2320         /* fs1 interrupt occur only when the address is different */
2321         if (intr_status & INTR_FS1)
2322                 intr_status &= ~INTR_FS1;
2323
2324         if (intr_status & INTR_ADDR_SAME)
2325                 intr_status &= ~INTR_ADDR_SAME;
2326
2327         if (intr_status & INTR_DSP_HOLD_VALID) {
2328                 complete(&vop_dev->sync.stdbyfin);
2329                 intr_status &= ~INTR_DSP_HOLD_VALID;
2330         }
2331
2332         if (intr_status & INTR_LINE_FLAG0)
2333                 intr_status &= ~INTR_LINE_FLAG0;
2334
2335         if (intr_status & INTR_LINE_FLAG1)
2336                 intr_status &= ~INTR_LINE_FLAG1;
2337
2338         if (intr_status & INTR_BUS_ERROR) {
2339                 intr_status &= ~INTR_BUS_ERROR;
2340                 dev_warn_ratelimited(vop_dev->dev, "bus error!");
2341         }
2342
2343         if (intr_status & INTR_WIN0_EMPTY) {
2344                 intr_status &= ~INTR_WIN0_EMPTY;
2345                 dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!");
2346         }
2347
2348         if (intr_status & INTR_WIN1_EMPTY) {
2349                 intr_status &= ~INTR_WIN1_EMPTY;
2350                 dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!");
2351         }
2352
2353         if (intr_status & INTR_DMA_FINISH)
2354                 intr_status &= ~INTR_DMA_FINISH;
2355
2356         if (intr_status & INTR_MMU_STATUS)
2357                 intr_status &= ~INTR_MMU_STATUS;
2358
2359         if (intr_status)
2360                 dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status);
2361
2362         return IRQ_HANDLED;
2363 }
2364
2365 #if defined(CONFIG_PM)
2366 static int vop_suspend(struct platform_device *pdev, pm_message_t state)
2367 {
2368         return 0;
2369 }
2370
2371 static int vop_resume(struct platform_device *pdev)
2372 {
2373         return 0;
2374 }
2375 #else
2376 #define vop_suspend NULL
2377 #define vop_resume  NULL
2378 #endif
2379
2380 static int vop_parse_dt(struct vop_device *vop_dev)
2381 {
2382         struct device_node *np = vop_dev->dev->of_node;
2383         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
2384         int val;
2385
2386         if (of_property_read_u32(np, "rockchip,prop", &val))
2387                 vop_dev->prop = PRMRY;  /*default set it as primary */
2388         else
2389                 vop_dev->prop = val;
2390
2391         if (of_property_read_u32(np, "rockchip,mirror", &val))
2392                 dev_drv->rotate_mode = NO_MIRROR;
2393         else
2394                 dev_drv->rotate_mode = val;
2395
2396         if (of_property_read_u32(np, "rockchip,pwr18", &val))
2397                 /*default set it as 3.xv power supply */
2398                 vop_dev->pwr18 = false;
2399         else
2400                 vop_dev->pwr18 = (val ? true : false);
2401
2402         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2403                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
2404         else
2405                 dev_drv->fb_win_map = val;
2406
2407         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
2408                 dev_drv->bcsh.enable = false;
2409         else
2410                 dev_drv->bcsh.enable = (val ? true : false);
2411
2412         if (of_property_read_u32(np, "rockchip,brightness", &val))
2413                 dev_drv->bcsh.brightness = 0xffff;
2414         else
2415                 dev_drv->bcsh.brightness = val;
2416
2417         if (of_property_read_u32(np, "rockchip,contrast", &val))
2418                 dev_drv->bcsh.contrast = 0xffff;
2419         else
2420                 dev_drv->bcsh.contrast = val;
2421
2422         if (of_property_read_u32(np, "rockchip,sat-con", &val))
2423                 dev_drv->bcsh.sat_con = 0xffff;
2424         else
2425                 dev_drv->bcsh.sat_con = val;
2426
2427         if (of_property_read_u32(np, "rockchip,hue", &val)) {
2428                 dev_drv->bcsh.sin_hue = 0xffff;
2429                 dev_drv->bcsh.cos_hue = 0xffff;
2430         } else {
2431                 dev_drv->bcsh.sin_hue = val & 0xff;
2432                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
2433         }
2434
2435         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2436                 dev_drv->iommu_enabled = 0;
2437         else
2438                 dev_drv->iommu_enabled = val;
2439
2440         return 0;
2441 }
2442
2443 static int vop_probe(struct platform_device *pdev)
2444 {
2445         struct vop_device *vop_dev = NULL;
2446         struct rk_lcdc_driver *dev_drv;
2447         struct device *dev = &pdev->dev;
2448         struct resource *res;
2449         struct device_node *np = pdev->dev.of_node;
2450         int prop;
2451         int ret = 0;
2452
2453         /*
2454          * if the primary lcdc has not registered ,the extend
2455          * lcdc register later
2456          */
2457         of_property_read_u32(np, "rockchip,prop", &prop);
2458         if (prop == EXTEND) {
2459                 if (!is_prmry_rk_lcdc_registered())
2460                         return -EPROBE_DEFER;
2461         }
2462         vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL);
2463         if (!vop_dev)
2464                 return -ENOMEM;
2465
2466         platform_set_drvdata(pdev, vop_dev);
2467         vop_dev->dev = dev;
2468         vop_parse_dt(vop_dev);
2469
2470         /* enable power domain */
2471         pm_runtime_enable(dev);
2472
2473         vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_vop");
2474         if (IS_ERR(vop_dev->hclk)) {
2475                 dev_err(vop_dev->dev, "failed to get hclk source\n");
2476                 return PTR_ERR(vop_dev->hclk);
2477         }
2478         vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_vop");
2479         if (IS_ERR(vop_dev->aclk)) {
2480                 dev_err(vop_dev->dev, "failed to get aclk source\n");
2481                 return PTR_ERR(vop_dev->aclk);
2482         }
2483         vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_vop");
2484         if (IS_ERR(vop_dev->dclk)) {
2485                 dev_err(vop_dev->dev, "failed to get dclk source\n");
2486                 return PTR_ERR(vop_dev->dclk);
2487         }
2488         clk_prepare(vop_dev->hclk);
2489         clk_prepare(vop_dev->aclk);
2490         clk_prepare(vop_dev->dclk);
2491
2492         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2493         vop_dev->regs = devm_ioremap_resource(dev, res);
2494         if (IS_ERR(vop_dev->regs)) {
2495                 ret = PTR_ERR(vop_dev->regs);
2496                 goto err_exit;
2497         }
2498
2499         vop_dev->reg_phy_base = res->start;
2500         vop_dev->len = resource_size(res);
2501         vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL);
2502         if (!vop_dev->regsbak) {
2503                 ret = -ENOMEM;
2504                 goto err_exit;
2505         }
2506
2507         vop_dev->hwc_lut_addr_base = (vop_dev->regs + HWC_LUT_ADDR);
2508         vop_dev->dsp_lut_addr_base = (vop_dev->regs + GAMMA_LUT_ADDR);
2509         vop_dev->grf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
2510         if (IS_ERR(vop_dev->grf_base)) {
2511                 dev_err(vop_dev->dev, "ERROR!! can't find grf reg property\n");
2512                 vop_dev->grf_base = NULL;
2513         }
2514
2515         vop_dev->id = 1;
2516         dev_set_name(vop_dev->dev, "vop%d", vop_dev->id);
2517         dev_drv = &vop_dev->driver;
2518         dev_drv->dev = dev;
2519         dev_drv->prop = prop;
2520         dev_drv->id = vop_dev->id;
2521         dev_drv->ops = &lcdc_drv_ops;
2522         dev_drv->lcdc_win_num = ARRAY_SIZE(vop_win);
2523         dev_drv->reserved_fb = 0;
2524         spin_lock_init(&vop_dev->reg_lock);
2525         spin_lock_init(&vop_dev->irq_lock);
2526         init_completion(&vop_dev->sync.stdbyfin);
2527         init_completion(&vop_dev->sync.frmst);
2528         vop_dev->sync.stdbyfin_to = 50; /* timeout 50 ms */
2529         vop_dev->sync.frmst_to = 50;
2530
2531         vop_dev->irq = platform_get_irq(pdev, 0);
2532         if (vop_dev->irq < 0) {
2533                 dev_err(dev, "cannot find IRQ for lcdc%d\n", vop_dev->id);
2534                 ret = vop_dev->irq;
2535                 goto err_exit;
2536         }
2537
2538         ret = devm_request_irq(dev, vop_dev->irq, vop_isr,
2539                                IRQF_SHARED,
2540                                dev_name(dev), vop_dev);
2541         if (ret) {
2542                 dev_err(dev, "cannot requeset irq %d - err %d\n",
2543                         vop_dev->irq, ret);
2544                 goto err_exit;
2545         }
2546
2547         if (dev_drv->iommu_enabled)
2548                 strcpy(dev_drv->mmu_dts_name, VOPL_IOMMU_COMPATIBLE_NAME);
2549
2550         ret = rk_fb_register(dev_drv, vop_win, vop_dev->id);
2551         if (ret < 0) {
2552                 dev_err(dev, "register fb for failed!\n");
2553                 goto err_exit;
2554         }
2555         vop_dev->screen = dev_drv->screen0;
2556         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2557                  vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2558
2559         return 0;
2560
2561 err_exit:
2562         clk_unprepare(vop_dev->dclk);
2563         clk_unprepare(vop_dev->aclk);
2564         clk_unprepare(vop_dev->hclk);
2565         pm_runtime_disable(dev);
2566
2567         return ret;
2568 }
2569
2570 static int vop_remove(struct platform_device *pdev)
2571 {
2572         return 0;
2573 }
2574
2575 static void vop_shutdown(struct platform_device *pdev)
2576 {
2577         struct vop_device *vop_dev = platform_get_drvdata(pdev);
2578         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
2579
2580         dev_drv->suspend_flag = 1;
2581         smp_wmb();
2582         flush_kthread_worker(&dev_drv->update_regs_worker);
2583         kthread_stop(dev_drv->update_regs_thread);
2584
2585         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2586                 dev_drv->trsm_ops->disable();
2587
2588         vop_deinit(vop_dev);
2589         rk_disp_pwr_disable(dev_drv);
2590 }
2591
2592 #if defined(CONFIG_OF)
2593 static const struct of_device_id vop_dt_ids[] = {
2594         {.compatible = "rockchip,rk3366-lcdc-lite",},
2595         {}
2596 };
2597 #endif
2598
2599 static struct platform_driver vop_driver = {
2600         .probe = vop_probe,
2601         .remove = vop_remove,
2602         .driver = {
2603                    .name = "rk-vop-lite",
2604                    .owner = THIS_MODULE,
2605                    .of_match_table = of_match_ptr(vop_dt_ids),
2606                    },
2607         .suspend = vop_suspend,
2608         .resume = vop_resume,
2609         .shutdown = vop_shutdown,
2610 };
2611
2612 static int __init vop_module_init(void)
2613 {
2614         return platform_driver_register(&vop_driver);
2615 }
2616
2617 static void __exit vop_module_exit(void)
2618 {
2619         platform_driver_unregister(&vop_driver);
2620 }
2621
2622 fs_initcall(vop_module_init);
2623 module_exit(vop_module_exit);