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