本次移植是针对ti omap3evm平台的u-boot进行移植的,u-boot源代码可从ti-sdk上获取(版本为: U-Boot 2010.06)。移植过程中主要参考内核lcd代码来进行的。
u-boot添加lcd支持,主要的任务可分为:
1) LCD管脚初始化
2) LCD相关寄存器初始化, 包括时钟在内
3) 添加lcd字符输出程序
1. LCD管脚初始化,包括背光、电源、复位等管脚。
其中omap_set_gpio_direction和omap_set_gpio_dataout是有gpio.c(路径:u-boot/arch/arm/cpu/arm_cortexa8/omap3/)这个文件定义的,它们的功能分别为设置gpio为输出和输出的高低电平。在设置gpio为输出或者输入之前,当然得先更改GPIO管脚的工作模式为Mode4,通过修改u-boot/board/ti/evm/evm.h中 #define MUX_EVM() 这个定义,来改变相应管脚的模式, 这里就不在列出本次移植的修改。一下为LCD相应GPIO的初始化函数定义。
/*
* OMAP3EVM LCD Panel control signals
*/
#define OMAP3EVM_LCD_PANEL_LR 2
#define OMAP3EVM_LCD_PANEL_UD 3
#define OMAP3EVM_LCD_PANEL_INI 152
#define OMAP3EVM_LCD_PANEL_ENVDD 167 //164 //153
#define OMAP3EVM_LCD_PANEL_QVGA 154
#define OMAP3EVM_LCD_PANEL_RESB 162 //155
#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 182 //58//210
#define OMAP3EVM_DVI_PANEL_EN_GPIO 199
static void omap3_evm_display_init(void)
{
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_RESB, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_RESB, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_INI, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_INI, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_QVGA, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_QVGA, 0);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_LR, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_LR, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_UD, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_UD, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_ENVDD, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_ENVDD, 0);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
}
2. LCD相关寄存器初始化, 包括时钟在内
DM3730与LCD相关的寄存器还是相当多的,如果说一个一个看过去的话会累死的(对与我来说)。 为了快速获得lcd相关寄存器的配置,修改内核的.config文件,添加 CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y 这个选项(作用是omap的 dss系统会添加debugfs接口,使得我们可以dump出所有的寄存器值出来),然后我们就可以在终端下输入如下命令:
# mount -t debugfs debugfs /sys/kernel/debug/
# cd /sys/kernel/debug/omapdss/
# ls
clk dispc dsi dss venc
# cat dss dispc dsi
DSS_REVISION 00000020
DSS_SYSCONFIG 00000001
DSS_SYSSTATUS 00000001
DSS_IRQSTATUS 00000000
DSS_CONTROL 00000019
DSS_SDI_CONTROL 00000000
.......
以上命令就可以获得lcd相关的寄存器配置值。当然,前提是内核已经支持lcd显示,并且可以正常显示的情况下,这些步骤才会有意义。
有了寄存器配置值之后,我们就可以根据内核kernel/drivers/video/omap2/dss目录下的dsi.c、dispc.c以及dss.c三个文件来配置和dump寄存器。
在所有寄存器配置开始之前要做的就是打开DSS模块的 ICLK和FCLK。
/* 当所有寄存器配置好了之后, 就可以把内存的数据传送到lcd去了 */
void dispc_go(void)
{
int r = dispc_read_reg(DISPC_CONTROL);
if (!(r & 1)) {
printf("lcd is not enable\n");
}
if (r & (1<<5)) {
printf("lcd is going\n");
}
r |= (1<<5);
dispc_write_reg(DISPC_CONTROL, r);
}
void lcd_init(void)
{
omap3_evm_display_init();
/* 打开DSS模块的ICLK和FCLK */
dss_clk_write_reg(CM_AUTOIDLE_DSS, 0);
dss_clk_write_reg(CM_CLKSTCTRL_DSS, 2);
dss_clk_write_reg(CM_ICLKEN_DSS, 1);
dss_clk_write_reg(CM_FCLKEN_DSS, 7);
//dss_clk_dump_regs();
/* 配置DSS */
dss_write_reg(DSS_SYSCONFIG, 0x1);
dss_write_reg(DSS_CONTROL, 0x19);
dss_write_reg(DSS_SDI_CONTROL, 0x00);
dss_write_reg(DSS_PLL_CONTROL, 0x00);
//dss_dump_regs();
/* 配置DISPC */
dispc_init();
//dispc_dump_regs();
/* 配置DSI */
dsi_init();
//dsi_dump_regs();
dispc_go();
}
3) 添加lcd字符输出程序
ti的 u-boot默认时支持lcd字符输出程序的,只不过没选上。
一、修改omap3_evm.h文件,添加如下几个函数定义就可以把输出定向到lcd:
#define CONFIG_CFB_CONSOLE 1
#define VIDEO_KBD_INIT_FCT 0
#define VIDEO_TSTC_FCT serial_tstc
#define VIDEO_GETC_FCT serial_getc
二、添加video_hw_init和video_set_lut两个函数
void *video_hw_init (void)
{
lcd_init ();
/* fill in Graphic Device */
glcd_dev.frameAdrs = (u32)lcd_static_mem;
glcd_dev.winSizeX = 800;
glcd_dev.winSizeY = 480;
glcd_dev.gdfBytesPP = 4;
glcd_dev.gdfIndex = GDF_32BIT_X888RGB;
return (void *) &glcd_dev;
}
void video_set_lut(unsigned int index,
unsigned char r, unsigned char g, unsigned char b)
{
return;
}
u-boot添加lcd支持,主要的任务可分为:
1) LCD管脚初始化
2) LCD相关寄存器初始化, 包括时钟在内
3) 添加lcd字符输出程序
1. LCD管脚初始化,包括背光、电源、复位等管脚。
其中omap_set_gpio_direction和omap_set_gpio_dataout是有gpio.c(路径:u-boot/arch/arm/cpu/arm_cortexa8/omap3/)这个文件定义的,它们的功能分别为设置gpio为输出和输出的高低电平。在设置gpio为输出或者输入之前,当然得先更改GPIO管脚的工作模式为Mode4,通过修改u-boot/board/ti/evm/evm.h中 #define MUX_EVM() 这个定义,来改变相应管脚的模式, 这里就不在列出本次移植的修改。一下为LCD相应GPIO的初始化函数定义。
/*
* OMAP3EVM LCD Panel control signals
*/
#define OMAP3EVM_LCD_PANEL_LR 2
#define OMAP3EVM_LCD_PANEL_UD 3
#define OMAP3EVM_LCD_PANEL_INI 152
#define OMAP3EVM_LCD_PANEL_ENVDD 167 //164 //153
#define OMAP3EVM_LCD_PANEL_QVGA 154
#define OMAP3EVM_LCD_PANEL_RESB 162 //155
#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 182 //58//210
#define OMAP3EVM_DVI_PANEL_EN_GPIO 199
static void omap3_evm_display_init(void)
{
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_RESB, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_RESB, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_INI, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_INI, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_QVGA, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_QVGA, 0);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_LR, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_LR, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_UD, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_UD, 1);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_ENVDD, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_ENVDD, 0);
omap_set_gpio_direction(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
omap_set_gpio_dataout(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
}
2. LCD相关寄存器初始化, 包括时钟在内
DM3730与LCD相关的寄存器还是相当多的,如果说一个一个看过去的话会累死的(对与我来说)。 为了快速获得lcd相关寄存器的配置,修改内核的.config文件,添加 CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y 这个选项(作用是omap的 dss系统会添加debugfs接口,使得我们可以dump出所有的寄存器值出来),然后我们就可以在终端下输入如下命令:
# mount -t debugfs debugfs /sys/kernel/debug/
# cd /sys/kernel/debug/omapdss/
# ls
clk dispc dsi dss venc
# cat dss dispc dsi
DSS_REVISION 00000020
DSS_SYSCONFIG 00000001
DSS_SYSSTATUS 00000001
DSS_IRQSTATUS 00000000
DSS_CONTROL 00000019
DSS_SDI_CONTROL 00000000
.......
以上命令就可以获得lcd相关的寄存器配置值。当然,前提是内核已经支持lcd显示,并且可以正常显示的情况下,这些步骤才会有意义。
有了寄存器配置值之后,我们就可以根据内核kernel/drivers/video/omap2/dss目录下的dsi.c、dispc.c以及dss.c三个文件来配置和dump寄存器。
在所有寄存器配置开始之前要做的就是打开DSS模块的 ICLK和FCLK。
/* 当所有寄存器配置好了之后, 就可以把内存的数据传送到lcd去了 */
void dispc_go(void)
{
int r = dispc_read_reg(DISPC_CONTROL);
if (!(r & 1)) {
printf("lcd is not enable\n");
}
if (r & (1<<5)) {
printf("lcd is going\n");
}
r |= (1<<5);
dispc_write_reg(DISPC_CONTROL, r);
}
void lcd_init(void)
{
omap3_evm_display_init();
/* 打开DSS模块的ICLK和FCLK */
dss_clk_write_reg(CM_AUTOIDLE_DSS, 0);
dss_clk_write_reg(CM_CLKSTCTRL_DSS, 2);
dss_clk_write_reg(CM_ICLKEN_DSS, 1);
dss_clk_write_reg(CM_FCLKEN_DSS, 7);
//dss_clk_dump_regs();
/* 配置DSS */
dss_write_reg(DSS_SYSCONFIG, 0x1);
dss_write_reg(DSS_CONTROL, 0x19);
dss_write_reg(DSS_SDI_CONTROL, 0x00);
dss_write_reg(DSS_PLL_CONTROL, 0x00);
//dss_dump_regs();
/* 配置DISPC */
dispc_init();
//dispc_dump_regs();
/* 配置DSI */
dsi_init();
//dsi_dump_regs();
dispc_go();
}
3) 添加lcd字符输出程序
ti的 u-boot默认时支持lcd字符输出程序的,只不过没选上。
一、修改omap3_evm.h文件,添加如下几个函数定义就可以把输出定向到lcd:
#define CONFIG_CFB_CONSOLE 1
#define VIDEO_KBD_INIT_FCT 0
#define VIDEO_TSTC_FCT serial_tstc
#define VIDEO_GETC_FCT serial_getc
二、添加video_hw_init和video_set_lut两个函数
void *video_hw_init (void)
{
lcd_init ();
/* fill in Graphic Device */
glcd_dev.frameAdrs = (u32)lcd_static_mem;
glcd_dev.winSizeX = 800;
glcd_dev.winSizeY = 480;
glcd_dev.gdfBytesPP = 4;
glcd_dev.gdfIndex = GDF_32BIT_X888RGB;
return (void *) &glcd_dev;
}
void video_set_lut(unsigned int index,
unsigned char r, unsigned char g, unsigned char b)
{
return;
}
总的来说, 通过以上几个步骤就可以实现lcd显示了。 本人在移植之后,lcd显示屏会闪烁。个人猜测是时钟的问题,应为内核跑的时钟跟u-boot跑的时钟时不一样的,而我只是照搬内核的配置,所以时钟应该会有问题的。 补丁的两个文件lcd.h和lcd.c稍后给出。
添加程序补丁地址:
http://download.csdn.net/detail/joans123/3743976