2 * drivers/video/rockchip/lcdc/rk3288_lcdc.c
4 * Copyright (C) 2014 ROCKCHIP, Inc.
5 *Author:hjc<hjc@rock-chips.com>
6 *This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
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.
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.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 "../../../arch/arm/mach-rockchip/cpu.h"
35 //#include "../../../arch/arm/mach-rockchip/iomap.h"
36 //#include "../../../arch/arm/mach-rockchip/grf.h"
38 #include "rk3288_lcdc.h"
40 #if defined(CONFIG_HAS_EARLYSUSPEND)
41 #include <linux/earlysuspend.h>
44 static int dbg_thresd;
45 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
47 #define DBG(level, x...) do { \
48 if (unlikely(dbg_thresd >= level)) \
49 printk(KERN_INFO x); } while (0)
51 /*#define WAIT_FOR_SYNC 1*/
53 static int rk3288_lcdc_get_id(u32 phy_base)
55 if (cpu_is_rk3288()) {
56 if (phy_base == 0xff940000)/*vop lite*/
62 else if (phy_base == 0xff930000)/*vop big*/
71 pr_err("un supported platform \n");
77 static int rk3288_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
82 struct lcdc_device *lcdc_dev = container_of(dev_drv,
86 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
87 lcdc_cfg_done(lcdc_dev);
89 for (i = 0; i < 256; i++) {
90 v = dev_drv->cur_screen->dsp_lut[i];
91 c = lcdc_dev->dsp_lut_addr_base + i;
95 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
101 static int rk3288_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
103 #ifdef CONFIG_RK_FPGA
104 lcdc_dev->clk_on = 1;
107 if (!lcdc_dev->clk_on) {
108 clk_prepare_enable(lcdc_dev->hclk);
109 clk_prepare_enable(lcdc_dev->dclk);
110 clk_prepare_enable(lcdc_dev->aclk);
111 /*clk_enable(lcdc_dev->pd);*/
112 spin_lock(&lcdc_dev->reg_lock);
113 lcdc_dev->clk_on = 1;
114 spin_unlock(&lcdc_dev->reg_lock);
120 static int rk3288_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
122 #ifdef CONFIG_RK_FPGA
123 lcdc_dev->clk_on = 0;
126 if (lcdc_dev->clk_on) {
127 spin_lock(&lcdc_dev->reg_lock);
128 lcdc_dev->clk_on = 0;
129 spin_unlock(&lcdc_dev->reg_lock);
131 clk_disable_unprepare(lcdc_dev->dclk);
132 clk_disable_unprepare(lcdc_dev->hclk);
133 clk_disable_unprepare(lcdc_dev->aclk);
134 /*clk_disable(lcdc_dev->pd);*/
140 static int rk3288_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
143 spin_lock(&lcdc_dev->reg_lock);
144 if (likely(lcdc_dev->clk_on)) {
145 mask = m_DSP_HOLD_VALID_INTR_EN | m_FS_INTR_EN |
146 m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_EN;
147 val = v_DSP_HOLD_VALID_INTR_EN(0) | v_FS_INTR_EN(0) |
148 v_LINE_FLAG_INTR_EN(0) | v_BUS_ERROR_INTR_EN(0);
149 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
151 mask = m_DSP_HOLD_VALID_INTR_CLR | m_FS_INTR_CLR |
152 m_LINE_FLAG_INTR_CLR | m_LINE_FLAG_INTR_CLR;
153 val = v_DSP_HOLD_VALID_INTR_CLR(0) | v_FS_INTR_CLR(0) |
154 v_LINE_FLAG_INTR_CLR(0) | v_BUS_ERROR_INTR_CLR(0);
155 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
157 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
158 m_WIN2_EMPTY_INTR_EN | m_WIN3_EMPTY_INTR_EN |
159 m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
160 m_POST_BUF_EMPTY_INTR_EN;
161 val = v_WIN0_EMPTY_INTR_EN(0) | v_WIN1_EMPTY_INTR_EN(0) |
162 v_WIN2_EMPTY_INTR_EN(0) | v_WIN3_EMPTY_INTR_EN(0) |
163 v_HWC_EMPTY_INTR_EN(0) | v_POST_BUF_EMPTY_INTR_EN(0) |
164 v_PWM_GEN_INTR_EN(0);
165 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
167 mask = m_WIN0_EMPTY_INTR_CLR | m_WIN1_EMPTY_INTR_CLR |
168 m_WIN2_EMPTY_INTR_CLR | m_WIN3_EMPTY_INTR_CLR |
169 m_HWC_EMPTY_INTR_CLR | m_POST_BUF_EMPTY_INTR_CLR |
170 m_POST_BUF_EMPTY_INTR_CLR;
171 val = v_WIN0_EMPTY_INTR_CLR(0) | v_WIN1_EMPTY_INTR_CLR(0) |
172 v_WIN2_EMPTY_INTR_CLR(0) | v_WIN3_EMPTY_INTR_CLR(0) |
173 v_HWC_EMPTY_INTR_CLR(0) | v_POST_BUF_EMPTY_INTR_CLR(0) |
174 v_PWM_GEN_INTR_CLR(0);
175 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
176 lcdc_cfg_done(lcdc_dev);
177 spin_unlock(&lcdc_dev->reg_lock);
179 spin_unlock(&lcdc_dev->reg_lock);
184 static void rk3288_lcdc_reg_dump(struct lcdc_device *lcdc_dev)
186 int *cbase = (int *)lcdc_dev->regs;
187 int *regsbak = (int *)lcdc_dev->regsbak;
190 printk("back up reg:\n");
191 for (i = 0; i <= (0x200 >> 4); i++) {
192 printk("0x%04x: ",i*16);
193 for (j = 0; j < 4; j++)
194 printk("%08x ", *(regsbak + i * 4 + j));
198 printk("lcdc reg:\n");
199 for (i = 0; i <= (0x200 >> 4); i++) {
200 printk("0x%04x: ",i*16);
201 for (j = 0; j < 4; j++)
202 printk("%08x ", readl_relaxed(cbase + i * 4 + j));
208 /********do basic init*********/
209 static int rk3288_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
212 struct lcdc_device *lcdc_dev = container_of(dev_drv,
216 int *cbase = (int *)lcdc_dev->regs;
217 if (lcdc_dev->pre_init)
220 if (lcdc_dev->id == 0) {
221 /*lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");*/
222 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc0");
223 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc0");
224 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc0");
225 } else if (lcdc_dev->id == 1) {
226 /*lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");*/
227 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc1");
228 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc1");
229 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc1");
231 dev_err(lcdc_dev->dev, "invalid lcdc device!\n");
234 if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
235 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
236 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
240 /*uboot display has enabled lcdc in boot */
241 if (!support_uboot_display()) {
242 rk_disp_pwr_enable(dev_drv);
243 rk3288_lcdc_clk_enable(lcdc_dev);
245 lcdc_dev->clk_on = 1;
248 /*rk3288_lcdc_read_reg_defalut_cfg(lcdc_dev);*/
249 /*rk3288_lcdc_reg_dump(lcdc_dev);*/
250 for (i = 0; i <= (0x200 >> 4); i++) {
251 for (j = 0; j < 4; j++)
252 readl_relaxed(cbase + i * 4 + j);
255 #ifndef CONFIG_RK_FPGA
256 if (lcdc_dev->pwr18 == true) {
257 v = 0x00010001; /*bit14: 1,1.8v;0,3.3v*/
258 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
261 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
264 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN);
265 lcdc_cfg_done(lcdc_dev);
266 lcdc_dev->pre_init = true;
271 static void rk3288_lcdc_deint(struct lcdc_device *lcdc_dev)
275 rk3288_lcdc_disable_irq(lcdc_dev);
276 spin_lock(&lcdc_dev->reg_lock);
277 if (likely(lcdc_dev->clk_on)) {
278 lcdc_dev->clk_on = 0;
279 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_STANDBY_EN);
280 lcdc_cfg_done(lcdc_dev);
281 spin_unlock(&lcdc_dev->reg_lock);
283 spin_unlock(&lcdc_dev->reg_lock);
287 static int rk3288_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv)
289 struct lcdc_device *lcdc_dev =
290 container_of(dev_drv, struct lcdc_device, driver);
291 struct rk_screen *screen = dev_drv->cur_screen;
292 u16 x_res = screen->mode.xres;
293 u16 y_res = screen->mode.yres;
296 u16 post_hsd_en,post_vsd_en;
297 u16 post_dsp_hact_st,post_dsp_hact_end;
298 u16 post_dsp_vact_st,post_dsp_vact_end;
299 u16 post_dsp_vact_st_f1,post_dsp_vact_end_f1;
300 u16 post_h_fac,post_v_fac;
302 h_total = screen->mode.hsync_len+screen->mode.left_margin +
303 x_res + screen->mode.right_margin;
304 v_total = screen->mode.vsync_len+screen->mode.upper_margin +
305 y_res + screen->mode.lower_margin;
307 if(screen->post_dsp_stx + screen->post_xsize > x_res){
308 dev_warn(lcdc_dev->dev, "post:stx[%d] + xsize[%d] > x_res[%d]\n",
309 screen->post_dsp_stx,screen->post_xsize,x_res);
310 screen->post_dsp_stx = x_res - screen->post_xsize;
312 if(screen->x_mirror == 0){
313 post_dsp_hact_st=screen->post_dsp_stx +
314 screen->mode.hsync_len+screen->mode.left_margin;
315 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
317 post_dsp_hact_st = h_total - screen->post_dsp_stx -
318 screen->mode.hsync_len-screen->mode.left_margin;
319 post_dsp_hact_end = post_dsp_hact_st - screen->post_xsize;
321 if((screen->post_xsize < x_res)&&(screen->post_xsize != 0)){
324 GET_SCALE_FACTOR_BILI_DN(x_res , screen->post_xsize);
331 if(screen->post_dsp_sty + screen->post_ysize > y_res){
332 dev_warn(lcdc_dev->dev, "post:sty[%d] + ysize[%d] > y_res[%d]\n",
333 screen->post_dsp_sty,screen->post_ysize,y_res);
334 screen->post_dsp_sty = y_res - screen->post_ysize;
337 if(screen->y_mirror == 0){
338 post_dsp_vact_st = screen->post_dsp_sty +
339 screen->mode.vsync_len+screen->mode.upper_margin;
340 post_dsp_vact_end = post_dsp_vact_st + screen->post_ysize;
342 post_dsp_vact_st = v_total - screen->post_dsp_sty -
343 screen->mode.vsync_len-screen->mode.upper_margin;
344 post_dsp_vact_end = post_dsp_vact_st - screen->post_ysize;
346 if((screen->post_ysize < y_res)&&(screen->post_ysize != 0)){
348 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res, screen->post_ysize);
354 if(screen->interlace == 1){
355 post_dsp_vact_st_f1 = v_total + post_dsp_vact_st;
356 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 + screen->post_ysize;
358 post_dsp_vact_st_f1 = 0;
359 post_dsp_vact_end_f1 = 0;
361 DBG(1,"post:xsize=%d,ysize=%d,xpos=%d,ypos=%d,"
362 "hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
363 screen->post_xsize,screen->post_ysize,screen->xpos,screen->ypos,
364 post_hsd_en,post_h_fac,post_vsd_en,post_v_fac);
365 mask = m_DSP_HACT_END_POST | m_DSP_HACT_ST_POST;
366 val = v_DSP_HACT_END_POST(post_dsp_hact_end) |
367 v_DSP_HACT_ST_POST(post_dsp_hact_st);
368 lcdc_msk_reg(lcdc_dev, POST_DSP_HACT_INFO, mask, val);
370 mask = m_DSP_VACT_END_POST | m_DSP_VACT_ST_POST;
371 val = v_DSP_VACT_END_POST(post_dsp_vact_end) |
372 v_DSP_VACT_ST_POST(post_dsp_vact_st);
373 lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO, mask, val);
375 mask = m_POST_HS_FACTOR_YRGB | m_POST_VS_FACTOR_YRGB;
376 val = v_POST_HS_FACTOR_YRGB(post_h_fac) |
377 v_POST_VS_FACTOR_YRGB(post_v_fac);
378 lcdc_msk_reg(lcdc_dev, POST_SCL_FACTOR_YRGB, mask, val);
380 mask = m_DSP_VACT_END_POST_F1 | m_DSP_VACT_ST_POST_F1;
381 val = v_DSP_VACT_END_POST_F1(post_dsp_vact_end_f1) |
382 v_DSP_VACT_ST_POST_F1(post_dsp_vact_st_f1);
383 lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO_F1, mask, val);
385 mask = m_POST_HOR_SD_EN | m_POST_VER_SD_EN;
386 val = v_POST_HOR_SD_EN(post_hsd_en) | v_POST_VER_SD_EN(post_vsd_en);
387 lcdc_msk_reg(lcdc_dev, POST_SCL_CTRL, mask, val);
391 static int rk3288_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
393 struct lcdc_device *lcdc_dev = container_of(dev_drv,
397 struct rk_lcdc_win *win;
398 u32 colorkey_r,colorkey_g,colorkey_b;
401 win = dev_drv->win[i];
402 key_val = win->color_key_val;
403 colorkey_r = (key_val & 0xff)<<2;
404 colorkey_g = ((key_val>>8)&0xff)<<12;
405 colorkey_b = ((key_val>>16)&0xff)<<22;
406 /*color key dither 565/888->aaa*/
407 key_val = colorkey_r | colorkey_g | colorkey_b;
410 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY, key_val);
413 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY, key_val);
416 lcdc_writel(lcdc_dev, WIN2_COLOR_KEY, key_val);
419 lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val);
428 static int rk3288_lcdc_alpha_cfg(struct rk_lcdc_driver *dev_drv,int win_id)
430 struct lcdc_device *lcdc_dev =
431 container_of(dev_drv, struct lcdc_device, driver);
432 struct rk_lcdc_win *win = dev_drv->win[win_id];
433 struct alpha_config alpha_config;
436 int ppixel_alpha,global_alpha;
437 u32 src_alpha_ctl,dst_alpha_ctl;
438 ppixel_alpha = ((win->format == ARGB888)||(win->format == ABGR888)) ? 1 : 0;
439 global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
440 alpha_config.src_global_alpha_val = win->g_alpha_val;
441 switch(win->alpha_mode){
445 alpha_config.src_factor_mode=AA_ZERO;
446 alpha_config.dst_factor_mode=AA_ZERO;
449 alpha_config.src_factor_mode=AA_ONE;
450 alpha_config.dst_factor_mode=AA_ZERO;
453 alpha_config.src_factor_mode=AA_ZERO;
454 alpha_config.dst_factor_mode=AA_ONE;
457 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
458 alpha_config.src_factor_mode=AA_ONE;
459 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
462 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
463 alpha_config.src_factor_mode=AA_SRC_INVERSE;
464 alpha_config.dst_factor_mode=AA_ONE;
467 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
468 alpha_config.src_factor_mode=AA_SRC;
469 alpha_config.dst_factor_mode=AA_ZERO;
472 alpha_config.src_factor_mode=AA_ZERO;
473 alpha_config.dst_factor_mode=AA_SRC;
476 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
477 alpha_config.src_factor_mode=AA_SRC_INVERSE;
478 alpha_config.dst_factor_mode=AA_ZERO;
481 alpha_config.src_factor_mode=AA_ZERO;
482 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
485 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
486 alpha_config.src_factor_mode=AA_SRC;
487 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
490 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
491 alpha_config.src_factor_mode=AA_SRC_INVERSE;
492 alpha_config.dst_factor_mode=AA_SRC;
495 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
496 alpha_config.src_factor_mode=AA_SRC_INVERSE;
497 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
499 case AB_SRC_OVER_GLOBAL:
500 alpha_config.src_global_alpha_mode=AA_PER_PIX_GLOBAL;
501 alpha_config.src_color_mode=AA_SRC_NO_PRE_MUL;
502 alpha_config.src_factor_mode=AA_SRC_GLOBAL;
503 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
506 pr_err("alpha mode error\n");
509 if((ppixel_alpha == 1)&&(global_alpha == 1)){
510 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
511 }else if(ppixel_alpha == 1){
512 alpha_config.src_global_alpha_mode = AA_PER_PIX;
513 }else if(global_alpha == 1){
514 alpha_config.src_global_alpha_mode = AA_GLOBAL;
516 dev_warn(lcdc_dev->dev,"alpha_en should be 0\n");
518 alpha_config.src_alpha_mode = AA_STRAIGHT;
519 alpha_config.src_alpha_sel = AA_NO_SAT;
523 src_alpha_ctl = 0x60;
524 dst_alpha_ctl = 0x64;
527 src_alpha_ctl = 0xa0;
528 dst_alpha_ctl = 0xa4;
531 src_alpha_ctl = 0xdc;
532 dst_alpha_ctl = 0xec;
535 src_alpha_ctl = 0x12c;
536 dst_alpha_ctl = 0x13c;
539 mask = m_WIN0_DST_FACTOR_M0;
540 val = v_WIN0_DST_FACTOR_M0(alpha_config.dst_factor_mode);
541 lcdc_msk_reg(lcdc_dev, dst_alpha_ctl, mask, val);
542 mask = m_WIN0_SRC_ALPHA_EN | m_WIN0_SRC_COLOR_M0 |
543 m_WIN0_SRC_ALPHA_M0 | m_WIN0_SRC_BLEND_M0 |
544 m_WIN0_SRC_ALPHA_CAL_M0 | m_WIN0_SRC_FACTOR_M0|
545 m_WIN0_SRC_GLOBAL_ALPHA;
546 val = v_WIN0_SRC_ALPHA_EN(1) |
547 v_WIN0_SRC_COLOR_M0(alpha_config.src_color_mode) |
548 v_WIN0_SRC_ALPHA_M0(alpha_config.src_alpha_mode) |
549 v_WIN0_SRC_BLEND_M0(alpha_config.src_global_alpha_mode) |
550 v_WIN0_SRC_FACTOR_M0(alpha_config.src_factor_mode) |
551 v_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
552 lcdc_msk_reg(lcdc_dev, src_alpha_ctl, mask, val);
557 static int rk3288_win_full_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
559 struct lcdc_device *lcdc_dev =
560 container_of(dev_drv, struct lcdc_device, driver);
561 struct rk_lcdc_win *win = dev_drv->win[win_id];
562 unsigned int mask, val, off;
566 mask = m_WIN0_EN | m_WIN0_DATA_FMT | m_WIN0_FMT_10 |
567 m_WIN0_LB_MODE | m_WIN0_RB_SWAP;
568 val = v_WIN0_EN(win->state) | v_WIN0_DATA_FMT(win->fmt_cfg) |
569 v_WIN0_FMT_10(win->fmt_10) |
570 v_WIN0_LB_MODE(win->win_lb_mode) |
571 v_WIN0_RB_SWAP(win->swap_rb);
572 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val);
574 mask = m_WIN0_BIC_COE_SEL |
575 m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
576 m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT4 |
577 m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
578 m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
579 m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
580 m_WIN0_CBR_VER_SCL_MODE | m_WIN0_CBR_HSD_MODE |
581 m_WIN0_CBR_VSU_MODE | m_WIN0_CBR_VSD_MODE;
582 val = v_WIN0_BIC_COE_SEL(win->bic_coe_el) |
583 v_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
584 v_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
585 v_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
586 v_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
587 v_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
588 v_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
589 v_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
590 v_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
591 v_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
592 v_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
593 v_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
594 v_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
595 v_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
596 v_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
597 lcdc_msk_reg(lcdc_dev, WIN0_CTRL1+off, mask,val);
599 val = v_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
600 v_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
601 lcdc_writel(lcdc_dev, WIN0_VIR+off, val);
602 lcdc_writel(lcdc_dev, WIN0_YRGB_MST+off, win->area[0].y_addr);
603 lcdc_writel(lcdc_dev, WIN0_CBR_MST+off, win->area[0].uv_addr);
604 val = v_WIN0_ACT_WIDTH(win->area[0].xact) |
605 v_WIN0_ACT_HEIGHT(win->area[0].yact);
606 lcdc_writel(lcdc_dev, WIN0_ACT_INFO+off, val);
608 val = v_WIN0_DSP_WIDTH(win->area[0].xsize) |
609 v_WIN0_DSP_HEIGHT(win->area[0].ysize);
610 lcdc_writel(lcdc_dev, WIN0_DSP_INFO+off, val);
612 val = v_WIN0_DSP_XST(win->area[0].dsp_stx) |
613 v_WIN0_DSP_YST(win->area[0].dsp_sty);
614 lcdc_writel(lcdc_dev, WIN0_DSP_ST+off, val);
616 val = v_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
617 v_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
618 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB+off, val);
620 val = v_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
621 v_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
622 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR+off, val);
623 if(win->alpha_en == 1)
624 rk3288_lcdc_alpha_cfg(dev_drv,win_id);
626 mask = m_WIN0_SRC_ALPHA_EN;
627 val = v_WIN0_SRC_ALPHA_EN(0);
628 lcdc_msk_reg(lcdc_dev,WIN0_SRC_ALPHA_CTRL+off,mask,val);
633 val = v_WIN0_EN(win->state);
634 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val);
639 static int rk3288_win_lite_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
641 struct lcdc_device *lcdc_dev =
642 container_of(dev_drv, struct lcdc_device, driver);
643 struct rk_lcdc_win *win = dev_drv->win[win_id];
644 unsigned int mask, val, off;
645 off = (win_id-2) * 0x50;
648 mask = m_WIN2_EN | m_WIN2_DATA_FMT | m_WIN2_RB_SWAP;
649 val = v_WIN2_EN(1) | v_WIN2_DATA_FMT(win->fmt_cfg) |
650 v_WIN2_RB_SWAP(win->swap_rb);
651 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
653 if(win->area[0].state == 1){
654 mask = m_WIN2_MST0_EN;
655 val = v_WIN2_MST0_EN(1);
656 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
658 mask = m_WIN2_VIR_STRIDE0;
659 val = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
660 lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
662 lcdc_writel(lcdc_dev,WIN2_MST0+off,win->area[0].y_addr);
663 val = v_WIN2_DSP_WIDTH0(win->area[0].xsize) |
664 v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
665 lcdc_writel(lcdc_dev,WIN2_DSP_INFO0+off,val);
666 val = v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
667 v_WIN2_DSP_YST0(win->area[0].dsp_sty);
668 lcdc_writel(lcdc_dev,WIN2_DSP_ST0+off,val);
670 mask = m_WIN2_MST0_EN;
671 val = v_WIN2_MST0_EN(0);
672 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
675 if(win->area[1].state == 1){
676 mask = m_WIN2_MST1_EN;
677 val = v_WIN2_MST1_EN(1);
678 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
680 mask = m_WIN2_VIR_STRIDE1;
681 val = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
682 lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
684 lcdc_writel(lcdc_dev,WIN2_MST1+off,win->area[1].y_addr);
685 val = v_WIN2_DSP_WIDTH1(win->area[1].xsize) |
686 v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
687 lcdc_writel(lcdc_dev,WIN2_DSP_INFO1+off,val);
688 val = v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
689 v_WIN2_DSP_YST1(win->area[1].dsp_sty);
690 lcdc_writel(lcdc_dev,WIN2_DSP_ST1+off,val);
692 mask = m_WIN2_MST1_EN;
693 val = v_WIN2_MST1_EN(0);
694 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
697 if(win->area[2].state == 1){
698 mask = m_WIN2_MST2_EN;
699 val = v_WIN2_MST2_EN(1);
700 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
702 mask = m_WIN2_VIR_STRIDE2;
703 val = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
704 lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
706 lcdc_writel(lcdc_dev,WIN2_MST2+off,win->area[2].y_addr);
707 val = v_WIN2_DSP_WIDTH2(win->area[2].xsize) |
708 v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
709 lcdc_writel(lcdc_dev,WIN2_DSP_INFO2+off,val);
710 val = v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
711 v_WIN2_DSP_YST2(win->area[2].dsp_sty);
712 lcdc_writel(lcdc_dev,WIN2_DSP_ST2+off,val);
714 mask = m_WIN2_MST2_EN;
715 val = v_WIN2_MST2_EN(0);
716 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
719 if(win->area[3].state == 1){
720 mask = m_WIN2_MST3_EN;
721 val = v_WIN2_MST3_EN(1);
722 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
724 mask = m_WIN2_VIR_STRIDE3;
725 val = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
726 lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
728 lcdc_writel(lcdc_dev,WIN2_MST3+off,win->area[3].y_addr);
729 val = v_WIN2_DSP_WIDTH3(win->area[3].xsize) |
730 v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
731 lcdc_writel(lcdc_dev,WIN2_DSP_INFO3+off,val);
732 val = v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
733 v_WIN2_DSP_YST3(win->area[3].dsp_sty);
734 lcdc_writel(lcdc_dev,WIN2_DSP_ST3+off,val);
736 mask = m_WIN2_MST3_EN;
737 val = v_WIN2_MST3_EN(0);
738 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
741 if(win->alpha_en == 1)
742 rk3288_lcdc_alpha_cfg(dev_drv,win_id);
744 mask = m_WIN2_SRC_ALPHA_EN;
745 val = v_WIN2_SRC_ALPHA_EN(0);
746 lcdc_msk_reg(lcdc_dev,WIN2_SRC_ALPHA_CTRL+off,mask,val);
749 mask = m_WIN2_EN | m_WIN2_MST0_EN |
750 m_WIN2_MST0_EN | m_WIN2_MST2_EN |
752 val = v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
753 v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) |
755 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0+off, mask,val);
760 static int rk3288_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
762 struct lcdc_device *lcdc_dev =
763 container_of(dev_drv, struct lcdc_device, driver);
767 spin_lock(&lcdc_dev->reg_lock);
768 if(likely(lcdc_dev->clk_on))
770 lcdc_dev->standby = 0;
771 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
772 v_STANDBY_EN(lcdc_dev->standby));
773 rk3288_win_full_reg_update(dev_drv,0);
774 rk3288_win_full_reg_update(dev_drv,1);
775 rk3288_win_lite_reg_update(dev_drv,2);
776 rk3288_win_lite_reg_update(dev_drv,3);
777 rk3288_lcdc_post_cfg(dev_drv);
778 lcdc_cfg_done(lcdc_dev);
780 spin_unlock(&lcdc_dev->reg_lock);
782 if (dev_drv->wait_fs) {
783 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
784 init_completion(&dev_drv->frame_done);
785 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
786 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
788 (dev_drv->cur_screen->ft +
790 if (!timeout && (!dev_drv->frame_done.done)) {
791 dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
795 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
800 static int rk3288_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
802 memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x84);
806 static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
812 struct lcdc_device *lcdc_dev =
813 container_of(dev_drv, struct lcdc_device, driver);
814 struct rk_screen *screen = dev_drv->cur_screen;
815 u16 hsync_len = screen->mode.hsync_len;
816 u16 left_margin = screen->mode.left_margin;
817 u16 right_margin = screen->mode.right_margin;
818 u16 vsync_len = screen->mode.vsync_len;
819 u16 upper_margin = screen->mode.upper_margin;
820 u16 lower_margin = screen->mode.lower_margin;
821 u16 x_res = screen->mode.xres;
822 u16 y_res = screen->mode.yres;
826 h_total = hsync_len + left_margin + x_res + right_margin;
827 v_total = vsync_len + upper_margin + y_res + lower_margin;
828 screen->post_dsp_stx=0;
829 screen->post_dsp_sty=0;
830 screen->post_xsize =x_res;
831 screen->post_ysize = y_res;
833 spin_lock(&lcdc_dev->reg_lock);
834 if (likely(lcdc_dev->clk_on)) {
835 switch (screen->face) {
838 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
840 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
841 v_DITHER_DOWN_SEL(1);
842 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
846 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
848 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
849 v_DITHER_DOWN_SEL(1);
850 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
854 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
856 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
857 v_DITHER_DOWN_SEL(1);
858 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
862 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
864 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
865 v_DITHER_DOWN_SEL(1);
866 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
870 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
871 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
872 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
875 dev_err(lcdc_dev->dev,"un supported interface!\n");
878 switch(screen->type){
881 case SCREEN_DUAL_LVDS:
883 val = v_RGB_OUT_EN(1);
885 v |= (lcdc_dev->id << 3);*/
888 mask = m_HDMI_OUT_EN;
889 val = v_HDMI_OUT_EN(1);
891 v |= (lcdc_dev->id << 4);*/
894 mask = m_MIPI_OUT_EN;
895 val = v_MIPI_OUT_EN(1);
896 /*v = (1 << (6+16))||(1 << (9+16));
897 v |= (lcdc_dev->id << 6);
898 v |= (lcdc_dev->id << 9);*/
900 case SCREEN_DUAL_MIPI:
901 mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN;
902 val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1);
903 /*v = (1 << (6+16))||(1 << (9+16));
904 v |= (lcdc_dev->id << 6);
905 v |= (lcdc_dev->id << 9);*/
908 face = OUT_RGB_AAA; /*RGB AAA output*/
909 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
910 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
911 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
913 val = v_EDP_OUT_EN(1);
915 v |= (lcdc_dev->id << 5);*/
918 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
919 #ifndef CONFIG_RK_FPGA
920 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
922 mask = m_DSP_OUT_MODE | m_DSP_HSYNC_POL | m_DSP_VSYNC_POL |
923 m_DSP_DEN_POL | m_DSP_DCLK_POL | m_DSP_BG_SWAP |
924 m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
925 m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN |
927 val = v_DSP_OUT_MODE(face) | v_DSP_HSYNC_POL(screen->pin_hsync) |
928 v_DSP_VSYNC_POL(screen->pin_vsync) |
929 v_DSP_DEN_POL(screen->pin_den) | v_DSP_DCLK_POL(screen->pin_dclk) |
930 v_DSP_BG_SWAP(screen->swap_gb) | v_DSP_RB_SWAP(screen->swap_rb) |
931 v_DSP_RG_SWAP(screen->swap_rg) |
932 v_DSP_DELTA_SWAP(screen->swap_delta) |
933 v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) |
934 v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0);;
935 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
937 mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
938 val = v_DSP_BG_BLUE(0x3ff) | v_DSP_BG_GREEN(0) | v_DSP_BG_RED(0);
939 lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
941 mask = m_DSP_HS_PW | m_DSP_HTOTAL;
942 val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
943 lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
945 mask = m_DSP_HACT_END | m_DSP_HACT_ST;
946 val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
947 v_DSP_HACT_ST(hsync_len + left_margin);
948 lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
950 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
951 val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
952 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
954 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
955 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
956 v_DSP_VACT_ST(vsync_len + upper_margin);
957 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
959 rk3288_lcdc_post_cfg(dev_drv);
961 spin_unlock(&lcdc_dev->reg_lock);
963 #ifndef CONFIG_RK_FPGA
964 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
966 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
968 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
969 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
971 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
972 screen->ft = 1000 / fps;
973 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
974 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
982 /*enable layer,open:1,enable;0 disable*/
983 static int win0_open(struct lcdc_device *lcdc_dev, bool open)
985 spin_lock(&lcdc_dev->reg_lock);
986 if (likely(lcdc_dev->clk_on)) {
988 if (!lcdc_dev->atv_layer_cnt) {
989 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
990 lcdc_dev->standby = 0;
992 lcdc_dev->atv_layer_cnt++;
993 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
994 lcdc_dev->atv_layer_cnt--;
996 lcdc_dev->driver.win[0]->state = open;
997 if (!lcdc_dev->atv_layer_cnt) {
998 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
999 lcdc_dev->standby = 1;
1002 spin_unlock(&lcdc_dev->reg_lock);
1007 static int win1_open(struct lcdc_device *lcdc_dev, bool open)
1009 spin_lock(&lcdc_dev->reg_lock);
1010 if (likely(lcdc_dev->clk_on)) {
1012 if (!lcdc_dev->atv_layer_cnt) {
1013 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1014 lcdc_dev->standby = 0;
1016 lcdc_dev->atv_layer_cnt++;
1017 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1018 lcdc_dev->atv_layer_cnt--;
1020 lcdc_dev->driver.win[1]->state = open;
1022 /*if no layer used,disable lcdc*/
1023 if (!lcdc_dev->atv_layer_cnt) {
1024 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1025 lcdc_dev->standby = 1;
1028 spin_unlock(&lcdc_dev->reg_lock);
1033 static int win2_open(struct lcdc_device *lcdc_dev, bool open)
1035 spin_lock(&lcdc_dev->reg_lock);
1036 if (likely(lcdc_dev->clk_on)) {
1038 if (!lcdc_dev->atv_layer_cnt) {
1039 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1040 lcdc_dev->standby = 0;
1042 lcdc_dev->atv_layer_cnt++;
1043 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1044 lcdc_dev->atv_layer_cnt--;
1046 lcdc_dev->driver.win[2]->state = open;
1048 /*if no layer used,disable lcdc*/
1049 if (!lcdc_dev->atv_layer_cnt) {
1050 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1051 lcdc_dev->standby = 1;
1054 spin_unlock(&lcdc_dev->reg_lock);
1059 static int win3_open(struct lcdc_device *lcdc_dev, bool open)
1061 spin_lock(&lcdc_dev->reg_lock);
1062 if (likely(lcdc_dev->clk_on)) {
1064 if (!lcdc_dev->atv_layer_cnt) {
1065 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1066 lcdc_dev->standby = 0;
1068 lcdc_dev->atv_layer_cnt++;
1069 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1070 lcdc_dev->atv_layer_cnt--;
1072 lcdc_dev->driver.win[3]->state = open;
1074 /*if no layer used,disable lcdc*/
1075 if (!lcdc_dev->atv_layer_cnt) {
1076 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1077 lcdc_dev->standby = 1;
1080 spin_unlock(&lcdc_dev->reg_lock);
1086 static int rk3288_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1089 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1090 struct lcdc_device, driver);
1092 /*enable clk,when first layer open */
1093 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1094 rk3288_lcdc_pre_init(dev_drv);
1095 rk3288_lcdc_clk_enable(lcdc_dev);
1096 rk3288_lcdc_reg_restore(lcdc_dev);
1097 rk3288_load_screen(dev_drv, 1);
1098 spin_lock(&lcdc_dev->reg_lock);
1099 if (dev_drv->cur_screen->dsp_lut)
1100 rk3288_lcdc_set_lut(dev_drv);
1101 spin_unlock(&lcdc_dev->reg_lock);
1105 win0_open(lcdc_dev, open);
1106 else if (win_id == 1)
1107 win1_open(lcdc_dev, open);
1108 else if (win_id == 2)
1109 win2_open(lcdc_dev, open);
1110 else if (win_id == 3)
1111 win3_open(lcdc_dev, open);
1113 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1115 /*when all layer closed,disable clk */
1116 if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1117 rk3288_lcdc_disable_irq(lcdc_dev);
1118 rk3288_lcdc_reg_update(dev_drv);
1119 rk3288_lcdc_clk_disable(lcdc_dev);
1125 static int win0_display(struct lcdc_device *lcdc_dev,
1126 struct rk_lcdc_win *win)
1130 y_addr = win->area[0].smem_start+win->area[0].y_offset;/*win->smem_start + win->y_offset;*/
1131 uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1132 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
1133 lcdc_dev->id, __func__, y_addr, uv_addr);
1134 spin_lock(&lcdc_dev->reg_lock);
1135 if (likely(lcdc_dev->clk_on)) {
1136 win->area[0].y_addr = y_addr;
1137 win->area[0].uv_addr = uv_addr;
1139 spin_unlock(&lcdc_dev->reg_lock);
1145 static int win1_display(struct lcdc_device *lcdc_dev,
1146 struct rk_lcdc_win *win)
1150 y_addr = win->area[0].smem_start + win->area[0].y_offset;
1151 uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1152 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
1153 lcdc_dev->id, __func__, y_addr, uv_addr);
1155 spin_lock(&lcdc_dev->reg_lock);
1156 if (likely(lcdc_dev->clk_on))
1157 win->area[0].y_addr = y_addr;
1158 spin_unlock(&lcdc_dev->reg_lock);
1163 static int win2_display(struct lcdc_device *lcdc_dev,
1164 struct rk_lcdc_win *win)
1167 y_addr = win->area[0].smem_start + win->area[0].y_offset;
1168 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>\n",
1169 lcdc_dev->id, __func__, y_addr);
1171 spin_lock(&lcdc_dev->reg_lock);
1172 if (likely(lcdc_dev->clk_on))
1173 for(i=0;i<win->area_num;i++){
1174 win->area[i].y_addr =
1175 win->area[i].smem_start + win->area[i].y_offset;
1177 spin_unlock(&lcdc_dev->reg_lock);
1181 static int win3_display(struct lcdc_device *lcdc_dev,
1182 struct rk_lcdc_win *win)
1185 y_addr = win->area[0].smem_start + win->area[0].y_offset;
1186 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>\n",
1187 lcdc_dev->id, __func__, y_addr);
1189 spin_lock(&lcdc_dev->reg_lock);
1190 if (likely(lcdc_dev->clk_on))
1191 for(i=0;i<win->area_num;i++){
1192 win->area[i].y_addr =
1193 win->area[i].smem_start + win->area[i].y_offset;
1195 spin_unlock(&lcdc_dev->reg_lock);
1200 static int rk3288_lcdc_win_display(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *win,int win_id)
1202 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1203 struct lcdc_device, driver);
1204 struct rk_screen *screen = dev_drv->cur_screen;
1207 lcdc_dev->atv_layer_cnt = dev_drv->atv_layer_cnt;
1209 dev_err(dev_drv->dev, "screen is null!\n");
1214 win0_display(lcdc_dev, win);
1215 }else if(win_id == 1){
1216 win1_display(lcdc_dev, win);
1217 }else if(win_id == 2){
1218 win2_display(lcdc_dev, win);
1219 }else if(win_id == 3){
1220 win3_display(lcdc_dev, win);
1222 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1225 /*this is the first frame of the system ,enable frame start interrupt */
1226 if ((dev_drv->first_frame)) {
1227 dev_drv->first_frame = 0;
1228 mask = m_FS_INTR_CLR | m_FS_INTR_EN | m_LINE_FLAG_INTR_CLR |
1229 m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_CLR |
1230 m_BUS_ERROR_INTR_EN | m_DSP_LINE_FLAG_NUM;
1231 val = v_FS_INTR_CLR(1) | v_FS_INTR_EN(1) | v_LINE_FLAG_INTR_CLR(1) |
1232 v_LINE_FLAG_INTR_EN(1) | v_BUS_ERROR_INTR_CLR(1) | v_BUS_ERROR_INTR_EN(0) |
1233 v_DSP_LINE_FLAG_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
1234 screen->mode.yres -1);
1235 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
1236 #ifdef CONFIG_RK_FPGA
1237 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN |
1238 m_WIN3_EMPTY_INTR_EN |m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
1240 val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) | v_WIN2_EMPTY_INTR_EN(1) |
1241 v_WIN3_EMPTY_INTR_EN(1)| v_HWC_EMPTY_INTR_EN(1) | v_POST_BUF_EMPTY_INTR_EN(1) |
1242 v_PWM_GEN_INTR_EN(1);
1243 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
1245 lcdc_cfg_done(lcdc_dev);
1251 static int rk3288_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1253 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1254 struct lcdc_device, driver);
1255 struct rk_lcdc_win *win = NULL;
1256 struct rk_screen *screen = dev_drv->cur_screen;
1258 #if defined(WAIT_FOR_SYNC)
1260 unsigned long flags;
1262 win = dev_drv->win[win_id];
1263 lcdc_dev->atv_layer_cnt = dev_drv->atv_layer_cnt;
1265 dev_err(dev_drv->dev, "screen is null!\n");
1270 win0_display(lcdc_dev, win);
1271 }else if(win_id == 1){
1272 win1_display(lcdc_dev, win);
1273 }else if(win_id == 2){
1274 win2_display(lcdc_dev, win);
1275 }else if(win_id == 3){
1276 win3_display(lcdc_dev, win);
1278 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1284 /*this is the first frame of the system ,enable frame start interrupt */
1285 if ((dev_drv->first_frame)) {
1286 dev_drv->first_frame = 0;
1287 mask = m_FS_INTR_CLR | m_FS_INTR_EN | m_LINE_FLAG_INTR_CLR |
1288 m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_CLR |
1289 m_BUS_ERROR_INTR_EN | m_DSP_LINE_FLAG_NUM;
1290 val = v_FS_INTR_CLR(1) | v_FS_INTR_EN(1) | v_LINE_FLAG_INTR_CLR(1) |
1291 v_LINE_FLAG_INTR_EN(1) | v_BUS_ERROR_INTR_CLR(1) | v_BUS_ERROR_INTR_EN(0) |
1292 v_DSP_LINE_FLAG_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
1293 screen->mode.yres -1);
1294 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
1295 #ifdef CONFIG_RK_FPGA
1296 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN |
1297 m_WIN3_EMPTY_INTR_EN |m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
1299 val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) | v_WIN2_EMPTY_INTR_EN(1) |
1300 v_WIN3_EMPTY_INTR_EN(1)| v_HWC_EMPTY_INTR_EN(1) | v_POST_BUF_EMPTY_INTR_EN(1) |
1301 v_PWM_GEN_INTR_EN(1);
1302 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
1304 lcdc_cfg_done(lcdc_dev);
1306 #if defined(WAIT_FOR_SYNC)
1307 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
1308 init_completion(&dev_drv->frame_done);
1309 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
1310 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
1311 msecs_to_jiffies(dev_drv->
1314 if (!timeout && (!dev_drv->frame_done.done)) {
1315 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
1319 dev_drv->ops->ovl_mgr(dev_drv, 0, 1);
1320 rk3288_lcdc_reg_update(dev_drv);
1324 static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win)
1334 u32 yrgb_vScaleDnMult;
1335 u32 yrgb_xscl_factor;
1336 u32 yrgb_yscl_factor;
1337 u8 yrgb_vsd_bil_gt2=0;
1338 u8 yrgb_vsd_bil_gt4=0;
1344 u32 cbcr_vScaleDnMult;
1345 u32 cbcr_xscl_factor;
1346 u32 cbcr_yscl_factor;
1347 u8 cbcr_vsd_bil_gt2=0;
1348 u8 cbcr_vsd_bil_gt4=0;
1351 srcW = win->area[0].xact;
1352 srcH = win->area[0].yact;
1353 dstW = win->area[0].xsize;
1354 dstH = win->area[0].ysize;
1361 if(yrgb_srcW < yrgb_dstW){
1362 win->yrgb_hor_scl_mode = SCALE_UP;
1363 }else if(yrgb_srcW > yrgb_dstW){
1364 win->yrgb_hor_scl_mode = SCALE_DOWN;
1366 win->yrgb_hor_scl_mode = SCALE_NONE;
1369 if(yrgb_srcH < yrgb_dstH){
1370 win->yrgb_ver_scl_mode = SCALE_UP;
1371 }else if (yrgb_srcH > yrgb_dstH){
1372 win->yrgb_ver_scl_mode = SCALE_DOWN;
1374 win->yrgb_ver_scl_mode = SCALE_NONE;
1378 switch (win->format) {
1404 if(cbcr_srcW < cbcr_dstW){
1405 win->cbr_hor_scl_mode = SCALE_UP;
1406 }else if(cbcr_srcW > cbcr_dstW){
1407 win->cbr_hor_scl_mode = SCALE_DOWN;
1409 win->cbr_hor_scl_mode = SCALE_NONE;
1412 if(cbcr_srcH < cbcr_dstH){
1413 win->cbr_ver_scl_mode = SCALE_UP;
1414 }else if(cbcr_srcH > cbcr_dstH){
1415 win->cbr_ver_scl_mode = SCALE_DOWN;
1417 win->cbr_ver_scl_mode = SCALE_NONE;
1419 DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
1420 "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1421 "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1422 ,srcW,srcH,dstW,dstH,yrgb_srcW,yrgb_srcH,yrgb_dstW,
1423 yrgb_dstH,win->yrgb_hor_scl_mode,win->yrgb_ver_scl_mode,
1424 cbcr_srcW,cbcr_srcH,cbcr_dstW,cbcr_dstH,
1425 win->cbr_hor_scl_mode,win->cbr_ver_scl_mode);
1427 /*line buffer mode*/
1428 if((win->format == YUV422) || (win->format == YUV420)){
1429 if(win->cbr_hor_scl_mode == SCALE_DOWN){
1430 if(cbcr_dstW > 3840){
1431 pr_err("ERROR cbcr_dst_width exceeds 3840\n");
1432 }else if(cbcr_dstW > 2560){
1433 win->win_lb_mode = LB_RGB_3840X2;
1434 }else if(cbcr_dstW > 1920){
1435 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1436 if(yrgb_dstW > 3840){
1437 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1438 }else if(yrgb_dstW > 2560){
1439 win->win_lb_mode = LB_RGB_3840X2;
1440 }else if(yrgb_dstW > 1920){
1441 win->win_lb_mode = LB_RGB_2560X4;
1443 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1446 }else if(cbcr_dstW > 1280){
1447 win->win_lb_mode = LB_YUV_3840X5;
1449 win->win_lb_mode = LB_YUV_2560X8;
1451 } else { /*SCALE_UP or SCALE_NONE*/
1452 if(cbcr_srcW > 3840){
1453 pr_err("ERROR cbcr_act_width exceeds 3840\n");
1454 }else if(cbcr_srcW > 2560){
1455 win->win_lb_mode = LB_RGB_3840X2;
1456 }else if(cbcr_srcW > 1920){
1457 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1458 if(yrgb_dstW > 3840){
1459 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1460 }else if(yrgb_dstW > 2560){
1461 win->win_lb_mode = LB_RGB_3840X2;
1462 }else if(yrgb_dstW > 1920){
1463 win->win_lb_mode = LB_RGB_2560X4;
1465 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1468 }else if(cbcr_srcW > 1280){
1469 win->win_lb_mode = LB_YUV_3840X5;
1471 win->win_lb_mode = LB_YUV_2560X8;
1475 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1476 if(yrgb_dstW > 3840){
1477 pr_err("ERROR yrgb_dsp_width exceeds 3840\n");
1478 }else if(yrgb_dstW > 2560){
1479 win->win_lb_mode = LB_RGB_3840X2;
1480 }else if(yrgb_dstW > 1920){
1481 win->win_lb_mode = LB_RGB_2560X4;
1482 }else if(yrgb_dstW > 1280){
1483 win->win_lb_mode = LB_RGB_1920X5;
1485 win->win_lb_mode = LB_RGB_1280X8;
1487 }else{ /*SCALE_UP or SCALE_NONE*/
1488 if(yrgb_srcW > 3840){
1489 pr_err("ERROR yrgb_act_width exceeds 3840\n");
1490 }else if(yrgb_srcW > 2560){
1491 win->win_lb_mode = LB_RGB_3840X2;
1492 }else if(yrgb_srcW > 1920){
1493 win->win_lb_mode = LB_RGB_2560X4;
1494 }else if(yrgb_srcW > 1280){
1495 win->win_lb_mode = LB_RGB_1920X5;
1497 win->win_lb_mode = LB_RGB_1280X8;
1501 DBG(1,"win->win_lb_mode = %d;\n",win->win_lb_mode);
1503 /*vsd/vsu scale ALGORITHM*/
1504 win->yrgb_hsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1505 win->cbr_hsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1506 win->yrgb_vsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1507 win->cbr_vsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1508 switch(win->win_lb_mode){
1513 win->yrgb_vsu_mode = SCALE_UP_BIC;
1514 win->cbr_vsu_mode = SCALE_UP_BIC;
1517 if(win->yrgb_ver_scl_mode != SCALE_NONE) {
1518 pr_err("ERROR : not allow yrgb ver scale\n");
1520 if(win->cbr_ver_scl_mode != SCALE_NONE) {
1521 pr_err("ERROR : not allow cbcr ver scale\n");
1525 win->yrgb_vsu_mode = SCALE_UP_BIL;
1526 win->cbr_vsu_mode = SCALE_UP_BIL;
1531 DBG(1,"yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
1532 win->yrgb_hsd_mode,win->yrgb_vsd_mode,win->yrgb_vsu_mode,
1533 win->cbr_hsd_mode,win->cbr_vsd_mode,win->cbr_vsu_mode);
1537 /*(1.1)YRGB HOR SCALE FACTOR*/
1538 switch(win->yrgb_hor_scl_mode){
1540 yrgb_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1543 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
1546 switch(win->yrgb_hsd_mode)
1548 case SCALE_DOWN_BIL:
1549 yrgb_xscl_factor = GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
1551 case SCALE_DOWN_AVG:
1552 yrgb_xscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
1560 } /*win->yrgb_hor_scl_mode*/
1562 /*(1.2)YRGB VER SCALE FACTOR*/
1563 switch(win->yrgb_ver_scl_mode)
1566 yrgb_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1569 switch(win->yrgb_vsu_mode)
1572 yrgb_yscl_factor = GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
1576 pr_err("yrgb_srcH should be greater than 3 !!!\n");
1578 yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH, yrgb_dstH);
1585 switch(win->yrgb_vsd_mode)
1587 case SCALE_DOWN_BIL:
1588 yrgb_vScaleDnMult = getHardWareVSkipLines(yrgb_srcH, yrgb_dstH);
1589 yrgb_yscl_factor = GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH, yrgb_vScaleDnMult);
1590 if(yrgb_vScaleDnMult == 4){
1591 yrgb_vsd_bil_gt4 = 1;
1592 yrgb_vsd_bil_gt2 = 0;
1593 }else if(yrgb_vScaleDnMult == 2){
1594 yrgb_vsd_bil_gt4 = 0;
1595 yrgb_vsd_bil_gt2 = 1;
1597 yrgb_vsd_bil_gt4 = 0;
1598 yrgb_vsd_bil_gt2 = 0;
1601 case SCALE_DOWN_AVG:
1602 yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH, yrgb_dstH);
1606 } /*win->yrgb_vsd_mode*/
1611 win->scale_yrgb_x = yrgb_xscl_factor;
1612 win->scale_yrgb_y = yrgb_yscl_factor;
1613 win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
1614 win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
1615 DBG(1,"yrgb:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",yrgb_xscl_factor,
1616 yrgb_yscl_factor,yrgb_vsd_bil_gt4,yrgb_vsd_bil_gt2);
1618 /*(2.1)CBCR HOR SCALE FACTOR*/
1619 switch(win->cbr_hor_scl_mode)
1622 cbcr_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1625 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
1628 switch(win->cbr_hsd_mode)
1630 case SCALE_DOWN_BIL:
1631 cbcr_xscl_factor = GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
1633 case SCALE_DOWN_AVG:
1634 cbcr_xscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
1642 } /*win->cbr_hor_scl_mode*/
1644 /*(2.2)CBCR VER SCALE FACTOR*/
1645 switch(win->cbr_ver_scl_mode)
1648 cbcr_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1651 switch(win->cbr_vsu_mode)
1654 cbcr_yscl_factor = GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
1658 pr_err("cbcr_srcH should be greater than 3 !!!\n");
1660 cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH, cbcr_dstH);
1667 switch(win->cbr_vsd_mode)
1669 case SCALE_DOWN_BIL:
1670 cbcr_vScaleDnMult = getHardWareVSkipLines(cbcr_srcH, cbcr_dstH);
1671 cbcr_yscl_factor = GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH, cbcr_vScaleDnMult);
1672 if(cbcr_vScaleDnMult == 4){
1673 cbcr_vsd_bil_gt4 = 1;
1674 cbcr_vsd_bil_gt2 = 0;
1675 }else if(cbcr_vScaleDnMult == 2){
1676 cbcr_vsd_bil_gt4 = 0;
1677 cbcr_vsd_bil_gt2 = 1;
1679 cbcr_vsd_bil_gt4 = 0;
1680 cbcr_vsd_bil_gt2 = 0;
1683 case SCALE_DOWN_AVG:
1684 cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH, cbcr_dstH);
1693 win->scale_cbcr_x = cbcr_xscl_factor;
1694 win->scale_cbcr_y = cbcr_yscl_factor;
1695 win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
1696 win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
1698 DBG(1,"cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",cbcr_xscl_factor,
1699 cbcr_yscl_factor,cbcr_vsd_bil_gt4,cbcr_vsd_bil_gt2);
1705 static int win0_set_par(struct lcdc_device *lcdc_dev,
1706 struct rk_screen *screen, struct rk_lcdc_win *win)
1708 u32 xact,yact,xvir, yvir,xpos, ypos;
1710 char fmt[9] = "NULL";
1712 xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
1713 ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
1715 spin_lock(&lcdc_dev->reg_lock);
1716 if(likely(lcdc_dev->clk_on)){
1717 rk3288_lcdc_cal_scl_fac(win);/*fac,lb.gt2,gt4*/
1718 switch (win->format){
1749 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1753 win->fmt_cfg = fmt_cfg;
1754 win->area[0].dsp_stx = xpos;
1755 win->area[0].dsp_sty = ypos;
1756 xact = win->area[0].xact;
1757 yact = win->area[0].yact;
1758 xvir = win->area[0].xvir;
1759 yvir = win->area[0].xvir;
1761 spin_unlock(&lcdc_dev->reg_lock);
1763 DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1764 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
1765 __func__, get_format_string(win->format, fmt), xact,
1766 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
1771 static int win1_set_par(struct lcdc_device *lcdc_dev,
1772 struct rk_screen *screen, struct rk_lcdc_win *win)
1774 u32 xact,yact,xvir, yvir,xpos, ypos;
1776 char fmt[9] = "NULL";
1778 xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
1779 ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
1781 spin_lock(&lcdc_dev->reg_lock);
1782 if(likely(lcdc_dev->clk_on)){
1783 rk3288_lcdc_cal_scl_fac(win);/*fac,lb.gt2,gt4*/
1784 switch (win->format){
1815 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1819 win->fmt_cfg = fmt_cfg;
1820 win->area[0].dsp_stx = xpos;
1821 win->area[0].dsp_sty = ypos;
1822 xact = win->area[0].xact;
1823 yact = win->area[0].yact;
1824 xvir = win->area[0].xvir;
1825 yvir = win->area[0].xvir;
1827 spin_unlock(&lcdc_dev->reg_lock);
1829 DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1830 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
1831 __func__, get_format_string(win->format, fmt), xact,
1832 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
1837 static int win2_set_par(struct lcdc_device *lcdc_dev,
1838 struct rk_screen *screen, struct rk_lcdc_win *win)
1843 spin_lock(&lcdc_dev->reg_lock);
1844 if(likely(lcdc_dev->clk_on)){
1845 for(i=0;i<win->area_num;i++){
1846 switch (win->format){
1865 dev_err(lcdc_dev->driver.dev,
1866 "%s:un supported format!\n",
1870 win->fmt_cfg = fmt_cfg;
1871 win->area[i].dsp_stx = win->area[i].xpos +
1872 screen->mode.left_margin +
1873 screen->mode.hsync_len;
1874 win->area[i].dsp_sty = win->area[i].ypos +
1875 screen->mode.upper_margin +
1876 screen->mode.vsync_len;;
1879 spin_unlock(&lcdc_dev->reg_lock);
1883 static int win3_set_par(struct lcdc_device *lcdc_dev,
1884 struct rk_screen *screen, struct rk_lcdc_win *win)
1890 spin_lock(&lcdc_dev->reg_lock);
1891 if(likely(lcdc_dev->clk_on)){
1892 for(i=0;i<win->area_num;i++){
1893 switch (win->format){
1912 dev_err(lcdc_dev->driver.dev,
1913 "%s:un supported format!\n",
1917 win->fmt_cfg = fmt_cfg;
1918 win->area[i].dsp_stx = win->area[i].xpos +
1919 screen->mode.left_margin +
1920 screen->mode.hsync_len;
1921 win->area[i].dsp_sty = win->area[i].ypos +
1922 screen->mode.upper_margin +
1923 screen->mode.vsync_len;;
1926 spin_unlock(&lcdc_dev->reg_lock);
1932 static int rk3288_set_win_par(struct rk_lcdc_driver *dev_drv,
1933 struct rk_screen *screen, struct rk_lcdc_win *win,int win_id)
1935 struct lcdc_device *lcdc_dev =
1936 container_of(dev_drv, struct lcdc_device, driver);
1941 win0_set_par(lcdc_dev, screen, win);
1944 win1_set_par(lcdc_dev, screen, win);
1947 win2_set_par(lcdc_dev, screen, win);
1950 win3_set_par(lcdc_dev, screen, win);
1953 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
1958 static int rk3288_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
1960 struct rk_lcdc_win *win = NULL;
1961 struct rk_screen *screen = dev_drv->cur_screen;
1965 dev_err(dev_drv->dev, "screen is null!\n");
1968 for(i=0;i<dev_drv->lcdc_win_num;i++){
1969 if(dev_drv->win[i]->state == 1){
1970 win = dev_drv->win[i];
1971 rk3288_set_win_par(dev_drv,screen,win,i);
1972 rk3288_lcdc_win_display(dev_drv,win,i);
1976 dev_drv->ops->ovl_mgr(dev_drv, 0, 1);
1977 rk3288_lcdc_reg_update(dev_drv);
1983 static int rk3288_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1984 unsigned long arg, int win_id)
1986 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1991 void __user *argp = (void __user *)arg;
1992 struct color_key_cfg clr_key_cfg;
1995 case RK_FBIOGET_PANEL_SIZE:
1996 panel_size[0] = lcdc_dev->screen->mode.xres;
1997 panel_size[1] = lcdc_dev->screen->mode.yres;
1998 if (copy_to_user(argp, panel_size, 8))
2001 case RK_FBIOPUT_COLOR_KEY_CFG:
2002 if (copy_from_user(&clr_key_cfg, argp,
2003 sizeof(struct color_key_cfg)))
2005 rk3288_lcdc_clr_key_cfg(dev_drv);
2006 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
2007 clr_key_cfg.win0_color_key_cfg);
2008 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
2009 clr_key_cfg.win1_color_key_cfg);
2018 static int rk3288_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
2020 struct lcdc_device *lcdc_dev =
2021 container_of(dev_drv, struct lcdc_device, driver);
2022 if (dev_drv->screen0->standby)
2023 dev_drv->screen0->standby(1);
2024 if (dev_drv->screen_ctr_info->io_disable)
2025 dev_drv->screen_ctr_info->io_disable();
2026 dev_drv->suspend_flag = 1;
2027 flush_kthread_worker(&dev_drv->update_regs_worker);
2029 spin_lock(&lcdc_dev->reg_lock);
2030 if (likely(lcdc_dev->clk_on)) {
2031 rk3288_lcdc_disable_irq(lcdc_dev);
2032 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2034 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2036 lcdc_cfg_done(lcdc_dev);
2037 spin_unlock(&lcdc_dev->reg_lock);
2039 spin_unlock(&lcdc_dev->reg_lock);
2042 rk3288_lcdc_clk_disable(lcdc_dev);
2046 static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
2048 struct lcdc_device *lcdc_dev =
2049 container_of(dev_drv, struct lcdc_device, driver);
2054 if (dev_drv->screen_ctr_info->io_enable)
2055 dev_drv->screen_ctr_info->io_enable();
2056 dev_drv->suspend_flag = 0;
2058 if (lcdc_dev->atv_layer_cnt) {
2059 rk3288_lcdc_clk_enable(lcdc_dev);
2060 rk3288_lcdc_reg_restore(lcdc_dev);
2062 spin_lock(&lcdc_dev->reg_lock);
2063 if (dev_drv->cur_screen->dsp_lut) {
2064 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2066 lcdc_cfg_done(lcdc_dev);
2068 for (i = 0; i < 256; i++) {
2069 v = dev_drv->cur_screen->dsp_lut[i];
2070 c = lcdc_dev->dsp_lut_addr_base + i;
2071 writel_relaxed(v, c);
2073 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2077 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2079 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2081 lcdc_cfg_done(lcdc_dev);
2083 spin_unlock(&lcdc_dev->reg_lock);
2086 if (dev_drv->screen0->standby)
2087 dev_drv->screen0->standby(0);
2091 static int rk3288_lcdc_blank(struct rk_lcdc_driver *dev_drv,
2092 int win_id, int blank_mode)
2094 struct lcdc_device *lcdc_dev =
2095 container_of(dev_drv, struct lcdc_device, driver);
2097 spin_lock(&lcdc_dev->reg_lock);
2098 if (likely(lcdc_dev->clk_on)) {
2099 switch (blank_mode) {
2100 case FB_BLANK_UNBLANK:
2101 rk3288_lcdc_early_resume(dev_drv);
2102 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2105 case FB_BLANK_NORMAL:
2106 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2108 rk3288_lcdc_early_suspend(dev_drv);
2111 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2113 rk3288_lcdc_early_suspend(dev_drv);
2116 lcdc_cfg_done(lcdc_dev);
2119 spin_unlock(&lcdc_dev->reg_lock);
2121 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
2126 static int rk3288_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
2131 /*overlay will be do at regupdate*/
2132 static int rk3288_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
2135 struct lcdc_device *lcdc_dev =
2136 container_of(dev_drv, struct lcdc_device, driver);
2138 unsigned int mask, val;
2139 int win0_order,win1_order,win2_order,win3_order;
2140 win0_order = dev_drv->win[0]->z_order;
2141 win1_order = dev_drv->win[1]->z_order;
2142 win2_order = dev_drv->win[2]->z_order;
2143 win3_order = dev_drv->win[3]->z_order;
2145 spin_lock(&lcdc_dev->reg_lock);
2146 if(lcdc_dev->clk_on){
2148 mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
2149 m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
2150 val = v_DSP_LAYER0_SEL(0) |
2151 v_DSP_LAYER1_SEL(1) |
2152 v_DSP_LAYER2_SEL(2) |
2153 v_DSP_LAYER3_SEL(3);
2154 lcdc_msk_reg(lcdc_dev,DSP_CTRL1,mask,val);
2156 win0_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER0_SEL);
2157 win1_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER1_SEL);
2158 win2_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER2_SEL);
2159 win3_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER3_SEL);
2160 ovl = win3_order*1000 + win2_order*100 + win1_order *10 + win0_order;
2165 spin_unlock(&lcdc_dev->reg_lock);
2170 static ssize_t rk3288_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2171 char *buf, int win_id)
2173 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2177 struct rk_screen *screen = dev_drv->cur_screen;
2178 u16 hsync_len = screen->mode.hsync_len;
2179 u16 left_margin = screen->mode.left_margin;
2180 u16 vsync_len = screen->mode.vsync_len;
2181 u16 upper_margin = screen->mode.upper_margin;
2182 u32 fmt_id,h_pw_bp,v_pw_bp;
2183 char format_w0[9] = "NULL";
2184 char format_w1[9] = "NULL";
2185 char format_w2[9] = "NULL";
2186 char format_w3[9] = "NULL";
2187 u32 win_ctrl,zorder,vir_info,act_info,dsp_info,dsp_st,y_factor,uv_factor;
2188 u8 layer0_sel,layer1_sel,layer2_sel,layer3_sel;
2189 u8 w0_state,w1_state,w2_state,w3_state;
2190 u8 w2_0_state,w2_1_state,w2_2_state,w2_3_state;
2191 u8 w3_0_state,w3_1_state,w3_2_state,w3_3_state;
2193 u32 w0_vir_y,w0_vir_uv,w0_act_x,w0_act_y,w0_dsp_x,w0_dsp_y,w0_st_x,w0_st_y;
2194 u32 w1_vir_y,w1_vir_uv,w1_act_x,w1_act_y,w1_dsp_x,w1_dsp_y,w1_st_x,w1_st_y;
2195 u32 w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,w0_uv_v_fac;
2196 u32 w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,w1_uv_v_fac;
2198 u32 w2_0_vir_y,w2_1_vir_y,w2_2_vir_y,w2_3_vir_y;
2199 u32 w2_0_dsp_x,w2_1_dsp_x,w2_2_dsp_x,w2_3_dsp_x;
2200 u32 w2_0_dsp_y,w2_1_dsp_y,w2_2_dsp_y,w2_3_dsp_y;
2201 u32 w2_0_st_x,w2_1_st_x,w2_2_st_x,w2_3_st_x;
2202 u32 w2_0_st_y,w2_1_st_y,w2_2_st_y,w2_3_st_y;
2204 u32 w3_0_vir_y,w3_1_vir_y,w3_2_vir_y,w3_3_vir_y;
2205 u32 w3_0_dsp_x,w3_1_dsp_x,w3_2_dsp_x,w3_3_dsp_x;
2206 u32 w3_0_dsp_y,w3_1_dsp_y,w3_2_dsp_y,w3_3_dsp_y;
2207 u32 w3_0_st_x,w3_1_st_x,w3_2_st_x,w3_3_st_x;
2208 u32 w3_0_st_y,w3_1_st_y,w3_2_st_y,w3_3_st_y;
2211 h_pw_bp = hsync_len + left_margin;
2212 v_pw_bp = vsync_len + upper_margin;
2213 dclk_freq = screen->mode.pixclock;
2214 rk3288_lcdc_reg_dump(lcdc_dev);
2216 spin_lock(&lcdc_dev->reg_lock);
2217 if (lcdc_dev->clk_on) {
2218 zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
2219 layer0_sel = zorder & m_DSP_LAYER0_SEL;
2220 layer1_sel = zorder & m_DSP_LAYER1_SEL;
2221 layer2_sel = zorder & m_DSP_LAYER2_SEL;
2222 layer3_sel = zorder & m_DSP_LAYER3_SEL;
2224 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
2225 w0_state = win_ctrl & m_WIN0_EN;
2226 fmt_id = (win_ctrl & m_WIN0_DATA_FMT)>>1;
2229 strcpy(format_w0, "ARGB888");
2232 strcpy(format_w0, "RGB888");
2235 strcpy(format_w0, "RGB565");
2238 strcpy(format_w0, "YCbCr420");
2241 strcpy(format_w0, "YCbCr422");
2244 strcpy(format_w0, "YCbCr444");
2247 strcpy(format_w0, "invalid\n");
2250 vir_info = lcdc_readl(lcdc_dev,WIN0_VIR);
2251 act_info = lcdc_readl(lcdc_dev,WIN0_ACT_INFO);
2252 dsp_info = lcdc_readl(lcdc_dev,WIN0_DSP_INFO);
2253 dsp_st = lcdc_readl(lcdc_dev,WIN0_DSP_ST);
2254 y_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
2255 uv_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_CBR);
2256 w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
2257 w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV)>>16;
2258 w0_act_x = (act_info & m_WIN0_ACT_WIDTH)+1;
2259 w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT)>>16)+1;
2260 w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH)+1;
2261 w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT)>>16)+1;
2262 w0_st_x = dsp_st & m_WIN0_DSP_XST;
2263 w0_st_y = (dsp_st & m_WIN0_DSP_YST)>>16;
2264 w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
2265 w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB)>>16;
2266 w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
2267 w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR)>>16;
2270 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
2271 w1_state = win_ctrl & m_WIN1_EN;
2272 fmt_id = (win_ctrl & m_WIN1_DATA_FMT)>>1;
2275 strcpy(format_w1, "ARGB888");
2278 strcpy(format_w1, "RGB888");
2281 strcpy(format_w1, "RGB565");
2284 strcpy(format_w1, "YCbCr420");
2287 strcpy(format_w1, "YCbCr422");
2290 strcpy(format_w1, "YCbCr444");
2293 strcpy(format_w1, "invalid\n");
2296 vir_info = lcdc_readl(lcdc_dev,WIN1_VIR);
2297 act_info = lcdc_readl(lcdc_dev,WIN1_ACT_INFO);
2298 dsp_info = lcdc_readl(lcdc_dev,WIN1_DSP_INFO);
2299 dsp_st = lcdc_readl(lcdc_dev,WIN1_DSP_ST);
2300 y_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_YRGB);
2301 uv_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_CBR);
2302 w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
2303 w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV)>>16;
2304 w1_act_x = (act_info & m_WIN1_ACT_WIDTH)+1;
2305 w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT)>>16)+1;
2306 w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH)+1;
2307 w1_dsp_y =((dsp_info & m_WIN1_DSP_HEIGHT)>>16)+1;
2308 w1_st_x = dsp_st & m_WIN1_DSP_XST;
2309 w1_st_y = (dsp_st & m_WIN1_DSP_YST)>>16;
2310 w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
2311 w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB)>>16;
2312 w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
2313 w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR)>>16;
2315 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
2316 w2_state = win_ctrl & m_WIN2_EN;
2317 w2_0_state = (win_ctrl & m_WIN2_MST0_EN)>>4;
2318 w2_1_state = (win_ctrl & m_WIN2_MST1_EN)>>5;
2319 w2_2_state = (win_ctrl & m_WIN2_MST2_EN)>>6;
2320 w2_3_state = (win_ctrl & m_WIN2_MST3_EN)>>7;
2321 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR0_1);
2322 w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
2323 w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1)>>16;
2324 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR2_3);
2325 w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
2326 w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3)>>16;
2327 fmt_id = (win_ctrl & m_WIN2_DATA_FMT)>>1;
2330 strcpy(format_w2, "ARGB888");
2333 strcpy(format_w2, "RGB888");
2336 strcpy(format_w2, "RGB565");
2339 strcpy(format_w2,"8bpp");
2342 strcpy(format_w2,"4bpp");
2345 strcpy(format_w2,"2bpp");
2348 strcpy(format_w2,"1bpp");
2351 strcpy(format_w2, "invalid\n");
2354 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO0);
2355 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST0);
2356 w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0)+1;
2357 w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0)>>16)+1;
2358 w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
2359 w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0);
2361 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO1);
2362 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST1);
2363 w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1)+1;
2364 w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1)>>16)+1;
2365 w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
2366 w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1)>>16;
2368 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO2);
2369 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST2);
2370 w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2)+1;
2371 w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2)>>16)+1;
2372 w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
2373 w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2)>>16;
2375 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO3);
2376 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST3);
2377 w2_3_dsp_x = dsp_info & m_WIN2_DSP_WIDTH3+1;
2378 w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3)>>16)+1;
2379 w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
2380 w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3)>>16;
2383 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
2384 w3_state = win_ctrl & m_WIN3_EN;
2385 w3_0_state = (win_ctrl & m_WIN3_MST0_EN)>>4;
2386 w3_1_state = (win_ctrl & m_WIN3_MST1_EN)>>5;
2387 w3_2_state = (win_ctrl & m_WIN3_MST2_EN)>>6;
2388 w3_3_state = (win_ctrl & m_WIN3_MST3_EN)>>7;
2389 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR0_1);
2390 w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
2391 w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1)>>16;
2392 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR2_3);
2393 w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
2394 w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3)>>16;
2395 fmt_id = (win_ctrl | m_WIN3_DATA_FMT)>>1;
2398 strcpy(format_w3, "ARGB888");
2401 strcpy(format_w3, "RGB888");
2404 strcpy(format_w3, "RGB565");
2407 strcpy(format_w3,"8bpp");
2410 strcpy(format_w3,"4bpp");
2413 strcpy(format_w3,"2bpp");
2416 strcpy(format_w3,"1bpp");
2419 strcpy(format_w3, "invalid");
2422 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO0);
2423 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST0);
2424 w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0)+1;
2425 w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0)>>16)+1;
2426 w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
2427 w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0)>>16;
2429 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO1);
2430 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST1);
2431 w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1)+1;
2432 w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1)>>16)+1;
2433 w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
2434 w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1)>>16;
2436 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO2);
2437 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST2);
2438 w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2)+1;
2439 w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2)>>16)+1;
2440 w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
2441 w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2)>>16;
2443 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO3);
2444 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST3);
2445 w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3)+1;
2446 w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3)>>16)+1;
2447 w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
2448 w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3)>>16;
2451 spin_unlock(&lcdc_dev->reg_lock);
2454 spin_unlock(&lcdc_dev->reg_lock);
2455 return snprintf(buf, PAGE_SIZE,
2459 " layer3_sel_win[%d]\n"
2460 " layer2_sel_win[%d]\n"
2461 " layer1_sel_win[%d]\n"
2462 " layer0_sel_win[%d]\n"
2568 layer3_sel,layer2_sel,layer1_sel,layer0_sel,
2569 w0_state,format_w0,w0_vir_y,w0_vir_uv,w0_act_x,w0_act_y,
2570 w0_dsp_x,w0_dsp_y,w0_st_x,w0_st_y,w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,
2571 w0_uv_v_fac,lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2572 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2574 w1_state,format_w1,w1_vir_y,w1_vir_uv,w1_act_x,w1_act_y,
2575 w1_dsp_x,w1_dsp_y,w1_st_x,w1_st_y,w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,
2576 w1_uv_v_fac,lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
2577 lcdc_readl(lcdc_dev, WIN1_CBR_MST),
2580 w2_0_state,w2_0_vir_y,w2_0_dsp_x,w2_0_dsp_y,
2581 w2_0_st_x,w2_0_st_y,lcdc_readl(lcdc_dev, WIN2_MST0),
2583 w2_1_state,w2_1_vir_y,w2_1_dsp_x,w2_1_dsp_y,
2584 w2_1_st_x,w2_1_st_y,lcdc_readl(lcdc_dev, WIN2_MST1),
2586 w2_2_state,w2_2_vir_y,w2_2_dsp_x,w2_2_dsp_y,
2587 w2_2_st_x,w2_2_st_y,lcdc_readl(lcdc_dev, WIN2_MST2),
2589 w2_3_state,w2_3_vir_y,w2_3_dsp_x,w2_3_dsp_y,
2590 w2_3_st_x,w2_3_st_y,lcdc_readl(lcdc_dev, WIN2_MST3),
2593 w3_0_state,w3_0_vir_y,w3_0_dsp_x,w3_0_dsp_y,
2594 w3_0_st_x,w3_0_st_y,lcdc_readl(lcdc_dev, WIN3_MST0),
2596 w3_1_state,w3_1_vir_y,w3_1_dsp_x,w3_1_dsp_y,
2597 w3_1_st_x,w3_1_st_y,lcdc_readl(lcdc_dev, WIN3_MST1),
2599 w3_2_state,w3_2_vir_y,w3_2_dsp_x,w3_2_dsp_y,
2600 w3_2_st_x,w3_2_st_y,lcdc_readl(lcdc_dev, WIN3_MST2),
2602 w3_3_state,w3_3_vir_y,w3_3_dsp_x,w3_3_dsp_y,
2603 w3_3_st_x,w3_3_st_y,lcdc_readl(lcdc_dev, WIN3_MST3)
2608 static int rk3288_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2611 struct lcdc_device *lcdc_dev =
2612 container_of(dev_drv, struct lcdc_device, driver);
2613 struct rk_screen *screen = dev_drv->cur_screen;
2618 u32 x_total, y_total;
2620 ft = div_u64(1000000000000llu, fps);
2622 screen->mode.upper_margin + screen->mode.lower_margin +
2623 screen->mode.yres + screen->mode.vsync_len;
2625 screen->mode.left_margin + screen->mode.right_margin +
2626 screen->mode.xres + screen->mode.hsync_len;
2627 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2628 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2629 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2632 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2633 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2634 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2635 screen->ft = 1000 / fps; /*one frame time in ms */
2638 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2639 clk_get_rate(lcdc_dev->dclk), fps);
2644 static int rk3288_fb_win_remap(struct rk_lcdc_driver *dev_drv,
2645 enum fb_win_map_order order)
2647 mutex_lock(&dev_drv->fb_win_id_mutex);
2648 if (order == FB_DEFAULT_ORDER)
2649 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3;
2650 dev_drv->fb3_win_id = order / 1000;
2651 dev_drv->fb2_win_id = (order / 100) % 10;
2652 dev_drv->fb1_win_id = (order / 10) % 10;
2653 dev_drv->fb0_win_id = order % 10;
2654 mutex_unlock(&dev_drv->fb_win_id_mutex);
2659 static int rk3288_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
2663 mutex_lock(&dev_drv->fb_win_id_mutex);
2664 if (!strcmp(id, "fb0") || !strcmp(id, "fb4"))
2665 win_id = dev_drv->fb0_win_id;
2666 else if (!strcmp(id, "fb1") || !strcmp(id, "fb5"))
2667 win_id = dev_drv->fb1_win_id;
2668 else if (!strcmp(id, "fb2") || !strcmp(id, "fb6"))
2669 win_id = dev_drv->fb2_win_id;
2670 else if (!strcmp(id, "fb3") || !strcmp(id, "fb7"))
2671 win_id = dev_drv->fb3_win_id;
2672 mutex_unlock(&dev_drv->fb_win_id_mutex);
2677 static int rk3288_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
2684 struct lcdc_device *lcdc_dev =
2685 container_of(dev_drv, struct lcdc_device, driver);
2686 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
2687 lcdc_cfg_done(lcdc_dev);
2689 if (dev_drv->cur_screen->dsp_lut) {
2690 for (i = 0; i < 256; i++) {
2691 v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
2692 c = lcdc_dev->dsp_lut_addr_base + i;
2693 writel_relaxed(v, c);
2697 dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
2700 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
2701 lcdc_cfg_done(lcdc_dev);
2706 static int rk3288_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2708 struct lcdc_device *lcdc_dev =
2709 container_of(dev_drv, struct lcdc_device, driver);
2710 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2711 v_DIRECT_PATH_EN(open));
2712 lcdc_cfg_done(lcdc_dev);
2716 static int rk3288_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2718 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2719 struct lcdc_device, driver);
2720 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
2721 v_DIRECT_PATCH_SEL(win_id));
2722 lcdc_cfg_done(lcdc_dev);
2727 static int rk3288_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2729 struct lcdc_device *lcdc_dev =
2730 container_of(dev_drv, struct lcdc_device, driver);
2731 int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2735 int rk3288_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2737 struct lcdc_device *lcdc_dev =
2738 container_of(dev_drv, struct lcdc_device, driver);
2742 if (lcdc_dev->clk_on) {
2743 int_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
2744 if (int_reg & m_LINE_FLAG_INTR_STS) {
2745 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
2746 v_LINE_FLAG_INTR_CLR(1));
2747 ret = RK_LF_STATUS_FC;
2749 ret = RK_LF_STATUS_FR;
2751 ret = RK_LF_STATUS_NC;
2756 static int rk3288_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
2758 struct lcdc_device *lcdc_dev =
2759 container_of(dev_drv, struct lcdc_device, driver);
2761 if(lcdc_dev->clk_on){
2762 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2763 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
2764 dsp_addr[2] = lcdc_readl(lcdc_dev, WIN2_MST0);
2765 dsp_addr[3] = lcdc_readl(lcdc_dev, WIN3_MST0);
2770 static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,int mode)
2772 struct lcdc_device *lcdc_dev =
2773 container_of(dev_drv, struct lcdc_device, driver);
2774 struct rk_screen *screen = dev_drv->cur_screen;
2775 int total_pixel,calc_pixel,stage_up,stage_down;
2778 u32 cabc_mode[5][3]={
2780 {2, 10, 10}, /*mode 1*/
2781 {4, 10, 10}, /*mode 2*/
2782 {6, 10, 10}, /*mode 3*/
2783 {8, 10, 10}, /*mode 4*/
2784 {10, 10, 10}, /*mode 5*/
2786 /*iomux connect to vop or pwm*/
2788 DBG(3,"close cabc\n");
2791 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
2794 total_pixel = screen->mode.xres * screen->mode.yres;
2795 calc_pixel = total_pixel * (100 - cabc_mode[mode-1][0])/100;
2796 stage_up = cabc_mode[mode-1][1];
2797 stage_down = cabc_mode[mode-1][2];
2799 spin_lock(&lcdc_dev->reg_lock);
2800 if(lcdc_dev->clk_on){
2801 mask = m_CABC_TOTAL_NUM | m_CABC_STAGE_DOWN;
2802 val = v_CABC_TOTAL_NUM(total_pixel) | v_CABC_STAGE_DOWN(stage_down);
2803 lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
2805 mask = m_CABC_EN | m_CABC_CALC_PIXEL_NUM |
2807 val = v_CABC_EN(1) | v_CABC_CALC_PIXEL_NUM(calc_pixel) |
2808 v_CABC_STAGE_UP(stage_up);
2809 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
2810 lcdc_cfg_done(lcdc_dev);
2812 spin_unlock(&lcdc_dev->reg_lock);
2816 Sin0=*0.000???????? Cos0=*1.000
2817 Sin5=*0.087???????C Cos5=*0.996
2818 Sin10=*0.174 Cos10=*0.985
2819 Sin15=*0.259 ???????CCos15=*0.966
2820 Sin20=*0.342????????Cos20=*0.940
2821 Sin25=*0.422????????Cos25=*0.906
2822 Sin30=*0.500????????Cos30=*0.866
2824 static int rk3288_lcdc_set_hue(struct rk_lcdc_driver *dev_drv,int hue)
2827 struct lcdc_device *lcdc_dev =
2828 container_of(dev_drv, struct lcdc_device, driver);
2829 int sin_hue_val,cos_hue_val;
2832 int sin_hue[7]={0,22, 44, 66, 87, 108, 128};
2833 int cos_hue[7]={256,254,252,247,240,231,221};
2835 if((hue > 0)&&(hue <= 30)){
2836 /*sin_hue_val = (int)sin_hue[hue] * 256;
2837 cos_hue_val = (int)cos_hue[hue] * 256;*/
2839 sin_hue_val = sin_hue[hue];
2840 cos_hue_val = cos_hue[hue];
2841 }else if((hue > 30)&&(hue <= 60)){
2844 /*sin_hue_val = (int)sin_hue[hue] * 256 + 0x100;
2845 cos_hue_val = (int)cos_hue[hue] * 256 + 0x100;*/
2846 sin_hue_val = sin_hue[hue] + 0x100;
2847 cos_hue_val = cos_hue[hue] + 0x100;
2849 dev_warn(lcdc_dev->dev,"hue=%d should be [0:60]\n",hue);
2852 spin_lock(&lcdc_dev->reg_lock);
2853 if(lcdc_dev->clk_on){
2855 mask = m_BCSH_OUT_MODE;
2856 val = v_BCSH_OUT_MODE(3);
2857 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2859 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
2860 val = v_BCSH_SIN_HUE(sin_hue_val) | v_BCSH_COS_HUE(cos_hue_val);
2861 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
2865 lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
2866 lcdc_cfg_done(lcdc_dev);
2868 spin_unlock(&lcdc_dev->reg_lock);
2873 static int rk3288_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,int bri,int con,int sat)
2875 struct lcdc_device *lcdc_dev =
2876 container_of(dev_drv, struct lcdc_device, driver);
2879 spin_lock(&lcdc_dev->reg_lock);
2880 if(lcdc_dev->clk_on){
2881 mask = m_BCSH_OUT_MODE | m_BCSH_BRIGHTNESS |
2882 m_BCSH_CONTRAST | m_BCSH_SAT_CON;
2883 val = v_BCSH_OUT_MODE(3) | v_BCSH_BRIGHTNESS(bri) |
2884 v_BCSH_CONTRAST(con) | v_BCSH_SAT_CON(sat);
2885 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2889 lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
2890 lcdc_cfg_done(lcdc_dev);
2892 spin_unlock(&lcdc_dev->reg_lock);
2897 static struct rk_lcdc_win lcdc_win[] = {
2901 .support_3d = false,
2906 .support_3d = false,
2911 .support_3d = false,
2916 .support_3d = false,
2920 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2921 .open = rk3288_lcdc_open,
2922 .load_screen = rk3288_load_screen,
2923 .set_par = rk3288_lcdc_set_par,
2924 .pan_display = rk3288_lcdc_pan_display,
2925 .lcdc_reg_update = rk3288_lcdc_reg_update,
2926 .blank = rk3288_lcdc_blank,
2927 .ioctl = rk3288_lcdc_ioctl,
2928 .suspend = rk3288_lcdc_early_suspend,
2929 .resume = rk3288_lcdc_early_resume,
2930 .get_win_state = rk3288_lcdc_get_win_state,
2931 .ovl_mgr = rk3288_lcdc_ovl_mgr,
2932 .get_disp_info = rk3288_lcdc_get_disp_info,
2933 .fps_mgr = rk3288_lcdc_fps_mgr,
2934 .fb_get_win_id = rk3288_lcdc_get_win_id,
2935 .fb_win_remap = rk3288_fb_win_remap,
2936 .set_dsp_lut = rk3288_set_dsp_lut,
2937 .poll_vblank = rk3288_lcdc_poll_vblank,
2938 .dpi_open = rk3288_lcdc_dpi_open,
2939 .dpi_win_sel = rk3288_lcdc_dpi_win_sel,
2940 .dpi_status = rk3288_lcdc_dpi_status,
2941 .get_dsp_addr = rk3288_lcdc_get_dsp_addr,
2942 .set_dsp_cabc = rk3288_lcdc_set_dsp_cabc,
2943 .set_dsp_hue = rk3288_lcdc_set_hue,
2944 .set_dsp_bcsh_bcs = rk3288_lcdc_set_bcsh_bcs,
2946 static int rk3288_lcdc_parse_irq(struct lcdc_device *lcdc_dev,unsigned int reg_val)
2948 if (reg_val & m_WIN0_EMPTY_INTR_STS) {
2949 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN0_EMPTY_INTR_CLR,
2950 v_WIN0_EMPTY_INTR_CLR(1));
2951 dev_warn(lcdc_dev->dev,"win0 empty irq!");
2952 }else if (reg_val & m_WIN1_EMPTY_INTR_STS) {
2953 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN1_EMPTY_INTR_CLR,
2954 v_WIN1_EMPTY_INTR_CLR(1));
2955 dev_warn(lcdc_dev->dev,"win1 empty irq!");
2956 }else if (reg_val & m_WIN2_EMPTY_INTR_STS) {
2957 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN2_EMPTY_INTR_CLR,
2958 v_WIN2_EMPTY_INTR_CLR(1));
2959 dev_warn(lcdc_dev->dev,"win2 empty irq!");
2960 }else if (reg_val & m_WIN3_EMPTY_INTR_STS) {
2961 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN3_EMPTY_INTR_CLR,
2962 v_WIN3_EMPTY_INTR_CLR(1));
2963 dev_warn(lcdc_dev->dev,"win3 empty irq!");
2964 }else if (reg_val & m_HWC_EMPTY_INTR_STS) {
2965 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_HWC_EMPTY_INTR_CLR,
2966 v_HWC_EMPTY_INTR_CLR(1));
2967 dev_warn(lcdc_dev->dev,"HWC empty irq!");
2968 }else if (reg_val & m_POST_BUF_EMPTY_INTR_STS) {
2969 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_POST_BUF_EMPTY_INTR_CLR,
2970 v_POST_BUF_EMPTY_INTR_CLR(1));
2971 dev_warn(lcdc_dev->dev,"post buf empty irq!");
2972 }else if (reg_val & m_PWM_GEN_INTR_STS) {
2973 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_PWM_GEN_INTR_CLR,
2974 v_PWM_GEN_INTR_CLR(1));
2975 dev_warn(lcdc_dev->dev,"PWM gen irq!");
2980 static irqreturn_t rk3288_lcdc_isr(int irq, void *dev_id)
2982 struct lcdc_device *lcdc_dev =
2983 (struct lcdc_device *)dev_id;
2984 ktime_t timestamp = ktime_get();
2986 intr0_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
2988 if(intr0_reg & m_FS_INTR_STS){
2989 timestamp = ktime_get();
2990 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_FS_INTR_CLR,
2992 if(lcdc_dev->driver.wait_fs){
2993 spin_lock(&(lcdc_dev->driver.cpl_lock));
2994 complete(&(lcdc_dev->driver.frame_done));
2995 spin_unlock(&(lcdc_dev->driver.cpl_lock));
2997 lcdc_dev->driver.vsync_info.timestamp = timestamp;
2998 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
3000 }else if(intr0_reg & m_LINE_FLAG_INTR_STS){
3001 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
3002 v_LINE_FLAG_INTR_CLR(1));
3003 }else if(intr0_reg & m_BUS_ERROR_INTR_STS){
3004 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_BUS_ERROR_INTR_CLR,
3005 v_BUS_ERROR_INTR_CLR(1));
3006 dev_warn(lcdc_dev->dev,"buf_error_int!");
3011 intr1_reg = lcdc_readl(lcdc_dev, INTR_CTRL1);
3013 rk3288_lcdc_parse_irq(intr1_reg);
3019 #if defined(CONFIG_PM)
3020 static int rk3288_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
3025 static int rk3288_lcdc_resume(struct platform_device *pdev)
3030 #define rk3288_lcdc_suspend NULL
3031 #define rk3288_lcdc_resume NULL
3034 static int rk3288_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
3036 struct device_node *np = lcdc_dev->dev->of_node;
3038 if (of_property_read_u32(np, "rockchip,prop", &val))
3039 lcdc_dev->prop = PRMRY; /*default set it as primary */
3041 lcdc_dev->prop = val;
3043 if (of_property_read_u32(np, "rockchip,pwr18", &val))
3044 lcdc_dev->pwr18 = false; /*default set it as 3.xv power supply */
3046 lcdc_dev->pwr18 = (val ? true : false);
3050 static int rk3288_lcdc_probe(struct platform_device *pdev)
3052 struct lcdc_device *lcdc_dev = NULL;
3053 struct rk_lcdc_driver *dev_drv;
3054 struct device *dev = &pdev->dev;
3055 struct resource *res;
3056 struct device_node *np = pdev->dev.of_node;
3060 /*if the primary lcdc has not registered ,the extend
3061 lcdc register later */
3062 of_property_read_u32(np, "rockchip,prop", &prop);
3063 if (prop == EXTEND) {
3064 if (!is_prmry_rk_lcdc_registered())
3065 return -EPROBE_DEFER;
3067 lcdc_dev = devm_kzalloc(dev,
3068 sizeof(struct lcdc_device), GFP_KERNEL);
3070 dev_err(&pdev->dev, "rk3288 lcdc device kmalloc fail!");
3073 platform_set_drvdata(pdev, lcdc_dev);
3074 lcdc_dev->dev = dev;
3075 rk3288_lcdc_parse_dt(lcdc_dev);
3076 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3077 lcdc_dev->reg_phy_base = res->start;
3078 lcdc_dev->len = resource_size(res);
3079 lcdc_dev->regs = devm_ioremap_resource(dev, res);
3080 if (IS_ERR(lcdc_dev->regs))
3081 return PTR_ERR(lcdc_dev->regs);
3083 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
3084 if (IS_ERR(lcdc_dev->regsbak))
3085 return PTR_ERR(lcdc_dev->regsbak);
3086 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
3087 lcdc_dev->id = rk3288_lcdc_get_id(lcdc_dev->reg_phy_base);
3088 if (lcdc_dev->id < 0) {
3089 dev_err(&pdev->dev, "no such lcdc device!\n");
3092 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
3093 dev_drv = &lcdc_dev->driver;
3095 dev_drv->prop = prop;
3096 dev_drv->id = lcdc_dev->id;
3097 dev_drv->ops = &lcdc_drv_ops;
3098 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
3099 spin_lock_init(&lcdc_dev->reg_lock);
3101 lcdc_dev->irq = platform_get_irq(pdev, 0);
3102 if (lcdc_dev->irq < 0) {
3103 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
3108 ret = devm_request_irq(dev, lcdc_dev->irq, rk3288_lcdc_isr,
3109 IRQF_DISABLED, dev_name(dev), lcdc_dev);
3111 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
3112 lcdc_dev->irq, ret);
3116 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
3118 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
3121 lcdc_dev->screen = dev_drv->screen0;
3123 dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
3128 static int rk3288_lcdc_remove(struct platform_device *pdev)
3134 static void rk3288_lcdc_shutdown(struct platform_device *pdev)
3136 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
3138 rk3288_lcdc_deint(lcdc_dev);
3139 rk_disp_pwr_disable(&lcdc_dev->driver);
3142 #if defined(CONFIG_OF)
3143 static const struct of_device_id rk3288_lcdc_dt_ids[] = {
3144 {.compatible = "rockchip,rk3288-lcdc",},
3149 static struct platform_driver rk3288_lcdc_driver = {
3150 .probe = rk3288_lcdc_probe,
3151 .remove = rk3288_lcdc_remove,
3153 .name = "rk3288-lcdc",
3154 .owner = THIS_MODULE,
3155 .of_match_table = of_match_ptr(rk3288_lcdc_dt_ids),
3157 .suspend = rk3288_lcdc_suspend,
3158 .resume = rk3288_lcdc_resume,
3159 .shutdown = rk3288_lcdc_shutdown,
3162 static int __init rk3288_lcdc_module_init(void)
3164 return platform_driver_register(&rk3288_lcdc_driver);
3167 static void __exit rk3288_lcdc_module_exit(void)
3169 platform_driver_unregister(&rk3288_lcdc_driver);
3172 fs_initcall(rk3288_lcdc_module_init);
3173 module_exit(rk3288_lcdc_module_exit);