s3c2416 u-boot增加LCD驱动
2014-01-06 10:43
127 查看
这里使用的是广州斯道的icool2416开发板 u-boot版本1.3.4
主要增加LCD驱动 同时增加LCD与串口同步输出
修改如下:
在drivers/video(以u-boot源码为要目录)目录下增加以下文件gzsd2416-lcd.c,gzsd2416-lcd.h和s3cfb-reg.h内容如下:
gzsd2416-lcd.c ,LCD初始化与背光控制
文件开始加入以下声明:
效果如图:
其实还可以加一个背景图片的
感觉左边不是满屏显示 可以把HBP参数改小,关于logo显示的问题 把logo读到显存后u-boot就不往下跑了 好奇怪的现象,以前调6410 4.3寸的效果很好 换成7寸的后字体显示的也不是很漂亮了.
logo读进去其实很简单,至于不往下跑了 有兴趣的可以继续往下研究:
run_command("fatload mmc 0 0xc3c00000 logo.bin",0);
logo.bin文件可以使用Image2Lcd软件***得到
其中0xc3c00000是显存地址,在include/lcd.h中我们定义的:
主要增加LCD驱动 同时增加LCD与串口同步输出
修改如下:
在drivers/video(以u-boot源码为要目录)目录下增加以下文件gzsd2416-lcd.c,gzsd2416-lcd.h和s3cfb-reg.h内容如下:
gzsd2416-lcd.c ,LCD初始化与背光控制
/* * Gzsd2416 Framebuffer driver. * * Copyright 2013 Store information technology guangzhou ltd * hclydao <hclydao@gmail.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <common.h> #include <lcd.h> #include "gzsd2416-lcd.h" #include <config.h> #include <command.h> #include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; vidinfo_t panel_info = { S3CFB_HRES, S3CFB_VRES, 0, 0, PIXELBITS, }; void lcd_backlight(int enable) { unsigned long reg; reg = readl(GPBCON); reg &= ~(0x3 << 0); reg |= (0x1 << 0); writel(reg,GPBCON); reg = readl(GPBDAT); if(enable) reg |= (0x1 << 0); else reg &= ~(0x1 << 0); writel(reg, GPBDAT); } void lcd_disable (void) { VIDCON0_REG &= (~(VIDCON0_ENVID_ENABLE | VIDCON0_ENVID_F_ENABLE)); } void lcd_enable (void) { VIDCON0_REG |= (VIDCON0_ENVID_ENABLE | VIDCON0_ENVID_F_ENABLE); } void lcd_panel_disable(void) { //MIFPCON_REG |= SEL_BYPASS_MASK; } ulong calc_fbsize (void) { ulong size; int line_length = (panel_info.vl_col * panel_info.vl_bpix) / 8; size = line_length * panel_info.vl_row; return size; } void lcd_ctrl_init(void *lcdbase) { ulong freq_lcdclk; ulong freq_Hclk; ulong fb_size; unsigned char nn; GPCCON_REG = 0xaaaa02aa; GPCPU_REG = 0xaaaa02aa; GPDCON_REG = 0xaaaaaaaa; GPDPU_REG = 0xaaaaaaaa; lcd_disable(); WINCON0_REG &= ~WINCONx_ENWIN_F_ENABLE; WINCON1_REG &= ~WINCONx_ENWIN_F_ENABLE; freq_lcdclk = S3CFB_PIXEL_CLOCK; freq_Hclk = get_HCLK(); nn = (unsigned char)(freq_Hclk / freq_lcdclk) - 1; if(freq_lcdclk < freq_Hclk/2) { VIDCON0_REG = (VIDCON0_S_RGB_IF) | (VIDCON0_S_RGB_PAR) | (VIDCON0_S_VCLK_GATING_OFF) | (VIDCON0_S_CLKDIR_DIVIDED) | (VIDCON0_S_CLKSEL_HCLK) | VIDCON0_CLKVAL_F(nn); } else { VIDCON0_REG = (VIDCON0_S_RGB_IF) | (VIDCON0_S_RGB_PAR) | (VIDCON0_S_VCLK_GATING_OFF) | (VIDCON0_S_CLKDIR_DIVIDED) | (VIDCON0_S_CLKSEL_HCLK) | VIDCON0_CLKVAL_F(0); } VIDCON1_REG = ( VIDCON1_S_HSYNC_INVERTED) | (VIDCON1_S_VSYNC_INVERTED); VIDTCON0_REG = VIDTCON0_VBPD(S3CFB_VBP - 1) | VIDTCON0_VFPD(S3CFB_VFP - 1) | VIDTCON0_VSPW(S3CFB_VSW - 1); VIDTCON1_REG = VIDTCON1_HBPD(S3CFB_HBP - 1) | VIDTCON1_HFPD(S3CFB_HFP - 1) | VIDTCON1_HSPW(S3CFB_HSW - 1); VIDTCON2_REG = VIDTCON2_LINEVAL(S3CFB_VRES - 1) | VIDTCON2_HOZVAL(S3CFB_HRES - 1); WINCON0_REG = WINCONx_BPPMODE_F_16BPP_565 | WINCONx_HAWSWP_ENABLE; WINCON1_REG = WINCONx_BPPMODE_F_16BPP_565 | WINCONx_HAWSWP_ENABLE;// | WINCONx_BLD_PIX_PIXEL; VIDOSD0A_REG = VIDOSDxA_OSD_LTX_F(0) | VIDOSDxA_OSD_LTY_F(0); VIDOSD0B_REG = VIDOSDxB_OSD_RBX_F(S3CFB_HRES - 1) | VIDOSDxB_OSD_RBY_F(S3CFB_VRES - 1); VIDOSD1A_REG = VIDOSDxA_OSD_LTX_F(0) | VIDOSDxA_OSD_LTY_F(0); VIDOSD1B_REG = VIDOSDxB_OSD_RBX_F(S3CFB_HRES - 1) | VIDOSDxB_OSD_RBY_F(S3CFB_VRES - 1); VIDOSD1C_REG = 0xDDD000;/*alpha blending*/ fb_size = calc_fbsize(); VIDW00ADD0B0_REG = virt_to_phys((unsigned int)lcdbase); VIDW01ADD0_REG = virt_to_phys(osd_frame_buffer); VIDW00ADD1B0_REG = virt_to_phys((unsigned int)lcdbase + fb_size); VIDW01ADD1_REG = virt_to_phys(osd_frame_buffer) + fb_size; VIDW00ADD2B0_REG = VIDWxADD2_OFFSIZE_F(0) | VIDWxADD2_PAGEWIDTH_F(S3CFB_HRES*2); W1KEYCON0_REG = WxKEYCON0_KEYBLEN_ENABLE | WxKEYCON0_KEYEN_F_ENABLE | WxKEYCON0_COMPKEY(0xFFFF); W1KEYCON1_REG = 0x00000000;/*color key*/ lcd_enable(); WINCON0_REG |= WINCONx_ENWIN_F_ENABLE; WINCON1_REG |= WINCONx_ENWIN_F_ENABLE; //run_command("fatload mmc 0 0x33d00000 logo.bin", 0); //memset(lcdbase,0xf0,fb_size); lcd_backlight(1); return 0; } void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue) { }gzsd2416.h 屏幕相关参数定义
#ifndef GZSD2416_LCD_H #define GZSD2416_LCD_H #include <config.h> #include "s3cfb-reg.h" #include <regs.h> #if defined(CONFIG_LCD_NC43) #define S3CFB_HSW 41 #define S3CFB_HBP 2 #define S3CFB_HFP 2 #define S3CFB_VSW 10 #define S3CFB_VBP 2 #define S3CFB_VFP 2 #define S3CFB_HRES 480 #define S3CFB_VRES 272 #define S3CFB_VFRAME_FREQ 60 #elif defined(CONFIG_LCD_AT070) #define S3CFB_HSW 20 #define S3CFB_HBP 30 #define S3CFB_HFP 88 #define S3CFB_VSW 5 #define S3CFB_VBP 15 #define S3CFB_VFP 5 #define S3CFB_HRES 800 #define S3CFB_VRES 480 #define S3CFB_VFRAME_FREQ 60 #endif #if defined(CONFIG_LCDBPP_32) #define PIXELBITS 32 #define LCD_BPP LCD_COLOR32 #elif defined(CONFIG_LCDBPP_16) #define PIXELBITS 16 #define LCD_BPP LCD_COLOR16 #endif #define S3CFB_IVCLK 0//CFG_LOW #define S3CFB_IHSYNC 1//CFG_HIGH #define S3CFB_IVSYNC 1//CFG_HIGH #define S3CFB_IVDEN 0//CFG_LOW #define S3CFB_PIXEL_CLOCK (S3CFB_VFRAME_FREQ * (S3CFB_HFP + S3CFB_HSW + S3CFB_HBP + S3CFB_HRES) * (S3CFB_VFP + S3CFB_VSW + S3CFB_VBP + S3CFB_VRES)) #endifs3cfb-reb.h LCD寄存器相关位
#ifndef S3CFB_REG_H #define S3CFB_REG_H //rVIDCON0 #define VIDCON0_S_RGB_IF (0<<22) #define VIDCON0_S_RGB_PAR (0<<13) #define VIDCON0_S_VCLK_GATING_OFF (1<<5) #define VIDCON0_S_CLKDIR_DIVIDED (1<<4) #define VIDCON0_S_CLKSEL_HCLK (0<<2) #define VIDCON0_ENVID_ENABLE (1 << 1) #define VIDCON0_ENVID_F_ENABLE (1 << 0) #define VIDCON0_CLKVAL_F(x) (((x)&0xff)<<6) //rVIDCON1 #define VIDCON1_S_HSYNC_INVERTED (1<<6) #define VIDCON1_S_VSYNC_INVERTED (1<<5) //rVIDTCON0 #define VIDTCON0_VBPD(x) (((x)&0xff)<<16) #define VIDTCON0_VFPD(x) (((x)&0xff)<<8) #define VIDTCON0_VSPW(x) (((x)&0xff)<<0) //rVIDTCON1 #define VIDTCON1_HBPD(x) (((x)&0xff)<<16) #define VIDTCON1_HFPD(x) (((x)&0xff)<<8) #define VIDTCON1_HSPW(x) (((x)&0xff)<<0) //rVIDTCON2 #define VIDTCON2_LINEVAL(x) (((x)&0x7ff)<<11) #define VIDTCON2_HOZVAL(x) (((x)&0x7ff)<<0) //rWINCONx #define WINCONx_BPPMODE_F_16BPP_565 (5 << 2) #define WINCONx_ENWIN_F_ENABLE (1 << 0) #define WINCONx_BLD_PIX_PIXEL (1<<6) #define WINCONx_HAWSWP_ENABLE (1<<16) //rVIDOSD0A #define VIDOSDxA_OSD_LTX_F(x) (((x)&0x7ff)<<11) #define VIDOSDxA_OSD_LTY_F(x) (((x)&0x7ff)<<0) //rVIDOSD0B #define VIDOSDxB_OSD_RBX_F(x) (((x)&0x7ff)<<11) #define VIDOSDxB_OSD_RBY_F(x) (((x)&0x7ff)<<0) //* VIDWxADD2 #define VIDWxADD2_OFFSIZE_F(x) (((x)&0x1fff)<<13) #define VIDWxADD2_PAGEWIDTH_F(x) (((x)&0x1fff)<<0) //WxKEYCON0 #define WxKEYCON0_KEYBLEN_ENABLE (1<<26) #define WxKEYCON0_KEYEN_F_ENABLE (1<<25) #define WxKEYCON0_COMPKEY(x) (((x)&0xFFFFFF)<<0) #endif修改当下目录下的makefile增加:
COBJS-$(CONFIG_VIDEO_GZSD2416) += gzsd2416-lcd.o在include/configs/gzsd2416.h中增加如下定义:
//LCD #define CONFIG_LCD 1 #define CONFIG_VIDEO_GZSD2416 1 #define CONFIG_LCD_AT070 1 #define CONFIG_LCDBPP_16 1 #define CONFIG_LCD_GZSD 1在include/lcd.h中#if defined CONFIG_MPC823分支中增加如下几行:
#elif defined(CONFIG_LCD_GZSD) typedef struct vidinfo { ushort vl_col; ushort vl_row; ushort vl_width; ushort vl_height; u_char vl_bpix; } vidinfo_t; #define LCD_FRAMEBUFFER (TEXT_BASE - 0x300000) #define LCD_FRAMEBUFFER_ADDR (TEXT_BASE - 0x200000) #define LCD_MONOCHROME 0 #define LCD_COLOR2 1 #define LCD_COLOR4 2 #define LCD_COLOR8 3 #define LCD_COLOR16 4 #define LCD_COLOR32 5 extern uchar *osd_frame_buffer; extern void lcd_backlight(int enable);common/lcd.c修改
文件开始加入以下声明:
void *lcd_base; /* Start of framebuffer memory */ void *lcd_console_address; /* Start of console buffer */ uchar *osd_frame_buffer; int lcd_line_length; int lcd_color_fg; int lcd_color_bg; short console_col; short console_row;在console_scrollup函数开头加入:
#ifdef CONFIG_LCD_GZSD lcd_console_address = (void*)osd_frame_buffer; #endiflcd_putc函数开头修改为如下:
#ifdef CONFIG_LCD_GZSD serial_putc(c); #else if (!lcd_is_enabled) { serial_putc(c); return; } #endiflcd_drawchars修改如下:
static void lcd_drawchars (ushort x, ushort y, uchar *str, int count) { uchar *dest; ushort off, row; #ifdef CONFIG_LCD_GZSD dest = (uchar *)(osd_frame_buffer + y * lcd_line_length + x * (1 << LCD_BPP) / 8); off = x * (1 << LCD_BPP) % 8; #else dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8); off = x * (1 << LCD_BPP) % 8; #endif for (row=0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) { uchar *s = str; #ifdef CONFIG_LCD_GZSD #if LCD_BPP == LCD_COLOR32 unsigned int *d = (unsigned int*)dest; #elif LCD_BPP == LCD_COLOR16 ushort *d = (ushort *)dest; #else uchar *d = dest; #endif #else uchar *d = dest; #endif int i; #if LCD_BPP == LCD_MONOCHROME uchar rest = *d & -(1 << (8-off)); uchar sym; #endif for (i=0; i<count; ++i) { uchar c, bits; c = *s++; bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; #if LCD_BPP == LCD_MONOCHROME sym = (COLOR_MASK(lcd_color_fg) & bits) | (COLOR_MASK(lcd_color_bg) & ~bits); *d++ = rest | (sym >> off); rest = sym << (8-off); #elif LCD_BPP == LCD_COLOR8 for (c=0; c<8; ++c) { *d++ = (bits & 0x80) ? lcd_color_fg : lcd_color_bg; bits <<= 1; } #elif LCD_BPP == LCD_COLOR16 for (c=0; c<16; ++c) { *d++ = (bits & 0x80) ? lcd_color_fg : lcd_color_bg; bits <<= 1; } #elif LCD_BPP == LCD_COLOR32 for (c=0; c<32; ++c) { *d++ = (bits & 0x80) ? lcd_color_fg : lcd_color_bg; bits <<= 1; } #endif } #if LCD_BPP == LCD_MONOCHROME *d = rest | (*d & ((1 << (8-off)) - 1)); #endif } }drv_lcd_init修改如下:
int drv_lcd_init (void) { struct stdio_dev lcddev; int rc; #ifdef CONFIG_LCD_GZSD lcd_base = (void*)LCD_FRAMEBUFFER_ADDR; osd_frame_buffer=(void*)((char*)lcd_base + calc_fbsize()); lcd_line_length = (panel_info.vl_col * panel_info.vl_bpix) / 8; #if LCD_BPP == LCD_COLOR32 lcd_color_fg = 0xFFFFFF; lcd_color_bg = 0x000000; #else lcd_color_fg = 0xFFFF; lcd_color_bg = 0x0000; #endif #else lcd_base = (void *)(gd->fb_base); lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8; #endif lcd_init (lcd_base); /* LCD initialization */ #if 1 /* Device initialization */ memset (&lcddev, 0, sizeof (lcddev)); strcpy (lcddev.name, "lcd"); lcddev.ext = 0; /* No extensions */ lcddev.flags = DEV_FLAGS_OUTPUT; /* Output only */ lcddev.putc = lcd_putc; /* 'putc' function */ lcddev.puts = lcd_puts; /* 'puts' function */ rc = stdio_register (&lcddev); return (rc == 0) ? 1 : rc; #else return 1; #endif }lcd_init修改如下:
static int lcd_init (void *lcdbase) { /* Initialize the lcd controller */ debug ("[LCD] Initializing LCD frambuffer at %p\n", lcdbase); lcd_ctrl_init (lcdbase); #if 0 //modify by hclydao lcd_clear (NULL, 1, 1, NULL); /* dummy args */ lcd_enable (); #endif /* Initialize the console */ console_col = 0; #ifdef CONFIG_LCD_INFO_BELOW_LOGO console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT; #else console_row = 1; /* leave 1 blank line below logo */ #endif lcd_is_enabled = 1; return 0; }
效果如图:
其实还可以加一个背景图片的
感觉左边不是满屏显示 可以把HBP参数改小,关于logo显示的问题 把logo读到显存后u-boot就不往下跑了 好奇怪的现象,以前调6410 4.3寸的效果很好 换成7寸的后字体显示的也不是很漂亮了.
logo读进去其实很简单,至于不往下跑了 有兴趣的可以继续往下研究:
run_command("fatload mmc 0 0xc3c00000 logo.bin",0);
logo.bin文件可以使用Image2Lcd软件***得到
其中0xc3c00000是显存地址,在include/lcd.h中我们定义的:
#define LCD_FRAMEBUFFER_ADDR (TEXT_BASE - 0x200000)这个的值.
相关文章推荐
- s3c2416 u-boot增加LCD驱动(二)
- Am335x下增加u-boot的LOGO
- Openwrt移植IMX6之增加u-boot支持
- 第二十章、 Tiny4412 U-BOOT移植二十 增加cleanlcd命令
- 全志平台boot框架中增加设备驱动过程分析
- u-boot-2009.08在mini2440上的移植 增加nand flash功能
- IMX6之Openwrt移植增加u-boot支持
- springboot 增加对jsp的支持,具体步骤
- springboot和mybatis集成,自动生成model、mapper,增加mybatis分页功能
- Am335x之u-boot LOGO的增加
- barebox U-BOOT 增加TQ2440 板级设置
- u-boot-2009.08在mini2440上的移植(二)---增加nor flash功能 ——心得体会
- u-boot-2009.08在mini2440上的移植 增加DM9000网卡驱动
- 移植u-boot-2015.07-rc3之增加smdk2440开发板框架支持(一)
- U-boot中增加ping命令
- spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息(推荐)
- smdkv210 uboot增加LCD显示(一)
- springboot-增加自定义资源映射
- u-boot-2009.08在mini2440上的移植(三)---增加nand flash功能——调试心得
- Spring Boot(七)增加事务@Transactional