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