上两节从整体上认识了uboot的,了解了4412的bootloader组成。要想在tiny4412跑起uboot2018,需要修改系统时钟,内存控制寄存器,串口配置和uboot拷贝相关代码。
diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts
index 65a5fcd..9f4875a 100755
--- a/arch/arm/dts/exynos4210-origen.dts
+++ b/arch/arm/dts/exynos4210-origen.dts
@@ -15,12 +15,13 @@
compatible = "insignal,origen", "samsung,exynos4210";
chosen {
+ stdout-path = "serial0";
bootargs ="";
};
aliases {
serial0 = "/serial@13800000";
- console = "/serial@13820000";
+ console = "/serial@13800000";
};
};
diff --git a/arch/arm/mach-exynos/clock_init_exynos4.c b/arch/arm/mach-exynos/clock_init_exynos4.c
index 584e4ba..5f5bf91 100755
--- a/arch/arm/mach-exynos/clock_init_exynos4.c
+++ b/arch/arm/mach-exynos/clock_init_exynos4.c
@@ -38,57 +38,59 @@
*/
void system_clock_init(void)
{
- struct exynos4_clock *clk =
- (struct exynos4_clock *)samsung_get_base_clock();
+ struct exynos4x12_clock *clk =
+ (struct exynos4x12_clock *)samsung_get_base_clock();
- writel(CLK_SRC_CPU_VAL, &clk->src_cpu);
+ u32 addr_tmp=0;
- sdelay(0x10000);
+ /* APLL= 1400 MHz MPLL=800 MHz */
+
+ writel(0x01000001, &clk->src_cpu); // 0x01000001 ok
- writel(CLK_SRC_TOP0_VAL, &clk->src_top0);
- writel(CLK_SRC_TOP1_VAL, &clk->src_top1);
- writel(CLK_SRC_DMC_VAL, &clk->src_dmc);
- writel(CLK_SRC_LEFTBUS_VAL, &clk->src_leftbus);
- writel(CLK_SRC_RIGHTBUS_VAL, &clk->src_rightbus);
+ sdelay(0x10000);
+ //CLK_DIV_LEFRBUS_VAL = 0x13 ??????? clk->div_leftbus
+ //CLK_DIV_RIGHTBUS_VAL = 0x13 ?????? clk->div_rightbus
+ writel(0x10, &clk->src_leftbus); //CLK_SRC_LEFTBUS_VAL = 0x10 ok
+ writel(0x10, &clk->src_rightbus); // CLK_SRC_RIGHTBUS_VAL = 0x10 ok
+ writel(0x110, &clk->src_top0); //CLK_DIV_DMC0_VAL = 0x100 ok
+ writel(0x1111000, &clk->src_top1); //CLK_SRC_TOP1_VAL = 0x01111000 ok
+ writel(0x00011000, &clk->src_dmc); // 0x00011000 ok
writel(CLK_SRC_FSYS_VAL, &clk->src_fsys);
writel(CLK_SRC_PERIL0_VAL, &clk->src_peril0);
writel(CLK_SRC_CAM_VAL, &clk->src_cam);
writel(CLK_SRC_MFC_VAL, &clk->src_mfc);
writel(CLK_SRC_G3D_VAL, &clk->src_g3d);
- writel(CLK_SRC_LCD0_VAL, &clk->src_lcd0);
sdelay(0x10000);
- writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0);
- writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1);
- writel(CLK_DIV_DMC0_VAL, &clk->div_dmc0);
- writel(CLK_DIV_DMC1_VAL, &clk->div_dmc1);
- writel(CLK_DIV_LEFTBUS_VAL, &clk->div_leftbus);
- writel(CLK_DIV_RIGHTBUS_VAL, &clk->div_rightbus);
- writel(CLK_DIV_TOP_VAL, &clk->div_top);
+ writel(0x1160730, &clk->div_cpu0); // CLK_DIV_CPU0_VAL = 0x2167730 ?????
+ writel(0x506, &clk->div_cpu1); // CLK_DIV_CPU1_VAL = 0x506 ok
+ writel(0x111113, &clk->div_dmc0); //CLK_DIV_DMC0_VAL = 0x111113 ok
+ writel(0x1011713, &clk->div_dmc1); //CLK_DIV_DMC1_VAL = 0x05051013 ?????
writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1);
- writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2);
+ writel(0x4070047, &clk->div_fsys2);
writel(CLK_DIV_FSYS3_VAL, &clk->div_fsys3);
writel(CLK_DIV_PERIL0_VAL, &clk->div_peril0);
writel(CLK_DIV_CAM_VAL, &clk->div_cam);
writel(CLK_DIV_MFC_VAL, &clk->div_mfc);
writel(CLK_DIV_G3D_VAL, &clk->div_g3d);
- writel(CLK_DIV_LCD0_VAL, &clk->div_lcd0);
/* Set PLL locktime */
- writel(PLL_LOCKTIME, &clk->apll_lock);
- writel(PLL_LOCKTIME, &clk->mpll_lock);
- writel(PLL_LOCKTIME, &clk->epll_lock);
- writel(PLL_LOCKTIME, &clk->vpll_lock);
-
- writel(APLL_CON1_VAL, &clk->apll_con1);
- writel(APLL_CON0_VAL, &clk->apll_con0);
- writel(MPLL_CON1_VAL, &clk->mpll_con1);
- writel(MPLL_CON0_VAL, &clk->mpll_con0);
- writel(EPLL_CON1_VAL, &clk->epll_con1);
- writel(EPLL_CON0_VAL, &clk->epll_con0);
- writel(VPLL_CON1_VAL, &clk->vpll_con1);
- writel(VPLL_CON0_VAL, &clk->vpll_con0);
+ writel(PLL_LOCKTIME, &clk->apll_lock); //APLL_LOCK_VAL = (APLL_PDIV * 270) = 0x3 * 270 = 0x32A ;1.4ghz ?????????
+ writel(PLL_LOCKTIME, &clk->mpll_lock); //MPLL_LOCK_VAL = MPLL_PDIV * 270) = 0x3 * 270 = 0x32A ;1.4ghz ?????????
+ writel(PLL_LOCKTIME, &clk->epll_lock); //EPLL_LOCK_VAL = (EPLL_PDIV * 3000) = 0x2 * 3000 = 0x1770 ??????
+ writel(PLL_LOCKTIME, &clk->vpll_lock); //VPLL_LOCK_VAL = (VPLL_PDIV * 3000) = 0x2 * 3000 = 0x1770 ??????
+ writel(0x803800, &clk->apll_con1); // APLL_CON1_VAL = (0x00803800) ok
+ writel(0x80af0300, &clk->apll_con0); // APLL_CON0_VAL = 8AF00300 ok
+ writel(0x803800, &clk->mpll_con1); //MPLL_CON1_VAL (0x00803800) ok
+ writel(0x80640300, &clk->mpll_con0); // MPLL_CON0_VAL = 0x80640300 ok
+ writel(EPLL_CON1_VAL, &clk->epll_con1); //EPLL_CON1_VAL = 0x66010000 ???????
+ writel(EPLL_CON0_VAL, &clk->epll_con0); //EPLL_CON0_VAL = 0x80400203 ???????
+ writel(VPLL_CON1_VAL, &clk->vpll_con1); //VPLL_CON1_VAL = 0x66010000 ??????? 0x11000400
+ writel(VPLL_CON0_VAL, &clk->vpll_con0); //VPLL_CON0_VAL = 0x80480203 ???????
+ //EPLL_CON2_VAL 0x00000080 ???? clk->epll_con2
+ //VPLL_CON2_VAL 0x00000080 ???? clk->vpll_con2
sdelay(0x30000);
+
}
diff --git a/arch/arm/mach-exynos/dmc_init_exynos4.c b/arch/arm/mach-exynos/dmc_init_exynos4.c
index ecddc72..7b30e2c 100755
--- a/arch/arm/mach-exynos/dmc_init_exynos4.c
+++ b/arch/arm/mach-exynos/dmc_init_exynos4.c
@@ -32,21 +32,22 @@ struct mem_timings mem = {
.direct_cmd_msr = {
DIRECT_CMD1, DIRECT_CMD2, DIRECT_CMD3, DIRECT_CMD4
},
- .timingref = TIMINGREF_VAL,
- .timingrow = TIMINGROW_VAL,
- .timingdata = TIMINGDATA_VAL,
- .timingpower = TIMINGPOWER_VAL,
- .zqcontrol = ZQ_CONTROL_VAL,
- .control0 = CONTROL0_VAL,
- .control1 = CONTROL1_VAL,
- .control2 = CONTROL2_VAL,
- .concontrol = CONCONTROL_VAL,
- .prechconfig = PRECHCONFIG,
- .memcontrol = MEMCONTROL_VAL,
- .memconfig0 = MEMCONFIG0_VAL,
- .memconfig1 = MEMCONFIG1_VAL,
+ .timingref = 0x000000bb,//TIMINGREF_VAL,
+ .timingrow = 0x7a46654f,//TIMINGROW_VAL,
+ .timingdata = 0x46400506,//TIMINGDATA_VAL,
+ .timingpower = 0x52000a3c,//TIMINGPOWER_VAL,
+ .zqcontrol = 0xe3854c03,//ZQ_CONTROL_VAL,
+ .control0 = 0x7110100b,//CONTROL0_VAL,
+ .control1 = 0xe0000086,//CONTROL1_VAL,
+ .control2 = 0x00000000,//CONTROL2_VAL,
+ .concontrol = 0x0fff333a,//CONCONTROL_VAL,
+ .prechconfig = 0xff000000,//PRECHCONFIG,
+ .memcontrol = 0x00302640,//MEMCONTROL_VAL,
+ .memconfig0 = 0x40c01333,//MEMCONFIG0_VAL,
+ .memconfig1 = 0x80e01323,//MEMCONFIG1_VAL,
.dll_resync = FORCE_DLL_RESYNC,
.dll_on = DLL_CONTROL_ON,
+
};
static void phy_control_reset(int ctrl_no, struct exynos4_dmc *dmc)
{
@@ -124,6 +125,8 @@ static void dmc_init(struct exynos4_dmc *dmc)
writel(mem.memconfig0, &dmc->memconfig0);
writel(mem.memconfig1, &dmc->memconfig1);
+ writel(0x8000001F, &dmc->ivcontrol);
+
/* Config Precharge Policy */
writel(mem.prechconfig, &dmc->prechconfig);
/*
diff --git a/arch/arm/mach-exynos/lowlevel_init.c b/arch/arm/mach-exynos/lowlevel_init.c
index 1e090fd..18aee59 100755
--- a/arch/arm/mach-exynos/lowlevel_init.c
+++ b/arch/arm/mach-exynos/lowlevel_init.c
@@ -218,7 +218,7 @@ int do_lowlevel_init(void)
#ifdef CONFIG_DEBUG_UART
#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL_SUPPORT)) || \
!defined(CONFIG_SPL_BUILD)
- exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
+ exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
debug_uart_init();
#endif
#endif
diff --git a/arch/arm/mach-exynos/spl_boot.c b/arch/arm/mach-exynos/spl_boot.c
index b4945bd..bc28cfc 100755
--- a/arch/arm/mach-exynos/spl_boot.c
+++ b/arch/arm/mach-exynos/spl_boot.c
@@ -228,12 +228,12 @@ void copy_uboot_to_ram(void)
#ifdef CONFIG_SUPPORT_EMMC_BOOT
case BOOT_MODE_EMMC:
/* Set the FSYS1 clock divisor value for EMMC boot */
- emmc_boot_clk_div_set();
+// emmc_boot_clk_div_set();
copy_bl2_from_emmc = get_irom_func(EMMC44_INDEX);
end_bootop_from_emmc = get_irom_func(EMMC44_END_INDEX);
- copy_bl2_from_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
+ copy_bl2_from_emmc(0x400, CONFIG_SYS_TEXT_BASE);
end_bootop_from_emmc();
break;
#endif
diff --git a/arch/arm/mach-exynos/tzpc.c b/arch/arm/mach-exynos/tzpc.c
index abe8e7f..b22c275 100755
--- a/arch/arm/mach-exynos/tzpc.c
+++ b/arch/arm/mach-exynos/tzpc.c
@@ -17,10 +17,7 @@ void tzpc_init(void)
start = samsung_get_base_tzpc();
- if (cpu_is_exynos5())
- end = start + ((EXYNOS5_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);
- else if (cpu_is_exynos4())
- end = start + ((EXYNOS4_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);
+ end = start + ((EXYNOS4_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);
for (addr = start; addr <= end; addr += TZPC_BASE_OFFSET) {
tzpc = (struct exynos_tzpc *)addr;
@@ -30,11 +27,8 @@ void tzpc_init(void)
writel(DECPROTXSET, &tzpc->decprot0set);
writel(DECPROTXSET, &tzpc->decprot1set);
-
- if (cpu_is_exynos5() && (addr == end))
- break;
-
- writel(DECPROTXSET, &tzpc->decprot2set);
+ writel(0xbd, &tzpc->decprot2set);
writel(DECPROTXSET, &tzpc->decprot3set);
}
+
}
diff --git a/include/configs/origen.h b/include/configs/origen.h
index 65e1c7c..515592d 100755
--- a/include/configs/origen.h
+++ b/include/configs/origen.h
@@ -46,7 +46,7 @@
/* MMC SPL */
#define COPY_BL2_FNPTR_ADDR 0x02020030
-#define CONFIG_SPL_TEXT_BASE 0x02021410
+#define CONFIG_SPL_TEXT_BASE 0x02023400
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=0x40007000\0" \
@@ -99,4 +99,14 @@
#define BL2_START_OFFSET ((CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)/512)
#define BL2_SIZE_BLOC_COUNT (COPY_BL2_SIZE/512)
+/* uart0 debug for spl */
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_DEBUG_UART
+#define CONFIG_DEBUG_UART_S5P
+#define CONFIG_DEBUG_UART_BASE 0x13800000 /* UART0 base address */
+#define CONFIG_DEBUG_UART_CLOCK (100000000) /* SCLK_UART0 is 100MHz */
+#define CONFIG_SUPPORT_EMMC_BOOT
+
+
#endif /* __CONFIG_H */
我这边的sd卡中的uboot是使用别人做好的现成的uboot(用sd_fuse目录下的sd_fusing.sh烧录uboot到sd卡中),这个uboot有提供现成的dnw命令,可供我们下载bin文件到emmc中uboot_tiny4412_0726.tar.gz
接下来介绍下dnw烧录的方式,pc端dnw我使用的是linux下dnw安装包适合tiny4412
在sd卡启动的uboot中输入命令:
fdisk -c 1 320 2057 520
fatformat mmc 1:1
ext3format mmc 1:2
ext3format mmc 1:3
ext3format mmc 1:4
#上面三个指令是分别对eMMC的分区2,3,4作ext3格式化
#接下来烧录bl1.bin, bl2.bin(由u-boot-spl.bin生成), u-boot.bin, tzsw.bin烧录到eMMC
emmc open 1
dnw
pc机输入命令:
dnw sd_fuse/tiny4412/E4412_N.bl1.bin
在sd卡启动的uboot中输入命令:
mmc write 1 0xc0000000 0 0x10
dnw
pc机输入命令:
sudo ./sd_fuse/mkbl2 ./spl/u-boot-spl.bin ./sd_fuse/tiny4412/bl2.bin 14336 # bl2.bin(由u-boot-spl.bin生成)
sudo dnw sd_fuse/tiny4412/bl2.bin
在sd卡启动的uboot中输入命令:
mmc write 1 0xc0000000 0x10 0x1C
dnw
pc机输入命令:
sudo dnw u-boot.bin
在sd卡启动的uboot中输入命令:
#从第48个block开始,写入0x400个block,0x400*512=524288 > 393456(我编译出来的uboot.bin的大小)
mmc write 1 0xc0000000 0x30 0x400
emmc close 1
#接下来把开关拨到emmc启动,再按下reset按键,就可以看到从emmc启动的uboot了
参考:
https://blog.csdn.net/fengyuwuzu0519/article/details/74080109
https://www.cnblogs.com/pengdonglin137/category/708681.html
https://blog.csdn.net/qq_33160790/article/category/7117737
https://blog.csdn.net/sinat_20006769/article/category/9271505