AVR32: Make SDRAM refresh rate configurable
authorHaavard Skinnemoen <hskinnemoen@atmel.com>
Wed, 23 Jan 2008 16:20:14 +0000 (17:20 +0100)
committerHaavard Skinnemoen <hskinnemoen@atmel.com>
Tue, 5 Feb 2008 11:14:27 +0000 (12:14 +0100)
The existing code assumes the SDRAM row refresh period should always
be 15.6 us. This is not always true, and indeed on the ATNGW100, the
refresh rate should really be 7.81 us.

Add a refresh_period member to struct sdram_info and initialize it
properly for both ATSTK1000 and ATNGW100. Out-of-tree boards will
panic() until the refresh_period member is updated properly.

Big thanks to Gerhard Berghofer for pointing out this issue.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
board/atmel/atngw100/atngw100.c
board/atmel/atstk1000/atstk1000.c
cpu/at32ap/hsdramc.c
include/asm-avr32/arch-at32ap700x/clk.h
include/asm-avr32/sdram.h

index bd4b6b4ce5b8cabc90dbc5b8a635b74d70de7157..1ccbe2c181752c08e5cb02d671e6b3a5dad72916 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <asm/io.h>
 #include <asm/sdram.h>
+#include <asm/arch/clk.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/hmatrix2.h>
 
@@ -40,6 +41,8 @@ static const struct sdram_info sdram = {
        .trcd           = 2,
        .tras           = 5,
        .txsr           = 5,
+       /* 7.81 us */
+       .refresh_period = (781 * (SDRAMC_BUS_HZ / 1000)) / 100000,
 };
 
 int board_early_init_f(void)
index 6618963cc0e4ed6a17c07877b7ccaf0c27b20b6b..28f64c4a6f240d0c1a5392264828da9d94295301 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <asm/io.h>
 #include <asm/sdram.h>
+#include <asm/arch/clk.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/hmatrix2.h>
 
@@ -40,6 +41,8 @@ static const struct sdram_info sdram = {
        .trcd           = 2,
        .tras           = 5,
        .txsr           = 5,
+       /* 15.6 us */
+       .refresh_period = (156 * (SDRAMC_BUS_HZ / 1000)) / 10000,
 };
 
 int board_early_init_f(void)
index a936e03166c1d81de52c760962b642c933ee92f5..1fcfe75d745768a881d1e3220a98542a2de6e000 100644 (file)
@@ -38,6 +38,10 @@ unsigned long sdram_init(const struct sdram_info *info)
        unsigned long bus_hz;
        unsigned int i;
 
+       if (!info->refresh_period)
+               panic("ERROR: SDRAM refresh period == 0. "
+                               "Please update the board code\n");
+
        tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
               | HSDRAMC1_BF(NR, info->row_bits - 11)
               | HSDRAMC1_BF(NB, info->bank_bits - 1)
@@ -113,7 +117,7 @@ unsigned long sdram_init(const struct sdram_info *info)
         * 15.6 us is a typical value for a burst of length one
         */
        bus_hz = get_sdram_clk_rate();
-       hsdramc1_writel(TR, (156 * (bus_hz / 1000)) / 10000);
+       hsdramc1_writel(TR, info->refresh_period);
 
        printf("SDRAM: %u MB at address 0x%08lx\n",
               sdram_size >> 20, info->phys_addr);
index ea84c0874c0acc7478d8e4d4a611c105efe5aff8..385319aac758d1cce268c6e5d4cc5724cf8e6f41 100644 (file)
@@ -75,4 +75,7 @@ static inline unsigned long get_mci_clk_rate(void)
 }
 #endif
 
+/* Board code may need the SDRAM base clock as a compile-time constant */
+#define SDRAMC_BUS_HZ  (MAIN_CLK_RATE >> CFG_CLKDIV_HSB)
+
 #endif /* __ASM_AVR32_ARCH_CLK_H__ */
index 5057eefa8ad66e9c651f1dd690fceff7f0ad7197..833af6e6ad160c1bbf05e1dd7c905d57972114d2 100644 (file)
@@ -26,6 +26,9 @@ struct sdram_info {
        unsigned long phys_addr;
        unsigned int row_bits, col_bits, bank_bits;
        unsigned int cas, twr, trc, trp, trcd, tras, txsr;
+
+       /* SDRAM refresh period in cycles */
+       unsigned long refresh_period;
 };
 
 extern unsigned long sdram_init(const struct sdram_info *info);