环境:CCSv6.1.3, ti-processor-sdk-linux-k2hk-evm-03.00.00.04.
自己做的板子上66AK2H14挂了一片NOR Flash、一片NAND Flash,跟EVMK2H一样。但是66AK2H14的DDR3A使用的不是EVMK2H上的DIMM条,而是4颗DDR3 SDRAM颗粒,没有ECC。
然后我修改了这个目录下的UBoot源码\ti-processor-sdk-linux-k2hk-evm-03.00.00.04\board-support\u-boot-2016.05+gitAUTOINC+b4e185a8c3-gb4e185a8c3,重新配置DDR3A,修改后的代码如下:
/* * Keystone2: DDR3 initialization * * (C) Copyright 2012-2014 *Texas Instruments Incorporated, <www.ti.com> * * SPDX-License-Identifier:GPL-2.0+ */ #include <asm/io.h> #include <common.h> #include "ddr3_cfg.h" #include <asm/arch/ddr3.h> #include <asm/arch/hardware.h> struct pll_init_data ddr3a_333 = DDR3_PLL_333(A); struct pll_init_data ddr3a_400 = DDR3_PLL_400(A); struct ddr3_phy_config ddr3phy_1600_2g = { .pllcr= 0x0001C000ul, .pgcr1_mask= (IODDRM_MASK | ZCKSEL_MASK), .pgcr1_val= ((1 << 2) | (1 << 7) | (1 << 23)), .ptr0= 0x42C21590ul, .ptr1= 0xD05612C0ul, .ptr2= 0, /* not set in gel */ .ptr3= 0x0D861A80ul, .ptr4= 0x0C827100ul, .dcr_mask= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK), .dcr_val= ((1 << 10)), .dtpr0= 0x9D5CBB66ul, .dtpr1= 0x12868300ul, .dtpr2= 0x5002D200ul, .mr0= 0x00001C70ul, .mr1= 0x00000006ul, .mr2= 0x00000018ul, .dtcr= 0x710035C7ul, .pgcr2= 0x00F07A12ul, .zq0cr1= 0x0001005Dul, .zq1cr1= 0x0001005Bul, .zq2cr1= 0x0001005Bul, .pir_v1= 0x00000033ul, .pir_v2= 0x0000FF81ul, }; struct ddr3_emif_config ddr3_1600_2g = { .sdcfg= 0x6200CE62ul, .sdtim1= 0x166C9855ul, .sdtim2= 0x00001D4Aul, .sdtim3= 0x435DFF53ul, .sdtim4= 0x543F0CFFul, .zqcfg= 0x70073200ul, .sdrfc= 0x00001869ul, }; u32 ddr3_init(void) { u32 ddr3_size; struct ddr3_spd_cb spd_cb; printf("DDR3 speed %d\n", 1600); init_pll(&ddr3a_400); u32 value = __raw_readl(KS2_DDR3A_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); printf("Before DDR3 config: DDR3A PGSR0 vaule is 0x%X\n", value); if (cpu_revision() > 1) { //PG 2.0 //Reset DDR3A PHY after PLL enabled ddr3_reset_ddrphy(); spd_cb.phy_cfg.zq0cr1 |= 0x10000; spd_cb.phy_cfg.zq1cr1 |= 0x10000; spd_cb.phy_cfg.zq2cr1 |= 0x10000; } ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_2g); ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_2g); //ddr3_size = spd_cb.ddr_size_gbyte; //printf("DRAM: %d GiB (includes reported below)\n", ddr3_size); //Apply the workaround for PG 1.0 and 1.1 Silicons if (cpu_revision() <= 1) ddr3_err_reset_workaround(); value = __raw_readl(KS2_DDR3A_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); printf("After DDR3 config: DDR3A PGSR0 vaule is 0x%X\n", value); printf("DDR3 config done! Exit function ddr3_init!\n", value); return ddr3_size; }
然后使用如下命令重新编译UBoot镜像:
make clean make k2hk_evm_config make u-boot-spi.gph
然后再JTAG模式下,将u-boot-spi.gph烧写到NOR Flash中,再将66AK2H14设置为SPI Boot,可以看到UBoot从串口打印信息如下:
U-Boot SPL 2016.05-00230-g7b75190-dirty (Oct 15 2016 - 11:25:08) Debug Flag 06 Trying to boot from SPI U-Boot 2016.05-00230-g7b75190-dirty (Oct 15 2016 - 11:25:08 +0800) CPU: 66AK2Hx SR2.0 I2C:ready DRAM: DDR3 speed 1600 Before DDR3 config: DDR3A PGSR0 vaule is 0xB000001F After DDR3 config: DDR3A PGSR0 vaule is 0xB0000FFF DDR3 config done! Exit function ddr3_init! Debug Flag 01
可以看到的是DDR3A的leveling都已经通过,DDR3A配置正常。
但是然后UBoot就卡在这个地方不走了,打印“Debug Flag 01”的位置为\ti-processor-sdk-linux-k2hk-evm-03.00.00.04\board-support\u-boot-2016.05+gitAUTOINC+b4e185a8c3-gb4e185a8c3\board\ti\ks2_evm\board.c中的dram_init函数
int dram_init(void) { u32 ddr3_size; ddr3_size = ddr3_init(); //gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, CONFIG_MAX_RAM_BANK_SIZE); gd->ram_size =2; #if defined(CONFIG_TI_AEMIF) aemif_init(ARRAY_SIZE(aemif_configs), aemif_configs); #endif //if (ddr3_size) //ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE, ddr3_size); puts("Debug Flag 01\n"); return 0; }
我的意思是UBoot初始化完DDR3之后,从dram_init这个函数return之后就不再走了。
这是由于什么引起的吗?
我搜了一下相关的帖子,说UBoot在初始化DDR3结束之后,就将UBoot拷贝到DDR3上,接着继续执行。
这里我的代码已经将DDR3配置成功了(此时用仿真器连的话,可以正常访问0x8000_0000之后的DDR3内存)
所以难道UBoot没有执行拷贝?拷贝完了程序指针没有跳转?
请大家帮忙看下~谢谢!
Denny%20Yang99373:
初始化成功后,用CCS测试下DDR,是不是DDR读写有问题?
Feng Jin:
回复 Denny%20Yang99373:
UBoot卡住的时候,我用仿真器JTAG方式下(没带GEL)连上片子,测试DDR3没有问题。不是EDMA测的,是手动在Memory Broswer下向0x8000_0000输入数据没有问题。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Updates:
我跟踪UBoot代码运行发现,UBoot是卡在\common\board_f.c里面的show_dram_config函数的地方,我感觉不需要打印DRAM配置信息,于是把这句话注释了。
重新编译UBoot,再跑一下,跟踪代码发现此时UBoot跑完了\common\board_f.c里面的board_init_f函数,然后UBoot就又不再运行,而且此时再用JTAG连的话,ARM核就连不上了,显示如下信息:
CortexA15_1: Trouble Halting Target CPU: (Error -1323 @ 0xC000514) Device failed to enter debug/halt mode because pipeline is stalled. Power-cycle the board. If error persists, confirm configuration and/or try more reliable JTAG settings (e.g. lower TCLK). (Emulation package 6.0.222.0)IcePick_D_0: Power Failure on Target CPU类似于ARM核被reset着,或者ARM PLL被重新配错了。
请问UBoot跑完board_init_f这个函数以后,具体的下一条执行的函数是在哪?会重新配ARM PLL吗?
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
谢谢!