void reset_cpu(ulong ignored)
{
-
struct mx28_rtc_regs *rtc_regs =
(struct mx28_rtc_regs *)MXS_RTC_BASE;
+ struct mx28_lcdif_regs *lcdif_regs =
+ (struct mx28_lcdif_regs *)MXS_LCDIF_BASE;
+
+ /*
+ * Shut down the LCD controller as it interferes with BootROM boot mode
+ * pads sampling.
+ */
+ writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
/* Wait 1 uS before doing the actual watchdog reset */
writel(1, &rtc_regs->hw_rtc_watchdog);
#endif
}
+#define MX28_HW_DIGCTL_MICROSECONDS (void *)0x8001c0c0
+
int mx28_wait_mask_set(struct mx28_register_32 *reg, uint32_t mask, int timeout)
{
- while (--timeout) {
- if ((readl(®->reg) & mask) == mask)
- break;
+ uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
+
+ /* Wait for at least one microsecond for the bit mask to be set */
+ while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
+ if ((readl(®->reg) & mask) == mask) {
+ while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
+ ;
+ return 0;
+ }
udelay(1);
}
int mx28_wait_mask_clr(struct mx28_register_32 *reg, uint32_t mask, int timeout)
{
- while (--timeout) {
- if ((readl(®->reg) & mask) == 0)
- break;
+ uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
+
+ /* Wait for at least one microsecond for the bit mask to be cleared */
+ while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
+ if ((readl(®->reg) & mask) == 0) {
+ while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
+ ;
+ return 0;
+ }
udelay(1);
}
/* Clear SFTRST */
writel(MX28_BLOCK_SFTRST, ®->reg_clr);
- if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
+ if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
+ printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
+ reg, readl(®->reg));
return 1;
+ }
/* Clear CLKGATE */
writel(MX28_BLOCK_CLKGATE, ®->reg_clr);
writel(MX28_BLOCK_SFTRST, ®->reg_set);
/* Wait for CLKGATE being set */
- if (mx28_wait_mask_set(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
+ if (mx28_wait_mask_set(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
+ printf("TIMEOUT waiting for CLKGATE[%p] to set: %08x\n",
+ reg, readl(®->reg));
return 1;
+ }
/* Clear SFTRST */
writel(MX28_BLOCK_SFTRST, ®->reg_clr);
- if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
+ if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
+ printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
+ reg, readl(®->reg));
return 1;
+ }
/* Clear CLKGATE */
writel(MX28_BLOCK_CLKGATE, ®->reg_clr);
- if (mx28_wait_mask_clr(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
+ if (mx28_wait_mask_clr(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
+ printf("TIMEOUT waiting for CLKGATE[%p] to clear: %08x\n",
+ reg, readl(®->reg));
return 1;
+ }
return 0;
}
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
+ struct mx28_spl_data *data = (struct mx28_spl_data *)
+ ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
+
printf("Freescale i.MX28 family at %d MHz\n",
mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("BOOT: %s\n", mx28_boot_modes[data->boot_mode_idx].mode);
return 0;
}
#endif
udelay(10);
+ /*
+ * Enable pad output; must be done BEFORE enabling PLL
+ * according to i.MX28 Ref. Manual Rev. 1, 2010 p. 883
+ */
+ setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
+
/* Gate on ENET PLL */
writel(CLKCTRL_PLL2CTRL0_CLKGATE,
&clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
- /* Enable pad output */
- setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
-
return 0;
}
#endif
int mx28_dram_init(void)
{
- struct mx28_digctl_regs *digctl_regs =
- (struct mx28_digctl_regs *)MXS_DIGCTL_BASE;
- uint32_t sz[2];
-
- sz[0] = readl(&digctl_regs->hw_digctl_scratch0);
- sz[1] = readl(&digctl_regs->hw_digctl_scratch1);
+ struct mx28_spl_data *data = (struct mx28_spl_data *)
+ ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
- if (sz[0] != sz[1]) {
+ if (data->mem_dram_size == 0) {
printf("MX28:\n"
- "Error, the RAM size in HW_DIGCTRL_SCRATCH0 and\n"
- "HW_DIGCTRL_SCRATCH1 is not the same. Please\n"
- "verify these two registers contain valid RAM size!\n");
+ "Error, the RAM size passed up from SPL is 0!\n");
hang();
}
- gd->ram_size = sz[0];
+ gd->ram_size = data->mem_dram_size;
return 0;
}