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