summaryrefslogtreecommitdiffstats
path: root/board
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-02-04 10:12:32 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2010-03-03 08:41:07 +0100
commit3b9f0a68693478136efdff0db0e4bb4e16d75031 (patch)
tree44b14951d985279393b27d7a59e7ae40d5fa1aa1 /board
parent53eaaf0f823066da80b8bdfb7a1a3628ae6efc77 (diff)
downloadbarebox-3b9f0a68693478136efdff0db0e4bb4e16d75031.tar.gz
barebox-3b9f0a68693478136efdff0db0e4bb4e16d75031.tar.xz
pcm038: initialize PLLs from internal RAM
The PLL setup occasionally fails when the setup code runs from SDRAM, so copy a little assembler helper function to SRAM and execute it there. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'board')
-rw-r--r--board/pcm038/Makefile2
-rw-r--r--board/pcm038/pcm038.c50
-rw-r--r--board/pcm038/pll_init.S48
3 files changed, 56 insertions, 44 deletions
diff --git a/board/pcm038/Makefile b/board/pcm038/Makefile
index 6082b2d657..d978c77b79 100644
--- a/board/pcm038/Makefile
+++ b/board/pcm038/Makefile
@@ -1,3 +1,3 @@
-obj-y += lowlevel_init.o
+obj-y += lowlevel_init.o pll_init.o
obj-y += pcm038.o
diff --git a/board/pcm038/pcm038.c b/board/pcm038/pcm038.c
index 56f44b51eb..326a848a95 100644
--- a/board/pcm038/pcm038.c
+++ b/board/pcm038/pcm038.c
@@ -382,18 +382,17 @@ static int pcm038_console_init(void)
console_initcall(pcm038_console_init);
-static noinline void pll_wait(void)
-{
- volatile int i;
-
- for (i = 0; i < 100000; i++);
-}
+extern void *pcm038_pll_init, *pcm038_pll_init_end;
static int pcm038_power_init(void)
{
int ret;
+ void *vram = 0xffff4c00;
+ void (*pllfunc)(void) = vram;
- printf("initialising PLLs\n");
+ printf("initialising PLLs: 0x%p 0x%p\n", &pcm038_pll_init);
+
+ memcpy(vram, &pcm038_pll_init, 0x100);
console_flush();
@@ -406,42 +405,7 @@ static int pcm038_power_init(void)
/* wait for good power level */
udelay(100000);
-#define CSCR_VAL CSCR_USB_DIV(3) | \
- CSCR_SD_CNT(3) | \
- CSCR_MSHC_SEL | \
- CSCR_H264_SEL | \
- CSCR_SSI1_SEL | \
- CSCR_SSI2_SEL | \
- CSCR_MCU_SEL | \
- CSCR_ARM_SRC_MPLL | \
- CSCR_SP_SEL | \
- CSCR_ARM_DIV(0) | \
- CSCR_FPM_EN | \
- CSCR_SPEN | \
- CSCR_MPEN
-
- /*
- * pll clock initialization - see section 3.4.3 of the i.MX27 manual
- */
- MPCTL0 = IMX_PLL_PD(0) |
- IMX_PLL_MFD(51) |
- IMX_PLL_MFI(7) |
- IMX_PLL_MFN(35); /* MPLL = 399 MHz */
-
- SPCTL0 = IMX_PLL_PD(1) |
- IMX_PLL_MFD(12) |
- IMX_PLL_MFI(9) |
- IMX_PLL_MFN(3); /* SPLL = 240 MHz */
-
- /*
- * ARM clock = (399 MHz / 2) / (ARM divider = 1) = 200 MHz
- * AHB clock = (399 MHz / 3) / (AHB divider = 2) = 66.5 MHz
- * System clock (HCLK) = 133 MHz
- */
-
- pll_wait();
- CSCR = CSCR_VAL | CSCR_AHB_DIV(1) | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART;
- pll_wait();
+ pllfunc();
/* clock gating enable */
GPCR = 0x00050f08;
diff --git a/board/pcm038/pll_init.S b/board/pcm038/pll_init.S
new file mode 100644
index 0000000000..0c1ff13415
--- /dev/null
+++ b/board/pcm038/pll_init.S
@@ -0,0 +1,48 @@
+#include <config.h>
+#include <mach/imx-regs.h>
+#include <mach/imx-pll.h>
+#include <linux/linkage.h>
+
+#define writel(val, reg) \
+ ldr r0, =reg; \
+ ldr r1, =val; \
+ str r1, [r0];
+
+#define CSCR_VAL CSCR_USB_DIV(3) | \
+ CSCR_SD_CNT(3) | \
+ CSCR_MSHC_SEL | \
+ CSCR_H264_SEL | \
+ CSCR_SSI1_SEL | \
+ CSCR_SSI2_SEL | \
+ CSCR_MCU_SEL | \
+ CSCR_ARM_SRC_MPLL | \
+ CSCR_SP_SEL | \
+ CSCR_ARM_DIV(0) | \
+ CSCR_FPM_EN | \
+ CSCR_SPEN | \
+ CSCR_MPEN | \
+ CSCR_AHB_DIV(1)
+
+ENTRY(pcm038_pll_init)
+
+ writel(IMX_PLL_PD(0) |
+ IMX_PLL_MFD(51) |
+ IMX_PLL_MFI(7) |
+ IMX_PLL_MFN(35), MPCTL0) /* 399 MHz */
+
+ writel(IMX_PLL_PD(1) |
+ IMX_PLL_MFD(12) |
+ IMX_PLL_MFI(9) |
+ IMX_PLL_MFN(3), SPCTL0) /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */
+
+ writel(CSCR_VAL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, CSCR)
+
+ ldr r2, =16000
+1:
+ subs r2, r2, #1
+ nop
+ bcs 1b
+
+ mov pc, lr
+ENDPROC(pcm038_pll_init)
+