Booting mx25 based device from SD and NOR
Roberto Nibali
rnibali at gmail.com
Tue May 29 05:06:00 EDT 2012
Hi Eric
> >
> http://git.pengutronix.de/?p=barebox.git;a=blob;f=arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c;h=63e87c9551c440edab572f5252a503ba4d533161;hb=c48de4beee21c3a5573cec084123c33ae08f6f7a
> > >
> > >
> > Now that piece certainly was missing, but how the heck did you find out
> > those register values? Where did you get the information about writing to
> > chip select 0 and selecting:
> >
> > CSCR0U: 0x00008F03
> > CSCR0L: 0xA0330D01
> > CSCR0A: 0x002208C0
> >
> you need the reference manual of the i.MX25 to know the meaning of
> these registers and the datasheet of your flash to know it's timings
> then you can calculate the value to put in the registers.
>
>
I have found them in an old uboot tree a previous person patched to have
working support for NOR on boot. The values are:
{ .ptr_type = 4, .addr = 0xB8002000, .val = 0x0000D003, },
{ .ptr_type = 4, .addr = 0xB8002004, .val = 0x00330D01, },
{ .ptr_type = 4, .addr = 0xB8002008, .val = 0x00220800, },
Still it does not work at all, it does not display anything upon boot. How
could I debug this? I have adapted the DCD header (not needed in my case)
according to what the old uboot patches did, I have also put this into my
lowlevel_init (which I have studied extensively over the weekend and I
start understanding much better):
/* Check 24.3.3.1 and 24.5.4.1.1 */
static inline void __bare_init setup_sdram(uint32_t base, uint32_t esdctl,
uint32_t esdcfg)
{
uint32_t esdctlreg = ESDCTL0;
uint32_t esdcfgreg = ESDCFG0;
if (base == 0x90000000) {
esdctlreg += 8;
esdcfgreg += 8;
}
esdctl |= ESDCTL0_SDE;
writel(esdcfg, esdcfgreg);
writel(esdctl | ESDCTL0_SMODE_PRECHARGE, esdctlreg);
writel(0, base + 1024);
writel(esdctl | ESDCTL0_SMODE_AUTO_REFRESH, esdctlreg);
readb(base);
readb(base);
writel(esdctl | ESDCTL0_SMODE_LOAD_MODE, esdctlreg);
writeb(0, base + 0x33);
writel(esdctl, esdctlreg);
}
void __bare_init __naked board_init_lowlevel(void)
{
uint32_t r;
#ifdef CONFIG_NAND_IMX_BOOT
unsigned int *trg, *src;
#endif
/* restart the MPLL and wait until it's stable */
writel(readl(IMX_CCM_BASE + CCM_CCTL) | (1 << 27),
IMX_CCM_BASE + CCM_CCTL);
while (readl(IMX_CCM_BASE + CCM_CCTL) & (1 << 27)) {};
/* Configure dividers and ARM clock source
* ARM @ 400 MHz
* AHB @ 133 MHz
*/
writel(0x20034000, IMX_CCM_BASE + CCM_CCTL);
/* Set up 16bit NOR flash on WEIM CS0 */
writel(0xB8002000, 0x0000D003);
writel(0xB8002004, 0x00330D01);
writel(0xB8002008, 0x00220800);
/* AIPS setup - Only setup MPROTx registers. The PACR default values are
good.
* Set all MPROTx to be non-bufferable, trusted for R/W,
* not forced to user-mode.
*/
writel(0x77777777, 0x43f00000);
writel(0x77777777, 0x43f00004);
writel(0x77777777, 0x53f00000);
writel(0x77777777, 0x53f00004);
/* MAX (Multi-Layer AHB Crossbar Switch) setup
* MPR - priority for MX25 is (SDHC2/SDMA)>USBOTG>RTIC>IAHB>DAHB
*/
writel(0x00043210, 0x43f04000);
writel(0x00043210, 0x43f04100);
writel(0x00043210, 0x43f04200);
writel(0x00043210, 0x43f04300);
writel(0x00043210, 0x43f04400);
/* SGPCR - always park on last master */
writel(0x10, 0x43f04010);
writel(0x10, 0x43f04110);
writel(0x10, 0x43f04210);
writel(0x10, 0x43f04310);
writel(0x10, 0x43f04410);
/* MGPCR - restore default values */
writel(0x0, 0x43f04800);
writel(0x0, 0x43f04900);
writel(0x0, 0x43f04a00);
writel(0x0, 0x43f04b00);
writel(0x0, 0x43f04c00);
/* Configure M3IF registers
* M3IF Control Register (M3IFCTL) for MX25
* MRRP[0] = LCDC on priority list (1 << 0) = 0x00000001
* MRRP[1] = MAX1 not on priority list (0 << 1) = 0x00000000
* MRRP[2] = MAX0 not on priority list (0 << 2) = 0x00000000
* MRRP[3] = USB HOST not on priority list (0 << 3) = 0x00000000
* MRRP[4] = SDMA not on priority list (0 << 4) = 0x00000000
* MRRP[5] = SD/ATA/FEC not on priority list (0 << 5) = 0x00000000
* MRRP[6] = SCMFBC not on priority list (0 << 6) = 0x00000000
* MRRP[7] = CSI not on priority list (0 << 7) = 0x00000000
* ----------
* 0x00000001
*/
writel(0x1, 0xb8003000);
/* enable all the clocks */
/*
writel(0x1fffffff, IMX_CCM_BASE + CCM_CGCR0);
writel(0xffffffff, IMX_CCM_BASE + CCM_CGCR1);
writel(0x000fdfff, IMX_CCM_BASE + CCM_CGCR2);
*/
/* Set DDR2 and NFC group driver voltages */
writel(0x1000, IMX_IOMUXC_BASE + 0x454);
writel(0x2000, IMX_IOMUXC_BASE + 0x448);
/* Skip SDRAM initialization if we run from RAM */
r = get_pc();
if (r > 0x80000000 && r < 0x90000000)
board_init_lowlevel_return();
writel(ESDMISC_RST, ESDMISC);
while (!(readl(ESDMISC) & (1 << 31)));
#define ESDCTLVAL (ESDCTL0_ROW13 | ESDCTL0_COL9 | ESDCTL0_DSIZ_15_0 | \
ESDCTL0_REF4 | ESDCTL0_PWDT_PRECHARGE_PWDN | ESDCTL0_BL)
#define ESDCFGVAL (ESDCFGx_tRP_3 | ESDCFGx_tMRD_2 | ESDCFGx_tRAS_6 | \
ESDCFGx_tRRD_2 | ESDCFGx_tCAS_3 | ESDCFGx_tRCD_3 | \
ESDCFGx_tRC_9)
setup_sdram(0x80000000, ESDCTLVAL, ESDCFGVAL);
setup_sdram(0x90000000, ESDCTLVAL, ESDCFGVAL);
board_init_lowlevel_return();
}
Why can't I printf() from low_level?
I have also tried to what you did for your eukrea_cpuimx27.c:
diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h
b/arch/arm/mach-imx/include/mach/imx25-reg
index 73307c4..8225832 100644
--- a/arch/arm/mach-imx/include/mach/imx25-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx25-regs.h
@@ -72,6 +72,7 @@
#define CCM_LTR1 0x44
#define CCM_LTR2 0x48
#define CCM_LTR3 0x4c
+#define CCM_MCR 0x64
#define PDR0_AUTO_MUX_DIV(x) (((x) & 0x7) << 9)
#define PDR0_CCM_PER_AHB(x) (((x) & 0x7) << 12)
@@ -107,6 +108,22 @@
#define CSCR_L(x) (WEIM_BASE + 4 + (x) * 0x10)
#define CSCR_A(x) (WEIM_BASE + 8 + (x) * 0x10)
+/* Chip Select Registers */
+#define IMX_WEIM_BASE WEIM_BASE
+#define CSxU(x) __REG(IMX_WEIM_BASE + (cs * 0x10) + 0x00) /* Chip Select x
Upper Register */
+#define CSxL(x) __REG(IMX_WEIM_BASE + (cs * 0x10) + 0x04) /* Chip Select x
Lower Register */
+#define CSxA(x) __REG(IMX_WEIM_BASE + (cs * 0x10) + 0x08) /* Chip Select x
Addition Register */
+#define EIM __REG(IMX_WEIM_BASE + 0x60) /* WEIM Configuration Register
*/
+
+#ifndef __ASSEMBLY__
+static inline void imx25_setup_weimcs(size_t cs, unsigned upper, unsigned
lower, unsigned addional
+{
+ CSxU(cs) = upper;
+ CSxL(cs) = lower;
+ CSxA(cs) = addional;
+}
+#endif /* __ASSEMBLY__ */
+
/*
* Definitions for the clocksource driver
*
No matter what I do, it just does not work.
Regards
Roberto
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20120529/efff8820/attachment.html>
More information about the barebox
mailing list