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