ba13a770bbb5b21a65ea94fb88c4912555b814d2
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3368_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3368_lcdc.c
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  *Author:hjc<hjc@rock-chips.com>
6  *This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/clk.h>
29 #include <linux/rockchip-iovmm.h>
30 #include <asm/div64.h>
31 #include <linux/uaccess.h>
32 #include <linux/rockchip/cpu.h>
33 #include <linux/rockchip/iomap.h>
34 #include <linux/rockchip/grf.h>
35 #include <linux/rockchip/common.h>
36 #include <dt-bindings/clock/rk_system_status.h>
37
38 #include "rk3368_lcdc.h"
39
40 #if defined(CONFIG_HAS_EARLYSUSPEND)
41 #include <linux/earlysuspend.h>
42 #endif
43 /*#define CONFIG_RK_FPGA 1*/
44
45 static int dbg_thresd;
46 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
47
48 #define DBG(level, x...) do {                   \
49         if (unlikely(dbg_thresd >= level))      \
50                 pr_info(x);\
51         } while (0)
52
53 static struct rk_lcdc_win lcdc_win[] = {
54         [0] = {
55                .name = "win0",
56                .id = 0,
57                .support_3d = false,
58                },
59         [1] = {
60                .name = "win1",
61                .id = 1,
62                .support_3d = false,
63                },
64         [2] = {
65                .name = "win2",
66                .id = 2,
67                .support_3d = false,
68                },
69         [3] = {
70                .name = "win3",
71                .id = 3,
72                .support_3d = false,
73                },
74         [4] = {
75                .name = "hwc",
76                .id = 4,
77                .support_3d = false,
78                }
79 };
80
81 static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
82
83 /*#define WAIT_FOR_SYNC 1*/
84 u32 rk3368_get_hard_ware_vskiplines(u32 srch, u32 dsth)
85 {
86         u32 vscalednmult;
87
88         if (srch >= (u32) (4 * dsth * MIN_SCALE_FACTOR_AFTER_VSKIP))
89                 vscalednmult = 4;
90         else if (srch >= (u32) (2 * dsth * MIN_SCALE_FACTOR_AFTER_VSKIP))
91                 vscalednmult = 2;
92         else
93                 vscalednmult = 1;
94
95         return vscalednmult;
96 }
97
98
99 static int rk3368_set_cabc_lut(struct rk_lcdc_driver *dev_drv, int *cabc_lut)
100 {
101         int i;
102         int __iomem *c;
103         u32 v;
104         struct lcdc_device *lcdc_dev =
105             container_of(dev_drv, struct lcdc_device, driver);
106
107         lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
108                      v_CABC_LUT_EN(0));
109         lcdc_cfg_done(lcdc_dev);
110         mdelay(25);
111         for (i = 0; i < 256; i++) {
112                 v = cabc_lut[i];
113                 c = lcdc_dev->cabc_lut_addr_base + i;
114                 writel_relaxed(v, c);
115         }
116         lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
117                      v_CABC_LUT_EN(1));
118         return 0;
119 }
120
121
122 static int rk3368_lcdc_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
123 {
124         int i;
125         int __iomem *c;
126         u32 v;
127         struct lcdc_device *lcdc_dev =
128             container_of(dev_drv, struct lcdc_device, driver);
129
130         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
131                      v_DSP_LUT_EN(0));
132         lcdc_cfg_done(lcdc_dev);
133         mdelay(25);
134         for (i = 0; i < 256; i++) {
135                 v = dsp_lut[i];
136                 c = lcdc_dev->dsp_lut_addr_base + i;
137                 writel_relaxed(v, c);
138         }
139         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
140                      v_DSP_LUT_EN(1));
141
142         return 0;
143 }
144
145 static int rk3368_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
146 {
147 #ifdef CONFIG_RK_FPGA
148         lcdc_dev->clk_on = 1;
149         return 0;
150 #endif
151         if (!lcdc_dev->clk_on) {
152                 clk_prepare_enable(lcdc_dev->hclk);
153                 clk_prepare_enable(lcdc_dev->dclk);
154                 clk_prepare_enable(lcdc_dev->aclk);
155                 /*clk_prepare_enable(lcdc_dev->pd);*/
156                 spin_lock(&lcdc_dev->reg_lock);
157                 lcdc_dev->clk_on = 1;
158                 spin_unlock(&lcdc_dev->reg_lock);
159         }
160
161         return 0;
162 }
163
164 static int rk3368_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
165 {
166 #ifdef CONFIG_RK_FPGA
167         lcdc_dev->clk_on = 0;
168         return 0;
169 #endif
170         if (lcdc_dev->clk_on) {
171                 spin_lock(&lcdc_dev->reg_lock);
172                 lcdc_dev->clk_on = 0;
173                 spin_unlock(&lcdc_dev->reg_lock);
174                 mdelay(25);
175                 clk_disable_unprepare(lcdc_dev->dclk);
176                 clk_disable_unprepare(lcdc_dev->hclk);
177                 clk_disable_unprepare(lcdc_dev->aclk);
178                 /*clk_disable_unprepare(lcdc_dev->pd);*/
179         }
180
181         return 0;
182 }
183
184 static int __maybe_unused
185         rk3368_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
186 {
187         u32 mask, val;
188
189         spin_lock(&lcdc_dev->reg_lock);
190         if (likely(lcdc_dev->clk_on)) {
191                 mask = m_FS_INTR_EN | m_FS_NEW_INTR_EN |
192                     m_ADDR_SAME_INTR_EN | m_LINE_FLAG0_INTR_EN |
193                     m_LINE_FLAG1_INTR_EN | m_BUS_ERROR_INTR_EN |
194                     m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
195                     m_WIN2_EMPTY_INTR_EN | m_WIN3_EMPTY_INTR_EN |
196                     m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
197                     m_PWM_GEN_INTR_EN | m_DSP_HOLD_VALID_INTR_EN;
198                 val = v_FS_INTR_EN(0) | v_FS_NEW_INTR_EN(0) |
199                     v_ADDR_SAME_INTR_EN(0) |
200                     v_LINE_FLAG0_INTR_EN(0) | v_LINE_FLAG1_INTR_EN(0) |
201                     v_BUS_ERROR_INTR_EN(0) | v_WIN0_EMPTY_INTR_EN(0) |
202                     v_WIN1_EMPTY_INTR_EN(0) | v_WIN2_EMPTY_INTR_EN(0) |
203                     v_WIN3_EMPTY_INTR_EN(0) | v_HWC_EMPTY_INTR_EN(0) |
204                     v_POST_BUF_EMPTY_INTR_EN(0) |
205                     v_PWM_GEN_INTR_EN(0) | v_DSP_HOLD_VALID_INTR_EN(0);
206                 lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
207
208                 mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR |
209                     m_ADDR_SAME_INTR_CLR | m_LINE_FLAG0_INTR_CLR |
210                     m_LINE_FLAG1_INTR_CLR | m_BUS_ERROR_INTR_CLR |
211                     m_WIN0_EMPTY_INTR_CLR | m_WIN1_EMPTY_INTR_CLR |
212                     m_WIN2_EMPTY_INTR_CLR | m_WIN3_EMPTY_INTR_CLR |
213                     m_HWC_EMPTY_INTR_CLR | m_POST_BUF_EMPTY_INTR_CLR |
214                     m_PWM_GEN_INTR_CLR | m_DSP_HOLD_VALID_INTR_CLR;
215                 val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) |
216                     v_ADDR_SAME_INTR_CLR(1) |
217                     v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1) |
218                     v_BUS_ERROR_INTR_CLR(1) | v_WIN0_EMPTY_INTR_CLR(1) |
219                     v_WIN1_EMPTY_INTR_CLR(1) | v_WIN2_EMPTY_INTR_CLR(1) |
220                     v_WIN3_EMPTY_INTR_CLR(1) | v_HWC_EMPTY_INTR_CLR(1) |
221                     v_POST_BUF_EMPTY_INTR_CLR(1) |
222                     v_PWM_GEN_INTR_CLR(1) | v_DSP_HOLD_VALID_INTR_CLR(1);
223                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val);
224                 lcdc_cfg_done(lcdc_dev);
225                 spin_unlock(&lcdc_dev->reg_lock);
226         } else {
227                 spin_unlock(&lcdc_dev->reg_lock);
228         }
229         mdelay(1);
230         return 0;
231 }
232
233 static int rk3368_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
234 {
235         struct lcdc_device *lcdc_dev =
236             container_of(dev_drv, struct lcdc_device, driver);
237         int *cbase = (int *)lcdc_dev->regs;
238         int *regsbak = (int *)lcdc_dev->regsbak;
239         int i, j, val;
240         char dbg_message[30];
241         char buf[10];
242
243         pr_info("lcd back up reg:\n");
244         memset(dbg_message, 0, sizeof(dbg_message));
245         memset(buf, 0, sizeof(buf));
246         for (i = 0; i <= (0x200 >> 4); i++) {
247                 val = sprintf(dbg_message, "0x%04x: ", i * 16);
248                 for (j = 0; j < 4; j++) {
249                         val = sprintf(buf, "%08x  ", *(regsbak + i * 4 + j));
250                         strcat(dbg_message, buf);
251                 }
252                 pr_info("%s\n", dbg_message);
253                 memset(dbg_message, 0, sizeof(dbg_message));
254                 memset(buf, 0, sizeof(buf));
255         }
256
257         pr_info("lcdc reg:\n");
258         for (i = 0; i <= (0x200 >> 4); i++) {
259                 val = sprintf(dbg_message, "0x%04x: ", i * 16);
260                 for (j = 0; j < 4; j++) {
261                         sprintf(buf, "%08x  ",
262                                 readl_relaxed(cbase + i * 4 + j));
263                         strcat(dbg_message, buf);
264                 }
265                 pr_info("%s\n", dbg_message);
266                 memset(dbg_message, 0, sizeof(dbg_message));
267                 memset(buf, 0, sizeof(buf));
268         }
269
270         return 0;
271 }
272
273 #define WIN_EN(id)              \
274 static int win##id##_enable(struct lcdc_device *lcdc_dev, int en)       \
275 { \
276         u32 msk, val;                                                   \
277         spin_lock(&lcdc_dev->reg_lock);                                 \
278         msk =  m_WIN##id##_EN;                                          \
279         val  =  v_WIN##id##_EN(en);                                     \
280         lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk, val);              \
281         lcdc_cfg_done(lcdc_dev);                                        \
282         val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);            \
283         while (val !=  (!!en))  {                                       \
284                 val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);    \
285         }                                                               \
286         spin_unlock(&lcdc_dev->reg_lock);                               \
287         return 0;                                                       \
288 }
289
290 WIN_EN(0);
291 WIN_EN(1);
292 WIN_EN(2);
293 WIN_EN(3);
294 /*enable/disable win directly*/
295 static int rk3368_lcdc_win_direct_en(struct rk_lcdc_driver *drv,
296                                      int win_id, int en)
297 {
298         struct lcdc_device *lcdc_dev =
299             container_of(drv, struct lcdc_device, driver);
300         if (win_id == 0)
301                 win0_enable(lcdc_dev, en);
302         else if (win_id == 1)
303                 win1_enable(lcdc_dev, en);
304         else if (win_id == 2)
305                 win2_enable(lcdc_dev, en);
306         else if (win_id == 3)
307                 win3_enable(lcdc_dev, en);
308         else
309                 dev_err(lcdc_dev->dev, "invalid win number:%d\n", win_id);
310         return 0;
311 }
312
313 #define SET_WIN_ADDR(id) \
314 static int set_win##id##_addr(struct lcdc_device *lcdc_dev, u32 addr) \
315 {                                                       \
316         u32 msk, val;                                   \
317         spin_lock(&lcdc_dev->reg_lock);                 \
318         lcdc_writel(lcdc_dev, WIN##id##_YRGB_MST, addr);        \
319         msk =  m_WIN##id##_EN;                          \
320         val  =  v_WIN0_EN(1);                           \
321         lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk, val);      \
322         lcdc_cfg_done(lcdc_dev);                        \
323         spin_unlock(&lcdc_dev->reg_lock);               \
324         return 0;                                       \
325 }
326
327 SET_WIN_ADDR(0);
328 SET_WIN_ADDR(1);
329 int rk3368_lcdc_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
330                                     int win_id, u32 addr)
331 {
332         struct lcdc_device *lcdc_dev =
333             container_of(dev_drv, struct lcdc_device, driver);
334         if (win_id == 0)
335                 set_win0_addr(lcdc_dev, addr);
336         else
337                 set_win1_addr(lcdc_dev, addr);
338
339         return 0;
340 }
341
342 static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev)
343 {
344         int reg = 0;
345         u32 val = 0;
346         struct rk_screen *screen = lcdc_dev->driver.cur_screen;
347         u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
348         u32 v_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
349         u32 st_x, st_y;
350         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
351
352         spin_lock(&lcdc_dev->reg_lock);
353         for (reg = 0; reg < SCAN_LINE_NUM; reg += 4) {
354                 val = lcdc_readl_backup(lcdc_dev, reg);
355                 switch (reg) {
356                 case WIN0_ACT_INFO:
357                         win0->area[0].xact = (val & m_WIN0_ACT_WIDTH) + 1;
358                         win0->area[0].yact =
359                             ((val & m_WIN0_ACT_HEIGHT) >> 16) + 1;
360                         break;
361                 case WIN0_DSP_INFO:
362                         win0->area[0].xsize = (val & m_WIN0_DSP_WIDTH) + 1;
363                         win0->area[0].ysize =
364                             ((val & m_WIN0_DSP_HEIGHT) >> 16) + 1;
365                         break;
366                 case WIN0_DSP_ST:
367                         st_x = val & m_WIN0_DSP_XST;
368                         st_y = (val & m_WIN0_DSP_YST) >> 16;
369                         win0->area[0].xpos = st_x - h_pw_bp;
370                         win0->area[0].ypos = st_y - v_pw_bp;
371                         break;
372                 case WIN0_CTRL0:
373                         win0->state = val & m_WIN0_EN;
374                         win0->area[0].fmt_cfg = (val & m_WIN0_DATA_FMT) >> 1;
375                         win0->fmt_10 = (val & m_WIN0_FMT_10) >> 4;
376                         win0->area[0].format = win0->area[0].fmt_cfg;
377                         break;
378                 case WIN0_VIR:
379                         win0->area[0].y_vir_stride = val & m_WIN0_VIR_STRIDE;
380                         win0->area[0].uv_vir_stride =
381                             (val & m_WIN0_VIR_STRIDE_UV) >> 16;
382                         if (win0->area[0].format == ARGB888)
383                                 win0->area[0].xvir = win0->area[0].y_vir_stride;
384                         else if (win0->area[0].format == RGB888)
385                                 win0->area[0].xvir =
386                                     win0->area[0].y_vir_stride * 4 / 3;
387                         else if (win0->area[0].format == RGB565)
388                                 win0->area[0].xvir =
389                                     2 * win0->area[0].y_vir_stride;
390                         else    /* YUV */
391                                 win0->area[0].xvir =
392                                     4 * win0->area[0].y_vir_stride;
393                         break;
394                 case WIN0_YRGB_MST:
395                         win0->area[0].smem_start = val;
396                         break;
397                 case WIN0_CBR_MST:
398                         win0->area[0].cbr_start = val;
399                         break;
400                 default:
401                         break;
402                 }
403         }
404         spin_unlock(&lcdc_dev->reg_lock);
405 }
406
407 /********do basic init*********/
408 static int rk3368_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
409 {
410         u32 mask, val, v;
411         struct lcdc_device *lcdc_dev =
412             container_of(dev_drv, struct lcdc_device, driver);
413         if (lcdc_dev->pre_init)
414                 return 0;
415
416         lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
417         lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
418         lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
419         /*lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");*/
420
421         if (/*IS_ERR(lcdc_dev->pd) || */(IS_ERR(lcdc_dev->aclk)) ||
422             (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
423                 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
424                         lcdc_dev->id);
425         }
426
427         rk_disp_pwr_enable(dev_drv);
428         rk3368_lcdc_clk_enable(lcdc_dev);
429
430         /*backup reg config at uboot */
431         lcdc_read_reg_defalut_cfg(lcdc_dev);
432         if (lcdc_dev->pwr18 == 1) {
433                 v = 0x00200020; /*bit5: 1,1.8v;0,3.3v*/
434                 lcdc_grf_writel(lcdc_dev->pmugrf_base,
435                                 PMUGRF_SOC_CON0_VOP, v);
436         } else {
437                 v = 0x00200000; /*bit5: 1,1.8v;0,3.3v*/
438                 lcdc_grf_writel(lcdc_dev->pmugrf_base,
439                                 PMUGRF_SOC_CON0_VOP, v);
440         }
441         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_0, 0x15110903);
442         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_1, 0x00030911);
443         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_0, 0x1a150b04);
444         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_1, 0x00040b15);
445         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_0, 0x15110903);
446         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_1, 0x00030911);
447
448         lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
449         lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
450         lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0xa55a9696);
451         lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x5aa56969);
452         lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
453         lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
454
455         mask = m_AUTO_GATING_EN;
456         val = v_AUTO_GATING_EN(0);
457         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
458         lcdc_cfg_done(lcdc_dev);
459         /*disable win0 to workaround iommu pagefault */
460         /*if (dev_drv->iommu_enabled) */
461         /*      win0_enable(lcdc_dev, 0); */
462         lcdc_dev->pre_init = true;
463
464         return 0;
465 }
466
467 static void rk3368_lcdc_deint(struct lcdc_device *lcdc_dev)
468 {
469 }
470
471 static int rk3368_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv)
472 {
473         struct lcdc_device *lcdc_dev =
474             container_of(dev_drv, struct lcdc_device, driver);
475         struct rk_screen *screen = dev_drv->cur_screen;
476         u16 x_res = screen->mode.xres;
477         u16 y_res = screen->mode.yres;
478         u32 mask, val;
479         u16 h_total, v_total;
480         u16 post_hsd_en, post_vsd_en;
481         u16 post_dsp_hact_st, post_dsp_hact_end;
482         u16 post_dsp_vact_st, post_dsp_vact_end;
483         u16 post_dsp_vact_st_f1, post_dsp_vact_end_f1;
484         u16 post_h_fac, post_v_fac;
485
486         screen->post_dsp_stx = x_res * (100 - dev_drv->overscan.left) / 200;
487         screen->post_dsp_sty = y_res * (100 - dev_drv->overscan.top) / 200;
488         screen->post_xsize = x_res *
489             (dev_drv->overscan.left + dev_drv->overscan.right) / 200;
490         screen->post_ysize = y_res *
491             (dev_drv->overscan.top + dev_drv->overscan.bottom) / 200;
492
493         h_total = screen->mode.hsync_len + screen->mode.left_margin +
494             x_res + screen->mode.right_margin;
495         v_total = screen->mode.vsync_len + screen->mode.upper_margin +
496             y_res + screen->mode.lower_margin;
497
498         if (screen->post_dsp_stx + screen->post_xsize > x_res) {
499                 dev_warn(lcdc_dev->dev, "post:stx[%d]+xsize[%d]>x_res[%d]\n",
500                          screen->post_dsp_stx, screen->post_xsize, x_res);
501                 screen->post_dsp_stx = x_res - screen->post_xsize;
502         }
503         if (screen->x_mirror == 0) {
504                 post_dsp_hact_st = screen->post_dsp_stx +
505                     screen->mode.hsync_len + screen->mode.left_margin;
506                 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
507         } else {
508                 post_dsp_hact_end = h_total - screen->mode.right_margin -
509                     screen->post_dsp_stx;
510                 post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
511         }
512         if ((screen->post_xsize < x_res) && (screen->post_xsize != 0)) {
513                 post_hsd_en = 1;
514                 post_h_fac =
515                     GET_SCALE_FACTOR_BILI_DN(x_res, screen->post_xsize);
516         } else {
517                 post_hsd_en = 0;
518                 post_h_fac = 0x1000;
519         }
520
521         if (screen->post_dsp_sty + screen->post_ysize > y_res) {
522                 dev_warn(lcdc_dev->dev, "post:sty[%d]+ysize[%d]> y_res[%d]\n",
523                          screen->post_dsp_sty, screen->post_ysize, y_res);
524                 screen->post_dsp_sty = y_res - screen->post_ysize;
525         }
526
527         if ((screen->post_ysize < y_res) && (screen->post_ysize != 0)) {
528                 post_vsd_en = 1;
529                 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res,
530                                                       screen->post_ysize);
531         } else {
532                 post_vsd_en = 0;
533                 post_v_fac = 0x1000;
534         }
535
536         if (screen->mode.vmode == FB_VMODE_INTERLACED) {
537                 post_dsp_vact_st = screen->post_dsp_sty / 2 +
538                                         screen->mode.vsync_len +
539                                         screen->mode.upper_margin;
540                 post_dsp_vact_end = post_dsp_vact_st +
541                                         screen->post_ysize / 2;
542
543                 post_dsp_vact_st_f1 = screen->mode.vsync_len +
544                                       screen->mode.upper_margin +
545                                       y_res/2 +
546                                       screen->mode.lower_margin +
547                                       screen->mode.vsync_len +
548                                       screen->mode.upper_margin +
549                                       screen->post_dsp_sty / 2 +
550                                       1;
551                 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 +
552                                         screen->post_ysize/2;
553         } else {
554                 if (screen->y_mirror == 0) {
555                         post_dsp_vact_st = screen->post_dsp_sty +
556                             screen->mode.vsync_len +
557                             screen->mode.upper_margin;
558                         post_dsp_vact_end = post_dsp_vact_st +
559                                 screen->post_ysize;
560                 } else {
561                         post_dsp_vact_end = v_total -
562                                 screen->mode.lower_margin -
563                             screen->post_dsp_sty;
564                         post_dsp_vact_st = post_dsp_vact_end -
565                                 screen->post_ysize;
566                 }
567                 post_dsp_vact_st_f1 = 0;
568                 post_dsp_vact_end_f1 = 0;
569         }
570         DBG(1, "post:xsize=%d,ysize=%d,xpos=%d",
571             screen->post_xsize, screen->post_ysize, screen->xpos);
572         DBG(1, ",ypos=%d,hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
573             screen->ypos, post_hsd_en, post_h_fac, post_vsd_en, post_v_fac);
574         mask = m_DSP_HACT_END_POST | m_DSP_HACT_ST_POST;
575         val = v_DSP_HACT_END_POST(post_dsp_hact_end) |
576             v_DSP_HACT_ST_POST(post_dsp_hact_st);
577         lcdc_msk_reg(lcdc_dev, POST_DSP_HACT_INFO, mask, val);
578
579         mask = m_DSP_VACT_END_POST | m_DSP_VACT_ST_POST;
580         val = v_DSP_VACT_END_POST(post_dsp_vact_end) |
581             v_DSP_VACT_ST_POST(post_dsp_vact_st);
582         lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO, mask, val);
583
584         mask = m_POST_HS_FACTOR_YRGB | m_POST_VS_FACTOR_YRGB;
585         val = v_POST_HS_FACTOR_YRGB(post_h_fac) |
586             v_POST_VS_FACTOR_YRGB(post_v_fac);
587         lcdc_msk_reg(lcdc_dev, POST_SCL_FACTOR_YRGB, mask, val);
588
589         mask = m_DSP_VACT_END_POST_F1 | m_DSP_VACT_ST_POST_F1;
590         val = v_DSP_VACT_END_POST_F1(post_dsp_vact_end_f1) |
591             v_DSP_VACT_ST_POST_F1(post_dsp_vact_st_f1);
592         lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO_F1, mask, val);
593
594         mask = m_POST_HOR_SD_EN | m_POST_VER_SD_EN;
595         val = v_POST_HOR_SD_EN(post_hsd_en) | v_POST_VER_SD_EN(post_vsd_en);
596         lcdc_msk_reg(lcdc_dev, POST_SCL_CTRL, mask, val);
597         return 0;
598 }
599
600 static int rk3368_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
601 {
602         struct lcdc_device *lcdc_dev =
603             container_of(dev_drv, struct lcdc_device, driver);
604         struct rk_lcdc_win *win;
605         u32 colorkey_r, colorkey_g, colorkey_b;
606         int i, key_val;
607
608         for (i = 0; i < 4; i++) {
609                 win = dev_drv->win[i];
610                 key_val = win->color_key_val;
611                 colorkey_r = (key_val & 0xff) << 2;
612                 colorkey_g = ((key_val >> 8) & 0xff) << 12;
613                 colorkey_b = ((key_val >> 16) & 0xff) << 22;
614                 /*color key dither 565/888->aaa */
615                 key_val = colorkey_r | colorkey_g | colorkey_b;
616                 switch (i) {
617                 case 0:
618                         lcdc_writel(lcdc_dev, WIN0_COLOR_KEY, key_val);
619                         break;
620                 case 1:
621                         lcdc_writel(lcdc_dev, WIN1_COLOR_KEY, key_val);
622                         break;
623                 case 2:
624                         lcdc_writel(lcdc_dev, WIN2_COLOR_KEY, key_val);
625                         break;
626                 case 3:
627                         lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val);
628                         break;
629                 default:
630                         pr_info("%s:un support win num:%d\n",
631                                 __func__, i);
632                         break;
633                 }
634         }
635         return 0;
636 }
637
638 static int rk3368_lcdc_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
639 {
640         struct lcdc_device *lcdc_dev =
641             container_of(dev_drv, struct lcdc_device, driver);
642         struct rk_lcdc_win *win = dev_drv->win[win_id];
643         struct alpha_config alpha_config;
644         u32 mask, val;
645         int ppixel_alpha = 0, global_alpha = 0, i;
646         u32 src_alpha_ctl, dst_alpha_ctl;
647
648         for (i = 0; i < win->area_num; i++) {
649                 ppixel_alpha |= ((win->area[i].format == ARGB888) ||
650                                  (win->area[i].format == FBDC_ARGB_888) ||
651                                  (win->area[i].format == FBDC_ABGR_888) ||
652                                  (win->area[i].format == ABGR888)) ? 1 : 0;
653         }
654         global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
655         alpha_config.src_global_alpha_val = win->g_alpha_val;
656         win->alpha_mode = AB_SRC_OVER;
657         /*printk("%s,alpha_mode=%d,alpha_en=%d,ppixel_a=%d,gla_a=%d\n",
658            __func__,win->alpha_mode,win->alpha_en,ppixel_alpha,
659            global_alpha); */
660         switch (win->alpha_mode) {
661         case AB_USER_DEFINE:
662                 break;
663         case AB_CLEAR:
664                 alpha_config.src_factor_mode = AA_ZERO;
665                 alpha_config.dst_factor_mode = AA_ZERO;
666                 break;
667         case AB_SRC:
668                 alpha_config.src_factor_mode = AA_ONE;
669                 alpha_config.dst_factor_mode = AA_ZERO;
670                 break;
671         case AB_DST:
672                 alpha_config.src_factor_mode = AA_ZERO;
673                 alpha_config.dst_factor_mode = AA_ONE;
674                 break;
675         case AB_SRC_OVER:
676                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
677                 if (global_alpha)
678                         alpha_config.src_factor_mode = AA_SRC_GLOBAL;
679                 else
680                         alpha_config.src_factor_mode = AA_ONE;
681                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
682                 break;
683         case AB_DST_OVER:
684                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
685                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
686                 alpha_config.dst_factor_mode = AA_ONE;
687                 break;
688         case AB_SRC_IN:
689                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
690                 alpha_config.src_factor_mode = AA_SRC;
691                 alpha_config.dst_factor_mode = AA_ZERO;
692                 break;
693         case AB_DST_IN:
694                 alpha_config.src_factor_mode = AA_ZERO;
695                 alpha_config.dst_factor_mode = AA_SRC;
696                 break;
697         case AB_SRC_OUT:
698                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
699                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
700                 alpha_config.dst_factor_mode = AA_ZERO;
701                 break;
702         case AB_DST_OUT:
703                 alpha_config.src_factor_mode = AA_ZERO;
704                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
705                 break;
706         case AB_SRC_ATOP:
707                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
708                 alpha_config.src_factor_mode = AA_SRC;
709                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
710                 break;
711         case AB_DST_ATOP:
712                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
713                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
714                 alpha_config.dst_factor_mode = AA_SRC;
715                 break;
716         case XOR:
717                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
718                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
719                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
720                 break;
721         case AB_SRC_OVER_GLOBAL:
722                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
723                 alpha_config.src_color_mode = AA_SRC_NO_PRE_MUL;
724                 alpha_config.src_factor_mode = AA_SRC_GLOBAL;
725                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
726                 break;
727         default:
728                 pr_err("alpha mode error\n");
729                 break;
730         }
731         if ((ppixel_alpha == 1) && (global_alpha == 1))
732                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
733         else if (ppixel_alpha == 1)
734                 alpha_config.src_global_alpha_mode = AA_PER_PIX;
735         else if (global_alpha == 1)
736                 alpha_config.src_global_alpha_mode = AA_GLOBAL;
737         else
738                 dev_warn(lcdc_dev->dev, "alpha_en should be 0\n");
739         alpha_config.src_alpha_mode = AA_STRAIGHT;
740         alpha_config.src_alpha_cal_m0 = AA_NO_SAT;
741
742         switch (win_id) {
743         case 0:
744                 src_alpha_ctl = 0x60;
745                 dst_alpha_ctl = 0x64;
746                 break;
747         case 1:
748                 src_alpha_ctl = 0xa0;
749                 dst_alpha_ctl = 0xa4;
750                 break;
751         case 2:
752                 src_alpha_ctl = 0xdc;
753                 dst_alpha_ctl = 0xec;
754                 break;
755         case 3:
756                 src_alpha_ctl = 0x12c;
757                 dst_alpha_ctl = 0x13c;
758                 break;
759         case 4:
760                 src_alpha_ctl = 0x160;
761                 dst_alpha_ctl = 0x164;
762                 break;
763         }
764         mask = m_WIN0_DST_FACTOR_M0;
765         val = v_WIN0_DST_FACTOR_M0(alpha_config.dst_factor_mode);
766         lcdc_msk_reg(lcdc_dev, dst_alpha_ctl, mask, val);
767         mask = m_WIN0_SRC_ALPHA_EN | m_WIN0_SRC_COLOR_M0 |
768             m_WIN0_SRC_ALPHA_M0 | m_WIN0_SRC_BLEND_M0 |
769             m_WIN0_SRC_ALPHA_CAL_M0 | m_WIN0_SRC_FACTOR_M0 |
770             m_WIN0_SRC_GLOBAL_ALPHA;
771         val = v_WIN0_SRC_ALPHA_EN(1) |
772             v_WIN0_SRC_COLOR_M0(alpha_config.src_color_mode) |
773             v_WIN0_SRC_ALPHA_M0(alpha_config.src_alpha_mode) |
774             v_WIN0_SRC_BLEND_M0(alpha_config.src_global_alpha_mode) |
775             v_WIN0_SRC_ALPHA_CAL_M0(alpha_config.src_alpha_cal_m0) |
776             v_WIN0_SRC_FACTOR_M0(alpha_config.src_factor_mode) |
777             v_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
778         lcdc_msk_reg(lcdc_dev, src_alpha_ctl, mask, val);
779
780         return 0;
781 }
782
783 static int rk3368_lcdc_area_xst(struct rk_lcdc_win *win, int area_num)
784 {
785         struct rk_lcdc_win_area area_temp;
786         int i, j;
787
788         for (i = 0; i < area_num; i++) {
789                 for (j = i + 1; j < area_num; j++) {
790                         if (win->area[i].dsp_stx >  win->area[j].dsp_stx) {
791                                 memcpy(&area_temp, &win->area[i],
792                                        sizeof(struct rk_lcdc_win_area));
793                                 memcpy(&win->area[i], &win->area[j],
794                                        sizeof(struct rk_lcdc_win_area));
795                                 memcpy(&win->area[j], &area_temp,
796                                        sizeof(struct rk_lcdc_win_area));
797                         }
798                 }
799         }
800
801         return 0;
802 }
803
804 static int __maybe_unused
805         rk3368_lcdc_area_swap(struct rk_lcdc_win *win, int area_num)
806 {
807         struct rk_lcdc_win_area area_temp;
808
809         switch (area_num) {
810         case 2:
811                 area_temp = win->area[0];
812                 win->area[0] = win->area[1];
813                 win->area[1] = area_temp;
814                 break;
815         case 3:
816                 area_temp = win->area[0];
817                 win->area[0] = win->area[2];
818                 win->area[2] = area_temp;
819                 break;
820         case 4:
821                 area_temp = win->area[0];
822                 win->area[0] = win->area[3];
823                 win->area[3] = area_temp;
824
825                 area_temp = win->area[1];
826                 win->area[1] = win->area[2];
827                 win->area[2] = area_temp;
828                 break;
829         default:
830                 pr_info("un supported area num!\n");
831                 break;
832         }
833         return 0;
834 }
835
836 static int __maybe_unused
837 rk3368_win_area_check_var(int win_id, int area_num,
838                           struct rk_lcdc_win_area *area_pre,
839                           struct rk_lcdc_win_area *area_now)
840 {
841         if ((area_pre->xpos > area_now->xpos) ||
842             ((area_pre->xpos + area_pre->xsize > area_now->xpos) &&
843              (area_pre->ypos + area_pre->ysize > area_now->ypos))) {
844                 area_now->state = 0;
845                 pr_err("win[%d]:\n"
846                        "area_pre[%d]:xpos[%d],xsize[%d],ypos[%d],ysize[%d]\n"
847                        "area_now[%d]:xpos[%d],xsize[%d],ypos[%d],ysize[%d]\n",
848                        win_id,
849                        area_num - 1, area_pre->xpos, area_pre->xsize,
850                        area_pre->ypos, area_pre->ysize,
851                        area_num, area_now->xpos, area_now->xsize,
852                        area_now->ypos, area_now->ysize);
853                 return -EINVAL;
854         }
855         return 0;
856 }
857
858 static int __maybe_unused rk3368_get_fbdc_idle(struct rk_lcdc_driver *dev_drv)
859 {
860         struct lcdc_device *lcdc_dev =
861             container_of(dev_drv, struct lcdc_device, driver);
862         u32 val, i;
863
864         for (i = 0; i < 100; i++) {
865                 val = lcdc_readl(lcdc_dev, IFBDC_DEBUG0);
866                 val &= m_DBG_IFBDC_IDLE;
867                 if (val)
868                         continue;
869                 else
870                         mdelay(10);
871         };
872         return val;
873 }
874
875 static int rk3368_fbdc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
876 {
877         struct lcdc_device *lcdc_dev =
878             container_of(dev_drv, struct lcdc_device, driver);
879         struct rk_lcdc_win *win = dev_drv->win[win_id];
880         u32 mask, val;
881
882         mask = m_IFBDC_CTRL_FBDC_EN | m_IFBDC_CTRL_FBDC_COR_EN |
883             m_IFBDC_CTRL_FBDC_WIN_SEL | m_IFBDC_CTRL_FBDC_ROTATION_MODE |
884             m_IFBDC_CTRL_FBDC_FMT | m_IFBDC_CTRL_WIDTH_RATIO;
885         val = v_IFBDC_CTRL_FBDC_EN(win->area[0].fbdc_en) |
886             v_IFBDC_CTRL_FBDC_COR_EN(win->area[0].fbdc_cor_en) |
887             v_IFBDC_CTRL_FBDC_WIN_SEL(win->id) |
888             v_IFBDC_CTRL_FBDC_ROTATION_MODE(win->mirror_en << 1) |
889             v_IFBDC_CTRL_FBDC_FMT(win->area[0].fbdc_fmt_cfg) |
890             v_IFBDC_CTRL_WIDTH_RATIO(win->area[0].fbdc_dsp_width_ratio);
891         lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
892
893         mask = m_IFBDC_TILES_NUM;
894         val = v_IFBDC_TILES_NUM(win->area[0].fbdc_num_tiles);
895         lcdc_msk_reg(lcdc_dev, IFBDC_TILES_NUM, mask, val);
896
897         mask = m_IFBDC_MB_SIZE_WIDTH | m_IFBDC_MB_SIZE_HEIGHT;
898         val = v_IFBDC_MB_SIZE_WIDTH(win->area[0].fbdc_mb_width) |
899             v_IFBDC_MB_SIZE_HEIGHT(win->area[0].fbdc_mb_height);
900         lcdc_msk_reg(lcdc_dev, IFBDC_MB_SIZE, mask, val);
901
902         mask = m_IFBDC_CMP_INDEX_INIT;
903         val = v_IFBDC_CMP_INDEX_INIT(win->area[0].fbdc_cmp_index_init);
904         lcdc_msk_reg(lcdc_dev, IFBDC_CMP_INDEX_INIT, mask, val);
905
906         mask = m_IFBDC_MB_VIR_WIDTH;
907         val = v_IFBDC_MB_VIR_WIDTH(win->area[0].fbdc_mb_vir_width);
908         lcdc_msk_reg(lcdc_dev, IFBDC_MB_VIR_WIDTH, mask, val);
909
910         return 0;
911 }
912
913 static int rk3368_init_fbdc_config(struct rk_lcdc_driver *dev_drv, int win_id)
914 {
915         struct lcdc_device *lcdc_dev =
916             container_of(dev_drv, struct lcdc_device, driver);
917         struct rk_lcdc_win *win = dev_drv->win[win_id];
918         u8 fbdc_dsp_width_ratio;
919         u16 fbdc_mb_vir_width, fbdc_mb_vir_height;
920         u16 fbdc_mb_width, fbdc_mb_height;
921         u16 fbdc_mb_xst, fbdc_mb_yst, fbdc_num_tiles;
922         u16 fbdc_cmp_index_init;
923         u8 mb_w_size, mb_h_size;
924         struct rk_screen *screen = dev_drv->cur_screen;
925
926         if (screen->mode.flag == FB_VMODE_INTERLACED) {
927                 dev_err(lcdc_dev->dev, "unsupport fbdc+interlace!\n");
928                 return 0;
929         }
930
931         switch (win->area[0].fmt_cfg) {
932         case VOP_FORMAT_ARGB888:
933                 fbdc_dsp_width_ratio = 0;
934                 mb_w_size = 16;
935                 break;
936         case VOP_FORMAT_RGB888:
937                 fbdc_dsp_width_ratio = 0;
938                 mb_w_size = 16;
939                 break;
940         case VOP_FORMAT_RGB565:
941                 fbdc_dsp_width_ratio = 1;
942                 mb_w_size = 32;
943                 break;
944         default:
945                 dev_err(lcdc_dev->dev,
946                         "in fbdc mode,unsupport fmt:%d!\n",
947                         win->area[0].fmt_cfg);
948                 break;
949         }
950         mb_h_size = 4;
951
952         /*macro block xvir and yvir */
953         if ((win->area[0].xvir % mb_w_size == 0) &&
954             (win->area[0].yvir % mb_h_size == 0)) {
955                 fbdc_mb_vir_width = win->area[0].xvir / mb_w_size;
956                 fbdc_mb_vir_height = win->area[0].yvir / mb_h_size;
957         } else {
958                 pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
959                 pr_err("xvir[%d]/yvir[%d] should %d/%d pix align!\n",
960                        win->area[0].xvir, win->area[0].yvir,
961                        mb_w_size, mb_h_size);
962         }
963         /*macro block xact and yact */
964         if ((win->area[0].xact % mb_w_size == 0) &&
965             (win->area[0].yact % mb_h_size == 0)) {
966                 fbdc_mb_width = win->area[0].xact / mb_w_size;
967                 fbdc_mb_height = win->area[0].yact / mb_h_size;
968         } else {
969                 pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
970                 pr_err("xact[%d]/yact[%d] should %d/%d pix align!\n",
971                        win->area[0].xact, win->area[0].yact,
972                        mb_w_size, mb_h_size);
973         }
974         /*macro block xoff and yoff */
975         if ((win->area[0].xoff % mb_w_size == 0) &&
976             (win->area[0].yoff % mb_h_size == 0)) {
977                 fbdc_mb_xst = win->area[0].xoff / mb_w_size;
978                 fbdc_mb_yst = win->area[0].yoff / mb_h_size;
979         } else {
980                 pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
981                 pr_err("xoff[%d]/yoff[%d] should %d/%d pix align!\n",
982                        win->area[0].xoff, win->area[0].yoff,
983                        mb_w_size, mb_h_size);
984         }
985
986         /*FBDC tiles */
987         fbdc_num_tiles = fbdc_mb_vir_width * fbdc_mb_vir_height;
988
989         /*
990            switch (fbdc_rotation_mode)  {
991            case FBDC_ROT_NONE:
992            fbdc_cmp_index_init =
993            (fbdc_mb_yst*fbdc_mb_vir_width) +  fbdc_mb_xst;
994            break;
995            case FBDC_X_MIRROR:
996            fbdc_cmp_index_init =
997            (fbdc_mb_yst*fbdc_mb_vir_width) + (fbdc_mb_xst+
998            (fbdc_mb_width-1));
999            break;
1000            case FBDC_Y_MIRROR:
1001            fbdc_cmp_index_init =
1002            ((fbdc_mb_yst+(fbdc_mb_height-1))*fbdc_mb_vir_width)  +
1003            fbdc_mb_xst;
1004            break;
1005            case FBDC_ROT_180:
1006            fbdc_cmp_index_init =
1007            ((fbdc_mb_yst+(fbdc_mb_height-1))*fbdc_mb_vir_width) +
1008            (fbdc_mb_xst+(fbdc_mb_width-1));
1009            break;
1010            }
1011          */
1012         if ((win->mirror_en) && ((win_id == 2) || (win_id == 3))) {
1013                 fbdc_cmp_index_init =
1014                     ((fbdc_mb_yst + (fbdc_mb_height - 1)) * fbdc_mb_vir_width) +
1015                     (fbdc_mb_xst + (fbdc_mb_width - 1));
1016         } else {
1017                 fbdc_cmp_index_init =
1018                     (fbdc_mb_yst * fbdc_mb_vir_width) + fbdc_mb_xst;
1019         }
1020         /*fbdc fmt maybe need to change*/
1021         win->area[0].fbdc_dsp_width_ratio = fbdc_dsp_width_ratio;
1022         win->area[0].fbdc_mb_vir_width = fbdc_mb_vir_width;
1023         win->area[0].fbdc_mb_vir_height = fbdc_mb_vir_height;
1024         win->area[0].fbdc_mb_width = fbdc_mb_width;
1025         win->area[0].fbdc_mb_height = fbdc_mb_height;
1026         win->area[0].fbdc_mb_xst = fbdc_mb_xst;
1027         win->area[0].fbdc_mb_yst = fbdc_mb_yst;
1028         win->area[0].fbdc_num_tiles = fbdc_num_tiles;
1029         win->area[0].fbdc_cmp_index_init = fbdc_cmp_index_init;
1030
1031         return 0;
1032 }
1033
1034 static void rk3368_lcdc_csc_mode(struct lcdc_device *lcdc_dev,
1035                                  struct rk_lcdc_win *win)
1036 {
1037         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
1038         struct rk_screen *screen = dev_drv->cur_screen;
1039
1040         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1041                 switch (win->area[0].fmt_cfg) {
1042                 case VOP_FORMAT_ARGB888:
1043                 case VOP_FORMAT_RGB888:
1044                 case VOP_FORMAT_RGB565:
1045                         if ((screen->mode.xres < 1280) &&
1046                             (screen->mode.yres < 720)) {
1047                                 win->csc_mode = VOP_R2Y_CSC_BT601;
1048                         } else {
1049                                 win->csc_mode = VOP_R2Y_CSC_BT709;
1050                         }
1051                         break;
1052                 default:
1053                         break;
1054                 }
1055         } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
1056                 switch (win->area[0].fmt_cfg) {
1057                 case VOP_FORMAT_YCBCR420:
1058                         if ((win->id == 0) || (win->id == 1))
1059                                 win->csc_mode = VOP_Y2R_CSC_MPEG;
1060                         break;
1061                 default:
1062                         break;
1063                 }
1064         }
1065 }
1066
1067 static int rk3368_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1068 {
1069         struct lcdc_device *lcdc_dev =
1070             container_of(dev_drv, struct lcdc_device, driver);
1071         struct rk_lcdc_win *win = dev_drv->win[win_id];
1072         unsigned int mask, val, off;
1073
1074         off = win_id * 0x40;
1075         /*if(win->win_lb_mode == 5)
1076            win->win_lb_mode = 4;
1077            for rk3288 to fix hw bug? */
1078
1079         if (win->state == 1) {
1080                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1081                 if (win->area[0].fbdc_en) {
1082                         rk3368_fbdc_reg_update(&lcdc_dev->driver, win_id);
1083                 } else {
1084                         mask = m_IFBDC_CTRL_FBDC_EN;
1085                         val = v_IFBDC_CTRL_FBDC_EN(0);
1086                         lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
1087                 }
1088                 mask = m_WIN0_EN | m_WIN0_DATA_FMT | m_WIN0_FMT_10 |
1089                     m_WIN0_LB_MODE | m_WIN0_RB_SWAP | m_WIN0_X_MIRROR |
1090                     m_WIN0_Y_MIRROR | m_WIN0_CSC_MODE |m_WIN0_UV_SWAP;
1091                 val = v_WIN0_EN(win->state) |
1092                     v_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
1093                     v_WIN0_FMT_10(win->fmt_10) |
1094                     v_WIN0_LB_MODE(win->win_lb_mode) |
1095                     v_WIN0_RB_SWAP(win->area[0].swap_rb) |
1096                     v_WIN0_X_MIRROR(win->mirror_en) |
1097                     v_WIN0_Y_MIRROR(win->mirror_en) |
1098                     v_WIN0_CSC_MODE(win->csc_mode) |
1099                     v_WIN0_UV_SWAP(win->area[0].swap_uv);
1100                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0 + off, mask, val);
1101
1102                 mask = m_WIN0_BIC_COE_SEL |
1103                     m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
1104                     m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT2 |
1105                     m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
1106                     m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
1107                     m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
1108                     m_WIN0_CBR_VER_SCL_MODE | m_WIN0_CBR_HSD_MODE |
1109                     m_WIN0_CBR_VSU_MODE | m_WIN0_CBR_VSD_MODE;
1110                 val = v_WIN0_BIC_COE_SEL(win->bic_coe_el) |
1111                     v_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
1112                     v_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
1113                     v_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
1114                     v_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
1115                     v_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
1116                     v_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
1117                     v_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
1118                     v_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
1119                     v_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
1120                     v_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
1121                     v_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
1122                     v_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
1123                     v_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
1124                     v_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
1125                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL1 + off, mask, val);
1126                 val = v_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
1127                     v_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
1128                 lcdc_writel(lcdc_dev, WIN0_VIR + off, val);
1129                 /*lcdc_writel(lcdc_dev, WIN0_YRGB_MST+off,
1130                                 win->area[0].y_addr);
1131                    lcdc_writel(lcdc_dev, WIN0_CBR_MST+off,
1132                                 win->area[0].uv_addr); */
1133                 val = v_WIN0_ACT_WIDTH(win->area[0].xact) |
1134                     v_WIN0_ACT_HEIGHT(win->area[0].yact);
1135                 lcdc_writel(lcdc_dev, WIN0_ACT_INFO + off, val);
1136
1137                 val = v_WIN0_DSP_WIDTH(win->area[0].xsize) |
1138                     v_WIN0_DSP_HEIGHT(win->area[0].ysize);
1139                 lcdc_writel(lcdc_dev, WIN0_DSP_INFO + off, val);
1140
1141                 val = v_WIN0_DSP_XST(win->area[0].dsp_stx) |
1142                     v_WIN0_DSP_YST(win->area[0].dsp_sty);
1143                 lcdc_writel(lcdc_dev, WIN0_DSP_ST + off, val);
1144
1145                 val = v_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
1146                     v_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
1147                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB + off, val);
1148
1149                 val = v_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
1150                     v_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
1151                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR + off, val);
1152                 if (win->alpha_en == 1) {
1153                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1154                 } else {
1155                         mask = m_WIN0_SRC_ALPHA_EN;
1156                         val = v_WIN0_SRC_ALPHA_EN(0);
1157                         lcdc_msk_reg(lcdc_dev, WIN0_SRC_ALPHA_CTRL + off,
1158                                      mask, val);
1159                 }
1160         } else {
1161                 mask = m_WIN0_EN;
1162                 val = v_WIN0_EN(win->state);
1163                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0 + off, mask, val);
1164         }
1165         return 0;
1166 }
1167
1168 static int rk3368_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1169 {
1170         struct lcdc_device *lcdc_dev =
1171             container_of(dev_drv, struct lcdc_device, driver);
1172         struct rk_lcdc_win *win = dev_drv->win[win_id];
1173         unsigned int mask, val, off;
1174
1175         off = (win_id - 2) * 0x50;
1176         rk3368_lcdc_area_xst(win, win->area_num);
1177
1178         if (win->state == 1) {
1179                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1180                 if (win->area[0].fbdc_en) {
1181                         rk3368_fbdc_reg_update(&lcdc_dev->driver, win_id);
1182                 } else {
1183                         mask = m_IFBDC_CTRL_FBDC_EN;
1184                         val = v_IFBDC_CTRL_FBDC_EN(0);
1185                         lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
1186                 }
1187
1188                 mask = m_WIN2_EN | m_WIN2_CSC_MODE;
1189                 val = v_WIN2_EN(1) | v_WIN1_CSC_MODE(win->csc_mode);
1190                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1191                 /*area 0 */
1192                 if (win->area[0].state == 1) {
1193                         mask = m_WIN2_MST0_EN | m_WIN2_DATA_FMT0 |
1194                             m_WIN2_RB_SWAP0;
1195                         val = v_WIN2_MST0_EN(win->area[0].state) |
1196                             v_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
1197                             v_WIN2_RB_SWAP0(win->area[0].swap_rb);
1198                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1199
1200                         mask = m_WIN2_VIR_STRIDE0;
1201                         val = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
1202                         lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
1203
1204                         /*lcdc_writel(lcdc_dev,WIN2_MST0+off,
1205                            win->area[0].y_addr); */
1206                         val = v_WIN2_DSP_WIDTH0(win->area[0].xsize) |
1207                             v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
1208                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO0 + off, val);
1209                         val = v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
1210                             v_WIN2_DSP_YST0(win->area[0].dsp_sty);
1211                         lcdc_writel(lcdc_dev, WIN2_DSP_ST0 + off, val);
1212                 } else {
1213                         mask = m_WIN2_MST0_EN;
1214                         val = v_WIN2_MST0_EN(0);
1215                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1216                 }
1217                 /*area 1 */
1218                 if (win->area[1].state == 1) {
1219                         /*rk3368_win_area_check_var(win_id, 1,
1220                                                   &win->area[0], &win->area[1]);
1221                         */
1222
1223                         mask = m_WIN2_MST1_EN | m_WIN2_DATA_FMT1 |
1224                             m_WIN2_RB_SWAP1;
1225                         val = v_WIN2_MST1_EN(win->area[1].state) |
1226                             v_WIN2_DATA_FMT1(win->area[1].fmt_cfg) |
1227                             v_WIN2_RB_SWAP1(win->area[1].swap_rb);
1228                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1229
1230                         mask = m_WIN2_VIR_STRIDE1;
1231                         val = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
1232                         lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
1233
1234                         /*lcdc_writel(lcdc_dev,WIN2_MST1+off,
1235                            win->area[1].y_addr); */
1236                         val = v_WIN2_DSP_WIDTH1(win->area[1].xsize) |
1237                             v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
1238                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO1 + off, val);
1239                         val = v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
1240                             v_WIN2_DSP_YST1(win->area[1].dsp_sty);
1241                         lcdc_writel(lcdc_dev, WIN2_DSP_ST1 + off, val);
1242                 } else {
1243                         mask = m_WIN2_MST1_EN;
1244                         val = v_WIN2_MST1_EN(0);
1245                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1246                 }
1247                 /*area 2 */
1248                 if (win->area[2].state == 1) {
1249                         /*rk3368_win_area_check_var(win_id, 2,
1250                                                   &win->area[1], &win->area[2]);
1251                         */
1252
1253                         mask = m_WIN2_MST2_EN | m_WIN2_DATA_FMT2 |
1254                             m_WIN2_RB_SWAP2;
1255                         val = v_WIN2_MST2_EN(win->area[2].state) |
1256                             v_WIN2_DATA_FMT2(win->area[2].fmt_cfg) |
1257                             v_WIN2_RB_SWAP2(win->area[2].swap_rb);
1258                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1259
1260                         mask = m_WIN2_VIR_STRIDE2;
1261                         val = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
1262                         lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
1263
1264                         /*lcdc_writel(lcdc_dev,WIN2_MST2+off,
1265                            win->area[2].y_addr); */
1266                         val = v_WIN2_DSP_WIDTH2(win->area[2].xsize) |
1267                             v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
1268                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO2 + off, val);
1269                         val = v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
1270                             v_WIN2_DSP_YST2(win->area[2].dsp_sty);
1271                         lcdc_writel(lcdc_dev, WIN2_DSP_ST2 + off, val);
1272                 } else {
1273                         mask = m_WIN2_MST2_EN;
1274                         val = v_WIN2_MST2_EN(0);
1275                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1276                 }
1277                 /*area 3 */
1278                 if (win->area[3].state == 1) {
1279                         /*rk3368_win_area_check_var(win_id, 3,
1280                                                   &win->area[2], &win->area[3]);
1281                         */
1282
1283                         mask = m_WIN2_MST3_EN | m_WIN2_DATA_FMT3 |
1284                             m_WIN2_RB_SWAP3;
1285                         val = v_WIN2_MST3_EN(win->area[3].state) |
1286                             v_WIN2_DATA_FMT3(win->area[3].fmt_cfg) |
1287                             v_WIN2_RB_SWAP3(win->area[3].swap_rb);
1288                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1289
1290                         mask = m_WIN2_VIR_STRIDE3;
1291                         val = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
1292                         lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
1293
1294                         /*lcdc_writel(lcdc_dev,WIN2_MST3+off,
1295                            win->area[3].y_addr); */
1296                         val = v_WIN2_DSP_WIDTH3(win->area[3].xsize) |
1297                             v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
1298                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO3 + off, val);
1299                         val = v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
1300                             v_WIN2_DSP_YST3(win->area[3].dsp_sty);
1301                         lcdc_writel(lcdc_dev, WIN2_DSP_ST3 + off, val);
1302                 } else {
1303                         mask = m_WIN2_MST3_EN;
1304                         val = v_WIN2_MST3_EN(0);
1305                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1306                 }
1307
1308                 if (win->alpha_en == 1) {
1309                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1310                 } else {
1311                         mask = m_WIN2_SRC_ALPHA_EN;
1312                         val = v_WIN2_SRC_ALPHA_EN(0);
1313                         lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL + off,
1314                                      mask, val);
1315                 }
1316         } else {
1317                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
1318                     m_WIN2_MST0_EN | m_WIN2_MST2_EN | m_WIN2_MST3_EN;
1319                 val = v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
1320                     v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
1321                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1322         }
1323         return 0;
1324 }
1325
1326 static int rk3368_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1327 {
1328         struct lcdc_device *lcdc_dev =
1329             container_of(dev_drv, struct lcdc_device, driver);
1330         struct rk_lcdc_win *win = dev_drv->win[win_id];
1331         unsigned int mask, val, hwc_size = 0;
1332
1333         if (win->state == 1) {
1334                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1335                 mask = m_HWC_EN | m_HWC_DATA_FMT |
1336                     m_HWC_RB_SWAP | m_WIN0_CSC_MODE;
1337                 val = v_HWC_EN(1) | v_HWC_DATA_FMT(win->area[0].fmt_cfg) |
1338                     v_HWC_RB_SWAP(win->area[0].swap_rb) |
1339                     v_WIN0_CSC_MODE(win->csc_mode);
1340                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1341
1342                 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
1343                         hwc_size = 0;
1344                 else if ((win->area[0].xsize == 64) &&
1345                          (win->area[0].ysize == 64))
1346                         hwc_size = 1;
1347                 else if ((win->area[0].xsize == 96) &&
1348                          (win->area[0].ysize == 96))
1349                         hwc_size = 2;
1350                 else if ((win->area[0].xsize == 128) &&
1351                          (win->area[0].ysize == 128))
1352                         hwc_size = 3;
1353                 else
1354                         dev_err(lcdc_dev->dev, "un supported hwc size!\n");
1355
1356                 mask = m_HWC_SIZE;
1357                 val = v_HWC_SIZE(hwc_size);
1358                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1359
1360                 mask = m_HWC_DSP_XST | m_HWC_DSP_YST;
1361                 val = v_HWC_DSP_XST(win->area[0].dsp_stx) |
1362                     v_HWC_DSP_YST(win->area[0].dsp_sty);
1363                 lcdc_msk_reg(lcdc_dev, HWC_DSP_ST, mask, val);
1364
1365                 if (win->alpha_en == 1) {
1366                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1367                 } else {
1368                         mask = m_WIN2_SRC_ALPHA_EN;
1369                         val = v_WIN2_SRC_ALPHA_EN(0);
1370                         lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL, mask, val);
1371                 }
1372         } else {
1373                 mask = m_HWC_EN;
1374                 val = v_HWC_EN(win->state);
1375                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1376         }
1377         return 0;
1378 }
1379
1380 static int rk3368_lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
1381                                          struct rk_lcdc_win *win)
1382 {
1383         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
1384         int timeout;
1385         unsigned long flags;
1386
1387         spin_lock(&lcdc_dev->reg_lock);
1388         if (likely(lcdc_dev->clk_on)) {
1389                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
1390                              v_STANDBY_EN(lcdc_dev->standby));
1391                 if ((win->id == 0) || (win->id == 1))
1392                         rk3368_win_0_1_reg_update(dev_drv, win->id);
1393                 else if ((win->id == 2) || (win->id == 3))
1394                         rk3368_win_2_3_reg_update(dev_drv, win->id);
1395                 else if (win->id == 4)
1396                         rk3368_hwc_reg_update(dev_drv, win->id);
1397                 /*rk3368_lcdc_post_cfg(dev_drv); */
1398                 lcdc_cfg_done(lcdc_dev);
1399         }
1400         spin_unlock(&lcdc_dev->reg_lock);
1401
1402         /*if (dev_drv->wait_fs) { */
1403         if (0) {
1404                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
1405                 init_completion(&dev_drv->frame_done);
1406                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
1407                 timeout =
1408                     wait_for_completion_timeout(&dev_drv->frame_done,
1409                                                 msecs_to_jiffies
1410                                                 (dev_drv->cur_screen->ft + 5));
1411                 if (!timeout && (!dev_drv->frame_done.done)) {
1412                         dev_warn(lcdc_dev->dev,
1413                                  "wait for new frame start time out!\n");
1414                         return -ETIMEDOUT;
1415                 }
1416         }
1417         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
1418         return 0;
1419 }
1420
1421 static int rk3368_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
1422 {
1423         memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0x270);
1424         return 0;
1425 }
1426
1427 static int __maybe_unused rk3368_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
1428 {
1429         u32 mask, val;
1430         struct lcdc_device *lcdc_dev =
1431             container_of(dev_drv, struct lcdc_device, driver);
1432
1433 #if defined(CONFIG_ROCKCHIP_IOMMU)
1434         if (dev_drv->iommu_enabled) {
1435                 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
1436                         if (likely(lcdc_dev->clk_on)) {
1437                                 mask = m_MMU_EN;
1438                                 val = v_MMU_EN(1);
1439                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1440                                 mask = m_AXI_MAX_OUTSTANDING_EN |
1441                                         m_AXI_OUTSTANDING_MAX_NUM;
1442                                 val = v_AXI_OUTSTANDING_MAX_NUM(31) |
1443                                         v_AXI_MAX_OUTSTANDING_EN(1);
1444                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL1, mask, val);
1445                         }
1446                         lcdc_dev->iommu_status = 1;
1447                         rockchip_iovmm_activate(dev_drv->dev);
1448                 }
1449         }
1450 #endif
1451         return 0;
1452 }
1453
1454 static int rk3368_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
1455 {
1456         int ret = 0, fps = 0;
1457         struct lcdc_device *lcdc_dev =
1458             container_of(dev_drv, struct lcdc_device, driver);
1459         struct rk_screen *screen = dev_drv->cur_screen;
1460 #ifdef CONFIG_RK_FPGA
1461         return 0;
1462 #endif
1463         if (reset_rate)
1464                 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);/*set pll */
1465         if (ret)
1466                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
1467         lcdc_dev->pixclock =
1468             div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1469         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
1470
1471         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
1472         screen->ft = 1000 / fps;
1473         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
1474                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
1475         return 0;
1476 }
1477
1478 static int rk3368_config_timing(struct rk_lcdc_driver *dev_drv)
1479 {
1480         struct lcdc_device *lcdc_dev =
1481             container_of(dev_drv, struct lcdc_device, driver);
1482         struct rk_screen *screen = dev_drv->cur_screen;
1483         u16 hsync_len = screen->mode.hsync_len;
1484         u16 left_margin = screen->mode.left_margin;
1485         u16 right_margin = screen->mode.right_margin;
1486         u16 vsync_len = screen->mode.vsync_len;
1487         u16 upper_margin = screen->mode.upper_margin;
1488         u16 lower_margin = screen->mode.lower_margin;
1489         u16 x_res = screen->mode.xres;
1490         u16 y_res = screen->mode.yres;
1491         u32 mask, val;
1492         u16 h_total, v_total;
1493         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
1494
1495         h_total = hsync_len + left_margin + x_res + right_margin;
1496         v_total = vsync_len + upper_margin + y_res + lower_margin;
1497
1498         mask = m_DSP_HS_PW | m_DSP_HTOTAL;
1499         val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
1500         lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
1501
1502         mask = m_DSP_HACT_END | m_DSP_HACT_ST;
1503         val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
1504             v_DSP_HACT_ST(hsync_len + left_margin);
1505         lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
1506
1507         if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1508                 /* First Field Timing */
1509                 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
1510                 val = v_DSP_VS_PW(vsync_len) |
1511                     v_DSP_VTOTAL(2 * (vsync_len + upper_margin +
1512                                       lower_margin) + y_res + 1);
1513                 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
1514
1515                 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
1516                 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
1517                     v_DSP_VACT_ST(vsync_len + upper_margin);
1518                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
1519
1520                 /* Second Field Timing */
1521                 mask = m_DSP_VS_ST_F1 | m_DSP_VS_END_F1;
1522                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
1523                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
1524                     lower_margin;
1525                 val = v_DSP_VS_ST_F1(vs_st_f1) | v_DSP_VS_END_F1(vs_end_f1);
1526                 lcdc_msk_reg(lcdc_dev, DSP_VS_ST_END_F1, mask, val);
1527
1528                 mask = m_DSP_VACT_END_F1 | m_DSP_VAC_ST_F1;
1529                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
1530                     lower_margin + 1;
1531                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
1532                     lower_margin + 1;
1533                 val =
1534                     v_DSP_VACT_END_F1(vact_end_f1) |
1535                     v_DSP_VAC_ST_F1(vact_st_f1);
1536                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END_F1, mask, val);
1537
1538                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1539                              m_DSP_INTERLACE | m_DSP_FIELD_POL,
1540                              v_DSP_INTERLACE(1) | v_DSP_FIELD_POL(0));
1541                 mask =
1542                     m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
1543                     m_WIN0_CBR_DEFLICK;
1544                 val =
1545                     v_WIN0_INTERLACE_READ(1) | v_WIN0_YRGB_DEFLICK(1) |
1546                     v_WIN0_CBR_DEFLICK(1);
1547                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1548
1549                 mask =
1550                     m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
1551                     m_WIN1_CBR_DEFLICK;
1552                 val =
1553                     v_WIN1_INTERLACE_READ(1) | v_WIN1_YRGB_DEFLICK(1) |
1554                     v_WIN1_CBR_DEFLICK(1);
1555                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1556
1557                 mask = m_WIN2_INTERLACE_READ;
1558                 val = v_WIN2_INTERLACE_READ(1);
1559                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1560
1561                 mask = m_WIN3_INTERLACE_READ;
1562                 val = v_WIN3_INTERLACE_READ(1);
1563                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1564
1565                 mask = m_HWC_INTERLACE_READ;
1566                 val = v_HWC_INTERLACE_READ(1);
1567                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1568
1569                 mask = m_DSP_LINE_FLAG0_NUM | m_DSP_LINE_FLAG1_NUM;
1570                 val =
1571                     v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res / 2) |
1572                     v_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res / 2);
1573                 lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
1574         } else {
1575                 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
1576                 val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
1577                 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
1578
1579                 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
1580                 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
1581                     v_DSP_VACT_ST(vsync_len + upper_margin);
1582                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
1583
1584                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1585                              m_DSP_INTERLACE | m_DSP_FIELD_POL,
1586                              v_DSP_INTERLACE(0) | v_DSP_FIELD_POL(0));
1587
1588                 mask =
1589                     m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
1590                     m_WIN0_CBR_DEFLICK;
1591                 val =
1592                     v_WIN0_INTERLACE_READ(0) | v_WIN0_YRGB_DEFLICK(0) |
1593                     v_WIN0_CBR_DEFLICK(0);
1594                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1595
1596                 mask =
1597                     m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
1598                     m_WIN1_CBR_DEFLICK;
1599                 val =
1600                     v_WIN1_INTERLACE_READ(0) | v_WIN1_YRGB_DEFLICK(0) |
1601                     v_WIN1_CBR_DEFLICK(0);
1602                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1603
1604                 mask = m_WIN2_INTERLACE_READ;
1605                 val = v_WIN2_INTERLACE_READ(0);
1606                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1607
1608                 mask = m_WIN3_INTERLACE_READ;
1609                 val = v_WIN3_INTERLACE_READ(0);
1610                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1611
1612                 mask = m_HWC_INTERLACE_READ;
1613                 val = v_HWC_INTERLACE_READ(0);
1614                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1615
1616                 mask = m_DSP_LINE_FLAG0_NUM | m_DSP_LINE_FLAG1_NUM;
1617                 val = v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res) |
1618                         v_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res);
1619                 lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
1620         }
1621         rk3368_lcdc_post_cfg(dev_drv);
1622         return 0;
1623 }
1624
1625 static void rk3368_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1626 {
1627         struct lcdc_device *lcdc_dev =
1628             container_of(dev_drv, struct lcdc_device, driver);
1629         u32 bcsh_ctrl;
1630
1631         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_OVERLAY_MODE,
1632                      v_OVERLAY_MODE(dev_drv->overlay_mode));
1633         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1634                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1635                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1636                                      m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1637                                      v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1638                 else            /* YUV2RGB */
1639                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1640                                      m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1641                                      m_BCSH_R2Y_EN,
1642                                      v_BCSH_Y2R_EN(1) |
1643                                      v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1644                                      v_BCSH_R2Y_EN(0));
1645         } else {                /* overlay_mode=VOP_RGB_DOMAIN */
1646                 /* bypass  --need check,if bcsh close? */
1647                 if (dev_drv->output_color == COLOR_RGB) {
1648                         bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
1649                         if (((bcsh_ctrl & m_BCSH_EN) == 1) ||
1650                             (dev_drv->bcsh.enable == 1))/*bcsh enabled */
1651                                 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1652                                              m_BCSH_R2Y_EN |
1653                                              m_BCSH_Y2R_EN,
1654                                              v_BCSH_R2Y_EN(1) |
1655                                              v_BCSH_Y2R_EN(1));
1656                         else
1657                                 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1658                                              m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1659                                              v_BCSH_R2Y_EN(0) |
1660                                              v_BCSH_Y2R_EN(0));
1661                 } else          /* RGB2YUV */
1662                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1663                                      m_BCSH_R2Y_EN |
1664                                      m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1665                                      v_BCSH_R2Y_EN(1) |
1666                                      v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1667                                      v_BCSH_Y2R_EN(0));
1668         }
1669 }
1670
1671 static int rk3368_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1672                                   u16 *yact, int *format, u32 *dsp_addr)
1673 {
1674         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1675                                                     struct lcdc_device, driver);
1676         u32 val;
1677
1678         spin_lock(&lcdc_dev->reg_lock);
1679
1680         val = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1681         *xact = (val & m_WIN0_ACT_WIDTH) + 1;
1682         *yact = ((val & m_WIN0_ACT_HEIGHT)>>16) + 1;
1683
1684         val = lcdc_readl(lcdc_dev, WIN0_CTRL0);
1685         *format = (val & m_WIN0_DATA_FMT) >> 1;
1686         *dsp_addr = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1687
1688         spin_unlock(&lcdc_dev->reg_lock);
1689
1690         return 0;
1691 }
1692
1693 static int rk3368_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1694                               int format, u16 xact, u16 yact, u16 xvir)
1695 {
1696         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1697                                                     struct lcdc_device, driver);
1698         u32 val, mask;
1699         int swap = (format == RGB888) ? 1 : 0;
1700
1701         mask = m_WIN0_DATA_FMT | m_WIN0_RB_SWAP;
1702         val = v_WIN0_DATA_FMT(format) | v_WIN0_RB_SWAP(swap);
1703         lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1704
1705         lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_WIN0_VIR_STRIDE,
1706                         v_WIN0_VIR_STRIDE(xvir));
1707         lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_WIN0_ACT_WIDTH(xact) |
1708                     v_WIN0_ACT_HEIGHT(yact));
1709
1710         lcdc_writel(lcdc_dev, WIN0_YRGB_MST, rgb_mst);
1711
1712         lcdc_cfg_done(lcdc_dev);
1713
1714         return 0;
1715 }
1716
1717
1718 static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1719 {
1720         u16 face = 0;
1721         u16 dclk_ddr = 0;
1722         u32 v = 0;
1723         struct lcdc_device *lcdc_dev =
1724             container_of(dev_drv, struct lcdc_device, driver);
1725         struct rk_screen *screen = dev_drv->cur_screen;
1726         u32 mask, val;
1727
1728         spin_lock(&lcdc_dev->reg_lock);
1729         if (likely(lcdc_dev->clk_on)) {
1730                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1731                 if (!lcdc_dev->standby && !initscreen) {
1732                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
1733                                      v_STANDBY_EN(1));
1734                         lcdc_cfg_done(lcdc_dev);
1735                         mdelay(50);
1736                 }
1737                 switch (screen->face) {
1738                 case OUT_P565:
1739                         face = OUT_P565;
1740                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1741                             m_DITHER_DOWN_SEL;
1742                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1743                             v_DITHER_DOWN_SEL(1);
1744                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1745                         break;
1746                 case OUT_P666:
1747                         face = OUT_P666;
1748                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1749                             m_DITHER_DOWN_SEL;
1750                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1751                             v_DITHER_DOWN_SEL(1);
1752                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1753                         break;
1754                 case OUT_D888_P565:
1755                         face = OUT_P888;
1756                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1757                             m_DITHER_DOWN_SEL;
1758                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1759                             v_DITHER_DOWN_SEL(1);
1760                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1761                         break;
1762                 case OUT_D888_P666:
1763                         face = OUT_P888;
1764                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1765                             m_DITHER_DOWN_SEL;
1766                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1767                             v_DITHER_DOWN_SEL(1);
1768                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1769                         break;
1770                 case OUT_P888:
1771                         face = OUT_P888;
1772                         mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1773                         val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1774                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1775                         break;
1776                 case OUT_YUV_420:
1777                         /*yuv420 output prefer yuv domain overlay */
1778                         face = OUT_YUV_420;
1779                         dclk_ddr = 1;
1780                         mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1781                         val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1782                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1783                         break;
1784                 default:
1785                         dev_err(lcdc_dev->dev, "un supported interface!\n");
1786                         break;
1787                 }
1788                 switch (screen->type) {
1789                 case SCREEN_RGB:
1790                         mask = m_RGB_OUT_EN;
1791                         val = v_RGB_OUT_EN(1);
1792                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1793                         mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
1794                             m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
1795                         val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
1796                             v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
1797                             v_RGB_LVDS_DEN_POL(screen->pin_den) |
1798                             v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
1799                         v = 1 << 15 | (1 << (15 + 16));
1800
1801                         break;
1802                 case SCREEN_LVDS:
1803                         mask = m_RGB_OUT_EN;
1804                         val = v_RGB_OUT_EN(1);
1805                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1806                         mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
1807                             m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
1808                         val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
1809                             v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
1810                             v_RGB_LVDS_DEN_POL(screen->pin_den) |
1811                             v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
1812                         v = 0 << 15 | (1 << (15 + 16));
1813                         break;
1814                 case SCREEN_HDMI:
1815                         /*face = OUT_RGB_AAA;*/
1816                         if (screen->color_mode == COLOR_RGB)
1817                                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1818                         else
1819                                 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1820                         mask = m_HDMI_OUT_EN  | m_RGB_OUT_EN;
1821                         val = v_HDMI_OUT_EN(1) | v_RGB_OUT_EN(0);
1822                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1823                         mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1824                             m_HDMI_DEN_POL | m_HDMI_DCLK_POL;
1825                         val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1826                             v_HDMI_VSYNC_POL(screen->pin_vsync) |
1827                             v_HDMI_DEN_POL(screen->pin_den) |
1828                             v_HDMI_DCLK_POL(screen->pin_dclk);
1829                         break;
1830                 case SCREEN_MIPI:
1831                         mask = m_MIPI_OUT_EN  | m_RGB_OUT_EN;
1832                         val = v_MIPI_OUT_EN(1) | v_RGB_OUT_EN(0);
1833                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1834                         mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
1835                             m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
1836                         val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
1837                             v_MIPI_VSYNC_POL(screen->pin_vsync) |
1838                             v_MIPI_DEN_POL(screen->pin_den) |
1839                             v_MIPI_DCLK_POL(screen->pin_dclk);
1840                         break;
1841                 case SCREEN_DUAL_MIPI:
1842                         mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN  |
1843                                 m_RGB_OUT_EN;
1844                         val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1) |
1845                                 v_RGB_OUT_EN(0);
1846                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1847                         mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
1848                             m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
1849                         val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
1850                             v_MIPI_VSYNC_POL(screen->pin_vsync) |
1851                             v_MIPI_DEN_POL(screen->pin_den) |
1852                             v_MIPI_DCLK_POL(screen->pin_dclk);
1853                         break;
1854                 case SCREEN_EDP:
1855                         face = OUT_P888;        /*RGB 888 output */
1856
1857                         mask = m_EDP_OUT_EN | m_RGB_OUT_EN;
1858                         val = v_EDP_OUT_EN(1) | v_RGB_OUT_EN(0);
1859                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1860                         /*because edp have to sent aaa fmt */
1861                         mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1862                         val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1863
1864                         mask |= m_EDP_HSYNC_POL | m_EDP_VSYNC_POL |
1865                             m_EDP_DEN_POL | m_EDP_DCLK_POL;
1866                         val |= v_EDP_HSYNC_POL(screen->pin_hsync) |
1867                             v_EDP_VSYNC_POL(screen->pin_vsync) |
1868                             v_EDP_DEN_POL(screen->pin_den) |
1869                             v_EDP_DCLK_POL(screen->pin_dclk);
1870                         break;
1871                 }
1872                 /*hsync vsync den dclk polo,dither */
1873                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1874 #ifndef CONFIG_RK_FPGA
1875                 /*writel_relaxed(v, RK_GRF_VIRT + rk3368_GRF_SOC_CON7);
1876                 move to  lvds driver*/
1877                 /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
1878 #endif
1879                 mask = m_DSP_OUT_MODE | m_DSP_DCLK_DDR | m_DSP_BG_SWAP |
1880                     m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1881                     m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN |
1882                     m_DSP_BLACK_EN | m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN;
1883                 val = v_DSP_OUT_MODE(face) | v_DSP_DCLK_DDR(dclk_ddr) |
1884                     v_DSP_BG_SWAP(screen->swap_gb) |
1885                     v_DSP_RB_SWAP(screen->swap_rb) |
1886                     v_DSP_RG_SWAP(screen->swap_rg) |
1887                     v_DSP_DELTA_SWAP(screen->swap_delta) |
1888                     v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) |
1889                     v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0) |
1890                     v_DSP_X_MIR_EN(screen->x_mirror) |
1891                     v_DSP_Y_MIR_EN(screen->y_mirror);
1892                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1893                 /*BG color */
1894                 mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
1895                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN)
1896                         val = v_DSP_BG_BLUE(0x80) | v_DSP_BG_GREEN(0x10) |
1897                                 v_DSP_BG_RED(0x80);
1898                 else
1899                         val = v_DSP_BG_BLUE(0) | v_DSP_BG_GREEN(0) |
1900                                 v_DSP_BG_RED(0);
1901                 lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
1902                 dev_drv->output_color = screen->color_mode;
1903                 if (screen->dsp_lut == NULL)
1904                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
1905                                      v_DSP_LUT_EN(0));
1906                 else
1907                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
1908                                      v_DSP_LUT_EN(1));
1909                 if (screen->cabc_lut == NULL) {
1910                         lcdc_msk_reg(lcdc_dev, CABC_CTRL0, m_CABC_EN,
1911                                      v_CABC_EN(0));
1912                 } else {
1913                         lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
1914                                      v_CABC_LUT_EN(1));
1915                 }
1916                 rk3368_lcdc_bcsh_path_sel(dev_drv);
1917                 rk3368_config_timing(dev_drv);
1918         }
1919         spin_unlock(&lcdc_dev->reg_lock);
1920         rk3368_lcdc_set_dclk(dev_drv, 1);
1921         if (screen->type != SCREEN_HDMI && dev_drv->trsm_ops &&
1922             dev_drv->trsm_ops->enable)
1923                 dev_drv->trsm_ops->enable();
1924         if (screen->init)
1925                 screen->init();
1926         if (!lcdc_dev->standby)
1927                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(0));
1928         return 0;
1929 }
1930
1931
1932 /*enable layer,open:1,enable;0 disable*/
1933 static void rk3368_lcdc_layer_enable(struct lcdc_device *lcdc_dev,
1934                                      unsigned int win_id, bool open)
1935 {
1936         spin_lock(&lcdc_dev->reg_lock);
1937         if (likely(lcdc_dev->clk_on) &&
1938             lcdc_dev->driver.win[win_id]->state != open) {
1939                 if (open) {
1940                         if (!lcdc_dev->atv_layer_cnt) {
1941                                 dev_info(lcdc_dev->dev,
1942                                          "wakeup from standby!\n");
1943                                 lcdc_dev->standby = 0;
1944                         }
1945                         lcdc_dev->atv_layer_cnt |= (1 << win_id);
1946                 } else {
1947                         if (lcdc_dev->atv_layer_cnt & (1 << win_id))
1948                                 lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
1949                 }
1950                 lcdc_dev->driver.win[win_id]->state = open;
1951                 if (!open) {
1952                         /*rk3368_lcdc_reg_update(dev_drv);*/
1953                         rk3368_lcdc_layer_update_regs
1954                         (lcdc_dev, lcdc_dev->driver.win[win_id]);
1955                         lcdc_cfg_done(lcdc_dev);
1956                 }
1957                 /*if no layer used,disable lcdc */
1958                 if (!lcdc_dev->atv_layer_cnt) {
1959                         dev_info(lcdc_dev->dev,
1960                                  "no layer is used,go to standby!\n");
1961                         lcdc_dev->standby = 1;
1962                 }
1963         }
1964         spin_unlock(&lcdc_dev->reg_lock);
1965 }
1966
1967 static int rk3368_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
1968 {
1969         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1970                                                     struct lcdc_device, driver);
1971         u32 mask, val;
1972         /*struct rk_screen *screen = dev_drv->cur_screen; */
1973
1974         mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR | m_LINE_FLAG0_INTR_CLR |
1975             m_LINE_FLAG1_INTR_CLR;
1976         val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) |
1977             v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1);
1978         lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val);
1979
1980         mask = m_FS_INTR_EN | m_LINE_FLAG0_INTR_EN |
1981                 m_BUS_ERROR_INTR_EN | m_LINE_FLAG1_INTR_EN;
1982         val = v_FS_INTR_EN(1) | v_LINE_FLAG0_INTR_EN(1) |
1983             v_BUS_ERROR_INTR_EN(1) | v_LINE_FLAG1_INTR_EN(0);
1984         lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
1985
1986 #ifdef LCDC_IRQ_EMPTY_DEBUG
1987         mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
1988             m_WIN2_EMPTY_INTR_EN |
1989             m_WIN3_EMPTY_INTR_EN | m_HWC_EMPTY_INTR_EN |
1990             m_POST_BUF_EMPTY_INTR_EN | m_PWM_GEN_INTR_EN;
1991         val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) |
1992             v_WIN2_EMPTY_INTR_EN(1) |
1993             v_WIN3_EMPTY_INTR_EN(1) | v_HWC_EMPTY_INTR_EN(1) |
1994             v_POST_BUF_EMPTY_INTR_EN(1) | v_PWM_GEN_INTR_EN(1);
1995         lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
1996 #endif
1997         return 0;
1998 }
1999
2000 static int rk3368_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
2001                             bool open)
2002 {
2003         struct lcdc_device *lcdc_dev =
2004             container_of(dev_drv, struct lcdc_device, driver);
2005 #if 0/*ndef CONFIG_RK_FPGA*/
2006         int sys_status =
2007             (dev_drv->id == 0) ? SYS_STATUS_LCDC0 : SYS_STATUS_LCDC1;
2008 #endif
2009         /*enable clk,when first layer open */
2010         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
2011                 /*rockchip_set_system_status(sys_status);*/
2012                 rk3368_lcdc_pre_init(dev_drv);
2013                 rk3368_lcdc_clk_enable(lcdc_dev);
2014 #if defined(CONFIG_ROCKCHIP_IOMMU)
2015                 if (dev_drv->iommu_enabled) {
2016                         if (!dev_drv->mmu_dev) {
2017                                 dev_drv->mmu_dev =
2018                                     rk_fb_get_sysmmu_device_by_compatible
2019                                     (dev_drv->mmu_dts_name);
2020                                 if (dev_drv->mmu_dev) {
2021                                         rk_fb_platform_set_sysmmu
2022                                             (dev_drv->mmu_dev, dev_drv->dev);
2023                                 } else {
2024                                         dev_err(dev_drv->dev,
2025                                                 "fail get rk iommu device\n");
2026                                         return -1;
2027                                 }
2028                         }
2029                         /*if (dev_drv->mmu_dev)
2030                            rockchip_iovmm_activate(dev_drv->dev); */
2031                 }
2032 #endif
2033                 rk3368_lcdc_reg_restore(lcdc_dev);
2034                 /*if (dev_drv->iommu_enabled)
2035                    rk3368_lcdc_mmu_en(dev_drv); */
2036                 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
2037                         rk3368_lcdc_set_dclk(dev_drv, 0);
2038                         rk3368_lcdc_enable_irq(dev_drv);
2039                 } else {
2040                         rk3368_load_screen(dev_drv, 1);
2041                 }
2042                 if (dev_drv->bcsh.enable)
2043                         rk3368_lcdc_set_bcsh(dev_drv, 1);
2044                 spin_lock(&lcdc_dev->reg_lock);
2045                 if (dev_drv->cur_screen->dsp_lut)
2046                         rk3368_lcdc_set_lut(dev_drv,
2047                                             dev_drv->cur_screen->dsp_lut);
2048                 if (dev_drv->cur_screen->cabc_lut)
2049                         rk3368_set_cabc_lut(dev_drv,
2050                                             dev_drv->cur_screen->cabc_lut);
2051                 spin_unlock(&lcdc_dev->reg_lock);
2052         }
2053
2054         if (win_id < ARRAY_SIZE(lcdc_win))
2055                 rk3368_lcdc_layer_enable(lcdc_dev, win_id, open);
2056         else
2057                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
2058
2059
2060         /* when all layer closed,disable clk */
2061         /*if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
2062            rk3368_lcdc_disable_irq(lcdc_dev);
2063            rk3368_lcdc_reg_update(dev_drv);
2064            #if defined(CONFIG_ROCKCHIP_IOMMU)
2065            if (dev_drv->iommu_enabled) {
2066            if (dev_drv->mmu_dev)
2067            rockchip_iovmm_deactivate(dev_drv->dev);
2068            }
2069            #endif
2070            rk3368_lcdc_clk_disable(lcdc_dev);
2071            #ifndef CONFIG_RK_FPGA
2072            rockchip_clear_system_status(sys_status);
2073            #endif
2074            } */
2075
2076         return 0;
2077 }
2078
2079 static int win_0_1_display(struct lcdc_device *lcdc_dev,
2080                            struct rk_lcdc_win *win)
2081 {
2082         u32 y_addr;
2083         u32 uv_addr;
2084         unsigned int off;
2085
2086         off = win->id * 0x40;
2087         /*win->smem_start + win->y_offset; */
2088         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2089         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
2090         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
2091             lcdc_dev->id, win->id, y_addr, uv_addr);
2092         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
2093             win->area[0].y_offset, win->area[0].c_offset);
2094         spin_lock(&lcdc_dev->reg_lock);
2095         if (likely(lcdc_dev->clk_on)) {
2096                 win->area[0].y_addr = y_addr;
2097                 win->area[0].uv_addr = uv_addr;
2098                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
2099                 lcdc_writel(lcdc_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
2100                 if (win->area[0].fbdc_en == 1)
2101                         lcdc_writel(lcdc_dev, IFBDC_BASE_ADDR,
2102                                         win->area[0].y_addr);
2103         }
2104         spin_unlock(&lcdc_dev->reg_lock);
2105
2106         return 0;
2107 }
2108
2109 static int win_2_3_display(struct lcdc_device *lcdc_dev,
2110                            struct rk_lcdc_win *win)
2111 {
2112         u32 i, y_addr;
2113         unsigned int off;
2114
2115         off = (win->id - 2) * 0x50;
2116         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2117         DBG(2, "lcdc[%d]:win[%d]:", lcdc_dev->id, win->id);
2118
2119         spin_lock(&lcdc_dev->reg_lock);
2120         if (likely(lcdc_dev->clk_on)) {
2121                 for (i = 0; i < win->area_num; i++) {
2122                         DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
2123                             i, win->area[i].y_addr, win->area[i].y_offset);
2124                         win->area[i].y_addr =
2125                             win->area[i].smem_start + win->area[i].y_offset;
2126                         }
2127                 lcdc_writel(lcdc_dev, WIN2_MST0 + off, win->area[0].y_addr);
2128                 lcdc_writel(lcdc_dev, WIN2_MST1 + off, win->area[1].y_addr);
2129                 lcdc_writel(lcdc_dev, WIN2_MST2 + off, win->area[2].y_addr);
2130                 lcdc_writel(lcdc_dev, WIN2_MST3 + off, win->area[3].y_addr);
2131                 if (win->area[0].fbdc_en == 1)
2132                         lcdc_writel(lcdc_dev, IFBDC_BASE_ADDR,
2133                                         win->area[0].y_addr);
2134         }
2135         spin_unlock(&lcdc_dev->reg_lock);
2136         return 0;
2137 }
2138
2139 static int hwc_display(struct lcdc_device *lcdc_dev, struct rk_lcdc_win *win)
2140 {
2141         u32 y_addr;
2142
2143         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2144         DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
2145             lcdc_dev->id, __func__, y_addr);
2146         spin_lock(&lcdc_dev->reg_lock);
2147         if (likely(lcdc_dev->clk_on)) {
2148                 win->area[0].y_addr = y_addr;
2149                 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
2150         }
2151         spin_unlock(&lcdc_dev->reg_lock);
2152
2153         return 0;
2154 }
2155
2156 static int rk3368_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
2157 {
2158         struct lcdc_device *lcdc_dev =
2159             container_of(dev_drv, struct lcdc_device, driver);
2160         struct rk_lcdc_win *win = NULL;
2161         struct rk_screen *screen = dev_drv->cur_screen;
2162
2163 #if defined(WAIT_FOR_SYNC)
2164         int timeout;
2165         unsigned long flags;
2166 #endif
2167         win = dev_drv->win[win_id];
2168         if (!screen) {
2169                 dev_err(dev_drv->dev, "screen is null!\n");
2170                 return -ENOENT;
2171         }
2172         if (win_id == 0) {
2173                 win_0_1_display(lcdc_dev, win);
2174         } else if (win_id == 1) {
2175                 win_0_1_display(lcdc_dev, win);
2176         } else if (win_id == 2) {
2177                 win_2_3_display(lcdc_dev, win);
2178         } else if (win_id == 3) {
2179                 win_2_3_display(lcdc_dev, win);
2180         } else if (win_id == 4) {
2181                 hwc_display(lcdc_dev, win);
2182         } else {
2183                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
2184                 return -EINVAL;
2185         }
2186
2187         /*this is the first frame of the system ,enable frame start interrupt */
2188         if ((dev_drv->first_frame)) {
2189                 dev_drv->first_frame = 0;
2190                 rk3368_lcdc_enable_irq(dev_drv);
2191         }
2192 #if defined(WAIT_FOR_SYNC)
2193         spin_lock_irqsave(&dev_drv->cpl_lock, flags);
2194         init_completion(&dev_drv->frame_done);
2195         spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
2196         timeout =
2197             wait_for_completion_timeout(&dev_drv->frame_done,
2198                                         msecs_to_jiffies(dev_drv->
2199                                                          cur_screen->ft + 5));
2200         if (!timeout && (!dev_drv->frame_done.done)) {
2201                 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
2202                 return -ETIMEDOUT;
2203         }
2204 #endif
2205         return 0;
2206 }
2207
2208 static int rk3368_lcdc_cal_scl_fac(struct rk_lcdc_win *win)
2209 {
2210         u16 srcW;
2211         u16 srcH;
2212         u16 dstW;
2213         u16 dstH;
2214         u16 yrgb_srcW;
2215         u16 yrgb_srcH;
2216         u16 yrgb_dstW;
2217         u16 yrgb_dstH;
2218         u32 yrgb_vscalednmult;
2219         u32 yrgb_xscl_factor;
2220         u32 yrgb_yscl_factor;
2221         u8 yrgb_vsd_bil_gt2 = 0;
2222         u8 yrgb_vsd_bil_gt4 = 0;
2223
2224         u16 cbcr_srcW;
2225         u16 cbcr_srcH;
2226         u16 cbcr_dstW;
2227         u16 cbcr_dstH;
2228         u32 cbcr_vscalednmult;
2229         u32 cbcr_xscl_factor;
2230         u32 cbcr_yscl_factor;
2231         u8 cbcr_vsd_bil_gt2 = 0;
2232         u8 cbcr_vsd_bil_gt4 = 0;
2233         u8 yuv_fmt = 0;
2234
2235         srcW = win->area[0].xact;
2236         srcH = win->area[0].yact;
2237         dstW = win->area[0].xsize;
2238         dstH = win->area[0].ysize;
2239
2240         /*yrgb scl mode */
2241         yrgb_srcW = srcW;
2242         yrgb_srcH = srcH;
2243         yrgb_dstW = dstW;
2244         yrgb_dstH = dstH;
2245         if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
2246                 pr_err("ERROR: yrgb scale exceed 8,");
2247                 pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
2248                        yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
2249         }
2250         if (yrgb_srcW < yrgb_dstW)
2251                 win->yrgb_hor_scl_mode = SCALE_UP;
2252         else if (yrgb_srcW > yrgb_dstW)
2253                 win->yrgb_hor_scl_mode = SCALE_DOWN;
2254         else
2255                 win->yrgb_hor_scl_mode = SCALE_NONE;
2256
2257         if (yrgb_srcH < yrgb_dstH)
2258                 win->yrgb_ver_scl_mode = SCALE_UP;
2259         else if (yrgb_srcH > yrgb_dstH)
2260                 win->yrgb_ver_scl_mode = SCALE_DOWN;
2261         else
2262                 win->yrgb_ver_scl_mode = SCALE_NONE;
2263
2264         /*cbcr scl mode */
2265         switch (win->area[0].format) {
2266         case YUV422:
2267         case YUV422_A:
2268                 cbcr_srcW = srcW / 2;
2269                 cbcr_dstW = dstW;
2270                 cbcr_srcH = srcH;
2271                 cbcr_dstH = dstH;
2272                 yuv_fmt = 1;
2273                 break;
2274         case YUV420:
2275         case YUV420_A:
2276                 cbcr_srcW = srcW / 2;
2277                 cbcr_dstW = dstW;
2278                 cbcr_srcH = srcH / 2;
2279                 cbcr_dstH = dstH;
2280                 yuv_fmt = 1;
2281                 break;
2282         case YUV444:
2283         case YUV444_A:
2284                 cbcr_srcW = srcW;
2285                 cbcr_dstW = dstW;
2286                 cbcr_srcH = srcH;
2287                 cbcr_dstH = dstH;
2288                 yuv_fmt = 1;
2289                 break;
2290         default:
2291                 cbcr_srcW = 0;
2292                 cbcr_dstW = 0;
2293                 cbcr_srcH = 0;
2294                 cbcr_dstH = 0;
2295                 yuv_fmt = 0;
2296                 break;
2297         }
2298         if (yuv_fmt) {
2299                 if ((cbcr_dstW * 8 <= cbcr_srcW) ||
2300                     (cbcr_dstH * 8 <= cbcr_srcH)) {
2301                         pr_err("ERROR: cbcr scale exceed 8,");
2302                         pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
2303                                cbcr_srcH, cbcr_dstW, cbcr_dstH);
2304                 }
2305         }
2306
2307         if (cbcr_srcW < cbcr_dstW)
2308                 win->cbr_hor_scl_mode = SCALE_UP;
2309         else if (cbcr_srcW > cbcr_dstW)
2310                 win->cbr_hor_scl_mode = SCALE_DOWN;
2311         else
2312                 win->cbr_hor_scl_mode = SCALE_NONE;
2313
2314         if (cbcr_srcH < cbcr_dstH)
2315                 win->cbr_ver_scl_mode = SCALE_UP;
2316         else if (cbcr_srcH > cbcr_dstH)
2317                 win->cbr_ver_scl_mode = SCALE_DOWN;
2318         else
2319                 win->cbr_ver_scl_mode = SCALE_NONE;
2320
2321         /*DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
2322             "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
2323             "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n", srcW,
2324             srcH, dstW, dstH, yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH,
2325             win->yrgb_hor_scl_mode, win->yrgb_ver_scl_mode, cbcr_srcW,
2326             cbcr_srcH, cbcr_dstW, cbcr_dstH, win->cbr_hor_scl_mode,
2327             win->cbr_ver_scl_mode);*/
2328
2329         /*line buffer mode */
2330         if ((win->area[0].format == YUV422) ||
2331             (win->area[0].format == YUV420) ||
2332             (win->area[0].format == YUV422_A) ||
2333             (win->area[0].format == YUV420_A)) {
2334                 if (win->cbr_hor_scl_mode == SCALE_DOWN) {
2335                         if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
2336                             (cbcr_dstW == 0))
2337                                 pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
2338                                        cbcr_dstW);
2339                         else if (cbcr_dstW > 1280)
2340                                 win->win_lb_mode = LB_YUV_3840X5;
2341                         else
2342                                 win->win_lb_mode = LB_YUV_2560X8;
2343                 } else {        /*SCALE_UP or SCALE_NONE */
2344                         if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
2345                             (cbcr_srcW == 0))
2346                                 pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
2347                                        cbcr_srcW);
2348                         else if (cbcr_srcW > 1280)
2349                                 win->win_lb_mode = LB_YUV_3840X5;
2350                         else
2351                                 win->win_lb_mode = LB_YUV_2560X8;
2352                 }
2353         } else {
2354                 if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
2355                         if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
2356                             (yrgb_dstW == 0))
2357                                 pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
2358                         else if (yrgb_dstW > 2560)
2359                                 win->win_lb_mode = LB_RGB_3840X2;
2360                         else if (yrgb_dstW > 1920)
2361                                 win->win_lb_mode = LB_RGB_2560X4;
2362                         else if (yrgb_dstW > 1280)
2363                                 win->win_lb_mode = LB_RGB_1920X5;
2364                         else
2365                                 win->win_lb_mode = LB_RGB_1280X8;
2366                 } else {        /*SCALE_UP or SCALE_NONE */
2367                         if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
2368                             (yrgb_srcW == 0))
2369                                 pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
2370                         else if (yrgb_srcW > 2560)
2371                                 win->win_lb_mode = LB_RGB_3840X2;
2372                         else if (yrgb_srcW > 1920)
2373                                 win->win_lb_mode = LB_RGB_2560X4;
2374                         else if (yrgb_srcW > 1280)
2375                                 win->win_lb_mode = LB_RGB_1920X5;
2376                         else
2377                                 win->win_lb_mode = LB_RGB_1280X8;
2378                 }
2379         }
2380         DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
2381
2382         /*vsd/vsu scale ALGORITHM */
2383         win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2384         win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2385         win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2386         win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2387         switch (win->win_lb_mode) {
2388         case LB_YUV_3840X5:
2389         case LB_YUV_2560X8:
2390         case LB_RGB_1920X5:
2391         case LB_RGB_1280X8:
2392                 win->yrgb_vsu_mode = SCALE_UP_BIC;
2393                 win->cbr_vsu_mode = SCALE_UP_BIC;
2394                 break;
2395         case LB_RGB_3840X2:
2396                 if (win->yrgb_ver_scl_mode != SCALE_NONE)
2397                         pr_err("ERROR : not allow yrgb ver scale\n");
2398                 if (win->cbr_ver_scl_mode != SCALE_NONE)
2399                         pr_err("ERROR : not allow cbcr ver scale\n");
2400                 break;
2401         case LB_RGB_2560X4:
2402                 win->yrgb_vsu_mode = SCALE_UP_BIL;
2403                 win->cbr_vsu_mode = SCALE_UP_BIL;
2404                 break;
2405         default:
2406                 pr_info("%s:un supported win_lb_mode:%d\n",
2407                         __func__, win->win_lb_mode);
2408                 break;
2409         }
2410         if (win->mirror_en == 1) {      /*interlace mode must bill */
2411                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2412         }
2413
2414         if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
2415             (win->area[0].fbdc_en == 1)) {
2416                 /*in this pattern,use bil mode,not support souble scd,
2417                 use avg mode, support double scd, but aclk should be
2418                 bigger than dclk,aclk>>dclk */
2419                 if (yrgb_srcH >= 2 * yrgb_dstH) {
2420                         pr_err("ERROR : fbdc mode,not support y scale down:");
2421                         pr_err("srcH[%d] > 2 *dstH[%d]\n",
2422                                yrgb_srcH, yrgb_dstH);
2423                 }
2424         }
2425         DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
2426             win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
2427             win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
2428
2429         /*SCALE FACTOR */
2430
2431         /*(1.1)YRGB HOR SCALE FACTOR */
2432         switch (win->yrgb_hor_scl_mode) {
2433         case SCALE_NONE:
2434                 yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2435                 break;
2436         case SCALE_UP:
2437                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
2438                 break;
2439         case SCALE_DOWN:
2440                 switch (win->yrgb_hsd_mode) {
2441                 case SCALE_DOWN_BIL:
2442                         yrgb_xscl_factor =
2443                             GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
2444                         break;
2445                 case SCALE_DOWN_AVG:
2446                         yrgb_xscl_factor =
2447                             GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
2448                         break;
2449                 default:
2450                         pr_info(
2451                                 "%s:un supported yrgb_hsd_mode:%d\n", __func__,
2452                                win->yrgb_hsd_mode);
2453                         break;
2454                 }
2455                 break;
2456         default:
2457                 pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
2458                         __func__, win->yrgb_hor_scl_mode);
2459                 break;
2460         }                       /*win->yrgb_hor_scl_mode */
2461
2462         /*(1.2)YRGB VER SCALE FACTOR */
2463         switch (win->yrgb_ver_scl_mode) {
2464         case SCALE_NONE:
2465                 yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2466                 break;
2467         case SCALE_UP:
2468                 switch (win->yrgb_vsu_mode) {
2469                 case SCALE_UP_BIL:
2470                         yrgb_yscl_factor =
2471                             GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
2472                         break;
2473                 case SCALE_UP_BIC:
2474                         if (yrgb_srcH < 3) {
2475                                 pr_err("yrgb_srcH should be");
2476                                 pr_err(" greater than 3 !!!\n");
2477                         }
2478                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
2479                                                                 yrgb_dstH);
2480                         break;
2481                 default:
2482                         pr_info("%s:un support yrgb_vsu_mode:%d\n",
2483                                 __func__, win->yrgb_vsu_mode);
2484                         break;
2485                 }
2486                 break;
2487         case SCALE_DOWN:
2488                 switch (win->yrgb_vsd_mode) {
2489                 case SCALE_DOWN_BIL:
2490                         yrgb_vscalednmult =
2491                             rk3368_get_hard_ware_vskiplines(yrgb_srcH,
2492                                                             yrgb_dstH);
2493                         yrgb_yscl_factor =
2494                             GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
2495                                                            yrgb_vscalednmult);
2496                         if (yrgb_yscl_factor >= 0x2000) {
2497                                 pr_err("yrgb_yscl_factor should be ");
2498                                 pr_err("less than 0x2000,yrgb_yscl_factor=%4x;\n",
2499                                        yrgb_yscl_factor);
2500                         }
2501                         if (yrgb_vscalednmult == 4) {
2502                                 yrgb_vsd_bil_gt4 = 1;
2503                                 yrgb_vsd_bil_gt2 = 0;
2504                         } else if (yrgb_vscalednmult == 2) {
2505                                 yrgb_vsd_bil_gt4 = 0;
2506                                 yrgb_vsd_bil_gt2 = 1;
2507                         } else {
2508                                 yrgb_vsd_bil_gt4 = 0;
2509                                 yrgb_vsd_bil_gt2 = 0;
2510                         }
2511                         break;
2512                 case SCALE_DOWN_AVG:
2513                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
2514                                                                  yrgb_dstH);
2515                         break;
2516                 default:
2517                         pr_info("%s:un support yrgb_vsd_mode:%d\n",
2518                                 __func__, win->yrgb_vsd_mode);
2519                         break;
2520                 }               /*win->yrgb_vsd_mode */
2521                 break;
2522         default:
2523                 pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
2524                         __func__, win->yrgb_ver_scl_mode);
2525                 break;
2526         }
2527         win->scale_yrgb_x = yrgb_xscl_factor;
2528         win->scale_yrgb_y = yrgb_yscl_factor;
2529         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
2530         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
2531         DBG(1, "yrgb:h_fac=%d, v_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
2532             yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
2533
2534         /*(2.1)CBCR HOR SCALE FACTOR */
2535         switch (win->cbr_hor_scl_mode) {
2536         case SCALE_NONE:
2537                 cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2538                 break;
2539         case SCALE_UP:
2540                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
2541                 break;
2542         case SCALE_DOWN:
2543                 switch (win->cbr_hsd_mode) {
2544                 case SCALE_DOWN_BIL:
2545                         cbcr_xscl_factor =
2546                             GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
2547                         break;
2548                 case SCALE_DOWN_AVG:
2549                         cbcr_xscl_factor =
2550                             GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
2551                         break;
2552                 default:
2553                         pr_info("%s:un support cbr_hsd_mode:%d\n",
2554                                 __func__, win->cbr_hsd_mode);
2555                         break;
2556                 }
2557                 break;
2558         default:
2559                 pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
2560                         __func__, win->cbr_hor_scl_mode);
2561                 break;
2562         }                       /*win->cbr_hor_scl_mode */
2563
2564         /*(2.2)CBCR VER SCALE FACTOR */
2565         switch (win->cbr_ver_scl_mode) {
2566         case SCALE_NONE:
2567                 cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2568                 break;
2569         case SCALE_UP:
2570                 switch (win->cbr_vsu_mode) {
2571                 case SCALE_UP_BIL:
2572                         cbcr_yscl_factor =
2573                             GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
2574                         break;
2575                 case SCALE_UP_BIC:
2576                         if (cbcr_srcH < 3) {
2577                                 pr_err("cbcr_srcH should be ");
2578                                 pr_err("greater than 3 !!!\n");
2579                         }
2580                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
2581                                                                 cbcr_dstH);
2582                         break;
2583                 default:
2584                         pr_info("%s:un support cbr_vsu_mode:%d\n",
2585                                 __func__, win->cbr_vsu_mode);
2586                         break;
2587                 }
2588                 break;
2589         case SCALE_DOWN:
2590                 switch (win->cbr_vsd_mode) {
2591                 case SCALE_DOWN_BIL:
2592                         cbcr_vscalednmult =
2593                             rk3368_get_hard_ware_vskiplines(cbcr_srcH,
2594                                                             cbcr_dstH);
2595                         cbcr_yscl_factor =
2596                             GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
2597                                                            cbcr_vscalednmult);
2598                         if (cbcr_yscl_factor >= 0x2000) {
2599                                 pr_err("cbcr_yscl_factor should be less ");
2600                                 pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
2601                                        cbcr_yscl_factor);
2602                         }
2603
2604                         if (cbcr_vscalednmult == 4) {
2605                                 cbcr_vsd_bil_gt4 = 1;
2606                                 cbcr_vsd_bil_gt2 = 0;
2607                         } else if (cbcr_vscalednmult == 2) {
2608                                 cbcr_vsd_bil_gt4 = 0;
2609                                 cbcr_vsd_bil_gt2 = 1;
2610                         } else {
2611                                 cbcr_vsd_bil_gt4 = 0;
2612                                 cbcr_vsd_bil_gt2 = 0;
2613                         }
2614                         break;
2615                 case SCALE_DOWN_AVG:
2616                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
2617                                                                  cbcr_dstH);
2618                         break;
2619                 default:
2620                         pr_info("%s:un support cbr_vsd_mode:%d\n",
2621                                 __func__, win->cbr_vsd_mode);
2622                         break;
2623                 }
2624                 break;
2625         default:
2626                 pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
2627                         __func__, win->cbr_ver_scl_mode);
2628                 break;
2629         }
2630         win->scale_cbcr_x = cbcr_xscl_factor;
2631         win->scale_cbcr_y = cbcr_yscl_factor;
2632         win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
2633         win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
2634
2635         DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
2636             cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
2637         return 0;
2638 }
2639
2640 static int dsp_x_pos(int mirror_en, struct rk_screen *screen,
2641                      struct rk_lcdc_win_area *area)
2642 {
2643         int pos;
2644
2645         if (screen->x_mirror && mirror_en)
2646                 pr_err("not support both win and global mirror\n");
2647
2648         if ((!mirror_en) && (!screen->x_mirror))
2649                 pos = area->xpos + screen->mode.left_margin +
2650                         screen->mode.hsync_len;
2651         else
2652                 pos = screen->mode.xres - area->xpos -
2653                         area->xsize + screen->mode.left_margin +
2654                         screen->mode.hsync_len;
2655
2656         return pos;
2657 }
2658
2659 static int dsp_y_pos(int mirror_en, struct rk_screen *screen,
2660                      struct rk_lcdc_win_area *area)
2661 {
2662         int pos;
2663
2664         if (screen->y_mirror && mirror_en)
2665                 pr_err("not support both win and global mirror\n");
2666         if (screen->mode.vmode == FB_VMODE_NONINTERLACED) {
2667                 if ((!mirror_en) && (!screen->y_mirror))
2668                         pos = area->ypos + screen->mode.upper_margin +
2669                                 screen->mode.vsync_len;
2670                 else
2671                         pos = screen->mode.yres - area->ypos -
2672                                 area->ysize + screen->mode.upper_margin +
2673                                 screen->mode.vsync_len;
2674         } else if (screen->mode.vmode == FB_VMODE_INTERLACED) {
2675                 pos = area->ypos / 2 + screen->mode.upper_margin +
2676                         screen->mode.vsync_len;
2677                 area->ysize /= 2;
2678         }
2679
2680         return pos;
2681 }
2682
2683 static int win_0_1_set_par(struct lcdc_device *lcdc_dev,
2684                            struct rk_screen *screen, struct rk_lcdc_win *win)
2685 {
2686         u32 xact, yact, xvir, yvir, xpos, ypos;
2687         u8 fmt_cfg = 0, swap_rb, swap_uv = 0;
2688         char fmt[9] = "NULL";
2689
2690         xpos = dsp_x_pos(win->mirror_en, screen, &win->area[0]);
2691         ypos = dsp_y_pos(win->mirror_en, screen, &win->area[0]);
2692
2693         spin_lock(&lcdc_dev->reg_lock);
2694         if (likely(lcdc_dev->clk_on)) {
2695                 rk3368_lcdc_cal_scl_fac(win);   /*fac,lb,gt2,gt4 */
2696                 switch (win->area[0].format) {
2697                 case FBDC_RGB_565:
2698                         fmt_cfg = 2;
2699                         swap_rb = 0;
2700                         win->fmt_10 = 0;
2701                         win->area[0].fbdc_fmt_cfg = 0x05;
2702                         break;
2703                 case FBDC_ARGB_888:
2704                         fmt_cfg = 0;
2705                         swap_rb = 0;
2706                         win->fmt_10 = 0;
2707                         win->area[0].fbdc_fmt_cfg = 0x0c;
2708                         break;
2709                 case FBDC_ABGR_888:
2710                         fmt_cfg = 0;
2711                         swap_rb = 1;
2712                         win->fmt_10 = 0;
2713                         win->area[0].fbdc_fmt_cfg = 0x0c;
2714                         break;
2715                 case FBDC_RGBX_888:
2716                         fmt_cfg = 0;
2717                         swap_rb = 0;
2718                         win->fmt_10 = 0;
2719                         win->area[0].fbdc_fmt_cfg = 0x3a;
2720                         break;
2721                 case ARGB888:
2722                         fmt_cfg = 0;
2723                         swap_rb = 0;
2724                         win->fmt_10 = 0;
2725                         break;
2726                 case XBGR888:
2727                 case ABGR888:
2728                         fmt_cfg = 0;
2729                         swap_rb = 1;
2730                         win->fmt_10 = 0;
2731                         break;
2732                 case RGB888:
2733                         fmt_cfg = 1;
2734                         swap_rb = 0;
2735                         win->fmt_10 = 0;
2736                         break;
2737                 case RGB565:
2738                         fmt_cfg = 2;
2739                         swap_rb = 0;
2740                         win->fmt_10 = 0;
2741                         break;
2742                 case YUV422:
2743                         fmt_cfg = 5;
2744                         swap_rb = 0;
2745                         win->fmt_10 = 0;
2746                         break;
2747                 case YUV420:
2748                         fmt_cfg = 4;
2749                         swap_rb = 0;
2750                         win->fmt_10 = 0;
2751                         break;
2752                 case YUV420_NV21:
2753                         fmt_cfg = 4;
2754                         swap_rb = 0;
2755                         swap_uv = 1;
2756                         win->fmt_10 = 0;
2757                         break;
2758                 case YUV444:
2759                         fmt_cfg = 6;
2760                         swap_rb = 0;
2761                         win->fmt_10 = 0;
2762                         break;
2763                 case YUV422_A:
2764                         fmt_cfg = 5;
2765                         swap_rb = 0;
2766                         win->fmt_10 = 1;
2767                         break;
2768                 case YUV420_A:
2769                         fmt_cfg = 4;
2770                         swap_rb = 0;
2771                         win->fmt_10 = 1;
2772                         break;
2773                 case YUV444_A:
2774                         fmt_cfg = 6;
2775                         swap_rb = 0;
2776                         win->fmt_10 = 1;
2777                         break;
2778                 default:
2779                         dev_err(lcdc_dev->driver.dev, "%s:unsupport format!\n",
2780                                 __func__);
2781                         break;
2782                 }
2783                 win->area[0].fmt_cfg = fmt_cfg;
2784                 win->area[0].swap_rb = swap_rb;
2785                 win->area[0].swap_uv = swap_uv;
2786                 win->area[0].dsp_stx = xpos;
2787                 win->area[0].dsp_sty = ypos;
2788                 xact = win->area[0].xact;
2789                 yact = win->area[0].yact;
2790                 xvir = win->area[0].xvir;
2791                 yvir = win->area[0].yvir;
2792         }
2793         if (win->area[0].fbdc_en)
2794                 rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
2795         rk3368_win_0_1_reg_update(&lcdc_dev->driver, win->id);
2796         spin_unlock(&lcdc_dev->reg_lock);
2797
2798         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2799             lcdc_dev->id, win->id, get_format_string(win->area[0].format, fmt),
2800             xact, yact, win->area[0].xsize);
2801         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
2802             win->area[0].ysize, xvir, yvir, xpos, ypos);
2803
2804         return 0;
2805 }
2806
2807
2808 static int win_2_3_set_par(struct lcdc_device *lcdc_dev,
2809                            struct rk_screen *screen, struct rk_lcdc_win *win)
2810 {
2811         int i;
2812         u8 fmt_cfg, swap_rb;
2813         char fmt[9] = "NULL";
2814
2815         if (win->mirror_en)
2816                 pr_err("win[%d] not support y mirror\n", win->id);
2817         spin_lock(&lcdc_dev->reg_lock);
2818         if (likely(lcdc_dev->clk_on)) {
2819                 DBG(2, "lcdc[%d]:win[%d]>>\n>\n", lcdc_dev->id, win->id);
2820                 for (i = 0; i < win->area_num; i++) {
2821                         switch (win->area[i].format) {
2822                         case FBDC_RGB_565:
2823                                 fmt_cfg = 2;
2824                                 swap_rb = 0;
2825                                 win->fmt_10 = 0;
2826                                 win->area[0].fbdc_fmt_cfg = 0x05;
2827                                 break;
2828                         case FBDC_ARGB_888:
2829                                 fmt_cfg = 0;
2830                                 swap_rb = 0;
2831                                 win->fmt_10 = 0;
2832                                 win->area[0].fbdc_fmt_cfg = 0x0c;
2833                                 break;
2834                         case FBDC_RGBX_888:
2835                                 fmt_cfg = 0;
2836                                 swap_rb = 0;
2837                                 win->fmt_10 = 0;
2838                                 win->area[0].fbdc_fmt_cfg = 0x3a;
2839                                 break;
2840                         case ARGB888:
2841                                 fmt_cfg = 0;
2842                                 swap_rb = 0;
2843                                 break;
2844                         case XBGR888:
2845                         case ABGR888:
2846                                 fmt_cfg = 0;
2847                                 swap_rb = 1;
2848                                 break;
2849                         case RGB888:
2850                                 fmt_cfg = 1;
2851                                 swap_rb = 0;
2852                                 break;
2853                         case RGB565:
2854                                 fmt_cfg = 2;
2855                                 swap_rb = 0;
2856                                 break;
2857                         default:
2858                                 dev_err(lcdc_dev->driver.dev,
2859                                         "%s:un supported format!\n", __func__);
2860                                 break;
2861                         }
2862                         win->area[i].fmt_cfg = fmt_cfg;
2863                         win->area[i].swap_rb = swap_rb;
2864                         win->area[i].dsp_stx =
2865                                         dsp_x_pos(win->mirror_en, screen,
2866                                                   &win->area[i]);
2867                         win->area[i].dsp_sty =
2868                                         dsp_y_pos(win->mirror_en, screen,
2869                                                   &win->area[i]);
2870                         if ((win->area[i].xact != win->area[i].xsize) ||
2871                             (win->area[i].yact != win->area[i].ysize)) {
2872                                 pr_err("win[%d]->area[%d],not support scale\n",
2873                                         win->id, i);
2874                                 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
2875                                         win->area[i].xact,win->area[i].yact,
2876                                         win->area[i].xsize,win->area[i].ysize);
2877                                 win->area[i].xsize = win->area[i].xact;
2878                                 win->area[i].ysize = win->area[i].yact;
2879                         }
2880                         DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
2881                             get_format_string(win->area[i].format, fmt),
2882                             win->area[i].xsize, win->area[i].ysize,
2883                             win->area[i].xpos, win->area[i].ypos);
2884                 }
2885         }
2886         if (win->area[0].fbdc_en)
2887                 rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
2888         rk3368_win_2_3_reg_update(&lcdc_dev->driver, win->id);
2889         spin_unlock(&lcdc_dev->reg_lock);
2890         return 0;
2891 }
2892
2893 static int hwc_set_par(struct lcdc_device *lcdc_dev,
2894                        struct rk_screen *screen, struct rk_lcdc_win *win)
2895 {
2896         u32 xact, yact, xvir, yvir, xpos, ypos;
2897         u8 fmt_cfg = 0, swap_rb;
2898         char fmt[9] = "NULL";
2899
2900         xpos = win->area[0].xpos + screen->mode.left_margin +
2901             screen->mode.hsync_len;
2902         ypos = win->area[0].ypos + screen->mode.upper_margin +
2903             screen->mode.vsync_len;
2904
2905         spin_lock(&lcdc_dev->reg_lock);
2906         if (likely(lcdc_dev->clk_on)) {
2907                 /*rk3368_lcdc_cal_scl_fac(win); *//*fac,lb,gt2,gt4 */
2908                 switch (win->area[0].format) {
2909                 case ARGB888:
2910                         fmt_cfg = 0;
2911                         swap_rb = 0;
2912                         break;
2913                 case XBGR888:
2914                 case ABGR888:
2915                         fmt_cfg = 0;
2916                         swap_rb = 1;
2917                         break;
2918                 case RGB888:
2919                         fmt_cfg = 1;
2920                         swap_rb = 0;
2921                         break;
2922                 case RGB565:
2923                         fmt_cfg = 2;
2924                         swap_rb = 0;
2925                         break;
2926                 default:
2927                         dev_err(lcdc_dev->driver.dev,
2928                                 "%s:un supported format!\n", __func__);
2929                         break;
2930                 }
2931                 win->area[0].fmt_cfg = fmt_cfg;
2932                 win->area[0].swap_rb = swap_rb;
2933                 win->area[0].dsp_stx = xpos;
2934                 win->area[0].dsp_sty = ypos;
2935                 xact = win->area[0].xact;
2936                 yact = win->area[0].yact;
2937                 xvir = win->area[0].xvir;
2938                 yvir = win->area[0].yvir;
2939         }
2940         rk3368_hwc_reg_update(&lcdc_dev->driver, 4);
2941         spin_unlock(&lcdc_dev->reg_lock);
2942
2943         DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2944             lcdc_dev->id, __func__, get_format_string(win->area[0].format, fmt),
2945             xact, yact, win->area[0].xsize);
2946         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
2947             win->area[0].ysize, xvir, yvir, xpos, ypos);
2948         return 0;
2949 }
2950
2951 static int rk3368_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
2952 {
2953         struct lcdc_device *lcdc_dev =
2954             container_of(dev_drv, struct lcdc_device, driver);
2955         struct rk_lcdc_win *win = NULL;
2956         struct rk_screen *screen = dev_drv->cur_screen;
2957
2958         win = dev_drv->win[win_id];
2959         switch (win_id) {
2960         case 0:
2961                 win_0_1_set_par(lcdc_dev, screen, win);
2962                 break;
2963         case 1:
2964                 win_0_1_set_par(lcdc_dev, screen, win);
2965                 break;
2966         case 2:
2967                 win_2_3_set_par(lcdc_dev, screen, win);
2968                 break;
2969         case 3:
2970                 win_2_3_set_par(lcdc_dev, screen, win);
2971                 break;
2972         case 4:
2973                 hwc_set_par(lcdc_dev, screen, win);
2974                 break;
2975         default:
2976                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
2977                 break;
2978         }
2979         return 0;
2980 }
2981
2982 static int rk3368_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
2983                              unsigned long arg, int win_id)
2984 {
2985         struct lcdc_device *lcdc_dev =
2986             container_of(dev_drv, struct lcdc_device, driver);
2987         u32 panel_size[2];
2988         void __user *argp = (void __user *)arg;
2989         struct color_key_cfg clr_key_cfg;
2990
2991         switch (cmd) {
2992         case RK_FBIOGET_PANEL_SIZE:
2993                 panel_size[0] = lcdc_dev->screen->mode.xres;
2994                 panel_size[1] = lcdc_dev->screen->mode.yres;
2995                 if (copy_to_user(argp, panel_size, 8))
2996                         return -EFAULT;
2997                 break;
2998         case RK_FBIOPUT_COLOR_KEY_CFG:
2999                 if (copy_from_user(&clr_key_cfg, argp,
3000                                    sizeof(struct color_key_cfg)))
3001                         return -EFAULT;
3002                 rk3368_lcdc_clr_key_cfg(dev_drv);
3003                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
3004                             clr_key_cfg.win0_color_key_cfg);
3005                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
3006                             clr_key_cfg.win1_color_key_cfg);
3007                 break;
3008
3009         default:
3010                 break;
3011         }
3012         return 0;
3013 }
3014
3015 static int rk3368_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
3016 {
3017         struct lcdc_device *lcdc_dev = container_of(dev_drv,
3018                                                     struct lcdc_device, driver);
3019         /*struct device_node *backlight;*/
3020
3021         if (lcdc_dev->backlight)
3022                 return 0;
3023 #if 0
3024         backlight = of_parse_phandle(lcdc_dev->dev->of_node, "backlight", 0);
3025         if (backlight) {
3026                 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
3027                 if (!lcdc_dev->backlight)
3028                         dev_info(lcdc_dev->dev, "No find backlight device\n");
3029         } else {
3030                 dev_info(lcdc_dev->dev, "No find backlight device node\n");
3031         }
3032 #endif
3033         return 0;
3034 }
3035
3036 static int rk3368_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
3037 {
3038         struct lcdc_device *lcdc_dev =
3039             container_of(dev_drv, struct lcdc_device, driver);
3040         if (dev_drv->suspend_flag)
3041                 return 0;
3042         /* close the backlight */
3043         /*rk3368_lcdc_get_backlight_device(dev_drv);
3044         if (lcdc_dev->backlight) {
3045                 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
3046                 backlight_update_status(lcdc_dev->backlight);
3047         }*/
3048
3049         dev_drv->suspend_flag = 1;
3050         flush_kthread_worker(&dev_drv->update_regs_worker);
3051
3052         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
3053                 dev_drv->trsm_ops->disable();
3054
3055         spin_lock(&lcdc_dev->reg_lock);
3056         if (likely(lcdc_dev->clk_on)) {
3057                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
3058                              v_DSP_BLANK_EN(1));
3059                 lcdc_msk_reg(lcdc_dev,
3060                              INTR_CLEAR, m_FS_INTR_CLR | m_LINE_FLAG0_INTR_CLR,
3061                              v_FS_INTR_CLR(1) | v_LINE_FLAG0_INTR_CLR(1));
3062                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
3063                              v_DSP_OUT_ZERO(1));
3064                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(1));
3065                 lcdc_cfg_done(lcdc_dev);
3066
3067                 if (dev_drv->iommu_enabled) {
3068                         if (dev_drv->mmu_dev)
3069                                 rockchip_iovmm_deactivate(dev_drv->dev);
3070                 }
3071
3072                 spin_unlock(&lcdc_dev->reg_lock);
3073         } else {
3074                 spin_unlock(&lcdc_dev->reg_lock);
3075                 return 0;
3076         }
3077         rk3368_lcdc_clk_disable(lcdc_dev);
3078         rk_disp_pwr_disable(dev_drv);
3079         return 0;
3080 }
3081
3082 static int rk3368_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
3083 {
3084         struct lcdc_device *lcdc_dev =
3085             container_of(dev_drv, struct lcdc_device, driver);
3086
3087         if (!dev_drv->suspend_flag)
3088                 return 0;
3089         rk_disp_pwr_enable(dev_drv);
3090         dev_drv->suspend_flag = 0;
3091
3092         if (1/*lcdc_dev->atv_layer_cnt*/) {
3093                 rk3368_lcdc_clk_enable(lcdc_dev);
3094                 rk3368_lcdc_reg_restore(lcdc_dev);
3095
3096                 spin_lock(&lcdc_dev->reg_lock);
3097                 if (dev_drv->cur_screen->dsp_lut)
3098                         rk3368_lcdc_set_lut(dev_drv,
3099                                             dev_drv->cur_screen->dsp_lut);
3100                 if (dev_drv->cur_screen->cabc_lut)
3101                         rk3368_set_cabc_lut(dev_drv,
3102                                             dev_drv->cur_screen->cabc_lut);
3103
3104                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
3105                              v_DSP_OUT_ZERO(0));
3106                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(0));
3107                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
3108                              v_DSP_BLANK_EN(0));
3109                 lcdc_cfg_done(lcdc_dev);
3110
3111                 if (dev_drv->iommu_enabled) {
3112                         if (dev_drv->mmu_dev)
3113                                 rockchip_iovmm_activate(dev_drv->dev);
3114                 }
3115
3116                 spin_unlock(&lcdc_dev->reg_lock);
3117         }
3118
3119         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
3120                 dev_drv->trsm_ops->enable();
3121         return 0;
3122 }
3123
3124 static int rk3368_lcdc_blank(struct rk_lcdc_driver *dev_drv,
3125                              int win_id, int blank_mode)
3126 {
3127         switch (blank_mode) {
3128         case FB_BLANK_UNBLANK:
3129                 rk3368_lcdc_early_resume(dev_drv);
3130                 break;
3131         case FB_BLANK_NORMAL:
3132                 rk3368_lcdc_early_suspend(dev_drv);
3133                 break;
3134         default:
3135                 rk3368_lcdc_early_suspend(dev_drv);
3136                 break;
3137         }
3138
3139         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
3140
3141         return 0;
3142 }
3143
3144 static int rk3368_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
3145 {
3146         struct lcdc_device *lcdc_dev =
3147             container_of(dev_drv, struct lcdc_device, driver);
3148         int win_status = 0;
3149         if (win_id == 0)
3150                 win_status = lcdc_read_bit(lcdc_dev, WIN0_CTRL0, m_WIN0_EN);
3151         else if (win_id == 1)
3152                 win_status = lcdc_read_bit(lcdc_dev, WIN1_CTRL0, m_WIN1_EN);
3153         else if (win_id == 2)
3154                 win_status = lcdc_read_bit(lcdc_dev, WIN2_CTRL0, m_WIN2_EN);
3155         else if (win_id == 3)
3156                 win_status = lcdc_read_bit(lcdc_dev, WIN3_CTRL0, m_WIN3_EN);
3157         else if (win_id == 4)
3158                 win_status = lcdc_read_bit(lcdc_dev, HWC_CTRL0, m_HWC_EN);
3159         else
3160                 pr_err("!!!%s,win_id :%d,unsupport!!!\n",__func__,win_id);
3161
3162         return win_status;
3163 }
3164
3165 /*overlay will be do at regupdate*/
3166 static int rk3368_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
3167                                bool set)
3168 {
3169         struct lcdc_device *lcdc_dev =
3170             container_of(dev_drv, struct lcdc_device, driver);
3171         struct rk_lcdc_win *win = NULL;
3172         int i, ovl;
3173         unsigned int mask, val;
3174         int z_order_num = 0;
3175         int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3176
3177         if (swap == 0) {
3178                 for (i = 0; i < 4; i++) {
3179                         win = dev_drv->win[i];
3180                         if (win->state == 1)
3181                                 z_order_num++;
3182                 }
3183                 for (i = 0; i < 4; i++) {
3184                         win = dev_drv->win[i];
3185                         if (win->state == 0)
3186                                 win->z_order = z_order_num++;
3187                         switch (win->z_order) {
3188                         case 0:
3189                                 layer0_sel = win->id;
3190                                 break;
3191                         case 1:
3192                                 layer1_sel = win->id;
3193                                 break;
3194                         case 2:
3195                                 layer2_sel = win->id;
3196                                 break;
3197                         case 3:
3198                                 layer3_sel = win->id;
3199                                 break;
3200                         default:
3201                                 break;
3202                         }
3203                 }
3204         } else {
3205                 layer0_sel = swap % 10;
3206                 layer1_sel = swap / 10 % 10;
3207                 layer2_sel = swap / 100 % 10;
3208                 layer3_sel = swap / 1000;
3209         }
3210
3211         spin_lock(&lcdc_dev->reg_lock);
3212         if (lcdc_dev->clk_on) {
3213                 if (set) {
3214                         mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
3215                             m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
3216                         val = v_DSP_LAYER0_SEL(layer0_sel) |
3217                             v_DSP_LAYER1_SEL(layer1_sel) |
3218                             v_DSP_LAYER2_SEL(layer2_sel) |
3219                             v_DSP_LAYER3_SEL(layer3_sel);
3220                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
3221                 } else {
3222                         layer0_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3223                                                    m_DSP_LAYER0_SEL);
3224                         layer1_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3225                                                    m_DSP_LAYER1_SEL);
3226                         layer2_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3227                                                    m_DSP_LAYER2_SEL);
3228                         layer3_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3229                                                    m_DSP_LAYER3_SEL);
3230                         ovl = layer3_sel * 1000 + layer2_sel * 100 +
3231                             layer1_sel * 10 + layer0_sel;
3232                 }
3233         } else {
3234                 ovl = -EPERM;
3235         }
3236         spin_unlock(&lcdc_dev->reg_lock);
3237
3238         return ovl;
3239 }
3240
3241 static char *rk3368_lcdc_format_to_string(int format, char *fmt)
3242 {
3243         if (!fmt)
3244                 return NULL;
3245
3246         switch (format) {
3247         case 0:
3248                 strcpy(fmt, "ARGB888");
3249                 break;
3250         case 1:
3251                 strcpy(fmt, "RGB888");
3252                 break;
3253         case 2:
3254                 strcpy(fmt, "RGB565");
3255                 break;
3256         case 4:
3257                 strcpy(fmt, "YCbCr420");
3258                 break;
3259         case 5:
3260                 strcpy(fmt, "YCbCr422");
3261                 break;
3262         case 6:
3263                 strcpy(fmt, "YCbCr444");
3264                 break;
3265         default:
3266                 strcpy(fmt, "invalid\n");
3267                 break;
3268         }
3269         return fmt;
3270 }
3271 static ssize_t rk3368_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
3272                                          char *buf, int win_id)
3273 {
3274         struct lcdc_device *lcdc_dev =
3275             container_of(dev_drv, struct lcdc_device, driver);
3276         struct rk_screen *screen = dev_drv->cur_screen;
3277         u16 hsync_len = screen->mode.hsync_len;
3278         u16 left_margin = screen->mode.left_margin;
3279         u16 vsync_len = screen->mode.vsync_len;
3280         u16 upper_margin = screen->mode.upper_margin;
3281         u32 h_pw_bp = hsync_len + left_margin;
3282         u32 v_pw_bp = vsync_len + upper_margin;
3283         u32 fmt_id;
3284         char format_w0[9] = "NULL";
3285         char format_w1[9] = "NULL";
3286         char format_w2_0[9] = "NULL";
3287         char format_w2_1[9] = "NULL";
3288         char format_w2_2[9] = "NULL";
3289         char format_w2_3[9] = "NULL";
3290         char format_w3_0[9] = "NULL";
3291         char format_w3_1[9] = "NULL";
3292         char format_w3_2[9] = "NULL";
3293         char format_w3_3[9] = "NULL";
3294         char dsp_buf[100];
3295         u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
3296         u32 y_factor, uv_factor;
3297         u8 layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3298         u8 w0_state, w1_state, w2_state, w3_state;
3299         u8 w2_0_state, w2_1_state, w2_2_state, w2_3_state;
3300         u8 w3_0_state, w3_1_state, w3_2_state, w3_3_state;
3301
3302         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
3303         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
3304         u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
3305         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
3306         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
3307         u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
3308
3309         u32 w2_0_vir_y, w2_1_vir_y, w2_2_vir_y, w2_3_vir_y;
3310         u32 w2_0_dsp_x, w2_1_dsp_x, w2_2_dsp_x, w2_3_dsp_x;
3311         u32 w2_0_dsp_y, w2_1_dsp_y, w2_2_dsp_y, w2_3_dsp_y;
3312         u32 w2_0_st_x = h_pw_bp, w2_1_st_x = h_pw_bp;
3313         u32 w2_2_st_x = h_pw_bp, w2_3_st_x = h_pw_bp;
3314         u32 w2_0_st_y = v_pw_bp, w2_1_st_y = v_pw_bp;
3315         u32 w2_2_st_y = v_pw_bp, w2_3_st_y = v_pw_bp;
3316
3317         u32 w3_0_vir_y, w3_1_vir_y, w3_2_vir_y, w3_3_vir_y;
3318         u32 w3_0_dsp_x, w3_1_dsp_x, w3_2_dsp_x, w3_3_dsp_x;
3319         u32 w3_0_dsp_y, w3_1_dsp_y, w3_2_dsp_y, w3_3_dsp_y;
3320         u32 w3_0_st_x = h_pw_bp, w3_1_st_x = h_pw_bp;
3321         u32 w3_2_st_x = h_pw_bp, w3_3_st_x = h_pw_bp;
3322         u32 w3_0_st_y = v_pw_bp, w3_1_st_y = v_pw_bp;
3323         u32 w3_2_st_y = v_pw_bp, w3_3_st_y = v_pw_bp;
3324         u32 dclk_freq;
3325         int size = 0;
3326
3327         dclk_freq = screen->mode.pixclock;
3328         /*rk3368_lcdc_reg_dump(dev_drv); */
3329
3330         spin_lock(&lcdc_dev->reg_lock);
3331         if (lcdc_dev->clk_on) {
3332                 zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
3333                 layer0_sel = (zorder & m_DSP_LAYER0_SEL) >> 8;
3334                 layer1_sel = (zorder & m_DSP_LAYER1_SEL) >> 10;
3335                 layer2_sel = (zorder & m_DSP_LAYER2_SEL) >> 12;
3336                 layer3_sel = (zorder & m_DSP_LAYER3_SEL) >> 14;
3337                 /*WIN0 */
3338                 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
3339                 w0_state = win_ctrl & m_WIN0_EN;
3340                 fmt_id = (win_ctrl & m_WIN0_DATA_FMT) >> 1;
3341                 rk3368_lcdc_format_to_string(fmt_id, format_w0);
3342                 vir_info = lcdc_readl(lcdc_dev, WIN0_VIR);
3343                 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
3344                 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
3345                 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
3346                 y_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
3347                 uv_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_CBR);
3348                 w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
3349                 w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV) >> 16;
3350                 w0_act_x = (act_info & m_WIN0_ACT_WIDTH) + 1;
3351                 w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT) >> 16) + 1;
3352                 w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH) + 1;
3353                 w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT) >> 16) + 1;
3354                 if (w0_state) {
3355                         w0_st_x = dsp_st & m_WIN0_DSP_XST;
3356                         w0_st_y = (dsp_st & m_WIN0_DSP_YST) >> 16;
3357                 }
3358                 w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
3359                 w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB) >> 16;
3360                 w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
3361                 w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR) >> 16;
3362
3363                 /*WIN1 */
3364                 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
3365                 w1_state = win_ctrl & m_WIN1_EN;
3366                 fmt_id = (win_ctrl & m_WIN1_DATA_FMT) >> 1;
3367                 rk3368_lcdc_format_to_string(fmt_id, format_w1);
3368                 vir_info = lcdc_readl(lcdc_dev, WIN1_VIR);
3369                 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
3370                 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
3371                 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
3372                 y_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_YRGB);
3373                 uv_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_CBR);
3374                 w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
3375                 w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV) >> 16;
3376                 w1_act_x = (act_info & m_WIN1_ACT_WIDTH) + 1;
3377                 w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT) >> 16) + 1;
3378                 w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH) + 1;
3379                 w1_dsp_y = ((dsp_info & m_WIN1_DSP_HEIGHT) >> 16) + 1;
3380                 if (w1_state) {
3381                         w1_st_x = dsp_st & m_WIN1_DSP_XST;
3382                         w1_st_y = (dsp_st & m_WIN1_DSP_YST) >> 16;
3383                 }
3384                 w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
3385                 w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB) >> 16;
3386                 w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
3387                 w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR) >> 16;
3388                 /*WIN2 */
3389                 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
3390                 w2_state = win_ctrl & m_WIN2_EN;
3391                 w2_0_state = (win_ctrl & 0x10) >> 4;
3392                 w2_1_state = (win_ctrl & 0x100) >> 8;
3393                 w2_2_state = (win_ctrl & 0x1000) >> 12;
3394                 w2_3_state = (win_ctrl & 0x10000) >> 16;
3395                 vir_info = lcdc_readl(lcdc_dev, WIN2_VIR0_1);
3396                 w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
3397                 w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1) >> 16;
3398                 vir_info = lcdc_readl(lcdc_dev, WIN2_VIR2_3);
3399                 w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
3400                 w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3) >> 16;
3401
3402                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT0) >> 1;
3403                 rk3368_lcdc_format_to_string(fmt_id, format_w2_0);
3404                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT1) >> 1;
3405                 rk3368_lcdc_format_to_string(fmt_id, format_w2_1);
3406                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT2) >> 1;
3407                 rk3368_lcdc_format_to_string(fmt_id, format_w2_2);
3408                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT3) >> 1;
3409                 rk3368_lcdc_format_to_string(fmt_id, format_w2_3);
3410
3411                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO0);
3412                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST0);
3413                 w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0) + 1;
3414                 w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0) >> 16) + 1;
3415                 if (w2_0_state) {
3416                         w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
3417                         w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0) >> 16;
3418                 }
3419                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO1);
3420                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST1);
3421                 w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1) + 1;
3422                 w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1) >> 16) + 1;
3423                 if (w2_1_state) {
3424                         w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
3425                         w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1) >> 16;
3426                 }
3427                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO2);
3428                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST2);
3429                 w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2) + 1;
3430                 w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2) >> 16) + 1;
3431                 if (w2_2_state) {
3432                         w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
3433                         w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2) >> 16;
3434                 }
3435                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO3);
3436                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST3);
3437                 w2_3_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH3) + 1;
3438                 w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3) >> 16) + 1;
3439                 if (w2_3_state) {
3440                         w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
3441                         w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3) >> 16;
3442                 }
3443
3444                 /*WIN3 */
3445                 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
3446                 w3_state = win_ctrl & m_WIN3_EN;
3447                 w3_0_state = (win_ctrl & m_WIN3_MST0_EN) >> 4;
3448                 w3_1_state = (win_ctrl & m_WIN3_MST1_EN) >> 8;
3449                 w3_2_state = (win_ctrl & m_WIN3_MST2_EN) >> 12;
3450                 w3_3_state = (win_ctrl & m_WIN3_MST3_EN) >> 16;
3451                 vir_info = lcdc_readl(lcdc_dev, WIN3_VIR0_1);
3452                 w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
3453                 w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1) >> 16;
3454                 vir_info = lcdc_readl(lcdc_dev, WIN3_VIR2_3);
3455                 w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
3456                 w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3) >> 16;
3457                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT0) >> 1;
3458                 rk3368_lcdc_format_to_string(fmt_id, format_w3_0);
3459                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT1) >> 1;
3460                 rk3368_lcdc_format_to_string(fmt_id, format_w3_1);
3461                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT2) >> 1;
3462                 rk3368_lcdc_format_to_string(fmt_id, format_w3_2);
3463                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT3) >> 1;
3464                 rk3368_lcdc_format_to_string(fmt_id, format_w3_3);
3465                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO0);
3466                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST0);
3467                 w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0) + 1;
3468                 w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0) >> 16) + 1;
3469                 if (w3_0_state) {
3470                         w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
3471                         w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0) >> 16;
3472                 }
3473
3474                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO1);
3475                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST1);
3476                 w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1) + 1;
3477                 w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1) >> 16) + 1;
3478                 if (w3_1_state) {
3479                         w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
3480                         w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1) >> 16;
3481                 }
3482
3483                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO2);
3484                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST2);
3485                 w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2) + 1;
3486                 w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2) >> 16) + 1;
3487                 if (w3_2_state) {
3488                         w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
3489                         w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2) >> 16;
3490                 }
3491
3492                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO3);
3493                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST3);
3494                 w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3) + 1;
3495                 w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3) >> 16) + 1;
3496                 if (w3_3_state) {
3497                         w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
3498                         w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3) >> 16;
3499                 }
3500
3501         } else {
3502                 spin_unlock(&lcdc_dev->reg_lock);
3503                 return -EPERM;
3504         }
3505         spin_unlock(&lcdc_dev->reg_lock);
3506         size += snprintf(dsp_buf, 80,
3507                 "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
3508                 layer3_sel, layer2_sel, layer1_sel, layer0_sel);
3509         strcat(buf, dsp_buf);
3510         memset(dsp_buf, 0, sizeof(dsp_buf));
3511         /*win0*/
3512         size += snprintf(dsp_buf, 80,
3513                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3514                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
3515         strcat(buf, dsp_buf);
3516         memset(dsp_buf, 0, sizeof(dsp_buf));
3517
3518         size += snprintf(dsp_buf, 80,
3519                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3520                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
3521         strcat(buf, dsp_buf);
3522         memset(dsp_buf, 0, sizeof(dsp_buf));
3523
3524         size += snprintf(dsp_buf, 80,
3525                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3526                  w0_st_x-h_pw_bp, w0_st_y-v_pw_bp, w0_y_h_fac, w0_y_v_fac);
3527         strcat(buf, dsp_buf);
3528         memset(dsp_buf, 0, sizeof(dsp_buf));
3529
3530         size += snprintf(dsp_buf, 80,
3531                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3532                  w0_uv_h_fac, w0_uv_v_fac, lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
3533                  lcdc_readl(lcdc_dev, WIN0_CBR_MST));
3534         strcat(buf, dsp_buf);
3535         memset(dsp_buf, 0, sizeof(dsp_buf));
3536
3537         /*win1*/
3538         size += snprintf(dsp_buf, 80,
3539                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3540                  w1_state, format_w1, w1_vir_y, w1_vir_uv);
3541         strcat(buf, dsp_buf);
3542         memset(dsp_buf, 0, sizeof(dsp_buf));
3543
3544         size += snprintf(dsp_buf, 80,
3545                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3546                  w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
3547         strcat(buf, dsp_buf);
3548         memset(dsp_buf, 0, sizeof(dsp_buf));
3549
3550         size += snprintf(dsp_buf, 80,
3551                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3552                  w1_st_x-h_pw_bp, w1_st_y-v_pw_bp, w1_y_h_fac, w1_y_v_fac);
3553         strcat(buf, dsp_buf);
3554         memset(dsp_buf, 0, sizeof(dsp_buf));
3555
3556         size += snprintf(dsp_buf, 80,
3557                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3558                  w1_uv_h_fac, w1_uv_v_fac, lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
3559                  lcdc_readl(lcdc_dev, WIN1_CBR_MST));
3560         strcat(buf, dsp_buf);
3561         memset(dsp_buf, 0, sizeof(dsp_buf));
3562
3563         /*win2*/
3564         size += snprintf(dsp_buf, 80,
3565                  "win2:\n  state:%d\n",
3566                  w2_state);
3567         strcat(buf, dsp_buf);
3568         memset(dsp_buf, 0, sizeof(dsp_buf));
3569         /*area 0*/
3570         size += snprintf(dsp_buf, 80,
3571                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3572                  w2_0_state, format_w2_0, w2_0_dsp_x, w2_0_dsp_y);
3573         strcat(buf, dsp_buf);
3574         memset(dsp_buf, 0, sizeof(dsp_buf));
3575         size += snprintf(dsp_buf, 80,
3576                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3577                  w2_0_st_x - h_pw_bp, w2_0_st_y - v_pw_bp,
3578                  lcdc_readl(lcdc_dev, WIN2_MST0));
3579         strcat(buf, dsp_buf);
3580         memset(dsp_buf, 0, sizeof(dsp_buf));
3581
3582         /*area 1*/
3583         size += snprintf(dsp_buf, 80,
3584                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3585                  w2_1_state, format_w2_1, w2_1_dsp_x, w2_1_dsp_y);
3586         strcat(buf, dsp_buf);
3587         memset(dsp_buf, 0, sizeof(dsp_buf));
3588         size += snprintf(dsp_buf, 80,
3589                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3590                  w2_1_st_x - h_pw_bp, w2_1_st_y - v_pw_bp,
3591                  lcdc_readl(lcdc_dev, WIN2_MST1));
3592         strcat(buf, dsp_buf);
3593         memset(dsp_buf, 0, sizeof(dsp_buf));
3594
3595         /*area 2*/
3596         size += snprintf(dsp_buf, 80,
3597                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3598                  w2_2_state, format_w2_2, w2_2_dsp_x, w2_2_dsp_y);
3599         strcat(buf, dsp_buf);
3600         memset(dsp_buf, 0, sizeof(dsp_buf));
3601         size += snprintf(dsp_buf, 80,
3602                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3603                  w2_2_st_x - h_pw_bp, w2_2_st_y - v_pw_bp,
3604                  lcdc_readl(lcdc_dev, WIN2_MST2));
3605         strcat(buf, dsp_buf);
3606         memset(dsp_buf, 0, sizeof(dsp_buf));
3607
3608         /*area 3*/
3609         size += snprintf(dsp_buf, 80,
3610                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3611                  w2_3_state, format_w2_3, w2_3_dsp_x, w2_3_dsp_y);
3612         strcat(buf, dsp_buf);
3613         memset(dsp_buf, 0, sizeof(dsp_buf));
3614         size += snprintf(dsp_buf, 80,
3615                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3616                  w2_3_st_x - h_pw_bp, w2_3_st_y - v_pw_bp,
3617                  lcdc_readl(lcdc_dev, WIN2_MST3));
3618         strcat(buf, dsp_buf);
3619         memset(dsp_buf, 0, sizeof(dsp_buf));
3620
3621         /*win3*/
3622         size += snprintf(dsp_buf, 80,
3623                  "win3:\n  state:%d\n",
3624                  w3_state);
3625         strcat(buf, dsp_buf);
3626         memset(dsp_buf, 0, sizeof(dsp_buf));
3627         /*area 0*/
3628         size += snprintf(dsp_buf, 80,
3629                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3630                  w3_0_state, format_w3_0, w3_0_dsp_x, w3_0_dsp_y);
3631         strcat(buf, dsp_buf);
3632         memset(dsp_buf, 0, sizeof(dsp_buf));
3633         size += snprintf(dsp_buf, 80,
3634                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3635                  w3_0_st_x - h_pw_bp, w3_0_st_y - v_pw_bp,
3636                  lcdc_readl(lcdc_dev, WIN3_MST0));
3637         strcat(buf, dsp_buf);
3638         memset(dsp_buf, 0, sizeof(dsp_buf));
3639
3640         /*area 1*/
3641         size += snprintf(dsp_buf, 80,
3642                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3643                  w3_1_state, format_w3_1, w3_1_dsp_x, w3_1_dsp_y);
3644         strcat(buf, dsp_buf);
3645         memset(dsp_buf, 0, sizeof(dsp_buf));
3646         size += snprintf(dsp_buf, 80,
3647                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3648                  w3_1_st_x - h_pw_bp, w3_1_st_y - v_pw_bp,
3649                  lcdc_readl(lcdc_dev, WIN3_MST1));
3650         strcat(buf, dsp_buf);
3651         memset(dsp_buf, 0, sizeof(dsp_buf));
3652
3653         /*area 2*/
3654         size += snprintf(dsp_buf, 80,
3655                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3656                  w3_2_state, format_w3_2, w3_2_dsp_x, w3_2_dsp_y);
3657         strcat(buf, dsp_buf);
3658         memset(dsp_buf, 0, sizeof(dsp_buf));
3659         size += snprintf(dsp_buf, 80,
3660                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3661                  w3_2_st_x - h_pw_bp, w3_2_st_y - v_pw_bp,
3662                  lcdc_readl(lcdc_dev, WIN3_MST2));
3663         strcat(buf, dsp_buf);
3664         memset(dsp_buf, 0, sizeof(dsp_buf));
3665
3666         /*area 3*/
3667         size += snprintf(dsp_buf, 80,
3668                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3669                  w3_3_state, format_w3_3, w3_3_dsp_x, w3_3_dsp_y);
3670         strcat(buf, dsp_buf);
3671         memset(dsp_buf, 0, sizeof(dsp_buf));
3672         size += snprintf(dsp_buf, 80,
3673                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3674                  w3_3_st_x - h_pw_bp, w3_3_st_y - v_pw_bp,
3675                  lcdc_readl(lcdc_dev, WIN3_MST3));
3676         strcat(buf, dsp_buf);
3677         memset(dsp_buf, 0, sizeof(dsp_buf));
3678
3679         return size;
3680 }
3681
3682 static int rk3368_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
3683                                bool set)
3684 {
3685         struct lcdc_device *lcdc_dev =
3686             container_of(dev_drv, struct lcdc_device, driver);
3687         struct rk_screen *screen = dev_drv->cur_screen;
3688         u64 ft = 0;
3689         u32 dotclk;
3690         int ret;
3691         u32 pixclock;
3692         u32 x_total, y_total;
3693
3694         if (set) {
3695                 if (fps == 0) {
3696                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
3697                         return 0;
3698                 }
3699                 ft = div_u64(1000000000000llu, fps);
3700                 x_total =
3701                     screen->mode.upper_margin + screen->mode.lower_margin +
3702                     screen->mode.yres + screen->mode.vsync_len;
3703                 y_total =
3704                     screen->mode.left_margin + screen->mode.right_margin +
3705                     screen->mode.xres + screen->mode.hsync_len;
3706                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
3707                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
3708                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
3709         }
3710
3711         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
3712         lcdc_dev->pixclock = pixclock;
3713         dev_drv->pixclock = lcdc_dev->pixclock;
3714         fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
3715         screen->ft = 1000 / fps;        /*one frame time in ms */
3716
3717         if (set)
3718                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
3719                          clk_get_rate(lcdc_dev->dclk), fps);
3720
3721         return fps;
3722 }
3723
3724 static int rk3368_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
3725 {
3726         mutex_lock(&dev_drv->fb_win_id_mutex);
3727         if (order == FB_DEFAULT_ORDER)
3728                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
3729         dev_drv->fb4_win_id = order / 10000;
3730         dev_drv->fb3_win_id = (order / 1000) % 10;
3731         dev_drv->fb2_win_id = (order / 100) % 10;
3732         dev_drv->fb1_win_id = (order / 10) % 10;
3733         dev_drv->fb0_win_id = order % 10;
3734         mutex_unlock(&dev_drv->fb_win_id_mutex);
3735
3736         return 0;
3737 }
3738
3739 static int rk3368_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
3740                                   const char *id)
3741 {
3742         int win_id = 0;
3743
3744         mutex_lock(&dev_drv->fb_win_id_mutex);
3745         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
3746                 win_id = dev_drv->fb0_win_id;
3747         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
3748                 win_id = dev_drv->fb1_win_id;
3749         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
3750                 win_id = dev_drv->fb2_win_id;
3751         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
3752                 win_id = dev_drv->fb3_win_id;
3753         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
3754                 win_id = dev_drv->fb4_win_id;
3755         mutex_unlock(&dev_drv->fb_win_id_mutex);
3756
3757         return win_id;
3758 }
3759
3760 static int rk3368_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
3761 {
3762         struct lcdc_device *lcdc_dev =
3763             container_of(dev_drv, struct lcdc_device, driver);
3764         int i;
3765         unsigned int mask, val;
3766         struct rk_lcdc_win *win = NULL;
3767
3768         spin_lock(&lcdc_dev->reg_lock);
3769         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
3770                      v_STANDBY_EN(lcdc_dev->standby));
3771         for (i = 0; i < 4; i++) {
3772                 win = dev_drv->win[i];
3773                 if ((win->state == 0) && (win->last_state == 1)) {
3774                         switch (win->id) {
3775                         case 0:
3776                                 /*lcdc_writel(lcdc_dev,WIN0_CTRL1,0x0);
3777                                    for rk3288 to fix hw bug? */
3778                                 mask = m_WIN0_EN;
3779                                 val = v_WIN0_EN(0);
3780                                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
3781                                 break;
3782                         case 1:
3783                                 /*lcdc_writel(lcdc_dev,WIN1_CTRL1,0x0);
3784                                    for rk3288 to fix hw bug? */
3785                                 mask = m_WIN1_EN;
3786                                 val = v_WIN1_EN(0);
3787                                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
3788                                 break;
3789                         case 2:
3790                                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
3791                                     m_WIN2_MST1_EN |
3792                                     m_WIN2_MST2_EN | m_WIN2_MST3_EN;
3793                                 val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
3794                                     v_WIN2_MST1_EN(0) |
3795                                     v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
3796                                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
3797                                 break;
3798                         case 3:
3799                                 mask = m_WIN3_EN | m_WIN3_MST0_EN |
3800                                     m_WIN3_MST1_EN |
3801                                     m_WIN3_MST2_EN | m_WIN3_MST3_EN;
3802                                 val = v_WIN3_EN(0) | v_WIN3_MST0_EN(0) |
3803                                     v_WIN3_MST1_EN(0) |
3804                                     v_WIN3_MST2_EN(0) | v_WIN3_MST3_EN(0);
3805                                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
3806                                 break;
3807                         case 4:
3808                                 mask = m_HWC_EN;
3809                                 val = v_HWC_EN(0);
3810                                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
3811                                 break;
3812                         default:
3813                                 break;
3814                         }
3815                 }
3816                 win->last_state = win->state;
3817         }
3818         lcdc_cfg_done(lcdc_dev);
3819         spin_unlock(&lcdc_dev->reg_lock);
3820         return 0;
3821 }
3822
3823 static int rk3368_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
3824 {
3825         struct lcdc_device *lcdc_dev =
3826             container_of(dev_drv, struct lcdc_device, driver);
3827         spin_lock(&lcdc_dev->reg_lock);
3828         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
3829                      v_DIRECT_PATH_EN(open));
3830         lcdc_cfg_done(lcdc_dev);
3831         spin_unlock(&lcdc_dev->reg_lock);
3832         return 0;
3833 }
3834
3835 static int rk3368_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
3836 {
3837         struct lcdc_device *lcdc_dev = container_of(dev_drv,
3838                                                     struct lcdc_device, driver);
3839         spin_lock(&lcdc_dev->reg_lock);
3840         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
3841                      v_DIRECT_PATCH_SEL(win_id));
3842         lcdc_cfg_done(lcdc_dev);
3843         spin_unlock(&lcdc_dev->reg_lock);
3844         return 0;
3845 }
3846
3847 static int rk3368_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
3848 {
3849         struct lcdc_device *lcdc_dev =
3850             container_of(dev_drv, struct lcdc_device, driver);
3851         int ovl;
3852
3853         spin_lock(&lcdc_dev->reg_lock);
3854         ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
3855         spin_unlock(&lcdc_dev->reg_lock);
3856         return ovl;
3857 }
3858
3859 static int rk3368_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
3860                                       int enable)
3861 {
3862         struct lcdc_device *lcdc_dev =
3863             container_of(dev_drv, struct lcdc_device, driver);
3864         if (enable)
3865                 enable_irq(lcdc_dev->irq);
3866         else
3867                 disable_irq(lcdc_dev->irq);
3868         return 0;
3869 }
3870
3871 int rk3368_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
3872 {
3873         struct lcdc_device *lcdc_dev =
3874             container_of(dev_drv, struct lcdc_device, driver);
3875         u32 int_reg;
3876         int ret;
3877
3878         if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
3879                 int_reg = lcdc_readl(lcdc_dev, INTR_STATUS);
3880                 if (int_reg & m_LINE_FLAG0_INTR_STS) {
3881                         lcdc_dev->driver.frame_time.last_framedone_t =
3882                             lcdc_dev->driver.frame_time.framedone_t;
3883                         lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
3884                         lcdc_msk_reg(lcdc_dev, INTR_CLEAR,
3885                                      m_LINE_FLAG0_INTR_CLR,
3886                                      v_LINE_FLAG0_INTR_CLR(1));
3887                         ret = RK_LF_STATUS_FC;
3888                 } else {
3889                         ret = RK_LF_STATUS_FR;
3890                 }
3891         } else {
3892                 ret = RK_LF_STATUS_NC;
3893         }
3894
3895         return ret;
3896 }
3897
3898 static int rk3368_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
3899                                     unsigned int *dsp_addr)
3900 {
3901         struct lcdc_device *lcdc_dev =
3902             container_of(dev_drv, struct lcdc_device, driver);
3903         spin_lock(&lcdc_dev->reg_lock);
3904         if (lcdc_dev->clk_on) {
3905                 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
3906                 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
3907                 dsp_addr[2] = lcdc_readl(lcdc_dev, WIN2_MST0);
3908                 dsp_addr[3] = lcdc_readl(lcdc_dev, WIN3_MST0);
3909         }
3910         spin_unlock(&lcdc_dev->reg_lock);
3911         return 0;
3912 }
3913
3914 static struct lcdc_cabc_mode cabc_mode[4] = {
3915       /* calc,     up,     down,   global_limit   */
3916         {5,    256,  256,   256},  /*mode 1   0*/
3917         {5,    258,  253,   277},  /*mode 2   15%*/
3918         {5,    259,  252,   330},  /*mode 3   40%*/
3919         {5,    267,  244,   400},  /*mode 4   60%*/
3920 };
3921
3922 static int rk3368_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode)
3923 {
3924         struct lcdc_device *lcdc_dev =
3925             container_of(dev_drv, struct lcdc_device, driver);
3926         struct rk_screen *screen = dev_drv->cur_screen;
3927         u32 total_pixel, calc_pixel, stage_up, stage_down;
3928         u32 pixel_num, global_su;
3929         u32 stage_up_rec, stage_down_rec, global_su_rec, gamma_global_su_rec;
3930         u32 mask = 0, val = 0, cabc_en = 0;
3931         int *cabc_lut = NULL;
3932
3933         if (!screen->cabc_lut) {
3934                 pr_err("screen cabc lut not config, so not open cabc\n");
3935                 return 0;
3936         } else {
3937                 cabc_lut = screen->cabc_lut;
3938         }
3939
3940         dev_drv->cabc_mode = mode;
3941         cabc_en = (mode > 0) ? 1 : 0;
3942
3943         if (cabc_en == 0) {
3944                 spin_lock(&lcdc_dev->reg_lock);
3945                 if (lcdc_dev->clk_on) {
3946                         lcdc_msk_reg(lcdc_dev, CABC_CTRL0,
3947                                      m_CABC_EN, v_CABC_EN(0));
3948                         lcdc_cfg_done(lcdc_dev);
3949                 }
3950                 spin_unlock(&lcdc_dev->reg_lock);
3951                 return 0;
3952         }
3953
3954         total_pixel = screen->mode.xres * screen->mode.yres;
3955         pixel_num = 1000 - (cabc_mode[mode - 1].pixel_num);
3956         calc_pixel = (total_pixel * pixel_num) / 1000;
3957         stage_up = cabc_mode[mode - 1].stage_up;
3958         stage_down = cabc_mode[mode - 1].stage_down;
3959         global_su = cabc_mode[mode - 1].global_su;
3960
3961         stage_up_rec = 256 * 256 / stage_up;
3962         stage_down_rec = 256 * 256 / stage_down;
3963         global_su_rec = (256 * 256 / global_su) - 1;
3964         gamma_global_su_rec = cabc_lut[global_su_rec];
3965
3966         spin_lock(&lcdc_dev->reg_lock);
3967         if (lcdc_dev->clk_on) {
3968                 mask = m_CABC_CALC_PIXEL_NUM | m_CABC_EN;
3969                 val = v_CABC_CALC_PIXEL_NUM(calc_pixel) |
3970                         v_CABC_EN(cabc_en);
3971                 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
3972
3973                 mask = m_CABC_TOTAL_PIXEL_NUM | m_CABC_LUT_EN;
3974                 val = v_CABC_TOTAL_PIXEL_NUM(total_pixel) | v_CABC_LUT_EN(1);
3975                 lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
3976
3977                 mask = m_CABC_STAGE_UP | m_CABC_STAGE_UP_REC |
3978                     m_CABC_GLOBAL_SU_LIMIT_EN | m_CABC_GLOBAL_SU_REC;
3979                 val = v_CABC_STAGE_UP(stage_up) |
3980                     v_CABC_STAGE_UP_REC(stage_up_rec) |
3981                     v_CABC_GLOBAL_SU_LIMIT_EN(1) |
3982                     v_CABC_GLOBAL_SU_REC(gamma_global_su_rec);
3983                 lcdc_msk_reg(lcdc_dev, CABC_CTRL2, mask, val);
3984
3985                 mask = m_CABC_STAGE_DOWN | m_CABC_STAGE_DOWN_REC |
3986                     m_CABC_GLOBAL_SU;
3987                 val = v_CABC_STAGE_DOWN(stage_down) |
3988                     v_CABC_STAGE_DOWN_REC(stage_down_rec) |
3989                     v_CABC_GLOBAL_SU(global_su);
3990                 lcdc_msk_reg(lcdc_dev, CABC_CTRL3, mask, val);
3991                 lcdc_cfg_done(lcdc_dev);
3992         }
3993         spin_unlock(&lcdc_dev->reg_lock);
3994
3995         return 0;
3996 }
3997
3998 /*
3999         a:[-30~0]:
4000             sin_hue = sin(a)*256 +0x100;
4001             cos_hue = cos(a)*256;
4002         a:[0~30]
4003             sin_hue = sin(a)*256;
4004             cos_hue = cos(a)*256;
4005 */
4006 static int rk3368_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4007                                     bcsh_hue_mode mode)
4008 {
4009         struct lcdc_device *lcdc_dev =
4010             container_of(dev_drv, struct lcdc_device, driver);
4011         u32 val;
4012
4013         spin_lock(&lcdc_dev->reg_lock);
4014         if (lcdc_dev->clk_on) {
4015                 val = lcdc_readl(lcdc_dev, BCSH_H);
4016                 switch (mode) {
4017                 case H_SIN:
4018                         val &= m_BCSH_SIN_HUE;
4019                         break;
4020                 case H_COS:
4021                         val &= m_BCSH_COS_HUE;
4022                         val >>= 16;
4023                         break;
4024                 default:
4025                         break;
4026                 }
4027         }
4028         spin_unlock(&lcdc_dev->reg_lock);
4029
4030         return val;
4031 }
4032
4033 static int rk3368_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4034                                     int sin_hue, int cos_hue)
4035 {
4036         struct lcdc_device *lcdc_dev =
4037             container_of(dev_drv, struct lcdc_device, driver);
4038         u32 mask, val;
4039
4040         spin_lock(&lcdc_dev->reg_lock);
4041         if (lcdc_dev->clk_on) {
4042                 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
4043                 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
4044                 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
4045                 lcdc_cfg_done(lcdc_dev);
4046         }
4047         spin_unlock(&lcdc_dev->reg_lock);
4048
4049         return 0;
4050 }
4051
4052 static int rk3368_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4053                                     bcsh_bcs_mode mode, int value)
4054 {
4055         struct lcdc_device *lcdc_dev =
4056             container_of(dev_drv, struct lcdc_device, driver);
4057         u32 mask, val;
4058
4059         spin_lock(&lcdc_dev->reg_lock);
4060         if (lcdc_dev->clk_on) {
4061                 switch (mode) {
4062                 case BRIGHTNESS:
4063                         /*from 0 to 255,typical is 128 */
4064                         if (value < 0x80)
4065                                 value += 0x80;
4066                         else if (value >= 0x80)
4067                                 value = value - 0x80;
4068                         mask = m_BCSH_BRIGHTNESS;
4069                         val = v_BCSH_BRIGHTNESS(value);
4070                         break;
4071                 case CONTRAST:
4072                         /*from 0 to 510,typical is 256 */
4073                         mask = m_BCSH_CONTRAST;
4074                         val = v_BCSH_CONTRAST(value);
4075                         break;
4076                 case SAT_CON:
4077                         /*from 0 to 1015,typical is 256 */
4078                         mask = m_BCSH_SAT_CON;
4079                         val = v_BCSH_SAT_CON(value);
4080                         break;
4081                 default:
4082                         break;
4083                 }
4084                 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
4085                 lcdc_cfg_done(lcdc_dev);
4086         }
4087         spin_unlock(&lcdc_dev->reg_lock);
4088         return val;
4089 }
4090
4091 static int rk3368_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4092                                     bcsh_bcs_mode mode)
4093 {
4094         struct lcdc_device *lcdc_dev =
4095             container_of(dev_drv, struct lcdc_device, driver);
4096         u32 val;
4097
4098         spin_lock(&lcdc_dev->reg_lock);
4099         if (lcdc_dev->clk_on) {
4100                 val = lcdc_readl(lcdc_dev, BCSH_BCS);
4101                 switch (mode) {
4102                 case BRIGHTNESS:
4103                         val &= m_BCSH_BRIGHTNESS;
4104                         if (val > 0x80)
4105                                 val -= 0x80;
4106                         else
4107                                 val += 0x80;
4108                         break;
4109                 case CONTRAST:
4110                         val &= m_BCSH_CONTRAST;
4111                         val >>= 8;
4112                         break;
4113                 case SAT_CON:
4114                         val &= m_BCSH_SAT_CON;
4115                         val >>= 20;
4116                         break;
4117                 default:
4118                         break;
4119                 }
4120         }
4121         spin_unlock(&lcdc_dev->reg_lock);
4122         return val;
4123 }
4124
4125 static int rk3368_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
4126 {
4127         struct lcdc_device *lcdc_dev =
4128             container_of(dev_drv, struct lcdc_device, driver);
4129         u32 mask, val;
4130
4131         spin_lock(&lcdc_dev->reg_lock);
4132         if (lcdc_dev->clk_on) {
4133                 if (open) {
4134                         lcdc_writel(lcdc_dev, BCSH_COLOR_BAR, 0x1);
4135                         lcdc_writel(lcdc_dev, BCSH_BCS, 0xd0010000);
4136                         lcdc_writel(lcdc_dev, BCSH_H, 0x01000000);
4137                         dev_drv->bcsh.enable = 1;
4138                 } else {
4139                         mask = m_BCSH_EN;
4140                         val = v_BCSH_EN(0);
4141                         lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
4142                         dev_drv->bcsh.enable = 0;
4143                 }
4144                 rk3368_lcdc_bcsh_path_sel(dev_drv);
4145                 lcdc_cfg_done(lcdc_dev);
4146         }
4147         spin_unlock(&lcdc_dev->reg_lock);
4148         return 0;
4149 }
4150
4151 static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
4152 {
4153         if (!enable || !dev_drv->bcsh.enable) {
4154                 rk3368_lcdc_open_bcsh(dev_drv, false);
4155                 return 0;
4156         }
4157
4158         if (dev_drv->bcsh.brightness <= 255 ||
4159             dev_drv->bcsh.contrast <= 510 ||
4160             dev_drv->bcsh.sat_con <= 1015 ||
4161             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
4162                 rk3368_lcdc_open_bcsh(dev_drv, true);
4163                 if (dev_drv->bcsh.brightness <= 255)
4164                         rk3368_lcdc_set_bcsh_bcs(dev_drv, BRIGHTNESS,
4165                                                  dev_drv->bcsh.brightness);
4166                 if (dev_drv->bcsh.contrast <= 510)
4167                         rk3368_lcdc_set_bcsh_bcs(dev_drv, CONTRAST,
4168                                                  dev_drv->bcsh.contrast);
4169                 if (dev_drv->bcsh.sat_con <= 1015)
4170                         rk3368_lcdc_set_bcsh_bcs(dev_drv, SAT_CON,
4171                                                  dev_drv->bcsh.sat_con);
4172                 if (dev_drv->bcsh.sin_hue <= 511 &&
4173                     dev_drv->bcsh.cos_hue <= 511)
4174                         rk3368_lcdc_set_bcsh_hue(dev_drv,
4175                                                  dev_drv->bcsh.sin_hue,
4176                                                  dev_drv->bcsh.cos_hue);
4177         }
4178         return 0;
4179 }
4180
4181 static int rk3368_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
4182 {
4183         struct lcdc_device *lcdc_dev =
4184             container_of(dev_drv, struct lcdc_device, driver);
4185
4186         if (enable) {
4187                 spin_lock(&lcdc_dev->reg_lock);
4188                 if (likely(lcdc_dev->clk_on)) {
4189                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
4190                                      v_DSP_BLACK_EN(1));
4191                         lcdc_cfg_done(lcdc_dev);
4192                 }
4193                 spin_unlock(&lcdc_dev->reg_lock);
4194         } else {
4195                 spin_lock(&lcdc_dev->reg_lock);
4196                 if (likely(lcdc_dev->clk_on)) {
4197                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
4198                                      v_DSP_BLACK_EN(0));
4199
4200                         lcdc_cfg_done(lcdc_dev);
4201                 }
4202                 spin_unlock(&lcdc_dev->reg_lock);
4203         }
4204
4205         return 0;
4206 }
4207
4208
4209 static int rk3368_lcdc_backlight_close(struct rk_lcdc_driver *dev_drv,
4210                                        int enable)
4211 {
4212         struct lcdc_device *lcdc_dev =
4213             container_of(dev_drv, struct lcdc_device, driver);
4214
4215         rk3368_lcdc_get_backlight_device(dev_drv);
4216
4217         if (enable) {
4218                 /* close the backlight */
4219                 if (lcdc_dev->backlight) {
4220                         lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
4221                         backlight_update_status(lcdc_dev->backlight);
4222                 }
4223                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4224                         dev_drv->trsm_ops->disable();
4225         } else {
4226                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
4227                         dev_drv->trsm_ops->enable();
4228                 msleep(100);
4229                 /* open the backlight */
4230                 if (lcdc_dev->backlight) {
4231                         lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
4232                         backlight_update_status(lcdc_dev->backlight);
4233                 }
4234         }
4235
4236         return 0;
4237 }
4238
4239 static int rk3368_lcdc_set_overscan(struct rk_lcdc_driver *dev_drv,
4240                                     struct overscan *overscan)
4241 {
4242         rk3368_lcdc_post_cfg(dev_drv);
4243
4244         return 0;
4245 }
4246
4247 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
4248         .open = rk3368_lcdc_open,
4249         .win_direct_en = rk3368_lcdc_win_direct_en,
4250         .load_screen = rk3368_load_screen,
4251         .get_dspbuf_info = rk3368_get_dspbuf_info,
4252         .post_dspbuf = rk3368_post_dspbuf,
4253         .set_par = rk3368_lcdc_set_par,
4254         .pan_display = rk3368_lcdc_pan_display,
4255         .direct_set_addr = rk3368_lcdc_direct_set_win_addr,
4256         /*.lcdc_reg_update = rk3368_lcdc_reg_update,*/
4257         .blank = rk3368_lcdc_blank,
4258         .ioctl = rk3368_lcdc_ioctl,
4259         .suspend = rk3368_lcdc_early_suspend,
4260         .resume = rk3368_lcdc_early_resume,
4261         .get_win_state = rk3368_lcdc_get_win_state,
4262         .ovl_mgr = rk3368_lcdc_ovl_mgr,
4263         .get_disp_info = rk3368_lcdc_get_disp_info,
4264         .fps_mgr = rk3368_lcdc_fps_mgr,
4265         .fb_get_win_id = rk3368_lcdc_get_win_id,
4266         .fb_win_remap = rk3368_fb_win_remap,
4267         .set_dsp_lut = rk3368_lcdc_set_lut,
4268         .set_cabc_lut = rk3368_set_cabc_lut,
4269         .poll_vblank = rk3368_lcdc_poll_vblank,
4270         .dpi_open = rk3368_lcdc_dpi_open,
4271         .dpi_win_sel = rk3368_lcdc_dpi_win_sel,
4272         .dpi_status = rk3368_lcdc_dpi_status,
4273         .get_dsp_addr = rk3368_lcdc_get_dsp_addr,
4274         .set_dsp_cabc = rk3368_lcdc_set_dsp_cabc,
4275         .set_dsp_bcsh_hue = rk3368_lcdc_set_bcsh_hue,
4276         .set_dsp_bcsh_bcs = rk3368_lcdc_set_bcsh_bcs,
4277         .get_dsp_bcsh_hue = rk3368_lcdc_get_bcsh_hue,
4278         .get_dsp_bcsh_bcs = rk3368_lcdc_get_bcsh_bcs,
4279         .open_bcsh = rk3368_lcdc_open_bcsh,
4280         .dump_reg = rk3368_lcdc_reg_dump,
4281         .cfg_done = rk3368_lcdc_config_done,
4282         .set_irq_to_cpu = rk3368_lcdc_set_irq_to_cpu,
4283         .dsp_black = rk3368_lcdc_dsp_black,
4284         .backlight_close = rk3368_lcdc_backlight_close,
4285         .mmu_en    = rk3368_lcdc_mmu_en,
4286         .set_overscan   = rk3368_lcdc_set_overscan,
4287 };
4288
4289 #ifdef LCDC_IRQ_EMPTY_DEBUG
4290 static int rk3368_lcdc_parse_irq(struct lcdc_device *lcdc_dev,
4291                                  unsigned int intr_status)
4292 {
4293         if (intr_status & m_WIN0_EMPTY_INTR_STS) {
4294                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN0_EMPTY_INTR_CLR,
4295                              v_WIN0_EMPTY_INTR_CLR(1));
4296                 dev_warn(lcdc_dev->dev, "win0 empty irq!");
4297         } else if (intr_status & m_WIN1_EMPTY_INTR_STS) {
4298                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN1_EMPTY_INTR_CLR,
4299                              v_WIN1_EMPTY_INTR_CLR(1));
4300                 dev_warn(lcdc_dev->dev, "win1 empty irq!");
4301         } else if (intr_status & m_WIN2_EMPTY_INTR_STS) {
4302                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN2_EMPTY_INTR_CLR,
4303                              v_WIN2_EMPTY_INTR_CLR(1));
4304                 dev_warn(lcdc_dev->dev, "win2 empty irq!");
4305         } else if (intr_status & m_WIN3_EMPTY_INTR_STS) {
4306                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN3_EMPTY_INTR_CLR,
4307                              v_WIN3_EMPTY_INTR_CLR(1));
4308                 dev_warn(lcdc_dev->dev, "win3 empty irq!");
4309         } else if (intr_status & m_HWC_EMPTY_INTR_STS) {
4310                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_HWC_EMPTY_INTR_CLR,
4311                              v_HWC_EMPTY_INTR_CLR(1));
4312                 dev_warn(lcdc_dev->dev, "HWC empty irq!");
4313         } else if (intr_status & m_POST_BUF_EMPTY_INTR_STS) {
4314                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_POST_BUF_EMPTY_INTR_CLR,
4315                              v_POST_BUF_EMPTY_INTR_CLR(1));
4316                 dev_warn(lcdc_dev->dev, "post buf empty irq!");
4317         } else if (intr_status & m_PWM_GEN_INTR_STS) {
4318                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_PWM_GEN_INTR_CLR,
4319                              v_PWM_GEN_INTR_CLR(1));
4320                 dev_warn(lcdc_dev->dev, "PWM gen irq!");
4321         }
4322         return 0;
4323 }
4324 #endif
4325
4326 static irqreturn_t rk3368_lcdc_isr(int irq, void *dev_id)
4327 {
4328         struct lcdc_device *lcdc_dev = (struct lcdc_device *)dev_id;
4329         ktime_t timestamp = ktime_get();
4330         u32 intr_status;
4331
4332         intr_status = lcdc_readl(lcdc_dev, INTR_STATUS);
4333
4334         if (intr_status & m_FS_INTR_STS) {
4335                 timestamp = ktime_get();
4336                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_INTR_CLR,
4337                              v_FS_INTR_CLR(1));
4338                 /*if(lcdc_dev->driver.wait_fs){ */
4339                 if (0) {
4340                         spin_lock(&(lcdc_dev->driver.cpl_lock));
4341                         complete(&(lcdc_dev->driver.frame_done));
4342                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
4343                 }
4344 #ifdef CONFIG_DRM_ROCKCHIP
4345                 lcdc_dev->driver.irq_call_back(&lcdc_dev->driver);
4346 #endif
4347                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
4348                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
4349
4350         } else if (intr_status & m_LINE_FLAG0_INTR_STS) {
4351                 lcdc_dev->driver.frame_time.last_framedone_t =
4352                     lcdc_dev->driver.frame_time.framedone_t;
4353                 lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
4354                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG0_INTR_CLR,
4355                              v_LINE_FLAG0_INTR_CLR(1));
4356         } else if (intr_status & m_LINE_FLAG1_INTR_STS) {
4357                 /*line flag1 */
4358                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG1_INTR_CLR,
4359                              v_LINE_FLAG1_INTR_CLR(1));
4360         } else if (intr_status & m_FS_NEW_INTR_STS) {
4361                 /*new frame start */
4362                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_NEW_INTR_CLR,
4363                              v_FS_NEW_INTR_CLR(1));
4364         } else if (intr_status & m_BUS_ERROR_INTR_STS) {
4365                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_BUS_ERROR_INTR_CLR,
4366                              v_BUS_ERROR_INTR_CLR(1));
4367                 dev_warn(lcdc_dev->dev, "bus error!");
4368         }
4369
4370         /* for win empty debug */
4371 #ifdef LCDC_IRQ_EMPTY_DEBUG
4372         rk3368_lcdc_parse_irq(lcdc_dev, intr_status);
4373 #endif
4374         return IRQ_HANDLED;
4375 }
4376
4377 #if defined(CONFIG_PM)
4378 static int rk3368_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
4379 {
4380         return 0;
4381 }
4382
4383 static int rk3368_lcdc_resume(struct platform_device *pdev)
4384 {
4385         return 0;
4386 }
4387 #else
4388 #define rk3368_lcdc_suspend NULL
4389 #define rk3368_lcdc_resume  NULL
4390 #endif
4391
4392 static int rk3368_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
4393 {
4394         struct device_node *np = lcdc_dev->dev->of_node;
4395         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
4396         int val;
4397
4398         if (of_property_read_u32(np, "rockchip,prop", &val))
4399                 lcdc_dev->prop = PRMRY; /*default set it as primary */
4400         else
4401                 lcdc_dev->prop = val;
4402
4403         if (of_property_read_u32(np, "rockchip,mirror", &val))
4404                 dev_drv->rotate_mode = NO_MIRROR;
4405         else
4406                 dev_drv->rotate_mode = val;
4407
4408         if (of_property_read_u32(np, "rockchip,cabc_mode", &val))
4409                 dev_drv->cabc_mode = 0; /* default set close cabc */
4410         else
4411                 dev_drv->cabc_mode = val;
4412
4413         if (of_property_read_u32(np, "rockchip,pwr18", &val))
4414                 /*default set it as 3.xv power supply */
4415                 lcdc_dev->pwr18 = false;
4416         else
4417                 lcdc_dev->pwr18 = (val ? true : false);
4418
4419         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
4420                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
4421         else
4422                 dev_drv->fb_win_map = val;
4423
4424         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
4425                 dev_drv->bcsh.enable = false;
4426         else
4427                 dev_drv->bcsh.enable = (val ? true : false);
4428
4429         if (of_property_read_u32(np, "rockchip,brightness", &val))
4430                 dev_drv->bcsh.brightness = 0xffff;
4431         else
4432                 dev_drv->bcsh.brightness = val;
4433
4434         if (of_property_read_u32(np, "rockchip,contrast", &val))
4435                 dev_drv->bcsh.contrast = 0xffff;
4436         else
4437                 dev_drv->bcsh.contrast = val;
4438
4439         if (of_property_read_u32(np, "rockchip,sat-con", &val))
4440                 dev_drv->bcsh.sat_con = 0xffff;
4441         else
4442                 dev_drv->bcsh.sat_con = val;
4443
4444         if (of_property_read_u32(np, "rockchip,hue", &val)) {
4445                 dev_drv->bcsh.sin_hue = 0xffff;
4446                 dev_drv->bcsh.cos_hue = 0xffff;
4447         } else {
4448                 dev_drv->bcsh.sin_hue = val & 0xff;
4449                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
4450         }
4451
4452 #if defined(CONFIG_ROCKCHIP_IOMMU)
4453         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
4454                 dev_drv->iommu_enabled = 0;
4455         else
4456                 dev_drv->iommu_enabled = val;
4457 #else
4458         dev_drv->iommu_enabled = 0;
4459 #endif
4460         return 0;
4461 }
4462
4463 static int rk3368_lcdc_probe(struct platform_device *pdev)
4464 {
4465         struct lcdc_device *lcdc_dev = NULL;
4466         struct rk_lcdc_driver *dev_drv;
4467         struct device *dev = &pdev->dev;
4468         struct resource *res;
4469         struct device_node *np = pdev->dev.of_node;
4470         int prop;
4471         int ret = 0;
4472
4473         /*if the primary lcdc has not registered ,the extend
4474            lcdc register later */
4475         of_property_read_u32(np, "rockchip,prop", &prop);
4476         if (prop == EXTEND) {
4477                 if (!is_prmry_rk_lcdc_registered())
4478                         return -EPROBE_DEFER;
4479         }
4480         lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
4481         if (!lcdc_dev) {
4482                 dev_err(&pdev->dev, "rk3368 lcdc device kmalloc fail!");
4483                 return -ENOMEM;
4484         }
4485         platform_set_drvdata(pdev, lcdc_dev);
4486         lcdc_dev->dev = dev;
4487         rk3368_lcdc_parse_dt(lcdc_dev);
4488         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4489         lcdc_dev->reg_phy_base = res->start;
4490         lcdc_dev->len = resource_size(res);
4491         lcdc_dev->regs = devm_ioremap_resource(dev, res);
4492         if (IS_ERR(lcdc_dev->regs))
4493                 return PTR_ERR(lcdc_dev->regs);
4494         else
4495                 dev_info(dev, "lcdc_dev->regs=0x%lx\n", (long)lcdc_dev->regs);
4496
4497         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
4498         if (IS_ERR(lcdc_dev->regsbak))
4499                 return PTR_ERR(lcdc_dev->regsbak);
4500         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
4501         lcdc_dev->cabc_lut_addr_base = (lcdc_dev->regs + CABC_GAMMA_LUT_ADDR);
4502         lcdc_dev->grf_base =
4503                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
4504         if (IS_ERR(lcdc_dev->grf_base)) {
4505                 dev_err(&pdev->dev, "can't find lcdc grf property\n");
4506                 return PTR_ERR(lcdc_dev->grf_base);
4507         }
4508         lcdc_dev->pmugrf_base =
4509                 syscon_regmap_lookup_by_phandle(np, "rockchip,pmugrf");
4510         if (IS_ERR(lcdc_dev->pmugrf_base)) {
4511                 dev_err(&pdev->dev, "can't find lcdc pmu grf property\n");
4512                 return PTR_ERR(lcdc_dev->pmugrf_base);
4513         }
4514         lcdc_dev->id = 0;
4515         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
4516         dev_drv = &lcdc_dev->driver;
4517         dev_drv->dev = dev;
4518         dev_drv->prop = prop;
4519         dev_drv->id = lcdc_dev->id;
4520         dev_drv->ops = &lcdc_drv_ops;
4521         dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
4522         spin_lock_init(&lcdc_dev->reg_lock);
4523
4524         lcdc_dev->irq = platform_get_irq(pdev, 0);
4525         if (lcdc_dev->irq < 0) {
4526                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
4527                         lcdc_dev->id);
4528                 return -ENXIO;
4529         }
4530
4531         ret = devm_request_irq(dev, lcdc_dev->irq, rk3368_lcdc_isr,
4532                                IRQF_DISABLED | IRQF_SHARED,
4533                                dev_name(dev), lcdc_dev);
4534         if (ret) {
4535                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
4536                         lcdc_dev->irq, ret);
4537                 return ret;
4538         }
4539
4540         if (dev_drv->iommu_enabled) {
4541                 if (lcdc_dev->id == 0) {
4542                         strcpy(dev_drv->mmu_dts_name,
4543                                VOPB_IOMMU_COMPATIBLE_NAME);
4544                 } else {
4545                         strcpy(dev_drv->mmu_dts_name,
4546                                VOPL_IOMMU_COMPATIBLE_NAME);
4547                 }
4548         }
4549
4550         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
4551         if (ret < 0) {
4552                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
4553                 return ret;
4554         }
4555         lcdc_dev->screen = dev_drv->screen0;
4556         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
4557                  lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
4558
4559         return 0;
4560 }
4561
4562 static int rk3368_lcdc_remove(struct platform_device *pdev)
4563 {
4564         return 0;
4565 }
4566
4567 static void rk3368_lcdc_shutdown(struct platform_device *pdev)
4568 {
4569         struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
4570
4571         rk3368_lcdc_early_suspend(&lcdc_dev->driver);
4572         rk3368_lcdc_deint(lcdc_dev);
4573 }
4574
4575 #if defined(CONFIG_OF)
4576 static const struct of_device_id rk3368_lcdc_dt_ids[] = {
4577         {.compatible = "rockchip,rk3368-lcdc",},
4578         {}
4579 };
4580 #endif
4581
4582 static struct platform_driver rk3368_lcdc_driver = {
4583         .probe = rk3368_lcdc_probe,
4584         .remove = rk3368_lcdc_remove,
4585         .driver = {
4586                    .name = "rk3368-lcdc",
4587                    .owner = THIS_MODULE,
4588                    .of_match_table = of_match_ptr(rk3368_lcdc_dt_ids),
4589                    },
4590         .suspend = rk3368_lcdc_suspend,
4591         .resume = rk3368_lcdc_resume,
4592         .shutdown = rk3368_lcdc_shutdown,
4593 };
4594
4595 static int __init rk3368_lcdc_module_init(void)
4596 {
4597         return platform_driver_register(&rk3368_lcdc_driver);
4598 }
4599
4600 static void __exit rk3368_lcdc_module_exit(void)
4601 {
4602         platform_driver_unregister(&rk3368_lcdc_driver);
4603 }
4604
4605 fs_initcall(rk3368_lcdc_module_init);
4606 module_exit(rk3368_lcdc_module_exit);