diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2010-02-04 10:12:32 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-03-03 08:41:07 +0100 |
commit | 3b9f0a68693478136efdff0db0e4bb4e16d75031 (patch) | |
tree | 44b14951d985279393b27d7a59e7ae40d5fa1aa1 /board | |
parent | 53eaaf0f823066da80b8bdfb7a1a3628ae6efc77 (diff) | |
download | barebox-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/Makefile | 2 | ||||
-rw-r--r-- | board/pcm038/pcm038.c | 50 | ||||
-rw-r--r-- | board/pcm038/pll_init.S | 48 |
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) + |