summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorChin Liang See <clsee@altera.com>2013-12-03 14:43:55 -0800
committerChin Liang See <clsee@altera.com>2013-12-03 14:43:55 -0800
commit82310b73c91a4dfbead6c6c3663e161beaa8121a (patch)
treefd6756ff54a8f3301efe3885250034bd001bc18c /arch
parentc62bd7dea69f3193e471f66bbc2f1a06ce91186b (diff)
downloadu-boot-socfpga-82310b73c91a4dfbead6c6c3663e161beaa8121a.tar.gz
FogBugz #168357: Enhance to auto calculate SDRAM size
Enhance Preloader and U-Boot to auto calculate the SDRAM size. This will save user from the hassle of modifying the PHYS_SDRAM_1 macro when the SDRAM change. The SDRAM size calculation will based on SDRAM controller settings such as address row, columns, banks and others. Signed-off-by: Chin Liang See <clsee@altera.com> --- Changes for v2 - using macro for SDRAM width with ECC enabled - fixed the SDRAM size calculation algorithm
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv7/socfpga/sdram.c41
-rw-r--r--arch/arm/cpu/armv7/socfpga/sdram_test.c5
-rw-r--r--arch/arm/cpu/armv7/socfpga/spl.c18
-rw-r--r--arch/arm/include/asm/arch-socfpga/sdram.h8
4 files changed, 64 insertions, 8 deletions
diff --git a/arch/arm/cpu/armv7/socfpga/sdram.c b/arch/arm/cpu/armv7/socfpga/sdram.c
index 2536c7bb96..862991ef61 100644
--- a/arch/arm/cpu/armv7/socfpga/sdram.c
+++ b/arch/arm/cpu/armv7/socfpga/sdram.c
@@ -40,7 +40,14 @@ unsigned long irq_cnt_ecc_sdram;
/* Initialise the DRAM by telling the DRAM Size */
int dram_init(void)
{
- gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
+ unsigned long sdram_size;
+
+#ifdef CONFIG_SDRAM_CALCULATE_SIZE
+ sdram_size = sdram_calculate_size();
+#else
+ sdram_size = PHYS_SDRAM_1_SIZE;
+#endif
+ gd->ram_size = get_ram_size(0, sdram_size);
return 0;
}
@@ -1020,3 +1027,35 @@ unsigned sdram_calibration_full(void)
#endif /* CONFIG_SPL_BUILD */
+/* To calculate SDRAM device size based on SDRAM controller parameters
+ * Size is specified in bytes
+ */
+unsigned long sdram_calculate_size(void)
+{
+ unsigned long temp;
+ unsigned long row, bank, col, cs, width;
+
+ temp = readl(SOCFPGA_SDR_ADDRESS +
+ SDR_CTRLGRP_DRAMADDRW_ADDRESS);
+ col = (temp & SDR_CTRLGRP_DRAMADDRW_COLBITS_MASK) >>
+ SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB;
+ row = (temp & SDR_CTRLGRP_DRAMADDRW_ROWBITS_MASK) >>
+ SDR_CTRLGRP_DRAMADDRW_ROWBITS_LSB;
+ bank = (temp & SDR_CTRLGRP_DRAMADDRW_BANKBITS_MASK) >>
+ SDR_CTRLGRP_DRAMADDRW_BANKBITS_LSB;
+ cs = (temp & SDR_CTRLGRP_DRAMADDRW_CSBITS_MASK) >>
+ SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB;
+
+ width = readl(SOCFPGA_SDR_ADDRESS +
+ SDR_CTRLGRP_DRAMIFWIDTH_ADDRESS);
+ /* ECC would not be calculated as its not addressible */
+ if (width == SDRAM_WIDTH_32BIT_WITH_ECC)
+ width = 32;
+ if (width == SDRAM_WIDTH_16BIT_WITH_ECC)
+ width = 16;
+
+ /* calculate the SDRAM size base on this info */
+ temp = 1 << (row + bank + col);
+ temp = temp * cs * (width / 8);
+ return temp;
+}
diff --git a/arch/arm/cpu/armv7/socfpga/sdram_test.c b/arch/arm/cpu/armv7/socfpga/sdram_test.c
index 0f57298b5e..70761fc071 100644
--- a/arch/arm/cpu/armv7/socfpga/sdram_test.c
+++ b/arch/arm/cpu/armv7/socfpga/sdram_test.c
@@ -79,10 +79,9 @@ int test_rand_address(int loop_cnt, unsigned int addr_bgn,
* SDRAM_TEST_NORMAL -> normal test which run around 30s
* SDRAM_TEST_LONG -> long test which run in minutes
*/
-int hps_emif_diag_test(int coverage)
+int hps_emif_diag_test(int coverage, unsigned int addr_bgn,
+ unsigned int addr_end)
{
- unsigned int addr_bgn = CONFIG_SYS_MEMTEST_START;
- unsigned int addr_end = CONFIG_SYS_MEMTEST_END;
int cnt_max = 1000000, status;
unsigned int seed = 0xdeadbeef;
diff --git a/arch/arm/cpu/armv7/socfpga/spl.c b/arch/arm/cpu/armv7/socfpga/spl.c
index db243ed9fe..6323557f9d 100644
--- a/arch/arm/cpu/armv7/socfpga/spl.c
+++ b/arch/arm/cpu/armv7/socfpga/spl.c
@@ -194,6 +194,10 @@ void spl_program_fpga_qspi(void)
*/
void spl_board_init(void)
{
+#if (CONFIG_PRELOADER_SKIP_SDRAM == 0)
+ unsigned long sdram_size;
+#endif
+
#ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET
cm_config_t cm_default_cfg = {
/* main group */
@@ -479,11 +483,19 @@ void spl_board_init(void)
/* SDRAM calibration */
if (sdram_calibration_full() == 0)
hang();
+
+ /* detect the SDRAM size */
+#ifdef CONFIG_SDRAM_CALCULATE_SIZE
+ sdram_size = sdram_calculate_size();
+#else
+ sdram_size = PHYS_SDRAM_1_SIZE;
+#endif
+ printf("SDRAM: %ld MiB\n", (sdram_size >> 20));
+
#if (CONFIG_PRELOADER_HARDWARE_DIAGNOSTIC == 1)
/* Sanity check ensure correct SDRAM size specified */
puts("SDRAM: Ensuring specified SDRAM size is correct ...");
- /* start with 1MB region as lowest 1MB is OCRAM */
- if (get_ram_size(0, PHYS_SDRAM_1_SIZE) != PHYS_SDRAM_1_SIZE) {
+ if (get_ram_size(0, sdram_size) != sdram_size) {
puts("failed\n");
hang();
}
@@ -495,7 +507,7 @@ void spl_board_init(void)
* SDRAM_TEST_NORMAL -> normal test which run around 30s
* SDRAM_TEST_LONG -> long test which run in minutes
*/
- if (hps_emif_diag_test(SDRAM_TEST_FAST) == 0)
+ if (hps_emif_diag_test(SDRAM_TEST_FAST, 0, sdram_size) == 0)
hang();
#endif /* CONFIG_PRELOADER_HARDWARE_DIAGNOSTIC */
#endif /* CONFIG_PRELOADER_SKIP_SDRAM */
diff --git a/arch/arm/include/asm/arch-socfpga/sdram.h b/arch/arm/include/asm/arch-socfpga/sdram.h
index 1e75a4a043..7d52ef3c1f 100644
--- a/arch/arm/include/asm/arch-socfpga/sdram.h
+++ b/arch/arm/include/asm/arch-socfpga/sdram.h
@@ -35,7 +35,9 @@ extern unsigned long irq_cnt_ecc_sdram;
void irq_handler_ecc_sdram(void *arg);
void sdram_enable_interrupt(unsigned enable);
void sdram_applycfg_uboot(void);
-int hps_emif_diag_test(int complexity);
+int hps_emif_diag_test(int complexity, unsigned int addr_bgn,
+ unsigned int addr_end);
+unsigned long sdram_calculate_size(void);
#ifdef CONFIG_SPL_BUILD
unsigned sdram_mmr_init_full(void);
unsigned sdram_calibration_full(void);
@@ -425,4 +427,8 @@ SDR_CTRLGRP_MPTHRESHOLDRST_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64_MASK \
/* long test which run in minutes */
#define SDRAM_TEST_LONG 2
+/* SDRAM width macro for configuration with ECC */
+#define SDRAM_WIDTH_32BIT_WITH_ECC 40
+#define SDRAM_WIDTH_16BIT_WITH_ECC 24
+
#endif /* _SDRAM_H_ */