[U-Boot] Hangs at relocation on 460EX Target

Hello,
We've got our custom hardware in and are having trouble getting u-boot to start up. We've modeled our board close to the canyonlands. The main differences are no sensors, DIMM at 0x51, and a 16Mb NOR flash instead of 64Mb. We boot and get messages and we've determined it is stuck inside the relocation or immediately after it branches to the code in RAM.
My first thought is that we need to make several changes to handle the 16Mb flash since there was some code to handle the movement of the 64Mb flash in early_init_r. It seems for us that is not needed.
Secondly, there might be some changes needed to the EBC Setup in the config file. However I've compared those to the data sheet and not seeing anything obvious. I have disabled early_init_r and made the following changes to the configuration
#define CFG_FLASH_BASE 0xFF000000 * later mapped to this addr */
#define CFG_FLASH_BASE_PHYS_H 0x0 #define CFG_FLASH_BASE_PHYS_L 0xFF000000 #define CFG_FLASH_BASE_PHYS (((u64)CFG_FLASH_BASE_PHYS_H << 32) | \ (u64)CFG_FLASH_BASE_PHYS_L)
#define CFG_FLASH_SIZE (16 << 20)
Any tips to what else I might be missing? I don't recall having this much difficulty last time u-boot was ported to our boards.
Thanks Ayman

On Tuesday 21 October 2008, Ayman M. El-Khashab wrote:
We've got our custom hardware in and are having trouble getting u-boot to start up. We've modeled our board close to the canyonlands. The main differences are no sensors, DIMM at 0x51, and a 16Mb NOR flash instead of 64Mb. We boot and get messages and we've determined it is stuck inside the relocation or immediately after it branches to the code in RAM.
I suggest that you enable DEBUG in lib_ppc/board.c (define DEBUG before the #includes). This will show you a little more.
But you may be correct that U-Boot hangs/crashes upon relocation. This is most likely a problem with the DDR2 configuration. You might have noticed the latest autocalibration changes for the 4xx DDR2 controller. It's worth to give these new methods a try.
My first thought is that we need to make several changes to handle the 16Mb flash since there was some code to handle the movement of the 64Mb flash in early_init_r. It seems for us that is not needed.
Secondly, there might be some changes needed to the EBC Setup in the config file. However I've compared those to the data sheet and not seeing anything obvious. I have disabled early_init_r and made the following changes to the configuration
#define CFG_FLASH_BASE 0xFF000000 * later mapped to this addr */
#define CFG_FLASH_BASE_PHYS_H 0x0 #define CFG_FLASH_BASE_PHYS_L 0xFF000000 #define CFG_FLASH_BASE_PHYS (((u64)CFG_FLASH_BASE_PHYS_H << 32) | \ (u64)CFG_FLASH_BASE_PHYS_L)
#define CFG_FLASH_SIZE (16 << 20)
Any tips to what else I might be missing? I don't recall having this much difficulty last time u-boot was ported to our boards.
On the 460EX/GT is especially hard to handle bigger boot FLASH sizes because of it's restricted boot map size.
But this is most likely not your problem. I'm pretty sure that you are experiencing SDRAM problem.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Thank you Stefan,
On Tue, Oct 21, 2008 at 05:54:21PM +0200, Stefan Roese wrote:
On Tuesday 21 October 2008, Ayman M. El-Khashab wrote:
it is stuck inside the relocation or immediately after it branches to the code in RAM.
I suggest that you enable DEBUG in lib_ppc/board.c (define DEBUG before the #includes). This will show you a little more.
I should have mentioned that we have DEBUG enabled and we've also run the RAM test that is included in u-boot. The ram test does pass.
But you may be correct that U-Boot hangs/crashes upon relocation. This is most likely a problem with the DDR2 configuration. You might have noticed the latest autocalibration changes for the 4xx DDR2 controller. It's worth to give these new methods a try.
I am not familiar with those, I thought that once the SDRAM is operating you cannot alter those calibration and timing/delay registers. Is this calibration something that is enabled in u-boot or just via the register accesses to the memory controller?
Thanks Ayman

Dear "Ayman M. El-Khashab",
In message 20081021162030.GB22117@crust.elkhashab.com you wrote:
I should have mentioned that we have DEBUG enabled and we've also run the RAM test that is included in u-boot. The ram test does pass.
Please see the FAQ, entry # 1. Passing the RAM test does not mean anything when it comes to accessing the RAM in burst mode.
I am not familiar with those, I thought that once the SDRAM is operating you cannot alter those calibration and timing/delay registers. Is this calibration something that is enabled in u-boot or just via the register accesses to the memory controller?
How about reading the code?
Best regards,
Wolfgang Denk

On Tue, Oct 21, 2008 at 09:10:03PM +0200, Wolfgang Denk wrote:
I should have mentioned that we have DEBUG enabled and we've also run the RAM test that is included in u-boot. The ram test does pass.
Please see the FAQ, entry # 1. Passing the RAM test does not mean anything when it comes to accessing the RAM in burst mode.
Ok, makes sense I understand that the ram test is not sufficient to fully exercise the bus. In particular, it appears that it does not have lots of entropy, so shorted address/data may not be detected and the timing tolerance is much wider than would be found in normal operating conditions.
I am not familiar with those, I thought that once the SDRAM is operating you cannot alter those calibration and timing/delay registers. Is this calibration something that is enabled in u-boot or just via the register accesses to the memory controller?
How about reading the code?
(Looking at canyonlands.h)
Ok, I took a look at this and the autocalibration is not obvious. It looks like there is a currently a hardcoded RQDC value of 80000038. If this is undefined then the code will go into the autocalibration mode. So I've undefined it and sure enough it goes into autocalibration. The part that is odd is that the autocal does not work on the Canyonlands board. If it is enabled, then the Canyonlands fails in the same way as our hardware. I.e. right at the time of relocation, it just hangs. When set back to the hardcoded value, the canyonlands works fine.
Perusing the code, the only sort of exception that I noticed was one for the Katmai. During operation I don't see the code fail to find the window, so it appears that it finds a suitable value. When examined with the abatron it looks like a value is set into the mfio_rqdc register.
So I am somewhat puzzled. It is not obvious to me why the autocal is failing to work on the canyonlands.
On another project we found that the window constrained slightly when operating in burst mode (via DMA) vs regular ram line reads/writes. I don't know if that could be the same issue where since the failure is just at the time the burst mode is enabled.
Thanks, Ayman

On Tuesday 21 October 2008, Ayman M. El-Khashab wrote:
How about reading the code?
(Looking at canyonlands.h)
Ok, I took a look at this and the autocalibration is not obvious. It looks like there is a currently a hardcoded RQDC value of 80000038. If this is undefined then the code will go into the autocalibration mode. So I've undefined it and sure enough it goes into autocalibration. The part that is odd is that the autocal does not work on the Canyonlands board. If it is enabled, then the Canyonlands fails in the same way as our hardware. I.e. right at the time of relocation, it just hangs. When set back to the hardcoded value, the canyonlands works fine.
Perusing the code, the only sort of exception that I noticed was one for the Katmai. During operation I don't see the code fail to find the window, so it appears that it finds a suitable value. When examined with the abatron it looks like a value is set into the mfio_rqdc register.
So I am somewhat puzzled. It is not obvious to me why the autocal is failing to work on the canyonlands.
Yes, there have been issues with the "old" autocalibration code on some boards. That's one reason that AMCC provided a new version just a few weeks ago:
075d0b81e896e8735ae26372cd384f87cbd24e41
ppc4xx: IBM Memory Controller DDR autocalibration routines
Alternate SDRAM DDR autocalibration routine that can be generically used for any PPC4xx chips that have the IBM SDRAM Controller core allowing for support of more DIMM/memory chip vendors and gets the DDR autocalibration values which give the best read latency performance (SDRAM0_RDCC.[RDSS]).
Two alternate SDRAM DDR autocalibration algoritm are provided in this patch, "Method_A" and "Method_B". DDR autocalibration Method_A scans the full range of possible PPC4xx SDRAM Controller DDR autocalibration values and takes a lot longer to run than Method_B. Method_B executes in the same amount of time as the currently existing DDR autocalibration routine, i.e. 1 second or so. Normally Method_B is used and it is set as the default method.
The current U-Boot PPC4xx DDR autocalibration code calibrates the IBM SDRAM Controller registers.[bit-field]: 1) SDRAM0_RQDC.[RQFD] 2) SDRAM0_RFDC.[RFFD]
This alternate PPC4xx DDR autocalibration code calibrates the following IBM SDRAM Controller registers.[bit-field]:
1) SDRAM0_WRDTR.[WDTR] 2) SDRAM0_CLKTR.[CKTR] 3) SDRAM0_RQDC.[RQFD] 4) SDRAM0_RFDC.[RFFD]
and will also use the calibrated settings of the above four registers that produce the best "Read Sample Cycle Select" value in the SDRAM0_RDCC.[RDSS] register.[bit-field].
Signed-off-by: Adam Graham agraham@amcc.com Signed-off-by: Stefan Roese sr@denx.de
It's currently only used on Kilauea (405EX) but I think it should work on Canyonlands as well. So I suggest you give this version a try. IIRC, it also has some advanced debugging mechanisms that you could use to track down the problems.
Here an extract from kilauea.h:
/* * CONFIG_PPC4xx_DDR_AUTOCALIBRATION * * Note: DDR Autocalibration Method_A scans the full range of possible PPC4xx * SDRAM Controller DDR autocalibration values and takes a lot longer * to run than Method_B. * (See the Method_A and Method_B algorithm discription in the file: * cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c) * Define CONFIG_PPC4xx_DDR_METHOD_A to use DDR autocalibration Method_A * * DDR Autocalibration Method_B is the default. */ #define CONFIG_PPC4xx_DDR_AUTOCALIBRATION /* IBM DDR autocalibration */ #define DEBUG_PPC4xx_DDR_AUTOCALIBRATION /* dynamic DDR autocal debug */ #undef CONFIG_PPC4xx_DDR_METHOD_A
Give it a try in your board (and Canyonlands as well) and let me know if this helps or not.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

On Wed, Oct 22, 2008 at 07:12:30AM +0200, Stefan Roese wrote:
Yes, there have been issues with the "old" autocalibration code on some boards. That's one reason that AMCC provided a new version just a few weeks ago:
Thanks Stefan, I've got the hardware mostly working now. The new calibration code did work once I got past another issue. I'll try to describe it here b/c It *might* be a bug, but I wasn't 100% sure.
First, I am using registered ecc dimms which appears to be handled in cpu/ppc4xx/44x_spd_ddr2.c However, what I found by observing the registers with the abatron was that the SDRAM_MCOPT1_RDEN was not set for the registered DIMM. Following the code, it looks like it should have been set if "registered" was set, but it does not appear that it worked correctly. So of course we were off by 1/2. I forced the bit in the mcopt1 variable and that fixed all the problems.
Any thoughts or is there something I can try/contribute?
Thanks Ayman

On Thursday 23 October 2008, Ayman M. El-Khashab wrote:
On Wed, Oct 22, 2008 at 07:12:30AM +0200, Stefan Roese wrote:
Yes, there have been issues with the "old" autocalibration code on some boards. That's one reason that AMCC provided a new version just a few weeks ago:
Thanks Stefan, I've got the hardware mostly working now.
Great, congrats.
The new calibration code did work once I got past another issue. I'll try to describe it here b/c It *might* be a bug, but I wasn't 100% sure.
First, I am using registered ecc dimms which appears to be handled in cpu/ppc4xx/44x_spd_ddr2.c
I personally have never used a registered DIMM on the 4xx systems. And I don't know of any systems that do. So it could be that this is still untested and buggy.
However, what I found by observing the registers with the abatron was that the SDRAM_MCOPT1_RDEN was not set for the registered DIMM. Following the code, it looks like it should have been set if "registered" was set, but it does not appear that it worked correctly. So of course we were off by 1/2. I forced the bit in the mcopt1 variable and that fixed all the problems.
Good.
Any thoughts or is there something I can try/contribute?
Best would be if you could provide a proper patch to fix this problem. Please see here:
http://www.denx.de/wiki/view/U-Boot/Patches
how this is done correctly.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Hi,
I had the same problem with u-boot-1.3.4 on custom 460EX board with registered SODIMM. The SPD code in 4xx_spd_ddr2.c (program_copt1()) checks two SPD fields to decide whether DIMM is registered: DDRII DIMM type (offset 20) and SDRAM module attributes (offset 21).
In my case, the values in these fields do not match what code is looking for. See http://www.micron.com/products/spddetail.aspx?part=MT9HTF6472RHY-667F1 I had to modify the following peice in program_copt1() to make it work:
if (dimm_num == 0) { if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */ mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE; if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */ mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE; if (registered == 1) { /* DDR2 always buffered */ /* TODO: what about above comments ? */ mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } else { /* TODO: the mask 0x02 doesn't match Samsung def for byte 21. */ if ((attribute & 0x02) == 0x00) { /* buffered not supported */ buf0 = FALSE; } else { mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } } }
I've changed
if ((attribute & 0x02) == 0x00)
to be
if (((attribute & 0x02) == 0x00) && (attribute != 0x04))
I'm not sure this is generic enough to go into mainline, but if yes, I can try to submit a patch.
Felix.
Stefan Roese wrote:
On Thursday 23 October 2008, Ayman M. El-Khashab wrote:
On Wed, Oct 22, 2008 at 07:12:30AM +0200, Stefan Roese wrote:
Yes, there have been issues with the "old" autocalibration code on some boards. That's one reason that AMCC provided a new version just a few weeks ago:
Thanks Stefan, I've got the hardware mostly working now.
Great, congrats.
The new calibration code did work once I got past another issue. I'll try to describe it here b/c It *might* be a bug, but I wasn't 100% sure.
First, I am using registered ecc dimms which appears to be handled in cpu/ppc4xx/44x_spd_ddr2.c
I personally have never used a registered DIMM on the 4xx systems. And I don't know of any systems that do. So it could be that this is still untested and buggy.
However, what I found by observing the registers with the abatron was that the SDRAM_MCOPT1_RDEN was not set for the registered DIMM. Following the code, it looks like it should have been set if "registered" was set, but it does not appear that it worked correctly. So of course we were off by 1/2. I forced the bit in the mcopt1 variable and that fixed all the problems.
Good.
Any thoughts or is there something I can try/contribute?
Best would be if you could provide a proper patch to fix this problem. Please see here:
http://www.denx.de/wiki/view/U-Boot/Patches
how this is done correctly.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de ===================================================================== _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Felix,
On Thursday 23 October 2008, Felix Radensky wrote:
I had the same problem with u-boot-1.3.4 on custom 460EX board with registered SODIMM. The SPD code in 4xx_spd_ddr2.c (program_copt1()) checks two SPD fields to decide whether DIMM is registered: DDRII DIMM type (offset 20) and SDRAM module attributes (offset 21).
In my case, the values in these fields do not match what code is looking for. See http://www.micron.com/products/spddetail.aspx?part=MT9HTF6472RHY-667F1 I had to modify the following peice in program_copt1() to make it work:
if (dimm_num == 0) { if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */ mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE; if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */ mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE; if (registered == 1) { /* DDR2 always buffered */ /* TODO: what about above comments ? */ mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } else { /* TODO: the mask 0x02 doesn't match Samsung def for
byte 21. */
So it seems already to be know that here is a problem.
if ((attribute & 0x02) == 0x00) { /* buffered not supported */ buf0 = FALSE; } else { mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } } }
I've changed
if ((attribute & 0x02) == 0x00)
to be
if (((attribute & 0x02) == 0x00) && (attribute != 0x04))
Why did you change it this way? Which DDR2 module are you using? And what's the value of SPD register 21?
I'm not sure this is generic enough to go into mainline, but if yes, I can try to submit a patch.
We should try to provide a generic fix now. Unfortunately I don't have the time right now to dig into the DDR2 SPD definitions and the different implementation for different brands (Micron, Samsung...). Perhaps somebody else could check what the correct check for registered DIMM is.
Thanks.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Hi, Stefan
Stefan Roese wrote:
Felix,
On Thursday 23 October 2008, Felix Radensky wrote:
I had the same problem with u-boot-1.3.4 on custom 460EX board with registered SODIMM. The SPD code in 4xx_spd_ddr2.c (program_copt1()) checks two SPD fields to decide whether DIMM is registered: DDRII DIMM type (offset 20) and SDRAM module attributes (offset 21).
In my case, the values in these fields do not match what code is looking for. See http://www.micron.com/products/spddetail.aspx?part=MT9HTF6472RHY-667F1 I had to modify the following peice in program_copt1() to make it work:
if (dimm_num == 0) { if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */ mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE; if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */ mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE; if (registered == 1) { /* DDR2 always buffered */ /* TODO: what about above comments ? */ mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } else { /* TODO: the mask 0x02 doesn't match Samsung def for
byte 21. */
So it seems already to be know that here is a problem.
if ((attribute & 0x02) == 0x00) { /* buffered not supported */ buf0 = FALSE; } else { mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } } }
I've changed
if ((attribute & 0x02) == 0x00)
to be
if (((attribute & 0x02) == 0x00) && (attribute != 0x04))
Why did you change it this way? Which DDR2 module are you using? And what's the value of SPD register 21?
My change causes the code to go into else branch and set SDRAM_MCOPT1_RDEN (registered) bit. I'm using Micron 512M registered SODIMM. The value of SPD register 21 is 0x4. The full SPD spec is here: http://www.micron.com/products/spddetail.aspx?part=MT9HTF6472RHY-667F1
Felix.

On Thursday 23 October 2008, Felix Radensky wrote:
I've changed
if ((attribute & 0x02) == 0x00)
to be
if (((attribute & 0x02) == 0x00) && (attribute != 0x04))
Why did you change it this way? Which DDR2 module are you using? And what's the value of SPD register 21?
My change causes the code to go into else branch and set SDRAM_MCOPT1_RDEN (registered) bit. I'm using Micron 512M registered SODIMM. The value of SPD register 21 is 0x4. The full SPD spec is here: http://www.micron.com/products/spddetail.aspx?part=MT9HTF6472RHY-667F1
Thanks.
Ayman, which module are you using and what's your reg 21 value? Does anybody have the time to dig into those specs to find a common solution?
Thanks.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

On Thu, Oct 23, 2008 at 10:39:11AM +0200, Stefan Roese wrote:
Ayman, which module are you using and what's your reg 21 value? Does anybody have the time to dig into those specs to find a common solution?
I am using a Kingston mini-dimm, my reg 21 value is 0x4, so 1 pll / 1 reg. For reg 20, it is reported as a Mini-Registered DIMM with 0x10
I will have time after this week to take a look if it would help.
Thank you, Ayman
participants (4)
-
Ayman M. El-Khashab
-
Felix Radensky
-
Stefan Roese
-
Wolfgang Denk