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