linux24内核驱动,解决了移植2.6.24内核的LCD驱动移植问题

解决了移植2.6.24内核的LCD驱动移植问题

发布时间:2008-03-27 13:35:26来源:红联作者:ylnyzl

因为项目所要求的是VGA的显示,但是我在移植了2.6.24内核后对LCD的驱动进行修改发现根本无法看到具体效果,于是我就想通过我自己的QQ2440开发板先做一下测试,因为QQ2440开发板我买时带一块3.5英寸的TFT屏,故先于昨天对其进行了2.6.24内核的LCD移植测试,基本上测试我没有查相关的LCD屏的手册,相信那些内容根据《S3C2410 下LCD 驱动程序移植及GUI 程序编写》这篇文章都能看明白具体寄存器的作用,本文重点对2.6.24的LCD差别部分进行说明,以给有同样问题出现的朋友一个捷径,首先,我想说明一下,在编译内核时需要在system type中选中 S3C2410 Machines中选中 SMDK2410/A9M2410,固然友善的QQ2440是s3c2440的ARM,但是不选中上述项就会在编译内核时出现缺少一个函数的错误,这个是2.6.24编译时发现的bug,另外,修改LCD的驱动文件得注意,因为选中了2410选项,需要针对arch/arm/mach-s3c2410/文件下的mach-smdk2410.c进行,不是2440的那个文件夹,开始我一直在2440的那个文件夹下对mach-smdk2440.c修改并让系统打印出信息,发现始终不行,就想是选中了2410的原因了,下边详情:

QQ2440出厂时内核2.6.13原LCD信息如下:

这是在2.6.13内核中的详细配置:[code]static struct s3c2410fb_mach_info sbc2440_lcdcfg __initdata = {

.regs = {

.lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \

S3C2410_LCDCON1_TFT | \

S3C2410_LCDCON1_CLKVAL(0x03),

.lcdcon2 = S3C2410_LCDCON2_VBPD(3) | \

S3C2410_LCDCON2_LINEVAL(239) | \

S3C2410_LCDCON2_VFPD(5) | \

S3C2410_LCDCON2_VSPW(15),

.lcdcon3 = S3C2410_LCDCON3_HBPD(5) | \

S3C2410_LCDCON3_HOZVAL(319) | \

S3C2410_LCDCON3_HFPD(15),

.lcdcon4 = S3C2410_LCDCON4_MVAL(13) | \

S3C2410_LCDCON4_HSPW(8),

.lcdcon5 = S3C2410_LCDCON5_FRM565 |

S3C2410_LCDCON5_INVVLINE |

S3C2410_LCDCON5_INVVFRAME |

S3C2410_LCDCON5_PWREN |

S3C2410_LCDCON5_HWSWP,

},

.lpcsel = 0xf82,

.gpccon = 0xaa955699,

.gpccon_mask = 0xffc003cc,

.gpcup = 0x0000ffff,

.gpcup_mask = 0xffffffff,

.gpdcon = 0xaa95aaa1,

.gpdcon_mask = 0xffc0fff0,

.gpdup = 0x0000faff,

.gpdup_mask = 0xffffffff,

.fixed_syncs = 1,

.width = 320,

.height = 240,

.xres = {

.min = 320,

.max = 320,

.defval = 320,

},

.yres = {

.max = 240,

.min = 240,

.defval = 240,

},

.bpp = {

.min = 16,

.max = 16,

.defval = 16,

},

};[/code]而在2.6.24内核中有了重大的数据结构变化,首先他把结构拆成了二部分,一个结构是s3c2410fb_display另一个结构是s3c2410fb_mach_info,所以先根据这二个数据结构进行拆分上述结构[code]static struct s3c2410fb_display smdk2410_lcd_cfg __initdata = {

.lcdcon5 = S3C2410_LCDCON5_FRM565 |

S3C2410_LCDCON5_INVVLINE |

S3C2410_LCDCON5_INVVFRAME |

S3C2410_LCDCON5_PWREN |

S3C2410_LCDCON5_HWSWP,

.type = S3C2410_LCDCON1_TFT,

.width = 320,

.height = 240,

.pixclock = 174757,

.xres = 320,

.yres = 240,

.bpp = 16,

.left_margin = 16,

.right_margin = 6,

.hsync_len = 9,

.upper_margin = 4,

.lower_margin = 6,

.vsync_len = 16,

};

static struct s3c2410fb_mach_info smdk2410_fb_info __initdata = {

.displays = &smdk2410_lcd_cfg,

.num_displays = 1,

.default_display = 0,

.gpccon = 0xaa955699,

.gpccon_mask = 0xffc003cc,

.gpcup = 0x0000ffff,

.gpcup_mask = 0xffffffff,

.gpdcon = 0xaa95aaa1,

.gpdcon_mask = 0xffc0fff0,

.gpdup = 0x0000faff,

.gpdup_mask = 0xffffffff,

.lpcsel = 0xf82,

};[/code]2.6.24结构中对寄存器lcdcon1-4全部用函数进行了自动设置,我们只需对lcdcon5进行设置,但是并不说明其他的数据不重要,或者不用设置,重点在这几个数值上

引用:

.left_margin = 16,根据下边的函数S3C2410_LCDCON3_HFPD(var->left_margin - 1)

.right_margin = 6,同上,以此类推

.hsync_len = 9,同上,以此类推

.upper_margin = 4, 同上,以此类推

.lower_margin = 6,同上,以此类推

.vsync_len = 16,同上,以此类推

这些数据的由来是我对比着2.6.24中自动生成lcdcon1-4寄存器值的函数[code]static void s3c2410fb_calculate_tft_lcd_regs(const struct fb_info *info,

struct s3c2410fb_hw *regs)

{

const struct s3c2410fb_info *fbi = info->par;

const struct fb_var_screeninfo *var = &info->var;

switch (var->bits_per_pixel) {

case 1:

regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;

break;

case 2:

regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;

break;

case 4:

regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;

break;

case 8:

regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;

regs->lcdcon5 |= S3C2410_LCDCON5_BSWP |

S3C2410_LCDCON5_FRM565;

regs->lcdcon5 &= ~S3C2410_LCDCON5_HWSWP;

break;

case 16:

regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;

regs->lcdcon5 &= ~S3C2410_LCDCON5_BSWP;

regs->lcdcon5 |= S3C2410_LCDCON5_HWSWP;

break;

case 32:

regs->lcdcon1 |= S3C2410_LCDCON1_TFT24BPP;

regs->lcdcon5 &= ~(S3C2410_LCDCON5_BSWP |

S3C2410_LCDCON5_HWSWP |

S3C2410_LCDCON5_BPP24BL);

break;

default:

/* invalid pixel depth */

dev_err(fbi->dev, "invalid bpp %d\n",

var->bits_per_pixel);

}

/* update X/Y info */

dprintk("setting vert: up=%d, low=%d, sync=%d\n",

var->upper_margin, var->lower_margin, var->vsync_len);

dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",

var->left_margin, var->right_margin, var->hsync_len);

regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1) |

S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |

S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |

S3C2410_LCDCON2_VSPW(var->vsync_len - 1);

regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) |

S3C2410_LCDCON3_HFPD(var->left_margin - 1) |

S3C2410_LCDCON3_HOZVAL(var->xres - 1);

regs->lcdcon4 = S3C2410_LCDCON4_HSPW(var->hsync_len - 1);

}[/code]可以从这个函数中看到对TFT,如果你为STN就看另一个函数,对我们数据结构中的值进行了自动换算,所以我就根据QQ2440板载的2.6.13的相关数据结构(见本文最上边的结构值)进行了换算并赋值,例如S3C2410_LCDCON3_HFPD(var->left_margin - 1)的公式看一下最上边的是S3C2410_LCDCON3_HFPD(15),所以.left_margin = 16,同理,其他的数值以此换算,最后,在smdk2410_init()函数中增加s3c24xx_fb_set_platdata(&smdk2410_fb_info),问题解决了,屏出现了小企鹅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值