您的位置:首页 > 编程语言 > Go语言

天漠SOC8200(TI AM3517 ARM芯片)u-boot增加开机logo

2012-05-11 14:56 330 查看
经过两个星期的努力,终于初步搞定了位开发板的uboot增加开机logo,此中酸甜苦辣,最终转化为调通那一刻的巨大喜悦,废话不多少,转入正题。

uboot增加开机logo的思路其实很简单,写好lcd控制器的底层代码,然后填充一个叫GraphicDevice的结构体,并在/include/configs/am3517_evm.h中增加与显示logo相关的宏。

在/drivers/video目录下增加两个文件:omap3Lcd.h和omap3Lcd.c,并在该层Makefile加上编译该文件。文件内容分别如下:

/******************omap3Lcd.c*******************/

#include <common.h>
#include <asm/io.h>
#include <asm/arch/mem.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
#include <asm/mach-types.h>
#include <video_fb.h>

#include "omap3Lcd.h"

GraphicDevice glcd_dev;

static int lcd_static_mem[640*480];

int lcd_ctrl_init(void )
{
u32 l = clkctrl_read_reg(CM_CLKSEL2_PLL);
printf("CLKSEL2_PLL is %d\n",l);

u32 m = clkctrl_read_reg(CM_CLKEN_PLL);
printf("CM_CLLEN_PLL is %d\n",m);
m &= 0xffffff;
m |= (0x7 << 16);//|(0x0f<<20);
clkctrl_write_reg(CM_CLKEN_PLL,m);
//	printf("CM_CLLEN_PLL is %d\n",m);

dss_clk_write_reg(CM_CLKSEL_DSS,0x10009);

dss_clk_write_reg(CM_FCLKEN_DSS, 5);
dss_clk_write_reg(CM_ICLKEN_DSS, 1);
dss_clk_write_reg(CM_AUTOIDLE_DSS, 0);
dss_clk_write_reg(CM_SLEEPDEP_DSS,0);
dss_clk_write_reg(CM_CLKSTCTRL_DSS,0);

dss_write_reg(DSS_SYSCONFIG,0x0002);
while(! dss_read_reg(DSS_SYSSTATUS));

dispc_write_reg(DISPC_CONTROL, 0x00018108 );//change 18309 to 18109 for 16bit per pix
dispc_write_reg(DISPC_SIZE_LCD, 0x01df027f);	//size:640*480
dispc_write_reg(DISPC_CONFIG,0x4);
dispc_write_reg(DISPC_TIMING_H, 0x0720101e);	//LCD Timing params
dispc_write_reg(DISPC_TIMING_V, 0x02100a03);
dispc_write_reg(DISPC_POL_FREQ, 0x00);
dispc_write_reg(DISPC_DIVISOR, 0x00010009);     //maybe need change

dispc_write_reg(DISPC_GFX_SIZE, 0x01df027f);
dispc_write_reg(DISPC_GFX_FIFO_THRESHOLD, 0x03ff0300);
dispc_write_reg(DISPC_GFX_ROW_INC, 0x01);
dispc_write_reg(DISPC_GFX_PIXEL_INC, 0x01);

memset(lcd_static_mem, 0xff, sizeof(lcd_static_mem));
dispc_write_reg(DISPC_GFX_BA0, (unsigned int )lcd_static_mem);

//	dispc_write_reg(DISPC_GFX_BA0, LCD_STATIC_MEM);

dispc_write_reg(DISPC_GFX_POSITION, 0);
dispc_write_reg(DISPC_GFX_ATTRIBUTES, 0x02d);	//change for GFX configuration

dispc_write_reg(DISPC_CONTROL, 0x00018129);

printf("color test\n");

return 0;
}

void *video_hw_init (void)
{
lcd_ctrl_init ();

/* fill in Graphic Device */

glcd_dev.frameAdrs = (u32)lcd_static_mem;
//	glcd_dev.frameAdrs = LCD_STATIC_MEM;

glcd_dev.winSizeX = 640;
glcd_dev.winSizeY = 480;
glcd_dev.gdfBytesPP = 2;
glcd_dev.gdfIndex = GDF_16BIT_565RGB;
return (void *) &glcd_dev;
}

void video_set_lut(unsigned int index,
unsigned char r, unsigned char g, unsigned char b)
{
}


/**************************omap3Lcd.h******************************/

#ifndef _OMAP3LCD_H_
#define _OMAP3LCD_H_

#define DISPC_BASE			0x48050400
#define DSS_BASE			0x48050000
#define DSS_CLK_BASE			0x48004e00
#define SGX_CLK_BASE			0x48004b00
#define DSI_BASE			0x4804FC00
#define PAD_CONFIG_BASE			0x48002030

#define CLOCK_CTRL_BASE			0x48004D00
#define CLOCK_CTRL_REG(idx)		((const u16) {idx})
#define CM_CLKEN_PLL			CLOCK_CTRL_REG(0x00)
#define CM_CLKSEL2_PLL			CLOCK_CTRL_REG(0x44)

#define DSS_REG(idx)			((const u16) { idx })
#define DISPC_REG(idx)			((const u16) { idx })
#define DSS_CLK_REG(idx)		((const u16) { idx })
#define SGX_CLK_REG(idx)		((const u16) { idx })
#define DSI_REG(idx)			((const u16) { idx })
#define PAD_CONFIG_REG(idx)		((const u16) { idx })

#define CONTROL_PADCONF_DSS_PCLK	PAD_CONFIG_REG(0xA4)
#define CONTROL_PADCONF_DSS_VSYNC	PAD_CONFIG_REG(0xA8)
#define CONTROL_PADCONF_DSS_DATA0	PAD_CONFIG_REG(0xAC)
#define CONTROL_PADCONF_DSS_DATA2	PAD_CONFIG_REG(0xB0)
#define CONTROL_PADCONF_DSS_DATA4	PAD_CONFIG_REG(0xB4)
#define CONTROL_PADCONF_DSS_DATA6	PAD_CONFIG_REG(0xB8)
#define CONTROL_PADCONF_DSS_DATA8	PAD_CONFIG_REG(0xBC)
#define CONTROL_PADCONF_DSS_DATA10	PAD_CONFIG_REG(0xC0)
#define CONTROL_PADCONF_DSS_DATA12	PAD_CONFIG_REG(0xC4)
#define CONTROL_PADCONF_DSS_DATA14	PAD_CONFIG_REG(0xC8)
#define CONTROL_PADCONF_DSS_DATA16	PAD_CONFIG_REG(0xCC)
#define CONTROL_PADCONF_DSS_DATA18	PAD_CONFIG_REG(0xD0)
#define CONTROL_PADCONF_DSS_DATA20	PAD_CONFIG_REG(0xD4)
#define CONTROL_PADCONF_DSS_DATA22	PAD_CONFIG_REG(0xD8)

#define CM_FCLKEN_DSS		DSS_CLK_REG(0x00)
#define CM_ICLKEN_DSS		DSS_CLK_REG(0x10)
#define CM_AUTOIDLE_DSS		DSS_CLK_REG(0x30)
#define CM_CLKSEL_DSS		DSS_CLK_REG(0x40)
#define CM_CLKSTCTRL_DSS	DSS_CLK_REG(0x48)
#define CM_CLKSTST_DSS		DSS_CLK_REG(0x4c)
#define CM_SLEEPDEP_DSS		DSS_CLK_REG(0x44)

#define DSS_REVISION			DSS_REG(0x0000)
#define DSS_SYSCONFIG			DSS_REG(0x0010)
#define DSS_SYSSTATUS			DSS_REG(0x0014)
#define DSS_IRQSTATUS			DSS_REG(0x0018)
#define DSS_CONTROL			DSS_REG(0x0040)
#define DSS_SDI_CONTROL		DSS_REG(0x0044)
#define DSS_PLL_CONTROL		DSS_REG(0x0048)
#define DSS_SDI_STATUS			DSS_REG(0x005C)

/* DISPC common */
#define DISPC_REVISION			DISPC_REG(0x0000)
#define DISPC_SYSCONFIG			DISPC_REG(0x0010)
#define DISPC_SYSSTATUS			DISPC_REG(0x0014)
#define DISPC_IRQSTATUS			DISPC_REG(0x0018)
#define DISPC_IRQENABLE			DISPC_REG(0x001C)
#define DISPC_CONTROL			DISPC_REG(0x0040)
#define DISPC_CONFIG			DISPC_REG(0x0044)
#define DISPC_CAPABLE			DISPC_REG(0x0048)
#define DISPC_DEFAULT_COLOR0		DISPC_REG(0x004C)
#define DISPC_DEFAULT_COLOR1		DISPC_REG(0x0050)
#define DISPC_TRANS_COLOR0		DISPC_REG(0x0054)
#define DISPC_TRANS_COLOR1		DISPC_REG(0x0058)
#define DISPC_LINE_STATUS		DISPC_REG(0x005C)
#define DISPC_LINE_NUMBER		DISPC_REG(0x0060)
#define DISPC_TIMING_H			DISPC_REG(0x0064)
#define DISPC_TIMING_V			DISPC_REG(0x0068)
#define DISPC_POL_FREQ			DISPC_REG(0x006C)
#define DISPC_DIVISOR			DISPC_REG(0x0070)
#define DISPC_GLOBAL_ALPHA		DISPC_REG(0x0074)
#define DISPC_SIZE_DIG			DISPC_REG(0x0078)
#define DISPC_SIZE_LCD			DISPC_REG(0x007C)

/* DISPC GFX plane */
#define DISPC_GFX_BA0			DISPC_REG(0x0080)
#define DISPC_GFX_BA1			DISPC_REG(0x0084)
#define DISPC_GFX_POSITION		DISPC_REG(0x0088)
#define DISPC_GFX_SIZE			DISPC_REG(0x008C)
#define DISPC_GFX_ATTRIBUTES		DISPC_REG(0x00A0)
#define DISPC_GFX_FIFO_THRESHOLD	DISPC_REG(0x00A4)
#define DISPC_GFX_FIFO_SIZE_STATUS	DISPC_REG(0x00A8)
#define DISPC_GFX_ROW_INC		DISPC_REG(0x00AC)
#define DISPC_GFX_PIXEL_INC		DISPC_REG(0x00B0)
#define DISPC_GFX_WINDOW_SKIP		DISPC_REG(0x00B4)
#define DISPC_GFX_TABLE_BA		DISPC_REG(0x00B8)

#define DISPC_DATA_CYCLE1		DISPC_REG(0x01D4)
#define DISPC_DATA_CYCLE2		DISPC_REG(0x01D8)
#define DISPC_DATA_CYCLE3		DISPC_REG(0x01DC)

#define DISPC_CPR_COEF_R		DISPC_REG(0x0220)
#define DISPC_CPR_COEF_G		DISPC_REG(0x0224)
#define DISPC_CPR_COEF_B		DISPC_REG(0x0228)

#define DISPC_GFX_PRELOAD		DISPC_REG(0x022C)

/* DSI_PLL_CTRL_SCP */

#define DSI_PLL_CONTROL			DSI_REG(0x300 + 0x0000)
#define DSI_PLL_STATUS			DSI_REG(0x300 + 0x0004)
#define DSI_PLL_GO			DSI_REG(0x300 + 0x0008)
#define DSI_PLL_CONFIGURATION1		DSI_REG(0x300 + 0x000C)
#define DSI_PLL_CONFIGURATION2		DSI_REG(0x300 + 0x0010)

enum dss_clock {
DSS_CLK_ICK	= 1 << 0,
DSS_CLK_FCK1	= 1 << 1,
DSS_CLK_FCK2	= 1 << 2,
DSS_CLK_54M	= 1 << 3,
DSS_CLK_96M	= 1 << 4,
};

static inline void clkctrl_write_reg(const u16 idx,u32 val)
{
__raw_writel(val,CLOCK_CTRL_BASE + idx);
}

static inline u32 clkctrl_read_reg(const u16 idx)
{
return __raw_readl(CLOCK_CTRL_BASE + idx);
}

static inline void pad_write_reg(const u16 idx, u32 val)
{
__raw_writel(val,PAD_CONFIG_BASE + idx);
}
static inline u32 pad_read_reg(const u16 idx)
{
return __raw_readl(PAD_CONFIG_BASE + idx);
}
static inline void dsi_write_reg(const u16 idx, u32 val)
{
__raw_writel(val, DSI_BASE + idx);
}

static inline u32 dsi_read_reg(const u16 idx)
{
return __raw_readl(DSI_BASE + idx);
}

static inline void dss_clk_write_reg(const u16 idx, u32 val)
{
__raw_writel(val, DSS_CLK_BASE + idx);
}

static inline u32 dss_clk_read_reg(const u16 idx)
{
return __raw_readl(DSS_CLK_BASE + idx);
}

static inline void dss_write_reg(const u16 idx, u32 val)
{
__raw_writel(val, DSS_BASE + idx);
}

static inline u32 dss_read_reg(const u16 idx)
{
return __raw_readl(DSS_BASE + idx);
}

static inline void dispc_write_reg(const u16 idx, u32 val)
{
__raw_writel(val, DISPC_BASE + idx);
}

static inline u32 dispc_read_reg(const u16 idx)
{
return __raw_readl(DISPC_BASE + idx);
}

#endif


在am3517_evm.h中添加下边几个宏:

//LCD related

#define CONFIG_VIDEO 1

#define CONFIG_VIDEO_LOGO 1

#define CONFIG_VIDEO_BMP_LOGO 1

#define VIDEO_FB_16BPP_PIXEL_SWAP 1

#define CONFIG_VIDEO_BMP_GZIP 1

#define CONFIG_CFB_CONSOLE 1

#define CONFIG_SPLASH_SCREEN 1

#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (1024*768+1024+100)

#define CONFIG_VIDEO_SW_CURSOR

#define CONFIG_SYS_CONSOLE_IS_IN_ENV

#define CONFIG_CMD_UNZIP

#define CONFIG_CMD_BMP

#define CONFIG_VGA_AS_SINGLE_DEVICE 1

OK,重新编译uboot,烧进板子,观察结果。

在调试的过程中,曾经被两个问题卡了很久,最后发现其实是同一个原因导致的,那就是----时钟。时钟一定要慎重处理,尤其是涉及时钟源的寄存器,不能为了得出想要的结果想当然的修改,该过程中像素时钟来自dpll4,经过层层(应该是3层)分频倍频最终得到10M左右的像素时钟,最底层的时钟分频寄存器最好不要改(牵一发而动全身),而通过修改dss domain内部的相关分频寄存器得到像素时钟即可。

最后,梳理一下u-boot显示logo的大致流程:

stdio_init ()(in /lib_arm/board.c)---->drv_video_init ()(in /drivers/vedio/cfb_console.c)------>video_init()-------->video_hw_init(in omap3Lcd.c)--->lcd_ctrl_init()(lcd底层初始化)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: