]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - cpu/blackfin/initcode.c
Blackfin: recurse with early serial initcode
[karo-tx-uboot.git] / cpu / blackfin / initcode.c
index 7bd4b227e6d3b71c07a5338e80ba2d77fad4b103..c0fe2c65a6c6232398ea0ce328c85d4ce2fcd7e8 100644 (file)
@@ -92,7 +92,7 @@ static inline void serial_putc(char c)
                return;
 
        if (c == '\n')
-               *pUART_THR = '\r';
+               serial_putc('\r');
 
        *pUART_THR = c;
 
@@ -246,9 +246,20 @@ static inline void serial_putc(char c)
 #endif
 #endif
 
+/* Conflicting Column Address Widths Causes SDRAM Errors:
+ * EB2CAW and EB3CAW must be the same
+ */
+#if ANOMALY_05000362
+# if ((CONFIG_EBIU_SDBCTL_VAL & 0x30000000) >> 8) != (CONFIG_EBIU_SDBCTL_VAL & 0x00300000)
+#  error "Anomaly 05000362: EB2CAW and EB3CAW must be the same"
+# endif
+#endif
+
 BOOTROM_CALLED_FUNC_ATTR
 void initcode(ADI_BOOT_DATA *bootstruct)
 {
+       ADI_BOOT_DATA bootstruct_scratch;
+
        /* Save the clock pieces that are used in baud rate calculation */
        unsigned int sdivB, divB, vcoB;
        serial_init();
@@ -260,6 +271,13 @@ void initcode(ADI_BOOT_DATA *bootstruct)
 
        serial_putc('A');
 
+       /* If the bootstruct is NULL, then it's because we're loading
+        * dynamically and not via LDR (bootrom).  So set the struct to
+        * some scratch space.
+        */
+       if (!bootstruct)
+               bootstruct = &bootstruct_scratch;
+
 #ifdef CONFIG_HW_WATCHDOG
 # ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE
 #  define CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE 20000
@@ -326,6 +344,7 @@ void initcode(ADI_BOOT_DATA *bootstruct)
        if (!ANOMALY_05000386) {
                serial_putc('F');
 
+               /* Always programming PLL_LOCKCNT avoids Anomaly 05000430 */
                ADI_SYSCTRL_VALUES memory_settings;
                uint32_t actions = SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV | SYSCTRL_LOCKCNT;
                if (CONFIG_HAS_VR) {
@@ -346,6 +365,10 @@ void initcode(ADI_BOOT_DATA *bootstruct)
                bfrom_SysControl(actions, &memory_settings, NULL);
 #if ANOMALY_05000432
                bfin_write_SIC_IWR1(-1);
+#endif
+#if ANOMALY_05000171
+               bfin_write_SICA_IWR0(-1);
+               bfin_write_SICA_IWR1(-1);
 #endif
        } else {
                serial_putc('G');
@@ -366,6 +389,7 @@ void initcode(ADI_BOOT_DATA *bootstruct)
 
                serial_putc('H');
 
+               /* Always programming PLL_LOCKCNT avoids Anomaly 05000430 */
                bfin_write_PLL_LOCKCNT(CONFIG_PLL_LOCKCNT_VAL);
 
                serial_putc('I');
@@ -388,7 +412,7 @@ void initcode(ADI_BOOT_DATA *bootstruct)
                /* Only reprogram when needed to avoid triggering unnecessary
                 * PLL relock sequences.
                 */
-               if (bfin_read_PLL_CTL() != CONFIG_PLL_CTL_VAL) {
+               if (ANOMALY_05000242 || bfin_read_PLL_CTL() != CONFIG_PLL_CTL_VAL) {
                        serial_putc('!');
                        bfin_write_PLL_CTL(CONFIG_PLL_CTL_VAL);
                        asm("idle;");