diff --git a/board/pcm038/Makefile b/board/pcm038/Makefile index 6082b2d..d978c77 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 56f44b5..326a848 100644 --- a/board/pcm038/pcm038.c +++ b/board/pcm038/pcm038.c @@ -382,18 +382,17 @@ 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 @@ /* 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 0000000..0c1ff13 --- /dev/null +++ b/board/pcm038/pll_init.S @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +#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) +