s3c2440液晶屏驱动 (内核自带) linux-4.1.24
自带有一部分驱动的配置信息,只要修改这部分就能支援 不同的液晶屏 - /arch/arm/mach-s3c24xx/mach-smdk2440.c
另一部分在 /drivers/video/fbdev/s3c2410fb.c
先打开调试功能,这样内核在启动的时候,就可以输出这些信息,或者使用 dmesg 查看到这些信息。当然,你配置内核 make menuconfig 也可以打开,但是太麻烦了,不如这样。
1 #define CONFIG_FB_S3C2410_DEBUG 2 #define dprintk(msg...) \ 3 do { \ 4 if (debug) \ 5 printk(msg); \ 6 } while (0)
使用新内核启动,出现了调试信息,检查是否有错。
lcdcon[1] = 0x00000778
lcdcon[2] = 0x0743c183
lcdcon[3] = 0x0039df13
lcdcon[4] = 0x00000003
lcdcon[5] = 0x00000b01
LCDSADDR1 = 0x19d20000
LCDSADDR2 = 0x19d3fe00
LCDSADDR3 = 0x000001e0
检查时钟设置是否正确 0x00000778>>8 输出 8 ,应该设为 4
s3c2410fb_activate_var()
clkdiv = DIV_ROUND_UP(s3c2410fb_calc_pixclk(fbi, var->pixclock), 2);
配置是按 HCLK 60M 算的 .pixclock = 166667, /* HCLK 60 MHz, divisor 10 */
s3c2410fb_calc_pixclk() 这个函数里面进行计算。
unsigned long clk = fbi->clk_rate;
unsigned long long div;
/* pixclk is in picoseconds, our clock is in Hz
*
* Hz -> picoseconds is / 10^-12
*/
div = (unsigned long long)clk * pixclk;
div >>= 12; /* div / 2^12 */
do_div(div, 625 * 625UL * 625); /* div / 5^12 */
添加打印出 clk 检查是多少 , 果然是 100M
dprintk("pixclk %ld, divisor is %ld clk %d\n", pixclk, (long)div, clk);
return div;
((100000000 * 166667)>>12) / (5**12) = 16
((100000000 * 100000)>>12) / (5**12) = 10
所以 设为 .pixclock = 100000,// HCLK 100M
mach-smdk2440.c 中的修改地方
1 /* LCD driver info */ 2 3 static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = { 4 5 .lcdcon5 = S3C2410_LCDCON5_FRM565 | 6 S3C2410_LCDCON5_INVVLINE | 7 S3C2410_LCDCON5_INVVFRAME | 8 S3C2410_LCDCON5_HWSWP, 9 10 .type = S3C2410_LCDCON1_TFT, 11 12 .width = 480, 13 .height = 272, 14 15 .pixclock = 100000, /* HCLK 100 MHz, divisor 10 */ 16 .xres = 480, 17 .yres = 272, 18 .bpp = 16, 19 .left_margin = 2, 20 .right_margin = 2, 21 .hsync_len = 41, 22 .upper_margin = 2, 23 .lower_margin = 2, 24 .vsync_len = 10, 25 }; 26 27 static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = { 28 .displays = &smdk2440_lcd_cfg, 29 .num_displays = 1, 30 .default_display = 0, 31 32 /* currently setup by downloader */ 33 .gpccon = 0xaaaaaaaa, 34 .gpccon_mask = 0xffffffff, 35 36 37 .gpdcon = 0xaaaaaaaa, 38 .gpdcon_mask = 0xffffffff, 39 40 //.lpcsel = ((0xCE6) & ~7) | 1<<4, 41 };
因为在里面,不能配置 背光 和 POWER EN 。所以还需要在 s3c2410fb.c 中配置
s3c2410fb_init_registers()
1 modify_gpio(S3C2410_GPCUP, mach_info->gpcup, mach_info->gpcup_mask); 2 modify_gpio(S3C2410_GPCCON, mach_info->gpccon, mach_info->gpccon_mask); 3 modify_gpio(S3C2410_GPDUP, mach_info->gpdup, mach_info->gpdup_mask); 4 modify_gpio(S3C2410_GPDCON, mach_info->gpdcon, mach_info->gpdcon_mask); 5 6 //背光控制为 GPB0 配置 为输出引脚 7 writel(1<<0, S3C2410_GPBCON); 8 //默认打开背光 9 writel(1<<0, S3C2410_GPBDAT); 10 //配置 GPG4 为 LCD POWER EN 11 writel(3<<8, S3C2410_GPGCON);
参数都是逐个带进去算出来的,这个要看你的液晶屏 datasheet 接线来确定。
最后是试机图: