uboot移植五:添加板级打印信息

时间:2024-04-14 14:02:18

一、初始化时钟

s5pv210内部的irom中有对时钟的初始化,但是其时钟配置不是三星官方的推荐的配置,它的配置是arm主频400MHz,在这里我们在lowlevel_init函数中重新初始化时钟,将主频初始化到1GHz。

初始化后时钟频率如下图所示:

uboot移植五:添加板级打印信息

时钟的初始化主要是向相关寄存器中写值,比较模式化,代码部分移植自三星官方,我主要在配置头文件include/configs/s5p_goni.h中添加相应的宏控制就行了, 这些宏主要控制时钟的MUX开关与DIV分频系数。

//clk
//#define CONFIG_CLK_667_166_166_133
//#define CONFIG_CLK_533_133_100_100
//#define CONFIG_CLK_800_200_166_133
//#define CONFIG_CLK_800_100_166_133
#define CONFIG_CLK_1000_200_166_133
//#define CONFIG_CLK_400_200_166_133
//#define CONFIG_CLK_400_100_166_133


#if defined(CONFIG_CLK_667_166_166_133)
#define APLL_MDIV       0xfa
#define APLL_PDIV       0x6
#define APLL_SDIV       0x1
#elif defined(CONFIG_CLK_533_133_100_100)
#define APLL_MDIV       0x215
#define APLL_PDIV       0x18
#define APLL_SDIV       0x1
#elif defined(CONFIG_CLK_800_200_166_133) || \
defined(CONFIG_CLK_800_100_166_133) || \
defined(CONFIG_CLK_400_200_166_133) || \
defined(CONFIG_CLK_400_100_166_133)
#define APLL_MDIV       0x64
#define APLL_PDIV       0x3
#define APLL_SDIV       0x1
#elif defined(CONFIG_CLK_1000_200_166_133)
#define APLL_MDIV       0x7d
#define APLL_PDIV       0x3
#define APLL_SDIV       0x1
#endif


#define APLL_LOCKTIME_VAL 0x2cf


#if defined(CONFIG_EVT1)
/* Set AFC value */
#define AFC_ON 0x00000000
#define AFC_OFF 0x10000010
#endif


#if defined(CONFIG_CLK_533_133_100_100)
#define MPLL_MDIV 0x190
#define MPLL_PDIV 0x6
#define MPLL_SDIV 0x2
#else
#define MPLL_MDIV 0x29b
#define MPLL_PDIV 0xc
#define MPLL_SDIV 0x1
#endif


#define EPLL_MDIV 0x60
#define EPLL_PDIV 0x6
#define EPLL_SDIV 0x2


#define VPLL_MDIV 0x6c
#define VPLL_PDIV 0x6
#define VPLL_SDIV 0x3


/* CLK_DIV0 */
#define APLL_RATIO 0
#define A2M_RATIO 4
#define HCLK_MSYS_RATIO 8
#define PCLK_MSYS_RATIO 12
#define HCLK_DSYS_RATIO 16
#define PCLK_DSYS_RATIO 20
#define HCLK_PSYS_RATIO 24
#define PCLK_PSYS_RATIO 28


#define CLK_DIV0_MASK 0x7fffffff


#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)


#define APLL_VAL set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)
#define MPLL_VAL set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)
#define EPLL_VAL set_pll(EPLL_MDIV,EPLL_PDIV,EPLL_SDIV)
#define VPLL_VAL set_pll(VPLL_MDIV,VPLL_PDIV,VPLL_SDIV)


#if defined(CONFIG_CLK_667_166_166_133)
#define CLK_DIV0_VAL    ((0<<APLL_RATIO)|(3<<A2M_RATIO)|(3<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
|(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#elif defined(CONFIG_CLK_533_133_100_100)
#define CLK_DIV0_VAL    ((0<<APLL_RATIO)|(3<<A2M_RATIO)|(3<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
|(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(3<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#elif defined(CONFIG_CLK_800_200_166_133)
#define CLK_DIV0_VAL    ((0<<APLL_RATIO)|(3<<A2M_RATIO)|(3<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
|(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#elif defined(CONFIG_CLK_800_100_166_133)
#define CLK_DIV0_VAL    ((0<<APLL_RATIO)|(7<<A2M_RATIO)|(7<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
|(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#elif defined(CONFIG_CLK_400_200_166_133)
#define CLK_DIV0_VAL    ((1<<APLL_RATIO)|(3<<A2M_RATIO)|(1<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
|(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#elif defined(CONFIG_CLK_400_100_166_133)
#define CLK_DIV0_VAL    ((1<<APLL_RATIO)|(7<<A2M_RATIO)|(3<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
|(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#elif defined(CONFIG_CLK_1000_200_166_133)
#define CLK_DIV0_VAL    ((0<<APLL_RATIO)|(4<<A2M_RATIO)|(4<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
|(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#endif


#define CLK_DIV1_VAL ((1<<16)|(1<<12)|(1<<8)|(1<<4))

#define CLK_DIV2_VAL (1<<0)

这些宏适配了7种不同的时钟配置,需要哪一种就打开对应的宏就行了,我们在这里打开了#define CONFIG_CLK_1000_200_166_133也就是说最终配置的时钟和上图中一致。

二、修改banner打印信息

banner打印信息由三部分组成

#define U_BOOT_VERSION_STRING U_BOOT_VERSION " (" U_BOOT_DATE " - " \

U_BOOT_TIME ")" CONFIG_IDENT_STRING

整体上由U_BOOT_VERSION_STRING 这个宏控制。

第一部分:U_BOOT_VERSION,这个在主Makefile中有定义,最终生成的include/generated/version_autogenerated.h头文件中包含了对这个宏的定义。

第二部分:" (" U_BOOT_DATE " - " U_BOOT_TIME ")"代表日期和时间,也是在makefile中生成然后宏定义在include/generated/timestamp_autogenerated.h 头文件中。

第三部分:uboot中将其定义为空

#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""

#endif

我们只需要在配置头文件include/configs/s5p_goni.h中定义这个宏为我们想要的字符串就可以了;我的定义如下:

#define CONFIG_IDENT_STRING " for LWL210"

三、打印cpu的时钟信息

修改print_cpuinfo函数代码如下:

char buf[10][32];
#if 0   // added by lwl
printf("CPU:\t%s%[email protected]%sMHz\n",
s5p_get_cpu_name(), s5p_cpu_id,
strmhz(buf, get_arm_clk()));
#endif // #if 0
/* added by lwl; uart print clk info */
printf("\nCPU:  [email protected]%sMHz\n", strmhz(buf[0], get_arm_clk()));


printf("        APLL = %sMHz, HclkMsys = %sMHz, PclkMsys = %sMHz\n",
strmhz(buf[1], get_pll_clk(APLL)), strmhz(buf[2], get_hclk_sys(0)), strmhz(buf[3], get_pclk_sys(0)));


printf(" MPLL = %sMHz, EPLL = %sMHz\n",
strmhz(buf[4], get_pll_clk(MPLL)), strmhz(buf[5], get_pll_clk(EPLL)));
printf("        HclkDsys = %sMHz, PclkDsys = %sMHz\n",
strmhz(buf[6], get_hclk_sys(1)), strmhz(buf[7], get_pclk_sys(1)));
printf("        HclkPsys = %sMHz, PclkPsys = %sMHz\n",
strmhz(buf[8], get_hclk_sys(2)), strmhz(buf[9], get_pclk_sys(2)));
/* end added */

return 0;

上面就是格式化打印时钟信息的函数,其中用到的工具函数均在arch/arm/cpu/armv7/s5pc1xx/clock.c文件中有定义。其中用到的两个函数get_hclk_sys、get_pclk_sys在文件中定义为static,由于我们要在别的文件中引用他们,所以去掉它们的static属性,并在头文件arch/arm/include/asm/arch-s5pc1xx/clk.h中添加对他们的申明:

/* added by lwl */
unsigned long get_hclk_sys(int dom);
unsigned long get_pclk_sys(int dom);

/* end added */

这样在包含了该头文件的c文件中就能调用上面这两个函数。

四、修改开发板名称打印信息

在checkboard函数中添加puts("Board:\tLWL210\n");    // modified by lwl

串口打印开发板名称:LWL210

五、修改ddr软初始化

我们的开发板上使用了两块ddr,有两个bank,为bank0与bank1,所以dram_init函数去掉bank2,修改如下:

/*gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE +
PHYS_SDRAM_3_SIZE; */
gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;  // modified by lwl

return 0;

dram_init_banksize函数也去掉bank2

gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
// modified by lwl
//gd->bd->bi_dram[2].start = PHYS_SDRAM_3;

//gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;

在配置头文件中修改ddr的信息:

#define CONFIG_NR_DRAM_BANKS 2   // modified by lwl; 2 banks
#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE /* OneDRAM Bank #0 */
//#define PHYS_SDRAM_1_SIZE (80 << 20) /* 80 MB in Bank #0 */
#define PHYS_SDRAM_1_SIZE (256 << 20) /* modified by lwl; 256 MB in Bank #0 */
#define PHYS_SDRAM_2 0x40000000 /* mDDR DMC1 Bank #1 */
#define PHYS_SDRAM_2_SIZE (256 << 20) /* 256 MB in Bank #1 */
//#define PHYS_SDRAM_3 0x50000000 /* mDDR DMC2 Bank #2 */

//#define PHYS_SDRAM_3_SIZE (128 << 20) /* 128 MB in Bank #2 */

去掉bank2的信息;bank0改成256MB。

六、修改机器码

由于我们的uboot将来去启动smdkv210的内核,在这里将机器码与其内核的机器码设置成一样的,修改board_init函数

gd->bd->bi_arch_number = MACH_TYPE_SMDKV210;   // modified by lwl

所有开发板的机器码信息全部在arch/arm/include/asm/mach-types,h中有定义

七、去掉onenand的初始化,添加MMC的初始化

由于我们的开发板上没有onenand,只有iNand,所以我们应该屏蔽掉队onenand的初始化,添加队mmc的初始化。代码中用宏进行控制。

去掉//#define CONFIG_CMD_ONENAND   // modified by lwl

由于去掉了这个宏,其他依赖于这个宏的文件预处理时会报错,所以直接将uboot中关于onenand的文件不加入编译之中。

修改board/samsung/goni/Makefile,去掉对onenand.c的编译。

我们的环境变量将来保存在iNand中,随意去掉环境变量与onenand有关的宏

#if 0
/* FLASH and environment organization */
#define CONFIG_ENV_IS_IN_ONENAND 1
#define CONFIG_ENV_SIZE (256 << 10) /* 256 KiB, 0x40000 */
#define CONFIG_ENV_ADDR (1 << 20) /* 1 MB, 0x100000 */

#define CONFIG_USE_ONENAND_BOARD_INIT
#define CONFIG_SAMSUNG_ONENAND 1
#define CONFIG_SYS_ONENAND_BASE 0xB0000000

#endif

添加环境变量与iNand有关的宏,CONFIG_SYS_MMC_ENV_DEV 表示设备0,指的是内部的iNand,将环境变量保存在iNand中而不是SD卡中。

// env
#define CONFIG_ENV_IS_IN_MMC 1
#define CONFIG_ENV_SIZE CFG_ENV_SIZE

#define CONFIG_SYS_MMC_ENV_DEV 0

这样对于common文件夹下有关环境变量的文件Makefile就会选择env_mmc.c,将其添加到编译之中,这种条件编译主要靠宏控制,如下:

COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o
COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o
XCOBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o
COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o
XCOBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o
COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o
COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
COBJS-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o
COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o
COBJS-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o

COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o

八、运行结果

重新编译uboot,运行结果如下:

uboot移植五:添加板级打印信息

可以看到已经进入了uboot的命令行,但是MMC设备读取失败,主要是MMC设备的驱动部分没有修改,接下来要做的就是对MMC驱动的移植。