b689e9c33752cd0b02f25f32d7a5ddc9e6f63dcb
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3188_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3188_lcdc.c
3  *
4  * Copyright (C) 2013 ROCKCHIP, Inc.
5  *Author:yxj<yxj@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 <asm/div64.h>
30 #include <asm/uaccess.h>
31 #include <linux/rockchip/cpu.h>
32 #include <linux/rockchip/iomap.h>
33 #include <linux/rockchip/grf.h>
34
35 #include "rk3188_lcdc.h"
36
37
38 static int dbg_thresd;
39 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
40
41 #define DBG(level, x...) do {                   \
42         if (unlikely(dbg_thresd >= level))      \
43                 printk(KERN_INFO x); } while (0)
44
45 //#define WAIT_FOR_SYNC 1
46
47 static int rk3188_lcdc_get_id(u32 phy_base)
48 {
49         if (cpu_is_rk319x()) {
50                 if (phy_base == 0xffc40000)
51                         return 0;
52                 else if (phy_base == 0xffc50000)
53                         return 1;
54                 else
55                         return -EINVAL;
56         } else if (cpu_is_rk3188()) {
57                 if (phy_base == 0x1010c000)
58                         return 0;
59                 else if (phy_base == 0x1010e000)
60                         return 1;
61                 else
62                         return -EINVAL;
63         } else if (cpu_is_rk3026()) {
64                 if (phy_base == 0x1010e000)
65                         return 0;
66                 else if (phy_base == 0x01110000)
67                         return 1;
68                 else
69                         return -EINVAL;
70         } else {
71                 pr_err("un supported platform \n");
72                 return -EINVAL;
73         }
74
75 }
76
77 static int rk3188_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
78 {
79         int i = 0;
80         int __iomem *c;
81         int v;
82         struct lcdc_device *lcdc_dev = container_of(dev_drv,
83                                                            struct
84                                                            lcdc_device,
85                                                            driver);
86         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
87         lcdc_cfg_done(lcdc_dev);
88         mdelay(25);
89         for (i = 0; i < 256; i++) {
90                 v = dev_drv->cur_screen->dsp_lut[i];
91                 c = lcdc_dev->dsp_lut_addr_base + i;
92                 writel_relaxed(v, c);
93
94         }
95         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
96
97         return 0;
98
99 }
100
101 static int rk3188_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
102 {
103
104         if (!lcdc_dev->clk_on) {
105                 clk_prepare_enable(lcdc_dev->hclk);
106                 clk_prepare_enable(lcdc_dev->dclk);
107                 clk_prepare_enable(lcdc_dev->aclk);
108                 //clk_enable(lcdc_dev->pd);
109                 spin_lock(&lcdc_dev->reg_lock);
110                 lcdc_dev->clk_on = 1;
111                 spin_unlock(&lcdc_dev->reg_lock);
112         }
113         return 0;
114 }
115
116 static int rk3188_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
117 {
118         if (lcdc_dev->clk_on) {
119                 spin_lock(&lcdc_dev->reg_lock);
120                 lcdc_dev->clk_on = 0;
121                 spin_unlock(&lcdc_dev->reg_lock);
122                 mdelay(25);
123                 clk_disable_unprepare(lcdc_dev->dclk);
124                 clk_disable_unprepare(lcdc_dev->hclk);
125                 clk_disable_unprepare(lcdc_dev->aclk);
126                 //clk_disable(lcdc_dev->pd);
127         }
128         return 0;
129 }
130
131 static int rk3188_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
132 {
133         struct lcdc_device *lcdc_dev = container_of(dev_drv,
134                                                 struct lcdc_device,
135                                                 driver);
136         int *cbase = (int *)lcdc_dev->regs;
137         int *regsbak = (int *)lcdc_dev->regsbak;
138         int i, j;
139
140         printk("back up reg:\n");
141         for (i = 0; i <= (0x90 >> 4); i++) {
142                 for (j = 0; j < 4; j++)
143                         printk("%08x  ", *(regsbak + i * 4 + j));
144                 printk("\n");
145         }
146
147         printk("lcdc reg:\n");
148         for (i = 0; i <= (0x90 >> 4); i++) {
149                 for (j = 0; j < 4; j++)
150                         printk("%08x  ", readl_relaxed(cbase + i * 4 + j));
151                 printk("\n");
152         }
153         return 0;
154 }
155
156 static void rk3188_lcdc_read_reg_defalut_cfg(struct lcdc_device
157                                              *lcdc_dev)
158 {
159         int reg = 0;
160         u32 value = 0;
161         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
162         struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
163
164         spin_lock(&lcdc_dev->reg_lock);
165         for (reg = 0; reg < REG_CFG_DONE; reg += 4) {
166                 value = lcdc_readl(lcdc_dev, reg);
167                 switch (reg) {
168                 case SYS_CTRL:
169                         lcdc_dev->standby = (value & m_LCDC_STANDBY) >> 17;
170                         win0->state = (value & m_WIN0_EN) >> 0;
171                         win1->state = (value & m_WIN1_EN) >> 1;
172                         if (lcdc_dev->id == 0)
173                                 lcdc_dev->atv_layer_cnt = win0->state;
174                         else
175                                 lcdc_dev->atv_layer_cnt = win1->state;
176                         win0->area[0].swap_rb = (value & m_WIN0_RB_SWAP) >> 15;
177                         win1->area[0].swap_rb = (value & m_WIN1_RB_SWAP) >> 19;
178                         win0->area[0].fmt_cfg = (value & m_WIN0_FORMAT) >> 3;
179                         win1->area[0].fmt_cfg = (value & m_WIN1_FORMAT) >> 6;
180                         break;
181                 case WIN0_SCL_FACTOR_YRGB:
182                         win0->scale_yrgb_x = (value >> 0) & 0xffff;
183                         win0->scale_yrgb_y = (value >> 16) & 0xffff;
184                         break;
185                 case WIN0_SCL_FACTOR_CBR:
186                         win0->scale_cbcr_x = (value >> 0) & 0xffff;
187                         win0->scale_cbcr_y = (value >> 16) & 0xffff;
188                         break;
189                 case WIN0_ACT_INFO:
190                         win0->area[0].xact = (((value >> 0) & 0x1fff) + 1);
191                         win0->area[0].yact = (((value >> 16) & 0x1fff) + 1);
192                         break;
193                 case WIN0_DSP_ST:
194                         win0->area[0].dsp_stx = (value >> 0) & 0xfff;
195                         win0->area[0].dsp_sty = (value >> 16) & 0xfff;
196                         break;
197                 case WIN0_DSP_INFO:
198                         win0->area[0].xsize = (((value >> 0) & 0x7ff) + 1);
199                         win0->area[0].ysize = (((value >> 16) & 0x7ff) + 1);
200                         break;
201                 case WIN_VIR:
202                         win0->area[0].y_vir_stride = (value >> 0) & 0x1fff;
203                         win1->area[0].y_vir_stride = (value) & 0x1fff0000;
204                         break;
205                 case WIN0_YRGB_MST0:
206                         win0->area[0].y_addr = value >> 0;
207                         break;
208                 case WIN0_CBR_MST0:
209                         win0->area[0].uv_addr = value >> 0;
210                         break;
211                 case WIN1_DSP_INFO:
212                         win1->area[0].xsize = (((value >> 0) & 0x7ff) + 1);
213                         win1->area[0].ysize = (((value >> 16) & 0x7ff) + 1);
214                         break;
215                 case WIN1_DSP_ST:
216                         win1->area[0].dsp_stx = (value >> 0) & 0xfff;
217                         win1->area[0].dsp_sty = (value >> 16) & 0xfff;
218                         break;
219                 case WIN1_MST:
220                         win1->area[0].y_addr = value >> 0;
221                         break;
222                 default:
223                         DBG(2, "%s:uncare reg\n", __func__);
224                         break;
225                 }
226         }
227         spin_unlock(&lcdc_dev->reg_lock);
228 }
229
230 /********do basic init*********/
231 static int rk3188_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
232 {
233         int v;
234         struct lcdc_device *lcdc_dev = container_of(dev_drv,
235                                                            struct
236                                                            lcdc_device,
237                                                            driver);
238
239         if (lcdc_dev->pre_init)
240                 return 0;
241
242         if (lcdc_dev->id == 0) {
243                 //lcdc_dev->pd  = clk_get(NULL,"pd_lcdc0");
244                 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc0");
245                 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc0");
246                 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc0");
247         } else if (lcdc_dev->id == 1) {
248                 //lcdc_dev->pd  = clk_get(NULL,"pd_lcdc1");
249                 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc1");
250                 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc1");
251                 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc1");
252         } else {
253                 dev_err(lcdc_dev->dev, "invalid lcdc device!\n");
254                 return -EINVAL;
255         }
256         if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
257             (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
258                 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
259                         lcdc_dev->id);
260         }
261
262         /*uboot display has enabled lcdc in boot */
263         if (!support_uboot_display()) {
264                 rk_disp_pwr_enable(dev_drv);
265                 rk3188_lcdc_clk_enable(lcdc_dev);
266         } else {
267                 lcdc_dev->clk_on = 1;
268         }
269
270         rk3188_lcdc_read_reg_defalut_cfg(lcdc_dev);
271
272         if (lcdc_dev->id == 0) {
273                 if (lcdc_dev->pwr18 == true) {
274                         v = 0x40004000; /*bit14: 1,1.8v;0,3.3v*/
275                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
276                 } else {
277                         v = 0x40000000;
278                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
279                 }
280         }
281
282         if (lcdc_dev->id == 1) {
283                 if (lcdc_dev->pwr18 == true) {
284                         v = 0x80008000; /*bit14: 1,1.8v;0,3.3v*/
285                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
286                 } else {
287                         v = 0x80000000;
288                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
289                 }
290                 pinctrl_select_state(lcdc_dev->dev->pins->p,
291                                      lcdc_dev->dev->pins->default_state);
292         }
293
294         lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN);
295         lcdc_cfg_done(lcdc_dev);
296         lcdc_dev->pre_init = true;
297
298         return 0;
299 }
300
301 static void rk3188_lcdc_deint(struct lcdc_device *lcdc_dev)
302 {
303         u32 mask, val;
304         spin_lock(&lcdc_dev->reg_lock);
305         if (likely(lcdc_dev->clk_on)) {
306                 lcdc_dev->clk_on = 0;
307                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
308                              v_FS_INT_CLEAR(1));
309                 mask = m_HS_INT_EN | m_FS_INT_EN | m_LF_INT_EN |
310                         m_BUS_ERR_INT_EN;
311                 val = v_HS_INT_EN(0) | v_FS_INT_EN(0) |
312                         v_LF_INT_EN(0) | v_BUS_ERR_INT_EN(0);
313                 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
314                 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
315                 lcdc_cfg_done(lcdc_dev);
316                 spin_unlock(&lcdc_dev->reg_lock);
317         } else {
318                 spin_unlock(&lcdc_dev->reg_lock);
319         }
320         mdelay(1);
321
322 }
323
324 static int rk3188_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
325 {
326         int win0_top = 0;
327         u32 mask, val;
328         enum data_format win0_format = lcdc_dev->driver.win[0]->area[0].format;
329         enum data_format win1_format = lcdc_dev->driver.win[1]->area[0].format;
330
331         int win0_alpha_en = ((win0_format == ARGB888)
332                              || (win0_format == ABGR888)) ? 1 : 0;
333         int win1_alpha_en = ((win1_format == ARGB888)
334                              || (win1_format == ABGR888)) ? 1 : 0;
335         u32 *_pv = (u32 *) lcdc_dev->regsbak;
336         _pv += (DSP_CTRL0 >> 2);
337         win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
338         if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
339                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, m_WIN0_ALPHA_EN |
340                              m_WIN1_ALPHA_EN, v_WIN0_ALPHA_EN(1) |
341                              v_WIN1_ALPHA_EN(0));
342                 mask = m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
343                 val = v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
344                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
345         } else if ((!win0_top) && (lcdc_dev->atv_layer_cnt >= 2)
346                    && (win1_alpha_en)) {
347                 mask =  m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
348                 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1);
349                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
350
351                 mask = m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
352                 val = v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
353                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
354         } else {
355                 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
356                 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
357                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
358         }
359
360         return 0;
361 }
362
363 static int rk3188_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
364 {
365         struct lcdc_device *lcdc_dev =
366             container_of(dev_drv, struct lcdc_device, driver);
367         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
368         struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
369         int timeout;
370         unsigned long flags;
371         spin_lock(&lcdc_dev->reg_lock);
372         if (likely(lcdc_dev->clk_on)) {
373                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
374                              v_LCDC_STANDBY(lcdc_dev->standby));
375                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
376                              m_WIN0_EN | m_WIN1_EN | m_WIN0_RB_SWAP |
377                              m_WIN1_RB_SWAP,
378                              v_WIN0_EN(win0->state) | v_WIN1_EN(win1->state) |
379                              v_WIN0_RB_SWAP(win0->area[0].swap_rb) |
380                              v_WIN1_RB_SWAP(win1->area[0].swap_rb));
381                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
382                             v_X_SCL_FACTOR(win0->scale_yrgb_x) |
383                             v_Y_SCL_FACTOR(win0->scale_yrgb_y));
384                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
385                             v_X_SCL_FACTOR(win0->scale_cbcr_x) |
386                             v_Y_SCL_FACTOR(win0->scale_cbcr_y));
387                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT,
388                              v_WIN0_FORMAT(win0->area[0].fmt_cfg));
389                 lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->area[0].xact) |
390                             v_ACT_HEIGHT(win0->area[0].yact));
391                 lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->area[0].dsp_stx) |
392                             v_DSP_STY(win0->area[0].dsp_sty));
393                 lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->area[0].xsize) |
394                             v_DSP_HEIGHT(win0->area[0].ysize));
395                 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN0_VIR,
396                              v_WIN0_VIR_VAL(win0->area[0].y_vir_stride));
397                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, win0->area[0].y_addr);
398                 lcdc_writel(lcdc_dev, WIN0_CBR_MST0, win0->area[0].uv_addr);
399                 lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->area[0].xsize) |
400                             v_DSP_HEIGHT(win1->area[0].ysize));
401                 lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->area[0].dsp_stx) |
402                             v_DSP_STY(win1->area[0].dsp_sty));
403                 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN1_VIR,
404                              ((win1->area[0].y_vir_stride)&0x1fff)<<16);
405                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_FORMAT,
406                              v_WIN1_FORMAT(win1->area[0].fmt_cfg));
407                 lcdc_writel(lcdc_dev, WIN1_MST, win1->area[0].y_addr);
408                 rk3188_lcdc_alpha_cfg(lcdc_dev);
409                 lcdc_cfg_done(lcdc_dev);
410
411         }
412         spin_unlock(&lcdc_dev->reg_lock);
413         //if (dev_drv->wait_fs) {
414         if (0) {
415                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
416                 init_completion(&dev_drv->frame_done);
417                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
418                 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
419                                                       msecs_to_jiffies
420                                                       (dev_drv->cur_screen->ft +
421                                                        5));
422                 if (!timeout && (!dev_drv->frame_done.done)) {
423                         dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
424                         return -ETIMEDOUT;
425                 }
426         }
427         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
428         return 0;
429
430 }
431
432 static int rk3188_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
433 {
434         memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x84);
435         return 0;
436 }
437
438
439 static int rk3188_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
440 {
441         int ret = -EINVAL;
442         int fps;
443         u16 face = 0;
444         struct lcdc_device *lcdc_dev = container_of(dev_drv,
445                                                 struct lcdc_device, driver);
446         struct rk_screen *screen = dev_drv->cur_screen;
447         u16 right_margin = screen->mode.right_margin;
448         u16 left_margin = screen->mode.left_margin;
449         u16 lower_margin = screen->mode.lower_margin;
450         u16 upper_margin = screen->mode.upper_margin;
451         u16 x_res = screen->mode.xres;
452         u16 y_res = screen->mode.yres;
453         u32 mask, val;
454
455         spin_lock(&lcdc_dev->reg_lock);
456         if (likely(lcdc_dev->clk_on)) {
457                 switch (screen->face) {
458                 case OUT_P565:
459                         face = OUT_P565;
460                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
461                             m_DITHER_DOWN_SEL;
462                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
463                             v_DITHER_DOWN_SEL(1);
464                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
465                         break;
466                 case OUT_P666:
467                         face = OUT_P666;
468                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
469                             m_DITHER_DOWN_SEL;
470                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
471                             v_DITHER_DOWN_SEL(1);
472                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
473                         break;
474                 case OUT_D888_P565:
475                         face = OUT_P888;
476                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
477                             m_DITHER_DOWN_SEL;
478                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
479                             v_DITHER_DOWN_SEL(1);
480                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
481                         break;
482                 case OUT_D888_P666:
483                         face = OUT_P888;
484                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
485                             m_DITHER_DOWN_SEL;
486                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
487                             v_DITHER_DOWN_SEL(1);
488                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
489                         break;
490                 case OUT_P888:
491                         face = OUT_P888;
492                         mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
493                         val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
494                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
495                         break;
496                 default:
497                         dev_err(lcdc_dev->dev, "un supported interface!\n");
498                         break;
499                 }
500
501                 mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
502                     m_DEN_POL | m_DCLK_POL;
503                 val = v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) |
504                     v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) |
505                     v_DCLK_POL(screen->pin_dclk);
506                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
507
508                 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
509                     m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
510                     m_DSP_DUMMY_SWAP | m_BLANK_EN;
511                 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
512                     v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->
513                                                                    swap_rg) |
514                     v_DSP_DELTA_SWAP(screen->
515                                      swap_delta) | v_DSP_DUMMY_SWAP(screen->
516                                                                     swap_dumy) |
517                     v_BLANK_EN(0) | v_BLACK_EN(0);
518                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
519                 val =
520                     v_HSYNC(screen->mode.hsync_len) | v_HORPRD(screen->mode.
521                                                                hsync_len +
522                                                                left_margin +
523                                                                x_res +
524                                                                right_margin);
525                 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
526                 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
527                     v_HASP(screen->mode.hsync_len + left_margin);
528                 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
529
530                 val =
531                     v_VSYNC(screen->mode.vsync_len) | v_VERPRD(screen->mode.
532                                                                vsync_len +
533                                                                upper_margin +
534                                                                y_res +
535                                                                lower_margin);
536                 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
537
538                 val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
539                     v_VASP(screen->mode.vsync_len + screen->mode.upper_margin);
540                 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
541         }
542         spin_unlock(&lcdc_dev->reg_lock);
543
544         ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
545         if (ret)
546                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
547         lcdc_dev->pixclock =
548             div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
549         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
550
551         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
552         screen->ft = 1000 / fps;
553         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
554                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
555         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
556                 dev_drv->trsm_ops->enable();
557         if (screen->init)
558                 screen->init();
559
560         return 0;
561 }
562
563 /*enable layer,open:1,enable;0 disable*/
564 static int win0_open(struct lcdc_device *lcdc_dev, bool open)
565 {
566         spin_lock(&lcdc_dev->reg_lock);
567         if (likely(lcdc_dev->clk_on)) {
568                 if (open) {
569                         if (!lcdc_dev->atv_layer_cnt) {
570                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
571                                 lcdc_dev->standby = 0;
572                         }
573                         lcdc_dev->atv_layer_cnt++;
574                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
575                         lcdc_dev->atv_layer_cnt--;
576                 }
577                 lcdc_dev->driver.win[0]->state = open;
578                 if (!lcdc_dev->atv_layer_cnt) {
579                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
580                         lcdc_dev->standby = 1;
581                 }
582         }
583         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(open));
584         spin_unlock(&lcdc_dev->reg_lock);
585
586         return 0;
587 }
588
589 static int win1_open(struct lcdc_device *lcdc_dev, bool open)
590 {
591         spin_lock(&lcdc_dev->reg_lock);
592         if (likely(lcdc_dev->clk_on)) {
593                 if (open) {
594                         if (!lcdc_dev->atv_layer_cnt) {
595                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
596                                 lcdc_dev->standby = 0;
597                         }
598                         lcdc_dev->atv_layer_cnt++;
599                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
600                         lcdc_dev->atv_layer_cnt--;
601                 }
602                 lcdc_dev->driver.win[1]->state = open;
603                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(open));
604                 /*if no layer used,disable lcdc*/
605                 if (!lcdc_dev->atv_layer_cnt) {
606                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
607                         lcdc_dev->standby = 1;
608                 }
609         }
610         spin_unlock(&lcdc_dev->reg_lock);
611
612         return 0;
613 }
614
615 static int rk3188_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
616                             bool open)
617 {
618         struct lcdc_device *lcdc_dev = container_of(dev_drv,
619                                         struct lcdc_device, driver);
620
621         /*enable clk,when first layer open */
622         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
623                 rk3188_lcdc_pre_init(dev_drv);
624                 rk3188_lcdc_clk_enable(lcdc_dev);
625                 rk3188_lcdc_reg_restore(lcdc_dev);
626                 rk3188_load_screen(dev_drv, 1);
627                 spin_lock(&lcdc_dev->reg_lock);
628                 if (dev_drv->cur_screen->dsp_lut)
629                         rk3188_lcdc_set_lut(dev_drv);
630                 spin_unlock(&lcdc_dev->reg_lock);
631         }
632
633         if (win_id == 0)
634                 win0_open(lcdc_dev, open);
635         else if (win_id == 1)
636                 win1_open(lcdc_dev, open);
637         else
638                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
639
640         /*when all layer closed,disable clk */
641         if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
642                 lcdc_msk_reg(lcdc_dev, INT_STATUS,
643                              m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
644                 rk3188_lcdc_reg_update(dev_drv);
645                 rk3188_lcdc_clk_disable(lcdc_dev);
646         }
647
648         return 0;
649 }
650
651 static int win0_display(struct lcdc_device *lcdc_dev,
652                         struct rk_lcdc_win *win)
653 {
654         u32 y_addr;
655         u32 uv_addr;
656         y_addr = win->area[0].smem_start+win->area[0].y_offset;
657         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
658         DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
659                 lcdc_dev->id, __func__, y_addr, uv_addr);
660         
661         spin_lock(&lcdc_dev->reg_lock);
662         if (likely(lcdc_dev->clk_on)) {
663                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, y_addr);
664                 lcdc_writel(lcdc_dev, WIN0_CBR_MST0, uv_addr);
665         }
666         spin_unlock(&lcdc_dev->reg_lock);
667
668         return 0;
669
670 }
671
672 static int win1_display(struct lcdc_device *lcdc_dev,
673                         struct rk_lcdc_win *win)
674 {
675         u32 y_addr;
676         u32 uv_addr;
677         y_addr = win->area[0].smem_start + win->area[0].y_offset;
678         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
679         DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
680             lcdc_dev->id, __func__, y_addr, uv_addr);
681
682         spin_lock(&lcdc_dev->reg_lock);
683         if (likely(lcdc_dev->clk_on))
684                 lcdc_writel(lcdc_dev,WIN1_MST,y_addr);
685         spin_unlock(&lcdc_dev->reg_lock);
686
687         return 0;
688 }
689
690
691 static int rk3188_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
692 {
693         struct lcdc_device *lcdc_dev = container_of(dev_drv, 
694                                                 struct lcdc_device, driver);
695         struct rk_lcdc_win *win = NULL;
696         struct rk_screen *screen = dev_drv->cur_screen;
697         u32 msk, val;
698 #if defined(WAIT_FOR_SYNC)
699         int timeout;
700         unsigned long flags;
701 #endif
702
703         if (!screen) {
704                 dev_err(dev_drv->dev,"screen is null!\n");
705                 return -ENOENT;
706         }
707         
708         if (win_id == 0) {
709                 win = dev_drv->win[0];
710                 win0_display(lcdc_dev, win);
711         } else if(win_id==1) {
712                 win = dev_drv->win[1];
713                 win1_display(lcdc_dev, win);
714         } else {
715                 dev_err(dev_drv->dev,"invalid win number:%d!\n", win_id);
716                 return -EINVAL;
717         }
718
719          /*this is the first frame of the system ,enable frame start interrupt*/
720         if ((dev_drv->first_frame))  {
721                 dev_drv->first_frame = 0;
722                 msk = m_FS_INT_CLEAR |m_FS_INT_EN;
723                 val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1);
724                 lcdc_msk_reg(lcdc_dev, INT_STATUS, msk, val);
725
726         }
727
728 #if defined(WAIT_FOR_SYNC)
729         spin_lock_irqsave(&dev_drv->cpl_lock, flags);
730         init_completion(&dev_drv->frame_done);
731         spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
732         timeout = wait_for_completion_timeout(&dev_drv->frame_done,
733                                 msecs_to_jiffies(dev_drv->cur_screen->ft +5));
734         if (!timeout && (!dev_drv->frame_done.done)) {
735                 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
736                 return -ETIMEDOUT;
737         }
738 #endif
739
740         return 0;
741 }
742
743
744 static int win0_set_par(struct lcdc_device *lcdc_dev,
745                         struct rk_screen *screen, struct rk_lcdc_win *win)
746 {
747         u32 xact, yact, xvir, yvir, xpos, ypos;
748         u32 ScaleYrgbX = 0x1000;
749         u32 ScaleYrgbY = 0x1000;
750         u32 ScaleCbrX = 0x1000;
751         u32 ScaleCbrY = 0x1000;
752         u8 fmt_cfg = 0;
753         char fmt[9] = "NULL";
754         xact = win->area[0].xact;
755         yact = win->area[0].yact;
756         xvir = win->area[0].xvir;
757         yvir = win->area[0].yvir;
758         xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
759         ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
760
761         ScaleYrgbX = CalScale(xact, win->area[0].xsize);
762         ScaleYrgbY = CalScale(yact, win->area[0].ysize);
763         switch (win->area[0].format) {
764         case ARGB888:
765         case XBGR888:
766         case ABGR888:
767                 fmt_cfg = 0;
768                 break;
769         case RGB888:
770                 fmt_cfg = 1;
771                 break;
772         case RGB565:
773                 fmt_cfg = 2;
774                 break;
775         case YUV422:
776                 fmt_cfg = 5;
777                 ScaleCbrX = CalScale((xact / 2), win->area[0].xsize);
778                 ScaleCbrY = CalScale(yact, win->area[0].ysize);
779                 break;
780         case YUV420:
781                 fmt_cfg = 4;
782                 ScaleCbrX = CalScale(xact / 2, win->area[0].xsize);
783                 ScaleCbrY = CalScale(yact / 2, win->area[0].ysize);
784                 break;
785         case YUV444:
786                 fmt_cfg = 6;
787                 ScaleCbrX = CalScale(xact, win->area[0].xsize);
788                 ScaleCbrY = CalScale(yact, win->area[0].ysize);
789                 break;
790         default:
791                 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
792                         __func__);
793                 break;
794         }
795
796         DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
797                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
798                 __func__, get_format_string(win->area[0].format, fmt), xact,
799                 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
800
801         spin_lock(&lcdc_dev->reg_lock);
802         
803         win->scale_yrgb_x = ScaleYrgbX;
804         win->scale_yrgb_y = ScaleYrgbY;
805         win->scale_cbcr_x = ScaleCbrX;
806         win->scale_cbcr_y = ScaleCbrY;
807         win->area[0].fmt_cfg = fmt_cfg;
808         win->area[0].dsp_stx = xpos;
809         win->area[0].dsp_sty = ypos;
810         
811         switch (win->area[0].format) {
812         case XBGR888:
813         case ABGR888:
814                 win->area[0].swap_rb = 1;
815                 break;
816         case ARGB888:
817                 win->area[0].swap_rb = 0;
818                 break;
819         case RGB888:
820                 win->area[0].swap_rb = 0;
821                 break;
822         case RGB565:
823                 win->area[0].swap_rb = 0;
824                 break;
825         case YUV422:
826         case YUV420:
827         case YUV444:
828                 win->area[0].swap_rb = 0;
829                 break;
830         default:
831                 dev_err(lcdc_dev->driver.dev,
832                         "%s:un supported format!\n", __func__);
833                 break;
834         }
835
836         
837         if (likely(lcdc_dev->clk_on)) {
838                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,v_X_SCL_FACTOR(ScaleYrgbX) | v_Y_SCL_FACTOR(ScaleYrgbY));
839                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,v_X_SCL_FACTOR(ScaleCbrX) | v_Y_SCL_FACTOR(ScaleCbrY));
840                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_WIN0_FORMAT,v_WIN0_FORMAT(fmt_cfg));         
841                 lcdc_writel(lcdc_dev, WIN0_ACT_INFO,v_ACT_WIDTH(xact) | v_ACT_HEIGHT(yact));
842                 lcdc_writel(lcdc_dev, WIN0_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
843                 lcdc_writel(lcdc_dev, WIN0_DSP_INFO,v_DSP_WIDTH(win->area[0].xsize) |
844                                                 v_DSP_HEIGHT(win->area[0].ysize));
845                 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN0_VIR, v_WIN0_VIR_VAL(win->area[0].y_vir_stride));
846                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN | m_WIN0_RB_SWAP,
847                              v_WIN0_EN(win->state) |
848                              v_WIN0_RB_SWAP(win->area[0].swap_rb));
849                 lcdc_msk_reg(lcdc_dev, WIN0_COLOR_KEY, m_COLOR_KEY_EN, v_COLOR_KEY_EN(0));
850         }
851         spin_unlock(&lcdc_dev->reg_lock);
852         
853         return 0;
854
855 }
856
857 static int win1_set_par(struct lcdc_device *lcdc_dev,
858                         struct rk_screen *screen, struct rk_lcdc_win *win)
859 {
860         u32 xact, yact, xvir, yvir, xpos, ypos;
861         u8 fmt_cfg;
862         char fmt[9] = "NULL";
863         xact = win->area[0].xact;
864         yact = win->area[0].yact;
865         xvir = win->area[0].xvir;
866         yvir = win->area[0].yvir;
867         xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
868         ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
869
870         DBG(1, "lcdc%d>>%s>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
871                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
872                 __func__, get_format_string(win->area[0].format, fmt),
873                 xact, yact, win->area[0].xsize, win->area[0].ysize,
874                 xvir, yvir, xpos, ypos);
875
876         spin_lock(&lcdc_dev->reg_lock);
877         win->area[0].dsp_stx = xpos;
878         win->area[0].dsp_sty = ypos;
879         switch (win->area[0].format) {
880         case XBGR888:
881         case ABGR888:
882                 fmt_cfg = 0;
883                 win->area[0].swap_rb = 1;
884                 break;
885         case ARGB888:
886                 fmt_cfg = 0;
887                 win->area[0].swap_rb = 0;
888
889                 break;
890         case RGB888:
891                 fmt_cfg = 1;
892                 win->area[0].swap_rb = 0;
893                 break;
894         case RGB565:
895                 fmt_cfg = 2;
896                 win->area[0].swap_rb = 0;
897                 break;
898         default:
899                 dev_err(lcdc_dev->driver.dev,
900                         "%s:un supported format!\n", __func__);
901                 break;
902         }
903         win->area[0].fmt_cfg = fmt_cfg;
904         if (likely(lcdc_dev->clk_on)) {
905                 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,v_DSP_WIDTH(win->area[0].xsize) |
906                                                         v_DSP_HEIGHT(win->area[0].ysize));
907                 lcdc_writel(lcdc_dev, WIN1_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
908                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN | m_WIN1_RB_SWAP,
909                              v_WIN1_EN(win->state) |
910                              v_WIN1_RB_SWAP(win->area[0].swap_rb));
911                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_WIN1_FORMAT, v_WIN1_FORMAT(fmt_cfg));
912                 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN1_VIR,
913                              ((win->area[0].y_vir_stride)&0x1fff)<<16);
914         }
915         spin_unlock(&lcdc_dev->reg_lock);
916
917         return 0;
918 }
919
920 static int rk3188_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
921 {
922         struct lcdc_device *lcdc_dev = container_of(dev_drv,
923                                                 struct lcdc_device, driver);
924         struct rk_lcdc_win *win = NULL;
925         struct rk_screen *screen = dev_drv->cur_screen;
926
927         if (!screen) {
928                 dev_err(dev_drv->dev, "screen is null!\n");
929                 return -ENOENT;
930         }
931         
932         if (win_id == 0) {
933                 win = dev_drv->win[0];
934                 win0_set_par(lcdc_dev, screen, win);
935         } else if (win_id == 1) {
936                 win = dev_drv->win[1];
937                 win1_set_par(lcdc_dev, screen, win);
938         } else {
939                 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
940                 return -EINVAL;
941         }
942         
943         if (lcdc_dev->clk_on) {
944                 rk3188_lcdc_alpha_cfg(lcdc_dev);
945         }
946
947         return 0;
948 }
949
950
951
952 static int rk3188_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
953                              unsigned long arg, int win_id)
954 {
955         struct lcdc_device *lcdc_dev = container_of(dev_drv,
956                                         struct lcdc_device, driver);
957         u32 panel_size[2];
958         void __user *argp = (void __user *)arg;
959         struct color_key_cfg clr_key_cfg;
960
961         switch (cmd) {
962         case RK_FBIOGET_PANEL_SIZE:
963                 panel_size[0] = lcdc_dev->screen->mode.xres;
964                 panel_size[1] = lcdc_dev->screen->mode.yres;
965                 if (copy_to_user(argp, panel_size, 8))
966                         return -EFAULT;
967                 break;
968         case RK_FBIOPUT_COLOR_KEY_CFG:
969                 if (copy_from_user(&clr_key_cfg, argp,
970                                    sizeof(struct color_key_cfg)))
971                         return -EFAULT;
972                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
973                             clr_key_cfg.win0_color_key_cfg);
974                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
975                             clr_key_cfg.win1_color_key_cfg);
976                 break;
977
978         default:
979                 break;
980         }
981         return 0;
982 }
983
984 static int rk3188_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
985 {
986
987         struct lcdc_device *lcdc_dev = container_of(dev_drv,
988                                         struct lcdc_device, driver);
989         if (dev_drv->suspend_flag) 
990                 return 0;
991         dev_drv->suspend_flag = 1;
992         flush_kthread_worker(&dev_drv->update_regs_worker);
993
994         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
995                 dev_drv->trsm_ops->disable();
996         spin_lock(&lcdc_dev->reg_lock);
997         if (likely(lcdc_dev->clk_on)) {
998                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
999                              v_BLANK_EN(1));
1000                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
1001                              v_FS_INT_CLEAR(1));
1002                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1003                              v_DSP_OUT_ZERO(1));
1004                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1005                              v_LCDC_STANDBY(1));
1006                 lcdc_cfg_done(lcdc_dev);
1007                 spin_unlock(&lcdc_dev->reg_lock);
1008         } else {
1009                 spin_unlock(&lcdc_dev->reg_lock);
1010                 return 0;
1011         }
1012         rk3188_lcdc_clk_disable(lcdc_dev);
1013         rk_disp_pwr_disable(dev_drv);
1014         return 0;
1015 }
1016
1017 static int rk3188_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1018 {
1019         struct lcdc_device *lcdc_dev =
1020             container_of(dev_drv, struct lcdc_device, driver);
1021         int i = 0;
1022         int __iomem *c;
1023         int v;
1024
1025         if (!dev_drv->suspend_flag)
1026                 return 0;
1027         rk_disp_pwr_enable(dev_drv);
1028         dev_drv->suspend_flag = 0;
1029
1030         if (lcdc_dev->atv_layer_cnt) {
1031                 rk3188_lcdc_clk_enable(lcdc_dev);
1032                 rk3188_lcdc_reg_restore(lcdc_dev);
1033
1034                 spin_lock(&lcdc_dev->reg_lock);
1035                 if (dev_drv->cur_screen->dsp_lut) {
1036                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN,
1037                                      v_DSP_LUT_EN(0));
1038                         lcdc_cfg_done(lcdc_dev);
1039                         mdelay(25);
1040                         for (i = 0; i < 256; i++) {
1041                                 v = dev_drv->cur_screen->dsp_lut[i];
1042                                 c = lcdc_dev->dsp_lut_addr_base + i;
1043                                 writel_relaxed(v, c);
1044                         }
1045                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN,
1046                                      v_DSP_LUT_EN(1));
1047                 }
1048
1049                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1050                              v_DSP_OUT_ZERO(0));
1051                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1052                              v_LCDC_STANDBY(0));
1053                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
1054                              v_BLANK_EN(0));
1055                 lcdc_cfg_done(lcdc_dev);
1056
1057                 spin_unlock(&lcdc_dev->reg_lock);
1058         }
1059         
1060         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1061                 dev_drv->trsm_ops->enable();
1062         return 0;
1063 }
1064
1065
1066 static int rk3188_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1067                              int win_id, int blank_mode)
1068 {
1069         switch (blank_mode) {
1070         case FB_BLANK_UNBLANK:
1071                 rk3188_lcdc_early_resume(dev_drv);
1072                 break;
1073         case FB_BLANK_NORMAL:
1074                 rk3188_lcdc_early_suspend(dev_drv);
1075                 break;
1076         default:
1077                 rk3188_lcdc_early_suspend(dev_drv);
1078                 break;
1079         }
1080         
1081         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1082
1083         return 0;
1084 }
1085
1086 static int rk3188_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
1087                                      int win_id,
1088                                      int area_id)
1089 {
1090         return 0;
1091 }
1092
1093 static int rk3188_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1094                                bool set)
1095 {
1096         struct lcdc_device *lcdc_dev =
1097             container_of(dev_drv, struct lcdc_device, driver);
1098         int ovl;
1099         spin_lock(&lcdc_dev->reg_lock);
1100         if (lcdc_dev->clk_on) {
1101                 if (set) {
1102                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1103                                      v_WIN0_TOP(swap));
1104                         ovl = swap;
1105                 } else {
1106                         ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1107                 }
1108         } else {
1109                 ovl = -EPERM;
1110         }
1111         spin_unlock(&lcdc_dev->reg_lock);
1112
1113         return ovl;
1114 }
1115
1116 static ssize_t rk3188_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
1117                                          char *buf, int win_id)
1118 {
1119         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1120                                                            struct
1121                                                            lcdc_device,
1122                                                            driver);
1123
1124         char format_w0[9] = "NULL";
1125         char format_w1[9] = "NULL";
1126         char status_w0[9] = "NULL";
1127         char status_w1[9] = "NULL";
1128         u32 fmt_id, act_info, dsp_info, dsp_st, factor;
1129         u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0;
1130         u16 x_st_w0, y_st_w0, x_factor, y_factor;
1131         u16 xvir_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
1132         u16 x_scale, y_scale, ovl;
1133         spin_lock(&lcdc_dev->reg_lock);
1134         if (lcdc_dev->clk_on) {
1135                 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
1136                 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1137                 switch ((fmt_id & m_WIN0_FORMAT) >> 3) {
1138                 case 0:
1139                         strcpy(format_w0, "ARGB888");
1140                         break;
1141                 case 1:
1142                         strcpy(format_w0, "RGB888");
1143                         break;
1144                 case 2:
1145                         strcpy(format_w0, "RGB565");
1146                         break;
1147                 case 4:
1148                         strcpy(format_w0, "YCbCr420");
1149                         break;
1150                 case 5:
1151                         strcpy(format_w0, "YCbCr422");
1152                         break;
1153                 case 6:
1154                         strcpy(format_w0, "YCbCr444");
1155                         break;
1156                 default:
1157                         strcpy(format_w0, "invalid\n");
1158                         break;
1159                 }
1160
1161                 switch ((fmt_id & m_WIN1_FORMAT) >> 6) {
1162                 case 0:
1163                         strcpy(format_w1, "ARGB888");
1164                         break;
1165                 case 1:
1166                         strcpy(format_w1, "RGB888");
1167                         break;
1168                 case 2:
1169                         strcpy(format_w1, "RGB565");
1170                         break;
1171                 case 4:
1172                         strcpy(format_w1, "8bpp");
1173                         break;
1174                 case 5:
1175                         strcpy(format_w1, "4bpp");
1176                         break;
1177                 case 6:
1178                         strcpy(format_w1, "2bpp");
1179                         break;
1180                 case 7:
1181                         strcpy(format_w1, "1bpp");
1182                         break;
1183                 default:
1184                         strcpy(format_w1, "invalid\n");
1185                         break;
1186                 }
1187
1188                 if (fmt_id & m_WIN0_EN)
1189                         strcpy(status_w0, "enabled");
1190                 else
1191                         strcpy(status_w0, "disabled");
1192
1193                 if ((fmt_id & m_WIN1_EN) >> 1)
1194                         strcpy(status_w1, "enabled");
1195                 else
1196                         strcpy(status_w1, "disabled");
1197
1198                 xvir_w0 = lcdc_readl(lcdc_dev, WIN_VIR) & 0x1fff;
1199                 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1200                 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
1201                 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
1202                 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
1203                 x_act_w0 = (act_info & 0x1fff) + 1;
1204                 y_act_w0 = ((act_info >> 16) & 0x1fff) + 1;
1205                 x_dsp_w0 = (dsp_info & 0x7ff) + 1;
1206                 y_dsp_w0 = ((dsp_info >> 16) & 0x7ff) + 1;
1207                 x_st_w0 = dsp_st & 0xffff;
1208                 y_st_w0 = dsp_st >> 16;
1209                 x_factor = factor & 0xffff;
1210                 y_factor = factor >> 16;
1211                 x_scale = 4096 * 100 / x_factor;
1212                 y_scale = 4096 * 100 / y_factor;
1213                 xvir_w1 = (lcdc_readl(lcdc_dev, WIN_VIR) >> 16) & 0x1fff;
1214                 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
1215                 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
1216                 x_dsp_w1 = (dsp_info & 0x7ff) + 1;
1217                 y_dsp_w1 = ((dsp_info >> 16) & 0x7ff) + 1;
1218                 x_st_w1 = dsp_st & 0xffff;
1219                 y_st_w1 = dsp_st >> 16;
1220         } else {
1221                 spin_unlock(&lcdc_dev->reg_lock);
1222                 return -EPERM;
1223         }
1224         spin_unlock(&lcdc_dev->reg_lock);
1225         return snprintf(buf, PAGE_SIZE,
1226                         "win0:%s\n"
1227                         "xvir:%d\n"
1228                         "xact:%d\n"
1229                         "yact:%d\n"
1230                         "xdsp:%d\n"
1231                         "ydsp:%d\n"
1232                         "x_st:%d\n"
1233                         "y_st:%d\n"
1234                         "x_scale:%d.%d\n"
1235                         "y_scale:%d.%d\n"
1236                         "format:%s\n"
1237                         "YRGB buffer addr:0x%08x\n"
1238                         "CBR buffer addr:0x%08x\n\n"
1239                         "win1:%s\n"
1240                         "xvir:%d\n"
1241                         "xdsp:%d\n"
1242                         "ydsp:%d\n"
1243                         "x_st:%d\n"
1244                         "y_st:%d\n"
1245                         "format:%s\n"
1246                         "YRGB buffer addr:0x%08x\n"
1247                         "overlay:%s\n",
1248                         status_w0,
1249                         xvir_w0,
1250                         x_act_w0,
1251                         y_act_w0,
1252                         x_dsp_w0,
1253                         y_dsp_w0,
1254                         x_st_w0,
1255                         y_st_w0,
1256                         x_scale / 100,
1257                         x_scale % 100,
1258                         y_scale / 100,
1259                         y_scale % 100,
1260                         format_w0,
1261                         lcdc_readl(lcdc_dev, WIN0_YRGB_MST0),
1262                         lcdc_readl(lcdc_dev, WIN0_CBR_MST0),
1263                         status_w1,
1264                         xvir_w1,
1265                         x_dsp_w1,
1266                         y_dsp_w1,
1267                         x_st_w1,
1268                         y_st_w1,
1269                         format_w1,
1270                         lcdc_readl(lcdc_dev, WIN1_MST),
1271                         ovl ? "win0 on the top of win1\n" :
1272                         "win1 on the top of win0\n");
1273 }
1274
1275 static int rk3188_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
1276                                bool set)
1277 {
1278         struct lcdc_device *lcdc_dev =
1279             container_of(dev_drv, struct lcdc_device, driver);
1280         struct rk_screen *screen = dev_drv->cur_screen;
1281         u64 ft = 0;
1282         u32 dotclk;
1283         int ret;
1284         u32 pixclock;
1285         u32 x_total, y_total;
1286         if (set) {
1287                 ft = div_u64(1000000000000llu, fps);
1288                 x_total =
1289                     screen->mode.upper_margin + screen->mode.lower_margin +
1290                     screen->mode.yres + screen->mode.vsync_len;
1291                 y_total =
1292                     screen->mode.left_margin + screen->mode.right_margin +
1293                     screen->mode.xres + screen->mode.hsync_len;
1294                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1295                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1296                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1297         }
1298
1299         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1300         dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
1301         fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
1302         screen->ft = 1000 / fps;        /*one frame time in ms */
1303
1304         if (set)
1305                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1306                          clk_get_rate(lcdc_dev->dclk), fps);
1307
1308         return fps;
1309 }
1310
1311 static int rk3188_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
1312 {
1313         mutex_lock(&dev_drv->fb_win_id_mutex);
1314         if (order == FB_DEFAULT_ORDER)
1315                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
1316         dev_drv->fb2_win_id = order / 100;
1317         dev_drv->fb1_win_id = (order / 10) % 10;
1318         dev_drv->fb0_win_id = order % 10;
1319         mutex_unlock(&dev_drv->fb_win_id_mutex);
1320
1321         return 0;
1322 }
1323
1324 static int rk3188_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1325                                   const char *id)
1326 {
1327         int win_id = 0;
1328         mutex_lock(&dev_drv->fb_win_id_mutex);
1329         if (!strcmp(id, "fb0") || !strcmp(id, "fb2"))
1330                 win_id = dev_drv->fb0_win_id;
1331         else if (!strcmp(id, "fb1") || !strcmp(id, "fb3"))
1332                 win_id = dev_drv->fb1_win_id;
1333         mutex_unlock(&dev_drv->fb_win_id_mutex);
1334
1335         return win_id;
1336 }
1337
1338 static int rk3188_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
1339 {
1340         int i = 0;
1341         int __iomem *c;
1342         int v;
1343         int ret = 0;
1344
1345         struct lcdc_device *lcdc_dev =
1346             container_of(dev_drv, struct lcdc_device, driver);
1347         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
1348         lcdc_cfg_done(lcdc_dev);
1349         msleep(25);
1350         if (dev_drv->cur_screen->dsp_lut) {
1351                 for (i = 0; i < 256; i++) {
1352                         v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
1353                         c = lcdc_dev->dsp_lut_addr_base + i;
1354                         writel_relaxed(v, c);
1355
1356                 }
1357         } else {
1358                 dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
1359                 ret = -1;
1360         }
1361         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
1362         lcdc_cfg_done(lcdc_dev);
1363
1364         return ret;
1365 }
1366
1367 static int rk3188_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
1368 {
1369         struct lcdc_device *lcdc_dev =
1370             container_of(dev_drv, struct lcdc_device, driver);
1371         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN,
1372                      v_DIRECT_PATCH_EN(open));
1373         lcdc_cfg_done(lcdc_dev);
1374         return 0;
1375 }
1376
1377 static int rk3188_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
1378 {
1379         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1380                                         struct lcdc_device, driver);
1381         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAY_SEL,
1382                      v_DIRECT_PATH_LAY_SEL(win_id));
1383         lcdc_cfg_done(lcdc_dev);
1384         return 0;
1385
1386 }
1387
1388 static int rk3188_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
1389 {
1390         struct lcdc_device *lcdc_dev =
1391             container_of(dev_drv, struct lcdc_device, driver);
1392         int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN);
1393         return ovl;
1394 }
1395
1396 int rk3188_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
1397 {
1398         struct lcdc_device *lcdc_dev =
1399             container_of(dev_drv, struct lcdc_device, driver);
1400         u32 int_reg;
1401         int ret;
1402
1403         if (lcdc_dev->clk_on) {
1404                 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1405                 if (int_reg & m_LF_INT_STA) {
1406                         lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1407                                      v_LF_INT_CLEAR(1));
1408                         ret = RK_LF_STATUS_FC;
1409                 } else
1410                         ret = RK_LF_STATUS_FR;
1411         } else {
1412                 ret = RK_LF_STATUS_NC;
1413         }
1414
1415         return ret;
1416 }
1417
1418
1419 static int rk3188_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int dsp_addr[][4])
1420 {
1421         struct lcdc_device *lcdc_dev =
1422             container_of(dev_drv, struct lcdc_device, driver);
1423
1424         if(lcdc_dev->clk_on){
1425                 dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST0);
1426                 dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST);
1427         }
1428         return 0;
1429 }
1430
1431 static int rk3188_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1432 {
1433         struct lcdc_device *lcdc_dev = container_of(dev_drv, 
1434                                         struct lcdc_device, driver);
1435         spin_lock(&lcdc_dev->reg_lock);
1436         if (lcdc_dev->clk_on)
1437                 lcdc_cfg_done(lcdc_dev);
1438         spin_unlock(&lcdc_dev->reg_lock);
1439         return 0;
1440 }
1441
1442
1443 static struct rk_lcdc_win lcdc_win[] = {
1444         [0] = {
1445                .name = "win0",
1446                .id = 0,
1447                .support_3d = true,
1448                },
1449         [1] = {
1450                .name = "win1",
1451                .id = 1,
1452                .support_3d = false,
1453                },
1454 };
1455
1456 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
1457         .open                   = rk3188_lcdc_open,
1458         .load_screen            = rk3188_load_screen,
1459         .set_par                = rk3188_lcdc_set_par,
1460         .pan_display            = rk3188_lcdc_pan_display,
1461         .blank                  = rk3188_lcdc_blank,
1462         .ioctl                  = rk3188_lcdc_ioctl,
1463         .get_win_state          = rk3188_lcdc_get_win_state,
1464         .ovl_mgr                = rk3188_lcdc_ovl_mgr,
1465         .get_disp_info          = rk3188_lcdc_get_disp_info,
1466         .fps_mgr                = rk3188_lcdc_fps_mgr,
1467         .fb_get_win_id          = rk3188_lcdc_get_win_id,
1468         .fb_win_remap           = rk3188_fb_win_remap,
1469         .set_dsp_lut            = rk3188_set_dsp_lut,
1470         .poll_vblank            = rk3188_lcdc_poll_vblank,
1471         .dpi_open               = rk3188_lcdc_dpi_open,
1472         .dpi_win_sel            = rk3188_lcdc_dpi_win_sel,
1473         .dpi_status             = rk3188_lcdc_dpi_status,
1474         .get_dsp_addr           = rk3188_lcdc_get_dsp_addr,
1475         .cfg_done               = rk3188_lcdc_cfg_done,
1476         .dump_reg               = rk3188_lcdc_reg_dump,
1477 };
1478
1479 static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
1480 {
1481         struct lcdc_device *lcdc_dev =
1482             (struct lcdc_device *)dev_id;
1483         ktime_t timestamp = ktime_get();
1484         u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1485
1486         if (int_reg & m_FS_INT_STA) {
1487                 timestamp = ktime_get();
1488                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
1489                              v_FS_INT_CLEAR(1));
1490                 //if (lcdc_dev->driver.wait_fs) {
1491                 if (0) {        
1492                         spin_lock(&(lcdc_dev->driver.cpl_lock));
1493                         complete(&(lcdc_dev->driver.frame_done));
1494                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
1495                 }
1496                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
1497                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
1498
1499         } else if (int_reg & m_LF_INT_STA) {
1500                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1501                              v_LF_INT_CLEAR(1));
1502         }
1503         return IRQ_HANDLED;
1504 }
1505
1506 #if defined(CONFIG_PM)
1507 static int rk3188_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
1508 {
1509         return 0;
1510 }
1511
1512 static int rk3188_lcdc_resume(struct platform_device *pdev)
1513 {
1514         return 0;
1515 }
1516 #else
1517 #define rk3188_lcdc_suspend NULL
1518 #define rk3188_lcdc_resume  NULL
1519 #endif
1520
1521 static int rk3188_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
1522 {
1523         struct device_node *np = lcdc_dev->dev->of_node;
1524         int val;
1525         if (of_property_read_u32(np, "rockchip,prop", &val))
1526                 lcdc_dev->prop = PRMRY; /*default set it as primary */
1527         else
1528                 lcdc_dev->prop = val;
1529
1530         if (of_property_read_u32(np, "rockchip,pwr18", &val))
1531                 lcdc_dev->pwr18 = false;        /*default set it as 3.xv power supply */
1532         else
1533                 lcdc_dev->pwr18 = (val ? true : false);
1534
1535         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
1536                 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
1537         else
1538                 lcdc_dev->driver.fb_win_map = val;
1539
1540         return 0;
1541 }
1542
1543 static int rk3188_lcdc_probe(struct platform_device *pdev)
1544 {
1545         struct lcdc_device *lcdc_dev = NULL;
1546         struct rk_lcdc_driver *dev_drv;
1547         struct device *dev = &pdev->dev;
1548         struct resource *res;
1549         struct device_node *np = pdev->dev.of_node;
1550         int prop;
1551         int ret = 0;
1552
1553         /*if the primary lcdc has not registered ,the extend
1554            lcdc register later */
1555         of_property_read_u32(np, "rockchip,prop", &prop);
1556         if (prop == EXTEND) {
1557                 if (!is_prmry_rk_lcdc_registered())
1558                         return -EPROBE_DEFER;
1559         }
1560         lcdc_dev = devm_kzalloc(dev,
1561                                 sizeof(struct lcdc_device), GFP_KERNEL);
1562         if (!lcdc_dev) {
1563                 dev_err(&pdev->dev, "rk3188 lcdc device kmalloc fail!");
1564                 return -ENOMEM;
1565         }
1566         platform_set_drvdata(pdev, lcdc_dev);
1567         lcdc_dev->dev = dev;
1568         rk3188_lcdc_parse_dt(lcdc_dev);
1569         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1570         lcdc_dev->reg_phy_base = res->start;
1571         lcdc_dev->len = resource_size(res);
1572         lcdc_dev->regs = devm_ioremap_resource(dev, res);
1573         if (IS_ERR(lcdc_dev->regs))
1574                 return PTR_ERR(lcdc_dev->regs);
1575
1576         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
1577         if (IS_ERR(lcdc_dev->regsbak))
1578                 return PTR_ERR(lcdc_dev->regsbak);
1579         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
1580         lcdc_dev->id = rk3188_lcdc_get_id(lcdc_dev->reg_phy_base);
1581         if (lcdc_dev->id < 0) {
1582                 dev_err(&pdev->dev, "no such lcdc device!\n");
1583                 return -ENXIO;
1584         }
1585         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
1586         dev_drv = &lcdc_dev->driver;
1587         dev_drv->dev = dev;
1588         dev_drv->prop = prop;
1589         dev_drv->id = lcdc_dev->id;
1590         dev_drv->ops = &lcdc_drv_ops;
1591         dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
1592         spin_lock_init(&lcdc_dev->reg_lock);
1593
1594         lcdc_dev->irq = platform_get_irq(pdev, 0);
1595         if (lcdc_dev->irq < 0) {
1596                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
1597                         lcdc_dev->id);
1598                 return -ENXIO;
1599         }
1600
1601         ret = devm_request_irq(dev, lcdc_dev->irq, rk3188_lcdc_isr,
1602                                IRQF_DISABLED, dev_name(dev), lcdc_dev);
1603         if (ret) {
1604                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
1605                         lcdc_dev->irq, ret);
1606                 return ret;
1607         }
1608
1609         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
1610         if (ret < 0) {
1611                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
1612                 return ret;
1613         }
1614         lcdc_dev->screen = dev_drv->screen0;
1615         
1616         dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
1617
1618         return 0;
1619 }
1620
1621 static int rk3188_lcdc_remove(struct platform_device *pdev)
1622 {
1623
1624         return 0;
1625 }
1626
1627 static void rk3188_lcdc_shutdown(struct platform_device *pdev)
1628 {
1629         struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
1630
1631         rk3188_lcdc_deint(lcdc_dev);
1632         rk_disp_pwr_disable(&lcdc_dev->driver);
1633 }
1634
1635 #if defined(CONFIG_OF)
1636 static const struct of_device_id rk3188_lcdc_dt_ids[] = {
1637         {.compatible = "rockchip,rk3188-lcdc",},
1638         {}
1639 };
1640 #endif
1641
1642 static struct platform_driver rk3188_lcdc_driver = {
1643         .probe = rk3188_lcdc_probe,
1644         .remove = rk3188_lcdc_remove,
1645         .driver = {
1646                    .name = "rk3188-lcdc",
1647                    .owner = THIS_MODULE,
1648                    .of_match_table = of_match_ptr(rk3188_lcdc_dt_ids),
1649                    },
1650         .suspend = rk3188_lcdc_suspend,
1651         .resume = rk3188_lcdc_resume,
1652         .shutdown = rk3188_lcdc_shutdown,
1653 };
1654
1655 static int __init rk3188_lcdc_module_init(void)
1656 {
1657         return platform_driver_register(&rk3188_lcdc_driver);
1658 }
1659
1660 static void __exit rk3188_lcdc_module_exit(void)
1661 {
1662         platform_driver_unregister(&rk3188_lcdc_driver);
1663 }
1664
1665 fs_initcall(rk3188_lcdc_module_init);
1666 module_exit(rk3188_lcdc_module_exit);