blackfin: Correct early serial mess output in BYPASS boot mode.
authorSonic Zhang <sonic.zhang@analog.com>
Fri, 30 Nov 2012 09:39:32 +0000 (17:39 +0800)
committerSonic Zhang <sonic.zhang@analog.com>
Mon, 13 May 2013 07:47:24 +0000 (15:47 +0800)
The early serial should not be configured again in initcode() for BYPASS
boot mode and in start() for the other LDR boot modes.

In BYPASS boot mode, the start up code is located in Nor flash address other
than the DRAM address defined in link script. The code embedded string can't
be addressed by its compile time symbol. Calculate it according to the flash
offset.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
arch/blackfin/cpu/initcode.c
arch/blackfin/cpu/serial.h
arch/blackfin/cpu/serial1.h
arch/blackfin/include/asm/clock.h

index 5c12726d779a4d1b9b7955efb5087898534807cb..4b10b6c6b2f971ac1c4e1458c25bacbdba78cc88 100644 (file)
@@ -193,10 +193,12 @@ static inline void serial_init(void)
        }
 #endif
 
+#if CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS
        if (BFIN_DEBUG_EARLY_SERIAL) {
                serial_early_init(uart_base);
                serial_early_set_baud(uart_base, CONFIG_BAUDRATE);
        }
+#endif
 }
 
 __attribute__((always_inline))
index 9200339668369609661a25e32862e5da88796240..d67fd81c0964c5dbf087915d6490119a78f8b190 100644 (file)
@@ -78,19 +78,31 @@ static inline void serial_early_puts(const char *s)
 #else
 
 .macro serial_early_init
-#ifdef CONFIG_DEBUG_EARLY_SERIAL
+#if defined(CONFIG_DEBUG_EARLY_SERIAL) && defined(BFIN_BOOT_BYPASS)
        call _serial_initialize;
 #endif
 .endm
 
 .macro serial_early_set_baud
-#ifdef CONFIG_DEBUG_EARLY_SERIAL
+#if defined(CONFIG_DEBUG_EARLY_SERIAL) && defined(BFIN_BOOT_BYPASS)
        R0.L = LO(CONFIG_BAUDRATE);
        R0.H = HI(CONFIG_BAUDRATE);
        call _serial_set_baud;
 #endif
 .endm
 
+#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS
+#define update_serial_early_string_addr \
+       R1.L = _start; \
+       R1.H = _start; \
+       R0 = R0 - R1; \
+       R1.L = 0; \
+       R1.H = 0x2000; \
+       R0 = R0 + R1;
+#else
+#define update_serial_early_string_addr
+#endif
+
 /* Since we embed the string right into our .text section, we need
  * to find its address.  We do this by getting our PC and adding 2
  * bytes (which is the length of the jump instruction).  Then we
@@ -108,6 +120,7 @@ static inline void serial_early_puts(const char *s)
        .previous; \
        R0.L = 7b; \
        R0.H = 7b; \
+       update_serial_early_string_addr \
        call _serial_puts;
 #else
 # define serial_early_puts(str)
index 52f1c62eb95a9a5e59fb626927c0ae56c9269b66..467d3817f169bdecf7ccb37e10a4634b014b7d11 100644 (file)
@@ -287,8 +287,13 @@ static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud)
         * weird multiplication is to make sure we over sample just
         * a little rather than under sample the incoming signals.
         */
+#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS
+       uint16_t divisor = (early_get_uart_clk() + baud * 8) / (baud * 16)
+                       - ANOMALY_05000230;
+#else
        uint16_t divisor = early_division(early_get_uart_clk() + (baud * 8),
                        baud * 16) - ANOMALY_05000230;
+#endif
 
        serial_set_divisor(uart_base, divisor);
 }
index df6cd68171ba75e10d6ef0d1f41d238459c72596..f1fcd404993de3c70bef6d188a3fb91fc4909d73 100644 (file)
@@ -10,7 +10,7 @@
 #include <asm/blackfin.h>
 #ifdef PLL_CTL
 #include <asm/mach-common/bits/pll.h>
-# define pll_is_bypassed() (bfin_read_PLL_STAT() & DF)
+# define pll_is_bypassed() (bfin_read_PLL_CTL() & BYPASS)
 #else
 #include <asm/mach-common/bits/cgu.h>
 # define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP)
@@ -55,7 +55,11 @@ static inline uint32_t early_get_uart_clk(void)
        if (!pll_is_bypassed()) {
                div = bfin_read_PLL_DIV();
                ssel = (div & SSEL) >> SSEL_P;
+#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS
+               sclk = vco/ssel;
+#else
                sclk = early_division(vco, ssel);
+#endif
        }
        uclk = sclk;
 #ifdef CGU_DIV