summaryrefslogtreecommitdiffstats
path: root/sys/arm/at91
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2006-06-20 20:13:40 +0000
committerimp <imp@FreeBSD.org>2006-06-20 20:13:40 +0000
commitda7a558f2ecbc1670e062416489b5d6941ad24c5 (patch)
tree3f4bcc24b979fb0d1802411172119a694f75d643 /sys/arm/at91
parent41188bcabec5989b5df3b8e9aa9b8451d12d237b (diff)
downloadFreeBSD-src-da7a558f2ecbc1670e062416489b5d6941ad24c5.zip
FreeBSD-src-da7a558f2ecbc1670e062416489b5d6941ad24c5.tar.gz
Probe the memory size of the board better. Look at the bus width,
number of banks, rows and columns the SDRAMC is programmed to access to determine the RAM size for the board, rather than hard-wiring it to be 32MB. My company's board with 64MB now probes correctly, as does the KB9202 with only 32MB. This means that to detect the right memory size, our boot loader must correctly initialize these values. This is a fairly safe assumption because the boot loader has to initialize SDRAM already, and it isn't really possible to change this register after we've accessed SDRAM.
Diffstat (limited to 'sys/arm/at91')
-rw-r--r--sys/arm/at91/at91rm92reg.h40
-rw-r--r--sys/arm/at91/kb920x_machdep.c22
2 files changed, 60 insertions, 2 deletions
diff --git a/sys/arm/at91/at91rm92reg.h b/sys/arm/at91/at91rm92reg.h
index 0c4473b..7a26339 100644
--- a/sys/arm/at91/at91rm92reg.h
+++ b/sys/arm/at91/at91rm92reg.h
@@ -341,4 +341,44 @@
#define AT91C_MASTER_CLOCK 60000000
+/* SDRAMC */
+
+#define AT91RM92_SDRAMC_BASE 0xfffff90
+#define AT91RM92_SDRAMC_MR 0x00
+#define AT91RM92_SDRAMC_MR_MODE_NORMAL 0
+#define AT91RM92_SDRAMC_MR_MODE_NOP 1
+#define AT91RM92_SDRAMC_MR_MODE_PRECHARGE 2
+#define AT91RM92_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
+#define AT91RM92_SDRAMC_MR_MODE_REFRESH 4
+#define AT91RM92_SDRAMC_MR_DBW_16 0x10
+#define AT91RM92_SDRAMC_TR 0x04
+#define AT91RM92_SDRAMC_CR 0x08
+#define AT91RM92_SDRAMC_CR_NC_8 0x0
+#define AT91RM92_SDRAMC_CR_NC_9 0x1
+#define AT91RM92_SDRAMC_CR_NC_10 0x2
+#define AT91RM92_SDRAMC_CR_NC_11 0x3
+#define AT91RM92_SDRAMC_CR_NC_MASK 0x00000003
+#define AT91RM92_SDRAMC_CR_NR_11 0x0
+#define AT91RM92_SDRAMC_CR_NR_12 0x4
+#define AT91RM92_SDRAMC_CR_NR_13 0x8
+#define AT91RM92_SDRAMC_CR_NR_RES 0xc
+#define AT91RM92_SDRAMC_CR_NR_MASK 0x0000000c
+#define AT91RM92_SDRAMC_CR_NB_2 0x00
+#define AT91RM92_SDRAMC_CR_NB_4 0x10
+#define AT91RM92_SDRAMC_CR_NB_MASK 0x00000010
+#define AT91RM92_SDRAMC_CR_NCAS_MASK 0x00000060
+#define AT91RM92_SDRAMC_CR_TWR_MASK 0x00000780
+#define AT91RM92_SDRAMC_CR_TRC_MASK 0x00007800
+#define AT91RM92_SDRAMC_CR_TRP_MASK 0x00078000
+#define AT91RM92_SDRAMC_CR_TRCD_MASK 0x00780000
+#define AT91RM92_SDRAMC_CR_TRAS_MASK 0x07800000
+#define AT91RM92_SDRAMC_CR_TXSR_MASK 0x78000000
+#define AT91RM92_SDRAMC_SRR 0x0c
+#define AT91RM92_SDRAMC_LPR 0x10
+#define AT91RM92_SDRAMC_IER 0x14
+#define AT91RM92_SDRAMC_IDR 0x18
+#define AT91RM92_SDRAMC_IMR 0x1c
+#define AT91RM92_SDRAMC_ISR 0x20
+#define AT91RM92_SDRAMC_IER_RES 0x1
+
#endif /* AT91RM92REG_H_ */
diff --git a/sys/arm/at91/kb920x_machdep.c b/sys/arm/at91/kb920x_machdep.c
index 18301c4..da6c6a6 100644
--- a/sys/arm/at91/kb920x_machdep.c
+++ b/sys/arm/at91/kb920x_machdep.c
@@ -182,6 +182,24 @@ static const struct pmap_devmap kb920x_devmap[] = {
extern vm_offset_t ksym_start, ksym_end;
#endif
+static int
+board_init(void)
+{
+ uint32_t memsize;
+ uint32_t *SDRAMC = (uint32_t *)(AT91RM92_BASE + AT91RM92_SDRAMC_BASE);
+ uint32_t cr, mr;
+ int banks, rows, cols, bw; /* log2 size */
+
+ cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
+ mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
+ bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2;
+ banks = (cr & AT91RM92_SDRAMC_CR_NB_4) ? 2 : 1;
+ rows = ((cr & AT91RM92_SDRAMC_CR_NR_MASK) >> 2) + 11;
+ cols = (cr & AT91RM92_SDRAMC_CR_NC_MASK) + 8;
+ memsize = 1 << (cols + rows + banks + bw);
+ return (memsize);
+}
+
void *
initarm(void *arg, void *arg2)
{
@@ -192,7 +210,7 @@ initarm(void *arg, void *arg2)
vm_offset_t afterkern;
int i = 0;
uint32_t fake_preload[35];
- uint32_t memsize = 32 * 1024 * 1024;
+ uint32_t memsize;
vm_offset_t lastaddr;
#ifdef DDB
vm_offset_t zstart = 0, zend = 0;
@@ -341,7 +359,7 @@ initarm(void *arg, void *arg2)
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
cninit();
-
+ memsize = board_init();
/*
* Pages were allocated during the secondary bootstrap for the
* stacks for different CPU modes.
OpenPOWER on IntegriCloud