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 int rk3288_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
186 struct lcdc_device *lcdc_dev = container_of(dev_drv,
189 int *cbase = (int *)lcdc_dev->regs;
190 int *regsbak = (int *)lcdc_dev->regsbak;
193 printk("back up reg:\n");
194 for (i = 0; i <= (0x200 >> 4); i++) {
195 printk("0x%04x: ",i*16);
196 for (j = 0; j < 4; j++)
197 printk("%08x ", *(regsbak + i * 4 + j));
201 printk("lcdc reg:\n");
202 for (i = 0; i <= (0x200 >> 4); i++) {
203 printk("0x%04x: ",i*16);
204 for (j = 0; j < 4; j++)
205 printk("%08x ", readl_relaxed(cbase + i * 4 + j));
212 /********do basic init*********/
213 static int rk3288_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
216 struct lcdc_device *lcdc_dev = container_of(dev_drv,
220 int *cbase = (int *)lcdc_dev->regs;
221 if (lcdc_dev->pre_init)
224 if (lcdc_dev->id == 0) {
225 /*lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");*/
226 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc0");
227 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc0");
228 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc0");
229 } else if (lcdc_dev->id == 1) {
230 /*lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");*/
231 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc1");
232 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc1");
233 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc1");
235 dev_err(lcdc_dev->dev, "invalid lcdc device!\n");
238 if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
239 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
240 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
244 /*uboot display has enabled lcdc in boot */
245 if (!support_uboot_display()) {
246 rk_disp_pwr_enable(dev_drv);
247 rk3288_lcdc_clk_enable(lcdc_dev);
249 lcdc_dev->clk_on = 1;
252 /*rk3288_lcdc_read_reg_defalut_cfg(lcdc_dev);*/
253 /*rk3288_lcdc_reg_dump(dev_drv);*/
254 for (i = 0; i <= (0x200 >> 4); i++) {
255 for (j = 0; j < 4; j++)
256 readl_relaxed(cbase + i * 4 + j);
259 #ifndef CONFIG_RK_FPGA
260 if (lcdc_dev->pwr18 == true) {
261 v = 0x00010001; /*bit14: 1,1.8v;0,3.3v*/
262 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
265 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
268 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN);
269 lcdc_cfg_done(lcdc_dev);
270 lcdc_dev->pre_init = true;
275 static void rk3288_lcdc_deint(struct lcdc_device *lcdc_dev)
279 rk3288_lcdc_disable_irq(lcdc_dev);
280 spin_lock(&lcdc_dev->reg_lock);
281 if (likely(lcdc_dev->clk_on)) {
282 lcdc_dev->clk_on = 0;
283 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_STANDBY_EN);
284 lcdc_cfg_done(lcdc_dev);
285 spin_unlock(&lcdc_dev->reg_lock);
287 spin_unlock(&lcdc_dev->reg_lock);
291 static int rk3288_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv)
293 struct lcdc_device *lcdc_dev =
294 container_of(dev_drv, struct lcdc_device, driver);
295 struct rk_screen *screen = dev_drv->cur_screen;
296 u16 x_res = screen->mode.xres;
297 u16 y_res = screen->mode.yres;
300 u16 post_hsd_en,post_vsd_en;
301 u16 post_dsp_hact_st,post_dsp_hact_end;
302 u16 post_dsp_vact_st,post_dsp_vact_end;
303 u16 post_dsp_vact_st_f1,post_dsp_vact_end_f1;
304 u16 post_h_fac,post_v_fac;
306 h_total = screen->mode.hsync_len+screen->mode.left_margin +
307 x_res + screen->mode.right_margin;
308 v_total = screen->mode.vsync_len+screen->mode.upper_margin +
309 y_res + screen->mode.lower_margin;
311 if(screen->post_dsp_stx + screen->post_xsize > x_res){
312 dev_warn(lcdc_dev->dev, "post:stx[%d] + xsize[%d] > x_res[%d]\n",
313 screen->post_dsp_stx,screen->post_xsize,x_res);
314 screen->post_dsp_stx = x_res - screen->post_xsize;
316 if(screen->x_mirror == 0){
317 post_dsp_hact_st=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 post_dsp_hact_st = h_total - screen->post_dsp_stx -
322 screen->mode.hsync_len-screen->mode.left_margin;
323 post_dsp_hact_end = post_dsp_hact_st - screen->post_xsize;
325 if((screen->post_xsize < x_res)&&(screen->post_xsize != 0)){
328 GET_SCALE_FACTOR_BILI_DN(x_res , screen->post_xsize);
335 if(screen->post_dsp_sty + screen->post_ysize > y_res){
336 dev_warn(lcdc_dev->dev, "post:sty[%d] + ysize[%d] > y_res[%d]\n",
337 screen->post_dsp_sty,screen->post_ysize,y_res);
338 screen->post_dsp_sty = y_res - screen->post_ysize;
341 if(screen->y_mirror == 0){
342 post_dsp_vact_st = 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 post_dsp_vact_st = v_total - screen->post_dsp_sty -
347 screen->mode.vsync_len-screen->mode.upper_margin;
348 post_dsp_vact_end = post_dsp_vact_st - screen->post_ysize;
350 if((screen->post_ysize < y_res)&&(screen->post_ysize != 0)){
352 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res, screen->post_ysize);
358 if(screen->interlace == 1){
359 post_dsp_vact_st_f1 = v_total + post_dsp_vact_st;
360 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 + screen->post_ysize;
362 post_dsp_vact_st_f1 = 0;
363 post_dsp_vact_end_f1 = 0;
365 DBG(1,"post:xsize=%d,ysize=%d,xpos=%d,ypos=%d,"
366 "hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
367 screen->post_xsize,screen->post_ysize,screen->xpos,screen->ypos,
368 post_hsd_en,post_h_fac,post_vsd_en,post_v_fac);
369 mask = m_DSP_HACT_END_POST | m_DSP_HACT_ST_POST;
370 val = v_DSP_HACT_END_POST(post_dsp_hact_end) |
371 v_DSP_HACT_ST_POST(post_dsp_hact_st);
372 lcdc_msk_reg(lcdc_dev, POST_DSP_HACT_INFO, mask, val);
374 mask = m_DSP_VACT_END_POST | m_DSP_VACT_ST_POST;
375 val = v_DSP_VACT_END_POST(post_dsp_vact_end) |
376 v_DSP_VACT_ST_POST(post_dsp_vact_st);
377 lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO, mask, val);
379 mask = m_POST_HS_FACTOR_YRGB | m_POST_VS_FACTOR_YRGB;
380 val = v_POST_HS_FACTOR_YRGB(post_h_fac) |
381 v_POST_VS_FACTOR_YRGB(post_v_fac);
382 lcdc_msk_reg(lcdc_dev, POST_SCL_FACTOR_YRGB, mask, val);
384 mask = m_DSP_VACT_END_POST_F1 | m_DSP_VACT_ST_POST_F1;
385 val = v_DSP_VACT_END_POST_F1(post_dsp_vact_end_f1) |
386 v_DSP_VACT_ST_POST_F1(post_dsp_vact_st_f1);
387 lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO_F1, mask, val);
389 mask = m_POST_HOR_SD_EN | m_POST_VER_SD_EN;
390 val = v_POST_HOR_SD_EN(post_hsd_en) | v_POST_VER_SD_EN(post_vsd_en);
391 lcdc_msk_reg(lcdc_dev, POST_SCL_CTRL, mask, val);
395 static int rk3288_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
397 struct lcdc_device *lcdc_dev = container_of(dev_drv,
401 struct rk_lcdc_win *win;
402 u32 colorkey_r,colorkey_g,colorkey_b;
405 win = dev_drv->win[i];
406 key_val = win->color_key_val;
407 colorkey_r = (key_val & 0xff)<<2;
408 colorkey_g = ((key_val>>8)&0xff)<<12;
409 colorkey_b = ((key_val>>16)&0xff)<<22;
410 /*color key dither 565/888->aaa*/
411 key_val = colorkey_r | colorkey_g | colorkey_b;
414 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY, key_val);
417 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY, key_val);
420 lcdc_writel(lcdc_dev, WIN2_COLOR_KEY, key_val);
423 lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val);
432 static int rk3288_lcdc_alpha_cfg(struct rk_lcdc_driver *dev_drv,int win_id)
434 struct lcdc_device *lcdc_dev =
435 container_of(dev_drv, struct lcdc_device, driver);
436 struct rk_lcdc_win *win = dev_drv->win[win_id];
437 struct alpha_config alpha_config;
440 int ppixel_alpha,global_alpha;
441 u32 src_alpha_ctl,dst_alpha_ctl;
442 ppixel_alpha = ((win->format == ARGB888)||(win->format == ABGR888)) ? 1 : 0;
443 global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
444 alpha_config.src_global_alpha_val = win->g_alpha_val;
445 switch(win->alpha_mode){
449 alpha_config.src_factor_mode=AA_ZERO;
450 alpha_config.dst_factor_mode=AA_ZERO;
453 alpha_config.src_factor_mode=AA_ONE;
454 alpha_config.dst_factor_mode=AA_ZERO;
457 alpha_config.src_factor_mode=AA_ZERO;
458 alpha_config.dst_factor_mode=AA_ONE;
461 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
462 alpha_config.src_factor_mode=AA_ONE;
463 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
466 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
467 alpha_config.src_factor_mode=AA_SRC_INVERSE;
468 alpha_config.dst_factor_mode=AA_ONE;
471 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
472 alpha_config.src_factor_mode=AA_SRC;
473 alpha_config.dst_factor_mode=AA_ZERO;
476 alpha_config.src_factor_mode=AA_ZERO;
477 alpha_config.dst_factor_mode=AA_SRC;
480 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
481 alpha_config.src_factor_mode=AA_SRC_INVERSE;
482 alpha_config.dst_factor_mode=AA_ZERO;
485 alpha_config.src_factor_mode=AA_ZERO;
486 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
489 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
490 alpha_config.src_factor_mode=AA_SRC;
491 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
494 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
495 alpha_config.src_factor_mode=AA_SRC_INVERSE;
496 alpha_config.dst_factor_mode=AA_SRC;
499 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
500 alpha_config.src_factor_mode=AA_SRC_INVERSE;
501 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
503 case AB_SRC_OVER_GLOBAL:
504 alpha_config.src_global_alpha_mode=AA_PER_PIX_GLOBAL;
505 alpha_config.src_color_mode=AA_SRC_NO_PRE_MUL;
506 alpha_config.src_factor_mode=AA_SRC_GLOBAL;
507 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
510 pr_err("alpha mode error\n");
513 if((ppixel_alpha == 1)&&(global_alpha == 1)){
514 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
515 }else if(ppixel_alpha == 1){
516 alpha_config.src_global_alpha_mode = AA_PER_PIX;
517 }else if(global_alpha == 1){
518 alpha_config.src_global_alpha_mode = AA_GLOBAL;
520 dev_warn(lcdc_dev->dev,"alpha_en should be 0\n");
522 alpha_config.src_alpha_mode = AA_STRAIGHT;
523 alpha_config.src_alpha_sel = AA_NO_SAT;
527 src_alpha_ctl = 0x60;
528 dst_alpha_ctl = 0x64;
531 src_alpha_ctl = 0xa0;
532 dst_alpha_ctl = 0xa4;
535 src_alpha_ctl = 0xdc;
536 dst_alpha_ctl = 0xec;
539 src_alpha_ctl = 0x12c;
540 dst_alpha_ctl = 0x13c;
543 mask = m_WIN0_DST_FACTOR_M0;
544 val = v_WIN0_DST_FACTOR_M0(alpha_config.dst_factor_mode);
545 lcdc_msk_reg(lcdc_dev, dst_alpha_ctl, mask, val);
546 mask = m_WIN0_SRC_ALPHA_EN | m_WIN0_SRC_COLOR_M0 |
547 m_WIN0_SRC_ALPHA_M0 | m_WIN0_SRC_BLEND_M0 |
548 m_WIN0_SRC_ALPHA_CAL_M0 | m_WIN0_SRC_FACTOR_M0|
549 m_WIN0_SRC_GLOBAL_ALPHA;
550 val = v_WIN0_SRC_ALPHA_EN(1) |
551 v_WIN0_SRC_COLOR_M0(alpha_config.src_color_mode) |
552 v_WIN0_SRC_ALPHA_M0(alpha_config.src_alpha_mode) |
553 v_WIN0_SRC_BLEND_M0(alpha_config.src_global_alpha_mode) |
554 v_WIN0_SRC_FACTOR_M0(alpha_config.src_factor_mode) |
555 v_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
556 lcdc_msk_reg(lcdc_dev, src_alpha_ctl, mask, val);
561 static int rk3288_win_full_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
563 struct lcdc_device *lcdc_dev =
564 container_of(dev_drv, struct lcdc_device, driver);
565 struct rk_lcdc_win *win = dev_drv->win[win_id];
566 unsigned int mask, val, off;
570 mask = m_WIN0_EN | m_WIN0_DATA_FMT | m_WIN0_FMT_10 |
571 m_WIN0_LB_MODE | m_WIN0_RB_SWAP;
572 val = v_WIN0_EN(win->state) | v_WIN0_DATA_FMT(win->fmt_cfg) |
573 v_WIN0_FMT_10(win->fmt_10) |
574 v_WIN0_LB_MODE(win->win_lb_mode) |
575 v_WIN0_RB_SWAP(win->swap_rb);
576 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val);
578 mask = m_WIN0_BIC_COE_SEL |
579 m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
580 m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT4 |
581 m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
582 m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
583 m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
584 m_WIN0_CBR_VER_SCL_MODE | m_WIN0_CBR_HSD_MODE |
585 m_WIN0_CBR_VSU_MODE | m_WIN0_CBR_VSD_MODE;
586 val = v_WIN0_BIC_COE_SEL(win->bic_coe_el) |
587 v_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
588 v_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
589 v_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
590 v_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
591 v_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
592 v_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
593 v_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
594 v_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
595 v_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
596 v_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
597 v_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
598 v_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
599 v_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
600 v_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
601 lcdc_msk_reg(lcdc_dev, WIN0_CTRL1+off, mask,val);
603 val = v_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
604 v_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
605 lcdc_writel(lcdc_dev, WIN0_VIR+off, val);
606 lcdc_writel(lcdc_dev, WIN0_YRGB_MST+off, win->area[0].y_addr);
607 lcdc_writel(lcdc_dev, WIN0_CBR_MST+off, win->area[0].uv_addr);
608 val = v_WIN0_ACT_WIDTH(win->area[0].xact) |
609 v_WIN0_ACT_HEIGHT(win->area[0].yact);
610 lcdc_writel(lcdc_dev, WIN0_ACT_INFO+off, val);
612 val = v_WIN0_DSP_WIDTH(win->area[0].xsize) |
613 v_WIN0_DSP_HEIGHT(win->area[0].ysize);
614 lcdc_writel(lcdc_dev, WIN0_DSP_INFO+off, val);
616 val = v_WIN0_DSP_XST(win->area[0].dsp_stx) |
617 v_WIN0_DSP_YST(win->area[0].dsp_sty);
618 lcdc_writel(lcdc_dev, WIN0_DSP_ST+off, val);
620 val = v_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
621 v_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
622 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB+off, val);
624 val = v_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
625 v_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
626 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR+off, val);
627 if(win->alpha_en == 1)
628 rk3288_lcdc_alpha_cfg(dev_drv,win_id);
630 mask = m_WIN0_SRC_ALPHA_EN;
631 val = v_WIN0_SRC_ALPHA_EN(0);
632 lcdc_msk_reg(lcdc_dev,WIN0_SRC_ALPHA_CTRL+off,mask,val);
637 val = v_WIN0_EN(win->state);
638 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val);
643 static int rk3288_win_lite_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
645 struct lcdc_device *lcdc_dev =
646 container_of(dev_drv, struct lcdc_device, driver);
647 struct rk_lcdc_win *win = dev_drv->win[win_id];
648 unsigned int mask, val, off;
649 off = (win_id-2) * 0x50;
652 mask = m_WIN2_EN | m_WIN2_DATA_FMT | m_WIN2_RB_SWAP;
653 val = v_WIN2_EN(1) | v_WIN2_DATA_FMT(win->fmt_cfg) |
654 v_WIN2_RB_SWAP(win->swap_rb);
655 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
657 if(win->area[0].state == 1){
658 mask = m_WIN2_MST0_EN;
659 val = v_WIN2_MST0_EN(1);
660 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
662 mask = m_WIN2_VIR_STRIDE0;
663 val = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
664 lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
666 lcdc_writel(lcdc_dev,WIN2_MST0+off,win->area[0].y_addr);
667 val = v_WIN2_DSP_WIDTH0(win->area[0].xsize) |
668 v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
669 lcdc_writel(lcdc_dev,WIN2_DSP_INFO0+off,val);
670 val = v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
671 v_WIN2_DSP_YST0(win->area[0].dsp_sty);
672 lcdc_writel(lcdc_dev,WIN2_DSP_ST0+off,val);
674 mask = m_WIN2_MST0_EN;
675 val = v_WIN2_MST0_EN(0);
676 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
679 if(win->area[1].state == 1){
680 mask = m_WIN2_MST1_EN;
681 val = v_WIN2_MST1_EN(1);
682 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
684 mask = m_WIN2_VIR_STRIDE1;
685 val = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
686 lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
688 lcdc_writel(lcdc_dev,WIN2_MST1+off,win->area[1].y_addr);
689 val = v_WIN2_DSP_WIDTH1(win->area[1].xsize) |
690 v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
691 lcdc_writel(lcdc_dev,WIN2_DSP_INFO1+off,val);
692 val = v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
693 v_WIN2_DSP_YST1(win->area[1].dsp_sty);
694 lcdc_writel(lcdc_dev,WIN2_DSP_ST1+off,val);
696 mask = m_WIN2_MST1_EN;
697 val = v_WIN2_MST1_EN(0);
698 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
701 if(win->area[2].state == 1){
702 mask = m_WIN2_MST2_EN;
703 val = v_WIN2_MST2_EN(1);
704 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
706 mask = m_WIN2_VIR_STRIDE2;
707 val = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
708 lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
710 lcdc_writel(lcdc_dev,WIN2_MST2+off,win->area[2].y_addr);
711 val = v_WIN2_DSP_WIDTH2(win->area[2].xsize) |
712 v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
713 lcdc_writel(lcdc_dev,WIN2_DSP_INFO2+off,val);
714 val = v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
715 v_WIN2_DSP_YST2(win->area[2].dsp_sty);
716 lcdc_writel(lcdc_dev,WIN2_DSP_ST2+off,val);
718 mask = m_WIN2_MST2_EN;
719 val = v_WIN2_MST2_EN(0);
720 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
723 if(win->area[3].state == 1){
724 mask = m_WIN2_MST3_EN;
725 val = v_WIN2_MST3_EN(1);
726 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
728 mask = m_WIN2_VIR_STRIDE3;
729 val = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
730 lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
732 lcdc_writel(lcdc_dev,WIN2_MST3+off,win->area[3].y_addr);
733 val = v_WIN2_DSP_WIDTH3(win->area[3].xsize) |
734 v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
735 lcdc_writel(lcdc_dev,WIN2_DSP_INFO3+off,val);
736 val = v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
737 v_WIN2_DSP_YST3(win->area[3].dsp_sty);
738 lcdc_writel(lcdc_dev,WIN2_DSP_ST3+off,val);
740 mask = m_WIN2_MST3_EN;
741 val = v_WIN2_MST3_EN(0);
742 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
745 if(win->alpha_en == 1)
746 rk3288_lcdc_alpha_cfg(dev_drv,win_id);
748 mask = m_WIN2_SRC_ALPHA_EN;
749 val = v_WIN2_SRC_ALPHA_EN(0);
750 lcdc_msk_reg(lcdc_dev,WIN2_SRC_ALPHA_CTRL+off,mask,val);
753 mask = m_WIN2_EN | m_WIN2_MST0_EN |
754 m_WIN2_MST0_EN | m_WIN2_MST2_EN |
756 val = v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
757 v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) |
759 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0+off, mask,val);
764 static int rk3288_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
766 struct lcdc_device *lcdc_dev =
767 container_of(dev_drv, struct lcdc_device, driver);
771 spin_lock(&lcdc_dev->reg_lock);
772 if(likely(lcdc_dev->clk_on))
774 lcdc_dev->standby = 0;
775 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
776 v_STANDBY_EN(lcdc_dev->standby));
777 rk3288_win_full_reg_update(dev_drv,0);
778 rk3288_win_full_reg_update(dev_drv,1);
779 rk3288_win_lite_reg_update(dev_drv,2);
780 rk3288_win_lite_reg_update(dev_drv,3);
781 rk3288_lcdc_post_cfg(dev_drv);
782 lcdc_cfg_done(lcdc_dev);
784 spin_unlock(&lcdc_dev->reg_lock);
786 if (dev_drv->wait_fs) {
787 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
788 init_completion(&dev_drv->frame_done);
789 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
790 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
792 (dev_drv->cur_screen->ft +
794 if (!timeout && (!dev_drv->frame_done.done)) {
795 dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
799 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
804 static int rk3288_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
806 memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x84);
810 static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
816 struct lcdc_device *lcdc_dev =
817 container_of(dev_drv, struct lcdc_device, driver);
818 struct rk_screen *screen = dev_drv->cur_screen;
819 u16 hsync_len = screen->mode.hsync_len;
820 u16 left_margin = screen->mode.left_margin;
821 u16 right_margin = screen->mode.right_margin;
822 u16 vsync_len = screen->mode.vsync_len;
823 u16 upper_margin = screen->mode.upper_margin;
824 u16 lower_margin = screen->mode.lower_margin;
825 u16 x_res = screen->mode.xres;
826 u16 y_res = screen->mode.yres;
830 h_total = hsync_len + left_margin + x_res + right_margin;
831 v_total = vsync_len + upper_margin + y_res + lower_margin;
832 screen->post_dsp_stx=0;
833 screen->post_dsp_sty=0;
834 screen->post_xsize =x_res;
835 screen->post_ysize = y_res;
837 spin_lock(&lcdc_dev->reg_lock);
838 if (likely(lcdc_dev->clk_on)) {
839 switch (screen->face) {
842 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
844 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
845 v_DITHER_DOWN_SEL(1);
846 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
850 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
852 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
853 v_DITHER_DOWN_SEL(1);
854 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
858 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
860 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
861 v_DITHER_DOWN_SEL(1);
862 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
866 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
868 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
869 v_DITHER_DOWN_SEL(1);
870 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
874 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
875 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
876 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
879 dev_err(lcdc_dev->dev,"un supported interface!\n");
882 switch(screen->type){
885 case SCREEN_DUAL_LVDS:
887 val = v_RGB_OUT_EN(1);
889 v |= (lcdc_dev->id << 3);
892 mask = m_HDMI_OUT_EN;
893 val = v_HDMI_OUT_EN(1);
895 v |= (lcdc_dev->id << 4);*/
898 mask = m_MIPI_OUT_EN;
899 val = v_MIPI_OUT_EN(1);
900 /*v = (1 << (6+16))||(1 << (9+16));
901 v |= (lcdc_dev->id << 6);
902 v |= (lcdc_dev->id << 9);*/
904 case SCREEN_DUAL_MIPI:
905 mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN;
906 val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1);
907 /*v = (1 << (6+16))||(1 << (9+16));
908 v |= (lcdc_dev->id << 6);
909 v |= (lcdc_dev->id << 9);*/
912 face = OUT_RGB_AAA; /*RGB AAA output*/
913 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
914 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
915 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
917 val = v_EDP_OUT_EN(1);
919 v |= (lcdc_dev->id << 5);*/
922 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
923 #ifndef CONFIG_RK_FPGA
924 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
926 mask = m_DSP_OUT_MODE | m_DSP_HSYNC_POL | m_DSP_VSYNC_POL |
927 m_DSP_DEN_POL | m_DSP_DCLK_POL | m_DSP_BG_SWAP |
928 m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
929 m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN |
931 val = v_DSP_OUT_MODE(face) | v_DSP_HSYNC_POL(screen->pin_hsync) |
932 v_DSP_VSYNC_POL(screen->pin_vsync) |
933 v_DSP_DEN_POL(screen->pin_den) | v_DSP_DCLK_POL(screen->pin_dclk) |
934 v_DSP_BG_SWAP(screen->swap_gb) | v_DSP_RB_SWAP(screen->swap_rb) |
935 v_DSP_RG_SWAP(screen->swap_rg) |
936 v_DSP_DELTA_SWAP(screen->swap_delta) |
937 v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) |
938 v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0);;
939 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
941 mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
942 val = v_DSP_BG_BLUE(0x3ff) | v_DSP_BG_GREEN(0) | v_DSP_BG_RED(0);
943 lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
945 mask = m_DSP_HS_PW | m_DSP_HTOTAL;
946 val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
947 lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
949 mask = m_DSP_HACT_END | m_DSP_HACT_ST;
950 val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
951 v_DSP_HACT_ST(hsync_len + left_margin);
952 lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
954 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
955 val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
956 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
958 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
959 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
960 v_DSP_VACT_ST(vsync_len + upper_margin);
961 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
963 rk3288_lcdc_post_cfg(dev_drv);
965 spin_unlock(&lcdc_dev->reg_lock);
967 #ifndef CONFIG_RK_FPGA
968 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
970 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
972 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
973 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
975 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
976 screen->ft = 1000 / fps;
977 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
978 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
986 /*enable layer,open:1,enable;0 disable*/
987 static int win0_open(struct lcdc_device *lcdc_dev, bool open)
989 spin_lock(&lcdc_dev->reg_lock);
990 if (likely(lcdc_dev->clk_on)) {
992 if (!lcdc_dev->atv_layer_cnt) {
993 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
994 lcdc_dev->standby = 0;
996 lcdc_dev->atv_layer_cnt++;
997 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
998 lcdc_dev->atv_layer_cnt--;
1000 lcdc_dev->driver.win[0]->state = open;
1001 if (!lcdc_dev->atv_layer_cnt) {
1002 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1003 lcdc_dev->standby = 1;
1006 spin_unlock(&lcdc_dev->reg_lock);
1011 static int win1_open(struct lcdc_device *lcdc_dev, bool open)
1013 spin_lock(&lcdc_dev->reg_lock);
1014 if (likely(lcdc_dev->clk_on)) {
1016 if (!lcdc_dev->atv_layer_cnt) {
1017 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1018 lcdc_dev->standby = 0;
1020 lcdc_dev->atv_layer_cnt++;
1021 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1022 lcdc_dev->atv_layer_cnt--;
1024 lcdc_dev->driver.win[1]->state = open;
1026 /*if no layer used,disable lcdc*/
1027 if (!lcdc_dev->atv_layer_cnt) {
1028 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1029 lcdc_dev->standby = 1;
1032 spin_unlock(&lcdc_dev->reg_lock);
1037 static int win2_open(struct lcdc_device *lcdc_dev, bool open)
1039 spin_lock(&lcdc_dev->reg_lock);
1040 if (likely(lcdc_dev->clk_on)) {
1042 if (!lcdc_dev->atv_layer_cnt) {
1043 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1044 lcdc_dev->standby = 0;
1046 lcdc_dev->atv_layer_cnt++;
1047 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1048 lcdc_dev->atv_layer_cnt--;
1050 lcdc_dev->driver.win[2]->state = open;
1052 /*if no layer used,disable lcdc*/
1053 if (!lcdc_dev->atv_layer_cnt) {
1054 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1055 lcdc_dev->standby = 1;
1058 spin_unlock(&lcdc_dev->reg_lock);
1063 static int win3_open(struct lcdc_device *lcdc_dev, bool open)
1065 spin_lock(&lcdc_dev->reg_lock);
1066 if (likely(lcdc_dev->clk_on)) {
1068 if (!lcdc_dev->atv_layer_cnt) {
1069 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1070 lcdc_dev->standby = 0;
1072 lcdc_dev->atv_layer_cnt++;
1073 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1074 lcdc_dev->atv_layer_cnt--;
1076 lcdc_dev->driver.win[3]->state = open;
1078 /*if no layer used,disable lcdc*/
1079 if (!lcdc_dev->atv_layer_cnt) {
1080 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1081 lcdc_dev->standby = 1;
1084 spin_unlock(&lcdc_dev->reg_lock);
1090 static int rk3288_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1093 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1094 struct lcdc_device, driver);
1096 /*enable clk,when first layer open */
1097 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1098 rk3288_lcdc_pre_init(dev_drv);
1099 rk3288_lcdc_clk_enable(lcdc_dev);
1100 rk3288_lcdc_reg_restore(lcdc_dev);
1101 rk3288_load_screen(dev_drv, 1);
1102 spin_lock(&lcdc_dev->reg_lock);
1103 if (dev_drv->cur_screen->dsp_lut)
1104 rk3288_lcdc_set_lut(dev_drv);
1105 spin_unlock(&lcdc_dev->reg_lock);
1109 win0_open(lcdc_dev, open);
1110 else if (win_id == 1)
1111 win1_open(lcdc_dev, open);
1112 else if (win_id == 2)
1113 win2_open(lcdc_dev, open);
1114 else if (win_id == 3)
1115 win3_open(lcdc_dev, open);
1117 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1119 /*when all layer closed,disable clk */
1120 if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1121 rk3288_lcdc_disable_irq(lcdc_dev);
1122 rk3288_lcdc_reg_update(dev_drv);
1123 rk3288_lcdc_clk_disable(lcdc_dev);
1129 static int win0_display(struct lcdc_device *lcdc_dev,
1130 struct rk_lcdc_win *win)
1134 y_addr = win->area[0].smem_start+win->area[0].y_offset;/*win->smem_start + win->y_offset;*/
1135 uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1136 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
1137 lcdc_dev->id, __func__, y_addr, uv_addr);
1138 spin_lock(&lcdc_dev->reg_lock);
1139 if (likely(lcdc_dev->clk_on)) {
1140 win->area[0].y_addr = y_addr;
1141 win->area[0].uv_addr = uv_addr;
1143 spin_unlock(&lcdc_dev->reg_lock);
1149 static int win1_display(struct lcdc_device *lcdc_dev,
1150 struct rk_lcdc_win *win)
1154 y_addr = win->area[0].smem_start + win->area[0].y_offset;
1155 uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1156 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
1157 lcdc_dev->id, __func__, y_addr, uv_addr);
1159 spin_lock(&lcdc_dev->reg_lock);
1160 if (likely(lcdc_dev->clk_on))
1161 win->area[0].y_addr = y_addr;
1162 spin_unlock(&lcdc_dev->reg_lock);
1167 static int win2_display(struct lcdc_device *lcdc_dev,
1168 struct rk_lcdc_win *win)
1171 y_addr = win->area[0].smem_start + win->area[0].y_offset;
1172 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>\n",
1173 lcdc_dev->id, __func__, y_addr);
1175 spin_lock(&lcdc_dev->reg_lock);
1176 if (likely(lcdc_dev->clk_on))
1177 for(i=0;i<win->area_num;i++){
1178 win->area[i].y_addr =
1179 win->area[i].smem_start + win->area[i].y_offset;
1181 spin_unlock(&lcdc_dev->reg_lock);
1185 static int win3_display(struct lcdc_device *lcdc_dev,
1186 struct rk_lcdc_win *win)
1189 y_addr = win->area[0].smem_start + win->area[0].y_offset;
1190 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>\n",
1191 lcdc_dev->id, __func__, y_addr);
1193 spin_lock(&lcdc_dev->reg_lock);
1194 if (likely(lcdc_dev->clk_on))
1195 for(i=0;i<win->area_num;i++){
1196 win->area[i].y_addr =
1197 win->area[i].smem_start + win->area[i].y_offset;
1199 spin_unlock(&lcdc_dev->reg_lock);
1204 static int rk3288_lcdc_win_display(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *win,int win_id)
1206 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1207 struct lcdc_device, driver);
1208 struct rk_screen *screen = dev_drv->cur_screen;
1211 lcdc_dev->atv_layer_cnt = dev_drv->atv_layer_cnt;
1213 dev_err(dev_drv->dev, "screen is null!\n");
1218 win0_display(lcdc_dev, win);
1219 }else if(win_id == 1){
1220 win1_display(lcdc_dev, win);
1221 }else if(win_id == 2){
1222 win2_display(lcdc_dev, win);
1223 }else if(win_id == 3){
1224 win3_display(lcdc_dev, win);
1226 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1229 /*this is the first frame of the system ,enable frame start interrupt */
1230 if ((dev_drv->first_frame)) {
1231 dev_drv->first_frame = 0;
1232 mask = m_FS_INTR_CLR | m_FS_INTR_EN | m_LINE_FLAG_INTR_CLR |
1233 m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_CLR |
1234 m_BUS_ERROR_INTR_EN | m_DSP_LINE_FLAG_NUM;
1235 val = v_FS_INTR_CLR(1) | v_FS_INTR_EN(1) | v_LINE_FLAG_INTR_CLR(1) |
1236 v_LINE_FLAG_INTR_EN(1) | v_BUS_ERROR_INTR_CLR(1) | v_BUS_ERROR_INTR_EN(0) |
1237 v_DSP_LINE_FLAG_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
1238 screen->mode.yres -1);
1239 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
1240 #ifdef CONFIG_RK_FPGA
1241 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN |
1242 m_WIN3_EMPTY_INTR_EN |m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
1244 val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) | v_WIN2_EMPTY_INTR_EN(1) |
1245 v_WIN3_EMPTY_INTR_EN(1)| v_HWC_EMPTY_INTR_EN(1) | v_POST_BUF_EMPTY_INTR_EN(1) |
1246 v_PWM_GEN_INTR_EN(1);
1247 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
1249 lcdc_cfg_done(lcdc_dev);
1255 static int rk3288_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1257 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1258 struct lcdc_device, driver);
1259 struct rk_lcdc_win *win = NULL;
1260 struct rk_screen *screen = dev_drv->cur_screen;
1262 #if defined(WAIT_FOR_SYNC)
1264 unsigned long flags;
1266 win = dev_drv->win[win_id];
1267 lcdc_dev->atv_layer_cnt = dev_drv->atv_layer_cnt;
1269 dev_err(dev_drv->dev, "screen is null!\n");
1274 win0_display(lcdc_dev, win);
1275 }else if(win_id == 1){
1276 win1_display(lcdc_dev, win);
1277 }else if(win_id == 2){
1278 win2_display(lcdc_dev, win);
1279 }else if(win_id == 3){
1280 win3_display(lcdc_dev, win);
1282 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1288 /*this is the first frame of the system ,enable frame start interrupt */
1289 if ((dev_drv->first_frame)) {
1290 dev_drv->first_frame = 0;
1291 mask = m_FS_INTR_CLR | m_FS_INTR_EN | m_LINE_FLAG_INTR_CLR |
1292 m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_CLR |
1293 m_BUS_ERROR_INTR_EN | m_DSP_LINE_FLAG_NUM;
1294 val = v_FS_INTR_CLR(1) | v_FS_INTR_EN(1) | v_LINE_FLAG_INTR_CLR(1) |
1295 v_LINE_FLAG_INTR_EN(1) | v_BUS_ERROR_INTR_CLR(1) | v_BUS_ERROR_INTR_EN(0) |
1296 v_DSP_LINE_FLAG_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
1297 screen->mode.yres -1);
1298 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
1299 #ifdef CONFIG_RK_FPGA
1300 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN |
1301 m_WIN3_EMPTY_INTR_EN |m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
1303 val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) | v_WIN2_EMPTY_INTR_EN(1) |
1304 v_WIN3_EMPTY_INTR_EN(1)| v_HWC_EMPTY_INTR_EN(1) | v_POST_BUF_EMPTY_INTR_EN(1) |
1305 v_PWM_GEN_INTR_EN(1);
1306 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
1308 lcdc_cfg_done(lcdc_dev);
1310 #if defined(WAIT_FOR_SYNC)
1311 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
1312 init_completion(&dev_drv->frame_done);
1313 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
1314 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
1315 msecs_to_jiffies(dev_drv->
1318 if (!timeout && (!dev_drv->frame_done.done)) {
1319 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
1323 dev_drv->ops->ovl_mgr(dev_drv, 0, 1);
1324 rk3288_lcdc_reg_update(dev_drv);
1328 static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win)
1338 u32 yrgb_vScaleDnMult;
1339 u32 yrgb_xscl_factor;
1340 u32 yrgb_yscl_factor;
1341 u8 yrgb_vsd_bil_gt2=0;
1342 u8 yrgb_vsd_bil_gt4=0;
1348 u32 cbcr_vScaleDnMult;
1349 u32 cbcr_xscl_factor;
1350 u32 cbcr_yscl_factor;
1351 u8 cbcr_vsd_bil_gt2=0;
1352 u8 cbcr_vsd_bil_gt4=0;
1355 srcW = win->area[0].xact;
1356 srcH = win->area[0].yact;
1357 dstW = win->area[0].xsize;
1358 dstH = win->area[0].ysize;
1365 if(yrgb_srcW < yrgb_dstW){
1366 win->yrgb_hor_scl_mode = SCALE_UP;
1367 }else if(yrgb_srcW > yrgb_dstW){
1368 win->yrgb_hor_scl_mode = SCALE_DOWN;
1370 win->yrgb_hor_scl_mode = SCALE_NONE;
1373 if(yrgb_srcH < yrgb_dstH){
1374 win->yrgb_ver_scl_mode = SCALE_UP;
1375 }else if (yrgb_srcH > yrgb_dstH){
1376 win->yrgb_ver_scl_mode = SCALE_DOWN;
1378 win->yrgb_ver_scl_mode = SCALE_NONE;
1382 switch (win->format) {
1408 if(cbcr_srcW < cbcr_dstW){
1409 win->cbr_hor_scl_mode = SCALE_UP;
1410 }else if(cbcr_srcW > cbcr_dstW){
1411 win->cbr_hor_scl_mode = SCALE_DOWN;
1413 win->cbr_hor_scl_mode = SCALE_NONE;
1416 if(cbcr_srcH < cbcr_dstH){
1417 win->cbr_ver_scl_mode = SCALE_UP;
1418 }else if(cbcr_srcH > cbcr_dstH){
1419 win->cbr_ver_scl_mode = SCALE_DOWN;
1421 win->cbr_ver_scl_mode = SCALE_NONE;
1423 DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
1424 "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1425 "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1426 ,srcW,srcH,dstW,dstH,yrgb_srcW,yrgb_srcH,yrgb_dstW,
1427 yrgb_dstH,win->yrgb_hor_scl_mode,win->yrgb_ver_scl_mode,
1428 cbcr_srcW,cbcr_srcH,cbcr_dstW,cbcr_dstH,
1429 win->cbr_hor_scl_mode,win->cbr_ver_scl_mode);
1431 /*line buffer mode*/
1432 if((win->format == YUV422) || (win->format == YUV420)){
1433 if(win->cbr_hor_scl_mode == SCALE_DOWN){
1434 if(cbcr_dstW > 3840){
1435 pr_err("ERROR cbcr_dst_width exceeds 3840\n");
1436 }else if(cbcr_dstW > 2560){
1437 win->win_lb_mode = LB_RGB_3840X2;
1438 }else if(cbcr_dstW > 1920){
1439 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1440 if(yrgb_dstW > 3840){
1441 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1442 }else if(yrgb_dstW > 2560){
1443 win->win_lb_mode = LB_RGB_3840X2;
1444 }else if(yrgb_dstW > 1920){
1445 win->win_lb_mode = LB_RGB_2560X4;
1447 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1450 }else if(cbcr_dstW > 1280){
1451 win->win_lb_mode = LB_YUV_3840X5;
1453 win->win_lb_mode = LB_YUV_2560X8;
1455 } else { /*SCALE_UP or SCALE_NONE*/
1456 if(cbcr_srcW > 3840){
1457 pr_err("ERROR cbcr_act_width exceeds 3840\n");
1458 }else if(cbcr_srcW > 2560){
1459 win->win_lb_mode = LB_RGB_3840X2;
1460 }else if(cbcr_srcW > 1920){
1461 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1462 if(yrgb_dstW > 3840){
1463 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1464 }else if(yrgb_dstW > 2560){
1465 win->win_lb_mode = LB_RGB_3840X2;
1466 }else if(yrgb_dstW > 1920){
1467 win->win_lb_mode = LB_RGB_2560X4;
1469 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1472 }else if(cbcr_srcW > 1280){
1473 win->win_lb_mode = LB_YUV_3840X5;
1475 win->win_lb_mode = LB_YUV_2560X8;
1479 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1480 if(yrgb_dstW > 3840){
1481 pr_err("ERROR yrgb_dsp_width exceeds 3840\n");
1482 }else if(yrgb_dstW > 2560){
1483 win->win_lb_mode = LB_RGB_3840X2;
1484 }else if(yrgb_dstW > 1920){
1485 win->win_lb_mode = LB_RGB_2560X4;
1486 }else if(yrgb_dstW > 1280){
1487 win->win_lb_mode = LB_RGB_1920X5;
1489 win->win_lb_mode = LB_RGB_1280X8;
1491 }else{ /*SCALE_UP or SCALE_NONE*/
1492 if(yrgb_srcW > 3840){
1493 pr_err("ERROR yrgb_act_width exceeds 3840\n");
1494 }else if(yrgb_srcW > 2560){
1495 win->win_lb_mode = LB_RGB_3840X2;
1496 }else if(yrgb_srcW > 1920){
1497 win->win_lb_mode = LB_RGB_2560X4;
1498 }else if(yrgb_srcW > 1280){
1499 win->win_lb_mode = LB_RGB_1920X5;
1501 win->win_lb_mode = LB_RGB_1280X8;
1505 DBG(1,"win->win_lb_mode = %d;\n",win->win_lb_mode);
1507 /*vsd/vsu scale ALGORITHM*/
1508 win->yrgb_hsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1509 win->cbr_hsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1510 win->yrgb_vsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1511 win->cbr_vsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1512 switch(win->win_lb_mode){
1517 win->yrgb_vsu_mode = SCALE_UP_BIC;
1518 win->cbr_vsu_mode = SCALE_UP_BIC;
1521 if(win->yrgb_ver_scl_mode != SCALE_NONE) {
1522 pr_err("ERROR : not allow yrgb ver scale\n");
1524 if(win->cbr_ver_scl_mode != SCALE_NONE) {
1525 pr_err("ERROR : not allow cbcr ver scale\n");
1529 win->yrgb_vsu_mode = SCALE_UP_BIL;
1530 win->cbr_vsu_mode = SCALE_UP_BIL;
1535 DBG(1,"yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
1536 win->yrgb_hsd_mode,win->yrgb_vsd_mode,win->yrgb_vsu_mode,
1537 win->cbr_hsd_mode,win->cbr_vsd_mode,win->cbr_vsu_mode);
1541 /*(1.1)YRGB HOR SCALE FACTOR*/
1542 switch(win->yrgb_hor_scl_mode){
1544 yrgb_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1547 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
1550 switch(win->yrgb_hsd_mode)
1552 case SCALE_DOWN_BIL:
1553 yrgb_xscl_factor = GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
1555 case SCALE_DOWN_AVG:
1556 yrgb_xscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
1564 } /*win->yrgb_hor_scl_mode*/
1566 /*(1.2)YRGB VER SCALE FACTOR*/
1567 switch(win->yrgb_ver_scl_mode)
1570 yrgb_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1573 switch(win->yrgb_vsu_mode)
1576 yrgb_yscl_factor = GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
1580 pr_err("yrgb_srcH should be greater than 3 !!!\n");
1582 yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH, yrgb_dstH);
1589 switch(win->yrgb_vsd_mode)
1591 case SCALE_DOWN_BIL:
1592 yrgb_vScaleDnMult = getHardWareVSkipLines(yrgb_srcH, yrgb_dstH);
1593 yrgb_yscl_factor = GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH, yrgb_vScaleDnMult);
1594 if(yrgb_vScaleDnMult == 4){
1595 yrgb_vsd_bil_gt4 = 1;
1596 yrgb_vsd_bil_gt2 = 0;
1597 }else if(yrgb_vScaleDnMult == 2){
1598 yrgb_vsd_bil_gt4 = 0;
1599 yrgb_vsd_bil_gt2 = 1;
1601 yrgb_vsd_bil_gt4 = 0;
1602 yrgb_vsd_bil_gt2 = 0;
1605 case SCALE_DOWN_AVG:
1606 yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH, yrgb_dstH);
1610 } /*win->yrgb_vsd_mode*/
1615 win->scale_yrgb_x = yrgb_xscl_factor;
1616 win->scale_yrgb_y = yrgb_yscl_factor;
1617 win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
1618 win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
1619 DBG(1,"yrgb:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",yrgb_xscl_factor,
1620 yrgb_yscl_factor,yrgb_vsd_bil_gt4,yrgb_vsd_bil_gt2);
1622 /*(2.1)CBCR HOR SCALE FACTOR*/
1623 switch(win->cbr_hor_scl_mode)
1626 cbcr_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1629 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
1632 switch(win->cbr_hsd_mode)
1634 case SCALE_DOWN_BIL:
1635 cbcr_xscl_factor = GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
1637 case SCALE_DOWN_AVG:
1638 cbcr_xscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
1646 } /*win->cbr_hor_scl_mode*/
1648 /*(2.2)CBCR VER SCALE FACTOR*/
1649 switch(win->cbr_ver_scl_mode)
1652 cbcr_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1655 switch(win->cbr_vsu_mode)
1658 cbcr_yscl_factor = GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
1662 pr_err("cbcr_srcH should be greater than 3 !!!\n");
1664 cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH, cbcr_dstH);
1671 switch(win->cbr_vsd_mode)
1673 case SCALE_DOWN_BIL:
1674 cbcr_vScaleDnMult = getHardWareVSkipLines(cbcr_srcH, cbcr_dstH);
1675 cbcr_yscl_factor = GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH, cbcr_vScaleDnMult);
1676 if(cbcr_vScaleDnMult == 4){
1677 cbcr_vsd_bil_gt4 = 1;
1678 cbcr_vsd_bil_gt2 = 0;
1679 }else if(cbcr_vScaleDnMult == 2){
1680 cbcr_vsd_bil_gt4 = 0;
1681 cbcr_vsd_bil_gt2 = 1;
1683 cbcr_vsd_bil_gt4 = 0;
1684 cbcr_vsd_bil_gt2 = 0;
1687 case SCALE_DOWN_AVG:
1688 cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH, cbcr_dstH);
1697 win->scale_cbcr_x = cbcr_xscl_factor;
1698 win->scale_cbcr_y = cbcr_yscl_factor;
1699 win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
1700 win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
1702 DBG(1,"cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",cbcr_xscl_factor,
1703 cbcr_yscl_factor,cbcr_vsd_bil_gt4,cbcr_vsd_bil_gt2);
1709 static int win0_set_par(struct lcdc_device *lcdc_dev,
1710 struct rk_screen *screen, struct rk_lcdc_win *win)
1712 u32 xact,yact,xvir, yvir,xpos, ypos;
1714 char fmt[9] = "NULL";
1716 xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
1717 ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
1719 spin_lock(&lcdc_dev->reg_lock);
1720 if(likely(lcdc_dev->clk_on)){
1721 rk3288_lcdc_cal_scl_fac(win);/*fac,lb.gt2,gt4*/
1722 switch (win->format){
1753 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1757 win->fmt_cfg = fmt_cfg;
1758 win->area[0].dsp_stx = xpos;
1759 win->area[0].dsp_sty = ypos;
1760 xact = win->area[0].xact;
1761 yact = win->area[0].yact;
1762 xvir = win->area[0].xvir;
1763 yvir = win->area[0].xvir;
1765 spin_unlock(&lcdc_dev->reg_lock);
1767 DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1768 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
1769 __func__, get_format_string(win->format, fmt), xact,
1770 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
1775 static int win1_set_par(struct lcdc_device *lcdc_dev,
1776 struct rk_screen *screen, struct rk_lcdc_win *win)
1778 u32 xact,yact,xvir, yvir,xpos, ypos;
1780 char fmt[9] = "NULL";
1782 xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
1783 ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
1785 spin_lock(&lcdc_dev->reg_lock);
1786 if(likely(lcdc_dev->clk_on)){
1787 rk3288_lcdc_cal_scl_fac(win);/*fac,lb.gt2,gt4*/
1788 switch (win->format){
1819 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1823 win->fmt_cfg = fmt_cfg;
1824 win->area[0].dsp_stx = xpos;
1825 win->area[0].dsp_sty = ypos;
1826 xact = win->area[0].xact;
1827 yact = win->area[0].yact;
1828 xvir = win->area[0].xvir;
1829 yvir = win->area[0].xvir;
1831 spin_unlock(&lcdc_dev->reg_lock);
1833 DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1834 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
1835 __func__, get_format_string(win->format, fmt), xact,
1836 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
1841 static int win2_set_par(struct lcdc_device *lcdc_dev,
1842 struct rk_screen *screen, struct rk_lcdc_win *win)
1847 spin_lock(&lcdc_dev->reg_lock);
1848 if(likely(lcdc_dev->clk_on)){
1849 for(i=0;i<win->area_num;i++){
1850 switch (win->format){
1869 dev_err(lcdc_dev->driver.dev,
1870 "%s:un supported format!\n",
1874 win->fmt_cfg = fmt_cfg;
1875 win->area[i].dsp_stx = win->area[i].xpos +
1876 screen->mode.left_margin +
1877 screen->mode.hsync_len;
1878 win->area[i].dsp_sty = win->area[i].ypos +
1879 screen->mode.upper_margin +
1880 screen->mode.vsync_len;;
1883 spin_unlock(&lcdc_dev->reg_lock);
1887 static int win3_set_par(struct lcdc_device *lcdc_dev,
1888 struct rk_screen *screen, struct rk_lcdc_win *win)
1894 spin_lock(&lcdc_dev->reg_lock);
1895 if(likely(lcdc_dev->clk_on)){
1896 for(i=0;i<win->area_num;i++){
1897 switch (win->format){
1916 dev_err(lcdc_dev->driver.dev,
1917 "%s:un supported format!\n",
1921 win->fmt_cfg = fmt_cfg;
1922 win->area[i].dsp_stx = win->area[i].xpos +
1923 screen->mode.left_margin +
1924 screen->mode.hsync_len;
1925 win->area[i].dsp_sty = win->area[i].ypos +
1926 screen->mode.upper_margin +
1927 screen->mode.vsync_len;;
1930 spin_unlock(&lcdc_dev->reg_lock);
1936 static int rk3288_set_win_par(struct rk_lcdc_driver *dev_drv,
1937 struct rk_screen *screen, struct rk_lcdc_win *win,int win_id)
1939 struct lcdc_device *lcdc_dev =
1940 container_of(dev_drv, struct lcdc_device, driver);
1945 win0_set_par(lcdc_dev, screen, win);
1948 win1_set_par(lcdc_dev, screen, win);
1951 win2_set_par(lcdc_dev, screen, win);
1954 win3_set_par(lcdc_dev, screen, win);
1957 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
1962 static int rk3288_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
1964 struct rk_lcdc_win *win = NULL;
1965 struct rk_screen *screen = dev_drv->cur_screen;
1969 dev_err(dev_drv->dev, "screen is null!\n");
1972 for(i=0;i<dev_drv->lcdc_win_num;i++){
1973 if(dev_drv->win[i]->state == 1){
1974 win = dev_drv->win[i];
1975 rk3288_set_win_par(dev_drv,screen,win,i);
1976 rk3288_lcdc_win_display(dev_drv,win,i);
1980 dev_drv->ops->ovl_mgr(dev_drv, 0, 1);
1981 rk3288_lcdc_reg_update(dev_drv);
1987 static int rk3288_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1988 unsigned long arg, int win_id)
1990 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1995 void __user *argp = (void __user *)arg;
1996 struct color_key_cfg clr_key_cfg;
1999 case RK_FBIOGET_PANEL_SIZE:
2000 panel_size[0] = lcdc_dev->screen->mode.xres;
2001 panel_size[1] = lcdc_dev->screen->mode.yres;
2002 if (copy_to_user(argp, panel_size, 8))
2005 case RK_FBIOPUT_COLOR_KEY_CFG:
2006 if (copy_from_user(&clr_key_cfg, argp,
2007 sizeof(struct color_key_cfg)))
2009 rk3288_lcdc_clr_key_cfg(dev_drv);
2010 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
2011 clr_key_cfg.win0_color_key_cfg);
2012 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
2013 clr_key_cfg.win1_color_key_cfg);
2022 static int rk3288_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
2024 struct lcdc_device *lcdc_dev =
2025 container_of(dev_drv, struct lcdc_device, driver);
2026 if (dev_drv->screen0->standby)
2027 dev_drv->screen0->standby(1);
2028 if (dev_drv->screen_ctr_info->io_disable)
2029 dev_drv->screen_ctr_info->io_disable();
2030 dev_drv->suspend_flag = 1;
2031 flush_kthread_worker(&dev_drv->update_regs_worker);
2033 spin_lock(&lcdc_dev->reg_lock);
2034 if (likely(lcdc_dev->clk_on)) {
2035 rk3288_lcdc_disable_irq(lcdc_dev);
2036 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2038 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2040 lcdc_cfg_done(lcdc_dev);
2041 spin_unlock(&lcdc_dev->reg_lock);
2043 spin_unlock(&lcdc_dev->reg_lock);
2046 rk3288_lcdc_clk_disable(lcdc_dev);
2050 static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
2052 struct lcdc_device *lcdc_dev =
2053 container_of(dev_drv, struct lcdc_device, driver);
2058 if (dev_drv->screen_ctr_info->io_enable)
2059 dev_drv->screen_ctr_info->io_enable();
2060 dev_drv->suspend_flag = 0;
2062 if (lcdc_dev->atv_layer_cnt) {
2063 rk3288_lcdc_clk_enable(lcdc_dev);
2064 rk3288_lcdc_reg_restore(lcdc_dev);
2066 spin_lock(&lcdc_dev->reg_lock);
2067 if (dev_drv->cur_screen->dsp_lut) {
2068 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2070 lcdc_cfg_done(lcdc_dev);
2072 for (i = 0; i < 256; i++) {
2073 v = dev_drv->cur_screen->dsp_lut[i];
2074 c = lcdc_dev->dsp_lut_addr_base + i;
2075 writel_relaxed(v, c);
2077 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2081 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2083 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2085 lcdc_cfg_done(lcdc_dev);
2087 spin_unlock(&lcdc_dev->reg_lock);
2090 if (dev_drv->screen0->standby)
2091 dev_drv->screen0->standby(0);
2095 static int rk3288_lcdc_blank(struct rk_lcdc_driver *dev_drv,
2096 int win_id, int blank_mode)
2098 struct lcdc_device *lcdc_dev =
2099 container_of(dev_drv, struct lcdc_device, driver);
2101 spin_lock(&lcdc_dev->reg_lock);
2102 if (likely(lcdc_dev->clk_on)) {
2103 switch (blank_mode) {
2104 case FB_BLANK_UNBLANK:
2105 rk3288_lcdc_early_resume(dev_drv);
2106 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2109 case FB_BLANK_NORMAL:
2110 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2112 rk3288_lcdc_early_suspend(dev_drv);
2115 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2117 rk3288_lcdc_early_suspend(dev_drv);
2120 lcdc_cfg_done(lcdc_dev);
2123 spin_unlock(&lcdc_dev->reg_lock);
2125 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
2130 static int rk3288_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
2135 /*overlay will be do at regupdate*/
2136 static int rk3288_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
2139 struct lcdc_device *lcdc_dev =
2140 container_of(dev_drv, struct lcdc_device, driver);
2142 unsigned int mask, val;
2143 int win0_order,win1_order,win2_order,win3_order;
2144 win0_order = dev_drv->win[0]->z_order;
2145 win1_order = dev_drv->win[1]->z_order;
2146 win2_order = dev_drv->win[2]->z_order;
2147 win3_order = dev_drv->win[3]->z_order;
2149 spin_lock(&lcdc_dev->reg_lock);
2150 if(lcdc_dev->clk_on){
2152 mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
2153 m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
2154 val = v_DSP_LAYER0_SEL(0) |
2155 v_DSP_LAYER1_SEL(1) |
2156 v_DSP_LAYER2_SEL(2) |
2157 v_DSP_LAYER3_SEL(3);
2158 lcdc_msk_reg(lcdc_dev,DSP_CTRL1,mask,val);
2160 win0_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER0_SEL);
2161 win1_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER1_SEL);
2162 win2_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER2_SEL);
2163 win3_order = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER3_SEL);
2164 ovl = win3_order*1000 + win2_order*100 + win1_order *10 + win0_order;
2169 spin_unlock(&lcdc_dev->reg_lock);
2174 static ssize_t rk3288_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2175 char *buf, int win_id)
2177 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2181 struct rk_screen *screen = dev_drv->cur_screen;
2182 u16 hsync_len = screen->mode.hsync_len;
2183 u16 left_margin = screen->mode.left_margin;
2184 u16 vsync_len = screen->mode.vsync_len;
2185 u16 upper_margin = screen->mode.upper_margin;
2186 u32 fmt_id,h_pw_bp,v_pw_bp;
2187 char format_w0[9] = "NULL";
2188 char format_w1[9] = "NULL";
2189 char format_w2[9] = "NULL";
2190 char format_w3[9] = "NULL";
2191 u32 win_ctrl,zorder,vir_info,act_info,dsp_info,dsp_st,y_factor,uv_factor;
2192 u8 layer0_sel,layer1_sel,layer2_sel,layer3_sel;
2193 u8 w0_state,w1_state,w2_state,w3_state;
2194 u8 w2_0_state,w2_1_state,w2_2_state,w2_3_state;
2195 u8 w3_0_state,w3_1_state,w3_2_state,w3_3_state;
2197 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;
2198 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;
2199 u32 w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,w0_uv_v_fac;
2200 u32 w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,w1_uv_v_fac;
2202 u32 w2_0_vir_y,w2_1_vir_y,w2_2_vir_y,w2_3_vir_y;
2203 u32 w2_0_dsp_x,w2_1_dsp_x,w2_2_dsp_x,w2_3_dsp_x;
2204 u32 w2_0_dsp_y,w2_1_dsp_y,w2_2_dsp_y,w2_3_dsp_y;
2205 u32 w2_0_st_x,w2_1_st_x,w2_2_st_x,w2_3_st_x;
2206 u32 w2_0_st_y,w2_1_st_y,w2_2_st_y,w2_3_st_y;
2208 u32 w3_0_vir_y,w3_1_vir_y,w3_2_vir_y,w3_3_vir_y;
2209 u32 w3_0_dsp_x,w3_1_dsp_x,w3_2_dsp_x,w3_3_dsp_x;
2210 u32 w3_0_dsp_y,w3_1_dsp_y,w3_2_dsp_y,w3_3_dsp_y;
2211 u32 w3_0_st_x,w3_1_st_x,w3_2_st_x,w3_3_st_x;
2212 u32 w3_0_st_y,w3_1_st_y,w3_2_st_y,w3_3_st_y;
2215 h_pw_bp = hsync_len + left_margin;
2216 v_pw_bp = vsync_len + upper_margin;
2217 dclk_freq = screen->mode.pixclock;
2218 rk3288_lcdc_reg_dump(dev_drv);
2220 spin_lock(&lcdc_dev->reg_lock);
2221 if (lcdc_dev->clk_on) {
2222 zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
2223 layer0_sel = zorder & m_DSP_LAYER0_SEL;
2224 layer1_sel = zorder & m_DSP_LAYER1_SEL;
2225 layer2_sel = zorder & m_DSP_LAYER2_SEL;
2226 layer3_sel = zorder & m_DSP_LAYER3_SEL;
2228 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
2229 w0_state = win_ctrl & m_WIN0_EN;
2230 fmt_id = (win_ctrl & m_WIN0_DATA_FMT)>>1;
2233 strcpy(format_w0, "ARGB888");
2236 strcpy(format_w0, "RGB888");
2239 strcpy(format_w0, "RGB565");
2242 strcpy(format_w0, "YCbCr420");
2245 strcpy(format_w0, "YCbCr422");
2248 strcpy(format_w0, "YCbCr444");
2251 strcpy(format_w0, "invalid\n");
2254 vir_info = lcdc_readl(lcdc_dev,WIN0_VIR);
2255 act_info = lcdc_readl(lcdc_dev,WIN0_ACT_INFO);
2256 dsp_info = lcdc_readl(lcdc_dev,WIN0_DSP_INFO);
2257 dsp_st = lcdc_readl(lcdc_dev,WIN0_DSP_ST);
2258 y_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
2259 uv_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_CBR);
2260 w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
2261 w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV)>>16;
2262 w0_act_x = (act_info & m_WIN0_ACT_WIDTH)+1;
2263 w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT)>>16)+1;
2264 w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH)+1;
2265 w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT)>>16)+1;
2266 w0_st_x = dsp_st & m_WIN0_DSP_XST;
2267 w0_st_y = (dsp_st & m_WIN0_DSP_YST)>>16;
2268 w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
2269 w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB)>>16;
2270 w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
2271 w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR)>>16;
2274 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
2275 w1_state = win_ctrl & m_WIN1_EN;
2276 fmt_id = (win_ctrl & m_WIN1_DATA_FMT)>>1;
2279 strcpy(format_w1, "ARGB888");
2282 strcpy(format_w1, "RGB888");
2285 strcpy(format_w1, "RGB565");
2288 strcpy(format_w1, "YCbCr420");
2291 strcpy(format_w1, "YCbCr422");
2294 strcpy(format_w1, "YCbCr444");
2297 strcpy(format_w1, "invalid\n");
2300 vir_info = lcdc_readl(lcdc_dev,WIN1_VIR);
2301 act_info = lcdc_readl(lcdc_dev,WIN1_ACT_INFO);
2302 dsp_info = lcdc_readl(lcdc_dev,WIN1_DSP_INFO);
2303 dsp_st = lcdc_readl(lcdc_dev,WIN1_DSP_ST);
2304 y_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_YRGB);
2305 uv_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_CBR);
2306 w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
2307 w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV)>>16;
2308 w1_act_x = (act_info & m_WIN1_ACT_WIDTH)+1;
2309 w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT)>>16)+1;
2310 w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH)+1;
2311 w1_dsp_y =((dsp_info & m_WIN1_DSP_HEIGHT)>>16)+1;
2312 w1_st_x = dsp_st & m_WIN1_DSP_XST;
2313 w1_st_y = (dsp_st & m_WIN1_DSP_YST)>>16;
2314 w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
2315 w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB)>>16;
2316 w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
2317 w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR)>>16;
2319 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
2320 w2_state = win_ctrl & m_WIN2_EN;
2321 w2_0_state = (win_ctrl & m_WIN2_MST0_EN)>>4;
2322 w2_1_state = (win_ctrl & m_WIN2_MST1_EN)>>5;
2323 w2_2_state = (win_ctrl & m_WIN2_MST2_EN)>>6;
2324 w2_3_state = (win_ctrl & m_WIN2_MST3_EN)>>7;
2325 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR0_1);
2326 w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
2327 w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1)>>16;
2328 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR2_3);
2329 w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
2330 w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3)>>16;
2331 fmt_id = (win_ctrl & m_WIN2_DATA_FMT)>>1;
2334 strcpy(format_w2, "ARGB888");
2337 strcpy(format_w2, "RGB888");
2340 strcpy(format_w2, "RGB565");
2343 strcpy(format_w2,"8bpp");
2346 strcpy(format_w2,"4bpp");
2349 strcpy(format_w2,"2bpp");
2352 strcpy(format_w2,"1bpp");
2355 strcpy(format_w2, "invalid\n");
2358 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO0);
2359 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST0);
2360 w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0)+1;
2361 w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0)>>16)+1;
2362 w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
2363 w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0);
2365 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO1);
2366 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST1);
2367 w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1)+1;
2368 w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1)>>16)+1;
2369 w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
2370 w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1)>>16;
2372 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO2);
2373 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST2);
2374 w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2)+1;
2375 w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2)>>16)+1;
2376 w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
2377 w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2)>>16;
2379 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO3);
2380 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST3);
2381 w2_3_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH3)+1;
2382 w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3)>>16)+1;
2383 w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
2384 w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3)>>16;
2387 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
2388 w3_state = win_ctrl & m_WIN3_EN;
2389 w3_0_state = (win_ctrl & m_WIN3_MST0_EN)>>4;
2390 w3_1_state = (win_ctrl & m_WIN3_MST1_EN)>>5;
2391 w3_2_state = (win_ctrl & m_WIN3_MST2_EN)>>6;
2392 w3_3_state = (win_ctrl & m_WIN3_MST3_EN)>>7;
2393 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR0_1);
2394 w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
2395 w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1)>>16;
2396 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR2_3);
2397 w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
2398 w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3)>>16;
2399 fmt_id = (win_ctrl | m_WIN3_DATA_FMT)>>1;
2402 strcpy(format_w3, "ARGB888");
2405 strcpy(format_w3, "RGB888");
2408 strcpy(format_w3, "RGB565");
2411 strcpy(format_w3,"8bpp");
2414 strcpy(format_w3,"4bpp");
2417 strcpy(format_w3,"2bpp");
2420 strcpy(format_w3,"1bpp");
2423 strcpy(format_w3, "invalid");
2426 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO0);
2427 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST0);
2428 w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0)+1;
2429 w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0)>>16)+1;
2430 w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
2431 w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0)>>16;
2433 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO1);
2434 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST1);
2435 w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1)+1;
2436 w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1)>>16)+1;
2437 w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
2438 w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1)>>16;
2440 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO2);
2441 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST2);
2442 w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2)+1;
2443 w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2)>>16)+1;
2444 w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
2445 w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2)>>16;
2447 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO3);
2448 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST3);
2449 w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3)+1;
2450 w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3)>>16)+1;
2451 w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
2452 w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3)>>16;
2455 spin_unlock(&lcdc_dev->reg_lock);
2458 spin_unlock(&lcdc_dev->reg_lock);
2459 return snprintf(buf, PAGE_SIZE,
2463 " layer3_sel_win[%d]\n"
2464 " layer2_sel_win[%d]\n"
2465 " layer1_sel_win[%d]\n"
2466 " layer0_sel_win[%d]\n"
2572 layer3_sel,layer2_sel,layer1_sel,layer0_sel,
2573 w0_state,format_w0,w0_vir_y,w0_vir_uv,w0_act_x,w0_act_y,
2574 w0_dsp_x,w0_dsp_y,w0_st_x,w0_st_y,w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,
2575 w0_uv_v_fac,lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2576 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2578 w1_state,format_w1,w1_vir_y,w1_vir_uv,w1_act_x,w1_act_y,
2579 w1_dsp_x,w1_dsp_y,w1_st_x,w1_st_y,w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,
2580 w1_uv_v_fac,lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
2581 lcdc_readl(lcdc_dev, WIN1_CBR_MST),
2584 w2_0_state,w2_0_vir_y,w2_0_dsp_x,w2_0_dsp_y,
2585 w2_0_st_x,w2_0_st_y,lcdc_readl(lcdc_dev, WIN2_MST0),
2587 w2_1_state,w2_1_vir_y,w2_1_dsp_x,w2_1_dsp_y,
2588 w2_1_st_x,w2_1_st_y,lcdc_readl(lcdc_dev, WIN2_MST1),
2590 w2_2_state,w2_2_vir_y,w2_2_dsp_x,w2_2_dsp_y,
2591 w2_2_st_x,w2_2_st_y,lcdc_readl(lcdc_dev, WIN2_MST2),
2593 w2_3_state,w2_3_vir_y,w2_3_dsp_x,w2_3_dsp_y,
2594 w2_3_st_x,w2_3_st_y,lcdc_readl(lcdc_dev, WIN2_MST3),
2597 w3_0_state,w3_0_vir_y,w3_0_dsp_x,w3_0_dsp_y,
2598 w3_0_st_x,w3_0_st_y,lcdc_readl(lcdc_dev, WIN3_MST0),
2600 w3_1_state,w3_1_vir_y,w3_1_dsp_x,w3_1_dsp_y,
2601 w3_1_st_x,w3_1_st_y,lcdc_readl(lcdc_dev, WIN3_MST1),
2603 w3_2_state,w3_2_vir_y,w3_2_dsp_x,w3_2_dsp_y,
2604 w3_2_st_x,w3_2_st_y,lcdc_readl(lcdc_dev, WIN3_MST2),
2606 w3_3_state,w3_3_vir_y,w3_3_dsp_x,w3_3_dsp_y,
2607 w3_3_st_x,w3_3_st_y,lcdc_readl(lcdc_dev, WIN3_MST3)
2612 static int rk3288_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2615 struct lcdc_device *lcdc_dev =
2616 container_of(dev_drv, struct lcdc_device, driver);
2617 struct rk_screen *screen = dev_drv->cur_screen;
2622 u32 x_total, y_total;
2624 ft = div_u64(1000000000000llu, fps);
2626 screen->mode.upper_margin + screen->mode.lower_margin +
2627 screen->mode.yres + screen->mode.vsync_len;
2629 screen->mode.left_margin + screen->mode.right_margin +
2630 screen->mode.xres + screen->mode.hsync_len;
2631 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2632 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2633 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2636 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2637 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2638 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2639 screen->ft = 1000 / fps; /*one frame time in ms */
2642 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2643 clk_get_rate(lcdc_dev->dclk), fps);
2648 static int rk3288_fb_win_remap(struct rk_lcdc_driver *dev_drv,
2649 enum fb_win_map_order order)
2651 mutex_lock(&dev_drv->fb_win_id_mutex);
2652 if (order == FB_DEFAULT_ORDER)
2653 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3;
2654 dev_drv->fb3_win_id = order / 1000;
2655 dev_drv->fb2_win_id = (order / 100) % 10;
2656 dev_drv->fb1_win_id = (order / 10) % 10;
2657 dev_drv->fb0_win_id = order % 10;
2658 mutex_unlock(&dev_drv->fb_win_id_mutex);
2663 static int rk3288_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
2667 mutex_lock(&dev_drv->fb_win_id_mutex);
2668 if (!strcmp(id, "fb0") || !strcmp(id, "fb4"))
2669 win_id = dev_drv->fb0_win_id;
2670 else if (!strcmp(id, "fb1") || !strcmp(id, "fb5"))
2671 win_id = dev_drv->fb1_win_id;
2672 else if (!strcmp(id, "fb2") || !strcmp(id, "fb6"))
2673 win_id = dev_drv->fb2_win_id;
2674 else if (!strcmp(id, "fb3") || !strcmp(id, "fb7"))
2675 win_id = dev_drv->fb3_win_id;
2676 mutex_unlock(&dev_drv->fb_win_id_mutex);
2681 static int rk3288_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
2688 struct lcdc_device *lcdc_dev =
2689 container_of(dev_drv, struct lcdc_device, driver);
2690 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
2691 lcdc_cfg_done(lcdc_dev);
2693 if (dev_drv->cur_screen->dsp_lut) {
2694 for (i = 0; i < 256; i++) {
2695 v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
2696 c = lcdc_dev->dsp_lut_addr_base + i;
2697 writel_relaxed(v, c);
2701 dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
2704 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
2705 lcdc_cfg_done(lcdc_dev);
2710 static int rk3288_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2712 struct lcdc_device *lcdc_dev =
2713 container_of(dev_drv, struct lcdc_device, driver);
2714 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2715 v_DIRECT_PATH_EN(open));
2716 lcdc_cfg_done(lcdc_dev);
2720 static int rk3288_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2722 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2723 struct lcdc_device, driver);
2724 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
2725 v_DIRECT_PATCH_SEL(win_id));
2726 lcdc_cfg_done(lcdc_dev);
2731 static int rk3288_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2733 struct lcdc_device *lcdc_dev =
2734 container_of(dev_drv, struct lcdc_device, driver);
2735 int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2739 int rk3288_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2741 struct lcdc_device *lcdc_dev =
2742 container_of(dev_drv, struct lcdc_device, driver);
2746 if (lcdc_dev->clk_on) {
2747 int_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
2748 if (int_reg & m_LINE_FLAG_INTR_STS) {
2749 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
2750 v_LINE_FLAG_INTR_CLR(1));
2751 ret = RK_LF_STATUS_FC;
2753 ret = RK_LF_STATUS_FR;
2755 ret = RK_LF_STATUS_NC;
2760 static int rk3288_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
2762 struct lcdc_device *lcdc_dev =
2763 container_of(dev_drv, struct lcdc_device, driver);
2765 if(lcdc_dev->clk_on){
2766 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2767 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
2768 dsp_addr[2] = lcdc_readl(lcdc_dev, WIN2_MST0);
2769 dsp_addr[3] = lcdc_readl(lcdc_dev, WIN3_MST0);
2774 static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,int mode)
2776 struct lcdc_device *lcdc_dev =
2777 container_of(dev_drv, struct lcdc_device, driver);
2778 struct rk_screen *screen = dev_drv->cur_screen;
2779 int total_pixel,calc_pixel,stage_up,stage_down;
2782 u32 cabc_mode[5][3]={
2784 {2, 10, 10}, /*mode 1*/
2785 {4, 10, 10}, /*mode 2*/
2786 {6, 10, 10}, /*mode 3*/
2787 {8, 10, 10}, /*mode 4*/
2788 {10, 10, 10}, /*mode 5*/
2790 /*iomux connect to vop or pwm*/
2792 DBG(3,"close cabc\n");
2795 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
2798 total_pixel = screen->mode.xres * screen->mode.yres;
2799 calc_pixel = total_pixel * (100 - cabc_mode[mode-1][0])/100;
2800 stage_up = cabc_mode[mode-1][1];
2801 stage_down = cabc_mode[mode-1][2];
2803 spin_lock(&lcdc_dev->reg_lock);
2804 if(lcdc_dev->clk_on){
2805 mask = m_CABC_TOTAL_NUM | m_CABC_STAGE_DOWN;
2806 val = v_CABC_TOTAL_NUM(total_pixel) | v_CABC_STAGE_DOWN(stage_down);
2807 lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
2809 mask = m_CABC_EN | m_CABC_CALC_PIXEL_NUM |
2811 val = v_CABC_EN(1) | v_CABC_CALC_PIXEL_NUM(calc_pixel) |
2812 v_CABC_STAGE_UP(stage_up);
2813 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
2814 lcdc_cfg_done(lcdc_dev);
2816 spin_unlock(&lcdc_dev->reg_lock);
2820 Sin0=*0.000???????? Cos0=*1.000
2821 Sin5=*0.087???????C Cos5=*0.996
2822 Sin10=*0.174 Cos10=*0.985
2823 Sin15=*0.259 ???????CCos15=*0.966
2824 Sin20=*0.342????????Cos20=*0.940
2825 Sin25=*0.422????????Cos25=*0.906
2826 Sin30=*0.500????????Cos30=*0.866
2828 static int rk3288_lcdc_set_hue(struct rk_lcdc_driver *dev_drv,int hue)
2831 struct lcdc_device *lcdc_dev =
2832 container_of(dev_drv, struct lcdc_device, driver);
2833 int sin_hue_val,cos_hue_val;
2836 int sin_hue[7]={0,22, 44, 66, 87, 108, 128};
2837 int cos_hue[7]={256,254,252,247,240,231,221};
2839 if((hue > 0)&&(hue <= 30)){
2840 /*sin_hue_val = (int)sin_hue[hue] * 256;
2841 cos_hue_val = (int)cos_hue[hue] * 256;*/
2843 sin_hue_val = sin_hue[hue];
2844 cos_hue_val = cos_hue[hue];
2845 }else if((hue > 30)&&(hue <= 60)){
2848 /*sin_hue_val = (int)sin_hue[hue] * 256 + 0x100;
2849 cos_hue_val = (int)cos_hue[hue] * 256 + 0x100;*/
2850 sin_hue_val = sin_hue[hue] + 0x100;
2851 cos_hue_val = cos_hue[hue] + 0x100;
2853 dev_warn(lcdc_dev->dev,"hue=%d should be [0:60]\n",hue);
2856 spin_lock(&lcdc_dev->reg_lock);
2857 if(lcdc_dev->clk_on){
2859 mask = m_BCSH_OUT_MODE;
2860 val = v_BCSH_OUT_MODE(3);
2861 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2863 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
2864 val = v_BCSH_SIN_HUE(sin_hue_val) | v_BCSH_COS_HUE(cos_hue_val);
2865 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
2869 lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
2870 lcdc_cfg_done(lcdc_dev);
2872 spin_unlock(&lcdc_dev->reg_lock);
2877 static int rk3288_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,int bri,int con,int sat)
2879 struct lcdc_device *lcdc_dev =
2880 container_of(dev_drv, struct lcdc_device, driver);
2883 spin_lock(&lcdc_dev->reg_lock);
2884 if(lcdc_dev->clk_on){
2885 mask = m_BCSH_OUT_MODE | m_BCSH_BRIGHTNESS |
2886 m_BCSH_CONTRAST | m_BCSH_SAT_CON;
2887 val = v_BCSH_OUT_MODE(3) | v_BCSH_BRIGHTNESS(bri) |
2888 v_BCSH_CONTRAST(con) | v_BCSH_SAT_CON(sat);
2889 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2893 lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
2894 lcdc_cfg_done(lcdc_dev);
2896 spin_unlock(&lcdc_dev->reg_lock);
2901 static struct rk_lcdc_win lcdc_win[] = {
2905 .support_3d = false,
2910 .support_3d = false,
2915 .support_3d = false,
2920 .support_3d = false,
2924 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2925 .open = rk3288_lcdc_open,
2926 .load_screen = rk3288_load_screen,
2927 .set_par = rk3288_lcdc_set_par,
2928 .pan_display = rk3288_lcdc_pan_display,
2929 .lcdc_reg_update = rk3288_lcdc_reg_update,
2930 .blank = rk3288_lcdc_blank,
2931 .ioctl = rk3288_lcdc_ioctl,
2932 .suspend = rk3288_lcdc_early_suspend,
2933 .resume = rk3288_lcdc_early_resume,
2934 .get_win_state = rk3288_lcdc_get_win_state,
2935 .ovl_mgr = rk3288_lcdc_ovl_mgr,
2936 .get_disp_info = rk3288_lcdc_get_disp_info,
2937 .fps_mgr = rk3288_lcdc_fps_mgr,
2938 .fb_get_win_id = rk3288_lcdc_get_win_id,
2939 .fb_win_remap = rk3288_fb_win_remap,
2940 .set_dsp_lut = rk3288_set_dsp_lut,
2941 .poll_vblank = rk3288_lcdc_poll_vblank,
2942 .dpi_open = rk3288_lcdc_dpi_open,
2943 .dpi_win_sel = rk3288_lcdc_dpi_win_sel,
2944 .dpi_status = rk3288_lcdc_dpi_status,
2945 .get_dsp_addr = rk3288_lcdc_get_dsp_addr,
2946 .set_dsp_cabc = rk3288_lcdc_set_dsp_cabc,
2947 .set_dsp_hue = rk3288_lcdc_set_hue,
2948 .set_dsp_bcsh_bcs = rk3288_lcdc_set_bcsh_bcs,
2949 .dump_reg = rk3288_lcdc_reg_dump,
2951 static int rk3288_lcdc_parse_irq(struct lcdc_device *lcdc_dev,unsigned int reg_val)
2953 if (reg_val & m_WIN0_EMPTY_INTR_STS) {
2954 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN0_EMPTY_INTR_CLR,
2955 v_WIN0_EMPTY_INTR_CLR(1));
2956 dev_warn(lcdc_dev->dev,"win0 empty irq!");
2957 }else if (reg_val & m_WIN1_EMPTY_INTR_STS) {
2958 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN1_EMPTY_INTR_CLR,
2959 v_WIN1_EMPTY_INTR_CLR(1));
2960 dev_warn(lcdc_dev->dev,"win1 empty irq!");
2961 }else if (reg_val & m_WIN2_EMPTY_INTR_STS) {
2962 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN2_EMPTY_INTR_CLR,
2963 v_WIN2_EMPTY_INTR_CLR(1));
2964 dev_warn(lcdc_dev->dev,"win2 empty irq!");
2965 }else if (reg_val & m_WIN3_EMPTY_INTR_STS) {
2966 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN3_EMPTY_INTR_CLR,
2967 v_WIN3_EMPTY_INTR_CLR(1));
2968 dev_warn(lcdc_dev->dev,"win3 empty irq!");
2969 }else if (reg_val & m_HWC_EMPTY_INTR_STS) {
2970 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_HWC_EMPTY_INTR_CLR,
2971 v_HWC_EMPTY_INTR_CLR(1));
2972 dev_warn(lcdc_dev->dev,"HWC empty irq!");
2973 }else if (reg_val & m_POST_BUF_EMPTY_INTR_STS) {
2974 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_POST_BUF_EMPTY_INTR_CLR,
2975 v_POST_BUF_EMPTY_INTR_CLR(1));
2976 dev_warn(lcdc_dev->dev,"post buf empty irq!");
2977 }else if (reg_val & m_PWM_GEN_INTR_STS) {
2978 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_PWM_GEN_INTR_CLR,
2979 v_PWM_GEN_INTR_CLR(1));
2980 dev_warn(lcdc_dev->dev,"PWM gen irq!");
2985 static irqreturn_t rk3288_lcdc_isr(int irq, void *dev_id)
2987 struct lcdc_device *lcdc_dev =
2988 (struct lcdc_device *)dev_id;
2989 ktime_t timestamp = ktime_get();
2991 intr0_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
2993 if(intr0_reg & m_FS_INTR_STS){
2994 timestamp = ktime_get();
2995 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_FS_INTR_CLR,
2997 if(lcdc_dev->driver.wait_fs){
2998 spin_lock(&(lcdc_dev->driver.cpl_lock));
2999 complete(&(lcdc_dev->driver.frame_done));
3000 spin_unlock(&(lcdc_dev->driver.cpl_lock));
3002 lcdc_dev->driver.vsync_info.timestamp = timestamp;
3003 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
3005 }else if(intr0_reg & m_LINE_FLAG_INTR_STS){
3006 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
3007 v_LINE_FLAG_INTR_CLR(1));
3008 }else if(intr0_reg & m_BUS_ERROR_INTR_STS){
3009 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_BUS_ERROR_INTR_CLR,
3010 v_BUS_ERROR_INTR_CLR(1));
3011 dev_warn(lcdc_dev->dev,"buf_error_int!");
3016 intr1_reg = lcdc_readl(lcdc_dev, INTR_CTRL1);
3018 rk3288_lcdc_parse_irq(intr1_reg);
3024 #if defined(CONFIG_PM)
3025 static int rk3288_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
3030 static int rk3288_lcdc_resume(struct platform_device *pdev)
3035 #define rk3288_lcdc_suspend NULL
3036 #define rk3288_lcdc_resume NULL
3039 static int rk3288_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
3041 struct device_node *np = lcdc_dev->dev->of_node;
3043 if (of_property_read_u32(np, "rockchip,prop", &val))
3044 lcdc_dev->prop = PRMRY; /*default set it as primary */
3046 lcdc_dev->prop = val;
3048 if (of_property_read_u32(np, "rockchip,pwr18", &val))
3049 lcdc_dev->pwr18 = false; /*default set it as 3.xv power supply */
3051 lcdc_dev->pwr18 = (val ? true : false);
3055 static int rk3288_lcdc_probe(struct platform_device *pdev)
3057 struct lcdc_device *lcdc_dev = NULL;
3058 struct rk_lcdc_driver *dev_drv;
3059 struct device *dev = &pdev->dev;
3060 struct resource *res;
3061 struct device_node *np = pdev->dev.of_node;
3065 /*if the primary lcdc has not registered ,the extend
3066 lcdc register later */
3067 of_property_read_u32(np, "rockchip,prop", &prop);
3068 if (prop == EXTEND) {
3069 if (!is_prmry_rk_lcdc_registered())
3070 return -EPROBE_DEFER;
3072 lcdc_dev = devm_kzalloc(dev,
3073 sizeof(struct lcdc_device), GFP_KERNEL);
3075 dev_err(&pdev->dev, "rk3288 lcdc device kmalloc fail!");
3078 platform_set_drvdata(pdev, lcdc_dev);
3079 lcdc_dev->dev = dev;
3080 rk3288_lcdc_parse_dt(lcdc_dev);
3081 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3082 lcdc_dev->reg_phy_base = res->start;
3083 lcdc_dev->len = resource_size(res);
3084 lcdc_dev->regs = devm_ioremap_resource(dev, res);
3085 if (IS_ERR(lcdc_dev->regs))
3086 return PTR_ERR(lcdc_dev->regs);
3088 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
3089 if (IS_ERR(lcdc_dev->regsbak))
3090 return PTR_ERR(lcdc_dev->regsbak);
3091 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
3092 lcdc_dev->id = rk3288_lcdc_get_id(lcdc_dev->reg_phy_base);
3093 if (lcdc_dev->id < 0) {
3094 dev_err(&pdev->dev, "no such lcdc device!\n");
3097 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
3098 dev_drv = &lcdc_dev->driver;
3100 dev_drv->prop = prop;
3101 dev_drv->id = lcdc_dev->id;
3102 dev_drv->ops = &lcdc_drv_ops;
3103 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
3104 spin_lock_init(&lcdc_dev->reg_lock);
3106 lcdc_dev->irq = platform_get_irq(pdev, 0);
3107 if (lcdc_dev->irq < 0) {
3108 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
3113 ret = devm_request_irq(dev, lcdc_dev->irq, rk3288_lcdc_isr,
3114 IRQF_DISABLED, dev_name(dev), lcdc_dev);
3116 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
3117 lcdc_dev->irq, ret);
3121 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
3123 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
3126 lcdc_dev->screen = dev_drv->screen0;
3128 dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
3133 static int rk3288_lcdc_remove(struct platform_device *pdev)
3139 static void rk3288_lcdc_shutdown(struct platform_device *pdev)
3141 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
3143 rk3288_lcdc_deint(lcdc_dev);
3144 rk_disp_pwr_disable(&lcdc_dev->driver);
3147 #if defined(CONFIG_OF)
3148 static const struct of_device_id rk3288_lcdc_dt_ids[] = {
3149 {.compatible = "rockchip,rk3288-lcdc",},
3154 static struct platform_driver rk3288_lcdc_driver = {
3155 .probe = rk3288_lcdc_probe,
3156 .remove = rk3288_lcdc_remove,
3158 .name = "rk3288-lcdc",
3159 .owner = THIS_MODULE,
3160 .of_match_table = of_match_ptr(rk3288_lcdc_dt_ids),
3162 .suspend = rk3288_lcdc_suspend,
3163 .resume = rk3288_lcdc_resume,
3164 .shutdown = rk3288_lcdc_shutdown,
3167 static int __init rk3288_lcdc_module_init(void)
3169 return platform_driver_register(&rk3288_lcdc_driver);
3172 static void __exit rk3288_lcdc_module_exit(void)
3174 platform_driver_unregister(&rk3288_lcdc_driver);
3177 fs_initcall(rk3288_lcdc_module_init);
3178 module_exit(rk3288_lcdc_module_exit);