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