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>
35 #include "rk3288_lcdc.h"
37 #if defined(CONFIG_HAS_EARLYSUSPEND)
38 #include <linux/earlysuspend.h>
41 static int dbg_thresd;
42 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
44 #define DBG(level, x...) do { \
45 if (unlikely(dbg_thresd >= level)) \
46 printk(KERN_INFO x); } while (0)
48 /*#define WAIT_FOR_SYNC 1*/
50 static int rk3288_lcdc_get_id(u32 phy_base)
52 if (cpu_is_rk3288()) {
53 if (phy_base == 0xff930000)/*vop big*/
55 else if (phy_base == 0xff940000)/*vop lit*/
60 pr_err("un supported platform \n");
65 static int rk3288_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
70 struct lcdc_device *lcdc_dev = container_of(dev_drv,
74 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
75 lcdc_cfg_done(lcdc_dev);
77 for (i = 0; i < 256; i++) {
78 v = dev_drv->cur_screen->dsp_lut[i];
79 c = lcdc_dev->dsp_lut_addr_base + i;
83 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
89 static int rk3288_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
95 if (!lcdc_dev->clk_on) {
96 clk_prepare_enable(lcdc_dev->hclk);
97 clk_prepare_enable(lcdc_dev->dclk);
98 clk_prepare_enable(lcdc_dev->aclk);
99 /*clk_enable(lcdc_dev->pd);*/
100 spin_lock(&lcdc_dev->reg_lock);
101 lcdc_dev->clk_on = 1;
102 spin_unlock(&lcdc_dev->reg_lock);
108 static int rk3288_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
110 #ifdef CONFIG_RK_FPGA
111 lcdc_dev->clk_on = 0;
114 if (lcdc_dev->clk_on) {
115 spin_lock(&lcdc_dev->reg_lock);
116 lcdc_dev->clk_on = 0;
117 spin_unlock(&lcdc_dev->reg_lock);
119 clk_disable_unprepare(lcdc_dev->dclk);
120 clk_disable_unprepare(lcdc_dev->hclk);
121 clk_disable_unprepare(lcdc_dev->aclk);
122 /*clk_disable(lcdc_dev->pd);*/
128 static int rk3288_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
131 spin_lock(&lcdc_dev->reg_lock);
132 if (likely(lcdc_dev->clk_on)) {
133 mask = m_DSP_HOLD_VALID_INTR_EN | m_FS_INTR_EN |
134 m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_EN;
135 val = v_DSP_HOLD_VALID_INTR_EN(0) | v_FS_INTR_EN(0) |
136 v_LINE_FLAG_INTR_EN(0) | v_BUS_ERROR_INTR_EN(0);
137 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
139 mask = m_DSP_HOLD_VALID_INTR_CLR | m_FS_INTR_CLR |
140 m_LINE_FLAG_INTR_CLR | m_LINE_FLAG_INTR_CLR;
141 val = v_DSP_HOLD_VALID_INTR_CLR(0) | v_FS_INTR_CLR(0) |
142 v_LINE_FLAG_INTR_CLR(0) | v_BUS_ERROR_INTR_CLR(0);
143 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
145 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
146 m_WIN2_EMPTY_INTR_EN | m_WIN3_EMPTY_INTR_EN |
147 m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
148 m_POST_BUF_EMPTY_INTR_EN;
149 val = v_WIN0_EMPTY_INTR_EN(0) | v_WIN1_EMPTY_INTR_EN(0) |
150 v_WIN2_EMPTY_INTR_EN(0) | v_WIN3_EMPTY_INTR_EN(0) |
151 v_HWC_EMPTY_INTR_EN(0) | v_POST_BUF_EMPTY_INTR_EN(0) |
152 v_PWM_GEN_INTR_EN(0);
153 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
155 mask = m_WIN0_EMPTY_INTR_CLR | m_WIN1_EMPTY_INTR_CLR |
156 m_WIN2_EMPTY_INTR_CLR | m_WIN3_EMPTY_INTR_CLR |
157 m_HWC_EMPTY_INTR_CLR | m_POST_BUF_EMPTY_INTR_CLR |
158 m_POST_BUF_EMPTY_INTR_CLR;
159 val = v_WIN0_EMPTY_INTR_CLR(0) | v_WIN1_EMPTY_INTR_CLR(0) |
160 v_WIN2_EMPTY_INTR_CLR(0) | v_WIN3_EMPTY_INTR_CLR(0) |
161 v_HWC_EMPTY_INTR_CLR(0) | v_POST_BUF_EMPTY_INTR_CLR(0) |
162 v_PWM_GEN_INTR_CLR(0);
163 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
164 lcdc_cfg_done(lcdc_dev);
165 spin_unlock(&lcdc_dev->reg_lock);
167 spin_unlock(&lcdc_dev->reg_lock);
172 static int rk3288_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
174 struct lcdc_device *lcdc_dev = container_of(dev_drv,
177 int *cbase = (int *)lcdc_dev->regs;
178 int *regsbak = (int *)lcdc_dev->regsbak;
181 printk("back up reg:\n");
182 for (i = 0; i <= (0x200 >> 4); i++) {
183 printk("0x%04x: ",i*16);
184 for (j = 0; j < 4; j++)
185 printk("%08x ", *(regsbak + i * 4 + j));
189 printk("lcdc reg:\n");
190 for (i = 0; i <= (0x200 >> 4); i++) {
191 printk("0x%04x: ",i*16);
192 for (j = 0; j < 4; j++)
193 printk("%08x ", readl_relaxed(cbase + i * 4 + j));
200 /********do basic init*********/
201 static int rk3288_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
204 struct lcdc_device *lcdc_dev = container_of(dev_drv,
208 int *cbase = (int *)lcdc_dev->regs;
209 if (lcdc_dev->pre_init)
211 #ifdef CONFIG_RK_FPGA
212 lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
213 lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
214 lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
216 if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
217 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
218 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
222 /*uboot display has enabled lcdc in boot */
223 if (!support_uboot_display()) {
224 rk_disp_pwr_enable(dev_drv);
225 rk3288_lcdc_clk_enable(lcdc_dev);
227 lcdc_dev->clk_on = 1;
230 /*rk3288_lcdc_read_reg_defalut_cfg(lcdc_dev);*/
231 for (i = 0; i <= (0x200 >> 4); i++) {
232 for (j = 0; j < 4; j++)
233 readl_relaxed(cbase + i * 4 + j);
236 #ifndef CONFIG_RK_FPGA
237 if (lcdc_dev->pwr18 == true) {
238 v = 0x00010001; /*bit14: 1,1.8v;0,3.3v*/
239 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
242 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
245 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN);
246 lcdc_cfg_done(lcdc_dev);
247 lcdc_dev->pre_init = true;
252 static void rk3288_lcdc_deint(struct lcdc_device *lcdc_dev)
256 rk3288_lcdc_disable_irq(lcdc_dev);
257 spin_lock(&lcdc_dev->reg_lock);
258 if (likely(lcdc_dev->clk_on)) {
259 lcdc_dev->clk_on = 0;
260 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_STANDBY_EN);
261 lcdc_cfg_done(lcdc_dev);
262 spin_unlock(&lcdc_dev->reg_lock);
264 spin_unlock(&lcdc_dev->reg_lock);
268 static int rk3288_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv)
270 struct lcdc_device *lcdc_dev =
271 container_of(dev_drv, struct lcdc_device, driver);
272 struct rk_screen *screen = dev_drv->cur_screen;
273 u16 x_res = screen->mode.xres;
274 u16 y_res = screen->mode.yres;
277 u16 post_hsd_en,post_vsd_en;
278 u16 post_dsp_hact_st,post_dsp_hact_end;
279 u16 post_dsp_vact_st,post_dsp_vact_end;
280 u16 post_dsp_vact_st_f1,post_dsp_vact_end_f1;
281 u16 post_h_fac,post_v_fac;
283 h_total = screen->mode.hsync_len+screen->mode.left_margin +
284 x_res + screen->mode.right_margin;
285 v_total = screen->mode.vsync_len+screen->mode.upper_margin +
286 y_res + screen->mode.lower_margin;
288 if(screen->post_dsp_stx + screen->post_xsize > x_res){
289 dev_warn(lcdc_dev->dev, "post:stx[%d] + xsize[%d] > x_res[%d]\n",
290 screen->post_dsp_stx,screen->post_xsize,x_res);
291 screen->post_dsp_stx = x_res - screen->post_xsize;
293 if(screen->x_mirror == 0){
294 post_dsp_hact_st=screen->post_dsp_stx +
295 screen->mode.hsync_len+screen->mode.left_margin;
296 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
298 post_dsp_hact_end = h_total - screen->mode.right_margin -
299 screen->post_dsp_stx;
300 post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
302 if((screen->post_xsize < x_res)&&(screen->post_xsize != 0)){
305 GET_SCALE_FACTOR_BILI_DN(x_res , screen->post_xsize);
312 if(screen->post_dsp_sty + screen->post_ysize > y_res){
313 dev_warn(lcdc_dev->dev, "post:sty[%d] + ysize[%d] > y_res[%d]\n",
314 screen->post_dsp_sty,screen->post_ysize,y_res);
315 screen->post_dsp_sty = y_res - screen->post_ysize;
318 if(screen->y_mirror == 0){
319 post_dsp_vact_st = screen->post_dsp_sty +
320 screen->mode.vsync_len+screen->mode.upper_margin;
321 post_dsp_vact_end = post_dsp_vact_st + screen->post_ysize;
323 post_dsp_vact_end = v_total - screen->mode.lower_margin -
324 - screen->post_dsp_sty;
325 post_dsp_hact_st = post_dsp_vact_end - screen->post_ysize;
327 if((screen->post_ysize < y_res)&&(screen->post_ysize != 0)){
329 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res, screen->post_ysize);
335 if(screen->interlace == 1){
336 post_dsp_vact_st_f1 = v_total + post_dsp_vact_st;
337 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 + screen->post_ysize;
339 post_dsp_vact_st_f1 = 0;
340 post_dsp_vact_end_f1 = 0;
342 DBG(1,"post:xsize=%d,ysize=%d,xpos=%d,ypos=%d,"
343 "hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
344 screen->post_xsize,screen->post_ysize,screen->xpos,screen->ypos,
345 post_hsd_en,post_h_fac,post_vsd_en,post_v_fac);
346 mask = m_DSP_HACT_END_POST | m_DSP_HACT_ST_POST;
347 val = v_DSP_HACT_END_POST(post_dsp_hact_end) |
348 v_DSP_HACT_ST_POST(post_dsp_hact_st);
349 lcdc_msk_reg(lcdc_dev, POST_DSP_HACT_INFO, mask, val);
351 mask = m_DSP_VACT_END_POST | m_DSP_VACT_ST_POST;
352 val = v_DSP_VACT_END_POST(post_dsp_vact_end) |
353 v_DSP_VACT_ST_POST(post_dsp_vact_st);
354 lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO, mask, val);
356 mask = m_POST_HS_FACTOR_YRGB | m_POST_VS_FACTOR_YRGB;
357 val = v_POST_HS_FACTOR_YRGB(post_h_fac) |
358 v_POST_VS_FACTOR_YRGB(post_v_fac);
359 lcdc_msk_reg(lcdc_dev, POST_SCL_FACTOR_YRGB, mask, val);
361 mask = m_DSP_VACT_END_POST_F1 | m_DSP_VACT_ST_POST_F1;
362 val = v_DSP_VACT_END_POST_F1(post_dsp_vact_end_f1) |
363 v_DSP_VACT_ST_POST_F1(post_dsp_vact_st_f1);
364 lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO_F1, mask, val);
366 mask = m_POST_HOR_SD_EN | m_POST_VER_SD_EN;
367 val = v_POST_HOR_SD_EN(post_hsd_en) | v_POST_VER_SD_EN(post_vsd_en);
368 lcdc_msk_reg(lcdc_dev, POST_SCL_CTRL, mask, val);
372 static int rk3288_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
374 struct lcdc_device *lcdc_dev = container_of(dev_drv,
378 struct rk_lcdc_win *win;
379 u32 colorkey_r,colorkey_g,colorkey_b;
382 win = dev_drv->win[i];
383 key_val = win->color_key_val;
384 colorkey_r = (key_val & 0xff)<<2;
385 colorkey_g = ((key_val>>8)&0xff)<<12;
386 colorkey_b = ((key_val>>16)&0xff)<<22;
387 /*color key dither 565/888->aaa*/
388 key_val = colorkey_r | colorkey_g | colorkey_b;
391 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY, key_val);
394 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY, key_val);
397 lcdc_writel(lcdc_dev, WIN2_COLOR_KEY, key_val);
400 lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val);
403 printk(KERN_WARNING "%s:un support win num:%d\n",
411 static int rk3288_lcdc_alpha_cfg(struct rk_lcdc_driver *dev_drv,int win_id)
413 struct lcdc_device *lcdc_dev =
414 container_of(dev_drv, struct lcdc_device, driver);
415 struct rk_lcdc_win *win = dev_drv->win[win_id];
416 struct alpha_config alpha_config;
419 int ppixel_alpha,global_alpha;
420 u32 src_alpha_ctl,dst_alpha_ctl;
421 ppixel_alpha = ((win->format == ARGB888)||(win->format == ABGR888)) ? 1 : 0;
422 global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
423 alpha_config.src_global_alpha_val = win->g_alpha_val;
424 switch(win->alpha_mode){
428 alpha_config.src_factor_mode=AA_ZERO;
429 alpha_config.dst_factor_mode=AA_ZERO;
432 alpha_config.src_factor_mode=AA_ONE;
433 alpha_config.dst_factor_mode=AA_ZERO;
436 alpha_config.src_factor_mode=AA_ZERO;
437 alpha_config.dst_factor_mode=AA_ONE;
440 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
441 alpha_config.src_factor_mode=AA_ONE;
442 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
445 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
446 alpha_config.src_factor_mode=AA_SRC_INVERSE;
447 alpha_config.dst_factor_mode=AA_ONE;
450 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
451 alpha_config.src_factor_mode=AA_SRC;
452 alpha_config.dst_factor_mode=AA_ZERO;
455 alpha_config.src_factor_mode=AA_ZERO;
456 alpha_config.dst_factor_mode=AA_SRC;
459 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
460 alpha_config.src_factor_mode=AA_SRC_INVERSE;
461 alpha_config.dst_factor_mode=AA_ZERO;
464 alpha_config.src_factor_mode=AA_ZERO;
465 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
468 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
469 alpha_config.src_factor_mode=AA_SRC;
470 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
473 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
474 alpha_config.src_factor_mode=AA_SRC_INVERSE;
475 alpha_config.dst_factor_mode=AA_SRC;
478 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
479 alpha_config.src_factor_mode=AA_SRC_INVERSE;
480 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
482 case AB_SRC_OVER_GLOBAL:
483 alpha_config.src_global_alpha_mode=AA_PER_PIX_GLOBAL;
484 alpha_config.src_color_mode=AA_SRC_NO_PRE_MUL;
485 alpha_config.src_factor_mode=AA_SRC_GLOBAL;
486 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
489 pr_err("alpha mode error\n");
492 if((ppixel_alpha == 1)&&(global_alpha == 1)){
493 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
494 }else if(ppixel_alpha == 1){
495 alpha_config.src_global_alpha_mode = AA_PER_PIX;
496 }else if(global_alpha == 1){
497 alpha_config.src_global_alpha_mode = AA_GLOBAL;
499 dev_warn(lcdc_dev->dev,"alpha_en should be 0\n");
501 alpha_config.src_alpha_mode = AA_STRAIGHT;
502 alpha_config.src_alpha_sel = AA_NO_SAT;
506 src_alpha_ctl = 0x60;
507 dst_alpha_ctl = 0x64;
510 src_alpha_ctl = 0xa0;
511 dst_alpha_ctl = 0xa4;
514 src_alpha_ctl = 0xdc;
515 dst_alpha_ctl = 0xec;
518 src_alpha_ctl = 0x12c;
519 dst_alpha_ctl = 0x13c;
522 mask = m_WIN0_DST_FACTOR_M0;
523 val = v_WIN0_DST_FACTOR_M0(alpha_config.dst_factor_mode);
524 lcdc_msk_reg(lcdc_dev, dst_alpha_ctl, mask, val);
525 mask = m_WIN0_SRC_ALPHA_EN | m_WIN0_SRC_COLOR_M0 |
526 m_WIN0_SRC_ALPHA_M0 | m_WIN0_SRC_BLEND_M0 |
527 m_WIN0_SRC_ALPHA_CAL_M0 | m_WIN0_SRC_FACTOR_M0|
528 m_WIN0_SRC_GLOBAL_ALPHA;
529 val = v_WIN0_SRC_ALPHA_EN(1) |
530 v_WIN0_SRC_COLOR_M0(alpha_config.src_color_mode) |
531 v_WIN0_SRC_ALPHA_M0(alpha_config.src_alpha_mode) |
532 v_WIN0_SRC_BLEND_M0(alpha_config.src_global_alpha_mode) |
533 v_WIN0_SRC_FACTOR_M0(alpha_config.src_factor_mode) |
534 v_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
535 lcdc_msk_reg(lcdc_dev, src_alpha_ctl, mask, val);
540 static int rk3288_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
542 struct lcdc_device *lcdc_dev =
543 container_of(dev_drv, struct lcdc_device, driver);
544 struct rk_lcdc_win *win = dev_drv->win[win_id];
545 unsigned int mask, val, off;
549 mask = m_WIN0_EN | m_WIN0_DATA_FMT | m_WIN0_FMT_10 |
550 m_WIN0_LB_MODE | m_WIN0_RB_SWAP;
551 val = v_WIN0_EN(win->state) | v_WIN0_DATA_FMT(win->fmt_cfg) |
552 v_WIN0_FMT_10(win->fmt_10) |
553 v_WIN0_LB_MODE(win->win_lb_mode) |
554 v_WIN0_RB_SWAP(win->swap_rb);
555 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val);
557 mask = m_WIN0_BIC_COE_SEL |
558 m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
559 m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT4 |
560 m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
561 m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
562 m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
563 m_WIN0_CBR_VER_SCL_MODE | m_WIN0_CBR_HSD_MODE |
564 m_WIN0_CBR_VSU_MODE | m_WIN0_CBR_VSD_MODE;
565 val = v_WIN0_BIC_COE_SEL(win->bic_coe_el) |
566 v_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
567 v_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
568 v_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
569 v_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
570 v_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
571 v_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
572 v_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
573 v_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
574 v_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
575 v_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
576 v_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
577 v_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
578 v_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
579 v_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
580 lcdc_msk_reg(lcdc_dev, WIN0_CTRL1+off, mask,val);
582 val = v_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
583 v_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
584 lcdc_writel(lcdc_dev, WIN0_VIR+off, val);
585 /*lcdc_writel(lcdc_dev, WIN0_YRGB_MST+off, win->area[0].y_addr);
586 lcdc_writel(lcdc_dev, WIN0_CBR_MST+off, win->area[0].uv_addr);*/
587 val = v_WIN0_ACT_WIDTH(win->area[0].xact) |
588 v_WIN0_ACT_HEIGHT(win->area[0].yact);
589 lcdc_writel(lcdc_dev, WIN0_ACT_INFO+off, val);
591 val = v_WIN0_DSP_WIDTH(win->area[0].xsize) |
592 v_WIN0_DSP_HEIGHT(win->area[0].ysize);
593 lcdc_writel(lcdc_dev, WIN0_DSP_INFO+off, val);
595 val = v_WIN0_DSP_XST(win->area[0].dsp_stx) |
596 v_WIN0_DSP_YST(win->area[0].dsp_sty);
597 lcdc_writel(lcdc_dev, WIN0_DSP_ST+off, val);
599 val = v_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
600 v_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
601 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB+off, val);
603 val = v_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
604 v_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
605 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR+off, val);
606 if(win->alpha_en == 1)
607 rk3288_lcdc_alpha_cfg(dev_drv,win_id);
609 mask = m_WIN0_SRC_ALPHA_EN;
610 val = v_WIN0_SRC_ALPHA_EN(0);
611 lcdc_msk_reg(lcdc_dev,WIN0_SRC_ALPHA_CTRL+off,mask,val);
616 val = v_WIN0_EN(win->state);
617 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val);
622 static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
624 struct lcdc_device *lcdc_dev =
625 container_of(dev_drv, struct lcdc_device, driver);
626 struct rk_lcdc_win *win = dev_drv->win[win_id];
627 unsigned int mask, val, off;
628 off = (win_id-2) * 0x50;
631 mask = m_WIN2_EN | m_WIN2_DATA_FMT | m_WIN2_RB_SWAP;
632 val = v_WIN2_EN(1) | v_WIN2_DATA_FMT(win->fmt_cfg) |
633 v_WIN2_RB_SWAP(win->swap_rb);
634 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
636 if(win->area[0].state == 1){
637 mask = m_WIN2_MST0_EN;
638 val = v_WIN2_MST0_EN(1);
639 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
641 mask = m_WIN2_VIR_STRIDE0;
642 val = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
643 lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
645 /*lcdc_writel(lcdc_dev,WIN2_MST0+off,win->area[0].y_addr);*/
646 val = v_WIN2_DSP_WIDTH0(win->area[0].xsize) |
647 v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
648 lcdc_writel(lcdc_dev,WIN2_DSP_INFO0+off,val);
649 val = v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
650 v_WIN2_DSP_YST0(win->area[0].dsp_sty);
651 lcdc_writel(lcdc_dev,WIN2_DSP_ST0+off,val);
653 mask = m_WIN2_MST0_EN;
654 val = v_WIN2_MST0_EN(0);
655 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
658 if(win->area[1].state == 1){
659 mask = m_WIN2_MST1_EN;
660 val = v_WIN2_MST1_EN(1);
661 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
663 mask = m_WIN2_VIR_STRIDE1;
664 val = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
665 lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
667 /*lcdc_writel(lcdc_dev,WIN2_MST1+off,win->area[1].y_addr);*/
668 val = v_WIN2_DSP_WIDTH1(win->area[1].xsize) |
669 v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
670 lcdc_writel(lcdc_dev,WIN2_DSP_INFO1+off,val);
671 val = v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
672 v_WIN2_DSP_YST1(win->area[1].dsp_sty);
673 lcdc_writel(lcdc_dev,WIN2_DSP_ST1+off,val);
675 mask = m_WIN2_MST1_EN;
676 val = v_WIN2_MST1_EN(0);
677 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
680 if(win->area[2].state == 1){
681 mask = m_WIN2_MST2_EN;
682 val = v_WIN2_MST2_EN(1);
683 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
685 mask = m_WIN2_VIR_STRIDE2;
686 val = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
687 lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
689 /*lcdc_writel(lcdc_dev,WIN2_MST2+off,win->area[2].y_addr);*/
690 val = v_WIN2_DSP_WIDTH2(win->area[2].xsize) |
691 v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
692 lcdc_writel(lcdc_dev,WIN2_DSP_INFO2+off,val);
693 val = v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
694 v_WIN2_DSP_YST2(win->area[2].dsp_sty);
695 lcdc_writel(lcdc_dev,WIN2_DSP_ST2+off,val);
697 mask = m_WIN2_MST2_EN;
698 val = v_WIN2_MST2_EN(0);
699 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
702 if(win->area[3].state == 1){
703 mask = m_WIN2_MST3_EN;
704 val = v_WIN2_MST3_EN(1);
705 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
707 mask = m_WIN2_VIR_STRIDE3;
708 val = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
709 lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
711 /*lcdc_writel(lcdc_dev,WIN2_MST3+off,win->area[3].y_addr);*/
712 val = v_WIN2_DSP_WIDTH3(win->area[3].xsize) |
713 v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
714 lcdc_writel(lcdc_dev,WIN2_DSP_INFO3+off,val);
715 val = v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
716 v_WIN2_DSP_YST3(win->area[3].dsp_sty);
717 lcdc_writel(lcdc_dev,WIN2_DSP_ST3+off,val);
719 mask = m_WIN2_MST3_EN;
720 val = v_WIN2_MST3_EN(0);
721 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
724 if(win->alpha_en == 1)
725 rk3288_lcdc_alpha_cfg(dev_drv,win_id);
727 mask = m_WIN2_SRC_ALPHA_EN;
728 val = v_WIN2_SRC_ALPHA_EN(0);
729 lcdc_msk_reg(lcdc_dev,WIN2_SRC_ALPHA_CTRL+off,mask,val);
732 mask = m_WIN2_EN | m_WIN2_MST0_EN |
733 m_WIN2_MST0_EN | m_WIN2_MST2_EN |
735 val = v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
736 v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) |
738 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0+off, mask,val);
743 static int rk3288_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
745 struct lcdc_device *lcdc_dev =
746 container_of(dev_drv, struct lcdc_device, driver);
750 spin_lock(&lcdc_dev->reg_lock);
751 if(likely(lcdc_dev->clk_on))
753 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
754 v_STANDBY_EN(lcdc_dev->standby));
755 rk3288_win_0_1_reg_update(dev_drv,0);
756 rk3288_win_0_1_reg_update(dev_drv,1);
757 rk3288_win_2_3_reg_update(dev_drv,2);
758 rk3288_win_2_3_reg_update(dev_drv,3);
759 /*rk3288_lcdc_post_cfg(dev_drv);*/
760 lcdc_cfg_done(lcdc_dev);
762 spin_unlock(&lcdc_dev->reg_lock);
764 /*if (dev_drv->wait_fs) {*/
766 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
767 init_completion(&dev_drv->frame_done);
768 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
769 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
771 (dev_drv->cur_screen->ft +
773 if (!timeout && (!dev_drv->frame_done.done)) {
774 dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
778 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
783 static int rk3288_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
785 memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x84);
789 static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
795 struct lcdc_device *lcdc_dev =
796 container_of(dev_drv, struct lcdc_device, driver);
797 struct rk_screen *screen = dev_drv->cur_screen;
798 u16 hsync_len = screen->mode.hsync_len;
799 u16 left_margin = screen->mode.left_margin;
800 u16 right_margin = screen->mode.right_margin;
801 u16 vsync_len = screen->mode.vsync_len;
802 u16 upper_margin = screen->mode.upper_margin;
803 u16 lower_margin = screen->mode.lower_margin;
804 u16 x_res = screen->mode.xres;
805 u16 y_res = screen->mode.yres;
809 h_total = hsync_len + left_margin + x_res + right_margin;
810 v_total = vsync_len + upper_margin + y_res + lower_margin;
811 screen->post_dsp_stx=0;
812 screen->post_dsp_sty=0;
813 screen->post_xsize =x_res;
814 screen->post_ysize = y_res;
816 spin_lock(&lcdc_dev->reg_lock);
817 if (likely(lcdc_dev->clk_on)) {
818 switch (screen->face) {
821 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
823 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
824 v_DITHER_DOWN_SEL(1);
825 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
829 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
831 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
832 v_DITHER_DOWN_SEL(1);
833 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
837 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
839 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
840 v_DITHER_DOWN_SEL(1);
841 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
845 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
847 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
848 v_DITHER_DOWN_SEL(1);
849 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
853 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
854 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
855 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
858 dev_err(lcdc_dev->dev,"un supported interface!\n");
861 switch(screen->type){
864 case SCREEN_DUAL_LVDS:
866 val = v_RGB_OUT_EN(1);
868 v |= (lcdc_dev->id << 3);
871 mask = m_HDMI_OUT_EN;
872 val = v_HDMI_OUT_EN(1);
874 v |= (lcdc_dev->id << 4);*/
877 mask = m_MIPI_OUT_EN;
878 val = v_MIPI_OUT_EN(1);
879 /*v = (1 << (6+16))||(1 << (9+16));
880 v |= (lcdc_dev->id << 6);
881 v |= (lcdc_dev->id << 9);*/
883 case SCREEN_DUAL_MIPI:
884 mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN;
885 val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1);
886 /*v = (1 << (6+16))||(1 << (9+16));
887 v |= (lcdc_dev->id << 6);
888 v |= (lcdc_dev->id << 9);*/
891 face = OUT_RGB_AAA; /*RGB AAA output*/
892 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
893 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
894 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
896 val = v_EDP_OUT_EN(1);
898 v |= (lcdc_dev->id << 5);*/
901 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
905 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
906 mask = m_AXI_MAX_OUTSTANDING_EN | m_AXI_OUTSTANDING_MAX_NUM;
907 val = v_AXI_OUTSTANDING_MAX_NUM(31) | v_AXI_MAX_OUTSTANDING_EN(1);
908 lcdc_msk_reg(lcdc_dev, SYS_CTRL1, mask, val);
910 #ifndef CONFIG_RK_FPGA
911 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
913 mask = m_DSP_OUT_MODE | m_DSP_HSYNC_POL | m_DSP_VSYNC_POL |
914 m_DSP_DEN_POL | m_DSP_DCLK_POL | m_DSP_BG_SWAP |
915 m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
916 m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN |
917 m_DSP_BLACK_EN | m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN;
918 val = v_DSP_OUT_MODE(face) | v_DSP_HSYNC_POL(screen->pin_hsync) |
919 v_DSP_VSYNC_POL(screen->pin_vsync) |
920 v_DSP_DEN_POL(screen->pin_den) | v_DSP_DCLK_POL(screen->pin_dclk) |
921 v_DSP_BG_SWAP(screen->swap_gb) | v_DSP_RB_SWAP(screen->swap_rb) |
922 v_DSP_RG_SWAP(screen->swap_rg) |
923 v_DSP_DELTA_SWAP(screen->swap_delta) |
924 v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) |
925 v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0) |
926 v_DSP_X_MIR_EN(screen->x_mirror) | v_DSP_Y_MIR_EN(screen->y_mirror);
927 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
929 mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
930 val = v_DSP_BG_BLUE(0x3ff) | v_DSP_BG_GREEN(0) | v_DSP_BG_RED(0);
931 lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
933 mask = m_DSP_HS_PW | m_DSP_HTOTAL;
934 val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
935 lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
937 mask = m_DSP_HACT_END | m_DSP_HACT_ST;
938 val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
939 v_DSP_HACT_ST(hsync_len + left_margin);
940 lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
942 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
943 val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
944 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
946 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
947 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
948 v_DSP_VACT_ST(vsync_len + upper_margin);
949 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
951 rk3288_lcdc_post_cfg(dev_drv);
953 spin_unlock(&lcdc_dev->reg_lock);
955 #ifndef CONFIG_RK_FPGA
956 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
958 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
960 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
961 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
963 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
964 screen->ft = 1000 / fps;
965 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
966 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
967 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
968 dev_drv->trsm_ops->enable();
975 /*enable layer,open:1,enable;0 disable*/
976 static int win0_open(struct lcdc_device *lcdc_dev, bool open)
978 spin_lock(&lcdc_dev->reg_lock);
979 if (likely(lcdc_dev->clk_on)) {
981 if (!lcdc_dev->atv_layer_cnt) {
982 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
983 lcdc_dev->standby = 0;
985 lcdc_dev->atv_layer_cnt++;
986 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
987 lcdc_dev->atv_layer_cnt--;
989 lcdc_dev->driver.win[0]->state = open;
990 if (!lcdc_dev->atv_layer_cnt) {
991 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
992 lcdc_dev->standby = 1;
995 spin_unlock(&lcdc_dev->reg_lock);
1000 static int win1_open(struct lcdc_device *lcdc_dev, bool open)
1002 spin_lock(&lcdc_dev->reg_lock);
1003 if (likely(lcdc_dev->clk_on)) {
1005 if (!lcdc_dev->atv_layer_cnt) {
1006 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1007 lcdc_dev->standby = 0;
1009 lcdc_dev->atv_layer_cnt++;
1010 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1011 lcdc_dev->atv_layer_cnt--;
1013 lcdc_dev->driver.win[1]->state = open;
1015 /*if no layer used,disable lcdc*/
1016 if (!lcdc_dev->atv_layer_cnt) {
1017 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1018 lcdc_dev->standby = 1;
1021 spin_unlock(&lcdc_dev->reg_lock);
1026 static int win2_open(struct lcdc_device *lcdc_dev, bool open)
1028 spin_lock(&lcdc_dev->reg_lock);
1029 if (likely(lcdc_dev->clk_on)) {
1031 if (!lcdc_dev->atv_layer_cnt) {
1032 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1033 lcdc_dev->standby = 0;
1035 lcdc_dev->atv_layer_cnt++;
1036 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1037 lcdc_dev->atv_layer_cnt--;
1039 lcdc_dev->driver.win[2]->state = open;
1041 /*if no layer used,disable lcdc*/
1042 if (!lcdc_dev->atv_layer_cnt) {
1043 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1044 lcdc_dev->standby = 1;
1047 spin_unlock(&lcdc_dev->reg_lock);
1052 static int win3_open(struct lcdc_device *lcdc_dev, bool open)
1054 spin_lock(&lcdc_dev->reg_lock);
1055 if (likely(lcdc_dev->clk_on)) {
1057 if (!lcdc_dev->atv_layer_cnt) {
1058 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1059 lcdc_dev->standby = 0;
1061 lcdc_dev->atv_layer_cnt++;
1062 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1063 lcdc_dev->atv_layer_cnt--;
1065 lcdc_dev->driver.win[3]->state = open;
1067 /*if no layer used,disable lcdc*/
1068 if (!lcdc_dev->atv_layer_cnt) {
1069 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1070 lcdc_dev->standby = 1;
1073 spin_unlock(&lcdc_dev->reg_lock);
1079 static int rk3288_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1082 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1083 struct lcdc_device, driver);
1085 /*enable clk,when first layer open */
1086 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1087 rk3288_lcdc_pre_init(dev_drv);
1088 rk3288_lcdc_clk_enable(lcdc_dev);
1089 rk3288_lcdc_reg_restore(lcdc_dev);
1090 rk3288_load_screen(dev_drv, 1);
1091 spin_lock(&lcdc_dev->reg_lock);
1092 if (dev_drv->cur_screen->dsp_lut)
1093 rk3288_lcdc_set_lut(dev_drv);
1094 spin_unlock(&lcdc_dev->reg_lock);
1098 win0_open(lcdc_dev, open);
1099 else if (win_id == 1)
1100 win1_open(lcdc_dev, open);
1101 else if (win_id == 2)
1102 win2_open(lcdc_dev, open);
1103 else if (win_id == 3)
1104 win3_open(lcdc_dev, open);
1106 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1108 /*when all layer closed,disable clk */
1109 if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1110 rk3288_lcdc_disable_irq(lcdc_dev);
1111 rk3288_lcdc_reg_update(dev_drv);
1112 rk3288_lcdc_clk_disable(lcdc_dev);
1118 static int win0_display(struct lcdc_device *lcdc_dev,
1119 struct rk_lcdc_win *win)
1123 y_addr = win->area[0].smem_start+win->area[0].y_offset;/*win->smem_start + win->y_offset;*/
1124 uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1125 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
1126 lcdc_dev->id, __func__, y_addr, uv_addr);
1127 spin_lock(&lcdc_dev->reg_lock);
1128 if (likely(lcdc_dev->clk_on)) {
1129 win->area[0].y_addr = y_addr;
1130 win->area[0].uv_addr = uv_addr;
1131 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, win->area[0].y_addr);
1132 lcdc_writel(lcdc_dev, WIN0_CBR_MST, win->area[0].uv_addr);
1134 spin_unlock(&lcdc_dev->reg_lock);
1140 static int win1_display(struct lcdc_device *lcdc_dev,
1141 struct rk_lcdc_win *win)
1145 y_addr = win->area[0].smem_start + win->area[0].y_offset;
1146 uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1147 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
1148 lcdc_dev->id, __func__, y_addr, uv_addr);
1150 spin_lock(&lcdc_dev->reg_lock);
1151 if (likely(lcdc_dev->clk_on)) {
1152 win->area[0].y_addr = y_addr;
1153 win->area[0].uv_addr = uv_addr;
1154 lcdc_writel(lcdc_dev, WIN1_YRGB_MST, win->area[0].y_addr);
1155 lcdc_writel(lcdc_dev, WIN1_CBR_MST, win->area[0].uv_addr);
1157 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;
1176 lcdc_writel(lcdc_dev,WIN2_MST0,win->area[0].y_addr);
1177 lcdc_writel(lcdc_dev,WIN2_MST1,win->area[1].y_addr);
1178 lcdc_writel(lcdc_dev,WIN2_MST2,win->area[2].y_addr);
1179 lcdc_writel(lcdc_dev,WIN2_MST3,win->area[3].y_addr);
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;
1198 lcdc_writel(lcdc_dev,WIN3_MST0,win->area[0].y_addr);
1199 lcdc_writel(lcdc_dev,WIN3_MST1,win->area[1].y_addr);
1200 lcdc_writel(lcdc_dev,WIN3_MST2,win->area[2].y_addr);
1201 lcdc_writel(lcdc_dev,WIN3_MST3,win->area[3].y_addr);
1203 spin_unlock(&lcdc_dev->reg_lock);
1207 static int rk3288_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1209 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1210 struct lcdc_device, driver);
1211 struct rk_lcdc_win *win = NULL;
1212 struct rk_screen *screen = dev_drv->cur_screen;
1214 #if defined(WAIT_FOR_SYNC)
1216 unsigned long flags;
1218 win = dev_drv->win[win_id];
1219 /*lcdc_dev->atv_layer_cnt = dev_drv->atv_layer_cnt;*/
1221 dev_err(dev_drv->dev, "screen is null!\n");
1226 win0_display(lcdc_dev, win);
1227 }else if(win_id == 1){
1228 win1_display(lcdc_dev, win);
1229 }else if(win_id == 2){
1230 win2_display(lcdc_dev, win);
1231 }else if(win_id == 3){
1232 win3_display(lcdc_dev, win);
1234 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1240 /*this is the first frame of the system ,enable frame start interrupt */
1241 if ((dev_drv->first_frame)) {
1242 dev_drv->first_frame = 0;
1243 mask = m_FS_INTR_CLR | m_FS_INTR_EN | m_LINE_FLAG_INTR_CLR |
1244 m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_CLR |
1245 m_BUS_ERROR_INTR_EN | m_DSP_LINE_FLAG_NUM;
1246 val = v_FS_INTR_CLR(1) | v_FS_INTR_EN(1) | v_LINE_FLAG_INTR_CLR(1) |
1247 v_LINE_FLAG_INTR_EN(1) | v_BUS_ERROR_INTR_CLR(1) | v_BUS_ERROR_INTR_EN(0) |
1248 v_DSP_LINE_FLAG_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
1249 screen->mode.yres -1);
1250 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
1251 #ifdef CONFIG_RK_FPGA
1252 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN |
1253 m_WIN3_EMPTY_INTR_EN |m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
1255 val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) | v_WIN2_EMPTY_INTR_EN(1) |
1256 v_WIN3_EMPTY_INTR_EN(1)| v_HWC_EMPTY_INTR_EN(1) | v_POST_BUF_EMPTY_INTR_EN(1) |
1257 v_PWM_GEN_INTR_EN(1);
1258 /*lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);*/
1260 /*lcdc_cfg_done(lcdc_dev);*/
1262 #if defined(WAIT_FOR_SYNC)
1263 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
1264 init_completion(&dev_drv->frame_done);
1265 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
1266 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
1267 msecs_to_jiffies(dev_drv->
1270 if (!timeout && (!dev_drv->frame_done.done)) {
1271 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
1275 /*dev_drv->ops->ovl_mgr(dev_drv, 0, 1);*/
1276 /*rk3288_lcdc_reg_update(dev_drv);*/
1280 static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win)
1290 u32 yrgb_vScaleDnMult;
1291 u32 yrgb_xscl_factor;
1292 u32 yrgb_yscl_factor;
1293 u8 yrgb_vsd_bil_gt2=0;
1294 u8 yrgb_vsd_bil_gt4=0;
1300 u32 cbcr_vScaleDnMult;
1301 u32 cbcr_xscl_factor;
1302 u32 cbcr_yscl_factor;
1303 u8 cbcr_vsd_bil_gt2=0;
1304 u8 cbcr_vsd_bil_gt4=0;
1307 srcW = win->area[0].xact;
1308 srcH = win->area[0].yact;
1309 dstW = win->area[0].xsize;
1310 dstH = win->area[0].ysize;
1317 if(yrgb_srcW < yrgb_dstW){
1318 win->yrgb_hor_scl_mode = SCALE_UP;
1319 }else if(yrgb_srcW > yrgb_dstW){
1320 win->yrgb_hor_scl_mode = SCALE_DOWN;
1322 win->yrgb_hor_scl_mode = SCALE_NONE;
1325 if(yrgb_srcH < yrgb_dstH){
1326 win->yrgb_ver_scl_mode = SCALE_UP;
1327 }else if (yrgb_srcH > yrgb_dstH){
1328 win->yrgb_ver_scl_mode = SCALE_DOWN;
1330 win->yrgb_ver_scl_mode = SCALE_NONE;
1334 switch (win->format) {
1360 if(cbcr_srcW < cbcr_dstW){
1361 win->cbr_hor_scl_mode = SCALE_UP;
1362 }else if(cbcr_srcW > cbcr_dstW){
1363 win->cbr_hor_scl_mode = SCALE_DOWN;
1365 win->cbr_hor_scl_mode = SCALE_NONE;
1368 if(cbcr_srcH < cbcr_dstH){
1369 win->cbr_ver_scl_mode = SCALE_UP;
1370 }else if(cbcr_srcH > cbcr_dstH){
1371 win->cbr_ver_scl_mode = SCALE_DOWN;
1373 win->cbr_ver_scl_mode = SCALE_NONE;
1375 DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
1376 "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1377 "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1378 ,srcW,srcH,dstW,dstH,yrgb_srcW,yrgb_srcH,yrgb_dstW,
1379 yrgb_dstH,win->yrgb_hor_scl_mode,win->yrgb_ver_scl_mode,
1380 cbcr_srcW,cbcr_srcH,cbcr_dstW,cbcr_dstH,
1381 win->cbr_hor_scl_mode,win->cbr_ver_scl_mode);
1383 /*line buffer mode*/
1384 if((win->format == YUV422) || (win->format == YUV420)){
1385 if(win->cbr_hor_scl_mode == SCALE_DOWN){
1386 if(cbcr_dstW > 3840){
1387 pr_err("ERROR cbcr_dst_width exceeds 3840\n");
1388 }else if(cbcr_dstW > 2560){
1389 win->win_lb_mode = LB_RGB_3840X2;
1390 }else if(cbcr_dstW > 1920){
1391 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1392 if(yrgb_dstW > 3840){
1393 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1394 }else if(yrgb_dstW > 2560){
1395 win->win_lb_mode = LB_RGB_3840X2;
1396 }else if(yrgb_dstW > 1920){
1397 win->win_lb_mode = LB_RGB_2560X4;
1399 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1402 }else if(cbcr_dstW > 1280){
1403 win->win_lb_mode = LB_YUV_3840X5;
1405 win->win_lb_mode = LB_YUV_2560X8;
1407 } else { /*SCALE_UP or SCALE_NONE*/
1408 if(cbcr_srcW > 3840){
1409 pr_err("ERROR cbcr_act_width exceeds 3840\n");
1410 }else if(cbcr_srcW > 2560){
1411 win->win_lb_mode = LB_RGB_3840X2;
1412 }else if(cbcr_srcW > 1920){
1413 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1414 if(yrgb_dstW > 3840){
1415 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1416 }else if(yrgb_dstW > 2560){
1417 win->win_lb_mode = LB_RGB_3840X2;
1418 }else if(yrgb_dstW > 1920){
1419 win->win_lb_mode = LB_RGB_2560X4;
1421 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1424 }else if(cbcr_srcW > 1280){
1425 win->win_lb_mode = LB_YUV_3840X5;
1427 win->win_lb_mode = LB_YUV_2560X8;
1431 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1432 if(yrgb_dstW > 3840){
1433 pr_err("ERROR yrgb_dsp_width exceeds 3840\n");
1434 }else if(yrgb_dstW > 2560){
1435 win->win_lb_mode = LB_RGB_3840X2;
1436 }else if(yrgb_dstW > 1920){
1437 win->win_lb_mode = LB_RGB_2560X4;
1438 }else if(yrgb_dstW > 1280){
1439 win->win_lb_mode = LB_RGB_1920X5;
1441 win->win_lb_mode = LB_RGB_1280X8;
1443 }else{ /*SCALE_UP or SCALE_NONE*/
1444 if(yrgb_srcW > 3840){
1445 pr_err("ERROR yrgb_act_width exceeds 3840\n");
1446 }else if(yrgb_srcW > 2560){
1447 win->win_lb_mode = LB_RGB_3840X2;
1448 }else if(yrgb_srcW > 1920){
1449 win->win_lb_mode = LB_RGB_2560X4;
1450 }else if(yrgb_srcW > 1280){
1451 win->win_lb_mode = LB_RGB_1920X5;
1453 win->win_lb_mode = LB_RGB_1280X8;
1457 DBG(1,"win->win_lb_mode = %d;\n",win->win_lb_mode);
1459 /*vsd/vsu scale ALGORITHM*/
1460 win->yrgb_hsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1461 win->cbr_hsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1462 win->yrgb_vsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1463 win->cbr_vsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1464 switch(win->win_lb_mode){
1469 win->yrgb_vsu_mode = SCALE_UP_BIC;
1470 win->cbr_vsu_mode = SCALE_UP_BIC;
1473 if(win->yrgb_ver_scl_mode != SCALE_NONE) {
1474 pr_err("ERROR : not allow yrgb ver scale\n");
1476 if(win->cbr_ver_scl_mode != SCALE_NONE) {
1477 pr_err("ERROR : not allow cbcr ver scale\n");
1481 win->yrgb_vsu_mode = SCALE_UP_BIL;
1482 win->cbr_vsu_mode = SCALE_UP_BIL;
1485 printk(KERN_WARNING "%s:un supported win_lb_mode:%d\n",
1486 __func__,win->win_lb_mode);
1489 DBG(1,"yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
1490 win->yrgb_hsd_mode,win->yrgb_vsd_mode,win->yrgb_vsu_mode,
1491 win->cbr_hsd_mode,win->cbr_vsd_mode,win->cbr_vsu_mode);
1495 /*(1.1)YRGB HOR SCALE FACTOR*/
1496 switch(win->yrgb_hor_scl_mode){
1498 yrgb_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1501 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
1504 switch(win->yrgb_hsd_mode)
1506 case SCALE_DOWN_BIL:
1507 yrgb_xscl_factor = GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
1509 case SCALE_DOWN_AVG:
1510 yrgb_xscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
1513 printk(KERN_WARNING "%s:un supported yrgb_hsd_mode:%d\n",
1514 __func__,win->yrgb_hsd_mode);
1519 printk(KERN_WARNING "%s:un supported yrgb_hor_scl_mode:%d\n",
1520 __func__,win->yrgb_hor_scl_mode);
1522 } /*win->yrgb_hor_scl_mode*/
1524 /*(1.2)YRGB VER SCALE FACTOR*/
1525 switch(win->yrgb_ver_scl_mode)
1528 yrgb_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1531 switch(win->yrgb_vsu_mode)
1534 yrgb_yscl_factor = GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
1538 pr_err("yrgb_srcH should be greater than 3 !!!\n");
1540 yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH, yrgb_dstH);
1543 printk(KERN_WARNING "%s:un supported yrgb_vsu_mode:%d\n",
1544 __func__,win->yrgb_vsu_mode);
1549 switch(win->yrgb_vsd_mode)
1551 case SCALE_DOWN_BIL:
1552 yrgb_vScaleDnMult = getHardWareVSkipLines(yrgb_srcH, yrgb_dstH);
1553 yrgb_yscl_factor = GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH, yrgb_vScaleDnMult);
1554 if(yrgb_vScaleDnMult == 4){
1555 yrgb_vsd_bil_gt4 = 1;
1556 yrgb_vsd_bil_gt2 = 0;
1557 }else if(yrgb_vScaleDnMult == 2){
1558 yrgb_vsd_bil_gt4 = 0;
1559 yrgb_vsd_bil_gt2 = 1;
1561 yrgb_vsd_bil_gt4 = 0;
1562 yrgb_vsd_bil_gt2 = 0;
1565 case SCALE_DOWN_AVG:
1566 yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH, yrgb_dstH);
1569 printk(KERN_WARNING "%s:un supported yrgb_vsd_mode:%d\n",
1570 __func__,win->yrgb_vsd_mode);
1572 } /*win->yrgb_vsd_mode*/
1575 printk(KERN_WARNING "%s:un supported yrgb_ver_scl_mode:%d\n",
1576 __func__,win->yrgb_ver_scl_mode);
1579 win->scale_yrgb_x = yrgb_xscl_factor;
1580 win->scale_yrgb_y = yrgb_yscl_factor;
1581 win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
1582 win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
1583 DBG(1,"yrgb:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",yrgb_xscl_factor,
1584 yrgb_yscl_factor,yrgb_vsd_bil_gt4,yrgb_vsd_bil_gt2);
1586 /*(2.1)CBCR HOR SCALE FACTOR*/
1587 switch(win->cbr_hor_scl_mode)
1590 cbcr_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1593 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
1596 switch(win->cbr_hsd_mode)
1598 case SCALE_DOWN_BIL:
1599 cbcr_xscl_factor = GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
1601 case SCALE_DOWN_AVG:
1602 cbcr_xscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
1605 printk(KERN_WARNING "%s:un supported cbr_hsd_mode:%d\n",
1606 __func__,win->cbr_hsd_mode);
1611 printk(KERN_WARNING "%s:un supported cbr_hor_scl_mode:%d\n",
1612 __func__,win->cbr_hor_scl_mode);
1614 } /*win->cbr_hor_scl_mode*/
1616 /*(2.2)CBCR VER SCALE FACTOR*/
1617 switch(win->cbr_ver_scl_mode)
1620 cbcr_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1623 switch(win->cbr_vsu_mode)
1626 cbcr_yscl_factor = GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
1630 pr_err("cbcr_srcH should be greater than 3 !!!\n");
1632 cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH, cbcr_dstH);
1635 printk(KERN_WARNING "%s:un supported cbr_vsu_mode:%d\n",
1636 __func__,win->cbr_vsu_mode);
1641 switch(win->cbr_vsd_mode)
1643 case SCALE_DOWN_BIL:
1644 cbcr_vScaleDnMult = getHardWareVSkipLines(cbcr_srcH, cbcr_dstH);
1645 cbcr_yscl_factor = GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH, cbcr_vScaleDnMult);
1646 if(cbcr_vScaleDnMult == 4){
1647 cbcr_vsd_bil_gt4 = 1;
1648 cbcr_vsd_bil_gt2 = 0;
1649 }else if(cbcr_vScaleDnMult == 2){
1650 cbcr_vsd_bil_gt4 = 0;
1651 cbcr_vsd_bil_gt2 = 1;
1653 cbcr_vsd_bil_gt4 = 0;
1654 cbcr_vsd_bil_gt2 = 0;
1657 case SCALE_DOWN_AVG:
1658 cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH, cbcr_dstH);
1661 printk(KERN_WARNING "%s:un supported cbr_vsd_mode:%d\n",
1662 __func__,win->cbr_vsd_mode);
1667 printk(KERN_WARNING "%s:un supported cbr_ver_scl_mode:%d\n",
1668 __func__,win->cbr_ver_scl_mode);
1671 win->scale_cbcr_x = cbcr_xscl_factor;
1672 win->scale_cbcr_y = cbcr_yscl_factor;
1673 win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
1674 win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
1676 DBG(1,"cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",cbcr_xscl_factor,
1677 cbcr_yscl_factor,cbcr_vsd_bil_gt4,cbcr_vsd_bil_gt2);
1683 static int win0_set_par(struct lcdc_device *lcdc_dev,
1684 struct rk_screen *screen, struct rk_lcdc_win *win)
1686 u32 xact,yact,xvir, yvir,xpos, ypos;
1688 char fmt[9] = "NULL";
1690 xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
1691 ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
1693 spin_lock(&lcdc_dev->reg_lock);
1694 if(likely(lcdc_dev->clk_on)){
1695 rk3288_lcdc_cal_scl_fac(win);/*fac,lb,gt2,gt4*/
1696 switch (win->format){
1727 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1731 win->fmt_cfg = fmt_cfg;
1732 win->area[0].dsp_stx = xpos;
1733 win->area[0].dsp_sty = ypos;
1734 xact = win->area[0].xact;
1735 yact = win->area[0].yact;
1736 xvir = win->area[0].xvir;
1737 yvir = win->area[0].xvir;
1739 rk3288_win_0_1_reg_update(&lcdc_dev->driver,0);
1740 spin_unlock(&lcdc_dev->reg_lock);
1742 DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1743 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
1744 __func__, get_format_string(win->format, fmt), xact,
1745 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
1750 static int win1_set_par(struct lcdc_device *lcdc_dev,
1751 struct rk_screen *screen, struct rk_lcdc_win *win)
1753 u32 xact,yact,xvir, yvir,xpos, ypos;
1755 char fmt[9] = "NULL";
1757 xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
1758 ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
1760 spin_lock(&lcdc_dev->reg_lock);
1761 if(likely(lcdc_dev->clk_on)){
1762 rk3288_lcdc_cal_scl_fac(win);/*fac,lb,gt2,gt4*/
1763 switch (win->format){
1794 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1798 win->fmt_cfg = fmt_cfg;
1799 win->area[0].dsp_stx = xpos;
1800 win->area[0].dsp_sty = ypos;
1801 xact = win->area[0].xact;
1802 yact = win->area[0].yact;
1803 xvir = win->area[0].xvir;
1804 yvir = win->area[0].xvir;
1806 rk3288_win_0_1_reg_update(&lcdc_dev->driver,1);
1807 spin_unlock(&lcdc_dev->reg_lock);
1809 DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1810 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
1811 __func__, get_format_string(win->format, fmt), xact,
1812 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
1817 static int win2_set_par(struct lcdc_device *lcdc_dev,
1818 struct rk_screen *screen, struct rk_lcdc_win *win)
1823 spin_lock(&lcdc_dev->reg_lock);
1824 if(likely(lcdc_dev->clk_on)){
1825 for(i=0;i<win->area_num;i++){
1826 switch (win->format){
1845 dev_err(lcdc_dev->driver.dev,
1846 "%s:un supported format!\n",
1850 win->fmt_cfg = fmt_cfg;
1851 win->area[i].dsp_stx = win->area[i].xpos +
1852 screen->mode.left_margin +
1853 screen->mode.hsync_len;
1854 if (screen->y_mirror == 1) {
1855 win->area[i].dsp_sty = screen->mode.yres -
1857 win->area[i].ysize +
1858 screen->mode.upper_margin +
1859 screen->mode.vsync_len;
1861 win->area[i].dsp_sty = win->area[i].ypos +
1862 screen->mode.upper_margin +
1863 screen->mode.vsync_len;
1867 rk3288_win_2_3_reg_update(&lcdc_dev->driver,2);
1868 spin_unlock(&lcdc_dev->reg_lock);
1872 static int win3_set_par(struct lcdc_device *lcdc_dev,
1873 struct rk_screen *screen, struct rk_lcdc_win *win)
1879 spin_lock(&lcdc_dev->reg_lock);
1880 if(likely(lcdc_dev->clk_on)){
1881 for(i=0;i<win->area_num;i++){
1882 switch (win->format){
1901 dev_err(lcdc_dev->driver.dev,
1902 "%s:un supported format!\n",
1906 win->fmt_cfg = fmt_cfg;
1907 win->area[i].dsp_stx = win->area[i].xpos +
1908 screen->mode.left_margin +
1909 screen->mode.hsync_len;
1910 if (screen->y_mirror == 1) {
1911 win->area[i].dsp_sty = screen->mode.yres -
1913 win->area[i].ysize +
1914 screen->mode.upper_margin +
1915 screen->mode.vsync_len;
1917 win->area[i].dsp_sty = win->area[i].ypos +
1918 screen->mode.upper_margin +
1919 screen->mode.vsync_len;
1923 rk3288_win_2_3_reg_update(&lcdc_dev->driver,3);
1924 spin_unlock(&lcdc_dev->reg_lock);
1928 static int rk3288_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
1930 struct lcdc_device *lcdc_dev =
1931 container_of(dev_drv, struct lcdc_device, driver);
1932 struct rk_lcdc_win *win = NULL;
1933 struct rk_screen *screen = dev_drv->cur_screen;
1934 win = dev_drv->win[win_id];
1939 win0_set_par(lcdc_dev, screen, win);
1942 win1_set_par(lcdc_dev, screen, win);
1945 win2_set_par(lcdc_dev, screen, win);
1948 win3_set_par(lcdc_dev, screen, win);
1951 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
1957 static int rk3288_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1958 unsigned long arg, int win_id)
1960 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1965 void __user *argp = (void __user *)arg;
1966 struct color_key_cfg clr_key_cfg;
1969 case RK_FBIOGET_PANEL_SIZE:
1970 panel_size[0] = lcdc_dev->screen->mode.xres;
1971 panel_size[1] = lcdc_dev->screen->mode.yres;
1972 if (copy_to_user(argp, panel_size, 8))
1975 case RK_FBIOPUT_COLOR_KEY_CFG:
1976 if (copy_from_user(&clr_key_cfg, argp,
1977 sizeof(struct color_key_cfg)))
1979 rk3288_lcdc_clr_key_cfg(dev_drv);
1980 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
1981 clr_key_cfg.win0_color_key_cfg);
1982 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
1983 clr_key_cfg.win1_color_key_cfg);
1992 static int rk3288_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1994 struct lcdc_device *lcdc_dev =
1995 container_of(dev_drv, struct lcdc_device, driver);
1996 if (dev_drv->suspend_flag)
1999 dev_drv->suspend_flag = 1;
2000 flush_kthread_worker(&dev_drv->update_regs_worker);
2001 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2002 dev_drv->trsm_ops->disable();
2004 spin_lock(&lcdc_dev->reg_lock);
2005 if (likely(lcdc_dev->clk_on)) {
2006 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2008 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_FS_INTR_CLR | m_LINE_FLAG_INTR_CLR,
2009 v_FS_INTR_CLR(1) | v_LINE_FLAG_INTR_CLR(1));
2010 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2012 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2014 lcdc_cfg_done(lcdc_dev);
2015 spin_unlock(&lcdc_dev->reg_lock);
2017 spin_unlock(&lcdc_dev->reg_lock);
2020 rk3288_lcdc_clk_disable(lcdc_dev);
2021 rk_disp_pwr_disable(dev_drv);
2025 static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
2027 struct lcdc_device *lcdc_dev =
2028 container_of(dev_drv, struct lcdc_device, driver);
2033 if (!dev_drv->suspend_flag)
2035 rk_disp_pwr_enable(dev_drv);
2036 dev_drv->suspend_flag = 0;
2038 if (lcdc_dev->atv_layer_cnt) {
2039 rk3288_lcdc_clk_enable(lcdc_dev);
2040 rk3288_lcdc_reg_restore(lcdc_dev);
2042 spin_lock(&lcdc_dev->reg_lock);
2043 if (dev_drv->cur_screen->dsp_lut) {
2044 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2046 lcdc_cfg_done(lcdc_dev);
2048 for (i = 0; i < 256; i++) {
2049 v = dev_drv->cur_screen->dsp_lut[i];
2050 c = lcdc_dev->dsp_lut_addr_base + i;
2051 writel_relaxed(v, c);
2053 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2057 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2059 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2061 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2063 lcdc_cfg_done(lcdc_dev);
2065 spin_unlock(&lcdc_dev->reg_lock);
2068 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2069 dev_drv->trsm_ops->enable();
2074 static int rk3288_lcdc_blank(struct rk_lcdc_driver *dev_drv,
2075 int win_id, int blank_mode)
2077 struct lcdc_device *lcdc_dev =
2078 container_of(dev_drv, struct lcdc_device, driver);
2080 if (likely(lcdc_dev->clk_on)) {
2081 switch (blank_mode) {
2082 case FB_BLANK_UNBLANK:
2083 rk3288_lcdc_early_resume(dev_drv);
2085 case FB_BLANK_NORMAL:
2086 rk3288_lcdc_early_suspend(dev_drv);
2089 rk3288_lcdc_early_suspend(dev_drv);
2094 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
2099 static int rk3288_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
2104 /*overlay will be do at regupdate*/
2105 static int rk3288_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
2108 struct lcdc_device *lcdc_dev =
2109 container_of(dev_drv, struct lcdc_device, driver);
2110 struct rk_lcdc_win *win = NULL;
2112 unsigned int mask, val;
2113 int layer0_sel,layer1_sel,layer2_sel,layer3_sel;
2115 win = dev_drv->win[i];
2116 switch(win->z_order){
2118 layer0_sel = win->id;
2121 layer1_sel = win->id;
2124 layer2_sel = win->id;
2127 layer3_sel = win->id;
2134 spin_lock(&lcdc_dev->reg_lock);
2135 if(lcdc_dev->clk_on){
2137 mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
2138 m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
2139 val = v_DSP_LAYER0_SEL(layer0_sel) |
2140 v_DSP_LAYER1_SEL(layer1_sel) |
2141 v_DSP_LAYER2_SEL(layer2_sel) |
2142 v_DSP_LAYER3_SEL(layer3_sel);
2143 lcdc_msk_reg(lcdc_dev,DSP_CTRL1,mask,val);
2145 layer0_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER0_SEL);
2146 layer1_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER1_SEL);
2147 layer2_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER2_SEL);
2148 layer3_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER3_SEL);
2149 ovl = layer3_sel*1000 + layer2_sel*100 + layer1_sel *10 + layer0_sel;
2154 spin_unlock(&lcdc_dev->reg_lock);
2159 static ssize_t rk3288_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2160 char *buf, int win_id)
2162 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2166 struct rk_screen *screen = dev_drv->cur_screen;
2167 u16 hsync_len = screen->mode.hsync_len;
2168 u16 left_margin = screen->mode.left_margin;
2169 u16 vsync_len = screen->mode.vsync_len;
2170 u16 upper_margin = screen->mode.upper_margin;
2171 u32 fmt_id,h_pw_bp,v_pw_bp;
2172 char format_w0[9] = "NULL";
2173 char format_w1[9] = "NULL";
2174 char format_w2[9] = "NULL";
2175 char format_w3[9] = "NULL";
2176 u32 win_ctrl,zorder,vir_info,act_info,dsp_info,dsp_st,y_factor,uv_factor;
2177 u8 layer0_sel,layer1_sel,layer2_sel,layer3_sel;
2178 u8 w0_state,w1_state,w2_state,w3_state;
2179 u8 w2_0_state,w2_1_state,w2_2_state,w2_3_state;
2180 u8 w3_0_state,w3_1_state,w3_2_state,w3_3_state;
2182 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;
2183 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;
2184 u32 w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,w0_uv_v_fac;
2185 u32 w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,w1_uv_v_fac;
2187 u32 w2_0_vir_y,w2_1_vir_y,w2_2_vir_y,w2_3_vir_y;
2188 u32 w2_0_dsp_x,w2_1_dsp_x,w2_2_dsp_x,w2_3_dsp_x;
2189 u32 w2_0_dsp_y,w2_1_dsp_y,w2_2_dsp_y,w2_3_dsp_y;
2190 u32 w2_0_st_x,w2_1_st_x,w2_2_st_x,w2_3_st_x;
2191 u32 w2_0_st_y,w2_1_st_y,w2_2_st_y,w2_3_st_y;
2193 u32 w3_0_vir_y,w3_1_vir_y,w3_2_vir_y,w3_3_vir_y;
2194 u32 w3_0_dsp_x,w3_1_dsp_x,w3_2_dsp_x,w3_3_dsp_x;
2195 u32 w3_0_dsp_y,w3_1_dsp_y,w3_2_dsp_y,w3_3_dsp_y;
2196 u32 w3_0_st_x,w3_1_st_x,w3_2_st_x,w3_3_st_x;
2197 u32 w3_0_st_y,w3_1_st_y,w3_2_st_y,w3_3_st_y;
2200 h_pw_bp = hsync_len + left_margin;
2201 v_pw_bp = vsync_len + upper_margin;
2202 dclk_freq = screen->mode.pixclock;
2203 rk3288_lcdc_reg_dump(dev_drv);
2205 spin_lock(&lcdc_dev->reg_lock);
2206 if (lcdc_dev->clk_on) {
2207 zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
2208 layer0_sel = zorder & m_DSP_LAYER0_SEL;
2209 layer1_sel = zorder & m_DSP_LAYER1_SEL;
2210 layer2_sel = zorder & m_DSP_LAYER2_SEL;
2211 layer3_sel = zorder & m_DSP_LAYER3_SEL;
2213 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
2214 w0_state = win_ctrl & m_WIN0_EN;
2215 fmt_id = (win_ctrl & m_WIN0_DATA_FMT)>>1;
2218 strcpy(format_w0, "ARGB888");
2221 strcpy(format_w0, "RGB888");
2224 strcpy(format_w0, "RGB565");
2227 strcpy(format_w0, "YCbCr420");
2230 strcpy(format_w0, "YCbCr422");
2233 strcpy(format_w0, "YCbCr444");
2236 strcpy(format_w0, "invalid\n");
2239 vir_info = lcdc_readl(lcdc_dev,WIN0_VIR);
2240 act_info = lcdc_readl(lcdc_dev,WIN0_ACT_INFO);
2241 dsp_info = lcdc_readl(lcdc_dev,WIN0_DSP_INFO);
2242 dsp_st = lcdc_readl(lcdc_dev,WIN0_DSP_ST);
2243 y_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
2244 uv_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_CBR);
2245 w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
2246 w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV)>>16;
2247 w0_act_x = (act_info & m_WIN0_ACT_WIDTH)+1;
2248 w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT)>>16)+1;
2249 w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH)+1;
2250 w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT)>>16)+1;
2251 w0_st_x = dsp_st & m_WIN0_DSP_XST;
2252 w0_st_y = (dsp_st & m_WIN0_DSP_YST)>>16;
2253 w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
2254 w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB)>>16;
2255 w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
2256 w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR)>>16;
2259 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
2260 w1_state = win_ctrl & m_WIN1_EN;
2261 fmt_id = (win_ctrl & m_WIN1_DATA_FMT)>>1;
2264 strcpy(format_w1, "ARGB888");
2267 strcpy(format_w1, "RGB888");
2270 strcpy(format_w1, "RGB565");
2273 strcpy(format_w1, "YCbCr420");
2276 strcpy(format_w1, "YCbCr422");
2279 strcpy(format_w1, "YCbCr444");
2282 strcpy(format_w1, "invalid\n");
2285 vir_info = lcdc_readl(lcdc_dev,WIN1_VIR);
2286 act_info = lcdc_readl(lcdc_dev,WIN1_ACT_INFO);
2287 dsp_info = lcdc_readl(lcdc_dev,WIN1_DSP_INFO);
2288 dsp_st = lcdc_readl(lcdc_dev,WIN1_DSP_ST);
2289 y_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_YRGB);
2290 uv_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_CBR);
2291 w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
2292 w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV)>>16;
2293 w1_act_x = (act_info & m_WIN1_ACT_WIDTH)+1;
2294 w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT)>>16)+1;
2295 w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH)+1;
2296 w1_dsp_y =((dsp_info & m_WIN1_DSP_HEIGHT)>>16)+1;
2297 w1_st_x = dsp_st & m_WIN1_DSP_XST;
2298 w1_st_y = (dsp_st & m_WIN1_DSP_YST)>>16;
2299 w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
2300 w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB)>>16;
2301 w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
2302 w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR)>>16;
2304 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
2305 w2_state = win_ctrl & m_WIN2_EN;
2306 w2_0_state = (win_ctrl & m_WIN2_MST0_EN)>>4;
2307 w2_1_state = (win_ctrl & m_WIN2_MST1_EN)>>5;
2308 w2_2_state = (win_ctrl & m_WIN2_MST2_EN)>>6;
2309 w2_3_state = (win_ctrl & m_WIN2_MST3_EN)>>7;
2310 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR0_1);
2311 w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
2312 w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1)>>16;
2313 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR2_3);
2314 w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
2315 w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3)>>16;
2316 fmt_id = (win_ctrl & m_WIN2_DATA_FMT)>>1;
2319 strcpy(format_w2, "ARGB888");
2322 strcpy(format_w2, "RGB888");
2325 strcpy(format_w2, "RGB565");
2328 strcpy(format_w2,"8bpp");
2331 strcpy(format_w2,"4bpp");
2334 strcpy(format_w2,"2bpp");
2337 strcpy(format_w2,"1bpp");
2340 strcpy(format_w2, "invalid\n");
2343 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO0);
2344 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST0);
2345 w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0)+1;
2346 w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0)>>16)+1;
2347 w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
2348 w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0);
2350 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO1);
2351 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST1);
2352 w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1)+1;
2353 w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1)>>16)+1;
2354 w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
2355 w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1)>>16;
2357 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO2);
2358 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST2);
2359 w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2)+1;
2360 w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2)>>16)+1;
2361 w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
2362 w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2)>>16;
2364 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO3);
2365 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST3);
2366 w2_3_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH3)+1;
2367 w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3)>>16)+1;
2368 w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
2369 w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3)>>16;
2372 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
2373 w3_state = win_ctrl & m_WIN3_EN;
2374 w3_0_state = (win_ctrl & m_WIN3_MST0_EN)>>4;
2375 w3_1_state = (win_ctrl & m_WIN3_MST1_EN)>>5;
2376 w3_2_state = (win_ctrl & m_WIN3_MST2_EN)>>6;
2377 w3_3_state = (win_ctrl & m_WIN3_MST3_EN)>>7;
2378 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR0_1);
2379 w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
2380 w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1)>>16;
2381 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR2_3);
2382 w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
2383 w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3)>>16;
2384 fmt_id = (win_ctrl | m_WIN3_DATA_FMT)>>1;
2387 strcpy(format_w3, "ARGB888");
2390 strcpy(format_w3, "RGB888");
2393 strcpy(format_w3, "RGB565");
2396 strcpy(format_w3,"8bpp");
2399 strcpy(format_w3,"4bpp");
2402 strcpy(format_w3,"2bpp");
2405 strcpy(format_w3,"1bpp");
2408 strcpy(format_w3, "invalid");
2411 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO0);
2412 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST0);
2413 w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0)+1;
2414 w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0)>>16)+1;
2415 w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
2416 w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0)>>16;
2418 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO1);
2419 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST1);
2420 w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1)+1;
2421 w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1)>>16)+1;
2422 w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
2423 w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1)>>16;
2425 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO2);
2426 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST2);
2427 w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2)+1;
2428 w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2)>>16)+1;
2429 w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
2430 w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2)>>16;
2432 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO3);
2433 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST3);
2434 w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3)+1;
2435 w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3)>>16)+1;
2436 w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
2437 w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3)>>16;
2440 spin_unlock(&lcdc_dev->reg_lock);
2443 spin_unlock(&lcdc_dev->reg_lock);
2444 return snprintf(buf, PAGE_SIZE,
2448 " layer3_sel_win[%d]\n"
2449 " layer2_sel_win[%d]\n"
2450 " layer1_sel_win[%d]\n"
2451 " layer0_sel_win[%d]\n"
2557 layer3_sel,layer2_sel,layer1_sel,layer0_sel,
2558 w0_state,format_w0,w0_vir_y,w0_vir_uv,w0_act_x,w0_act_y,
2559 w0_dsp_x,w0_dsp_y,w0_st_x,w0_st_y,w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,
2560 w0_uv_v_fac,lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2561 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2563 w1_state,format_w1,w1_vir_y,w1_vir_uv,w1_act_x,w1_act_y,
2564 w1_dsp_x,w1_dsp_y,w1_st_x,w1_st_y,w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,
2565 w1_uv_v_fac,lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
2566 lcdc_readl(lcdc_dev, WIN1_CBR_MST),
2569 w2_0_state,w2_0_vir_y,w2_0_dsp_x,w2_0_dsp_y,
2570 w2_0_st_x,w2_0_st_y,lcdc_readl(lcdc_dev, WIN2_MST0),
2572 w2_1_state,w2_1_vir_y,w2_1_dsp_x,w2_1_dsp_y,
2573 w2_1_st_x,w2_1_st_y,lcdc_readl(lcdc_dev, WIN2_MST1),
2575 w2_2_state,w2_2_vir_y,w2_2_dsp_x,w2_2_dsp_y,
2576 w2_2_st_x,w2_2_st_y,lcdc_readl(lcdc_dev, WIN2_MST2),
2578 w2_3_state,w2_3_vir_y,w2_3_dsp_x,w2_3_dsp_y,
2579 w2_3_st_x,w2_3_st_y,lcdc_readl(lcdc_dev, WIN2_MST3),
2582 w3_0_state,w3_0_vir_y,w3_0_dsp_x,w3_0_dsp_y,
2583 w3_0_st_x,w3_0_st_y,lcdc_readl(lcdc_dev, WIN3_MST0),
2585 w3_1_state,w3_1_vir_y,w3_1_dsp_x,w3_1_dsp_y,
2586 w3_1_st_x,w3_1_st_y,lcdc_readl(lcdc_dev, WIN3_MST1),
2588 w3_2_state,w3_2_vir_y,w3_2_dsp_x,w3_2_dsp_y,
2589 w3_2_st_x,w3_2_st_y,lcdc_readl(lcdc_dev, WIN3_MST2),
2591 w3_3_state,w3_3_vir_y,w3_3_dsp_x,w3_3_dsp_y,
2592 w3_3_st_x,w3_3_st_y,lcdc_readl(lcdc_dev, WIN3_MST3)
2597 static int rk3288_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2600 struct lcdc_device *lcdc_dev =
2601 container_of(dev_drv, struct lcdc_device, driver);
2602 struct rk_screen *screen = dev_drv->cur_screen;
2607 u32 x_total, y_total;
2609 ft = div_u64(1000000000000llu, fps);
2611 screen->mode.upper_margin + screen->mode.lower_margin +
2612 screen->mode.yres + screen->mode.vsync_len;
2614 screen->mode.left_margin + screen->mode.right_margin +
2615 screen->mode.xres + screen->mode.hsync_len;
2616 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2617 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2618 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2621 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2622 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2623 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2624 screen->ft = 1000 / fps; /*one frame time in ms */
2627 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2628 clk_get_rate(lcdc_dev->dclk), fps);
2633 static int rk3288_fb_win_remap(struct rk_lcdc_driver *dev_drv,
2634 enum fb_win_map_order order)
2636 mutex_lock(&dev_drv->fb_win_id_mutex);
2637 if (order == FB_DEFAULT_ORDER)
2638 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3;
2639 dev_drv->fb3_win_id = order / 1000;
2640 dev_drv->fb2_win_id = (order / 100) % 10;
2641 dev_drv->fb1_win_id = (order / 10) % 10;
2642 dev_drv->fb0_win_id = order % 10;
2643 mutex_unlock(&dev_drv->fb_win_id_mutex);
2648 static int rk3288_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
2652 mutex_lock(&dev_drv->fb_win_id_mutex);
2653 if (!strcmp(id, "fb0") || !strcmp(id, "fb4"))
2654 win_id = dev_drv->fb0_win_id;
2655 else if (!strcmp(id, "fb1") || !strcmp(id, "fb5"))
2656 win_id = dev_drv->fb1_win_id;
2657 else if (!strcmp(id, "fb2") || !strcmp(id, "fb6"))
2658 win_id = dev_drv->fb2_win_id;
2659 else if (!strcmp(id, "fb3") || !strcmp(id, "fb7"))
2660 win_id = dev_drv->fb3_win_id;
2661 mutex_unlock(&dev_drv->fb_win_id_mutex);
2666 static int rk3288_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
2673 struct lcdc_device *lcdc_dev =
2674 container_of(dev_drv, struct lcdc_device, driver);
2675 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
2676 lcdc_cfg_done(lcdc_dev);
2678 if (dev_drv->cur_screen->dsp_lut) {
2679 for (i = 0; i < 256; i++) {
2680 v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
2681 c = lcdc_dev->dsp_lut_addr_base + i;
2682 writel_relaxed(v, c);
2686 dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
2689 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
2690 lcdc_cfg_done(lcdc_dev);
2695 static int rk3288_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv, bool en)
2697 struct lcdc_device *lcdc_dev =
2698 container_of(dev_drv, struct lcdc_device, driver);
2699 spin_lock(&lcdc_dev->reg_lock);
2701 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_MMU_EN,
2703 lcdc_cfg_done(lcdc_dev);
2704 spin_unlock(&lcdc_dev->reg_lock);
2708 static int rk3288_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
2710 struct lcdc_device *lcdc_dev =
2711 container_of(dev_drv, struct lcdc_device, driver);
2713 unsigned int mask, val;
2714 struct rk_lcdc_win *win = NULL;
2715 spin_lock(&lcdc_dev->reg_lock);
2716 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2717 v_STANDBY_EN(lcdc_dev->standby));
2719 win = dev_drv->win[i];
2720 if (win->state == 0) {
2725 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask,val);
2730 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask,val);
2733 mask = m_WIN2_EN | m_WIN2_MST0_EN | m_WIN2_MST1_EN |
2734 m_WIN2_MST2_EN | m_WIN2_MST3_EN;
2735 val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) | v_WIN2_MST1_EN(0) |
2736 v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
2737 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask,val);
2740 mask = m_WIN3_EN | m_WIN3_MST0_EN | m_WIN3_MST1_EN |
2741 m_WIN3_MST2_EN | m_WIN3_MST3_EN;
2742 val = v_WIN3_EN(0) | v_WIN3_MST0_EN(0) | v_WIN3_MST1_EN(0) |
2743 v_WIN3_MST2_EN(0) | v_WIN3_MST3_EN(0);
2744 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask,val);
2751 lcdc_cfg_done(lcdc_dev);
2752 spin_unlock(&lcdc_dev->reg_lock);
2757 static int rk3288_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2759 struct lcdc_device *lcdc_dev =
2760 container_of(dev_drv, struct lcdc_device, driver);
2761 spin_lock(&lcdc_dev->reg_lock);
2762 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2763 v_DIRECT_PATH_EN(open));
2764 lcdc_cfg_done(lcdc_dev);
2765 spin_unlock(&lcdc_dev->reg_lock);
2769 static int rk3288_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2771 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2772 struct lcdc_device, driver);
2773 spin_lock(&lcdc_dev->reg_lock);
2774 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
2775 v_DIRECT_PATCH_SEL(win_id));
2776 lcdc_cfg_done(lcdc_dev);
2777 spin_unlock(&lcdc_dev->reg_lock);
2782 static int rk3288_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2784 struct lcdc_device *lcdc_dev =
2785 container_of(dev_drv, struct lcdc_device, driver);
2786 spin_lock(&lcdc_dev->reg_lock);
2787 int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2788 spin_unlock(&lcdc_dev->reg_lock);
2792 int rk3288_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2794 struct lcdc_device *lcdc_dev =
2795 container_of(dev_drv, struct lcdc_device, driver);
2799 if (lcdc_dev->clk_on) {
2800 int_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
2801 if (int_reg & m_LINE_FLAG_INTR_STS) {
2802 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
2803 v_LINE_FLAG_INTR_CLR(1));
2804 ret = RK_LF_STATUS_FC;
2806 ret = RK_LF_STATUS_FR;
2808 ret = RK_LF_STATUS_NC;
2813 static int rk3288_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
2815 struct lcdc_device *lcdc_dev =
2816 container_of(dev_drv, struct lcdc_device, driver);
2818 if(lcdc_dev->clk_on){
2819 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2820 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
2821 dsp_addr[2] = lcdc_readl(lcdc_dev, WIN2_MST0);
2822 dsp_addr[3] = lcdc_readl(lcdc_dev, WIN3_MST0);
2827 static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,int mode)
2829 struct lcdc_device *lcdc_dev =
2830 container_of(dev_drv, struct lcdc_device, driver);
2831 struct rk_screen *screen = dev_drv->cur_screen;
2832 int total_pixel,calc_pixel,stage_up,stage_down;
2835 u32 cabc_mode[5][3]={
2837 {2, 10, 10}, /*mode 1*/
2838 {4, 10, 10}, /*mode 2*/
2839 {6, 10, 10}, /*mode 3*/
2840 {8, 10, 10}, /*mode 4*/
2841 {10, 10, 10}, /*mode 5*/
2843 /*iomux connect to vop or pwm*/
2845 DBG(3,"close cabc\n");
2848 /*lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);*/
2851 total_pixel = screen->mode.xres * screen->mode.yres;
2852 calc_pixel = total_pixel * (100 - cabc_mode[mode-1][0])/100;
2853 stage_up = cabc_mode[mode-1][1];
2854 stage_down = cabc_mode[mode-1][2];
2856 spin_lock(&lcdc_dev->reg_lock);
2857 if(lcdc_dev->clk_on){
2858 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
2859 mask = m_CABC_TOTAL_NUM | m_CABC_STAGE_DOWN;
2860 val = v_CABC_TOTAL_NUM(total_pixel) | v_CABC_STAGE_DOWN(stage_down);
2861 lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
2863 mask = m_CABC_EN | m_CABC_CALC_PIXEL_NUM |
2865 val = v_CABC_EN(1) | v_CABC_CALC_PIXEL_NUM(calc_pixel) |
2866 v_CABC_STAGE_UP(stage_up);
2867 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
2868 lcdc_cfg_done(lcdc_dev);
2870 spin_unlock(&lcdc_dev->reg_lock);
2874 Sin0=*0.000???????? Cos0=*1.000
2875 Sin5=*0.087???????C Cos5=*0.996
2876 Sin10=*0.174 Cos10=*0.985
2877 Sin15=*0.259 ???????CCos15=*0.966
2878 Sin20=*0.342????????Cos20=*0.940
2879 Sin25=*0.422????????Cos25=*0.906
2880 Sin30=*0.500????????Cos30=*0.866
2882 static int rk3288_lcdc_set_hue(struct rk_lcdc_driver *dev_drv,int hue)
2885 struct lcdc_device *lcdc_dev =
2886 container_of(dev_drv, struct lcdc_device, driver);
2887 int sin_hue_val,cos_hue_val;
2890 int sin_hue[7]={0,22, 44, 66, 87, 108, 128};
2891 int cos_hue[7]={256,254,252,247,240,231,221};
2893 if((hue > 0)&&(hue <= 30)){
2894 /*sin_hue_val = (int)sin_hue[hue] * 256;
2895 cos_hue_val = (int)cos_hue[hue] * 256;*/
2897 sin_hue_val = sin_hue[hue];
2898 cos_hue_val = cos_hue[hue];
2899 }else if((hue > 30)&&(hue <= 60)){
2902 /*sin_hue_val = (int)sin_hue[hue] * 256 + 0x100;
2903 cos_hue_val = (int)cos_hue[hue] * 256 + 0x100;*/
2904 sin_hue_val = sin_hue[hue] + 0x100;
2905 cos_hue_val = cos_hue[hue] + 0x100;
2907 dev_warn(lcdc_dev->dev,"hue=%d should be [0:60]\n",hue);
2910 spin_lock(&lcdc_dev->reg_lock);
2911 if(lcdc_dev->clk_on){
2913 mask = m_BCSH_OUT_MODE;
2914 val = v_BCSH_OUT_MODE(3);
2915 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2917 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
2918 val = v_BCSH_SIN_HUE(sin_hue_val) | v_BCSH_COS_HUE(cos_hue_val);
2919 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
2923 lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
2924 lcdc_cfg_done(lcdc_dev);
2926 spin_unlock(&lcdc_dev->reg_lock);
2931 static int rk3288_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,int bri,int con,int sat)
2933 struct lcdc_device *lcdc_dev =
2934 container_of(dev_drv, struct lcdc_device, driver);
2937 spin_lock(&lcdc_dev->reg_lock);
2938 if(lcdc_dev->clk_on){
2939 mask = m_BCSH_OUT_MODE | m_BCSH_BRIGHTNESS |
2940 m_BCSH_CONTRAST | m_BCSH_SAT_CON;
2941 val = v_BCSH_OUT_MODE(3) | v_BCSH_BRIGHTNESS(bri) |
2942 v_BCSH_CONTRAST(con) | v_BCSH_SAT_CON(sat);
2943 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2947 lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
2948 lcdc_cfg_done(lcdc_dev);
2950 spin_unlock(&lcdc_dev->reg_lock);
2955 static struct rk_lcdc_win lcdc_win[] = {
2959 .support_3d = false,
2964 .support_3d = false,
2969 .support_3d = false,
2974 .support_3d = false,
2978 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2979 .open = rk3288_lcdc_open,
2980 .load_screen = rk3288_load_screen,
2981 .set_par = rk3288_lcdc_set_par,
2982 .pan_display = rk3288_lcdc_pan_display,
2983 .lcdc_reg_update = rk3288_lcdc_reg_update,
2984 .blank = rk3288_lcdc_blank,
2985 .ioctl = rk3288_lcdc_ioctl,
2986 .suspend = rk3288_lcdc_early_suspend,
2987 .resume = rk3288_lcdc_early_resume,
2988 .get_win_state = rk3288_lcdc_get_win_state,
2989 .ovl_mgr = rk3288_lcdc_ovl_mgr,
2990 .get_disp_info = rk3288_lcdc_get_disp_info,
2991 .fps_mgr = rk3288_lcdc_fps_mgr,
2992 .fb_get_win_id = rk3288_lcdc_get_win_id,
2993 .fb_win_remap = rk3288_fb_win_remap,
2994 .set_dsp_lut = rk3288_set_dsp_lut,
2995 .poll_vblank = rk3288_lcdc_poll_vblank,
2996 .dpi_open = rk3288_lcdc_dpi_open,
2997 .dpi_win_sel = rk3288_lcdc_dpi_win_sel,
2998 .dpi_status = rk3288_lcdc_dpi_status,
2999 .get_dsp_addr = rk3288_lcdc_get_dsp_addr,
3000 .set_dsp_cabc = rk3288_lcdc_set_dsp_cabc,
3001 .set_dsp_hue = rk3288_lcdc_set_hue,
3002 .set_dsp_bcsh_bcs = rk3288_lcdc_set_bcsh_bcs,
3003 .dump_reg = rk3288_lcdc_reg_dump,
3004 .mmu_en = rk3288_lcdc_mmu_en,
3005 .cfg_done = rk3288_lcdc_config_done,
3007 static int rk3288_lcdc_parse_irq(struct lcdc_device *lcdc_dev,unsigned int reg_val)
3009 if (reg_val & m_WIN0_EMPTY_INTR_STS) {
3010 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN0_EMPTY_INTR_CLR,
3011 v_WIN0_EMPTY_INTR_CLR(1));
3012 dev_warn(lcdc_dev->dev,"win0 empty irq!");
3013 }else if (reg_val & m_WIN1_EMPTY_INTR_STS) {
3014 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN1_EMPTY_INTR_CLR,
3015 v_WIN1_EMPTY_INTR_CLR(1));
3016 dev_warn(lcdc_dev->dev,"win1 empty irq!");
3017 }else if (reg_val & m_WIN2_EMPTY_INTR_STS) {
3018 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN2_EMPTY_INTR_CLR,
3019 v_WIN2_EMPTY_INTR_CLR(1));
3020 dev_warn(lcdc_dev->dev,"win2 empty irq!");
3021 }else if (reg_val & m_WIN3_EMPTY_INTR_STS) {
3022 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN3_EMPTY_INTR_CLR,
3023 v_WIN3_EMPTY_INTR_CLR(1));
3024 dev_warn(lcdc_dev->dev,"win3 empty irq!");
3025 }else if (reg_val & m_HWC_EMPTY_INTR_STS) {
3026 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_HWC_EMPTY_INTR_CLR,
3027 v_HWC_EMPTY_INTR_CLR(1));
3028 dev_warn(lcdc_dev->dev,"HWC empty irq!");
3029 }else if (reg_val & m_POST_BUF_EMPTY_INTR_STS) {
3030 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_POST_BUF_EMPTY_INTR_CLR,
3031 v_POST_BUF_EMPTY_INTR_CLR(1));
3032 dev_warn(lcdc_dev->dev,"post buf empty irq!");
3033 }else if (reg_val & m_PWM_GEN_INTR_STS) {
3034 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_PWM_GEN_INTR_CLR,
3035 v_PWM_GEN_INTR_CLR(1));
3036 dev_warn(lcdc_dev->dev,"PWM gen irq!");
3041 static irqreturn_t rk3288_lcdc_isr(int irq, void *dev_id)
3043 struct lcdc_device *lcdc_dev =
3044 (struct lcdc_device *)dev_id;
3045 ktime_t timestamp = ktime_get();
3047 intr0_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
3049 if(intr0_reg & m_FS_INTR_STS){
3050 timestamp = ktime_get();
3051 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_FS_INTR_CLR,
3053 /*if(lcdc_dev->driver.wait_fs){ */
3055 spin_lock(&(lcdc_dev->driver.cpl_lock));
3056 complete(&(lcdc_dev->driver.frame_done));
3057 spin_unlock(&(lcdc_dev->driver.cpl_lock));
3059 lcdc_dev->driver.vsync_info.timestamp = timestamp;
3060 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
3062 }else if(intr0_reg & m_LINE_FLAG_INTR_STS){
3063 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
3064 v_LINE_FLAG_INTR_CLR(1));
3065 }else if(intr0_reg & m_BUS_ERROR_INTR_STS){
3066 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_BUS_ERROR_INTR_CLR,
3067 v_BUS_ERROR_INTR_CLR(1));
3068 dev_warn(lcdc_dev->dev,"buf_error_int!");
3073 intr1_reg = lcdc_readl(lcdc_dev, INTR_CTRL1);
3075 rk3288_lcdc_parse_irq(lcdc_dev,intr1_reg);
3081 #if defined(CONFIG_PM)
3082 static int rk3288_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
3087 static int rk3288_lcdc_resume(struct platform_device *pdev)
3092 #define rk3288_lcdc_suspend NULL
3093 #define rk3288_lcdc_resume NULL
3096 static int rk3288_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
3098 struct device_node *np = lcdc_dev->dev->of_node;
3100 if (of_property_read_u32(np, "rockchip,prop", &val))
3101 lcdc_dev->prop = PRMRY; /*default set it as primary */
3103 lcdc_dev->prop = val;
3105 if (of_property_read_u32(np, "rockchip,pwr18", &val))
3106 lcdc_dev->pwr18 = false; /*default set it as 3.xv power supply */
3108 lcdc_dev->pwr18 = (val ? true : false);
3112 static int rk3288_lcdc_probe(struct platform_device *pdev)
3114 struct lcdc_device *lcdc_dev = NULL;
3115 struct rk_lcdc_driver *dev_drv;
3116 struct device *dev = &pdev->dev;
3117 struct resource *res;
3118 struct device_node *np = pdev->dev.of_node;
3122 /*if the primary lcdc has not registered ,the extend
3123 lcdc register later */
3124 of_property_read_u32(np, "rockchip,prop", &prop);
3125 if (prop == EXTEND) {
3126 if (!is_prmry_rk_lcdc_registered())
3127 return -EPROBE_DEFER;
3129 lcdc_dev = devm_kzalloc(dev,
3130 sizeof(struct lcdc_device), GFP_KERNEL);
3132 dev_err(&pdev->dev, "rk3288 lcdc device kmalloc fail!");
3135 platform_set_drvdata(pdev, lcdc_dev);
3136 lcdc_dev->dev = dev;
3137 rk3288_lcdc_parse_dt(lcdc_dev);
3138 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3139 lcdc_dev->reg_phy_base = res->start;
3140 lcdc_dev->len = resource_size(res);
3141 lcdc_dev->regs = devm_ioremap_resource(dev, res);
3142 if (IS_ERR(lcdc_dev->regs))
3143 return PTR_ERR(lcdc_dev->regs);
3145 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
3146 if (IS_ERR(lcdc_dev->regsbak))
3147 return PTR_ERR(lcdc_dev->regsbak);
3148 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
3149 lcdc_dev->id = rk3288_lcdc_get_id(lcdc_dev->reg_phy_base);
3150 if (lcdc_dev->id < 0) {
3151 dev_err(&pdev->dev, "no such lcdc device!\n");
3154 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
3155 dev_drv = &lcdc_dev->driver;
3157 dev_drv->prop = prop;
3158 dev_drv->id = lcdc_dev->id;
3159 dev_drv->ops = &lcdc_drv_ops;
3160 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
3161 spin_lock_init(&lcdc_dev->reg_lock);
3163 lcdc_dev->irq = platform_get_irq(pdev, 0);
3164 if (lcdc_dev->irq < 0) {
3165 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
3170 ret = devm_request_irq(dev, lcdc_dev->irq, rk3288_lcdc_isr,
3171 IRQF_DISABLED | IRQF_SHARED, dev_name(dev), lcdc_dev);
3173 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
3174 lcdc_dev->irq, ret);
3178 if(lcdc_dev->id == 0){
3179 strcpy(dev_drv->mmu_dts_name, "iommu,vopb_mmu");
3181 strcpy(dev_drv->mmu_dts_name, "iommu,vopl_mmu");
3185 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
3187 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
3190 lcdc_dev->screen = dev_drv->screen0;
3192 dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
3197 static int rk3288_lcdc_remove(struct platform_device *pdev)
3203 static void rk3288_lcdc_shutdown(struct platform_device *pdev)
3205 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
3207 rk3288_lcdc_deint(lcdc_dev);
3208 rk_disp_pwr_disable(&lcdc_dev->driver);
3211 #if defined(CONFIG_OF)
3212 static const struct of_device_id rk3288_lcdc_dt_ids[] = {
3213 {.compatible = "rockchip,rk3288-lcdc",},
3218 static struct platform_driver rk3288_lcdc_driver = {
3219 .probe = rk3288_lcdc_probe,
3220 .remove = rk3288_lcdc_remove,
3222 .name = "rk3288-lcdc",
3223 .owner = THIS_MODULE,
3224 .of_match_table = of_match_ptr(rk3288_lcdc_dt_ids),
3226 .suspend = rk3288_lcdc_suspend,
3227 .resume = rk3288_lcdc_resume,
3228 .shutdown = rk3288_lcdc_shutdown,
3231 static int __init rk3288_lcdc_module_init(void)
3233 return platform_driver_register(&rk3288_lcdc_driver);
3236 static void __exit rk3288_lcdc_module_exit(void)
3238 platform_driver_unregister(&rk3288_lcdc_driver);
3241 fs_initcall(rk3288_lcdc_module_init);
3242 module_exit(rk3288_lcdc_module_exit);