Force UARTBAUD on before uncompressing. Signed-off-by: Lennert Buytenhek Index: linux-2.6.22/include/asm-arm/arch-ep93xx/uncompress.h =================================================================== --- linux-2.6.22.orig/include/asm-arm/arch-ep93xx/uncompress.h +++ linux-2.6.22/include/asm-arm/arch-ep93xx/uncompress.h @@ -77,9 +77,56 @@ static void ethernet_reset(void) } +/* + * Some bootloaders don't turn on the UARTBAUD bit, which means that + * the UARTs will be running off a divided 7.3728 MHz clock instead of + * the 14.7456 MHz peripheral clock when linux boots. + * + * We detect that condition here and fix it by turning on UARTBAUD, and + * then reprogramming the divisors on all enabled UARTs to twice what + * they were before we turned UARTBAUD on, to preserve the programmed + * baud rate. + */ +#define PHYS_SYSCON_CLOCK_CONTROL 0x80930004 +#define SYSCON_CLOCK_UARTBAUD 0x20000000 +#define PHYS_UART1_BASE 0x808c0000 +#define PHYS_UART2_BASE 0x808d0000 +#define PHYS_UART3_BASE 0x808e0000 + +static void uart_divisor_times_two(unsigned int base) +{ + u16 divisor; + + divisor = __raw_readb(base + 0x0c) << 8; + divisor |= __raw_readb(base + 0x10); + if (divisor) { + divisor = (2 * (divisor + 1)) - 1; + __raw_writeb(divisor >> 8, base + 0x0c); + __raw_writeb(divisor & 0xff, base + 0x10); + __raw_writeb(__raw_readb(base + 0x08), base + 0x08); + } +} + +static void fix_uart_base(void) +{ + unsigned int v; + + v = __raw_readl(PHYS_SYSCON_CLOCK_CONTROL); + if ((v & SYSCON_CLOCK_UARTBAUD) == 0) { + v |= SYSCON_CLOCK_UARTBAUD; + __raw_writel(v, PHYS_SYSCON_CLOCK_CONTROL); + + uart_divisor_times_two(PHYS_UART1_BASE); + uart_divisor_times_two(PHYS_UART2_BASE); + uart_divisor_times_two(PHYS_UART3_BASE); + } +} + + static void arch_decomp_setup(void) { ethernet_reset(); + fix_uart_base(); } #define arch_decomp_wdog()