From d38da537943cd36356b9d3d9d9b60533554b81d8 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 23 Jan 2008 17:20:14 +0100 Subject: [PATCH] AVR32: Make SDRAM refresh rate configurable 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 --- board/atmel/atngw100/atngw100.c | 3 +++ board/atmel/atstk1000/atstk1000.c | 3 +++ cpu/at32ap/hsdramc.c | 6 +++++- include/asm-avr32/arch-at32ap700x/clk.h | 3 +++ include/asm-avr32/sdram.h | 3 +++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/board/atmel/atngw100/atngw100.c b/board/atmel/atngw100/atngw100.c index bd4b6b4ce5..1ccbe2c181 100644 --- a/board/atmel/atngw100/atngw100.c +++ b/board/atmel/atngw100/atngw100.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -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) diff --git a/board/atmel/atstk1000/atstk1000.c b/board/atmel/atstk1000/atstk1000.c index 6618963cc0..28f64c4a6f 100644 --- a/board/atmel/atstk1000/atstk1000.c +++ b/board/atmel/atstk1000/atstk1000.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -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) diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c index a936e03166..1fcfe75d74 100644 --- a/cpu/at32ap/hsdramc.c +++ b/cpu/at32ap/hsdramc.c @@ -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); diff --git a/include/asm-avr32/arch-at32ap700x/clk.h b/include/asm-avr32/arch-at32ap700x/clk.h index ea84c0874c..385319aac7 100644 --- a/include/asm-avr32/arch-at32ap700x/clk.h +++ b/include/asm-avr32/arch-at32ap700x/clk.h @@ -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__ */ diff --git a/include/asm-avr32/sdram.h b/include/asm-avr32/sdram.h index 5057eefa8a..833af6e6ad 100644 --- a/include/asm-avr32/sdram.h +++ b/include/asm-avr32/sdram.h @@ -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); -- 2.25.1