diff options
-rw-r--r-- | arch/powerpc/boot/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/boot/simpleboot.c | 6 | ||||
-rw-r--r-- | arch/powerpc/boot/virtex.c | 100 | ||||
-rwxr-xr-x | arch/powerpc/boot/wrapper | 6 |
4 files changed, 112 insertions, 2 deletions
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 751a6e6070d2..df6e62116e37 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -68,7 +68,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \ cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ - virtex405-head.S redboot-83xx.c cuboot-sam440ep.c + virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) diff --git a/arch/powerpc/boot/simpleboot.c b/arch/powerpc/boot/simpleboot.c index 86cd285bccc6..c58a0dada992 100644 --- a/arch/powerpc/boot/simpleboot.c +++ b/arch/powerpc/boot/simpleboot.c @@ -23,6 +23,8 @@ BSS_STACK(4*1024); +extern int platform_specific_init(void) __attribute__((weak)); + void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { @@ -80,5 +82,9 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, /* prepare the device tree and find the console */ fdt_init(_dtb_start); + + if (platform_specific_init) + platform_specific_init(); + serial_console_init(); } diff --git a/arch/powerpc/boot/virtex.c b/arch/powerpc/boot/virtex.c new file mode 100644 index 000000000000..f622805f8000 --- /dev/null +++ b/arch/powerpc/boot/virtex.c @@ -0,0 +1,100 @@ +/* + * The platform specific code for virtex devices since a boot loader is not + * always used. + * + * (C) Copyright 2008 Xilinx, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include "ops.h" +#include "io.h" +#include "stdio.h" + +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ +#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ +#define UART_LCR 3 /* Out: Line Control Register */ +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_MCR_RTS 0x02 /* RTS complement */ +#define UART_MCR_DTR 0x01 /* DTR complement */ +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ +#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ + +static int virtex_ns16550_console_init(void *devp) +{ + unsigned char *reg_base; + u32 reg_shift, reg_offset, clk, spd; + u16 divisor; + int n; + + if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) + return -1; + + n = getprop(devp, "reg-offset", ®_offset, sizeof(reg_offset)); + if (n == sizeof(reg_offset)) + reg_base += reg_offset; + + n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); + if (n != sizeof(reg_shift)) + reg_shift = 0; + + n = getprop(devp, "current-speed", (void *)&spd, sizeof(spd)); + if (n != sizeof(spd)) + spd = 9600; + + /* should there be a default clock rate?*/ + n = getprop(devp, "clock-frequency", (void *)&clk, sizeof(clk)); + if (n != sizeof(clk)) + return -1; + + divisor = clk / (16 * spd); + + /* Access baud rate */ + out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_DLAB); + + /* Baud rate based on input clock */ + out_8(reg_base + (UART_DLL << reg_shift), divisor & 0xFF); + out_8(reg_base + (UART_DLM << reg_shift), divisor >> 8); + + /* 8 data, 1 stop, no parity */ + out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_WLEN8); + + /* RTS/DTR */ + out_8(reg_base + (UART_MCR << reg_shift), UART_MCR_RTS | UART_MCR_DTR); + + /* Clear transmitter and receiver */ + out_8(reg_base + (UART_FCR << reg_shift), + UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); + return 0; +} + +/* For virtex, the kernel may be loaded without using a bootloader and if so + some UARTs need more setup than is provided in the normal console init +*/ +int platform_specific_init(void) +{ + void *devp; + char devtype[MAX_PROP_LEN]; + char path[MAX_PATH_LEN]; + + devp = finddevice("/chosen"); + if (devp == NULL) + return -1; + + if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) { + devp = finddevice(path); + if (devp == NULL) + return -1; + + if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0) + && !strcmp(devtype, "serial") + && (dt_is_compatible(devp, "ns16550"))) + virtex_ns16550_console_init(devp); + } + return 0; +} diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index df2358e9f1ca..592a6ea474f6 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -207,7 +207,11 @@ adder875-redboot) binary=y ;; simpleboot-virtex405-*) - platformo="$object/virtex405-head.o $object/simpleboot.o" + platformo="$object/virtex405-head.o $object/simpleboot.o $object/virtex.o" + binary=y + ;; +simpleboot-virtex440-*) + platformo="$object/simpleboot.o $object/virtex.o" binary=y ;; asp834x-redboot) |