diff options
Diffstat (limited to 'arch/powerpc/boot/virtex.c')
-rw-r--r-- | arch/powerpc/boot/virtex.c | 100 |
1 files changed, 100 insertions, 0 deletions
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 @@ | |||
1 | /* | ||
2 | * The platform specific code for virtex devices since a boot loader is not | ||
3 | * always used. | ||
4 | * | ||
5 | * (C) Copyright 2008 Xilinx, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published | ||
9 | * by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include "ops.h" | ||
13 | #include "io.h" | ||
14 | #include "stdio.h" | ||
15 | |||
16 | #define UART_DLL 0 /* Out: Divisor Latch Low */ | ||
17 | #define UART_DLM 1 /* Out: Divisor Latch High */ | ||
18 | #define UART_FCR 2 /* Out: FIFO Control Register */ | ||
19 | #define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ | ||
20 | #define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ | ||
21 | #define UART_LCR 3 /* Out: Line Control Register */ | ||
22 | #define UART_MCR 4 /* Out: Modem Control Register */ | ||
23 | #define UART_MCR_RTS 0x02 /* RTS complement */ | ||
24 | #define UART_MCR_DTR 0x01 /* DTR complement */ | ||
25 | #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ | ||
26 | #define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ | ||
27 | |||
28 | static int virtex_ns16550_console_init(void *devp) | ||
29 | { | ||
30 | unsigned char *reg_base; | ||
31 | u32 reg_shift, reg_offset, clk, spd; | ||
32 | u16 divisor; | ||
33 | int n; | ||
34 | |||
35 | if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) | ||
36 | return -1; | ||
37 | |||
38 | n = getprop(devp, "reg-offset", ®_offset, sizeof(reg_offset)); | ||
39 | if (n == sizeof(reg_offset)) | ||
40 | reg_base += reg_offset; | ||
41 | |||
42 | n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); | ||
43 | if (n != sizeof(reg_shift)) | ||
44 | reg_shift = 0; | ||
45 | |||
46 | n = getprop(devp, "current-speed", (void *)&spd, sizeof(spd)); | ||
47 | if (n != sizeof(spd)) | ||
48 | spd = 9600; | ||
49 | |||
50 | /* should there be a default clock rate?*/ | ||
51 | n = getprop(devp, "clock-frequency", (void *)&clk, sizeof(clk)); | ||
52 | if (n != sizeof(clk)) | ||
53 | return -1; | ||
54 | |||
55 | divisor = clk / (16 * spd); | ||
56 | |||
57 | /* Access baud rate */ | ||
58 | out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_DLAB); | ||
59 | |||
60 | /* Baud rate based on input clock */ | ||
61 | out_8(reg_base + (UART_DLL << reg_shift), divisor & 0xFF); | ||
62 | out_8(reg_base + (UART_DLM << reg_shift), divisor >> 8); | ||
63 | |||
64 | /* 8 data, 1 stop, no parity */ | ||
65 | out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_WLEN8); | ||
66 | |||
67 | /* RTS/DTR */ | ||
68 | out_8(reg_base + (UART_MCR << reg_shift), UART_MCR_RTS | UART_MCR_DTR); | ||
69 | |||
70 | /* Clear transmitter and receiver */ | ||
71 | out_8(reg_base + (UART_FCR << reg_shift), | ||
72 | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | /* For virtex, the kernel may be loaded without using a bootloader and if so | ||
77 | some UARTs need more setup than is provided in the normal console init | ||
78 | */ | ||
79 | int platform_specific_init(void) | ||
80 | { | ||
81 | void *devp; | ||
82 | char devtype[MAX_PROP_LEN]; | ||
83 | char path[MAX_PATH_LEN]; | ||
84 | |||
85 | devp = finddevice("/chosen"); | ||
86 | if (devp == NULL) | ||
87 | return -1; | ||
88 | |||
89 | if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) { | ||
90 | devp = finddevice(path); | ||
91 | if (devp == NULL) | ||
92 | return -1; | ||
93 | |||
94 | if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0) | ||
95 | && !strcmp(devtype, "serial") | ||
96 | && (dt_is_compatible(devp, "ns16550"))) | ||
97 | virtex_ns16550_console_init(devp); | ||
98 | } | ||
99 | return 0; | ||
100 | } | ||