summaryrefslogtreecommitdiffstats
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/edb93xx/sdram_cfg.c21
-rw-r--r--board/pcm038/Makefile2
-rw-r--r--board/pcm038/pcm038.c50
-rw-r--r--board/pcm038/pll_init.S48
4 files changed, 71 insertions, 50 deletions
diff --git a/board/edb93xx/sdram_cfg.c b/board/edb93xx/sdram_cfg.c
index 25b214be4b..3d4fe08e19 100644
--- a/board/edb93xx/sdram_cfg.c
+++ b/board/edb93xx/sdram_cfg.c
@@ -31,9 +31,9 @@
(SDRAM_BASE_ADDR | SDRAM_BANK_SEL_##bank | SDRAM_MODE_REG_VAL))
#define PRECHARGE_BANK(bank) (*(volatile uint32_t *) \
- (SDRAM_BASE_ADDR | SDRAM_BANK_SEL_##bank))
+ (SDRAM_BASE_ADDR | SDRAM_BANK_SEL_##bank)) = 0
-static void force_precharge(void);
+static void precharge_all_banks(void);
static void setup_refresh_timer(void);
static void program_mode_registers(void);
@@ -48,7 +48,7 @@ void sdram_cfg(void)
early_udelay(200);
- force_precharge();
+ precharge_all_banks();
setup_refresh_timer();
@@ -58,13 +58,22 @@ void sdram_cfg(void)
writel(GLCONFIG_CKE, &sdram->glconfig);
}
-static void force_precharge(void)
+static void precharge_all_banks(void)
{
+ struct sdram_regs *sdram = (struct sdram_regs *)SDRAM_BASE;
+
+ /* Issue PRECHARGE ALL commands */
+ writel(GLCONFIG_INIT | GLCONFIG_CKE, &sdram->glconfig);
+
/*
- * Errata most EP93xx revisions say that PRECHARGE ALL isn't always
+ * Errata of most EP93xx revisions say that PRECHARGE ALL isn't always
* issued.
*
- * Do a read from each bank to make sure they're precharged
+ * Cirrus proposes a workaround which consists in performing a read from
+ * each bank to force the precharge. This causes some boards to hang.
+ * Writing to the SDRAM banks instead of reading has the same
+ * side-effect (the SDRAM controller issues the necessary precharges),
+ * but is known to work on all supported boards
*/
PRECHARGE_BANK(0);
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 313b7df77b..3c17036cb0 100644
--- a/board/pcm038/pcm038.c
+++ b/board/pcm038/pcm038.c
@@ -381,18 +381,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();
@@ -405,42 +404,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)
+