rk3036 lcdc: commit driver code, just pass compiling.
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3036_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3036_lcdc.c
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  * Author:zhengyang<zhengyang@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 #include <linux/rockchip/common.h>
35 #include <dt-bindings/clock/rk_system_status.h>
36
37 #include "rk3036_lcdc.h"
38
39 static int dbg_thresd;
40 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
41
42 #define DBG(level, x...) do {                   \
43         if (unlikely(dbg_thresd >= level))      \
44                 printk(KERN_INFO x); } while (0)
45
46 static struct rk_lcdc_win lcdc_win[] = {
47         [0] = {
48                .name = "win0",
49                .id = 0,
50                .support_3d = false,
51                },
52         [1] = {
53                .name = "win1",
54                .id = 1,
55                .support_3d = false,
56                },
57         [2] = {
58                .name = "hwc",
59                .id = 2,
60                .support_3d = false,
61                },
62 };
63
64 static void layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id, bool open);
65
66 static irqreturn_t rk3036_lcdc_isr(int irq, void *dev_id)
67 {
68         struct lcdc_device *lcdc_dev =
69             (struct lcdc_device *)dev_id;
70         ktime_t timestamp = ktime_get();
71         u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
72
73         if (int_reg & m_FS_INT_STA) {
74                 timestamp = ktime_get();
75                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
76                              v_FS_INT_CLEAR(1));
77                 //if (lcdc_dev->driver.wait_fs) {
78                 if (0) {        
79                         spin_lock(&(lcdc_dev->driver.cpl_lock));
80                         complete(&(lcdc_dev->driver.frame_done));
81                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
82                 }
83                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
84                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
85
86         } else if (int_reg & m_LF_INT_STA) {
87                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
88                              v_LF_INT_CLEAR(1));
89         }
90         return IRQ_HANDLED;
91 }
92
93 static int rk3036_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
94 {
95 #ifdef CONFIG_RK_FPGA
96         lcdc_dev->clk_on = 1;
97         return 0;
98 #endif  
99         if (!lcdc_dev->clk_on) {
100                 clk_prepare_enable(lcdc_dev->hclk);
101                 clk_prepare_enable(lcdc_dev->dclk);
102                 clk_prepare_enable(lcdc_dev->aclk);
103 //              clk_prepare_enable(lcdc_dev->pd);
104                 spin_lock(&lcdc_dev->reg_lock);
105                 lcdc_dev->clk_on = 1;
106                 spin_unlock(&lcdc_dev->reg_lock);
107         }
108
109         return 0;
110 }
111
112 static int rk3036_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
113 {
114 #ifdef CONFIG_RK_FPGA
115         lcdc_dev->clk_on = 0;
116         return 0;
117 #endif  
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_unprepare(lcdc_dev->pd);
127         }
128
129         return 0;
130 }
131
132 static int rk3036_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
133 {
134         u32 mask, val;
135         struct lcdc_device *lcdc_dev = container_of(dev_drv,
136                                         struct lcdc_device, driver);
137         mask = m_FS_INT_CLEAR |m_FS_INT_EN;
138         val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1);
139         lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
140         return 0;
141 }
142
143 static int rk3036_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
144 {       
145         u32 mask, val;
146         spin_lock(&lcdc_dev->reg_lock);
147         if (likely(lcdc_dev->clk_on)) {
148                 mask = m_FS_INT_CLEAR |m_FS_INT_EN;
149                 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0);
150                 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
151                 spin_unlock(&lcdc_dev->reg_lock);
152         } else {
153                 spin_unlock(&lcdc_dev->reg_lock);
154         }
155         mdelay(1);
156         return 0;
157 }
158
159 static void rk_lcdc_read_reg_defalut_cfg(struct lcdc_device
160                                              *lcdc_dev)
161 {
162         int reg = 0;
163         u32 value = 0;
164
165         spin_lock(&lcdc_dev->reg_lock);
166         for (reg = 0; reg < 0xdc; reg += 4) {
167                 value = lcdc_readl(lcdc_dev, reg);
168         }
169         spin_unlock(&lcdc_dev->reg_lock);
170 }
171
172 /********do basic init*********/
173 static int rk3036_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
174 {
175         u32 mask,val;
176         struct lcdc_device *lcdc_dev = container_of(dev_drv,
177                                                            struct
178                                                            lcdc_device,
179                                                    driver);
180         if (lcdc_dev->pre_init)
181                 return 0;
182
183         lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
184         lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
185         lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
186 //      lcdc_dev->pd   = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
187         
188         if (/*IS_ERR(lcdc_dev->pd) ||*/ (IS_ERR(lcdc_dev->aclk)) ||
189             (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
190                 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
191                         lcdc_dev->id);
192         }
193
194         rk_disp_pwr_enable(dev_drv);
195         rk3036_lcdc_clk_enable(lcdc_dev);
196
197         /*backup reg config at uboot*/
198         rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
199
200         mask =  m_AUTO_GATING_EN;
201         val  =  v_AUTO_GATING_EN(0);
202         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask,val);
203         lcdc_cfg_done(lcdc_dev);
204         if (dev_drv->iommu_enabled) /*disable win0 to workaround iommu pagefault*/
205                 layer_enable(lcdc_dev, 0, 0);
206         lcdc_dev->pre_init = true;
207
208         return 0;
209 }
210
211 static int rk3036_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
212 {
213         return 0;
214 }
215
216 static int rk3036_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
217 {
218         struct lcdc_device *lcdc_dev =
219             container_of(dev_drv, struct lcdc_device, driver);
220         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
221         struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
222         int timeout;
223         unsigned long flags;
224         spin_lock(&lcdc_dev->reg_lock);
225         if (likely(lcdc_dev->clk_on)) {
226                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
227                              v_LCDC_STANDBY(lcdc_dev->standby));
228                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
229                              m_WIN0_EN | m_WIN1_EN | m_WIN0_RB_SWAP |
230                              m_WIN1_RB_SWAP,
231                              v_WIN0_EN(win0->state) | v_WIN1_EN(win1->state) |
232                              v_WIN0_RB_SWAP(win0->swap_rb) |
233                              v_WIN1_RB_SWAP(win1->swap_rb));
234                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
235                             v_X_SCL_FACTOR(win0->scale_yrgb_x) |
236                             v_Y_SCL_FACTOR(win0->scale_yrgb_y));
237                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
238                             v_X_SCL_FACTOR(win0->scale_cbcr_x) |
239                             v_Y_SCL_FACTOR(win0->scale_cbcr_y));
240                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT, v_WIN0_FORMAT(win0->fmt_cfg));
241                 lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->area[0].xact) |
242                             v_ACT_HEIGHT(win0->area[0].yact));
243                 lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->area[0].dsp_stx) |
244                             v_DSP_STY(win0->area[0].dsp_sty));
245                 lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->area[0].xsize) |
246                             v_DSP_HEIGHT(win0->area[0].ysize));
247                 lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_YRGB_VIR | m_CBBR_VIR,
248                              v_YRGB_VIR(win0->area[0].y_vir_stride) | v_YRGB_VIR(win0->area[0].uv_vir_stride));
249                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, win0->area[0].y_addr);
250                 lcdc_writel(lcdc_dev, WIN0_CBR_MST, win0->area[0].uv_addr);
251                 lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->area[0].xsize) |
252                             v_DSP_HEIGHT(win1->area[0].ysize));
253                 lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->area[0].dsp_stx) |
254                             v_DSP_STY(win1->area[0].dsp_sty));
255                 lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR, v_YRGB_VIR(win1->area[0].y_vir_stride));
256                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_FORMAT,
257                              v_WIN1_FORMAT(win1->fmt_cfg));
258                 lcdc_writel(lcdc_dev, WIN1_MST, win1->area[0].y_addr);
259                 rk3036_lcdc_alpha_cfg(lcdc_dev);
260                 lcdc_cfg_done(lcdc_dev);
261
262         }
263         spin_unlock(&lcdc_dev->reg_lock);
264         //if (dev_drv->wait_fs) {
265         if (0) {
266                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
267                 init_completion(&dev_drv->frame_done);
268                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
269                 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
270                                                       msecs_to_jiffies
271                                                       (dev_drv->cur_screen->ft +
272                                                        5));
273                 if (!timeout && (!dev_drv->frame_done.done)) {
274                         dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
275                         return -ETIMEDOUT;
276                 }
277         }
278         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
279         return 0;
280
281 }
282
283 static void rk3036_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
284 {
285         memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0xdc);
286 }
287
288 static void rk3036_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
289 {
290         u32 mask,val;
291         struct lcdc_device *lcdc_dev =
292             container_of(dev_drv, struct lcdc_device, driver);
293         spin_lock(&lcdc_dev->reg_lock);
294         if (likely(lcdc_dev->clk_on)) {
295                 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN | m_AXI_OUTSTANDING_MAX_NUM;;
296                 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) | v_AXI_MAX_OUTSTANDING_EN(1);
297                 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
298         }
299         spin_unlock(&lcdc_dev->reg_lock);
300 }
301
302 static int rk3036_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
303 {
304 #ifdef CONFIG_RK_FPGA
305         return 0;
306 #endif
307         int ret,fps;
308         struct lcdc_device *lcdc_dev =
309             container_of(dev_drv, struct lcdc_device, driver);
310         struct rk_screen *screen = dev_drv->cur_screen;
311
312         ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
313         if (ret)
314                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
315         lcdc_dev->pixclock =
316                  div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
317         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
318         
319         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
320         screen->ft = 1000 / fps;
321         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
322                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
323         return 0;
324
325 }
326
327 static int rk3036_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
328 {
329         int ret = -EINVAL;
330         int fps;
331         u16 face = 0;
332         struct lcdc_device *lcdc_dev = container_of(dev_drv,
333                                                 struct lcdc_device, driver);
334         struct rk_screen *screen = dev_drv->cur_screen;
335         u16 right_margin = screen->mode.right_margin;
336         u16 left_margin = screen->mode.left_margin;
337         u16 lower_margin = screen->mode.lower_margin;
338         u16 upper_margin = screen->mode.upper_margin;
339         u16 x_res = screen->mode.xres;
340         u16 y_res = screen->mode.yres;
341         u32 mask, val;
342
343         spin_lock(&lcdc_dev->reg_lock);
344         if (likely(lcdc_dev->clk_on)) {
345                 switch (screen->type) {
346                 case SCREEN_HDMI:
347                         mask = m_HDMI_DCLK_EN;
348                         val = v_HDMI_DCLK_EN(1);
349                         if(screen->pixelrepeat) {
350                                 mask |= m_CORE_CLK_DIV_EN;
351                                 val |= v_CORE_CLK_DIV_EN(1);
352                         }
353                         lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
354                         break;
355                 case SCREEN_TVOUT:
356                         mask = m_TVE_DAC_DCLK_EN;
357                         val = v_TVE_DAC_DCLK_EN(1);
358                         if(screen->pixelrepeat) {
359                                 mask |= m_CORE_CLK_DIV_EN;
360                                 val |= v_CORE_CLK_DIV_EN(1);
361                         }
362                         lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
363                         break;
364                 default:
365                         dev_err(lcdc_dev->dev, "un supported interface!\n");
366                         break;
367                 }
368
369                 mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
370                     m_DEN_POL | m_DCLK_POL;
371                 val = v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) |
372                     v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) |
373                     v_DCLK_POL(screen->pin_dclk);
374                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
375
376                 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
377                     m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
378                     m_DSP_DUMMY_SWAP | m_BLANK_EN;
379                     
380                 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
381                     v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->
382                                                                    swap_rg) |
383                     v_DSP_DELTA_SWAP(screen->
384                                      swap_delta) | v_DSP_DUMMY_SWAP(screen->
385                                                                     swap_dumy) |
386                     v_BLANK_EN(0) | v_BLACK_EN(0);
387                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
388                 val =
389                     v_HSYNC(screen->mode.hsync_len) | v_HORPRD(screen->mode.
390                                                                hsync_len +
391                                                                left_margin +
392                                                                x_res +
393                                                                right_margin);
394                 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
395                 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
396                     v_HASP(screen->mode.hsync_len + left_margin);
397                 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
398
399                 val =
400                     v_VSYNC(screen->mode.vsync_len) | v_VERPRD(screen->mode.
401                                                                vsync_len +
402                                                                upper_margin +
403                                                                y_res +
404                                                                lower_margin);
405                 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
406
407                 val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
408                     v_VASP(screen->mode.vsync_len + screen->mode.upper_margin);
409                 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
410         }
411         spin_unlock(&lcdc_dev->reg_lock);
412
413         ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
414         if (ret)
415                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
416         lcdc_dev->pixclock =
417             div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
418         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
419
420         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
421         screen->ft = 1000 / fps;
422         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
423                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
424         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
425                 dev_drv->trsm_ops->enable();
426         if (screen->init)
427                 screen->init();
428
429         return 0;
430 }
431
432 static void layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id, bool open)
433 {
434         spin_lock(&lcdc_dev->reg_lock);
435                 if (likely(lcdc_dev->clk_on)) {
436                         if (open) {
437                                 if (!lcdc_dev->atv_layer_cnt) {
438                                         dev_info(lcdc_dev->dev, "wakeup from standby!\n");
439                                         lcdc_dev->standby = 0;
440                                 }
441                                 lcdc_dev->atv_layer_cnt++;
442                         } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
443                                 lcdc_dev->atv_layer_cnt--;
444                         }
445                         lcdc_dev->driver.win[win_id]->state = open;
446                         if(win_id == 0)
447                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(open));
448                         else if(win_id == 1)
449                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(open));
450                         else
451                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_EN, v_HWC_EN(open));
452                         /*if no layer used,disable lcdc*/
453                         if (!lcdc_dev->atv_layer_cnt) {
454                                 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
455                                 lcdc_dev->standby = 1;
456                         }
457                 }
458                 spin_unlock(&lcdc_dev->reg_lock);
459 }
460
461 static int rk3036_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
462                             bool open)
463 {
464         struct lcdc_device *lcdc_dev = container_of(dev_drv,
465                                         struct lcdc_device, driver);
466
467         /*enable clk,when first layer open */
468         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
469                 rk3036_lcdc_pre_init(dev_drv);
470                 rk3036_lcdc_clk_enable(lcdc_dev);
471                 rk3036_lcdc_reg_restore(lcdc_dev);
472                 if (dev_drv->iommu_enabled)
473                         rk3036_lcdc_mmu_en(dev_drv);
474                 if ((support_uboot_display()&&(lcdc_dev->prop == PRMRY))) {
475                         rk3036_lcdc_set_dclk(dev_drv);
476                         rk3036_lcdc_enable_irq(dev_drv);
477                 } else {
478                         rk3036_load_screen(dev_drv, 1);
479                 }
480         }
481         if(win_id < ARRAY_SIZE(lcdc_win)) {
482                 layer_enable(lcdc_dev, win_id, open);
483         }
484         else
485                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
486
487         /*when all layer closed,disable clk */
488         if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
489                 rk3036_lcdc_disable_irq(lcdc_dev);
490                 rk3036_lcdc_reg_update(dev_drv);
491                 rk3036_lcdc_clk_disable(lcdc_dev);
492         }
493         
494         return 0;
495 }
496
497 static int rk3036_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
498 {
499         struct lcdc_device *lcdc_dev = container_of(dev_drv,
500                                                 struct lcdc_device, driver);
501         struct rk_screen *screen = dev_drv->cur_screen;
502         struct rk_lcdc_win *win = NULL;
503         char fmt[9] = "NULL";
504         
505         if (!screen) {
506                 dev_err(dev_drv->dev, "screen is null!\n");
507                 return -ENOENT;
508         }
509         
510         if (win_id == 0) {
511                 win = dev_drv->win[0];
512         } else if (win_id == 1) {
513                 win = dev_drv->win[1];
514         } else {
515                 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
516                 return -EINVAL;
517         }
518         
519         spin_lock(&lcdc_dev->reg_lock);
520         
521         win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
522         win->area[0].dsp_sty = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
523         win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
524         win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
525         switch (win->format) {
526                 case ARGB888:
527                         win->fmt_cfg = VOP_FORMAT_ARGB888;
528                         win->swap_rb = 0;
529                         break;
530                 case XBGR888:
531                         win->fmt_cfg = VOP_FORMAT_ARGB888;
532                         win->swap_rb = 1;
533                         break;
534                 case ABGR888:
535                         win->fmt_cfg = VOP_FORMAT_ARGB888;
536                         win->swap_rb = 1;
537                         break;
538                 case RGB888:
539                         win->fmt_cfg = VOP_FORMAT_RGB888;
540                         win->swap_rb = 0;
541                         break;
542                 case RGB565:
543                         win->fmt_cfg = VOP_FORMAT_RGB565;
544                         win->swap_rb = 0;
545                         break;
546                 case YUV444:
547                         if(win_id == 0) {
548                                 win->fmt_cfg = VOP_FORMAT_YCBCR444;
549                                 win->scale_cbcr_x = CalScale(win->area[0].xact, win->area[0].xsize);
550                                 win->scale_cbcr_y = CalScale(win->area[0].yact, win->area[0].ysize);
551                                 win->swap_rb = 0;
552                         } else {
553                                 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
554                                 __func__);
555                         }
556                         break;
557                 case YUV422:
558                         if(win_id == 0) {
559                                 win->fmt_cfg = VOP_FORMAT_YCBCR422;
560                                 win->scale_cbcr_x = CalScale((win->area[0].xact / 2), win->area[0].xsize);
561                                 win->scale_cbcr_y = CalScale(win->area[0].yact, win->area[0].ysize);
562                                 win->swap_rb = 0;
563                         } else {
564                                 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
565                                 __func__);
566                         }
567                         break;
568                 case YUV420:
569                         if(win_id == 0) {
570                                 win->fmt_cfg = VOP_FORMAT_YCBCR420;
571                                 win->scale_cbcr_x = CalScale(win->area[0].xact / 2, win->area[0].xsize);
572                                 win->scale_cbcr_y = CalScale(win->area[0].yact / 2, win->area[0].ysize);
573                                 win->swap_rb = 0;
574                         }
575                         else {
576                                 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
577                                 __func__);
578                         }
579                         break;
580                 default:
581                         dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
582                                 __func__);
583                         break;
584         }
585         spin_unlock(&lcdc_dev->reg_lock);
586         
587         if (lcdc_dev->clk_on) {
588                 rk3036_lcdc_alpha_cfg(lcdc_dev);
589         }
590         DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
591                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
592                 __func__, get_format_string(win->format, fmt), win->area[0].xact,
593                 win->area[0].yact, win->area[0].xsize, win->area[0].ysize, win->area[0].xvir, 
594                 win->area[0].yvir, win->area[0].xpos, win->area[0].ypos);
595         return 0;
596 }
597
598 static int rk3036_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
599 {
600         struct lcdc_device *lcdc_dev = container_of(dev_drv, 
601                                                 struct lcdc_device, driver);
602         struct rk_lcdc_win *win = NULL;
603         struct rk_screen *screen = dev_drv->cur_screen;
604
605         if (!screen) {
606                 dev_err(dev_drv->dev,"screen is null!\n");
607                 return -ENOENT;
608         }
609         
610         if (win_id == 0) {
611                 win = dev_drv->win[0];
612         } else if(win_id==1) {
613                 win = dev_drv->win[1];
614         } else {
615                 dev_err(dev_drv->dev,"invalid win number:%d!\n", win_id);
616                 return -EINVAL;
617         }
618
619         
620         spin_lock(&lcdc_dev->reg_lock);
621         if (likely(lcdc_dev->clk_on)) {
622                 win->area[0].y_addr = win->area[0].smem_start+win->area[0].y_offset;
623                 win->area[0].uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
624                 if(win_id == 0) {
625                         lcdc_writel(lcdc_dev, WIN0_YRGB_MST, win->area[0].y_addr); 
626                         lcdc_writel(lcdc_dev, WIN0_CBR_MST, win->area[0].uv_addr);
627                 } else
628                         lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr); 
629                 /*lcdc_cfg_done(lcdc_dev);*/
630         }
631         spin_unlock(&lcdc_dev->reg_lock);
632
633         DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
634             lcdc_dev->id, __func__, win->area[0].y_addr, win->area[0].uv_addr,win->area[0].y_offset);
635          /*this is the first frame of the system ,enable frame start interrupt*/
636         if ((dev_drv->first_frame))  {
637                 dev_drv->first_frame = 0;
638                 rk3036_lcdc_enable_irq(dev_drv);
639
640         }
641         
642         return 0;
643 }
644
645 static int rk3036_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
646                              unsigned long arg, int win_id)
647 {
648         struct lcdc_device *lcdc_dev = container_of(dev_drv,
649                                         struct lcdc_device, driver);
650         u32 panel_size[2];
651         void __user *argp = (void __user *)arg;
652         struct color_key_cfg clr_key_cfg;
653
654         switch (cmd) {
655         case RK_FBIOGET_PANEL_SIZE:
656                 panel_size[0] = lcdc_dev->screen->mode.xres;
657                 panel_size[1] = lcdc_dev->screen->mode.yres;
658                 if (copy_to_user(argp, panel_size, 8))
659                         return -EFAULT;
660                 break;
661         case RK_FBIOPUT_COLOR_KEY_CFG:
662                 if (copy_from_user(&clr_key_cfg, argp,
663                                    sizeof(struct color_key_cfg)))
664                         return -EFAULT;
665                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
666                             clr_key_cfg.win0_color_key_cfg);
667                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
668                             clr_key_cfg.win1_color_key_cfg);
669                 break;
670
671         default:
672                 break;
673         }
674         return 0;
675 }
676
677 static int rk3036_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
678                                   const char *id)
679 {
680         int win_id = 0;
681         mutex_lock(&dev_drv->fb_win_id_mutex);
682         if (!strcmp(id, "fb0"))
683                 win_id = dev_drv->fb0_win_id;
684         else if (!strcmp(id, "fb1"))
685                 win_id = dev_drv->fb1_win_id;
686         else if (!strcmp(id, "fb2"))
687                 win_id = dev_drv->fb2_win_id;
688         mutex_unlock(&dev_drv->fb_win_id_mutex);
689
690         return win_id;
691 }
692
693 static int rk3036_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
694 {
695         return 0;
696 }
697
698 static int rk3036_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
699                                bool set)
700 {
701         struct lcdc_device *lcdc_dev =
702             container_of(dev_drv, struct lcdc_device, driver);
703         int ovl;
704         spin_lock(&lcdc_dev->reg_lock);
705         if (lcdc_dev->clk_on) {
706                 if (set) {
707                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
708                                      v_WIN0_TOP(swap));
709                         ovl = swap;
710                 } else {
711                         ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
712                 }
713         } else {
714                 ovl = -EPERM;
715         }
716         spin_unlock(&lcdc_dev->reg_lock);
717
718         return ovl;
719 }
720
721 static int rk3036_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
722 {
723
724         struct lcdc_device *lcdc_dev = container_of(dev_drv,
725                                         struct lcdc_device, driver);
726         if (dev_drv->suspend_flag) 
727                 return 0;
728         dev_drv->suspend_flag = 1;
729         flush_kthread_worker(&dev_drv->update_regs_worker);
730
731         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
732                 dev_drv->trsm_ops->disable();
733         spin_lock(&lcdc_dev->reg_lock);
734         if (likely(lcdc_dev->clk_on)) {
735                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
736                              v_BLANK_EN(1));
737                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
738                              v_FS_INT_CLEAR(1));
739                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
740                              v_DSP_OUT_ZERO(1));
741                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
742                              v_LCDC_STANDBY(1));
743                 lcdc_cfg_done(lcdc_dev);
744                 spin_unlock(&lcdc_dev->reg_lock);
745         } else {
746                 spin_unlock(&lcdc_dev->reg_lock);
747                 return 0;
748         }
749         rk3036_lcdc_clk_disable(lcdc_dev);
750         rk_disp_pwr_disable(dev_drv);
751         return 0;
752 }
753
754 static int rk3036_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
755 {
756         struct lcdc_device *lcdc_dev =
757             container_of(dev_drv, struct lcdc_device, driver);
758
759         if (!dev_drv->suspend_flag)
760                 return 0;
761         rk_disp_pwr_enable(dev_drv);
762         dev_drv->suspend_flag = 0;
763
764         if (lcdc_dev->atv_layer_cnt) {
765                 rk3036_lcdc_clk_enable(lcdc_dev);
766                 rk3036_lcdc_reg_restore(lcdc_dev);
767
768                 spin_lock(&lcdc_dev->reg_lock);
769
770                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
771                              v_DSP_OUT_ZERO(0));
772                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
773                              v_LCDC_STANDBY(0));
774                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
775                              v_BLANK_EN(0));
776                 lcdc_cfg_done(lcdc_dev);
777
778                 spin_unlock(&lcdc_dev->reg_lock);
779         }
780         
781         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
782                 dev_drv->trsm_ops->enable();
783         return 0;
784 }
785
786
787 static int rk3036_lcdc_blank(struct rk_lcdc_driver *dev_drv,
788                              int win_id, int blank_mode)
789 {
790         switch (blank_mode) {
791         case FB_BLANK_UNBLANK:
792                 rk3036_lcdc_early_resume(dev_drv);
793                 break;
794         case FB_BLANK_NORMAL:
795                 rk3036_lcdc_early_suspend(dev_drv);
796                 break;
797         default:
798                 rk3036_lcdc_early_suspend(dev_drv);
799                 break;
800         }
801         
802         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
803
804         return 0;
805 }
806
807 static int rk3036_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
808 {
809         struct lcdc_device *lcdc_dev = container_of(dev_drv, 
810                                         struct lcdc_device, driver);
811         spin_lock(&lcdc_dev->reg_lock);
812         if (lcdc_dev->clk_on)
813                 lcdc_cfg_done(lcdc_dev);
814         spin_unlock(&lcdc_dev->reg_lock);
815         return 0;
816 }
817
818 /*
819         a:[-30~0]:
820             sin_hue = sin(a)*256 +0x100;
821             cos_hue = cos(a)*256;
822         a:[0~30]
823             sin_hue = sin(a)*256;
824             cos_hue = cos(a)*256;
825 */
826 static int rk3036_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,bcsh_hue_mode mode)
827 {
828
829         struct lcdc_device *lcdc_dev =
830             container_of(dev_drv, struct lcdc_device, driver);
831         u32 val;
832                         
833         spin_lock(&lcdc_dev->reg_lock);
834         if (lcdc_dev->clk_on) {
835                 val = lcdc_readl(lcdc_dev, BCSH_H);
836                 switch(mode){
837                 case H_SIN:
838                         val &= m_BCSH_SIN_HUE;
839                         break;
840                 case H_COS:
841                         val &= m_BCSH_COS_HUE;
842                         val >>= 16;
843                         break;
844                 default:
845                         break;
846                 }
847         }
848         spin_unlock(&lcdc_dev->reg_lock);
849
850         return val;
851 }
852
853
854 static int rk3036_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,int sin_hue, int cos_hue)
855 {
856
857         struct lcdc_device *lcdc_dev =
858             container_of(dev_drv, struct lcdc_device, driver);
859         u32 mask, val;
860
861         spin_lock(&lcdc_dev->reg_lock);
862         if (lcdc_dev->clk_on) {
863                 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
864                 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
865                 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
866                 lcdc_cfg_done(lcdc_dev);
867         }       
868         spin_unlock(&lcdc_dev->reg_lock);
869         
870         return 0;
871 }
872
873 static int rk3036_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode,int value)
874 {
875         struct lcdc_device *lcdc_dev =
876             container_of(dev_drv, struct lcdc_device, driver);
877         u32 mask, val;
878         
879         spin_lock(&lcdc_dev->reg_lock);
880         if(lcdc_dev->clk_on) {
881                 switch (mode) {
882                 case BRIGHTNESS:
883                 /*from 0 to 255,typical is 128*/
884                         if (value < 0x80)
885                                 value += 0x80;
886                         else if (value >= 0x80)
887                                 value = value - 0x80;
888                         mask =  m_BCSH_BRIGHTNESS;
889                         val = v_BCSH_BRIGHTNESS(value);
890                         break;
891                 case CONTRAST:
892                 /*from 0 to 510,typical is 256*/
893                         mask =  m_BCSH_CONTRAST;
894                         val =  v_BCSH_CONTRAST(value);
895                         break;
896                 case SAT_CON:
897                 /*from 0 to 1015,typical is 256*/
898                         mask = m_BCSH_SAT_CON;
899                         val = v_BCSH_SAT_CON(value);
900                         break;
901                 default:
902                         break;
903                 }
904                 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
905                 lcdc_cfg_done(lcdc_dev);
906         }
907         spin_unlock(&lcdc_dev->reg_lock);
908         return val;
909 }
910
911 static int rk3036_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode)
912 {
913         struct lcdc_device *lcdc_dev =
914             container_of(dev_drv, struct lcdc_device, driver);
915         u32 val;
916
917         spin_lock(&lcdc_dev->reg_lock);
918         if(lcdc_dev->clk_on) {
919                 val = lcdc_readl(lcdc_dev, BCSH_BCS);
920                 switch (mode) {
921                 case BRIGHTNESS:
922                         val &= m_BCSH_BRIGHTNESS;
923                         if(val > 0x80)
924                                 val -= 0x80;
925                         else
926                                 val += 0x80;
927                         break;
928                 case CONTRAST:
929                         val &= m_BCSH_CONTRAST;
930                         val >>= 8;
931                         break;
932                 case SAT_CON:
933                         val &= m_BCSH_SAT_CON;
934                         val >>= 20;
935                         break;
936                 default:
937                         break;
938                 }
939         }
940         spin_unlock(&lcdc_dev->reg_lock);
941         return val;
942 }
943
944
945 static int rk3036_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
946 {
947         struct lcdc_device *lcdc_dev =
948             container_of(dev_drv, struct lcdc_device, driver);
949         u32 mask, val;
950
951         spin_lock(&lcdc_dev->reg_lock);
952         if (lcdc_dev->clk_on) {
953                 if (open) {
954                         lcdc_writel(lcdc_dev,BCSH_COLOR_BAR,0x1);
955                         lcdc_writel(lcdc_dev,BCSH_BCS,0xd0010000);
956                         lcdc_writel(lcdc_dev,BCSH_H,0x01000000);
957                 } else {
958                         mask = m_BCSH_EN;
959                         val = v_BCSH_EN(0);
960                         lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
961                 }
962                 lcdc_cfg_done(lcdc_dev);
963         }
964         spin_unlock(&lcdc_dev->reg_lock);
965         return 0;
966 }
967
968 static int rk3036_fb_win_remap(struct rk_lcdc_driver *dev_drv,
969                                enum fb_win_map_order order)
970 {
971         mutex_lock(&dev_drv->fb_win_id_mutex);
972         if (order == FB_DEFAULT_ORDER)
973                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
974         dev_drv->fb2_win_id = order / 100;
975         dev_drv->fb1_win_id = (order / 10) % 10;
976         dev_drv->fb0_win_id = order % 10;
977         mutex_unlock(&dev_drv->fb_win_id_mutex);
978
979         return 0;
980 }
981
982 static int rk3036_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
983                                bool set)
984 {
985         struct lcdc_device *lcdc_dev =
986             container_of(dev_drv, struct lcdc_device, driver);
987         struct rk_screen *screen = dev_drv->cur_screen;
988         u64 ft = 0;
989         u32 dotclk;
990         int ret;
991         u32 pixclock;
992         u32 x_total, y_total;
993         if (set) {
994                 ft = div_u64(1000000000000llu, fps);
995                 x_total =
996                     screen->mode.upper_margin + screen->mode.lower_margin +
997                     screen->mode.yres + screen->mode.vsync_len;
998                 y_total =
999                     screen->mode.left_margin + screen->mode.right_margin +
1000                     screen->mode.xres + screen->mode.hsync_len;
1001                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1002                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1003                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1004         }
1005
1006         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1007         dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
1008         fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
1009         screen->ft = 1000 / fps;        /*one frame time in ms */
1010
1011         if (set)
1012                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1013                          clk_get_rate(lcdc_dev->dclk), fps);
1014
1015         return fps;
1016 }
1017
1018 static int rk3036_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
1019 {
1020         struct lcdc_device *lcdc_dev =
1021             container_of(dev_drv, struct lcdc_device, driver);
1022         u32 int_reg;
1023         int ret;
1024
1025         if (lcdc_dev->clk_on) {
1026                 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1027                 if (int_reg & m_LF_INT_STA) {
1028                         lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1029                                      v_LF_INT_CLEAR(1));
1030                         ret = RK_LF_STATUS_FC;
1031                 } else
1032                         ret = RK_LF_STATUS_FR;
1033         } else {
1034                 ret = RK_LF_STATUS_NC;
1035         }
1036
1037         return ret;
1038 }
1039
1040 static int rk3036_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
1041 {
1042         struct lcdc_device *lcdc_dev =
1043             container_of(dev_drv, struct lcdc_device, driver);
1044
1045         if(lcdc_dev->clk_on){
1046                 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1047                 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
1048         }
1049         return 0;
1050 }
1051
1052 static ssize_t rk3036_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
1053                                          char *buf, int win_id)
1054 {
1055 //      struct lcdc_device *lcdc_dev = container_of(dev_drv,
1056 //                                      struct lcdc_device, driver);
1057 //      struct rk_screen *screen = dev_drv->cur_screen;
1058         struct rk_lcdc_win *win = NULL;
1059         char fmt[9] = "NULL";
1060         u32     size;
1061         
1062         if (win_id < ARRAY_SIZE(lcdc_win)) {
1063                 win = dev_drv->win[win_id];
1064         } else {
1065                 dev_err(dev_drv->dev,"invalid win number:%d!\n", win_id);
1066                 return 0;
1067         }
1068         
1069         size = snprintf(buf, PAGE_SIZE, "win%d: %s\n", win_id, get_format_string(win->format, fmt));
1070         size += snprintf(buf + size, PAGE_SIZE - size, "        xact %d yact %d xvir %d yvir %d\n", 
1071                 win->area[0].xact, win->area[0].yact, win->area[0].xvir, win->area[0].yvir);
1072         size += snprintf(buf + size, PAGE_SIZE - size, "        xpos %d ypos %d xsize %d ysize %d\n", 
1073                 win->area[0].xpos, win->area[0].ypos, win->area[0].xsize, win->area[0].ysize);
1074         size += snprintf(buf + size, PAGE_SIZE - size, "        yaddr 0x%x uvaddr 0x%x\n", 
1075                 win->area[0].y_addr, win->area[0].uv_addr);
1076         return size;
1077 }
1078
1079 static int rk3036_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
1080 {
1081         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1082                                                 struct lcdc_device,
1083                                                 driver);
1084         int *cbase = (int *)lcdc_dev->regs;
1085         int *regsbak = (int *)lcdc_dev->regsbak;
1086         int i, j;
1087
1088         printk("back up reg:\n");
1089         for (i = 0; i <= (0x90 >> 4); i++) {
1090                 for (j = 0; j < 4; j++)
1091                         printk("%08x  ", *(regsbak + i * 4 + j));
1092                 printk("\n");
1093         }
1094
1095         printk("lcdc reg:\n");
1096         for (i = 0; i <= (0x90 >> 4); i++) {
1097                 for (j = 0; j < 4; j++)
1098                         printk("%08x  ", readl_relaxed(cbase + i * 4 + j));
1099                 printk("\n");
1100         }
1101         return 0;
1102 }
1103
1104 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
1105         .open                   = rk3036_lcdc_open,
1106         .load_screen            = rk3036_load_screen,
1107         .set_par                = rk3036_lcdc_set_par,
1108         .pan_display            = rk3036_lcdc_pan_display,
1109         .blank                  = rk3036_lcdc_blank,
1110         .ioctl                  = rk3036_lcdc_ioctl,
1111         .get_win_state          = rk3036_lcdc_get_win_state,
1112         .ovl_mgr                = rk3036_lcdc_ovl_mgr,
1113         .get_disp_info          = rk3036_lcdc_get_disp_info,
1114         .fps_mgr                = rk3036_lcdc_fps_mgr,
1115         .fb_get_win_id          = rk3036_lcdc_get_win_id,
1116         .fb_win_remap           = rk3036_fb_win_remap,
1117         .poll_vblank            = rk3036_lcdc_poll_vblank,
1118         .get_dsp_addr           = rk3036_lcdc_get_dsp_addr,
1119         .cfg_done               = rk3036_lcdc_cfg_done,
1120         .dump_reg               = rk3036_lcdc_reg_dump,
1121         .set_dsp_bcsh_hue       = rk3036_lcdc_set_bcsh_hue,
1122         .set_dsp_bcsh_bcs       = rk3036_lcdc_set_bcsh_bcs,
1123         .get_dsp_bcsh_hue       = rk3036_lcdc_get_bcsh_hue,
1124         .get_dsp_bcsh_bcs       = rk3036_lcdc_get_bcsh_bcs,
1125         .open_bcsh              = rk3036_lcdc_open_bcsh,
1126 };
1127
1128 static int rk3036_lcdc_probe(struct platform_device *pdev)
1129 {
1130         struct lcdc_device *lcdc_dev = NULL;
1131         struct rk_lcdc_driver *dev_drv;
1132         struct device *dev = &pdev->dev;
1133         struct resource *res;
1134         int ret;
1135         
1136         lcdc_dev = devm_kzalloc(dev,
1137                                 sizeof(struct lcdc_device), GFP_KERNEL);
1138         if (!lcdc_dev) {
1139                 dev_err(&pdev->dev, "rk3036 lcdc device kmalloc fail!");
1140                 return -ENOMEM;
1141         }
1142         platform_set_drvdata(pdev, lcdc_dev);
1143         lcdc_dev->dev = dev;
1144         
1145         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1146         lcdc_dev->reg_phy_base = res->start;
1147         lcdc_dev->len = resource_size(res);
1148         lcdc_dev->regs = devm_ioremap_resource(dev, res);
1149         if (IS_ERR(lcdc_dev->regs))
1150                 return PTR_ERR(lcdc_dev->regs);
1151
1152         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
1153         if (IS_ERR(lcdc_dev->regsbak))
1154                 return PTR_ERR(lcdc_dev->regsbak);
1155
1156         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
1157         dev_drv = &lcdc_dev->driver;
1158         dev_drv->dev = dev;
1159         dev_drv->prop = 0;
1160         dev_drv->id = lcdc_dev->id;
1161         dev_drv->ops = &lcdc_drv_ops;
1162         dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
1163         spin_lock_init(&lcdc_dev->reg_lock);
1164         
1165         lcdc_dev->irq = platform_get_irq(pdev, 0);
1166         if (lcdc_dev->irq < 0) {
1167                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
1168                         lcdc_dev->id);
1169                 return -ENXIO;
1170         }
1171
1172         ret = devm_request_irq(dev, lcdc_dev->irq, rk3036_lcdc_isr,
1173                                IRQF_DISABLED, dev_name(dev), lcdc_dev);
1174         if (ret) {
1175                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
1176                         lcdc_dev->irq, ret);
1177                 return ret;
1178         }
1179
1180         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
1181         if (ret < 0) {
1182                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
1183                 return ret;
1184         }
1185         lcdc_dev->screen = dev_drv->screen0;
1186         
1187         dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
1188         return 0;
1189 }
1190
1191 #if defined(CONFIG_PM)
1192 static int rk3036_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
1193 {
1194         return 0;
1195 }
1196
1197 static int rk3036_lcdc_resume(struct platform_device *pdev)
1198 {
1199         return 0;
1200 }
1201 #else
1202 #define rk3036_lcdc_suspend NULL
1203 #define rk3036_lcdc_resume  NULL
1204 #endif
1205
1206 static int rk3036_lcdc_remove(struct platform_device *pdev)
1207 {
1208         return 0;
1209 }
1210
1211 static void rk3036_lcdc_shutdown(struct platform_device *pdev)
1212 {
1213         
1214 }
1215
1216 #if defined(CONFIG_OF)
1217 static const struct of_device_id rk3036_lcdc_dt_ids[] = {
1218         {.compatible = "rockchip,rk3036-lcdc",},
1219         {}
1220 };
1221 #endif
1222
1223 static struct platform_driver rk3036_lcdc_driver = {
1224         .probe = rk3036_lcdc_probe,
1225         .remove = rk3036_lcdc_remove,
1226         .driver = {
1227                 .name = "rk3036-lcdc",
1228                 .owner = THIS_MODULE,
1229                 .of_match_table = of_match_ptr(rk3036_lcdc_dt_ids),
1230         },
1231         .suspend = rk3036_lcdc_suspend,
1232         .resume = rk3036_lcdc_resume,
1233         .shutdown = rk3036_lcdc_shutdown,
1234 };
1235
1236 static int __init rk3036_lcdc_module_init(void)
1237 {
1238         return platform_driver_register(&rk3036_lcdc_driver);
1239 }
1240
1241 static void __exit rk3036_lcdc_module_exit(void)
1242 {
1243         platform_driver_unregister(&rk3036_lcdc_driver);
1244 }
1245
1246 fs_initcall(rk3036_lcdc_module_init);
1247 module_exit(rk3036_lcdc_module_exit);