]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/arm/cpu/arm926ejs/mx28/mx28.c
Merge branch 'master' of git://git.denx.de/u-boot-microblaze
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / mx28 / mx28.c
index 088c019b7bc8a8036789f46ed27f1a0149562cc3..ff25772099b5bccbebaa63cc6189d1d3494c3ee9 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/dma.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/iomux.h>
 #include <asm/arch/imx-regs.h>
@@ -50,9 +51,16 @@ void reset_cpu(ulong ignored) __attribute__((noreturn));
 
 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);
@@ -63,7 +71,17 @@ void reset_cpu(ulong ignored)
                ;
 }
 
-int mx28_wait_mask_set(struct mx28_register *reg, uint32_t mask, int timeout)
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+       icache_enable();
+#endif
+#ifndef CONFIG_SYS_DCACHE_OFF
+       dcache_enable();
+#endif
+}
+
+int mx28_wait_mask_set(struct mx28_register_32 *reg, uint32_t mask, int timeout)
 {
        while (--timeout) {
                if ((readl(&reg->reg) & mask) == mask)
@@ -74,7 +92,7 @@ int mx28_wait_mask_set(struct mx28_register *reg, uint32_t mask, int timeout)
        return !timeout;
 }
 
-int mx28_wait_mask_clr(struct mx28_register *reg, uint32_t mask, int timeout)
+int mx28_wait_mask_clr(struct mx28_register_32 *reg, uint32_t mask, int timeout)
 {
        while (--timeout) {
                if ((readl(&reg->reg) & mask) == 0)
@@ -85,7 +103,7 @@ int mx28_wait_mask_clr(struct mx28_register *reg, uint32_t mask, int timeout)
        return !timeout;
 }
 
-int mx28_reset_block(struct mx28_register *reg)
+int mx28_reset_block(struct mx28_register_32 *reg)
 {
        /* Clear SFTRST */
        writel(MX28_BLOCK_SFTRST, &reg->reg_clr);
@@ -135,7 +153,6 @@ int arch_misc_init(void)
 }
 #endif
 
-#ifdef CONFIG_ARCH_CPU_INIT
 int arch_cpu_init(void)
 {
        struct mx28_clkctrl_regs *clkctrl_regs =
@@ -162,14 +179,23 @@ int arch_cpu_init(void)
         */
        mxs_gpio_init();
 
+#ifdef CONFIG_APBH_DMA
+       /* Start APBH DMA */
+       mxs_dma_init();
+#endif
+
        return 0;
 }
-#endif
 
 #if defined(CONFIG_DISPLAY_CPUINFO)
 int print_cpuinfo(void)
 {
-       printf("Freescale i.MX28 family\n");
+       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
@@ -214,6 +240,67 @@ int cpu_eth_init(bd_t *bis)
 }
 #endif
 
+static void __mx28_adjust_mac(int dev_id, unsigned char *mac)
+{
+       mac[0] = 0x00;
+       mac[1] = 0x04; /* Use FSL vendor MAC address by default */
+
+       if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */
+               mac[5] += 1;
+}
+
+void mx28_adjust_mac(int dev_id, unsigned char *mac)
+       __attribute__((weak, alias("__mx28_adjust_mac")));
+
+#ifdef CONFIG_MX28_FEC_MAC_IN_OCOTP
+
+#define        MXS_OCOTP_MAX_TIMEOUT   1000000
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+       struct mx28_ocotp_regs *ocotp_regs =
+               (struct mx28_ocotp_regs *)MXS_OCOTP_BASE;
+       uint32_t data;
+
+       memset(mac, 0, 6);
+
+       writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set);
+
+       if (mx28_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY,
+                               MXS_OCOTP_MAX_TIMEOUT)) {
+               printf("MXS FEC: Can't get MAC from OCOTP\n");
+               return;
+       }
+
+       data = readl(&ocotp_regs->hw_ocotp_cust0);
+
+       mac[2] = (data >> 24) & 0xff;
+       mac[3] = (data >> 16) & 0xff;
+       mac[4] = (data >> 8) & 0xff;
+       mac[5] = data & 0xff;
+       mx28_adjust_mac(dev_id, mac);
+}
+#else
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+       memset(mac, 0, 6);
+}
+#endif
+
+int mx28_dram_init(void)
+{
+       struct mx28_spl_data *data = (struct mx28_spl_data *)
+               ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
+
+       if (data->mem_dram_size == 0) {
+               printf("MX28:\n"
+                       "Error, the RAM size passed up from SPL is 0!\n");
+               hang();
+       }
+
+       gd->ram_size = data->mem_dram_size;
+       return 0;
+}
+
 U_BOOT_CMD(
        clocks, CONFIG_SYS_MAXARGS, 1, do_mx28_showclocks,
        "display clocks",