主题 : 在QQ2440上解决了移植2.6.24内核的LCD驱动移植问题 复制链接 | 浏览器收藏 | 打印
会当凌绝顶,一览众山小!
级别: 总版主
UID: 2
精华: 17
发帖: 1655
金钱: 13860 两
威望: 5369 点
贡献值: 17 点
综合积分: 3650 分
注册时间: 2008-01-01
最后登录: 2024-02-17
楼主  发表于: 2008-03-26 11:08

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

作者:无名小卒

因为项目所要求的是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内核中的详细配置: 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,
},
}; 而在2.6.24内核中有了重大的数据结构变化,首先他把结构拆成了二部分,一个结构是s3c2410fb_display另一个结构是s3c2410fb_mach_info,所以先根据这二个数据结构进行拆分上述结构 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,
}; 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寄存器值的函数 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);
} 可以从这个函数中看到对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),问题解决了,屏出现了小企鹅。
友善之臂淘宝直销店:http://shop34928758.taobao.com

手机:13560352861(杨工),QQ:10108270
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2008-03-26 11:49
重新修正了一下格式:

作者:无名小卒

因为项目所要求的是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内核中的详细配置:

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,
},
};

而在2.6.24内核中有了重大的数据结构变化,首先他把结构拆成了二部分,一个结构是s3c2410fb_display另一个结构是s3c2410fb_mach_info,所以先根据这二个数据结构进行拆分上述结构

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,
};

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寄存器值的函数

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);
}

可以从这个函数中看到对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),问题解决了,屏出现了小企鹅。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
会当凌绝顶,一览众山小!
级别: 总版主
UID: 2
精华: 17
发帖: 1655
金钱: 13860 两
威望: 5369 点
贡献值: 17 点
综合积分: 3650 分
注册时间: 2008-01-01
最后登录: 2024-02-17
2楼  发表于: 2008-03-26 15:18
呵呵!谢谢!
友善之臂淘宝直销店:http://shop34928758.taobao.com

手机:13560352861(杨工),QQ:10108270