From d497efb8ff02775f2ad5197f8151cc9f9f38d91b Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=92=9F=E5=8B=87=E6=B1=AA?= Date: Wed, 19 May 2010 14:35:01 +0000 Subject: [PATCH] update win0 i2p --- drivers/video/rk2818_fb.c | 236 ++++++++++++++++++++++++-------------- 1 file changed, 150 insertions(+), 86 deletions(-) diff --git a/drivers/video/rk2818_fb.c b/drivers/video/rk2818_fb.c index f3b16665b657..3ac0473e39e3 100644 --- a/drivers/video/rk2818_fb.c +++ b/drivers/video/rk2818_fb.c @@ -62,7 +62,7 @@ #define CURSOR_BUF_SIZE 256 //RK2818 cursor need 256B buf -#if 1 +#if 0 #define fbprintk(msg...) printk(msg); #else #define fbprintk(msg...) @@ -423,8 +423,7 @@ int init_lcdc(struct fb_info *info) u32 reg1=0, reg2=0, msk=0, clr=0; fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__); - fbprintk(">>>>>> inf %x ; inf->regbak%x ; inf->preg %x \n", inf, &inf->regbak, inf->preg); - fbprintk(">>>>>> %x ; %x \n", &(inf->regbak.SYS_CONFIG), &(inf->preg->SYS_CONFIG)); + // set AHB access rule and disable all windows LcdMskReg(inf, SYS_CONFIG, m_W1_ROLLER | m_W0_ROLLER | m_INTERIACE_EN | m_MPEG2_I2P_EN | m_W0_ROTATE | @@ -581,25 +580,6 @@ void load_screen(struct fb_info *info, bool initscreen) fbprintk(">>>>>> set lcdc dclk need %d HZ, clk_parent = %d hz \n ", screen->pixclock, clk_rate); - if(clk_rate < dclk_rate) - { - clk_rate = dclk_rate; - ret = clk_set_rate(inf->dclk_parent, clk_rate); - if(ret) - { - printk(KERN_ERR ">>>>>> set lcdc dclk_parent faild clk_rate = %d \n ", clk_rate); - } - } - else if((clk_rate > dclk_rate) && (clk_rate % dclk_rate)) - { - clk_rate = clk_rate/dclk_rate * dclk_rate; - ret = clk_set_rate(inf->dclk_parent, clk_rate); - if(ret) - { - printk(KERN_ERR ">>>>>> set lcdc dclk_parent faild clk_rate = %d \n ", clk_rate); - } - } - ret = clk_set_rate(inf->dclk_divider, dclk_rate); if(ret) @@ -845,6 +825,7 @@ static int win0fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->bits_per_pixel = 32; break; } + var->nonstd &= 0xFCFF; //not support I2P in this format break; case 1: // yuv422 var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3); @@ -866,6 +847,7 @@ static int win0fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->yres = (var->yres + 0x1) & (~0x1); var->xoffset = (var->xoffset) & (~0x3); var->yoffset = (var->yoffset) & (~0x1); + var->nonstd &= 0xFCFF; //not support I2P in this format break; case 4: // yuv420m var->xres_virtual = (var->xres_virtual + 0x7) & (~0x7); @@ -874,11 +856,13 @@ static int win0fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->yres = (var->yres + 0x1) & (~0x1); var->xoffset = (var->xoffset) & (~0x7); var->yoffset = (var->yoffset) & (~0x1); + var->nonstd &= 0xFCFF; //not support I2P in this format break; case 5: // yuv444 var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3); var->xres = (var->xres + 0x3) & (~0x3); var->xoffset = (var->xoffset) & (~0x3); + var->nonstd &= 0xFCFF; //not support I2P in this format break; default: printk(">>>>>> win0fb var->nonstd=%d is invalid! \n", var->nonstd); @@ -914,39 +898,53 @@ static int win0fb_set_par(struct fb_info *info) u8 format = 0; dma_addr_t map_dma; - u32 y_offset=0, uv_offset=0, cblen=0, crlen=0, map_size=0, smem_len=0; - u16 xpos = (var->nonstd>>8) & 0xfff; - u16 ypos = (var->nonstd>>20) & 0xfff; - u16 xsize = (var->grayscale>>8) & 0xfff; - u16 ysize = (var->grayscale>>20) & 0xfff; - u32 win0_en = var->reserved[2]; - u32 y_addr = var->reserved[3]; - u32 uv_addr = var->reserved[4]; + u32 y_offset=0, uv_offset=0, cblen=0, crlen=0, map_size=0, smem_len=0, i2p_len=0; + u32 pre_y_addr = 0, pre_uv_addr = 0, nxt_y_addr = 0, nxt_uv_addr = 0; + u32 actWidth = 0; u32 actHeight = 0; + u32 xact = var->xres; /* visible resolution */ + u32 yact = var->yres; + u32 xvir = var->xres_virtual; /* virtual resolution */ + u32 yvir = var->yres_virtual; + u32 xact_st = var->xoffset; /* offset from virtual to visible */ + u32 yact_st = var->yoffset; /* resolution */ + + u16 xpos = (var->nonstd>>8) & 0xfff; //visiable pos in panel + u16 ypos = (var->nonstd>>20) & 0xfff; + u16 xsize = (var->grayscale>>8) & 0xfff; //visiable size in panel + u16 ysize = (var->grayscale>>20) & 0xfff; + u32 ScaleYUpX=0x1000, ScaleYDnX=0x1000, ScaleYUpY=0x1000, ScaleYDnY=0x1000; u32 ScaleCbrUpX=0x1000, ScaleCbrDnX=0x1000, ScaleCbrUpY=0x1000, ScaleCbrDnY=0x1000; + u8 i2p_mode = (var->nonstd & 0x0100)>>8; + u8 i2p_polarity = (var->nonstd & 0x0200)>>9; + u8 data_format = var->nonstd&0xff; + u32 win0_en = var->reserved[2]; + u32 y_addr = var->reserved[3]; //user alloc buf addr y + u32 uv_addr = var->reserved[4]; + fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__); CHK_SUSPEND(inf); /* calculate y_offset,uv_offset,line_length,cblen and crlen */ - switch(var->nonstd&0xff) + switch (data_format) { case 0: // rgb switch(var->bits_per_pixel) { case 16: // rgb565 format = 1; - fix->line_length = 2 * var->xres_virtual; - y_offset = (var->yoffset*var->xres_virtual + var->xoffset)*2; + fix->line_length = 2 * xvir; + y_offset = (yact_st*xvir + xact_st)*2; break; case 32: // rgb888 format = 0; - fix->line_length = 4 * var->xres_virtual; - y_offset = (var->yoffset*var->xres_virtual + var->xoffset)*4; + fix->line_length = 4 * xvir; + y_offset = (yact_st*xvir + xact_st)*4; break; default: return -EINVAL; @@ -954,61 +952,69 @@ static int win0fb_set_par(struct fb_info *info) break; case 1: // yuv422 format = 2; - fix->line_length = var->xres_virtual; - y_offset = var->yoffset*var->xres_virtual + var->xoffset; - uv_offset = var->yoffset*var->xres_virtual + var->xoffset; + fix->line_length = xvir; + y_offset = yact_st*xvir + xact_st; + uv_offset = yact_st*xvir + xact_st; if(var->rotate == 270) { - y_offset += var->xres_virtual*(var->yres - 1); - uv_offset += var->xres_virtual*(var->yres - 1); + y_offset += xvir*(yact- 1); + uv_offset += xvir*(yact - 1); + } + cblen = crlen = (xvir*yvir)/2; + if(i2p_mode) + { + i2p_len = (xvir*yvir)*2; } - cblen = crlen = (var->xres_virtual*var->yres_virtual)/2; break; case 2: // yuv4200 format = 3; - fix->line_length = var->xres_virtual; - y_offset = var->yoffset*var->xres_virtual + var->xoffset; - uv_offset = (var->yoffset/2)*var->xres_virtual + var->xoffset; + fix->line_length = xvir; + y_offset = yact_st*xvir + xact_st; + uv_offset = (yact_st/2)*xvir + xact_st; if(var->rotate == 270) { - y_offset += var->xres_virtual*(var->yres - 1); - uv_offset += var->xres_virtual*(var->yres/2 - 1); + y_offset += xvir*(yact - 1); + uv_offset += xvir*(yact/2 - 1); + } + cblen = crlen = (xvir*yvir)/4; + if(i2p_mode) + { + i2p_len = (xvir*yvir)*3/2; } - cblen = crlen = (var->xres_virtual*var->yres_virtual)/4; break; case 3: // yuv4201 format = 4; - fix->line_length = var->xres_virtual; - y_offset = (var->yoffset/2)*2*var->xres_virtual + (var->xoffset)*2; - uv_offset = (var->yoffset/2)*var->xres_virtual + var->xoffset; + fix->line_length = xvir; + y_offset = (yact_st/2)*2*xvir + (xact_st)*2; + uv_offset = (yact_st/2)*xvir + xact_st; if(var->rotate == 270) { - y_offset += var->xres_virtual*2*(var->yres/2 - 1); - uv_offset += var->xres_virtual*(var->yres/2 - 1); + y_offset += xvir*2*(yact/2 - 1); + uv_offset += xvir*(yact/2 - 1); } - cblen = crlen = (var->xres_virtual*var->yres_virtual)/4; + cblen = crlen = (xvir*yvir)/4; break; case 4: // yuv420m format = 5; - fix->line_length = var->xres_virtual; - y_offset = (var->yoffset/2)*3*var->xres_virtual + (var->xoffset)*3; - cblen = crlen = (var->xres_virtual*var->yres_virtual)/4; + fix->line_length = xvir; + y_offset = (yact_st/2)*3*xvir + (xact_st)*3; + cblen = crlen = (xvir*yvir)/4; break; case 5: // yuv444 format = 6; - fix->line_length = var->xres_virtual; - y_offset = var->yoffset*var->xres_virtual + var->xoffset; - uv_offset = var->yoffset*2*var->xres_virtual + var->xoffset*2; - cblen = crlen = (var->xres_virtual*var->yres_virtual); + fix->line_length = xvir; + y_offset = yact_st*xvir + xact_st; + uv_offset = yact_st*2*xvir + xact_st*2; + cblen = crlen = (xvir*yvir); break; default: return -EINVAL; } - smem_len = fix->line_length * var->yres_virtual + cblen + crlen; + smem_len = fix->line_length * yvir + cblen + crlen + i2p_len; map_size = PAGE_ALIGN(smem_len); - if(y_addr && uv_addr) // buffer alloced by user + if(y_addr && uv_addr && !i2p_mode) // buffer alloced by user { if (info->screen_base) { printk(">>>>>> win0fb unmap memory(%d)! \n", info->fix.smem_len); @@ -1026,7 +1032,7 @@ static int win0fb_set_par(struct fb_info *info) if ( (smem_len != fix->smem_len) || !info->screen_base ) // buffer need realloc { fbprintk(">>>>>> win0 buffer size is change! remap memory!\n"); - fbprintk(">>>>>> smem_len %d = %d * %d + %d + %d\n", smem_len, fix->line_length, var->yres_virtual, cblen, crlen); + fbprintk(">>>>>> smem_len %d = %d * %d + %d + %d\n", smem_len, fix->line_length, yvir, cblen, crlen); fbprintk(">>>>>> map_size = %d\n", map_size); LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(0)); LcdWrReg(inf, REG_CFG_DONE, 0x01); @@ -1037,6 +1043,8 @@ static int win0fb_set_par(struct fb_info *info) info->screen_base = 0; fix->smem_start = 0; fix->smem_len = 0; + fix->reserved[1] = 0; + fix->reserved[2]= 0; } info->screen_base = dma_alloc_writecombine(NULL, map_size, &map_dma, GFP_KERNEL); @@ -1047,7 +1055,16 @@ static int win0fb_set_par(struct fb_info *info) memset(info->screen_base, 0x00, map_size); fix->smem_start = map_dma; fix->smem_len = smem_len; - fix->mmio_start = fix->smem_start + fix->line_length * var->yres_virtual; + fix->mmio_start = fix->smem_start + fix->line_length * yvir; + if(i2p_len) + { + fix->reserved[1] = fix->mmio_start + cblen + crlen; //next frame buf Y address in i2p mode + fix->reserved[2] = fix->reserved[1] + fix->line_length * yvir; //next frame buf UV address in i2p mode + } + else + { + fix->reserved[1] = fix->reserved[2]= 0; + } fbprintk(">>>>>> alloc succ, smem_start=%08x, smem_len=%d, mmio_start=%d!\n", (u32)fix->smem_start, fix->smem_len, (u32)fix->mmio_start); } @@ -1057,22 +1074,66 @@ static int win0fb_set_par(struct fb_info *info) par->uv_offset = uv_offset; // calculate the display phy address - y_addr = fix->smem_start + y_offset; - uv_addr = fix->mmio_start + uv_offset; + + if(i2p_mode && fix->reserved[1] && fix->reserved[2]) + { + if(i2p_polarity && (var->rotate==0)) //even + { + y_addr = fix->smem_start + (yact_st*xvir+xact_st) + xvir; + uv_addr = fix->mmio_start + (yact_st/data_format*xvir+xact_st) + xvir; + pre_y_addr = y_addr - xvir; + pre_uv_addr = uv_addr - xvir; + nxt_y_addr = fix->reserved[1] + (yact_st*xvir+xact_st); + nxt_uv_addr = fix->reserved[2] + (yact_st/data_format*xvir+xact_st); + } + else if(!i2p_polarity && (var->rotate==0)) //odd + { + y_addr = fix->reserved[1] + (yact_st*xvir+xact_st); + uv_addr = fix->reserved[2] + (yact_st/data_format*xvir+xact_st); + pre_y_addr = y_addr + xvir; + pre_uv_addr = uv_addr + xvir; + nxt_y_addr = fix->smem_start+ (yact_st*xvir+xact_st) + xvir; + nxt_uv_addr = fix->mmio_start + (yact_st/data_format*xvir+xact_st) + xvir; + } + else if(i2p_polarity && (var->rotate==270)) //even + { + y_addr = fix->smem_start+ (yact_st*xvir+xact_st) + xvir*(yact-1); + uv_addr = fix->mmio_start+ (yact_st/data_format*xvir+xact_st) + xvir*(yact/data_format-1); + pre_y_addr = fix->smem_start+ (yact_st*xvir+xact_st) + xvir*(yact-2); + pre_uv_addr = fix->mmio_start+ (yact_st/data_format*xvir+xact_st) + xvir*(yact/data_format-2); + nxt_y_addr = fix->reserved[1] + (yact_st*xvir+xact_st) + xvir*(yact-2); + nxt_uv_addr = fix->reserved[2] + (yact_st/data_format*xvir+xact_st) + xvir*(yact/data_format-2); + } + else if(!i2p_polarity&& (var->rotate==270)) //odd + { + y_addr = fix->reserved[1]+ (yact_st*xvir+xact_st) + xvir*(yact-2); + uv_addr = fix->reserved[2]+ (yact_st/data_format*xvir+xact_st) + xvir*(yact/data_format-2); + pre_y_addr = fix->reserved[1]+ (yact_st*xvir+xact_st) + xvir*(yact-1); + pre_uv_addr = fix->reserved[2]+ (yact_st/data_format*xvir+xact_st) + xvir*(yact/data_format-1); + nxt_y_addr = fix->smem_start + (yact_st*xvir+xact_st) + xvir*(yact-1); + nxt_uv_addr = fix->mmio_start + (yact_st/data_format*xvir+xact_st) + xvir*(yact/data_format-1); + } + } + else + { + y_addr = fix->smem_start + y_offset; + uv_addr = fix->mmio_start + uv_offset; + } + fbprintk("y_addr 0x%08x = 0x%08x + %d\n", y_addr, (u32)fix->smem_start, y_offset); fbprintk("uv_addr 0x%08x = 0x%08x + %d\n", uv_addr, (u32)fix->mmio_start , uv_offset); if(var->rotate == 270) { - actWidth = var->yres; - actHeight = var->xres; + actWidth = yact; + actHeight = xact; } else { - actWidth = var->xres; - actHeight = var->yres; + actWidth = xact; + actHeight = yact; } - if((var->xres>1280) && (xsize>1280)) + if((xact>1280) && (xsize>1280)) { ScaleYDnX = CalScaleDownW0(actWidth, 1280); ScaleYUpX = CalScaleUpW0(1280, xsize); @@ -1086,10 +1147,10 @@ static int win0fb_set_par(struct fb_info *info) ScaleYDnY = CalScaleDownW0(actHeight, ysize); ScaleYUpY = CalScaleUpW0(actHeight, ysize); - switch(var->nonstd&0xff) + switch (data_format) { case 1:// yuv422 - if((var->xres>1280) && (xsize>1280)) + if((xact>1280) && (xsize>1280)) { ScaleCbrDnX= CalScaleDownW0((actWidth/2), 1280); ScaleCbrUpX = CalScaleUpW0((640), xsize); @@ -1114,7 +1175,7 @@ static int win0fb_set_par(struct fb_info *info) case 2: // yuv4200 case 3: // yuv4201 case 4: // yuv420m - if((var->xres>1280) && (xsize>1280)) + if((xact>1280) && (xsize>1280)) { ScaleCbrDnX= CalScaleDownW0(actWidth/2, 1280); ScaleCbrUpX = CalScaleUpW0(640, xsize); @@ -1129,7 +1190,7 @@ static int win0fb_set_par(struct fb_info *info) ScaleCbrUpY = CalScaleUpW0(actHeight/2, ysize); break; case 5:// yuv444 - if((var->xres>1280) && (xsize>1280)) + if((xact>1280) && (xsize>1280)) { ScaleCbrDnX= CalScaleDownW0(actWidth, 1280); ScaleCbrUpX = CalScaleUpW0(1280, xsize); @@ -1150,10 +1211,10 @@ static int win0fb_set_par(struct fb_info *info) LcdWrReg(inf, WIN0_YRGB_MST, y_addr); LcdWrReg(inf, WIN0_CBR_MST, uv_addr); - LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE | m_W0_FORMAT | m_W0_ROTATE, - v_W0_ENABLE(win0_en) | v_W0_FORMAT(format) | v_W0_ROTATE(var->rotate==270)); + LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE | m_W0_FORMAT | m_W0_ROTATE | m_MPEG2_I2P_EN, + v_W0_ENABLE(win0_en) | v_W0_FORMAT(format) | v_W0_ROTATE(var->rotate==270) | v_MPEG2_I2P_EN(i2p_mode)); - LcdMskReg(inf, WIN0_VIR, m_WORDLO | m_WORDHI, v_VIRWIDTH(var->xres_virtual) | v_VIRHEIGHT((var->yres_virtual)) ); + LcdMskReg(inf, WIN0_VIR, m_WORDLO | m_WORDHI, v_VIRWIDTH(xvir) | v_VIRHEIGHT((yvir)) ); LcdMskReg(inf, WIN0_ACT_INFO, m_WORDLO | m_WORDHI, v_WORDLO(actWidth) | v_WORDHI(actHeight)); LcdMskReg(inf, WIN0_DSP_ST, m_BIT11LO | m_BIT11HI, v_BIT11LO(xpos) | v_BIT11HI(ypos)); LcdMskReg(inf, WIN0_DSP_INFO, m_BIT11LO | m_BIT11HI, v_BIT11LO(xsize) | v_BIT11HI(ysize)); @@ -1163,7 +1224,12 @@ static int win0fb_set_par(struct fb_info *info) LcdMskReg(inf, WIN0_SP_FACTOR_CBR, m_WORDLO | m_WORDHI, v_WORDLO(ScaleCbrUpX) | v_WORDHI(ScaleCbrUpY)); LcdMskReg(inf, DSP_CTRL0, m_I2P_THRESHOLD_Y | m_I2P_THRESHOLD_CBR | m_I2P_CUR_POLARITY | m_DROP_LINE_W0, - v_I2P_THRESHOLD_Y(0) | v_I2P_THRESHOLD_CBR(0)| v_I2P_CUR_POLARITY(0) | v_DROP_LINE_W0(0)); + v_I2P_THRESHOLD_Y(0) | v_I2P_THRESHOLD_CBR(0)| v_I2P_CUR_POLARITY(i2p_polarity) | v_DROP_LINE_W0(0)); + + LcdWrReg(inf, I2P_REF0_MST_Y, pre_y_addr); + LcdWrReg(inf, I2P_REF0_MST_CBR, pre_uv_addr); + LcdWrReg(inf, I2P_REF1_MST_Y, nxt_y_addr); + LcdWrReg(inf, I2P_REF1_MST_CBR, nxt_uv_addr); switch(format) { @@ -1728,7 +1794,7 @@ static int win1fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf addr = fix1->smem_start + offset; - fbprintk("info->screen_base = %8x ; fix1->smem_len = %d , addr = %8x\n",info->screen_base, fix1->smem_len, addr); + fbprintk("info->screen_base = %8x ; fix1->smem_len = %d , addr = %8x\n",(u32)info->screen_base, fix1->smem_len, addr); LcdWrReg(inf, WIN1_YRGB_MST, addr); LcdWrReg(inf, REG_CFG_DONE, 0x01); @@ -2069,8 +2135,7 @@ static int __init rk2818fb_probe (struct platform_device *pdev) dev_err(&pdev->dev, ">> inf kmalloc fail!"); ret = -ENOMEM; goto release_drvdata; - } - fbprintk(">> rk2818fb_inf addr = 0x%x \n", inf); + } memset(inf, 0, sizeof(struct rk2818fb_inf)); platform_set_drvdata(pdev, inf); @@ -2347,7 +2412,8 @@ static int __init rk2818fb_probe (struct platform_device *pdev) goto release_irq; } } - + + printk(" %s ok\n", __FUNCTION__); return ret; release_irq: @@ -2599,14 +2665,12 @@ static struct platform_driver rk2818fb_driver = { }; static int __init rk2818fb_init(void) -{ - printk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__); +{ return platform_driver_register(&rk2818fb_driver); } static void __exit rk2818fb_exit(void) { - printk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__); platform_driver_unregister(&rk2818fb_driver); } -- 2.34.1