summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2013-01-27 17:40:51 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2013-01-27 21:26:51 +0100
commit11bae6b40a50b48d5ee9924ac9ef3a85889c7dc9 (patch)
treebea7ca904117eaefbe61b3120bce84268d4a3c25
parent7cf50cf26cfc13607bec45f5499900ae802e7e62 (diff)
downloadbarebox-11bae6b40a50b48d5ee9924ac9ef3a85889c7dc9.tar.gz
barebox-11bae6b40a50b48d5ee9924ac9ef3a85889c7dc9.tar.xz
at91sam9x5: add autodetect sd/ddram size
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/arm/mach-at91/at91sam9x5_devices.c4
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h58
2 files changed, 62 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/at91sam9x5_devices.c b/arch/arm/mach-at91/at91sam9x5_devices.c
index 8e59fe0113..90d8756438 100644
--- a/arch/arm/mach-at91/at91sam9x5_devices.c
+++ b/arch/arm/mach-at91/at91sam9x5_devices.c
@@ -16,6 +16,7 @@
#include <mach/board.h>
#include <mach/at91_pmc.h>
#include <mach/at91sam9x5_matrix.h>
+#include <mach/at91sam9_ddrsdr.h>
#include <mach/gpio.h>
#include <mach/io.h>
#include <mach/cpu.h>
@@ -25,6 +26,9 @@
void at91_add_device_sdram(u32 size)
{
+ if (!size)
+ size = at91sam9x5_get_ddram_size();
+
arm_add_mem_device("ram0", AT91_CHIPSELECT_1, size);
add_mem_device("sram0", AT91SAM9X5_SRAM_BASE,
AT91SAM9X5_SRAM_SIZE, IORESOURCE_MEM_WRITEABLE);
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
index 070f730618..90937f4757 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -50,6 +50,10 @@
#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver [SAM9 Only] */
#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared [SAM9 Only] */
#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */
+#define AT91_DDRSDRC_NB (1 << 20) /* Number of
+Banks [not SAM9G45] */
+#define AT91_SDRAMC_NB_4 (0 << 20)
+#define AT91_SDRAMC_NB_8 (1 << 20)
#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
@@ -131,4 +135,58 @@
#define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */
#define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */
+#ifndef __ASSEMBLY__
+#include <mach/io.h>
+
+static inline u32 at91_get_ddram_size(void * __iomem base, bool is_nb)
+{
+ u32 cr;
+ u32 mdr;
+ u32 size;
+ bool is_sdram;
+
+ cr = __raw_readl(base + AT91_DDRSDRC_CR);
+ mdr = __raw_readl(base + AT91_DDRSDRC_CR);
+
+ is_sdram = (mdr & AT91_DDRSDRC_MD) <= AT91_DDRSDRC_MD_LOW_POWER_SDR;
+
+ /* Formula:
+ * size = bank << (col + row + 1);
+ * if (bandwidth == 32 bits)
+ * size <<= 1;
+ */
+ size = 1;
+ /* COL */
+ size += (cr & AT91_DDRSDRC_NC) + 8;
+ if (is_sdram)
+ size ++;
+ /* ROW */
+ size += ((cr & AT91_DDRSDRC_NR) >> 2) + 11;
+ /* BANK */
+ if (is_nb)
+ size = ((cr & AT91_DDRSDRC_NB) ? 8 : 4) << size;
+ else
+ size = 4 << size;
+
+ /* bandwidth */
+ if (!(mdr & AT91_DDRSDRC_DBW))
+ size <<= 1;
+
+ return size;
+}
+
+#ifdef CONFIG_SOC_AT91SAM9X5
+static inline u32 at91sam9x5_get_ddram_size(void)
+{
+ return at91_get_ddram_size(IOMEM(AT91SAM9X5_BASE_DDRSDRC0), true);
+}
+#else
+static inline u32 at91sam9x5_get_ddram_size(void)
+{
+ return 0;
+}
+#endif
+
+#endif
+
#endif