imx-common: cpu: add imx_ddr_size
authorTroy Kisky <troy.kisky@boundarydevices.com>
Tue, 23 Oct 2012 10:57:48 +0000 (10:57 +0000)
committerStefano Babic <sbabic@denx.de>
Sat, 10 Nov 2012 07:15:40 +0000 (08:15 +0100)
Read memory setup registers to determine size
of available ram. This routine works for mx53/mx6x

I need this because when mx6solo called get_ram_size
with a too large maximum size, the system hanged.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
arch/arm/imx-common/cpu.c
arch/arm/include/asm/arch-mx5/sys_proto.h
arch/arm/include/asm/arch-mx6/sys_proto.h

index 102c254a45f1641d5c6b6218f40a5aab326e100f..50819085550d363a7558166c378a6840c39c75de 100644 (file)
@@ -65,6 +65,56 @@ char *get_reset_cause(void)
        }
 }
 
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
+#if defined(CONFIG_MX53)
+#define MEMCTL_BASE    ESDCTL_BASE_ADDR;
+#else
+#define MEMCTL_BASE    MMDC_P0_BASE_ADDR;
+#endif
+static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
+static const unsigned char bank_lookup[] = {3, 2};
+
+struct esd_mmdc_regs {
+       uint32_t        ctl;
+       uint32_t        pdc;
+       uint32_t        otc;
+       uint32_t        cfg0;
+       uint32_t        cfg1;
+       uint32_t        cfg2;
+       uint32_t        misc;
+       uint32_t        scr;
+       uint32_t        ref;
+       uint32_t        rsvd1;
+       uint32_t        rsvd2;
+       uint32_t        rwd;
+       uint32_t        or;
+       uint32_t        mrr;
+       uint32_t        cfg3lp;
+       uint32_t        mr4;
+};
+
+#define ESD_MMDC_CTL_GET_ROW(mdctl)    ((ctl >> 24) & 7)
+#define ESD_MMDC_CTL_GET_COLUMN(mdctl) ((ctl >> 20) & 7)
+#define ESD_MMDC_CTL_GET_WIDTH(mdctl)  ((ctl >> 16) & 3)
+#define ESD_MMDC_CTL_GET_CS1(mdctl)    ((ctl >> 30) & 1)
+#define ESD_MMDC_MISC_GET_BANK(mdmisc) ((misc >> 5) & 1)
+
+unsigned imx_ddr_size(void)
+{
+       struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE;
+       unsigned ctl = readl(&mem->ctl);
+       unsigned misc = readl(&mem->misc);
+       int bits = 11 + 0 + 0 + 1;      /* row + col + bank + width */
+
+       bits += ESD_MMDC_CTL_GET_ROW(ctl);
+       bits += col_lookup[ESD_MMDC_CTL_GET_COLUMN(ctl)];
+       bits += bank_lookup[ESD_MMDC_MISC_GET_BANK(misc)];
+       bits += ESD_MMDC_CTL_GET_WIDTH(ctl);
+       bits += ESD_MMDC_CTL_GET_CS1(ctl);
+       return 1 << bits;
+}
+#endif
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
 
 const char *get_imx_type(u32 imxtype)
index 4435be1ee9a055f3f876aa258e9e45ac156f8984..93ad1c6b336715acc80bf1477d69ea1707e25164 100644 (file)
@@ -33,6 +33,7 @@
 
 #define is_soc_rev(rev)        ((get_cpu_rev() & 0xFF) - rev)
 u32 get_cpu_rev(void);
+unsigned imx_ddr_size(void);
 void sdelay(unsigned long);
 void set_chipselect_size(int const);
 
index 6627bbc02175f224fca06f61a502664801c1783d..319329761049a62516999fc30f0f0220a15ebca9 100644 (file)
@@ -34,6 +34,7 @@
 #define is_soc_rev(rev)        ((get_cpu_rev() & 0xFF) - rev)
 u32 get_cpu_rev(void);
 const char *get_imx_type(u32 imxtype);
+unsigned imx_ddr_size(void);
 
 void set_vddsoc(u32 mv);