[U-Boot] [PATCH 1/3] tegra: add a method to query RAM size from hardware

The RAM configuration is set by the bootrom to values specified by the BCT. To query the available RAM size of a board we can easily read back those values instead of using the hardcoded ODMdata. This allows for a single u-boot image on similar boards with different amount of RAM.
Note that the register description in the TRM is not entirely correct here.
Signed-off-by: Lucas Stach dev@lynxeye.de CC: Stephen Warren swarren@wwwdotorg.org CC: Tom Warren twarren.nvidia@gmail.com CC: Marek Vasut marex@denx.de --- arch/arm/cpu/armv7/tegra2/board.c | 21 ++++++++++++++++++++- arch/arm/include/asm/arch-tegra2/tegra2.h | 1 + 2 Dateien geändert, 21 Zeilen hinzugefügt(+), 1 Zeile entfernt(-)
diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c index 923678d..850a517 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -23,12 +23,14 @@
#include <common.h> #include <asm/io.h> -#include <asm/arch/ap20.h> +#include <asm/sizes.h> #include <asm/arch/clock.h> #include <asm/arch/funcmux.h> #include <asm/arch/pmc.h> #include <asm/arch/sys_proto.h> #include <asm/arch/tegra2.h> +#include <asm/arch/pmc.h> +#include <asm/arch/emc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -47,6 +49,22 @@ enum {
unsigned int query_sdram_size(void) { +#ifdef CONFIG_TEGRA_RAMSIZE_BCT + /* get the memory size from the BCT programmed EMC register */ + struct emc_ctlr *const emc = (struct emc_ctlr *)TEGRA2_EMC_BASE; + u32 cfg, cfg1 = 0, sz1 = 0, sz2 = 0; + + cfg = readl(&emc->adr_cfg); + sz1 = SZ_4M << ((cfg & (0xf << 16)) >> 16); + + /* if EMEM_NUMDEV is N2 we have to also read info for the second device */ + if (cfg & (0x1 << 25)) { + cfg1 = readl(&emc->adr_cfg1); + sz2 = SZ_4M << ((cfg1 & (0xf << 16)) >> 16); + } + + return sz1 + sz2; +#else struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; u32 reg;
@@ -63,6 +81,7 @@ unsigned int query_sdram_size(void) case 3: return 0x40000000; /* 1GB */ } +#endif }
int dram_init(void) diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h b/arch/arm/include/asm/arch-tegra2/tegra2.h index d4ada10..8b57b77 100644 --- a/arch/arm/include/asm/arch-tegra2/tegra2.h +++ b/arch/arm/include/asm/arch-tegra2/tegra2.h @@ -41,6 +41,7 @@ #define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400) #define TEGRA2_SPI_BASE (NV_PA_APB_MISC_BASE + 0xC380) #define TEGRA2_PMC_BASE (NV_PA_APB_MISC_BASE + 0xE400) +#define TEGRA2_EMC_BASE (NV_PA_APB_MISC_BASE + 0xF400) #define TEGRA2_FUSE_BASE (NV_PA_APB_MISC_BASE + 0xF800) #define NV_PA_CSITE_BASE 0x70040000 #define TEGRA_USB1_BASE 0xC5000000

Signed-off-by: Lucas Stach dev@lynxeye.de CC: Stephen Warren swarren@wwwdotorg.org CC: Tom Warren twarren@nvidia.com --- arch/arm/cpu/armv7/tegra2/funcmux.c | 13 ++++++++++++- arch/arm/include/asm/arch-tegra2/funcmux.h | 3 +++ 2 Dateien geändert, 15 Zeilen hinzugefügt(+), 1 Zeile entfernt(-)
diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c index 820ba4e9..455d010 100644 --- a/arch/arm/cpu/armv7/tegra2/funcmux.c +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -209,9 +209,20 @@ int funcmux_select(enum periph_id id, int config) pinmux_set_func(grp[i], PMUX_FUNC_KBC); pinmux_set_pullupdown(grp[i], PMUX_PULL_UP); } + } + break;
- break; + case PERIPH_ID_USB2: + if (config == FUNCMUX_USB2_ULPI) { + pinmux_set_func(PINGRP_UAA, PMUX_FUNC_ULPI); + pinmux_set_func(PINGRP_UAB, PMUX_FUNC_ULPI); + pinmux_set_func(PINGRP_UDA, PMUX_FUNC_ULPI); + + pinmux_tristate_disable(PINGRP_UAA); + pinmux_tristate_disable(PINGRP_UAB); + pinmux_tristate_disable(PINGRP_UDA); } + break;
default: debug("%s: invalid periph_id %d", __func__, id); diff --git a/arch/arm/include/asm/arch-tegra2/funcmux.h b/arch/arm/include/asm/arch-tegra2/funcmux.h index b16c496..3cbc7d2 100644 --- a/arch/arm/include/asm/arch-tegra2/funcmux.h +++ b/arch/arm/include/asm/arch-tegra2/funcmux.h @@ -51,6 +51,9 @@ enum { FUNCMUX_SDMMC4_ATC_ATD_8BIT = 0, FUNCMUX_SDMMC4_ATB_GMA_4_BIT, FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT, + + /* USB configs */ + FUNCMUX_USB2_ULPI = 0, };
/**

On 05/29/2012 03:47 PM, Lucas Stach wrote:
Signed-off-by: Lucas Stach dev@lynxeye.de
Acked-by: Stephen Warren swarren@wwwdotorg.org
Although two comments: * A commit description would be a good idea * The indentation change to the KBC case might be better as a separate commit.

Just stumbled upon this, while looking through the usb code. loop_count runs down from 10000, so the correct condition to error out is ==0.
Signed-off-by: Lucas Stach dev@lynxeye.de CC: Stephen Warren swarren@wwwdotorg.org CC: Tom Warren twarren.nvidia@gmail.com --- arch/arm/cpu/armv7/tegra2/usb.c | 2 +- 1 Datei geändert, 1 Zeile hinzugefügt(+), 1 Zeile entfernt(-)
diff --git a/arch/arm/cpu/armv7/tegra2/usb.c b/arch/arm/cpu/armv7/tegra2/usb.c index c80de7f..5f2b243 100644 --- a/arch/arm/cpu/armv7/tegra2/usb.c +++ b/arch/arm/cpu/armv7/tegra2/usb.c @@ -290,7 +290,7 @@ static int init_usb_controller(struct fdt_usb *config, break; udelay(1); } - if (loop_count == 100000) + if (!loop_count) return -1;
return 0;

On 05/29/2012 03:47 PM, Lucas Stach wrote:
Just stumbled upon this, while looking through the usb code. loop_count runs down from 10000, so the correct condition to error out is ==0.
The code change is probably fine, but it'd be better if the commit description stated just what was being changed and why, rather than being conversational.
Acked-by: Stephen Warren swarren@wwwdotorg.org

Lucas,
On Tue, May 29, 2012 at 3:18 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 05/29/2012 03:47 PM, Lucas Stach wrote:
Just stumbled upon this, while looking through the usb code. loop_count runs down from 10000, so the correct condition to error out is ==0.
The code change is probably fine, but it'd be better if the commit description stated just what was being changed and why, rather than being conversational.
Acked-by: Stephen Warren swarren@wwwdotorg.org
In addition, I'd like to see come comment in the commit msg about what HW this was tested on, what was done to test it, etc.
Tom

On 05/29/2012 03:47 PM, Lucas Stach wrote:
The RAM configuration is set by the bootrom to values specified by the BCT. To query the available RAM size of a board we can easily read back those values instead of using the hardcoded ODMdata. This allows for a single u-boot image on similar boards with different amount of RAM.
While this probably works fine (although I didn't read it in detail), the boot protocol is defined to work a little differently. U-Boot is supposed to read the BCT/BIT from the IRAM, and program PMC_SCRATCH20 with the ODMDATA, and then the rest of the bootloader and kernel can continue to use the fields in the ODMDATA as they currently do.
Tom, you wrote commit f22c431 "arm: Tegra: Use ODMDATA from BCT in IRAM" in our downstream tree for this. Are you planning on upstreaming it?

On Tue, May 29, 2012 at 3:12 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 05/29/2012 03:47 PM, Lucas Stach wrote:
The RAM configuration is set by the bootrom to values specified by the BCT. To query the available RAM size of a board we can easily read back those values instead of using the hardcoded ODMdata. This allows for a single u-boot image on similar boards with different amount of RAM.
While this probably works fine (although I didn't read it in detail), the boot protocol is defined to work a little differently. U-Boot is supposed to read the BCT/BIT from the IRAM, and program PMC_SCRATCH20 with the ODMDATA, and then the rest of the bootloader and kernel can continue to use the fields in the ODMDATA as they currently do.
Tom, you wrote commit f22c431 "arm: Tegra: Use ODMDATA from BCT in IRAM" in our downstream tree for this. Are you planning on upstreaming it?
Eventually, yes. The nice thing about using a (flash) cmd-line variable ODMData is that you can vary things like RAM size, UART, etc. With Lucas' change, you get the fixed RAM size directly from the HW instead of the ODMDATA (which could be wrong, since it currently has no bearing on anything else in the BL code, and isn't checked against what's in the BCT/BIT that the BootROM used).
I'll work up a patchset for upstream that takes the ODMData from the flash cmd line and we can discuss the merits of each approach.
Tom

On 05/29/2012 05:19 PM, Tom Warren wrote:
On Tue, May 29, 2012 at 3:12 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 05/29/2012 03:47 PM, Lucas Stach wrote:
The RAM configuration is set by the bootrom to values specified by the BCT. To query the available RAM size of a board we can easily read back those values instead of using the hardcoded ODMdata. This allows for a single u-boot image on similar boards with different amount of RAM.
While this probably works fine (although I didn't read it in detail), the boot protocol is defined to work a little differently. U-Boot is supposed to read the BCT/BIT from the IRAM, and program PMC_SCRATCH20 with the ODMDATA, and then the rest of the bootloader and kernel can continue to use the fields in the ODMDATA as they currently do.
Tom, you wrote commit f22c431 "arm: Tegra: Use ODMDATA from BCT in IRAM" in our downstream tree for this. Are you planning on upstreaming it?
Eventually, yes. The nice thing about using a (flash) cmd-line variable ODMData is that you can vary things like RAM size, UART, etc. With Lucas' change, you get the fixed RAM size directly from the HW instead of the ODMDATA (which could be wrong, since it currently has no bearing on anything else in the BL code, and isn't checked against what's in the BCT/BIT that the BootROM used).
I don't quite understand. Doesn't the boot ROM read the ODMDATA in order to set up the EMC register that Lucas' change reads? Hmm. Perhaps not ODMDATA, but at least some field in the BCT. And when flashing, both the ODMDATA and the BCT are part of the flashing process.

On Tue, May 29, 2012 at 4:47 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 05/29/2012 05:19 PM, Tom Warren wrote:
On Tue, May 29, 2012 at 3:12 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 05/29/2012 03:47 PM, Lucas Stach wrote:
The RAM configuration is set by the bootrom to values specified by the BCT. To query the available RAM size of a board we can easily read back those values instead of using the hardcoded ODMdata. This allows for a single u-boot image on similar boards with different amount of RAM.
While this probably works fine (although I didn't read it in detail), the boot protocol is defined to work a little differently. U-Boot is supposed to read the BCT/BIT from the IRAM, and program PMC_SCRATCH20 with the ODMDATA, and then the rest of the bootloader and kernel can continue to use the fields in the ODMDATA as they currently do.
Tom, you wrote commit f22c431 "arm: Tegra: Use ODMDATA from BCT in IRAM" in our downstream tree for this. Are you planning on upstreaming it?
Eventually, yes. The nice thing about using a (flash) cmd-line variable ODMData is that you can vary things like RAM size, UART, etc. With Lucas' change, you get the fixed RAM size directly from the HW instead of the ODMDATA (which could be wrong, since it currently has no bearing on anything else in the BL code, and isn't checked against what's in the BCT/BIT that the BootROM used).
I don't quite understand. Doesn't the boot ROM read the ODMDATA in order to set up the EMC register that Lucas' change reads? Hmm. Perhaps not ODMDATA, but at least some field in the BCT. And when flashing, both the ODMDATA and the BCT are part of the flashing process.
The BootROM uses the BCT (and maybe the ODMDATA) to set up the SDRAM, including, I assume, the size. What I'm talking about is varying the ODMDATA RAM size bits so that the BL and kernel/OS see a smaller amount of RAM, so you could, for instance, test how things run in 1GB on a 2GB system. Not sure if that's actually applicable, but the flexibility is there when you allow the ODMData to be changed.
Let me get the patch up, and we can discuss it further then.

On 05/30/2012 10:04 AM, Tom Warren wrote:
On Tue, May 29, 2012 at 4:47 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 05/29/2012 05:19 PM, Tom Warren wrote:
On Tue, May 29, 2012 at 3:12 PM, Stephen Warren swarren@wwwdotorg.org wrote:
On 05/29/2012 03:47 PM, Lucas Stach wrote:
The RAM configuration is set by the bootrom to values specified by the BCT. To query the available RAM size of a board we can easily read back those values instead of using the hardcoded ODMdata. This allows for a single u-boot image on similar boards with different amount of RAM.
While this probably works fine (although I didn't read it in detail), the boot protocol is defined to work a little differently. U-Boot is supposed to read the BCT/BIT from the IRAM, and program PMC_SCRATCH20 with the ODMDATA, and then the rest of the bootloader and kernel can continue to use the fields in the ODMDATA as they currently do.
Tom, you wrote commit f22c431 "arm: Tegra: Use ODMDATA from BCT in IRAM" in our downstream tree for this. Are you planning on upstreaming it?
Eventually, yes. The nice thing about using a (flash) cmd-line variable ODMData is that you can vary things like RAM size, UART, etc. With Lucas' change, you get the fixed RAM size directly from the HW instead of the ODMDATA (which could be wrong, since it currently has no bearing on anything else in the BL code, and isn't checked against what's in the BCT/BIT that the BootROM used).
I don't quite understand. Doesn't the boot ROM read the ODMDATA in order to set up the EMC register that Lucas' change reads? Hmm. Perhaps not ODMDATA, but at least some field in the BCT. And when flashing, both the ODMDATA and the BCT are part of the flashing process.
The BootROM uses the BCT (and maybe the ODMDATA) to set up the SDRAM, including, I assume, the size. What I'm talking about is varying the ODMDATA RAM size bits so that the BL and kernel/OS see a smaller amount of RAM, so you could, for instance, test how things run in 1GB on a 2GB system. Not sure if that's actually applicable, but the flexibility is there when you allow the ODMData to be changed.
Oh right. I don't think we should support putting the wrong data into ODMDATA at all.
Having U-Boot or the kernel assume less RAM for testing purposes seems reasonable. I don't know of a way to do that in U-Boot right now other than changing the ODMDATA (which as I'll explain below I don't like) or editing the source. Since this is a pretty low-level testing thing, I think editing the source is a reasonable method. For the kernel, this can easily be achieved by editing the device tree or using the mem= command-line argument.
I don't know if the boot ROM does use ODMDATA to initialize the memory controller or not, but since the fields are defined, I think we can't rule out that it either does now or will in a future chip. Typically, the memory controller (EMC) initialization would need to know exactly how many chips, chip selects, RAS/CAS lines etc. are actually present. Some of that information might be automatically derived from the total RAM size coupled with knowledge of supported configurations in HW. In other words, if we lie to the EMC setup code about the RAM size, it's quite possible it would completely mis-program the EMC and hence nothing would work. So, I think we should, as policy, require that any BCT/ODMDATA/BIT-related data always be completely accurate, and use other techniques to test limited-memory scenarios.
participants (3)
-
Lucas Stach
-
Stephen Warren
-
Tom Warren