6410参照韦老师写的LCD驱动无法注册以及显示位移的问题
把内核自带的LCD驱动删除掉以后,自己写的LCD 驱动每次都在register_framebuffer(info);时出现段错误,当不删除内核自带的LCD驱动时,把自己的LCD驱动注册为fb1时,可以注册成功,并且能够用tislib成功测试,代码如下
static int cnt;
static struct fb_info *info,fbinfo;
struct fb_ops s3cfb_ops = {
.owner = THIS_MODULE,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
};
int request_io(void)
{
printk("\nget in the IO\n");
/* ss=request_mem_region(0x71200010,0x04,"fb0");
if(!ss)
{
printk("\nrequest VIC0INTENABLE failed\n");
return -ENXIO;
}
ss=ioremap(0x71200010,0x04);
if(!ss)
{
printk("\nioremap VIC0INTENABLE failed\n");
return -ENXIO;
}*/
k=request_mem_region(0x7F008100,0x0c,"fb0");
if(!k)
{
printk("\nrequest GPICON_IO failed\n");
return -ENXIO;
}
k=ioremap(0x7F008100,0x0c);
if(!k)
{
printk("\nioremap GPICON_IO failed\n");
return -ENXIO;
}
zz=request_mem_region(0x7F006000,0x48,"fb0");
if(!zz)
{
printk("\nrequest PWMTIMER_BASE failed\n");
return -ENXIO;
}
zz=ioremap(0x7F006000,0x48);
if(!zz)
{
printk("\nioremap PWMTIMER_BASE failed\n");
return -ENXIO;
}
b=request_mem_region(0x7E00F030,0x04,"fb0");
if(!b)
{
printk("\nrequest HCLK_GATE failed\n");
return -ENXIO;
}
b=ioremap(0x7E00F030,0x04);
if(!b)
{
printk("\nioremap HCLK_GATE failed\n");
return -ENXIO;
}
xx=request_mem_region(0x7F008080,0x28,"fb0");
if(!xx)
{
printk("\nrequest GPECON failed\n");
return -ENXIO;
}
xx=ioremap(0x7F008080,0x28);
if(!xx)
{
printk("\nioremap GPECON failed\n");
return -ENXIO;
}
x=request_mem_region(0x7F008120,0x0c,"fb0");
if(!x)
{
printk("\nrequest GPJCON_IO failed\n");
return -ENXIO;
}
x=ioremap(0x7F008120,0x0c);
if(!x)
{
printk("\nioremap GPJCON_IO failed\n");
return -ENXIO;
}
y=request_mem_region(0x7F0081A0,0x04,"fb0");
if(!y)
{
printk("\nrequest SPCON failed\n");
return 0;
}
y=ioremap(0x7F0081A0,0x04);
if(!y)
{
printk("\nioremap SPCON failed\n");
return 0;
}
l=request_mem_region(0x7410800C,0x04,"fb0");
if(!l)
{
printk("\nrequest MIFPCON failed\n");
return -ENXIO;
}
l=ioremap(0x7410800C,0x04);
if(!l)
{
printk("\nioremap MIFPCON failed\n");
return -ENXIO;
}
printk("finish the io\n");
}
int __devinit s3cfb_init(void)
{
info= framebuffer_alloc(0, NULL);
if (!info)
return -ENOMEM;
printk(KERN_EMERG"finish the framebuffer");
strcpy(info->fix.id,"s3ccfb");
printk(KERN_EMERG"finish the strcpy");
info->fix.smem_len=480*800*16/8;
info->fix.type=FB_TYPE_PACKED_PIXELS;
info->fix.visual=FB_VISUAL_TRUECOLOR;
info->fix.line_length=800*2;
info->var.xres=800;
info->var.yres=480;
info->var.xres_virtual=800;
info->var.yres_virtual=480;
info->var.bits_per_pixel=16;
info->var.red.offset=11;
info->var.red.length=5;
info->var.green.offset=5;
info->var.green.length=6;
info->var.blue.offset=0;
info->var.blue.length=5;
info->var.activate=FB_ACTIVATE_NOW;
info->fbops=&s3cfb_ops;
//s3c_lcd->screen_baseisvirtual address
info->screen_size=480*800*2;
//s3c_lcd->fix.smem_startis physical address
request_io();
value=readl(HCLK_GATE);
value=value|1<<3;
writel(value,HCLK_GATE);
mm=ioremap(0x77100000,0x350);
if (mm == NULL) {
printk(KERN_EMERG"ioremap() of registers failed\n");
return -ENOMEM;
}
printk(KERN_EMERG"finish the ioremap");
value=0x00011111;
writel(value,lu_GPECON);
value=0x00000001;
writel(value,lu_GPEDAT);
value=0x8AAAAAAA;
writel(value,lu_GPFCON);
value=0x00000000;
writel(value,lu_GPFDAT);
value=0x80000000;
writel(value,lu_GPFPUD);
value=0xAAAAAAAA;
writel(value,lu_GPICON);
value=0x00AAAAAA;
writel(value,lu_GPJCON);
value=0x15<<16 | 0x16<<8 | 0x02<<0;
writel(value,S3C_VIDTCON0);
value=0x2C<<16 | 0xD2<<8 | 0x02<<0;
writel(value,S3C_VIDTCON1);
value=(480 - 1)<<11|(800 - 1);
writel(value,S3C_VIDTCON2);
value=1<<19|1<<15|1<<12|1;
writel(value,S3C_VIDINTCON0);
value=readl(S3C_VIDINTCON1);
writel(value,S3C_VIDINTCON1);
value=readl(lu_MIFPCON);
value=value&~(1<<3);
writel(value,lu_MIFPCON);
value=readl(lu_SPCON);
value =(value & ~(0x3)) | 1;
writel(value,lu_SPCON);
value=2<<5|1<<3|2<<1|1;
writel(value,S3C_DITHMODE);
value = request_irq(62, s3_irq, 0, "s3ccfb", NULL);
if (value != 0) {
printk("s3c_ts.c: Could not request lcd_irq !\n");
return -EIO;
}
value=(0<<26)|(0<<17)|(0<<16)|(3<<6)|(0<<5)|(1<<4)|(0<<2);
writel(value,S3C_VIDCON0);
value=readl(S3C_VIDCON1);
value |= 1<<5|1<<6;
writel(value,S3C_VIDCON1);
value=0;
writel(value,S3C_VIDOSD0A);
value=(800 - 1)<<11 |(480 - 1);
writel(value,S3C_VIDOSD0B);
value=480*800*2;
writel(value,S3C_VIDOSD0C);
value=readl(S3C_WINCON0);
value |= 1<<0;
value &= ~(0xf << 2);
value |= 0x5<<2;
writel(value,S3C_WINCON0);
info->screen_base = dma_alloc_writecombine(NULL, info->fix.smem_len,&info->fix.smem_start, GFP_KERNEL);
printk(KERN_EMERG"finish the dma_alloc_writecombine");
value=info->fix.smem_start;
writel(value,S3C_VIDW00ADD0B0);
value=(info->fix.smem_start+info->fix.smem_len)&0xFFFFFF;
writel(value,S3C_VIDW00ADD1B0);
/*value= request_irq(55, do_irq, IRQF_DISABLED, "LCD", NULL);
if (value != 0) {
printk("s3c_ts.c: Could not request timer_irq !\n");
return -EIO;
}*/
pwm(50);
printk("register framebuffer\n");
value=readl(S3C_VIDCON0);
value=value|3;
writel(value,S3C_VIDCON0);
value=register_framebuffer(info);
if (value < 0) {
printk(KERN_EMERG"Failed to register framebuffer device");}
printk("finish the insmod\n");
return 0;
}
问题1:当删除系统自带驱动,注册自己的LCD驱动fb0以后,文字出现位移导致不清楚的图片,这是用tislib测试时打印出的代码,明显的能看出来这个箭头的光标行与行之间有漂移,位置不对,到底是什么原因会导致这样的问题呀,而且自己的驱动注册fb0成功只能把register_framebuffer(info);函数写在int __devinit s3cfb_init(void)函数的ioremap()函数之前,一旦写在ioremap()函数之后,就无法注册成功了,出现段错误。
问题2:当不删除系统自带的LCD驱动,也就是已经有了fb0,注册自己的驱动fb1时,不管register_framebuffer(info)函数写在int __devinit s3cfb_init(void)函数的什么位置,都能调用成功,而且当用tislib测试自己的FB1 LCD驱动时画面显示正常,一点问题都没有,和上面问题1作对比,感觉有没有去掉系统驱动对我的驱动影响很大,不知道为什么会这样,已经纠结这个问题几个月了,求高手指点迷津,不甚感谢!!!
听起来像是你的fb0与fb1用的同一块buffer,然后系统起来默认会对fb0进行初始化,你后面再用fb1就正常了,应该查下上层是怎么初始化fb0的吧
页:
[1]