Commit b187f180cc942e50007aa039f8e3a620ee5f3171
Committed by
Linus Torvalds
1 parent
04e08d0e9b
serial: add early_serial_setup() back to header file
early_serial_setup was removed from serial.h, but forgot to put in serial_8250.h Signed-off-by: Yinghai Lu <yinghai.lu@sun.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 24 changed files with 25 additions and 0 deletions Inline Diff
- arch/frv/kernel/setup.c
- arch/mips/basler/excite/excite_setup.c
- arch/mips/gt64120/wrppmc/setup.c
- arch/mips/mips-boards/atlas/atlas_setup.c
- arch/mips/mips-boards/sead/sead_setup.c
- arch/mips/mipssim/sim_setup.c
- arch/mips/pmc-sierra/msp71xx/msp_serial.c
- arch/mips/pmc-sierra/yosemite/setup.c
- arch/ppc/platforms/4xx/bamboo.c
- arch/ppc/platforms/4xx/bubinga.c
- arch/ppc/platforms/4xx/cpci405.c
- arch/ppc/platforms/4xx/ebony.c
- arch/ppc/platforms/4xx/luan.c
- arch/ppc/platforms/4xx/ocotea.c
- arch/ppc/platforms/4xx/taishan.c
- arch/ppc/platforms/4xx/yucca.c
- arch/ppc/platforms/85xx/sbc8560.c
- arch/ppc/platforms/chestnut.c
- arch/ppc/platforms/ev64260.c
- arch/ppc/platforms/radstone_ppc7d.c
- arch/ppc/platforms/spruce.c
- drivers/parisc/superio.c
- drivers/serial/8250_hp300.c
- include/linux/serial_8250.h
arch/frv/kernel/setup.c
1 | /* setup.c: FRV specific setup | 1 | /* setup.c: FRV specific setup |
2 | * | 2 | * |
3 | * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.com) |
5 | * - Derived from arch/m68k/kernel/setup.c | 5 | * - Derived from arch/m68k/kernel/setup.c |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/utsrelease.h> | 13 | #include <linux/utsrelease.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/fb.h> | 20 | #include <linux/fb.h> |
21 | #include <linux/console.h> | 21 | #include <linux/console.h> |
22 | #include <linux/genhd.h> | 22 | #include <linux/genhd.h> |
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/major.h> | 25 | #include <linux/major.h> |
26 | #include <linux/bootmem.h> | 26 | #include <linux/bootmem.h> |
27 | #include <linux/highmem.h> | 27 | #include <linux/highmem.h> |
28 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
29 | #include <linux/serial.h> | 29 | #include <linux/serial.h> |
30 | #include <linux/serial_core.h> | 30 | #include <linux/serial_core.h> |
31 | #include <linux/serial_reg.h> | 31 | #include <linux/serial_reg.h> |
32 | #include <linux/serial_8250.h> | ||
32 | 33 | ||
33 | #include <asm/setup.h> | 34 | #include <asm/setup.h> |
34 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
35 | #include <asm/sections.h> | 36 | #include <asm/sections.h> |
36 | #include <asm/pgalloc.h> | 37 | #include <asm/pgalloc.h> |
37 | #include <asm/busctl-regs.h> | 38 | #include <asm/busctl-regs.h> |
38 | #include <asm/serial-regs.h> | 39 | #include <asm/serial-regs.h> |
39 | #include <asm/timer-regs.h> | 40 | #include <asm/timer-regs.h> |
40 | #include <asm/irc-regs.h> | 41 | #include <asm/irc-regs.h> |
41 | #include <asm/spr-regs.h> | 42 | #include <asm/spr-regs.h> |
42 | #include <asm/mb-regs.h> | 43 | #include <asm/mb-regs.h> |
43 | #include <asm/mb93493-regs.h> | 44 | #include <asm/mb93493-regs.h> |
44 | #include <asm/gdb-stub.h> | 45 | #include <asm/gdb-stub.h> |
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
46 | 47 | ||
47 | #ifdef CONFIG_BLK_DEV_INITRD | 48 | #ifdef CONFIG_BLK_DEV_INITRD |
48 | #include <linux/blk.h> | 49 | #include <linux/blk.h> |
49 | #include <asm/pgtable.h> | 50 | #include <asm/pgtable.h> |
50 | #endif | 51 | #endif |
51 | 52 | ||
52 | #include "local.h" | 53 | #include "local.h" |
53 | 54 | ||
54 | #ifdef CONFIG_MB93090_MB00 | 55 | #ifdef CONFIG_MB93090_MB00 |
55 | static void __init mb93090_display(void); | 56 | static void __init mb93090_display(void); |
56 | #endif | 57 | #endif |
57 | #ifdef CONFIG_MMU | 58 | #ifdef CONFIG_MMU |
58 | static void __init setup_linux_memory(void); | 59 | static void __init setup_linux_memory(void); |
59 | #else | 60 | #else |
60 | static void __init setup_uclinux_memory(void); | 61 | static void __init setup_uclinux_memory(void); |
61 | #endif | 62 | #endif |
62 | 63 | ||
63 | #ifdef CONFIG_MB93090_MB00 | 64 | #ifdef CONFIG_MB93090_MB00 |
64 | static char __initdata mb93090_banner[] = "FJ/RH FR-V Linux"; | 65 | static char __initdata mb93090_banner[] = "FJ/RH FR-V Linux"; |
65 | static char __initdata mb93090_version[] = UTS_RELEASE; | 66 | static char __initdata mb93090_version[] = UTS_RELEASE; |
66 | 67 | ||
67 | int __nongprelbss mb93090_mb00_detected; | 68 | int __nongprelbss mb93090_mb00_detected; |
68 | #endif | 69 | #endif |
69 | 70 | ||
70 | const char __frv_unknown_system[] = "unknown"; | 71 | const char __frv_unknown_system[] = "unknown"; |
71 | const char __frv_mb93091_cb10[] = "mb93091-cb10"; | 72 | const char __frv_mb93091_cb10[] = "mb93091-cb10"; |
72 | const char __frv_mb93091_cb11[] = "mb93091-cb11"; | 73 | const char __frv_mb93091_cb11[] = "mb93091-cb11"; |
73 | const char __frv_mb93091_cb30[] = "mb93091-cb30"; | 74 | const char __frv_mb93091_cb30[] = "mb93091-cb30"; |
74 | const char __frv_mb93091_cb41[] = "mb93091-cb41"; | 75 | const char __frv_mb93091_cb41[] = "mb93091-cb41"; |
75 | const char __frv_mb93091_cb60[] = "mb93091-cb60"; | 76 | const char __frv_mb93091_cb60[] = "mb93091-cb60"; |
76 | const char __frv_mb93091_cb70[] = "mb93091-cb70"; | 77 | const char __frv_mb93091_cb70[] = "mb93091-cb70"; |
77 | const char __frv_mb93091_cb451[] = "mb93091-cb451"; | 78 | const char __frv_mb93091_cb451[] = "mb93091-cb451"; |
78 | const char __frv_mb93090_mb00[] = "mb93090-mb00"; | 79 | const char __frv_mb93090_mb00[] = "mb93090-mb00"; |
79 | 80 | ||
80 | const char __frv_mb93493[] = "mb93493"; | 81 | const char __frv_mb93493[] = "mb93493"; |
81 | 82 | ||
82 | const char __frv_mb93093[] = "mb93093"; | 83 | const char __frv_mb93093[] = "mb93093"; |
83 | 84 | ||
84 | static const char *__nongprelbss cpu_series; | 85 | static const char *__nongprelbss cpu_series; |
85 | static const char *__nongprelbss cpu_core; | 86 | static const char *__nongprelbss cpu_core; |
86 | static const char *__nongprelbss cpu_silicon; | 87 | static const char *__nongprelbss cpu_silicon; |
87 | static const char *__nongprelbss cpu_mmu; | 88 | static const char *__nongprelbss cpu_mmu; |
88 | static const char *__nongprelbss cpu_system; | 89 | static const char *__nongprelbss cpu_system; |
89 | static const char *__nongprelbss cpu_board1; | 90 | static const char *__nongprelbss cpu_board1; |
90 | static const char *__nongprelbss cpu_board2; | 91 | static const char *__nongprelbss cpu_board2; |
91 | 92 | ||
92 | static unsigned long __nongprelbss cpu_psr_all; | 93 | static unsigned long __nongprelbss cpu_psr_all; |
93 | static unsigned long __nongprelbss cpu_hsr0_all; | 94 | static unsigned long __nongprelbss cpu_hsr0_all; |
94 | 95 | ||
95 | unsigned long __nongprelbss pdm_suspend_mode; | 96 | unsigned long __nongprelbss pdm_suspend_mode; |
96 | 97 | ||
97 | unsigned long __nongprelbss rom_length; | 98 | unsigned long __nongprelbss rom_length; |
98 | unsigned long __nongprelbss memory_start; | 99 | unsigned long __nongprelbss memory_start; |
99 | unsigned long __nongprelbss memory_end; | 100 | unsigned long __nongprelbss memory_end; |
100 | 101 | ||
101 | unsigned long __nongprelbss dma_coherent_mem_start; | 102 | unsigned long __nongprelbss dma_coherent_mem_start; |
102 | unsigned long __nongprelbss dma_coherent_mem_end; | 103 | unsigned long __nongprelbss dma_coherent_mem_end; |
103 | 104 | ||
104 | unsigned long __initdata __sdram_old_base; | 105 | unsigned long __initdata __sdram_old_base; |
105 | unsigned long __initdata num_mappedpages; | 106 | unsigned long __initdata num_mappedpages; |
106 | 107 | ||
107 | struct cpuinfo_frv __nongprelbss boot_cpu_data; | 108 | struct cpuinfo_frv __nongprelbss boot_cpu_data; |
108 | 109 | ||
109 | char __initdata command_line[COMMAND_LINE_SIZE]; | 110 | char __initdata command_line[COMMAND_LINE_SIZE]; |
110 | char __initdata redboot_command_line[COMMAND_LINE_SIZE]; | 111 | char __initdata redboot_command_line[COMMAND_LINE_SIZE]; |
111 | 112 | ||
112 | #ifdef CONFIG_PM | 113 | #ifdef CONFIG_PM |
113 | #define __pminit | 114 | #define __pminit |
114 | #define __pminitdata | 115 | #define __pminitdata |
115 | #else | 116 | #else |
116 | #define __pminit __init | 117 | #define __pminit __init |
117 | #define __pminitdata __initdata | 118 | #define __pminitdata __initdata |
118 | #endif | 119 | #endif |
119 | 120 | ||
120 | struct clock_cmode { | 121 | struct clock_cmode { |
121 | uint8_t xbus, sdram, corebus, core, dsu; | 122 | uint8_t xbus, sdram, corebus, core, dsu; |
122 | }; | 123 | }; |
123 | 124 | ||
124 | #define _frac(N,D) ((N)<<4 | (D)) | 125 | #define _frac(N,D) ((N)<<4 | (D)) |
125 | #define _x0_16 _frac(1,6) | 126 | #define _x0_16 _frac(1,6) |
126 | #define _x0_25 _frac(1,4) | 127 | #define _x0_25 _frac(1,4) |
127 | #define _x0_33 _frac(1,3) | 128 | #define _x0_33 _frac(1,3) |
128 | #define _x0_375 _frac(3,8) | 129 | #define _x0_375 _frac(3,8) |
129 | #define _x0_5 _frac(1,2) | 130 | #define _x0_5 _frac(1,2) |
130 | #define _x0_66 _frac(2,3) | 131 | #define _x0_66 _frac(2,3) |
131 | #define _x0_75 _frac(3,4) | 132 | #define _x0_75 _frac(3,4) |
132 | #define _x1 _frac(1,1) | 133 | #define _x1 _frac(1,1) |
133 | #define _x1_5 _frac(3,2) | 134 | #define _x1_5 _frac(3,2) |
134 | #define _x2 _frac(2,1) | 135 | #define _x2 _frac(2,1) |
135 | #define _x3 _frac(3,1) | 136 | #define _x3 _frac(3,1) |
136 | #define _x4 _frac(4,1) | 137 | #define _x4 _frac(4,1) |
137 | #define _x4_5 _frac(9,2) | 138 | #define _x4_5 _frac(9,2) |
138 | #define _x6 _frac(6,1) | 139 | #define _x6 _frac(6,1) |
139 | #define _x8 _frac(8,1) | 140 | #define _x8 _frac(8,1) |
140 | #define _x9 _frac(9,1) | 141 | #define _x9 _frac(9,1) |
141 | 142 | ||
142 | int __nongprelbss clock_p0_current; | 143 | int __nongprelbss clock_p0_current; |
143 | int __nongprelbss clock_cm_current; | 144 | int __nongprelbss clock_cm_current; |
144 | int __nongprelbss clock_cmode_current; | 145 | int __nongprelbss clock_cmode_current; |
145 | #ifdef CONFIG_PM | 146 | #ifdef CONFIG_PM |
146 | int __nongprelbss clock_cmodes_permitted; | 147 | int __nongprelbss clock_cmodes_permitted; |
147 | unsigned long __nongprelbss clock_bits_settable; | 148 | unsigned long __nongprelbss clock_bits_settable; |
148 | #endif | 149 | #endif |
149 | 150 | ||
150 | static struct clock_cmode __pminitdata undef_clock_cmode = { _x1, _x1, _x1, _x1, _x1 }; | 151 | static struct clock_cmode __pminitdata undef_clock_cmode = { _x1, _x1, _x1, _x1, _x1 }; |
151 | 152 | ||
152 | static struct clock_cmode __pminitdata clock_cmodes_fr401_fr403[16] = { | 153 | static struct clock_cmode __pminitdata clock_cmodes_fr401_fr403[16] = { |
153 | [4] = { _x1, _x1, _x2, _x2, _x0_25 }, | 154 | [4] = { _x1, _x1, _x2, _x2, _x0_25 }, |
154 | [5] = { _x1, _x2, _x4, _x4, _x0_5 }, | 155 | [5] = { _x1, _x2, _x4, _x4, _x0_5 }, |
155 | [8] = { _x1, _x1, _x1, _x2, _x0_25 }, | 156 | [8] = { _x1, _x1, _x1, _x2, _x0_25 }, |
156 | [9] = { _x1, _x2, _x2, _x4, _x0_5 }, | 157 | [9] = { _x1, _x2, _x2, _x4, _x0_5 }, |
157 | [11] = { _x1, _x4, _x4, _x8, _x1 }, | 158 | [11] = { _x1, _x4, _x4, _x8, _x1 }, |
158 | [12] = { _x1, _x1, _x2, _x4, _x0_5 }, | 159 | [12] = { _x1, _x1, _x2, _x4, _x0_5 }, |
159 | [13] = { _x1, _x2, _x4, _x8, _x1 }, | 160 | [13] = { _x1, _x2, _x4, _x8, _x1 }, |
160 | }; | 161 | }; |
161 | 162 | ||
162 | static struct clock_cmode __pminitdata clock_cmodes_fr405[16] = { | 163 | static struct clock_cmode __pminitdata clock_cmodes_fr405[16] = { |
163 | [0] = { _x1, _x1, _x1, _x1, _x0_5 }, | 164 | [0] = { _x1, _x1, _x1, _x1, _x0_5 }, |
164 | [1] = { _x1, _x1, _x1, _x3, _x0_25 }, | 165 | [1] = { _x1, _x1, _x1, _x3, _x0_25 }, |
165 | [2] = { _x1, _x1, _x2, _x6, _x0_5 }, | 166 | [2] = { _x1, _x1, _x2, _x6, _x0_5 }, |
166 | [3] = { _x1, _x2, _x2, _x6, _x0_5 }, | 167 | [3] = { _x1, _x2, _x2, _x6, _x0_5 }, |
167 | [4] = { _x1, _x1, _x2, _x2, _x0_16 }, | 168 | [4] = { _x1, _x1, _x2, _x2, _x0_16 }, |
168 | [8] = { _x1, _x1, _x1, _x2, _x0_16 }, | 169 | [8] = { _x1, _x1, _x1, _x2, _x0_16 }, |
169 | [9] = { _x1, _x2, _x2, _x4, _x0_33 }, | 170 | [9] = { _x1, _x2, _x2, _x4, _x0_33 }, |
170 | [12] = { _x1, _x1, _x2, _x4, _x0_33 }, | 171 | [12] = { _x1, _x1, _x2, _x4, _x0_33 }, |
171 | [14] = { _x1, _x3, _x3, _x9, _x0_75 }, | 172 | [14] = { _x1, _x3, _x3, _x9, _x0_75 }, |
172 | [15] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, | 173 | [15] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, |
173 | 174 | ||
174 | #define CLOCK_CMODES_PERMITTED_FR405 0xd31f | 175 | #define CLOCK_CMODES_PERMITTED_FR405 0xd31f |
175 | }; | 176 | }; |
176 | 177 | ||
177 | static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = { | 178 | static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = { |
178 | [0] = { _x1, _x2, _x2, _x4, _x0_33 }, | 179 | [0] = { _x1, _x2, _x2, _x4, _x0_33 }, |
179 | [1] = { _x1, _x3, _x3, _x6, _x0_5 }, | 180 | [1] = { _x1, _x3, _x3, _x6, _x0_5 }, |
180 | [2] = { _x1, _x2, _x4, _x8, _x0_66 }, | 181 | [2] = { _x1, _x2, _x4, _x8, _x0_66 }, |
181 | [3] = { _x1, _x1_5, _x3, _x6, _x0_5 }, | 182 | [3] = { _x1, _x1_5, _x3, _x6, _x0_5 }, |
182 | [4] = { _x1, _x3, _x3, _x9, _x0_75 }, | 183 | [4] = { _x1, _x3, _x3, _x9, _x0_75 }, |
183 | [5] = { _x1, _x2, _x2, _x6, _x0_5 }, | 184 | [5] = { _x1, _x2, _x2, _x6, _x0_5 }, |
184 | [6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, | 185 | [6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, |
185 | }; | 186 | }; |
186 | 187 | ||
187 | static const struct clock_cmode __pminitdata *clock_cmodes; | 188 | static const struct clock_cmode __pminitdata *clock_cmodes; |
188 | static int __pminitdata clock_doubled; | 189 | static int __pminitdata clock_doubled; |
189 | 190 | ||
190 | static struct uart_port __pminitdata __frv_uart0 = { | 191 | static struct uart_port __pminitdata __frv_uart0 = { |
191 | .uartclk = 0, | 192 | .uartclk = 0, |
192 | .membase = (char *) UART0_BASE, | 193 | .membase = (char *) UART0_BASE, |
193 | .irq = IRQ_CPU_UART0, | 194 | .irq = IRQ_CPU_UART0, |
194 | .regshift = 3, | 195 | .regshift = 3, |
195 | .iotype = UPIO_MEM, | 196 | .iotype = UPIO_MEM, |
196 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | 197 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
197 | }; | 198 | }; |
198 | 199 | ||
199 | static struct uart_port __pminitdata __frv_uart1 = { | 200 | static struct uart_port __pminitdata __frv_uart1 = { |
200 | .uartclk = 0, | 201 | .uartclk = 0, |
201 | .membase = (char *) UART1_BASE, | 202 | .membase = (char *) UART1_BASE, |
202 | .irq = IRQ_CPU_UART1, | 203 | .irq = IRQ_CPU_UART1, |
203 | .regshift = 3, | 204 | .regshift = 3, |
204 | .iotype = UPIO_MEM, | 205 | .iotype = UPIO_MEM, |
205 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | 206 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
206 | }; | 207 | }; |
207 | 208 | ||
208 | #if 0 | 209 | #if 0 |
209 | static void __init printk_xampr(unsigned long ampr, unsigned long amlr, char i_d, int n) | 210 | static void __init printk_xampr(unsigned long ampr, unsigned long amlr, char i_d, int n) |
210 | { | 211 | { |
211 | unsigned long phys, virt, cxn, size; | 212 | unsigned long phys, virt, cxn, size; |
212 | 213 | ||
213 | #ifdef CONFIG_MMU | 214 | #ifdef CONFIG_MMU |
214 | virt = amlr & 0xffffc000; | 215 | virt = amlr & 0xffffc000; |
215 | cxn = amlr & 0x3fff; | 216 | cxn = amlr & 0x3fff; |
216 | #else | 217 | #else |
217 | virt = ampr & 0xffffc000; | 218 | virt = ampr & 0xffffc000; |
218 | cxn = 0; | 219 | cxn = 0; |
219 | #endif | 220 | #endif |
220 | phys = ampr & xAMPRx_PPFN; | 221 | phys = ampr & xAMPRx_PPFN; |
221 | size = 1 << (((ampr & xAMPRx_SS) >> 4) + 17); | 222 | size = 1 << (((ampr & xAMPRx_SS) >> 4) + 17); |
222 | 223 | ||
223 | printk("%cAMPR%d: va %08lx-%08lx [pa %08lx] %c%c%c%c [cxn:%04lx]\n", | 224 | printk("%cAMPR%d: va %08lx-%08lx [pa %08lx] %c%c%c%c [cxn:%04lx]\n", |
224 | i_d, n, | 225 | i_d, n, |
225 | virt, virt + size - 1, | 226 | virt, virt + size - 1, |
226 | phys, | 227 | phys, |
227 | ampr & xAMPRx_S ? 'S' : '-', | 228 | ampr & xAMPRx_S ? 'S' : '-', |
228 | ampr & xAMPRx_C ? 'C' : '-', | 229 | ampr & xAMPRx_C ? 'C' : '-', |
229 | ampr & DAMPRx_WP ? 'W' : '-', | 230 | ampr & DAMPRx_WP ? 'W' : '-', |
230 | ampr & xAMPRx_V ? 'V' : '-', | 231 | ampr & xAMPRx_V ? 'V' : '-', |
231 | cxn | 232 | cxn |
232 | ); | 233 | ); |
233 | } | 234 | } |
234 | #endif | 235 | #endif |
235 | 236 | ||
236 | /*****************************************************************************/ | 237 | /*****************************************************************************/ |
237 | /* | 238 | /* |
238 | * dump the memory map | 239 | * dump the memory map |
239 | */ | 240 | */ |
240 | static void __init dump_memory_map(void) | 241 | static void __init dump_memory_map(void) |
241 | { | 242 | { |
242 | 243 | ||
243 | #if 0 | 244 | #if 0 |
244 | /* dump the protection map */ | 245 | /* dump the protection map */ |
245 | printk_xampr(__get_IAMPR(0), __get_IAMLR(0), 'I', 0); | 246 | printk_xampr(__get_IAMPR(0), __get_IAMLR(0), 'I', 0); |
246 | printk_xampr(__get_IAMPR(1), __get_IAMLR(1), 'I', 1); | 247 | printk_xampr(__get_IAMPR(1), __get_IAMLR(1), 'I', 1); |
247 | printk_xampr(__get_IAMPR(2), __get_IAMLR(2), 'I', 2); | 248 | printk_xampr(__get_IAMPR(2), __get_IAMLR(2), 'I', 2); |
248 | printk_xampr(__get_IAMPR(3), __get_IAMLR(3), 'I', 3); | 249 | printk_xampr(__get_IAMPR(3), __get_IAMLR(3), 'I', 3); |
249 | printk_xampr(__get_IAMPR(4), __get_IAMLR(4), 'I', 4); | 250 | printk_xampr(__get_IAMPR(4), __get_IAMLR(4), 'I', 4); |
250 | printk_xampr(__get_IAMPR(5), __get_IAMLR(5), 'I', 5); | 251 | printk_xampr(__get_IAMPR(5), __get_IAMLR(5), 'I', 5); |
251 | printk_xampr(__get_IAMPR(6), __get_IAMLR(6), 'I', 6); | 252 | printk_xampr(__get_IAMPR(6), __get_IAMLR(6), 'I', 6); |
252 | printk_xampr(__get_IAMPR(7), __get_IAMLR(7), 'I', 7); | 253 | printk_xampr(__get_IAMPR(7), __get_IAMLR(7), 'I', 7); |
253 | printk_xampr(__get_IAMPR(8), __get_IAMLR(8), 'I', 8); | 254 | printk_xampr(__get_IAMPR(8), __get_IAMLR(8), 'I', 8); |
254 | printk_xampr(__get_IAMPR(9), __get_IAMLR(9), 'i', 9); | 255 | printk_xampr(__get_IAMPR(9), __get_IAMLR(9), 'i', 9); |
255 | printk_xampr(__get_IAMPR(10), __get_IAMLR(10), 'I', 10); | 256 | printk_xampr(__get_IAMPR(10), __get_IAMLR(10), 'I', 10); |
256 | printk_xampr(__get_IAMPR(11), __get_IAMLR(11), 'I', 11); | 257 | printk_xampr(__get_IAMPR(11), __get_IAMLR(11), 'I', 11); |
257 | printk_xampr(__get_IAMPR(12), __get_IAMLR(12), 'I', 12); | 258 | printk_xampr(__get_IAMPR(12), __get_IAMLR(12), 'I', 12); |
258 | printk_xampr(__get_IAMPR(13), __get_IAMLR(13), 'I', 13); | 259 | printk_xampr(__get_IAMPR(13), __get_IAMLR(13), 'I', 13); |
259 | printk_xampr(__get_IAMPR(14), __get_IAMLR(14), 'I', 14); | 260 | printk_xampr(__get_IAMPR(14), __get_IAMLR(14), 'I', 14); |
260 | printk_xampr(__get_IAMPR(15), __get_IAMLR(15), 'I', 15); | 261 | printk_xampr(__get_IAMPR(15), __get_IAMLR(15), 'I', 15); |
261 | 262 | ||
262 | printk_xampr(__get_DAMPR(0), __get_DAMLR(0), 'D', 0); | 263 | printk_xampr(__get_DAMPR(0), __get_DAMLR(0), 'D', 0); |
263 | printk_xampr(__get_DAMPR(1), __get_DAMLR(1), 'D', 1); | 264 | printk_xampr(__get_DAMPR(1), __get_DAMLR(1), 'D', 1); |
264 | printk_xampr(__get_DAMPR(2), __get_DAMLR(2), 'D', 2); | 265 | printk_xampr(__get_DAMPR(2), __get_DAMLR(2), 'D', 2); |
265 | printk_xampr(__get_DAMPR(3), __get_DAMLR(3), 'D', 3); | 266 | printk_xampr(__get_DAMPR(3), __get_DAMLR(3), 'D', 3); |
266 | printk_xampr(__get_DAMPR(4), __get_DAMLR(4), 'D', 4); | 267 | printk_xampr(__get_DAMPR(4), __get_DAMLR(4), 'D', 4); |
267 | printk_xampr(__get_DAMPR(5), __get_DAMLR(5), 'D', 5); | 268 | printk_xampr(__get_DAMPR(5), __get_DAMLR(5), 'D', 5); |
268 | printk_xampr(__get_DAMPR(6), __get_DAMLR(6), 'D', 6); | 269 | printk_xampr(__get_DAMPR(6), __get_DAMLR(6), 'D', 6); |
269 | printk_xampr(__get_DAMPR(7), __get_DAMLR(7), 'D', 7); | 270 | printk_xampr(__get_DAMPR(7), __get_DAMLR(7), 'D', 7); |
270 | printk_xampr(__get_DAMPR(8), __get_DAMLR(8), 'D', 8); | 271 | printk_xampr(__get_DAMPR(8), __get_DAMLR(8), 'D', 8); |
271 | printk_xampr(__get_DAMPR(9), __get_DAMLR(9), 'D', 9); | 272 | printk_xampr(__get_DAMPR(9), __get_DAMLR(9), 'D', 9); |
272 | printk_xampr(__get_DAMPR(10), __get_DAMLR(10), 'D', 10); | 273 | printk_xampr(__get_DAMPR(10), __get_DAMLR(10), 'D', 10); |
273 | printk_xampr(__get_DAMPR(11), __get_DAMLR(11), 'D', 11); | 274 | printk_xampr(__get_DAMPR(11), __get_DAMLR(11), 'D', 11); |
274 | printk_xampr(__get_DAMPR(12), __get_DAMLR(12), 'D', 12); | 275 | printk_xampr(__get_DAMPR(12), __get_DAMLR(12), 'D', 12); |
275 | printk_xampr(__get_DAMPR(13), __get_DAMLR(13), 'D', 13); | 276 | printk_xampr(__get_DAMPR(13), __get_DAMLR(13), 'D', 13); |
276 | printk_xampr(__get_DAMPR(14), __get_DAMLR(14), 'D', 14); | 277 | printk_xampr(__get_DAMPR(14), __get_DAMLR(14), 'D', 14); |
277 | printk_xampr(__get_DAMPR(15), __get_DAMLR(15), 'D', 15); | 278 | printk_xampr(__get_DAMPR(15), __get_DAMLR(15), 'D', 15); |
278 | #endif | 279 | #endif |
279 | 280 | ||
280 | #if 0 | 281 | #if 0 |
281 | /* dump the bus controller registers */ | 282 | /* dump the bus controller registers */ |
282 | printk("LGCR: %08lx\n", __get_LGCR()); | 283 | printk("LGCR: %08lx\n", __get_LGCR()); |
283 | printk("Master: %08lx-%08lx CR=%08lx\n", | 284 | printk("Master: %08lx-%08lx CR=%08lx\n", |
284 | __get_LEMBR(), __get_LEMBR() + __get_LEMAM(), | 285 | __get_LEMBR(), __get_LEMBR() + __get_LEMAM(), |
285 | __get_LMAICR()); | 286 | __get_LMAICR()); |
286 | 287 | ||
287 | int loop; | 288 | int loop; |
288 | for (loop = 1; loop <= 7; loop++) { | 289 | for (loop = 1; loop <= 7; loop++) { |
289 | unsigned long lcr = __get_LCR(loop), lsbr = __get_LSBR(loop); | 290 | unsigned long lcr = __get_LCR(loop), lsbr = __get_LSBR(loop); |
290 | printk("CS#%d: %08lx-%08lx %c%c%c%c%c%c%c%c%c\n", | 291 | printk("CS#%d: %08lx-%08lx %c%c%c%c%c%c%c%c%c\n", |
291 | loop, | 292 | loop, |
292 | lsbr, lsbr + __get_LSAM(loop), | 293 | lsbr, lsbr + __get_LSAM(loop), |
293 | lcr & 0x80000000 ? 'r' : '-', | 294 | lcr & 0x80000000 ? 'r' : '-', |
294 | lcr & 0x40000000 ? 'w' : '-', | 295 | lcr & 0x40000000 ? 'w' : '-', |
295 | lcr & 0x08000000 ? 'b' : '-', | 296 | lcr & 0x08000000 ? 'b' : '-', |
296 | lcr & 0x04000000 ? 'B' : '-', | 297 | lcr & 0x04000000 ? 'B' : '-', |
297 | lcr & 0x02000000 ? 'C' : '-', | 298 | lcr & 0x02000000 ? 'C' : '-', |
298 | lcr & 0x01000000 ? 'D' : '-', | 299 | lcr & 0x01000000 ? 'D' : '-', |
299 | lcr & 0x00800000 ? 'W' : '-', | 300 | lcr & 0x00800000 ? 'W' : '-', |
300 | lcr & 0x00400000 ? 'R' : '-', | 301 | lcr & 0x00400000 ? 'R' : '-', |
301 | (lcr & 0x00030000) == 0x00000000 ? '4' : | 302 | (lcr & 0x00030000) == 0x00000000 ? '4' : |
302 | (lcr & 0x00030000) == 0x00010000 ? '2' : | 303 | (lcr & 0x00030000) == 0x00010000 ? '2' : |
303 | (lcr & 0x00030000) == 0x00020000 ? '1' : | 304 | (lcr & 0x00030000) == 0x00020000 ? '1' : |
304 | '-' | 305 | '-' |
305 | ); | 306 | ); |
306 | } | 307 | } |
307 | #endif | 308 | #endif |
308 | 309 | ||
309 | #if 0 | 310 | #if 0 |
310 | printk("\n"); | 311 | printk("\n"); |
311 | #endif | 312 | #endif |
312 | } /* end dump_memory_map() */ | 313 | } /* end dump_memory_map() */ |
313 | 314 | ||
314 | /*****************************************************************************/ | 315 | /*****************************************************************************/ |
315 | /* | 316 | /* |
316 | * attempt to detect a VDK motherboard and DAV daughter board on an MB93091 system | 317 | * attempt to detect a VDK motherboard and DAV daughter board on an MB93091 system |
317 | */ | 318 | */ |
318 | #ifdef CONFIG_MB93091_VDK | 319 | #ifdef CONFIG_MB93091_VDK |
319 | static void __init detect_mb93091(void) | 320 | static void __init detect_mb93091(void) |
320 | { | 321 | { |
321 | #ifdef CONFIG_MB93090_MB00 | 322 | #ifdef CONFIG_MB93090_MB00 |
322 | /* Detect CB70 without motherboard */ | 323 | /* Detect CB70 without motherboard */ |
323 | if (!(cpu_system == __frv_mb93091_cb70 && ((*(unsigned short *)0xffc00030) & 0x100))) { | 324 | if (!(cpu_system == __frv_mb93091_cb70 && ((*(unsigned short *)0xffc00030) & 0x100))) { |
324 | cpu_board1 = __frv_mb93090_mb00; | 325 | cpu_board1 = __frv_mb93090_mb00; |
325 | mb93090_mb00_detected = 1; | 326 | mb93090_mb00_detected = 1; |
326 | } | 327 | } |
327 | #endif | 328 | #endif |
328 | 329 | ||
329 | #ifdef CONFIG_FUJITSU_MB93493 | 330 | #ifdef CONFIG_FUJITSU_MB93493 |
330 | cpu_board2 = __frv_mb93493; | 331 | cpu_board2 = __frv_mb93493; |
331 | #endif | 332 | #endif |
332 | 333 | ||
333 | } /* end detect_mb93091() */ | 334 | } /* end detect_mb93091() */ |
334 | #endif | 335 | #endif |
335 | 336 | ||
336 | /*****************************************************************************/ | 337 | /*****************************************************************************/ |
337 | /* | 338 | /* |
338 | * determine the CPU type and set appropriate parameters | 339 | * determine the CPU type and set appropriate parameters |
339 | * | 340 | * |
340 | * Family Series CPU Core Silicon Imple Vers | 341 | * Family Series CPU Core Silicon Imple Vers |
341 | * ---------------------------------------------------------- | 342 | * ---------------------------------------------------------- |
342 | * FR-V --+-> FR400 --+-> FR401 --+-> MB93401 02 00 [1] | 343 | * FR-V --+-> FR400 --+-> FR401 --+-> MB93401 02 00 [1] |
343 | * | | | | 344 | * | | | |
344 | * | | +-> MB93401/A 02 01 | 345 | * | | +-> MB93401/A 02 01 |
345 | * | | | | 346 | * | | | |
346 | * | | +-> MB93403 02 02 | 347 | * | | +-> MB93403 02 02 |
347 | * | | | 348 | * | | |
348 | * | +-> FR405 ----> MB93405 04 00 | 349 | * | +-> FR405 ----> MB93405 04 00 |
349 | * | | 350 | * | |
350 | * +-> FR450 ----> FR451 ----> MB93451 05 00 | 351 | * +-> FR450 ----> FR451 ----> MB93451 05 00 |
351 | * | | 352 | * | |
352 | * +-> FR500 ----> FR501 --+-> MB93501 01 01 [2] | 353 | * +-> FR500 ----> FR501 --+-> MB93501 01 01 [2] |
353 | * | | | 354 | * | | |
354 | * | +-> MB93501/A 01 02 | 355 | * | +-> MB93501/A 01 02 |
355 | * | | 356 | * | |
356 | * +-> FR550 --+-> FR551 ----> MB93555 03 01 | 357 | * +-> FR550 --+-> FR551 ----> MB93555 03 01 |
357 | * | 358 | * |
358 | * [1] The MB93401 is an obsolete CPU replaced by the MB93401A | 359 | * [1] The MB93401 is an obsolete CPU replaced by the MB93401A |
359 | * [2] The MB93501 is an obsolete CPU replaced by the MB93501A | 360 | * [2] The MB93501 is an obsolete CPU replaced by the MB93501A |
360 | * | 361 | * |
361 | * Imple is PSR(Processor Status Register)[31:28]. | 362 | * Imple is PSR(Processor Status Register)[31:28]. |
362 | * Vers is PSR(Processor Status Register)[27:24]. | 363 | * Vers is PSR(Processor Status Register)[27:24]. |
363 | * | 364 | * |
364 | * A "Silicon" consists of CPU core and some on-chip peripherals. | 365 | * A "Silicon" consists of CPU core and some on-chip peripherals. |
365 | */ | 366 | */ |
366 | static void __init determine_cpu(void) | 367 | static void __init determine_cpu(void) |
367 | { | 368 | { |
368 | unsigned long hsr0 = __get_HSR(0); | 369 | unsigned long hsr0 = __get_HSR(0); |
369 | unsigned long psr = __get_PSR(); | 370 | unsigned long psr = __get_PSR(); |
370 | 371 | ||
371 | /* work out what selectable services the CPU supports */ | 372 | /* work out what selectable services the CPU supports */ |
372 | __set_PSR(psr | PSR_EM | PSR_EF | PSR_CM | PSR_NEM); | 373 | __set_PSR(psr | PSR_EM | PSR_EF | PSR_CM | PSR_NEM); |
373 | cpu_psr_all = __get_PSR(); | 374 | cpu_psr_all = __get_PSR(); |
374 | __set_PSR(psr); | 375 | __set_PSR(psr); |
375 | 376 | ||
376 | __set_HSR(0, hsr0 | HSR0_GRLE | HSR0_GRHE | HSR0_FRLE | HSR0_FRHE); | 377 | __set_HSR(0, hsr0 | HSR0_GRLE | HSR0_GRHE | HSR0_FRLE | HSR0_FRHE); |
377 | cpu_hsr0_all = __get_HSR(0); | 378 | cpu_hsr0_all = __get_HSR(0); |
378 | __set_HSR(0, hsr0); | 379 | __set_HSR(0, hsr0); |
379 | 380 | ||
380 | /* derive other service specs from the CPU type */ | 381 | /* derive other service specs from the CPU type */ |
381 | cpu_series = "unknown"; | 382 | cpu_series = "unknown"; |
382 | cpu_core = "unknown"; | 383 | cpu_core = "unknown"; |
383 | cpu_silicon = "unknown"; | 384 | cpu_silicon = "unknown"; |
384 | cpu_mmu = "Prot"; | 385 | cpu_mmu = "Prot"; |
385 | cpu_system = __frv_unknown_system; | 386 | cpu_system = __frv_unknown_system; |
386 | clock_cmodes = NULL; | 387 | clock_cmodes = NULL; |
387 | clock_doubled = 0; | 388 | clock_doubled = 0; |
388 | #ifdef CONFIG_PM | 389 | #ifdef CONFIG_PM |
389 | clock_bits_settable = CLOCK_BIT_CM_H | CLOCK_BIT_CM_M | CLOCK_BIT_P0; | 390 | clock_bits_settable = CLOCK_BIT_CM_H | CLOCK_BIT_CM_M | CLOCK_BIT_P0; |
390 | #endif | 391 | #endif |
391 | 392 | ||
392 | switch (PSR_IMPLE(psr)) { | 393 | switch (PSR_IMPLE(psr)) { |
393 | case PSR_IMPLE_FR401: | 394 | case PSR_IMPLE_FR401: |
394 | cpu_series = "fr400"; | 395 | cpu_series = "fr400"; |
395 | cpu_core = "fr401"; | 396 | cpu_core = "fr401"; |
396 | pdm_suspend_mode = HSR0_PDM_PLL_RUN; | 397 | pdm_suspend_mode = HSR0_PDM_PLL_RUN; |
397 | 398 | ||
398 | switch (PSR_VERSION(psr)) { | 399 | switch (PSR_VERSION(psr)) { |
399 | case PSR_VERSION_FR401_MB93401: | 400 | case PSR_VERSION_FR401_MB93401: |
400 | cpu_silicon = "mb93401"; | 401 | cpu_silicon = "mb93401"; |
401 | cpu_system = __frv_mb93091_cb10; | 402 | cpu_system = __frv_mb93091_cb10; |
402 | clock_cmodes = clock_cmodes_fr401_fr403; | 403 | clock_cmodes = clock_cmodes_fr401_fr403; |
403 | clock_doubled = 1; | 404 | clock_doubled = 1; |
404 | break; | 405 | break; |
405 | case PSR_VERSION_FR401_MB93401A: | 406 | case PSR_VERSION_FR401_MB93401A: |
406 | cpu_silicon = "mb93401/A"; | 407 | cpu_silicon = "mb93401/A"; |
407 | cpu_system = __frv_mb93091_cb11; | 408 | cpu_system = __frv_mb93091_cb11; |
408 | clock_cmodes = clock_cmodes_fr401_fr403; | 409 | clock_cmodes = clock_cmodes_fr401_fr403; |
409 | break; | 410 | break; |
410 | case PSR_VERSION_FR401_MB93403: | 411 | case PSR_VERSION_FR401_MB93403: |
411 | cpu_silicon = "mb93403"; | 412 | cpu_silicon = "mb93403"; |
412 | #ifndef CONFIG_MB93093_PDK | 413 | #ifndef CONFIG_MB93093_PDK |
413 | cpu_system = __frv_mb93091_cb30; | 414 | cpu_system = __frv_mb93091_cb30; |
414 | #else | 415 | #else |
415 | cpu_system = __frv_mb93093; | 416 | cpu_system = __frv_mb93093; |
416 | #endif | 417 | #endif |
417 | clock_cmodes = clock_cmodes_fr401_fr403; | 418 | clock_cmodes = clock_cmodes_fr401_fr403; |
418 | break; | 419 | break; |
419 | default: | 420 | default: |
420 | break; | 421 | break; |
421 | } | 422 | } |
422 | break; | 423 | break; |
423 | 424 | ||
424 | case PSR_IMPLE_FR405: | 425 | case PSR_IMPLE_FR405: |
425 | cpu_series = "fr400"; | 426 | cpu_series = "fr400"; |
426 | cpu_core = "fr405"; | 427 | cpu_core = "fr405"; |
427 | pdm_suspend_mode = HSR0_PDM_PLL_STOP; | 428 | pdm_suspend_mode = HSR0_PDM_PLL_STOP; |
428 | 429 | ||
429 | switch (PSR_VERSION(psr)) { | 430 | switch (PSR_VERSION(psr)) { |
430 | case PSR_VERSION_FR405_MB93405: | 431 | case PSR_VERSION_FR405_MB93405: |
431 | cpu_silicon = "mb93405"; | 432 | cpu_silicon = "mb93405"; |
432 | cpu_system = __frv_mb93091_cb60; | 433 | cpu_system = __frv_mb93091_cb60; |
433 | clock_cmodes = clock_cmodes_fr405; | 434 | clock_cmodes = clock_cmodes_fr405; |
434 | #ifdef CONFIG_PM | 435 | #ifdef CONFIG_PM |
435 | clock_bits_settable |= CLOCK_BIT_CMODE; | 436 | clock_bits_settable |= CLOCK_BIT_CMODE; |
436 | clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405; | 437 | clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405; |
437 | #endif | 438 | #endif |
438 | 439 | ||
439 | /* the FPGA on the CB70 has extra registers | 440 | /* the FPGA on the CB70 has extra registers |
440 | * - it has 0x0046 in the VDK_ID FPGA register at 0x1a0, which is | 441 | * - it has 0x0046 in the VDK_ID FPGA register at 0x1a0, which is |
441 | * how we tell the difference between it and a CB60 | 442 | * how we tell the difference between it and a CB60 |
442 | */ | 443 | */ |
443 | if (*(volatile unsigned short *) 0xffc001a0 == 0x0046) | 444 | if (*(volatile unsigned short *) 0xffc001a0 == 0x0046) |
444 | cpu_system = __frv_mb93091_cb70; | 445 | cpu_system = __frv_mb93091_cb70; |
445 | break; | 446 | break; |
446 | default: | 447 | default: |
447 | break; | 448 | break; |
448 | } | 449 | } |
449 | break; | 450 | break; |
450 | 451 | ||
451 | case PSR_IMPLE_FR451: | 452 | case PSR_IMPLE_FR451: |
452 | cpu_series = "fr450"; | 453 | cpu_series = "fr450"; |
453 | cpu_core = "fr451"; | 454 | cpu_core = "fr451"; |
454 | pdm_suspend_mode = HSR0_PDM_PLL_STOP; | 455 | pdm_suspend_mode = HSR0_PDM_PLL_STOP; |
455 | #ifdef CONFIG_PM | 456 | #ifdef CONFIG_PM |
456 | clock_bits_settable |= CLOCK_BIT_CMODE; | 457 | clock_bits_settable |= CLOCK_BIT_CMODE; |
457 | clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405; | 458 | clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405; |
458 | #endif | 459 | #endif |
459 | switch (PSR_VERSION(psr)) { | 460 | switch (PSR_VERSION(psr)) { |
460 | case PSR_VERSION_FR451_MB93451: | 461 | case PSR_VERSION_FR451_MB93451: |
461 | cpu_silicon = "mb93451"; | 462 | cpu_silicon = "mb93451"; |
462 | cpu_mmu = "Prot, SAT, xSAT, DAT"; | 463 | cpu_mmu = "Prot, SAT, xSAT, DAT"; |
463 | cpu_system = __frv_mb93091_cb451; | 464 | cpu_system = __frv_mb93091_cb451; |
464 | clock_cmodes = clock_cmodes_fr405; | 465 | clock_cmodes = clock_cmodes_fr405; |
465 | break; | 466 | break; |
466 | default: | 467 | default: |
467 | break; | 468 | break; |
468 | } | 469 | } |
469 | break; | 470 | break; |
470 | 471 | ||
471 | case PSR_IMPLE_FR501: | 472 | case PSR_IMPLE_FR501: |
472 | cpu_series = "fr500"; | 473 | cpu_series = "fr500"; |
473 | cpu_core = "fr501"; | 474 | cpu_core = "fr501"; |
474 | pdm_suspend_mode = HSR0_PDM_PLL_STOP; | 475 | pdm_suspend_mode = HSR0_PDM_PLL_STOP; |
475 | 476 | ||
476 | switch (PSR_VERSION(psr)) { | 477 | switch (PSR_VERSION(psr)) { |
477 | case PSR_VERSION_FR501_MB93501: cpu_silicon = "mb93501"; break; | 478 | case PSR_VERSION_FR501_MB93501: cpu_silicon = "mb93501"; break; |
478 | case PSR_VERSION_FR501_MB93501A: cpu_silicon = "mb93501/A"; break; | 479 | case PSR_VERSION_FR501_MB93501A: cpu_silicon = "mb93501/A"; break; |
479 | default: | 480 | default: |
480 | break; | 481 | break; |
481 | } | 482 | } |
482 | break; | 483 | break; |
483 | 484 | ||
484 | case PSR_IMPLE_FR551: | 485 | case PSR_IMPLE_FR551: |
485 | cpu_series = "fr550"; | 486 | cpu_series = "fr550"; |
486 | cpu_core = "fr551"; | 487 | cpu_core = "fr551"; |
487 | pdm_suspend_mode = HSR0_PDM_PLL_RUN; | 488 | pdm_suspend_mode = HSR0_PDM_PLL_RUN; |
488 | 489 | ||
489 | switch (PSR_VERSION(psr)) { | 490 | switch (PSR_VERSION(psr)) { |
490 | case PSR_VERSION_FR551_MB93555: | 491 | case PSR_VERSION_FR551_MB93555: |
491 | cpu_silicon = "mb93555"; | 492 | cpu_silicon = "mb93555"; |
492 | cpu_mmu = "Prot, SAT"; | 493 | cpu_mmu = "Prot, SAT"; |
493 | cpu_system = __frv_mb93091_cb41; | 494 | cpu_system = __frv_mb93091_cb41; |
494 | clock_cmodes = clock_cmodes_fr555; | 495 | clock_cmodes = clock_cmodes_fr555; |
495 | clock_doubled = 1; | 496 | clock_doubled = 1; |
496 | break; | 497 | break; |
497 | default: | 498 | default: |
498 | break; | 499 | break; |
499 | } | 500 | } |
500 | break; | 501 | break; |
501 | 502 | ||
502 | default: | 503 | default: |
503 | break; | 504 | break; |
504 | } | 505 | } |
505 | 506 | ||
506 | printk("- Series:%s CPU:%s Silicon:%s\n", | 507 | printk("- Series:%s CPU:%s Silicon:%s\n", |
507 | cpu_series, cpu_core, cpu_silicon); | 508 | cpu_series, cpu_core, cpu_silicon); |
508 | 509 | ||
509 | #ifdef CONFIG_MB93091_VDK | 510 | #ifdef CONFIG_MB93091_VDK |
510 | detect_mb93091(); | 511 | detect_mb93091(); |
511 | #endif | 512 | #endif |
512 | 513 | ||
513 | #if defined(CONFIG_MB93093_PDK) && defined(CONFIG_FUJITSU_MB93493) | 514 | #if defined(CONFIG_MB93093_PDK) && defined(CONFIG_FUJITSU_MB93493) |
514 | cpu_board2 = __frv_mb93493; | 515 | cpu_board2 = __frv_mb93493; |
515 | #endif | 516 | #endif |
516 | 517 | ||
517 | } /* end determine_cpu() */ | 518 | } /* end determine_cpu() */ |
518 | 519 | ||
519 | /*****************************************************************************/ | 520 | /*****************************************************************************/ |
520 | /* | 521 | /* |
521 | * calculate the bus clock speed | 522 | * calculate the bus clock speed |
522 | */ | 523 | */ |
523 | void __pminit determine_clocks(int verbose) | 524 | void __pminit determine_clocks(int verbose) |
524 | { | 525 | { |
525 | const struct clock_cmode *mode, *tmode; | 526 | const struct clock_cmode *mode, *tmode; |
526 | unsigned long clkc, psr, quot; | 527 | unsigned long clkc, psr, quot; |
527 | 528 | ||
528 | clkc = __get_CLKC(); | 529 | clkc = __get_CLKC(); |
529 | psr = __get_PSR(); | 530 | psr = __get_PSR(); |
530 | 531 | ||
531 | clock_p0_current = !!(clkc & CLKC_P0); | 532 | clock_p0_current = !!(clkc & CLKC_P0); |
532 | clock_cm_current = clkc & CLKC_CM; | 533 | clock_cm_current = clkc & CLKC_CM; |
533 | clock_cmode_current = (clkc & CLKC_CMODE) >> CLKC_CMODE_s; | 534 | clock_cmode_current = (clkc & CLKC_CMODE) >> CLKC_CMODE_s; |
534 | 535 | ||
535 | if (verbose) | 536 | if (verbose) |
536 | printk("psr=%08lx hsr0=%08lx clkc=%08lx\n", psr, __get_HSR(0), clkc); | 537 | printk("psr=%08lx hsr0=%08lx clkc=%08lx\n", psr, __get_HSR(0), clkc); |
537 | 538 | ||
538 | /* the CB70 has some alternative ways of setting the clock speed through switches accessed | 539 | /* the CB70 has some alternative ways of setting the clock speed through switches accessed |
539 | * through the FPGA. */ | 540 | * through the FPGA. */ |
540 | if (cpu_system == __frv_mb93091_cb70) { | 541 | if (cpu_system == __frv_mb93091_cb70) { |
541 | unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL; | 542 | unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL; |
542 | 543 | ||
543 | if (clkswr & 0x1000) | 544 | if (clkswr & 0x1000) |
544 | __clkin_clock_speed_HZ = 60000000UL; | 545 | __clkin_clock_speed_HZ = 60000000UL; |
545 | else | 546 | else |
546 | __clkin_clock_speed_HZ = | 547 | __clkin_clock_speed_HZ = |
547 | ((clkswr >> 8) & 0xf) * 10000000 + | 548 | ((clkswr >> 8) & 0xf) * 10000000 + |
548 | ((clkswr >> 4) & 0xf) * 1000000 + | 549 | ((clkswr >> 4) & 0xf) * 1000000 + |
549 | ((clkswr ) & 0xf) * 100000; | 550 | ((clkswr ) & 0xf) * 100000; |
550 | } | 551 | } |
551 | /* the FR451 is currently fixed at 24MHz */ | 552 | /* the FR451 is currently fixed at 24MHz */ |
552 | else if (cpu_system == __frv_mb93091_cb451) { | 553 | else if (cpu_system == __frv_mb93091_cb451) { |
553 | //__clkin_clock_speed_HZ = 24000000UL; // CB451-FPGA | 554 | //__clkin_clock_speed_HZ = 24000000UL; // CB451-FPGA |
554 | unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL; | 555 | unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL; |
555 | 556 | ||
556 | if (clkswr & 0x1000) | 557 | if (clkswr & 0x1000) |
557 | __clkin_clock_speed_HZ = 60000000UL; | 558 | __clkin_clock_speed_HZ = 60000000UL; |
558 | else | 559 | else |
559 | __clkin_clock_speed_HZ = | 560 | __clkin_clock_speed_HZ = |
560 | ((clkswr >> 8) & 0xf) * 10000000 + | 561 | ((clkswr >> 8) & 0xf) * 10000000 + |
561 | ((clkswr >> 4) & 0xf) * 1000000 + | 562 | ((clkswr >> 4) & 0xf) * 1000000 + |
562 | ((clkswr ) & 0xf) * 100000; | 563 | ((clkswr ) & 0xf) * 100000; |
563 | } | 564 | } |
564 | /* otherwise determine the clockspeed from VDK or other registers */ | 565 | /* otherwise determine the clockspeed from VDK or other registers */ |
565 | else { | 566 | else { |
566 | __clkin_clock_speed_HZ = __get_CLKIN(); | 567 | __clkin_clock_speed_HZ = __get_CLKIN(); |
567 | } | 568 | } |
568 | 569 | ||
569 | /* look up the appropriate clock relationships table entry */ | 570 | /* look up the appropriate clock relationships table entry */ |
570 | mode = &undef_clock_cmode; | 571 | mode = &undef_clock_cmode; |
571 | if (clock_cmodes) { | 572 | if (clock_cmodes) { |
572 | tmode = &clock_cmodes[(clkc & CLKC_CMODE) >> CLKC_CMODE_s]; | 573 | tmode = &clock_cmodes[(clkc & CLKC_CMODE) >> CLKC_CMODE_s]; |
573 | if (tmode->xbus) | 574 | if (tmode->xbus) |
574 | mode = tmode; | 575 | mode = tmode; |
575 | } | 576 | } |
576 | 577 | ||
577 | #define CLOCK(SRC,RATIO) ((SRC) * (((RATIO) >> 4) & 0x0f) / ((RATIO) & 0x0f)) | 578 | #define CLOCK(SRC,RATIO) ((SRC) * (((RATIO) >> 4) & 0x0f) / ((RATIO) & 0x0f)) |
578 | 579 | ||
579 | if (clock_doubled) | 580 | if (clock_doubled) |
580 | __clkin_clock_speed_HZ <<= 1; | 581 | __clkin_clock_speed_HZ <<= 1; |
581 | 582 | ||
582 | __ext_bus_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->xbus); | 583 | __ext_bus_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->xbus); |
583 | __sdram_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->sdram); | 584 | __sdram_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->sdram); |
584 | __dsu_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->dsu); | 585 | __dsu_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->dsu); |
585 | 586 | ||
586 | switch (clkc & CLKC_CM) { | 587 | switch (clkc & CLKC_CM) { |
587 | case 0: /* High */ | 588 | case 0: /* High */ |
588 | __core_bus_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->corebus); | 589 | __core_bus_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->corebus); |
589 | __core_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->core); | 590 | __core_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->core); |
590 | break; | 591 | break; |
591 | case 1: /* Medium */ | 592 | case 1: /* Medium */ |
592 | __core_bus_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->sdram); | 593 | __core_bus_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->sdram); |
593 | __core_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->sdram); | 594 | __core_clock_speed_HZ = CLOCK(__clkin_clock_speed_HZ, mode->sdram); |
594 | break; | 595 | break; |
595 | case 2: /* Low; not supported */ | 596 | case 2: /* Low; not supported */ |
596 | case 3: /* UNDEF */ | 597 | case 3: /* UNDEF */ |
597 | printk("Unsupported CLKC CM %ld\n", clkc & CLKC_CM); | 598 | printk("Unsupported CLKC CM %ld\n", clkc & CLKC_CM); |
598 | panic("Bye"); | 599 | panic("Bye"); |
599 | } | 600 | } |
600 | 601 | ||
601 | __res_bus_clock_speed_HZ = __ext_bus_clock_speed_HZ; | 602 | __res_bus_clock_speed_HZ = __ext_bus_clock_speed_HZ; |
602 | if (clkc & CLKC_P0) | 603 | if (clkc & CLKC_P0) |
603 | __res_bus_clock_speed_HZ >>= 1; | 604 | __res_bus_clock_speed_HZ >>= 1; |
604 | 605 | ||
605 | if (verbose) { | 606 | if (verbose) { |
606 | printk("CLKIN: %lu.%3.3luMHz\n", | 607 | printk("CLKIN: %lu.%3.3luMHz\n", |
607 | __clkin_clock_speed_HZ / 1000000, | 608 | __clkin_clock_speed_HZ / 1000000, |
608 | (__clkin_clock_speed_HZ / 1000) % 1000); | 609 | (__clkin_clock_speed_HZ / 1000) % 1000); |
609 | 610 | ||
610 | printk("CLKS:" | 611 | printk("CLKS:" |
611 | " ext=%luMHz res=%luMHz sdram=%luMHz cbus=%luMHz core=%luMHz dsu=%luMHz\n", | 612 | " ext=%luMHz res=%luMHz sdram=%luMHz cbus=%luMHz core=%luMHz dsu=%luMHz\n", |
612 | __ext_bus_clock_speed_HZ / 1000000, | 613 | __ext_bus_clock_speed_HZ / 1000000, |
613 | __res_bus_clock_speed_HZ / 1000000, | 614 | __res_bus_clock_speed_HZ / 1000000, |
614 | __sdram_clock_speed_HZ / 1000000, | 615 | __sdram_clock_speed_HZ / 1000000, |
615 | __core_bus_clock_speed_HZ / 1000000, | 616 | __core_bus_clock_speed_HZ / 1000000, |
616 | __core_clock_speed_HZ / 1000000, | 617 | __core_clock_speed_HZ / 1000000, |
617 | __dsu_clock_speed_HZ / 1000000 | 618 | __dsu_clock_speed_HZ / 1000000 |
618 | ); | 619 | ); |
619 | } | 620 | } |
620 | 621 | ||
621 | /* calculate the number of __delay() loop iterations per sec (2 insn loop) */ | 622 | /* calculate the number of __delay() loop iterations per sec (2 insn loop) */ |
622 | __delay_loops_MHz = __core_clock_speed_HZ / (1000000 * 2); | 623 | __delay_loops_MHz = __core_clock_speed_HZ / (1000000 * 2); |
623 | 624 | ||
624 | /* set the serial prescaler */ | 625 | /* set the serial prescaler */ |
625 | __serial_clock_speed_HZ = __res_bus_clock_speed_HZ; | 626 | __serial_clock_speed_HZ = __res_bus_clock_speed_HZ; |
626 | quot = 1; | 627 | quot = 1; |
627 | while (__serial_clock_speed_HZ / quot / 16 / 65536 > 3000) | 628 | while (__serial_clock_speed_HZ / quot / 16 / 65536 > 3000) |
628 | quot += 1; | 629 | quot += 1; |
629 | 630 | ||
630 | /* double the divisor if P0 is clear, so that if/when P0 is set, it's still achievable | 631 | /* double the divisor if P0 is clear, so that if/when P0 is set, it's still achievable |
631 | * - we have to be careful - dividing too much can mean we can't get 115200 baud | 632 | * - we have to be careful - dividing too much can mean we can't get 115200 baud |
632 | */ | 633 | */ |
633 | if (__serial_clock_speed_HZ > 32000000 && !(clkc & CLKC_P0)) | 634 | if (__serial_clock_speed_HZ > 32000000 && !(clkc & CLKC_P0)) |
634 | quot <<= 1; | 635 | quot <<= 1; |
635 | 636 | ||
636 | __serial_clock_speed_HZ /= quot; | 637 | __serial_clock_speed_HZ /= quot; |
637 | __frv_uart0.uartclk = __serial_clock_speed_HZ; | 638 | __frv_uart0.uartclk = __serial_clock_speed_HZ; |
638 | __frv_uart1.uartclk = __serial_clock_speed_HZ; | 639 | __frv_uart1.uartclk = __serial_clock_speed_HZ; |
639 | 640 | ||
640 | if (verbose) | 641 | if (verbose) |
641 | printk(" uart=%luMHz\n", __serial_clock_speed_HZ / 1000000 * quot); | 642 | printk(" uart=%luMHz\n", __serial_clock_speed_HZ / 1000000 * quot); |
642 | 643 | ||
643 | while (!(__get_UART0_LSR() & UART_LSR_TEMT)) | 644 | while (!(__get_UART0_LSR() & UART_LSR_TEMT)) |
644 | continue; | 645 | continue; |
645 | 646 | ||
646 | while (!(__get_UART1_LSR() & UART_LSR_TEMT)) | 647 | while (!(__get_UART1_LSR() & UART_LSR_TEMT)) |
647 | continue; | 648 | continue; |
648 | 649 | ||
649 | __set_UCPVR(quot); | 650 | __set_UCPVR(quot); |
650 | __set_UCPSR(0); | 651 | __set_UCPSR(0); |
651 | } /* end determine_clocks() */ | 652 | } /* end determine_clocks() */ |
652 | 653 | ||
653 | /*****************************************************************************/ | 654 | /*****************************************************************************/ |
654 | /* | 655 | /* |
655 | * reserve some DMA consistent memory | 656 | * reserve some DMA consistent memory |
656 | */ | 657 | */ |
657 | #ifdef CONFIG_RESERVE_DMA_COHERENT | 658 | #ifdef CONFIG_RESERVE_DMA_COHERENT |
658 | static void __init reserve_dma_coherent(void) | 659 | static void __init reserve_dma_coherent(void) |
659 | { | 660 | { |
660 | unsigned long ampr; | 661 | unsigned long ampr; |
661 | 662 | ||
662 | /* find the first non-kernel memory tile and steal it */ | 663 | /* find the first non-kernel memory tile and steal it */ |
663 | #define __steal_AMPR(r) \ | 664 | #define __steal_AMPR(r) \ |
664 | if (__get_DAMPR(r) & xAMPRx_V) { \ | 665 | if (__get_DAMPR(r) & xAMPRx_V) { \ |
665 | ampr = __get_DAMPR(r); \ | 666 | ampr = __get_DAMPR(r); \ |
666 | __set_DAMPR(r, ampr | xAMPRx_S | xAMPRx_C); \ | 667 | __set_DAMPR(r, ampr | xAMPRx_S | xAMPRx_C); \ |
667 | __set_IAMPR(r, 0); \ | 668 | __set_IAMPR(r, 0); \ |
668 | goto found; \ | 669 | goto found; \ |
669 | } | 670 | } |
670 | 671 | ||
671 | __steal_AMPR(1); | 672 | __steal_AMPR(1); |
672 | __steal_AMPR(2); | 673 | __steal_AMPR(2); |
673 | __steal_AMPR(3); | 674 | __steal_AMPR(3); |
674 | __steal_AMPR(4); | 675 | __steal_AMPR(4); |
675 | __steal_AMPR(5); | 676 | __steal_AMPR(5); |
676 | __steal_AMPR(6); | 677 | __steal_AMPR(6); |
677 | 678 | ||
678 | if (PSR_IMPLE(__get_PSR()) == PSR_IMPLE_FR551) { | 679 | if (PSR_IMPLE(__get_PSR()) == PSR_IMPLE_FR551) { |
679 | __steal_AMPR(7); | 680 | __steal_AMPR(7); |
680 | __steal_AMPR(8); | 681 | __steal_AMPR(8); |
681 | __steal_AMPR(9); | 682 | __steal_AMPR(9); |
682 | __steal_AMPR(10); | 683 | __steal_AMPR(10); |
683 | __steal_AMPR(11); | 684 | __steal_AMPR(11); |
684 | __steal_AMPR(12); | 685 | __steal_AMPR(12); |
685 | __steal_AMPR(13); | 686 | __steal_AMPR(13); |
686 | __steal_AMPR(14); | 687 | __steal_AMPR(14); |
687 | } | 688 | } |
688 | 689 | ||
689 | /* unable to grant any DMA consistent memory */ | 690 | /* unable to grant any DMA consistent memory */ |
690 | printk("No DMA consistent memory reserved\n"); | 691 | printk("No DMA consistent memory reserved\n"); |
691 | return; | 692 | return; |
692 | 693 | ||
693 | found: | 694 | found: |
694 | dma_coherent_mem_start = ampr & xAMPRx_PPFN; | 695 | dma_coherent_mem_start = ampr & xAMPRx_PPFN; |
695 | ampr &= xAMPRx_SS; | 696 | ampr &= xAMPRx_SS; |
696 | ampr >>= 4; | 697 | ampr >>= 4; |
697 | ampr = 1 << (ampr - 3 + 20); | 698 | ampr = 1 << (ampr - 3 + 20); |
698 | dma_coherent_mem_end = dma_coherent_mem_start + ampr; | 699 | dma_coherent_mem_end = dma_coherent_mem_start + ampr; |
699 | 700 | ||
700 | printk("DMA consistent memory reserved %lx-%lx\n", | 701 | printk("DMA consistent memory reserved %lx-%lx\n", |
701 | dma_coherent_mem_start, dma_coherent_mem_end); | 702 | dma_coherent_mem_start, dma_coherent_mem_end); |
702 | 703 | ||
703 | } /* end reserve_dma_coherent() */ | 704 | } /* end reserve_dma_coherent() */ |
704 | #endif | 705 | #endif |
705 | 706 | ||
706 | /*****************************************************************************/ | 707 | /*****************************************************************************/ |
707 | /* | 708 | /* |
708 | * calibrate the delay loop | 709 | * calibrate the delay loop |
709 | */ | 710 | */ |
710 | void __init calibrate_delay(void) | 711 | void __init calibrate_delay(void) |
711 | { | 712 | { |
712 | loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ); | 713 | loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ); |
713 | 714 | ||
714 | printk("Calibrating delay loop... %lu.%02lu BogoMIPS\n", | 715 | printk("Calibrating delay loop... %lu.%02lu BogoMIPS\n", |
715 | loops_per_jiffy / (500000 / HZ), | 716 | loops_per_jiffy / (500000 / HZ), |
716 | (loops_per_jiffy / (5000 / HZ)) % 100); | 717 | (loops_per_jiffy / (5000 / HZ)) % 100); |
717 | 718 | ||
718 | } /* end calibrate_delay() */ | 719 | } /* end calibrate_delay() */ |
719 | 720 | ||
720 | /*****************************************************************************/ | 721 | /*****************************************************************************/ |
721 | /* | 722 | /* |
722 | * look through the command line for some things we need to know immediately | 723 | * look through the command line for some things we need to know immediately |
723 | */ | 724 | */ |
724 | static void __init parse_cmdline_early(char *cmdline) | 725 | static void __init parse_cmdline_early(char *cmdline) |
725 | { | 726 | { |
726 | if (!cmdline) | 727 | if (!cmdline) |
727 | return; | 728 | return; |
728 | 729 | ||
729 | while (*cmdline) { | 730 | while (*cmdline) { |
730 | if (*cmdline == ' ') | 731 | if (*cmdline == ' ') |
731 | cmdline++; | 732 | cmdline++; |
732 | 733 | ||
733 | /* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked | 734 | /* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked |
734 | * out from the SDRAM controller mask register | 735 | * out from the SDRAM controller mask register |
735 | */ | 736 | */ |
736 | if (!memcmp(cmdline, "mem=", 4)) { | 737 | if (!memcmp(cmdline, "mem=", 4)) { |
737 | unsigned long long mem_size; | 738 | unsigned long long mem_size; |
738 | 739 | ||
739 | mem_size = memparse(cmdline + 4, &cmdline); | 740 | mem_size = memparse(cmdline + 4, &cmdline); |
740 | memory_end = memory_start + mem_size; | 741 | memory_end = memory_start + mem_size; |
741 | } | 742 | } |
742 | 743 | ||
743 | while (*cmdline && *cmdline != ' ') | 744 | while (*cmdline && *cmdline != ' ') |
744 | cmdline++; | 745 | cmdline++; |
745 | } | 746 | } |
746 | 747 | ||
747 | } /* end parse_cmdline_early() */ | 748 | } /* end parse_cmdline_early() */ |
748 | 749 | ||
749 | /*****************************************************************************/ | 750 | /*****************************************************************************/ |
750 | /* | 751 | /* |
751 | * | 752 | * |
752 | */ | 753 | */ |
753 | void __init setup_arch(char **cmdline_p) | 754 | void __init setup_arch(char **cmdline_p) |
754 | { | 755 | { |
755 | #ifdef CONFIG_MMU | 756 | #ifdef CONFIG_MMU |
756 | printk("Linux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n"); | 757 | printk("Linux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n"); |
757 | #else | 758 | #else |
758 | printk("uClinux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n"); | 759 | printk("uClinux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n"); |
759 | #endif | 760 | #endif |
760 | 761 | ||
761 | memcpy(boot_command_line, redboot_command_line, COMMAND_LINE_SIZE); | 762 | memcpy(boot_command_line, redboot_command_line, COMMAND_LINE_SIZE); |
762 | 763 | ||
763 | determine_cpu(); | 764 | determine_cpu(); |
764 | determine_clocks(1); | 765 | determine_clocks(1); |
765 | 766 | ||
766 | /* For printk-directly-beats-on-serial-hardware hack */ | 767 | /* For printk-directly-beats-on-serial-hardware hack */ |
767 | console_set_baud(115200); | 768 | console_set_baud(115200); |
768 | #ifdef CONFIG_GDBSTUB | 769 | #ifdef CONFIG_GDBSTUB |
769 | gdbstub_set_baud(115200); | 770 | gdbstub_set_baud(115200); |
770 | #endif | 771 | #endif |
771 | 772 | ||
772 | #ifdef CONFIG_RESERVE_DMA_COHERENT | 773 | #ifdef CONFIG_RESERVE_DMA_COHERENT |
773 | reserve_dma_coherent(); | 774 | reserve_dma_coherent(); |
774 | #endif | 775 | #endif |
775 | dump_memory_map(); | 776 | dump_memory_map(); |
776 | 777 | ||
777 | #ifdef CONFIG_MB93090_MB00 | 778 | #ifdef CONFIG_MB93090_MB00 |
778 | if (mb93090_mb00_detected) | 779 | if (mb93090_mb00_detected) |
779 | mb93090_display(); | 780 | mb93090_display(); |
780 | #endif | 781 | #endif |
781 | 782 | ||
782 | /* register those serial ports that are available */ | 783 | /* register those serial ports that are available */ |
783 | #ifdef CONFIG_FRV_ONCPU_SERIAL | 784 | #ifdef CONFIG_FRV_ONCPU_SERIAL |
784 | #ifndef CONFIG_GDBSTUB_UART0 | 785 | #ifndef CONFIG_GDBSTUB_UART0 |
785 | __reg(UART0_BASE + UART_IER * 8) = 0; | 786 | __reg(UART0_BASE + UART_IER * 8) = 0; |
786 | early_serial_setup(&__frv_uart0); | 787 | early_serial_setup(&__frv_uart0); |
787 | #endif | 788 | #endif |
788 | #ifndef CONFIG_GDBSTUB_UART1 | 789 | #ifndef CONFIG_GDBSTUB_UART1 |
789 | __reg(UART1_BASE + UART_IER * 8) = 0; | 790 | __reg(UART1_BASE + UART_IER * 8) = 0; |
790 | early_serial_setup(&__frv_uart1); | 791 | early_serial_setup(&__frv_uart1); |
791 | #endif | 792 | #endif |
792 | #endif | 793 | #endif |
793 | 794 | ||
794 | /* deal with the command line - RedBoot may have passed one to the kernel */ | 795 | /* deal with the command line - RedBoot may have passed one to the kernel */ |
795 | memcpy(command_line, boot_command_line, sizeof(command_line)); | 796 | memcpy(command_line, boot_command_line, sizeof(command_line)); |
796 | *cmdline_p = &command_line[0]; | 797 | *cmdline_p = &command_line[0]; |
797 | parse_cmdline_early(command_line); | 798 | parse_cmdline_early(command_line); |
798 | 799 | ||
799 | /* set up the memory description | 800 | /* set up the memory description |
800 | * - by now the stack is part of the init task */ | 801 | * - by now the stack is part of the init task */ |
801 | printk("Memory %08lx-%08lx\n", memory_start, memory_end); | 802 | printk("Memory %08lx-%08lx\n", memory_start, memory_end); |
802 | 803 | ||
803 | BUG_ON(memory_start == memory_end); | 804 | BUG_ON(memory_start == memory_end); |
804 | 805 | ||
805 | init_mm.start_code = (unsigned long) &_stext; | 806 | init_mm.start_code = (unsigned long) &_stext; |
806 | init_mm.end_code = (unsigned long) &_etext; | 807 | init_mm.end_code = (unsigned long) &_etext; |
807 | init_mm.end_data = (unsigned long) &_edata; | 808 | init_mm.end_data = (unsigned long) &_edata; |
808 | #if 0 /* DAVIDM - don't set brk just incase someone decides to use it */ | 809 | #if 0 /* DAVIDM - don't set brk just incase someone decides to use it */ |
809 | init_mm.brk = (unsigned long) &_end; | 810 | init_mm.brk = (unsigned long) &_end; |
810 | #else | 811 | #else |
811 | init_mm.brk = (unsigned long) 0; | 812 | init_mm.brk = (unsigned long) 0; |
812 | #endif | 813 | #endif |
813 | 814 | ||
814 | #ifdef DEBUG | 815 | #ifdef DEBUG |
815 | printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n", | 816 | printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n", |
816 | (int) &_stext, (int) &_etext, | 817 | (int) &_stext, (int) &_etext, |
817 | (int) &_sdata, (int) &_edata, | 818 | (int) &_sdata, (int) &_edata, |
818 | (int) &_sbss, (int) &_ebss); | 819 | (int) &_sbss, (int) &_ebss); |
819 | #endif | 820 | #endif |
820 | 821 | ||
821 | #ifdef CONFIG_VT | 822 | #ifdef CONFIG_VT |
822 | #if defined(CONFIG_VGA_CONSOLE) | 823 | #if defined(CONFIG_VGA_CONSOLE) |
823 | conswitchp = &vga_con; | 824 | conswitchp = &vga_con; |
824 | #elif defined(CONFIG_DUMMY_CONSOLE) | 825 | #elif defined(CONFIG_DUMMY_CONSOLE) |
825 | conswitchp = &dummy_con; | 826 | conswitchp = &dummy_con; |
826 | #endif | 827 | #endif |
827 | #endif | 828 | #endif |
828 | 829 | ||
829 | #ifdef CONFIG_MMU | 830 | #ifdef CONFIG_MMU |
830 | setup_linux_memory(); | 831 | setup_linux_memory(); |
831 | #else | 832 | #else |
832 | setup_uclinux_memory(); | 833 | setup_uclinux_memory(); |
833 | #endif | 834 | #endif |
834 | 835 | ||
835 | /* get kmalloc into gear */ | 836 | /* get kmalloc into gear */ |
836 | paging_init(); | 837 | paging_init(); |
837 | 838 | ||
838 | /* init DMA */ | 839 | /* init DMA */ |
839 | frv_dma_init(); | 840 | frv_dma_init(); |
840 | #ifdef DEBUG | 841 | #ifdef DEBUG |
841 | printk("Done setup_arch\n"); | 842 | printk("Done setup_arch\n"); |
842 | #endif | 843 | #endif |
843 | 844 | ||
844 | /* start the decrement timer running */ | 845 | /* start the decrement timer running */ |
845 | // asm volatile("movgs %0,timerd" :: "r"(10000000)); | 846 | // asm volatile("movgs %0,timerd" :: "r"(10000000)); |
846 | // __set_HSR(0, __get_HSR(0) | HSR0_ETMD); | 847 | // __set_HSR(0, __get_HSR(0) | HSR0_ETMD); |
847 | 848 | ||
848 | } /* end setup_arch() */ | 849 | } /* end setup_arch() */ |
849 | 850 | ||
850 | #if 0 | 851 | #if 0 |
851 | /*****************************************************************************/ | 852 | /*****************************************************************************/ |
852 | /* | 853 | /* |
853 | * | 854 | * |
854 | */ | 855 | */ |
855 | static int __devinit setup_arch_serial(void) | 856 | static int __devinit setup_arch_serial(void) |
856 | { | 857 | { |
857 | /* register those serial ports that are available */ | 858 | /* register those serial ports that are available */ |
858 | #ifndef CONFIG_GDBSTUB_UART0 | 859 | #ifndef CONFIG_GDBSTUB_UART0 |
859 | early_serial_setup(&__frv_uart0); | 860 | early_serial_setup(&__frv_uart0); |
860 | #endif | 861 | #endif |
861 | #ifndef CONFIG_GDBSTUB_UART1 | 862 | #ifndef CONFIG_GDBSTUB_UART1 |
862 | early_serial_setup(&__frv_uart1); | 863 | early_serial_setup(&__frv_uart1); |
863 | #endif | 864 | #endif |
864 | 865 | ||
865 | return 0; | 866 | return 0; |
866 | } /* end setup_arch_serial() */ | 867 | } /* end setup_arch_serial() */ |
867 | 868 | ||
868 | late_initcall(setup_arch_serial); | 869 | late_initcall(setup_arch_serial); |
869 | #endif | 870 | #endif |
870 | 871 | ||
871 | /*****************************************************************************/ | 872 | /*****************************************************************************/ |
872 | /* | 873 | /* |
873 | * set up the memory map for normal MMU linux | 874 | * set up the memory map for normal MMU linux |
874 | */ | 875 | */ |
875 | #ifdef CONFIG_MMU | 876 | #ifdef CONFIG_MMU |
876 | static void __init setup_linux_memory(void) | 877 | static void __init setup_linux_memory(void) |
877 | { | 878 | { |
878 | unsigned long bootmap_size, low_top_pfn, kstart, kend, high_mem; | 879 | unsigned long bootmap_size, low_top_pfn, kstart, kend, high_mem; |
879 | 880 | ||
880 | kstart = (unsigned long) &__kernel_image_start - PAGE_OFFSET; | 881 | kstart = (unsigned long) &__kernel_image_start - PAGE_OFFSET; |
881 | kend = (unsigned long) &__kernel_image_end - PAGE_OFFSET; | 882 | kend = (unsigned long) &__kernel_image_end - PAGE_OFFSET; |
882 | 883 | ||
883 | kstart = kstart & PAGE_MASK; | 884 | kstart = kstart & PAGE_MASK; |
884 | kend = (kend + PAGE_SIZE - 1) & PAGE_MASK; | 885 | kend = (kend + PAGE_SIZE - 1) & PAGE_MASK; |
885 | 886 | ||
886 | /* give all the memory to the bootmap allocator, tell it to put the | 887 | /* give all the memory to the bootmap allocator, tell it to put the |
887 | * boot mem_map immediately following the kernel image | 888 | * boot mem_map immediately following the kernel image |
888 | */ | 889 | */ |
889 | bootmap_size = init_bootmem_node(NODE_DATA(0), | 890 | bootmap_size = init_bootmem_node(NODE_DATA(0), |
890 | kend >> PAGE_SHIFT, /* map addr */ | 891 | kend >> PAGE_SHIFT, /* map addr */ |
891 | memory_start >> PAGE_SHIFT, /* start of RAM */ | 892 | memory_start >> PAGE_SHIFT, /* start of RAM */ |
892 | memory_end >> PAGE_SHIFT /* end of RAM */ | 893 | memory_end >> PAGE_SHIFT /* end of RAM */ |
893 | ); | 894 | ); |
894 | 895 | ||
895 | /* pass the memory that the kernel can immediately use over to the bootmem allocator */ | 896 | /* pass the memory that the kernel can immediately use over to the bootmem allocator */ |
896 | max_mapnr = num_physpages = (memory_end - memory_start) >> PAGE_SHIFT; | 897 | max_mapnr = num_physpages = (memory_end - memory_start) >> PAGE_SHIFT; |
897 | low_top_pfn = (KERNEL_LOWMEM_END - KERNEL_LOWMEM_START) >> PAGE_SHIFT; | 898 | low_top_pfn = (KERNEL_LOWMEM_END - KERNEL_LOWMEM_START) >> PAGE_SHIFT; |
898 | high_mem = 0; | 899 | high_mem = 0; |
899 | 900 | ||
900 | if (num_physpages > low_top_pfn) { | 901 | if (num_physpages > low_top_pfn) { |
901 | #ifdef CONFIG_HIGHMEM | 902 | #ifdef CONFIG_HIGHMEM |
902 | high_mem = num_physpages - low_top_pfn; | 903 | high_mem = num_physpages - low_top_pfn; |
903 | #else | 904 | #else |
904 | max_mapnr = num_physpages = low_top_pfn; | 905 | max_mapnr = num_physpages = low_top_pfn; |
905 | #endif | 906 | #endif |
906 | } | 907 | } |
907 | else { | 908 | else { |
908 | low_top_pfn = num_physpages; | 909 | low_top_pfn = num_physpages; |
909 | } | 910 | } |
910 | 911 | ||
911 | min_low_pfn = memory_start >> PAGE_SHIFT; | 912 | min_low_pfn = memory_start >> PAGE_SHIFT; |
912 | max_low_pfn = low_top_pfn; | 913 | max_low_pfn = low_top_pfn; |
913 | max_pfn = memory_end >> PAGE_SHIFT; | 914 | max_pfn = memory_end >> PAGE_SHIFT; |
914 | 915 | ||
915 | num_mappedpages = low_top_pfn; | 916 | num_mappedpages = low_top_pfn; |
916 | 917 | ||
917 | printk(KERN_NOTICE "%ldMB LOWMEM available.\n", low_top_pfn >> (20 - PAGE_SHIFT)); | 918 | printk(KERN_NOTICE "%ldMB LOWMEM available.\n", low_top_pfn >> (20 - PAGE_SHIFT)); |
918 | 919 | ||
919 | free_bootmem(memory_start, low_top_pfn << PAGE_SHIFT); | 920 | free_bootmem(memory_start, low_top_pfn << PAGE_SHIFT); |
920 | 921 | ||
921 | #ifdef CONFIG_HIGHMEM | 922 | #ifdef CONFIG_HIGHMEM |
922 | if (high_mem) | 923 | if (high_mem) |
923 | printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", high_mem >> (20 - PAGE_SHIFT)); | 924 | printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", high_mem >> (20 - PAGE_SHIFT)); |
924 | #endif | 925 | #endif |
925 | 926 | ||
926 | /* take back the memory occupied by the kernel image and the bootmem alloc map */ | 927 | /* take back the memory occupied by the kernel image and the bootmem alloc map */ |
927 | reserve_bootmem(kstart, kend - kstart + bootmap_size); | 928 | reserve_bootmem(kstart, kend - kstart + bootmap_size); |
928 | 929 | ||
929 | /* reserve the memory occupied by the initial ramdisk */ | 930 | /* reserve the memory occupied by the initial ramdisk */ |
930 | #ifdef CONFIG_BLK_DEV_INITRD | 931 | #ifdef CONFIG_BLK_DEV_INITRD |
931 | if (LOADER_TYPE && INITRD_START) { | 932 | if (LOADER_TYPE && INITRD_START) { |
932 | if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) { | 933 | if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) { |
933 | reserve_bootmem(INITRD_START, INITRD_SIZE); | 934 | reserve_bootmem(INITRD_START, INITRD_SIZE); |
934 | initrd_start = INITRD_START + PAGE_OFFSET; | 935 | initrd_start = INITRD_START + PAGE_OFFSET; |
935 | initrd_end = initrd_start + INITRD_SIZE; | 936 | initrd_end = initrd_start + INITRD_SIZE; |
936 | } | 937 | } |
937 | else { | 938 | else { |
938 | printk(KERN_ERR | 939 | printk(KERN_ERR |
939 | "initrd extends beyond end of memory (0x%08lx > 0x%08lx)\n" | 940 | "initrd extends beyond end of memory (0x%08lx > 0x%08lx)\n" |
940 | "disabling initrd\n", | 941 | "disabling initrd\n", |
941 | INITRD_START + INITRD_SIZE, | 942 | INITRD_START + INITRD_SIZE, |
942 | low_top_pfn << PAGE_SHIFT); | 943 | low_top_pfn << PAGE_SHIFT); |
943 | initrd_start = 0; | 944 | initrd_start = 0; |
944 | } | 945 | } |
945 | } | 946 | } |
946 | #endif | 947 | #endif |
947 | 948 | ||
948 | } /* end setup_linux_memory() */ | 949 | } /* end setup_linux_memory() */ |
949 | #endif | 950 | #endif |
950 | 951 | ||
951 | /*****************************************************************************/ | 952 | /*****************************************************************************/ |
952 | /* | 953 | /* |
953 | * set up the memory map for uClinux | 954 | * set up the memory map for uClinux |
954 | */ | 955 | */ |
955 | #ifndef CONFIG_MMU | 956 | #ifndef CONFIG_MMU |
956 | static void __init setup_uclinux_memory(void) | 957 | static void __init setup_uclinux_memory(void) |
957 | { | 958 | { |
958 | #ifdef CONFIG_PROTECT_KERNEL | 959 | #ifdef CONFIG_PROTECT_KERNEL |
959 | unsigned long dampr; | 960 | unsigned long dampr; |
960 | #endif | 961 | #endif |
961 | unsigned long kend; | 962 | unsigned long kend; |
962 | int bootmap_size; | 963 | int bootmap_size; |
963 | 964 | ||
964 | kend = (unsigned long) &__kernel_image_end; | 965 | kend = (unsigned long) &__kernel_image_end; |
965 | kend = (kend + PAGE_SIZE - 1) & PAGE_MASK; | 966 | kend = (kend + PAGE_SIZE - 1) & PAGE_MASK; |
966 | 967 | ||
967 | /* give all the memory to the bootmap allocator, tell it to put the | 968 | /* give all the memory to the bootmap allocator, tell it to put the |
968 | * boot mem_map immediately following the kernel image | 969 | * boot mem_map immediately following the kernel image |
969 | */ | 970 | */ |
970 | bootmap_size = init_bootmem_node(NODE_DATA(0), | 971 | bootmap_size = init_bootmem_node(NODE_DATA(0), |
971 | kend >> PAGE_SHIFT, /* map addr */ | 972 | kend >> PAGE_SHIFT, /* map addr */ |
972 | memory_start >> PAGE_SHIFT, /* start of RAM */ | 973 | memory_start >> PAGE_SHIFT, /* start of RAM */ |
973 | memory_end >> PAGE_SHIFT /* end of RAM */ | 974 | memory_end >> PAGE_SHIFT /* end of RAM */ |
974 | ); | 975 | ); |
975 | 976 | ||
976 | /* free all the usable memory */ | 977 | /* free all the usable memory */ |
977 | free_bootmem(memory_start, memory_end - memory_start); | 978 | free_bootmem(memory_start, memory_end - memory_start); |
978 | 979 | ||
979 | high_memory = (void *) (memory_end & PAGE_MASK); | 980 | high_memory = (void *) (memory_end & PAGE_MASK); |
980 | max_mapnr = num_physpages = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT; | 981 | max_mapnr = num_physpages = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT; |
981 | 982 | ||
982 | min_low_pfn = memory_start >> PAGE_SHIFT; | 983 | min_low_pfn = memory_start >> PAGE_SHIFT; |
983 | max_low_pfn = memory_end >> PAGE_SHIFT; | 984 | max_low_pfn = memory_end >> PAGE_SHIFT; |
984 | max_pfn = max_low_pfn; | 985 | max_pfn = max_low_pfn; |
985 | 986 | ||
986 | /* now take back the bits the core kernel is occupying */ | 987 | /* now take back the bits the core kernel is occupying */ |
987 | #ifndef CONFIG_PROTECT_KERNEL | 988 | #ifndef CONFIG_PROTECT_KERNEL |
988 | reserve_bootmem(kend, bootmap_size); | 989 | reserve_bootmem(kend, bootmap_size); |
989 | reserve_bootmem((unsigned long) &__kernel_image_start, | 990 | reserve_bootmem((unsigned long) &__kernel_image_start, |
990 | kend - (unsigned long) &__kernel_image_start); | 991 | kend - (unsigned long) &__kernel_image_start); |
991 | 992 | ||
992 | #else | 993 | #else |
993 | dampr = __get_DAMPR(0); | 994 | dampr = __get_DAMPR(0); |
994 | dampr &= xAMPRx_SS; | 995 | dampr &= xAMPRx_SS; |
995 | dampr = (dampr >> 4) + 17; | 996 | dampr = (dampr >> 4) + 17; |
996 | dampr = 1 << dampr; | 997 | dampr = 1 << dampr; |
997 | 998 | ||
998 | reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr); | 999 | reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr); |
999 | #endif | 1000 | #endif |
1000 | 1001 | ||
1001 | /* reserve some memory to do uncached DMA through if requested */ | 1002 | /* reserve some memory to do uncached DMA through if requested */ |
1002 | #ifdef CONFIG_RESERVE_DMA_COHERENT | 1003 | #ifdef CONFIG_RESERVE_DMA_COHERENT |
1003 | if (dma_coherent_mem_start) | 1004 | if (dma_coherent_mem_start) |
1004 | reserve_bootmem(dma_coherent_mem_start, | 1005 | reserve_bootmem(dma_coherent_mem_start, |
1005 | dma_coherent_mem_end - dma_coherent_mem_start); | 1006 | dma_coherent_mem_end - dma_coherent_mem_start); |
1006 | #endif | 1007 | #endif |
1007 | 1008 | ||
1008 | } /* end setup_uclinux_memory() */ | 1009 | } /* end setup_uclinux_memory() */ |
1009 | #endif | 1010 | #endif |
1010 | 1011 | ||
1011 | /*****************************************************************************/ | 1012 | /*****************************************************************************/ |
1012 | /* | 1013 | /* |
1013 | * get CPU information for use by procfs | 1014 | * get CPU information for use by procfs |
1014 | */ | 1015 | */ |
1015 | static int show_cpuinfo(struct seq_file *m, void *v) | 1016 | static int show_cpuinfo(struct seq_file *m, void *v) |
1016 | { | 1017 | { |
1017 | const char *gr, *fr, *fm, *fp, *cm, *nem, *ble; | 1018 | const char *gr, *fr, *fm, *fp, *cm, *nem, *ble; |
1018 | #ifdef CONFIG_PM | 1019 | #ifdef CONFIG_PM |
1019 | const char *sep; | 1020 | const char *sep; |
1020 | #endif | 1021 | #endif |
1021 | 1022 | ||
1022 | gr = cpu_hsr0_all & HSR0_GRHE ? "gr0-63" : "gr0-31"; | 1023 | gr = cpu_hsr0_all & HSR0_GRHE ? "gr0-63" : "gr0-31"; |
1023 | fr = cpu_hsr0_all & HSR0_FRHE ? "fr0-63" : "fr0-31"; | 1024 | fr = cpu_hsr0_all & HSR0_FRHE ? "fr0-63" : "fr0-31"; |
1024 | fm = cpu_psr_all & PSR_EM ? ", Media" : ""; | 1025 | fm = cpu_psr_all & PSR_EM ? ", Media" : ""; |
1025 | fp = cpu_psr_all & PSR_EF ? ", FPU" : ""; | 1026 | fp = cpu_psr_all & PSR_EF ? ", FPU" : ""; |
1026 | cm = cpu_psr_all & PSR_CM ? ", CCCR" : ""; | 1027 | cm = cpu_psr_all & PSR_CM ? ", CCCR" : ""; |
1027 | nem = cpu_psr_all & PSR_NEM ? ", NE" : ""; | 1028 | nem = cpu_psr_all & PSR_NEM ? ", NE" : ""; |
1028 | ble = cpu_psr_all & PSR_BE ? "BE" : "LE"; | 1029 | ble = cpu_psr_all & PSR_BE ? "BE" : "LE"; |
1029 | 1030 | ||
1030 | seq_printf(m, | 1031 | seq_printf(m, |
1031 | "CPU-Series:\t%s\n" | 1032 | "CPU-Series:\t%s\n" |
1032 | "CPU-Core:\t%s, %s, %s%s%s\n" | 1033 | "CPU-Core:\t%s, %s, %s%s%s\n" |
1033 | "CPU:\t\t%s\n" | 1034 | "CPU:\t\t%s\n" |
1034 | "MMU:\t\t%s\n" | 1035 | "MMU:\t\t%s\n" |
1035 | "FP-Media:\t%s%s%s\n" | 1036 | "FP-Media:\t%s%s%s\n" |
1036 | "System:\t\t%s", | 1037 | "System:\t\t%s", |
1037 | cpu_series, | 1038 | cpu_series, |
1038 | cpu_core, gr, ble, cm, nem, | 1039 | cpu_core, gr, ble, cm, nem, |
1039 | cpu_silicon, | 1040 | cpu_silicon, |
1040 | cpu_mmu, | 1041 | cpu_mmu, |
1041 | fr, fm, fp, | 1042 | fr, fm, fp, |
1042 | cpu_system); | 1043 | cpu_system); |
1043 | 1044 | ||
1044 | if (cpu_board1) | 1045 | if (cpu_board1) |
1045 | seq_printf(m, ", %s", cpu_board1); | 1046 | seq_printf(m, ", %s", cpu_board1); |
1046 | 1047 | ||
1047 | if (cpu_board2) | 1048 | if (cpu_board2) |
1048 | seq_printf(m, ", %s", cpu_board2); | 1049 | seq_printf(m, ", %s", cpu_board2); |
1049 | 1050 | ||
1050 | seq_printf(m, "\n"); | 1051 | seq_printf(m, "\n"); |
1051 | 1052 | ||
1052 | #ifdef CONFIG_PM | 1053 | #ifdef CONFIG_PM |
1053 | seq_printf(m, "PM-Controls:"); | 1054 | seq_printf(m, "PM-Controls:"); |
1054 | sep = "\t"; | 1055 | sep = "\t"; |
1055 | 1056 | ||
1056 | if (clock_bits_settable & CLOCK_BIT_CMODE) { | 1057 | if (clock_bits_settable & CLOCK_BIT_CMODE) { |
1057 | seq_printf(m, "%scmode=0x%04hx", sep, clock_cmodes_permitted); | 1058 | seq_printf(m, "%scmode=0x%04hx", sep, clock_cmodes_permitted); |
1058 | sep = ", "; | 1059 | sep = ", "; |
1059 | } | 1060 | } |
1060 | 1061 | ||
1061 | if (clock_bits_settable & CLOCK_BIT_CM) { | 1062 | if (clock_bits_settable & CLOCK_BIT_CM) { |
1062 | seq_printf(m, "%scm=0x%lx", sep, clock_bits_settable & CLOCK_BIT_CM); | 1063 | seq_printf(m, "%scm=0x%lx", sep, clock_bits_settable & CLOCK_BIT_CM); |
1063 | sep = ", "; | 1064 | sep = ", "; |
1064 | } | 1065 | } |
1065 | 1066 | ||
1066 | if (clock_bits_settable & CLOCK_BIT_P0) { | 1067 | if (clock_bits_settable & CLOCK_BIT_P0) { |
1067 | seq_printf(m, "%sp0=0x3", sep); | 1068 | seq_printf(m, "%sp0=0x3", sep); |
1068 | sep = ", "; | 1069 | sep = ", "; |
1069 | } | 1070 | } |
1070 | 1071 | ||
1071 | seq_printf(m, "%ssuspend=0x22\n", sep); | 1072 | seq_printf(m, "%ssuspend=0x22\n", sep); |
1072 | #endif | 1073 | #endif |
1073 | 1074 | ||
1074 | seq_printf(m, | 1075 | seq_printf(m, |
1075 | "PM-Status:\tcmode=%d, cm=%d, p0=%d\n", | 1076 | "PM-Status:\tcmode=%d, cm=%d, p0=%d\n", |
1076 | clock_cmode_current, clock_cm_current, clock_p0_current); | 1077 | clock_cmode_current, clock_cm_current, clock_p0_current); |
1077 | 1078 | ||
1078 | #define print_clk(TAG, VAR) \ | 1079 | #define print_clk(TAG, VAR) \ |
1079 | seq_printf(m, "Clock-" TAG ":\t%lu.%2.2lu MHz\n", VAR / 1000000, (VAR / 10000) % 100) | 1080 | seq_printf(m, "Clock-" TAG ":\t%lu.%2.2lu MHz\n", VAR / 1000000, (VAR / 10000) % 100) |
1080 | 1081 | ||
1081 | print_clk("In", __clkin_clock_speed_HZ); | 1082 | print_clk("In", __clkin_clock_speed_HZ); |
1082 | print_clk("Core", __core_clock_speed_HZ); | 1083 | print_clk("Core", __core_clock_speed_HZ); |
1083 | print_clk("SDRAM", __sdram_clock_speed_HZ); | 1084 | print_clk("SDRAM", __sdram_clock_speed_HZ); |
1084 | print_clk("CBus", __core_bus_clock_speed_HZ); | 1085 | print_clk("CBus", __core_bus_clock_speed_HZ); |
1085 | print_clk("Res", __res_bus_clock_speed_HZ); | 1086 | print_clk("Res", __res_bus_clock_speed_HZ); |
1086 | print_clk("Ext", __ext_bus_clock_speed_HZ); | 1087 | print_clk("Ext", __ext_bus_clock_speed_HZ); |
1087 | print_clk("DSU", __dsu_clock_speed_HZ); | 1088 | print_clk("DSU", __dsu_clock_speed_HZ); |
1088 | 1089 | ||
1089 | seq_printf(m, | 1090 | seq_printf(m, |
1090 | "BogoMips:\t%lu.%02lu\n", | 1091 | "BogoMips:\t%lu.%02lu\n", |
1091 | (loops_per_jiffy * HZ) / 500000, ((loops_per_jiffy * HZ) / 5000) % 100); | 1092 | (loops_per_jiffy * HZ) / 500000, ((loops_per_jiffy * HZ) / 5000) % 100); |
1092 | 1093 | ||
1093 | return 0; | 1094 | return 0; |
1094 | } /* end show_cpuinfo() */ | 1095 | } /* end show_cpuinfo() */ |
1095 | 1096 | ||
1096 | static void *c_start(struct seq_file *m, loff_t *pos) | 1097 | static void *c_start(struct seq_file *m, loff_t *pos) |
1097 | { | 1098 | { |
1098 | return *pos < NR_CPUS ? (void *) 0x12345678 : NULL; | 1099 | return *pos < NR_CPUS ? (void *) 0x12345678 : NULL; |
1099 | } | 1100 | } |
1100 | 1101 | ||
1101 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | 1102 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) |
1102 | { | 1103 | { |
1103 | ++*pos; | 1104 | ++*pos; |
1104 | return c_start(m, pos); | 1105 | return c_start(m, pos); |
1105 | } | 1106 | } |
1106 | 1107 | ||
1107 | static void c_stop(struct seq_file *m, void *v) | 1108 | static void c_stop(struct seq_file *m, void *v) |
1108 | { | 1109 | { |
1109 | } | 1110 | } |
1110 | 1111 | ||
1111 | struct seq_operations cpuinfo_op = { | 1112 | struct seq_operations cpuinfo_op = { |
1112 | .start = c_start, | 1113 | .start = c_start, |
1113 | .next = c_next, | 1114 | .next = c_next, |
1114 | .stop = c_stop, | 1115 | .stop = c_stop, |
1115 | .show = show_cpuinfo, | 1116 | .show = show_cpuinfo, |
1116 | }; | 1117 | }; |
1117 | 1118 | ||
1118 | void arch_gettod(int *year, int *mon, int *day, int *hour, | 1119 | void arch_gettod(int *year, int *mon, int *day, int *hour, |
1119 | int *min, int *sec) | 1120 | int *min, int *sec) |
1120 | { | 1121 | { |
1121 | *year = *mon = *day = *hour = *min = *sec = 0; | 1122 | *year = *mon = *day = *hour = *min = *sec = 0; |
1122 | } | 1123 | } |
1123 | 1124 | ||
1124 | /*****************************************************************************/ | 1125 | /*****************************************************************************/ |
1125 | /* | 1126 | /* |
1126 | * | 1127 | * |
1127 | */ | 1128 | */ |
1128 | #ifdef CONFIG_MB93090_MB00 | 1129 | #ifdef CONFIG_MB93090_MB00 |
1129 | static void __init mb93090_sendlcdcmd(uint32_t cmd) | 1130 | static void __init mb93090_sendlcdcmd(uint32_t cmd) |
1130 | { | 1131 | { |
1131 | unsigned long base = __addr_LCD(); | 1132 | unsigned long base = __addr_LCD(); |
1132 | int loop; | 1133 | int loop; |
1133 | 1134 | ||
1134 | /* request reading of the busy flag */ | 1135 | /* request reading of the busy flag */ |
1135 | __set_LCD(base, LCD_CMD_READ_BUSY); | 1136 | __set_LCD(base, LCD_CMD_READ_BUSY); |
1136 | __set_LCD(base, LCD_CMD_READ_BUSY & ~LCD_E); | 1137 | __set_LCD(base, LCD_CMD_READ_BUSY & ~LCD_E); |
1137 | 1138 | ||
1138 | /* wait for the busy flag to become clear */ | 1139 | /* wait for the busy flag to become clear */ |
1139 | for (loop = 10000; loop > 0; loop--) | 1140 | for (loop = 10000; loop > 0; loop--) |
1140 | if (!(__get_LCD(base) & 0x80)) | 1141 | if (!(__get_LCD(base) & 0x80)) |
1141 | break; | 1142 | break; |
1142 | 1143 | ||
1143 | /* send the command */ | 1144 | /* send the command */ |
1144 | __set_LCD(base, cmd); | 1145 | __set_LCD(base, cmd); |
1145 | __set_LCD(base, cmd & ~LCD_E); | 1146 | __set_LCD(base, cmd & ~LCD_E); |
1146 | 1147 | ||
1147 | } /* end mb93090_sendlcdcmd() */ | 1148 | } /* end mb93090_sendlcdcmd() */ |
1148 | 1149 | ||
1149 | /*****************************************************************************/ | 1150 | /*****************************************************************************/ |
1150 | /* | 1151 | /* |
1151 | * write to the MB93090 LEDs and LCD | 1152 | * write to the MB93090 LEDs and LCD |
1152 | */ | 1153 | */ |
1153 | static void __init mb93090_display(void) | 1154 | static void __init mb93090_display(void) |
1154 | { | 1155 | { |
1155 | const char *p; | 1156 | const char *p; |
1156 | 1157 | ||
1157 | __set_LEDS(0); | 1158 | __set_LEDS(0); |
1158 | 1159 | ||
1159 | /* set up the LCD */ | 1160 | /* set up the LCD */ |
1160 | mb93090_sendlcdcmd(LCD_CMD_CLEAR); | 1161 | mb93090_sendlcdcmd(LCD_CMD_CLEAR); |
1161 | mb93090_sendlcdcmd(LCD_CMD_FUNCSET(1,1,0)); | 1162 | mb93090_sendlcdcmd(LCD_CMD_FUNCSET(1,1,0)); |
1162 | mb93090_sendlcdcmd(LCD_CMD_ON(0,0)); | 1163 | mb93090_sendlcdcmd(LCD_CMD_ON(0,0)); |
1163 | mb93090_sendlcdcmd(LCD_CMD_HOME); | 1164 | mb93090_sendlcdcmd(LCD_CMD_HOME); |
1164 | 1165 | ||
1165 | mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(0)); | 1166 | mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(0)); |
1166 | for (p = mb93090_banner; *p; p++) | 1167 | for (p = mb93090_banner; *p; p++) |
1167 | mb93090_sendlcdcmd(LCD_DATA_WRITE(*p)); | 1168 | mb93090_sendlcdcmd(LCD_DATA_WRITE(*p)); |
1168 | 1169 | ||
1169 | mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(64)); | 1170 | mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(64)); |
1170 | for (p = mb93090_version; *p; p++) | 1171 | for (p = mb93090_version; *p; p++) |
1171 | mb93090_sendlcdcmd(LCD_DATA_WRITE(*p)); | 1172 | mb93090_sendlcdcmd(LCD_DATA_WRITE(*p)); |
1172 | 1173 | ||
1173 | } /* end mb93090_display() */ | 1174 | } /* end mb93090_display() */ |
1174 | 1175 | ||
1175 | #endif // CONFIG_MB93090_MB00 | 1176 | #endif // CONFIG_MB93090_MB00 |
1176 | 1177 |
arch/mips/basler/excite/excite_setup.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2004, 2005 by Basler Vision Technologies AG | 2 | * Copyright (C) 2004, 2005 by Basler Vision Technologies AG |
3 | * Author: Thomas Koeller <thomas.koeller@baslerweb.com> | 3 | * Author: Thomas Koeller <thomas.koeller@baslerweb.com> |
4 | * Based on the PMC-Sierra Yosemite board support by Ralf Baechle and | 4 | * Based on the PMC-Sierra Yosemite board support by Ralf Baechle and |
5 | * Manish Lachwani. | 5 | * Manish Lachwani. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | #include <linux/serial_core.h> | 27 | #include <linux/serial_core.h> |
28 | #include <linux/serial.h> | 28 | #include <linux/serial.h> |
29 | #include <linux/serial_8250.h> | ||
29 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
30 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
31 | #include <asm/bootinfo.h> | 32 | #include <asm/bootinfo.h> |
32 | #include <asm/mipsregs.h> | 33 | #include <asm/mipsregs.h> |
33 | #include <asm/pgtable-32.h> | 34 | #include <asm/pgtable-32.h> |
34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
35 | #include <asm/time.h> | 36 | #include <asm/time.h> |
36 | #include <asm/rm9k-ocd.h> | 37 | #include <asm/rm9k-ocd.h> |
37 | 38 | ||
38 | #include <excite.h> | 39 | #include <excite.h> |
39 | 40 | ||
40 | #define TITAN_UART_CLK 25000000 | 41 | #define TITAN_UART_CLK 25000000 |
41 | 42 | ||
42 | #if 1 | 43 | #if 1 |
43 | /* normal serial port assignment */ | 44 | /* normal serial port assignment */ |
44 | #define REGBASE_SER0 0x0208 | 45 | #define REGBASE_SER0 0x0208 |
45 | #define REGBASE_SER1 0x0238 | 46 | #define REGBASE_SER1 0x0238 |
46 | #define MASK_SER0 0x1 | 47 | #define MASK_SER0 0x1 |
47 | #define MASK_SER1 0x2 | 48 | #define MASK_SER1 0x2 |
48 | #else | 49 | #else |
49 | /* serial ports swapped */ | 50 | /* serial ports swapped */ |
50 | #define REGBASE_SER0 0x0238 | 51 | #define REGBASE_SER0 0x0238 |
51 | #define REGBASE_SER1 0x0208 | 52 | #define REGBASE_SER1 0x0208 |
52 | #define MASK_SER0 0x2 | 53 | #define MASK_SER0 0x2 |
53 | #define MASK_SER1 0x1 | 54 | #define MASK_SER1 0x1 |
54 | #endif | 55 | #endif |
55 | 56 | ||
56 | unsigned long memsize; | 57 | unsigned long memsize; |
57 | char modetty[30]; | 58 | char modetty[30]; |
58 | unsigned int titan_irq = TITAN_IRQ; | 59 | unsigned int titan_irq = TITAN_IRQ; |
59 | static void __iomem * ctl_regs; | 60 | static void __iomem * ctl_regs; |
60 | u32 unit_id; | 61 | u32 unit_id; |
61 | 62 | ||
62 | volatile void __iomem * const ocd_base = (void *) (EXCITE_ADDR_OCD); | 63 | volatile void __iomem * const ocd_base = (void *) (EXCITE_ADDR_OCD); |
63 | volatile void __iomem * const titan_base = (void *) (EXCITE_ADDR_TITAN); | 64 | volatile void __iomem * const titan_base = (void *) (EXCITE_ADDR_TITAN); |
64 | 65 | ||
65 | /* Protect access to shared GPI registers */ | 66 | /* Protect access to shared GPI registers */ |
66 | DEFINE_SPINLOCK(titan_lock); | 67 | DEFINE_SPINLOCK(titan_lock); |
67 | int titan_irqflags; | 68 | int titan_irqflags; |
68 | 69 | ||
69 | 70 | ||
70 | static void excite_timer_init(void) | 71 | static void excite_timer_init(void) |
71 | { | 72 | { |
72 | const u32 modebit5 = ocd_readl(0x00e4); | 73 | const u32 modebit5 = ocd_readl(0x00e4); |
73 | unsigned int | 74 | unsigned int |
74 | mult = ((modebit5 >> 11) & 0x1f) + 2, | 75 | mult = ((modebit5 >> 11) & 0x1f) + 2, |
75 | div = ((modebit5 >> 16) & 0x1f) + 2; | 76 | div = ((modebit5 >> 16) & 0x1f) + 2; |
76 | 77 | ||
77 | if (div == 33) div = 1; | 78 | if (div == 33) div = 1; |
78 | mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2; | 79 | mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2; |
79 | } | 80 | } |
80 | 81 | ||
81 | void __init plat_timer_setup(struct irqaction *irq) | 82 | void __init plat_timer_setup(struct irqaction *irq) |
82 | { | 83 | { |
83 | /* The eXcite platform uses the alternate timer interrupt */ | 84 | /* The eXcite platform uses the alternate timer interrupt */ |
84 | set_c0_intcontrol(0x80); | 85 | set_c0_intcontrol(0x80); |
85 | setup_irq(TIMER_IRQ, irq); | 86 | setup_irq(TIMER_IRQ, irq); |
86 | } | 87 | } |
87 | 88 | ||
88 | static int __init excite_init_console(void) | 89 | static int __init excite_init_console(void) |
89 | { | 90 | { |
90 | #if defined(CONFIG_SERIAL_8250) | 91 | #if defined(CONFIG_SERIAL_8250) |
91 | static __initdata char serr[] = | 92 | static __initdata char serr[] = |
92 | KERN_ERR "Serial port #%u setup failed\n"; | 93 | KERN_ERR "Serial port #%u setup failed\n"; |
93 | struct uart_port up; | 94 | struct uart_port up; |
94 | 95 | ||
95 | /* Take the DUART out of reset */ | 96 | /* Take the DUART out of reset */ |
96 | titan_writel(0x00ff1cff, CPRR); | 97 | titan_writel(0x00ff1cff, CPRR); |
97 | 98 | ||
98 | #if defined(CONFIG_KGDB) || (CONFIG_SERIAL_8250_NR_UARTS > 1) | 99 | #if defined(CONFIG_KGDB) || (CONFIG_SERIAL_8250_NR_UARTS > 1) |
99 | /* Enable both ports */ | 100 | /* Enable both ports */ |
100 | titan_writel(MASK_SER0 | MASK_SER1, UACFG); | 101 | titan_writel(MASK_SER0 | MASK_SER1, UACFG); |
101 | #else | 102 | #else |
102 | /* Enable port #0 only */ | 103 | /* Enable port #0 only */ |
103 | titan_writel(MASK_SER0, UACFG); | 104 | titan_writel(MASK_SER0, UACFG); |
104 | #endif /* defined(CONFIG_KGDB) */ | 105 | #endif /* defined(CONFIG_KGDB) */ |
105 | 106 | ||
106 | /* | 107 | /* |
107 | * Set up serial port #0. Do not use autodetection; the result is | 108 | * Set up serial port #0. Do not use autodetection; the result is |
108 | * not what we want. | 109 | * not what we want. |
109 | */ | 110 | */ |
110 | memset(&up, 0, sizeof(up)); | 111 | memset(&up, 0, sizeof(up)); |
111 | up.membase = (char *) titan_addr(REGBASE_SER0); | 112 | up.membase = (char *) titan_addr(REGBASE_SER0); |
112 | up.irq = TITAN_IRQ; | 113 | up.irq = TITAN_IRQ; |
113 | up.uartclk = TITAN_UART_CLK; | 114 | up.uartclk = TITAN_UART_CLK; |
114 | up.regshift = 0; | 115 | up.regshift = 0; |
115 | up.iotype = UPIO_RM9000; | 116 | up.iotype = UPIO_RM9000; |
116 | up.type = PORT_RM9000; | 117 | up.type = PORT_RM9000; |
117 | up.flags = UPF_SHARE_IRQ; | 118 | up.flags = UPF_SHARE_IRQ; |
118 | up.line = 0; | 119 | up.line = 0; |
119 | if (early_serial_setup(&up)) | 120 | if (early_serial_setup(&up)) |
120 | printk(serr, up.line); | 121 | printk(serr, up.line); |
121 | 122 | ||
122 | #if CONFIG_SERIAL_8250_NR_UARTS > 1 | 123 | #if CONFIG_SERIAL_8250_NR_UARTS > 1 |
123 | /* And now for port #1. */ | 124 | /* And now for port #1. */ |
124 | up.membase = (char *) titan_addr(REGBASE_SER1); | 125 | up.membase = (char *) titan_addr(REGBASE_SER1); |
125 | up.line = 1; | 126 | up.line = 1; |
126 | if (early_serial_setup(&up)) | 127 | if (early_serial_setup(&up)) |
127 | printk(serr, up.line); | 128 | printk(serr, up.line); |
128 | #endif /* CONFIG_SERIAL_8250_NR_UARTS > 1 */ | 129 | #endif /* CONFIG_SERIAL_8250_NR_UARTS > 1 */ |
129 | #else | 130 | #else |
130 | /* Leave the DUART in reset */ | 131 | /* Leave the DUART in reset */ |
131 | titan_writel(0x00ff3cff, CPRR); | 132 | titan_writel(0x00ff3cff, CPRR); |
132 | #endif /* defined(CONFIG_SERIAL_8250) */ | 133 | #endif /* defined(CONFIG_SERIAL_8250) */ |
133 | 134 | ||
134 | return 0; | 135 | return 0; |
135 | } | 136 | } |
136 | 137 | ||
137 | static int __init excite_platform_init(void) | 138 | static int __init excite_platform_init(void) |
138 | { | 139 | { |
139 | unsigned int i; | 140 | unsigned int i; |
140 | unsigned char buf[3]; | 141 | unsigned char buf[3]; |
141 | u8 reg; | 142 | u8 reg; |
142 | void __iomem * dpr; | 143 | void __iomem * dpr; |
143 | 144 | ||
144 | /* BIU buffer allocations */ | 145 | /* BIU buffer allocations */ |
145 | ocd_writel(8, CPURSLMT); /* CPU */ | 146 | ocd_writel(8, CPURSLMT); /* CPU */ |
146 | titan_writel(4, CPGRWL); /* GPI / Ethernet */ | 147 | titan_writel(4, CPGRWL); /* GPI / Ethernet */ |
147 | 148 | ||
148 | /* Map control registers located in FPGA */ | 149 | /* Map control registers located in FPGA */ |
149 | ctl_regs = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_SYSCTL, 16); | 150 | ctl_regs = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_SYSCTL, 16); |
150 | if (!ctl_regs) | 151 | if (!ctl_regs) |
151 | panic("eXcite: failed to map platform control registers\n"); | 152 | panic("eXcite: failed to map platform control registers\n"); |
152 | memcpy_fromio(buf, ctl_regs + 2, ARRAY_SIZE(buf)); | 153 | memcpy_fromio(buf, ctl_regs + 2, ARRAY_SIZE(buf)); |
153 | unit_id = buf[0] | (buf[1] << 8) | (buf[2] << 16); | 154 | unit_id = buf[0] | (buf[1] << 8) | (buf[2] << 16); |
154 | 155 | ||
155 | /* Clear the reboot flag */ | 156 | /* Clear the reboot flag */ |
156 | dpr = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_DPR, 1); | 157 | dpr = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_DPR, 1); |
157 | reg = __raw_readb(dpr); | 158 | reg = __raw_readb(dpr); |
158 | __raw_writeb(reg & 0x7f, dpr); | 159 | __raw_writeb(reg & 0x7f, dpr); |
159 | iounmap(dpr); | 160 | iounmap(dpr); |
160 | 161 | ||
161 | /* Interrupt controller setup */ | 162 | /* Interrupt controller setup */ |
162 | for (i = INTP0Status0; i < INTP0Status0 + 0x80; i += 0x10) { | 163 | for (i = INTP0Status0; i < INTP0Status0 + 0x80; i += 0x10) { |
163 | ocd_writel(0x00000000, i + 0x04); | 164 | ocd_writel(0x00000000, i + 0x04); |
164 | ocd_writel(0xffffffff, i + 0x0c); | 165 | ocd_writel(0xffffffff, i + 0x0c); |
165 | } | 166 | } |
166 | ocd_writel(0x2, NMICONFIG); | 167 | ocd_writel(0x2, NMICONFIG); |
167 | 168 | ||
168 | ocd_writel(0x1 << (TITAN_MSGINT % 0x20), | 169 | ocd_writel(0x1 << (TITAN_MSGINT % 0x20), |
169 | INTP0Mask0 + (0x10 * (TITAN_MSGINT / 0x20))); | 170 | INTP0Mask0 + (0x10 * (TITAN_MSGINT / 0x20))); |
170 | ocd_writel((0x1 << (FPGA0_MSGINT % 0x20)) | 171 | ocd_writel((0x1 << (FPGA0_MSGINT % 0x20)) |
171 | | ocd_readl(INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))), | 172 | | ocd_readl(INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))), |
172 | INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))); | 173 | INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))); |
173 | ocd_writel((0x1 << (FPGA1_MSGINT % 0x20)) | 174 | ocd_writel((0x1 << (FPGA1_MSGINT % 0x20)) |
174 | | ocd_readl(INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))), | 175 | | ocd_readl(INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))), |
175 | INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))); | 176 | INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))); |
176 | ocd_writel((0x1 << (PHY_MSGINT % 0x20)) | 177 | ocd_writel((0x1 << (PHY_MSGINT % 0x20)) |
177 | | ocd_readl(INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))), | 178 | | ocd_readl(INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))), |
178 | INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))); | 179 | INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))); |
179 | #if USB_IRQ < 10 | 180 | #if USB_IRQ < 10 |
180 | ocd_writel((0x1 << (USB_MSGINT % 0x20)) | 181 | ocd_writel((0x1 << (USB_MSGINT % 0x20)) |
181 | | ocd_readl(INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))), | 182 | | ocd_readl(INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))), |
182 | INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))); | 183 | INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))); |
183 | #endif | 184 | #endif |
184 | /* Enable the packet FIFO, XDMA and XDMA arbiter */ | 185 | /* Enable the packet FIFO, XDMA and XDMA arbiter */ |
185 | titan_writel(0x00ff18ff, CPRR); | 186 | titan_writel(0x00ff18ff, CPRR); |
186 | 187 | ||
187 | /* | 188 | /* |
188 | * Set up the PADMUX. Power down all ethernet slices, | 189 | * Set up the PADMUX. Power down all ethernet slices, |
189 | * they will be powered up and configured at device startup. | 190 | * they will be powered up and configured at device startup. |
190 | */ | 191 | */ |
191 | titan_writel(0x00878206, CPTC1R); | 192 | titan_writel(0x00878206, CPTC1R); |
192 | titan_writel(0x00001100, CPTC0R); /* latch PADMUX, enable WCIMODE */ | 193 | titan_writel(0x00001100, CPTC0R); /* latch PADMUX, enable WCIMODE */ |
193 | 194 | ||
194 | /* Reset and enable the FIFO block */ | 195 | /* Reset and enable the FIFO block */ |
195 | titan_writel(0x00000001, SDRXFCIE); | 196 | titan_writel(0x00000001, SDRXFCIE); |
196 | titan_writel(0x00000001, SDTXFCIE); | 197 | titan_writel(0x00000001, SDTXFCIE); |
197 | titan_writel(0x00000100, SDRXFCIE); | 198 | titan_writel(0x00000100, SDRXFCIE); |
198 | titan_writel(0x00000000, SDTXFCIE); | 199 | titan_writel(0x00000000, SDTXFCIE); |
199 | 200 | ||
200 | /* | 201 | /* |
201 | * Initialize the common interrupt shared by all components of | 202 | * Initialize the common interrupt shared by all components of |
202 | * the GPI/Ethernet subsystem. | 203 | * the GPI/Ethernet subsystem. |
203 | */ | 204 | */ |
204 | titan_writel((EXCITE_PHYS_OCD >> 12), CPCFG0); | 205 | titan_writel((EXCITE_PHYS_OCD >> 12), CPCFG0); |
205 | titan_writel(TITAN_MSGINT, CPCFG1); | 206 | titan_writel(TITAN_MSGINT, CPCFG1); |
206 | 207 | ||
207 | /* | 208 | /* |
208 | * XDMA configuration. | 209 | * XDMA configuration. |
209 | * In order for the XDMA to be sharable among multiple drivers, | 210 | * In order for the XDMA to be sharable among multiple drivers, |
210 | * the setup must be done here in the platform. The reason is that | 211 | * the setup must be done here in the platform. The reason is that |
211 | * this setup can only be done while the XDMA is in reset. If this | 212 | * this setup can only be done while the XDMA is in reset. If this |
212 | * were done in a driver, it would interrupt all other drivers | 213 | * were done in a driver, it would interrupt all other drivers |
213 | * using the XDMA. | 214 | * using the XDMA. |
214 | */ | 215 | */ |
215 | titan_writel(0x80021dff, GXCFG); /* XDMA reset */ | 216 | titan_writel(0x80021dff, GXCFG); /* XDMA reset */ |
216 | titan_writel(0x00000000, CPXCISRA); | 217 | titan_writel(0x00000000, CPXCISRA); |
217 | titan_writel(0x00000000, CPXCISRB); /* clear pending interrupts */ | 218 | titan_writel(0x00000000, CPXCISRB); /* clear pending interrupts */ |
218 | #if defined (CONFIG_HIGHMEM) | 219 | #if defined (CONFIG_HIGHMEM) |
219 | # error change for HIGHMEM support! | 220 | # error change for HIGHMEM support! |
220 | #else | 221 | #else |
221 | titan_writel(0x00000000, GXDMADRPFX); /* buffer address prefix */ | 222 | titan_writel(0x00000000, GXDMADRPFX); /* buffer address prefix */ |
222 | #endif | 223 | #endif |
223 | titan_writel(0, GXDMA_DESCADR); | 224 | titan_writel(0, GXDMA_DESCADR); |
224 | 225 | ||
225 | for (i = 0x5040; i <= 0x5300; i += 0x0040) | 226 | for (i = 0x5040; i <= 0x5300; i += 0x0040) |
226 | titan_writel(0x80080000, i); /* reset channel */ | 227 | titan_writel(0x80080000, i); /* reset channel */ |
227 | 228 | ||
228 | titan_writel((0x1 << 29) /* no sparse tx descr. */ | 229 | titan_writel((0x1 << 29) /* no sparse tx descr. */ |
229 | | (0x1 << 28) /* no sparse rx descr. */ | 230 | | (0x1 << 28) /* no sparse rx descr. */ |
230 | | (0x1 << 23) | (0x1 << 24) /* descriptor coherency */ | 231 | | (0x1 << 23) | (0x1 << 24) /* descriptor coherency */ |
231 | | (0x1 << 21) | (0x1 << 22) /* data coherency */ | 232 | | (0x1 << 21) | (0x1 << 22) /* data coherency */ |
232 | | (0x1 << 17) | 233 | | (0x1 << 17) |
233 | | 0x1dff, | 234 | | 0x1dff, |
234 | GXCFG); | 235 | GXCFG); |
235 | 236 | ||
236 | #if defined(CONFIG_SMP) | 237 | #if defined(CONFIG_SMP) |
237 | # error No SMP support | 238 | # error No SMP support |
238 | #else | 239 | #else |
239 | /* All interrupts go to core #0 only. */ | 240 | /* All interrupts go to core #0 only. */ |
240 | titan_writel(0x1f007fff, CPDST0A); | 241 | titan_writel(0x1f007fff, CPDST0A); |
241 | titan_writel(0x00000000, CPDST0B); | 242 | titan_writel(0x00000000, CPDST0B); |
242 | titan_writel(0x0000ff3f, CPDST1A); | 243 | titan_writel(0x0000ff3f, CPDST1A); |
243 | titan_writel(0x00000000, CPDST1B); | 244 | titan_writel(0x00000000, CPDST1B); |
244 | titan_writel(0x00ffffff, CPXDSTA); | 245 | titan_writel(0x00ffffff, CPXDSTA); |
245 | titan_writel(0x00000000, CPXDSTB); | 246 | titan_writel(0x00000000, CPXDSTB); |
246 | #endif | 247 | #endif |
247 | 248 | ||
248 | /* Enable DUART interrupts, disable everything else. */ | 249 | /* Enable DUART interrupts, disable everything else. */ |
249 | titan_writel(0x04000000, CPGIG0ER); | 250 | titan_writel(0x04000000, CPGIG0ER); |
250 | titan_writel(0x000000c0, CPGIG1ER); | 251 | titan_writel(0x000000c0, CPGIG1ER); |
251 | 252 | ||
252 | excite_procfs_init(); | 253 | excite_procfs_init(); |
253 | return 0; | 254 | return 0; |
254 | } | 255 | } |
255 | 256 | ||
256 | void __init plat_mem_setup(void) | 257 | void __init plat_mem_setup(void) |
257 | { | 258 | { |
258 | volatile u32 * const boot_ocd_base = (u32 *) 0xbf7fc000; | 259 | volatile u32 * const boot_ocd_base = (u32 *) 0xbf7fc000; |
259 | 260 | ||
260 | /* Announce RAM to system */ | 261 | /* Announce RAM to system */ |
261 | add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); | 262 | add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); |
262 | 263 | ||
263 | /* Set up timer initialization hooks */ | 264 | /* Set up timer initialization hooks */ |
264 | board_time_init = excite_timer_init; | 265 | board_time_init = excite_timer_init; |
265 | 266 | ||
266 | /* Set up the peripheral address map */ | 267 | /* Set up the peripheral address map */ |
267 | *(boot_ocd_base + (LKB9 / sizeof (u32))) = 0; | 268 | *(boot_ocd_base + (LKB9 / sizeof (u32))) = 0; |
268 | *(boot_ocd_base + (LKB10 / sizeof (u32))) = 0; | 269 | *(boot_ocd_base + (LKB10 / sizeof (u32))) = 0; |
269 | *(boot_ocd_base + (LKB11 / sizeof (u32))) = 0; | 270 | *(boot_ocd_base + (LKB11 / sizeof (u32))) = 0; |
270 | *(boot_ocd_base + (LKB12 / sizeof (u32))) = 0; | 271 | *(boot_ocd_base + (LKB12 / sizeof (u32))) = 0; |
271 | wmb(); | 272 | wmb(); |
272 | *(boot_ocd_base + (LKB0 / sizeof (u32))) = EXCITE_PHYS_OCD >> 4; | 273 | *(boot_ocd_base + (LKB0 / sizeof (u32))) = EXCITE_PHYS_OCD >> 4; |
273 | wmb(); | 274 | wmb(); |
274 | 275 | ||
275 | ocd_writel((EXCITE_PHYS_TITAN >> 4) | 0x1UL, LKB5); | 276 | ocd_writel((EXCITE_PHYS_TITAN >> 4) | 0x1UL, LKB5); |
276 | ocd_writel(((EXCITE_SIZE_TITAN >> 4) & 0x7fffff00) - 0x100, LKM5); | 277 | ocd_writel(((EXCITE_SIZE_TITAN >> 4) & 0x7fffff00) - 0x100, LKM5); |
277 | ocd_writel((EXCITE_PHYS_SCRAM >> 4) | 0x1UL, LKB13); | 278 | ocd_writel((EXCITE_PHYS_SCRAM >> 4) | 0x1UL, LKB13); |
278 | ocd_writel(((EXCITE_SIZE_SCRAM >> 4) & 0xffffff00) - 0x100, LKM13); | 279 | ocd_writel(((EXCITE_SIZE_SCRAM >> 4) & 0xffffff00) - 0x100, LKM13); |
279 | 280 | ||
280 | /* Local bus slot #0 */ | 281 | /* Local bus slot #0 */ |
281 | ocd_writel(0x00040510, LDP0); | 282 | ocd_writel(0x00040510, LDP0); |
282 | ocd_writel((EXCITE_PHYS_BOOTROM >> 4) | 0x1UL, LKB9); | 283 | ocd_writel((EXCITE_PHYS_BOOTROM >> 4) | 0x1UL, LKB9); |
283 | ocd_writel(((EXCITE_SIZE_BOOTROM >> 4) & 0x03ffff00) - 0x100, LKM9); | 284 | ocd_writel(((EXCITE_SIZE_BOOTROM >> 4) & 0x03ffff00) - 0x100, LKM9); |
284 | 285 | ||
285 | /* Local bus slot #2 */ | 286 | /* Local bus slot #2 */ |
286 | ocd_writel(0x00000330, LDP2); | 287 | ocd_writel(0x00000330, LDP2); |
287 | ocd_writel((EXCITE_PHYS_FPGA >> 4) | 0x1, LKB11); | 288 | ocd_writel((EXCITE_PHYS_FPGA >> 4) | 0x1, LKB11); |
288 | ocd_writel(((EXCITE_SIZE_FPGA >> 4) - 0x100) & 0x03ffff00, LKM11); | 289 | ocd_writel(((EXCITE_SIZE_FPGA >> 4) - 0x100) & 0x03ffff00, LKM11); |
289 | 290 | ||
290 | /* Local bus slot #3 */ | 291 | /* Local bus slot #3 */ |
291 | ocd_writel(0x00123413, LDP3); | 292 | ocd_writel(0x00123413, LDP3); |
292 | ocd_writel((EXCITE_PHYS_NAND >> 4) | 0x1, LKB12); | 293 | ocd_writel((EXCITE_PHYS_NAND >> 4) | 0x1, LKB12); |
293 | ocd_writel(((EXCITE_SIZE_NAND >> 4) - 0x100) & 0x03ffff00, LKM12); | 294 | ocd_writel(((EXCITE_SIZE_NAND >> 4) - 0x100) & 0x03ffff00, LKM12); |
294 | } | 295 | } |
295 | 296 | ||
296 | 297 | ||
297 | 298 | ||
298 | console_initcall(excite_init_console); | 299 | console_initcall(excite_init_console); |
299 | arch_initcall(excite_platform_init); | 300 | arch_initcall(excite_platform_init); |
300 | 301 | ||
301 | EXPORT_SYMBOL(titan_lock); | 302 | EXPORT_SYMBOL(titan_lock); |
302 | EXPORT_SYMBOL(titan_irqflags); | 303 | EXPORT_SYMBOL(titan_irqflags); |
303 | EXPORT_SYMBOL(titan_irq); | 304 | EXPORT_SYMBOL(titan_irq); |
304 | EXPORT_SYMBOL(ocd_base); | 305 | EXPORT_SYMBOL(ocd_base); |
305 | EXPORT_SYMBOL(titan_base); | 306 | EXPORT_SYMBOL(titan_base); |
306 | 307 |
arch/mips/gt64120/wrppmc/setup.c
1 | /* | 1 | /* |
2 | * setup.c: Setup pointers to hardware dependent routines. | 2 | * setup.c: Setup pointers to hardware dependent routines. |
3 | * | 3 | * |
4 | * This file is subject to the terms and conditions of the GNU General Public | 4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org) |
9 | * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com> | 9 | * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com> |
10 | */ | 10 | */ |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
16 | #include <linux/serial_core.h> | 16 | #include <linux/serial_core.h> |
17 | #include <linux/serial_8250.h> | ||
17 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
18 | 19 | ||
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
20 | #include <asm/bootinfo.h> | 21 | #include <asm/bootinfo.h> |
21 | #include <asm/reboot.h> | 22 | #include <asm/reboot.h> |
22 | #include <asm/time.h> | 23 | #include <asm/time.h> |
23 | #include <asm/gt64120.h> | 24 | #include <asm/gt64120.h> |
24 | 25 | ||
25 | unsigned long gt64120_base = KSEG1ADDR(0x14000000); | 26 | unsigned long gt64120_base = KSEG1ADDR(0x14000000); |
26 | 27 | ||
27 | #ifdef WRPPMC_EARLY_DEBUG | 28 | #ifdef WRPPMC_EARLY_DEBUG |
28 | 29 | ||
29 | static volatile unsigned char * wrppmc_led = \ | 30 | static volatile unsigned char * wrppmc_led = \ |
30 | (volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE); | 31 | (volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE); |
31 | 32 | ||
32 | /* | 33 | /* |
33 | * PPMC LED control register: | 34 | * PPMC LED control register: |
34 | * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON) | 35 | * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON) |
35 | * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON) | 36 | * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON) |
36 | * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON) | 37 | * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON) |
37 | */ | 38 | */ |
38 | void wrppmc_led_on(int mask) | 39 | void wrppmc_led_on(int mask) |
39 | { | 40 | { |
40 | unsigned char value = *wrppmc_led; | 41 | unsigned char value = *wrppmc_led; |
41 | 42 | ||
42 | value &= (0xF8 | mask); | 43 | value &= (0xF8 | mask); |
43 | *wrppmc_led = value; | 44 | *wrppmc_led = value; |
44 | } | 45 | } |
45 | 46 | ||
46 | /* If mask = 0, turn off all LEDs */ | 47 | /* If mask = 0, turn off all LEDs */ |
47 | void wrppmc_led_off(int mask) | 48 | void wrppmc_led_off(int mask) |
48 | { | 49 | { |
49 | unsigned char value = *wrppmc_led; | 50 | unsigned char value = *wrppmc_led; |
50 | 51 | ||
51 | value |= (0x7 & mask); | 52 | value |= (0x7 & mask); |
52 | *wrppmc_led = value; | 53 | *wrppmc_led = value; |
53 | } | 54 | } |
54 | 55 | ||
55 | /* | 56 | /* |
56 | * We assume that bootloader has initialized UART16550 correctly | 57 | * We assume that bootloader has initialized UART16550 correctly |
57 | */ | 58 | */ |
58 | void __init wrppmc_early_putc(char ch) | 59 | void __init wrppmc_early_putc(char ch) |
59 | { | 60 | { |
60 | static volatile unsigned char *wrppmc_uart = \ | 61 | static volatile unsigned char *wrppmc_uart = \ |
61 | (volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE); | 62 | (volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE); |
62 | unsigned char value; | 63 | unsigned char value; |
63 | 64 | ||
64 | /* Wait until Transmit-Holding-Register is empty */ | 65 | /* Wait until Transmit-Holding-Register is empty */ |
65 | while (1) { | 66 | while (1) { |
66 | value = *(wrppmc_uart + 5); | 67 | value = *(wrppmc_uart + 5); |
67 | if (value & 0x20) | 68 | if (value & 0x20) |
68 | break; | 69 | break; |
69 | } | 70 | } |
70 | 71 | ||
71 | *wrppmc_uart = ch; | 72 | *wrppmc_uart = ch; |
72 | } | 73 | } |
73 | 74 | ||
74 | void __init wrppmc_early_printk(const char *fmt, ...) | 75 | void __init wrppmc_early_printk(const char *fmt, ...) |
75 | { | 76 | { |
76 | static char pbuf[256] = {'\0', }; | 77 | static char pbuf[256] = {'\0', }; |
77 | char *ch = pbuf; | 78 | char *ch = pbuf; |
78 | va_list args; | 79 | va_list args; |
79 | unsigned int i; | 80 | unsigned int i; |
80 | 81 | ||
81 | memset(pbuf, 0, 256); | 82 | memset(pbuf, 0, 256); |
82 | va_start(args, fmt); | 83 | va_start(args, fmt); |
83 | i = vsprintf(pbuf, fmt, args); | 84 | i = vsprintf(pbuf, fmt, args); |
84 | va_end(args); | 85 | va_end(args); |
85 | 86 | ||
86 | /* Print the string */ | 87 | /* Print the string */ |
87 | while (*ch != '\0') { | 88 | while (*ch != '\0') { |
88 | wrppmc_early_putc(*ch); | 89 | wrppmc_early_putc(*ch); |
89 | /* if print '\n', also print '\r' */ | 90 | /* if print '\n', also print '\r' */ |
90 | if (*ch++ == '\n') | 91 | if (*ch++ == '\n') |
91 | wrppmc_early_putc('\r'); | 92 | wrppmc_early_putc('\r'); |
92 | } | 93 | } |
93 | } | 94 | } |
94 | #endif /* WRPPMC_EARLY_DEBUG */ | 95 | #endif /* WRPPMC_EARLY_DEBUG */ |
95 | 96 | ||
96 | void __init prom_free_prom_memory(void) | 97 | void __init prom_free_prom_memory(void) |
97 | { | 98 | { |
98 | } | 99 | } |
99 | 100 | ||
100 | #ifdef CONFIG_SERIAL_8250 | 101 | #ifdef CONFIG_SERIAL_8250 |
101 | static void wrppmc_setup_serial(void) | 102 | static void wrppmc_setup_serial(void) |
102 | { | 103 | { |
103 | struct uart_port up; | 104 | struct uart_port up; |
104 | 105 | ||
105 | memset(&up, 0x00, sizeof(struct uart_port)); | 106 | memset(&up, 0x00, sizeof(struct uart_port)); |
106 | 107 | ||
107 | /* | 108 | /* |
108 | * A note about mapbase/membase | 109 | * A note about mapbase/membase |
109 | * -) mapbase is the physical address of the IO port. | 110 | * -) mapbase is the physical address of the IO port. |
110 | * -) membase is an 'ioremapped' cookie. | 111 | * -) membase is an 'ioremapped' cookie. |
111 | */ | 112 | */ |
112 | up.line = 0; | 113 | up.line = 0; |
113 | up.type = PORT_16550; | 114 | up.type = PORT_16550; |
114 | up.iotype = UPIO_MEM; | 115 | up.iotype = UPIO_MEM; |
115 | up.mapbase = WRPPMC_UART16550_BASE; | 116 | up.mapbase = WRPPMC_UART16550_BASE; |
116 | up.membase = ioremap(up.mapbase, 8); | 117 | up.membase = ioremap(up.mapbase, 8); |
117 | up.irq = WRPPMC_UART16550_IRQ; | 118 | up.irq = WRPPMC_UART16550_IRQ; |
118 | up.uartclk = WRPPMC_UART16550_CLOCK; | 119 | up.uartclk = WRPPMC_UART16550_CLOCK; |
119 | up.flags = UPF_SKIP_TEST/* | UPF_BOOT_AUTOCONF */; | 120 | up.flags = UPF_SKIP_TEST/* | UPF_BOOT_AUTOCONF */; |
120 | up.regshift = 0; | 121 | up.regshift = 0; |
121 | 122 | ||
122 | early_serial_setup(&up); | 123 | early_serial_setup(&up); |
123 | } | 124 | } |
124 | #endif | 125 | #endif |
125 | 126 | ||
126 | void __init plat_mem_setup(void) | 127 | void __init plat_mem_setup(void) |
127 | { | 128 | { |
128 | extern void wrppmc_time_init(void); | 129 | extern void wrppmc_time_init(void); |
129 | extern void wrppmc_machine_restart(char *command); | 130 | extern void wrppmc_machine_restart(char *command); |
130 | extern void wrppmc_machine_halt(void); | 131 | extern void wrppmc_machine_halt(void); |
131 | extern void wrppmc_machine_power_off(void); | 132 | extern void wrppmc_machine_power_off(void); |
132 | 133 | ||
133 | _machine_restart = wrppmc_machine_restart; | 134 | _machine_restart = wrppmc_machine_restart; |
134 | _machine_halt = wrppmc_machine_halt; | 135 | _machine_halt = wrppmc_machine_halt; |
135 | pm_power_off = wrppmc_machine_power_off; | 136 | pm_power_off = wrppmc_machine_power_off; |
136 | 137 | ||
137 | /* Use MIPS Count/Compare Timer */ | 138 | /* Use MIPS Count/Compare Timer */ |
138 | board_time_init = wrppmc_time_init; | 139 | board_time_init = wrppmc_time_init; |
139 | 140 | ||
140 | /* This makes the operations of 'in/out[bwl]' to the | 141 | /* This makes the operations of 'in/out[bwl]' to the |
141 | * physical address ( < KSEG0) can work via KSEG1 | 142 | * physical address ( < KSEG0) can work via KSEG1 |
142 | */ | 143 | */ |
143 | set_io_port_base(KSEG1); | 144 | set_io_port_base(KSEG1); |
144 | 145 | ||
145 | #ifdef CONFIG_SERIAL_8250 | 146 | #ifdef CONFIG_SERIAL_8250 |
146 | wrppmc_setup_serial(); | 147 | wrppmc_setup_serial(); |
147 | #endif | 148 | #endif |
148 | } | 149 | } |
149 | 150 | ||
150 | const char *get_system_type(void) | 151 | const char *get_system_type(void) |
151 | { | 152 | { |
152 | return "Wind River PPMC (GT64120)"; | 153 | return "Wind River PPMC (GT64120)"; |
153 | } | 154 | } |
154 | 155 | ||
155 | /* | 156 | /* |
156 | * Initializes basic routines and structures pointers, memory size (as | 157 | * Initializes basic routines and structures pointers, memory size (as |
157 | * given by the bios and saves the command line. | 158 | * given by the bios and saves the command line. |
158 | */ | 159 | */ |
159 | void __init prom_init(void) | 160 | void __init prom_init(void) |
160 | { | 161 | { |
161 | mips_machgroup = MACH_GROUP_WINDRIVER; | 162 | mips_machgroup = MACH_GROUP_WINDRIVER; |
162 | mips_machtype = MACH_WRPPMC; | 163 | mips_machtype = MACH_WRPPMC; |
163 | 164 | ||
164 | add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); | 165 | add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); |
165 | add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); | 166 | add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); |
166 | 167 | ||
167 | wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n", | 168 | wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n", |
168 | WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE)); | 169 | WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE)); |
169 | } | 170 | } |
170 | 171 |
arch/mips/mips-boards/atlas/atlas_setup.c
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * Carsten Langgaard, carstenl@mips.com |
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | 3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can distribute it and/or modify it | 5 | * This program is free software; you can distribute it and/or modify it |
6 | * under the terms of the GNU General Public License (Version 2) as | 6 | * under the terms of the GNU General Public License (Version 2) as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | 9 | * This program is distributed in the hope it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * for more details. | 12 | * for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License along | 14 | * You should have received a copy of the GNU General Public License along |
15 | * with this program; if not, write to the Free Software Foundation, Inc., | 15 | * with this program; if not, write to the Free Software Foundation, Inc., |
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
17 | */ | 17 | */ |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | #include <linux/tty.h> | 22 | #include <linux/tty.h> |
23 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
24 | #include <linux/serial_core.h> | 24 | #include <linux/serial_core.h> |
25 | #include <linux/serial_8250.h> | ||
25 | 26 | ||
26 | #include <asm/cpu.h> | 27 | #include <asm/cpu.h> |
27 | #include <asm/bootinfo.h> | 28 | #include <asm/bootinfo.h> |
28 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
29 | #include <asm/mips-boards/generic.h> | 30 | #include <asm/mips-boards/generic.h> |
30 | #include <asm/mips-boards/prom.h> | 31 | #include <asm/mips-boards/prom.h> |
31 | #include <asm/mips-boards/atlas.h> | 32 | #include <asm/mips-boards/atlas.h> |
32 | #include <asm/mips-boards/atlasint.h> | 33 | #include <asm/mips-boards/atlasint.h> |
33 | #include <asm/time.h> | 34 | #include <asm/time.h> |
34 | #include <asm/traps.h> | 35 | #include <asm/traps.h> |
35 | 36 | ||
36 | extern void mips_reboot_setup(void); | 37 | extern void mips_reboot_setup(void); |
37 | extern void mips_time_init(void); | 38 | extern void mips_time_init(void); |
38 | extern unsigned long mips_rtc_get_time(void); | 39 | extern unsigned long mips_rtc_get_time(void); |
39 | 40 | ||
40 | #ifdef CONFIG_KGDB | 41 | #ifdef CONFIG_KGDB |
41 | extern void kgdb_config(void); | 42 | extern void kgdb_config(void); |
42 | #endif | 43 | #endif |
43 | 44 | ||
44 | static void __init serial_init(void); | 45 | static void __init serial_init(void); |
45 | 46 | ||
46 | const char *get_system_type(void) | 47 | const char *get_system_type(void) |
47 | { | 48 | { |
48 | return "MIPS Atlas"; | 49 | return "MIPS Atlas"; |
49 | } | 50 | } |
50 | 51 | ||
51 | const char display_string[] = " LINUX ON ATLAS "; | 52 | const char display_string[] = " LINUX ON ATLAS "; |
52 | 53 | ||
53 | void __init plat_mem_setup(void) | 54 | void __init plat_mem_setup(void) |
54 | { | 55 | { |
55 | mips_pcibios_init(); | 56 | mips_pcibios_init(); |
56 | 57 | ||
57 | ioport_resource.end = 0x7fffffff; | 58 | ioport_resource.end = 0x7fffffff; |
58 | 59 | ||
59 | serial_init (); | 60 | serial_init (); |
60 | 61 | ||
61 | #ifdef CONFIG_KGDB | 62 | #ifdef CONFIG_KGDB |
62 | kgdb_config(); | 63 | kgdb_config(); |
63 | #endif | 64 | #endif |
64 | mips_reboot_setup(); | 65 | mips_reboot_setup(); |
65 | 66 | ||
66 | board_time_init = mips_time_init; | 67 | board_time_init = mips_time_init; |
67 | rtc_mips_get_time = mips_rtc_get_time; | 68 | rtc_mips_get_time = mips_rtc_get_time; |
68 | } | 69 | } |
69 | 70 | ||
70 | static void __init serial_init(void) | 71 | static void __init serial_init(void) |
71 | { | 72 | { |
72 | #ifdef CONFIG_SERIAL_8250 | 73 | #ifdef CONFIG_SERIAL_8250 |
73 | struct uart_port s; | 74 | struct uart_port s; |
74 | 75 | ||
75 | memset(&s, 0, sizeof(s)); | 76 | memset(&s, 0, sizeof(s)); |
76 | 77 | ||
77 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | 78 | #ifdef CONFIG_CPU_LITTLE_ENDIAN |
78 | s.iobase = ATLAS_UART_REGS_BASE; | 79 | s.iobase = ATLAS_UART_REGS_BASE; |
79 | #else | 80 | #else |
80 | s.iobase = ATLAS_UART_REGS_BASE+3; | 81 | s.iobase = ATLAS_UART_REGS_BASE+3; |
81 | #endif | 82 | #endif |
82 | s.irq = ATLAS_INT_UART; | 83 | s.irq = ATLAS_INT_UART; |
83 | s.uartclk = ATLAS_BASE_BAUD * 16; | 84 | s.uartclk = ATLAS_BASE_BAUD * 16; |
84 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; | 85 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; |
85 | s.iotype = UPIO_PORT; | 86 | s.iotype = UPIO_PORT; |
86 | s.regshift = 3; | 87 | s.regshift = 3; |
87 | 88 | ||
88 | if (early_serial_setup(&s) != 0) { | 89 | if (early_serial_setup(&s) != 0) { |
89 | printk(KERN_ERR "Serial setup failed!\n"); | 90 | printk(KERN_ERR "Serial setup failed!\n"); |
90 | } | 91 | } |
91 | #endif | 92 | #endif |
92 | } | 93 | } |
93 | 94 |
arch/mips/mips-boards/sead/sead_setup.c
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * Carsten Langgaard, carstenl@mips.com |
3 | * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. | 3 | * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can distribute it and/or modify it | 5 | * This program is free software; you can distribute it and/or modify it |
6 | * under the terms of the GNU General Public License (Version 2) as | 6 | * under the terms of the GNU General Public License (Version 2) as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | 9 | * This program is distributed in the hope it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * for more details. | 12 | * for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License along | 14 | * You should have received a copy of the GNU General Public License along |
15 | * with this program; if not, write to the Free Software Foundation, Inc., | 15 | * with this program; if not, write to the Free Software Foundation, Inc., |
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
17 | * | 17 | * |
18 | * SEAD specific setup. | 18 | * SEAD specific setup. |
19 | */ | 19 | */ |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/serial.h> | 24 | #include <linux/serial.h> |
25 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
26 | #include <linux/serial_8250.h> | ||
26 | 27 | ||
27 | #include <asm/cpu.h> | 28 | #include <asm/cpu.h> |
28 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
29 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
30 | #include <asm/mips-boards/generic.h> | 31 | #include <asm/mips-boards/generic.h> |
31 | #include <asm/mips-boards/prom.h> | 32 | #include <asm/mips-boards/prom.h> |
32 | #include <asm/mips-boards/sead.h> | 33 | #include <asm/mips-boards/sead.h> |
33 | #include <asm/mips-boards/seadint.h> | 34 | #include <asm/mips-boards/seadint.h> |
34 | #include <asm/time.h> | 35 | #include <asm/time.h> |
35 | 36 | ||
36 | extern void mips_reboot_setup(void); | 37 | extern void mips_reboot_setup(void); |
37 | extern void mips_time_init(void); | 38 | extern void mips_time_init(void); |
38 | 39 | ||
39 | static void __init serial_init(void); | 40 | static void __init serial_init(void); |
40 | 41 | ||
41 | const char *get_system_type(void) | 42 | const char *get_system_type(void) |
42 | { | 43 | { |
43 | return "MIPS SEAD"; | 44 | return "MIPS SEAD"; |
44 | } | 45 | } |
45 | 46 | ||
46 | const char display_string[] = " LINUX ON SEAD "; | 47 | const char display_string[] = " LINUX ON SEAD "; |
47 | 48 | ||
48 | void __init plat_mem_setup(void) | 49 | void __init plat_mem_setup(void) |
49 | { | 50 | { |
50 | ioport_resource.end = 0x7fffffff; | 51 | ioport_resource.end = 0x7fffffff; |
51 | 52 | ||
52 | serial_init (); | 53 | serial_init (); |
53 | 54 | ||
54 | board_time_init = mips_time_init; | 55 | board_time_init = mips_time_init; |
55 | 56 | ||
56 | mips_reboot_setup(); | 57 | mips_reboot_setup(); |
57 | } | 58 | } |
58 | 59 | ||
59 | static void __init serial_init(void) | 60 | static void __init serial_init(void) |
60 | { | 61 | { |
61 | #ifdef CONFIG_SERIAL_8250 | 62 | #ifdef CONFIG_SERIAL_8250 |
62 | struct uart_port s; | 63 | struct uart_port s; |
63 | 64 | ||
64 | memset(&s, 0, sizeof(s)); | 65 | memset(&s, 0, sizeof(s)); |
65 | 66 | ||
66 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | 67 | #ifdef CONFIG_CPU_LITTLE_ENDIAN |
67 | s.iobase = SEAD_UART0_REGS_BASE; | 68 | s.iobase = SEAD_UART0_REGS_BASE; |
68 | #else | 69 | #else |
69 | s.iobase = SEAD_UART0_REGS_BASE+3; | 70 | s.iobase = SEAD_UART0_REGS_BASE+3; |
70 | #endif | 71 | #endif |
71 | s.irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_UART0; | 72 | s.irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_UART0; |
72 | s.uartclk = SEAD_BASE_BAUD * 16; | 73 | s.uartclk = SEAD_BASE_BAUD * 16; |
73 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; | 74 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; |
74 | s.iotype = UPIO_PORT; | 75 | s.iotype = UPIO_PORT; |
75 | s.regshift = 3; | 76 | s.regshift = 3; |
76 | 77 | ||
77 | if (early_serial_setup(&s) != 0) { | 78 | if (early_serial_setup(&s) != 0) { |
78 | printk(KERN_ERR "Serial setup failed!\n"); | 79 | printk(KERN_ERR "Serial setup failed!\n"); |
79 | } | 80 | } |
80 | #endif | 81 | #endif |
81 | } | 82 | } |
82 | 83 |
arch/mips/mipssim/sim_setup.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | 2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can distribute it and/or modify it | 4 | * This program is free software; you can distribute it and/or modify it |
5 | * under the terms of the GNU General Public License (Version 2) as | 5 | * under the terms of the GNU General Public License (Version 2) as |
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | * | 7 | * |
8 | * This program is distributed in the hope it will be useful, but WITHOUT | 8 | * This program is distributed in the hope it will be useful, but WITHOUT |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
11 | * for more details. | 11 | * for more details. |
12 | * | 12 | * |
13 | * You should have received a copy of the GNU General Public License along | 13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., | 14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/ioport.h> | 24 | #include <linux/ioport.h> |
25 | #include <linux/serial.h> | 25 | #include <linux/serial.h> |
26 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | #include <linux/serial.h> | 27 | #include <linux/serial.h> |
28 | #include <linux/serial_core.h> | 28 | #include <linux/serial_core.h> |
29 | #include <linux/serial_8250.h> | ||
29 | 30 | ||
30 | #include <asm/cpu.h> | 31 | #include <asm/cpu.h> |
31 | #include <asm/bootinfo.h> | 32 | #include <asm/bootinfo.h> |
32 | #include <asm/mips-boards/generic.h> | 33 | #include <asm/mips-boards/generic.h> |
33 | #include <asm/mips-boards/prom.h> | 34 | #include <asm/mips-boards/prom.h> |
34 | #include <asm/time.h> | 35 | #include <asm/time.h> |
35 | #include <asm/mips-boards/sim.h> | 36 | #include <asm/mips-boards/sim.h> |
36 | #include <asm/mips-boards/simint.h> | 37 | #include <asm/mips-boards/simint.h> |
37 | 38 | ||
38 | 39 | ||
39 | extern void sim_time_init(void); | 40 | extern void sim_time_init(void); |
40 | static void __init serial_init(void); | 41 | static void __init serial_init(void); |
41 | unsigned int _isbonito = 0; | 42 | unsigned int _isbonito = 0; |
42 | 43 | ||
43 | extern void __init sanitize_tlb_entries(void); | 44 | extern void __init sanitize_tlb_entries(void); |
44 | 45 | ||
45 | 46 | ||
46 | const char *get_system_type(void) | 47 | const char *get_system_type(void) |
47 | { | 48 | { |
48 | return "MIPSsim"; | 49 | return "MIPSsim"; |
49 | } | 50 | } |
50 | 51 | ||
51 | void __init plat_mem_setup(void) | 52 | void __init plat_mem_setup(void) |
52 | { | 53 | { |
53 | set_io_port_base(0xbfd00000); | 54 | set_io_port_base(0xbfd00000); |
54 | 55 | ||
55 | serial_init(); | 56 | serial_init(); |
56 | 57 | ||
57 | board_time_init = sim_time_init; | 58 | board_time_init = sim_time_init; |
58 | pr_info("Linux started...\n"); | 59 | pr_info("Linux started...\n"); |
59 | 60 | ||
60 | #ifdef CONFIG_MIPS_MT_SMP | 61 | #ifdef CONFIG_MIPS_MT_SMP |
61 | sanitize_tlb_entries(); | 62 | sanitize_tlb_entries(); |
62 | #endif | 63 | #endif |
63 | } | 64 | } |
64 | 65 | ||
65 | void __init prom_init(void) | 66 | void __init prom_init(void) |
66 | { | 67 | { |
67 | set_io_port_base(0xbfd00000); | 68 | set_io_port_base(0xbfd00000); |
68 | 69 | ||
69 | pr_info("\nLINUX started...\n"); | 70 | pr_info("\nLINUX started...\n"); |
70 | prom_init_cmdline(); | 71 | prom_init_cmdline(); |
71 | prom_meminit(); | 72 | prom_meminit(); |
72 | } | 73 | } |
73 | 74 | ||
74 | 75 | ||
75 | static void __init serial_init(void) | 76 | static void __init serial_init(void) |
76 | { | 77 | { |
77 | #ifdef CONFIG_SERIAL_8250 | 78 | #ifdef CONFIG_SERIAL_8250 |
78 | struct uart_port s; | 79 | struct uart_port s; |
79 | 80 | ||
80 | memset(&s, 0, sizeof(s)); | 81 | memset(&s, 0, sizeof(s)); |
81 | 82 | ||
82 | s.iobase = 0x3f8; | 83 | s.iobase = 0x3f8; |
83 | 84 | ||
84 | /* hardware int 4 - the serial int, is CPU int 6 | 85 | /* hardware int 4 - the serial int, is CPU int 6 |
85 | but poll for now */ | 86 | but poll for now */ |
86 | s.irq = 0; | 87 | s.irq = 0; |
87 | s.uartclk = 1843200; | 88 | s.uartclk = 1843200; |
88 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 89 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
89 | s.iotype = UPIO_PORT; | 90 | s.iotype = UPIO_PORT; |
90 | s.regshift = 0; | 91 | s.regshift = 0; |
91 | s.timeout = 4; | 92 | s.timeout = 4; |
92 | 93 | ||
93 | if (early_serial_setup(&s) != 0) { | 94 | if (early_serial_setup(&s) != 0) { |
94 | printk(KERN_ERR "Serial setup failed!\n"); | 95 | printk(KERN_ERR "Serial setup failed!\n"); |
95 | } | 96 | } |
96 | 97 | ||
97 | #endif | 98 | #endif |
98 | } | 99 | } |
99 | 100 |
arch/mips/pmc-sierra/msp71xx/msp_serial.c
1 | /* | 1 | /* |
2 | * The setup file for serial related hardware on PMC-Sierra MSP processors. | 2 | * The setup file for serial related hardware on PMC-Sierra MSP processors. |
3 | * | 3 | * |
4 | * Copyright 2005 PMC-Sierra, Inc. | 4 | * Copyright 2005 PMC-Sierra, Inc. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
8 | * Free Software Foundation; either version 2 of the License, or (at your | 8 | * Free Software Foundation; either version 2 of the License, or (at your |
9 | * option) any later version. | 9 | * option) any later version. |
10 | * | 10 | * |
11 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | 11 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
12 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 12 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
13 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | 13 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN |
14 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 14 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
15 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 15 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
16 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | 16 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
17 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | 17 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
18 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 18 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
19 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 19 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
20 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 20 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
21 | * | 21 | * |
22 | * You should have received a copy of the GNU General Public License along | 22 | * You should have received a copy of the GNU General Public License along |
23 | * with this program; if not, write to the Free Software Foundation, Inc., | 23 | * with this program; if not, write to the Free Software Foundation, Inc., |
24 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 24 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/serial.h> | 27 | #include <linux/serial.h> |
28 | #include <linux/serial_core.h> | 28 | #include <linux/serial_core.h> |
29 | #include <linux/serial_reg.h> | 29 | #include <linux/serial_reg.h> |
30 | 30 | ||
31 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
32 | #include <asm/io.h> | 32 | #include <asm/io.h> |
33 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
34 | #include <asm/serial.h> | 34 | #include <asm/serial.h> |
35 | #include <linux/serial_8250.h> | ||
35 | 36 | ||
36 | #include <msp_prom.h> | 37 | #include <msp_prom.h> |
37 | #include <msp_int.h> | 38 | #include <msp_int.h> |
38 | #include <msp_regs.h> | 39 | #include <msp_regs.h> |
39 | 40 | ||
40 | #ifdef CONFIG_KGDB | 41 | #ifdef CONFIG_KGDB |
41 | /* | 42 | /* |
42 | * kgdb uses serial port 1 so the console can remain on port 0. | 43 | * kgdb uses serial port 1 so the console can remain on port 0. |
43 | * To use port 0 change the definition to read as follows: | 44 | * To use port 0 change the definition to read as follows: |
44 | * #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART0_BASE) | 45 | * #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART0_BASE) |
45 | */ | 46 | */ |
46 | #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART1_BASE) | 47 | #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART1_BASE) |
47 | 48 | ||
48 | int putDebugChar(char c) | 49 | int putDebugChar(char c) |
49 | { | 50 | { |
50 | volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; | 51 | volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; |
51 | uint32_t val = (uint32_t)c; | 52 | uint32_t val = (uint32_t)c; |
52 | 53 | ||
53 | local_irq_disable(); | 54 | local_irq_disable(); |
54 | while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ | 55 | while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ |
55 | uart[0] = val; | 56 | uart[0] = val; |
56 | while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ | 57 | while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ |
57 | local_irq_enable(); | 58 | local_irq_enable(); |
58 | 59 | ||
59 | return 1; | 60 | return 1; |
60 | } | 61 | } |
61 | 62 | ||
62 | char getDebugChar(void) | 63 | char getDebugChar(void) |
63 | { | 64 | { |
64 | volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; | 65 | volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; |
65 | uint32_t val; | 66 | uint32_t val; |
66 | 67 | ||
67 | while( !(uart[5] & 0x01) ); /* Wait for RXRDY */ | 68 | while( !(uart[5] & 0x01) ); /* Wait for RXRDY */ |
68 | val = uart[0]; | 69 | val = uart[0]; |
69 | 70 | ||
70 | return (char)val; | 71 | return (char)val; |
71 | } | 72 | } |
72 | 73 | ||
73 | void initDebugPort(unsigned int uartclk, unsigned int baudrate) | 74 | void initDebugPort(unsigned int uartclk, unsigned int baudrate) |
74 | { | 75 | { |
75 | unsigned int baud_divisor = (uartclk + 8 * baudrate)/(16 * baudrate); | 76 | unsigned int baud_divisor = (uartclk + 8 * baudrate)/(16 * baudrate); |
76 | 77 | ||
77 | /* Enable FIFOs */ | 78 | /* Enable FIFOs */ |
78 | writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | | 79 | writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | |
79 | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_4, | 80 | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_4, |
80 | (char *)DEBUG_PORT_BASE + (UART_FCR * 4)); | 81 | (char *)DEBUG_PORT_BASE + (UART_FCR * 4)); |
81 | 82 | ||
82 | /* Select brtc divisor */ | 83 | /* Select brtc divisor */ |
83 | writeb(UART_LCR_DLAB, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); | 84 | writeb(UART_LCR_DLAB, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); |
84 | 85 | ||
85 | /* Store divisor lsb */ | 86 | /* Store divisor lsb */ |
86 | writeb(baud_divisor, (char *)DEBUG_PORT_BASE + (UART_TX * 4)); | 87 | writeb(baud_divisor, (char *)DEBUG_PORT_BASE + (UART_TX * 4)); |
87 | 88 | ||
88 | /* Store divisor msb */ | 89 | /* Store divisor msb */ |
89 | writeb(baud_divisor >> 8, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); | 90 | writeb(baud_divisor >> 8, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); |
90 | 91 | ||
91 | /* Set 8N1 mode */ | 92 | /* Set 8N1 mode */ |
92 | writeb(UART_LCR_WLEN8, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); | 93 | writeb(UART_LCR_WLEN8, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); |
93 | 94 | ||
94 | /* Disable flow control */ | 95 | /* Disable flow control */ |
95 | writeb(0, (char *)DEBUG_PORT_BASE + (UART_MCR * 4)); | 96 | writeb(0, (char *)DEBUG_PORT_BASE + (UART_MCR * 4)); |
96 | 97 | ||
97 | /* Disable receive interrupt(!) */ | 98 | /* Disable receive interrupt(!) */ |
98 | writeb(0, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); | 99 | writeb(0, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); |
99 | } | 100 | } |
100 | #endif | 101 | #endif |
101 | 102 | ||
102 | void __init msp_serial_setup(void) | 103 | void __init msp_serial_setup(void) |
103 | { | 104 | { |
104 | char *s; | 105 | char *s; |
105 | char *endp; | 106 | char *endp; |
106 | struct uart_port up; | 107 | struct uart_port up; |
107 | unsigned int uartclk; | 108 | unsigned int uartclk; |
108 | 109 | ||
109 | memset(&up, 0, sizeof(up)); | 110 | memset(&up, 0, sizeof(up)); |
110 | 111 | ||
111 | /* Check if clock was specified in environment */ | 112 | /* Check if clock was specified in environment */ |
112 | s = prom_getenv("uartfreqhz"); | 113 | s = prom_getenv("uartfreqhz"); |
113 | if(!(s && *s && (uartclk = simple_strtoul(s, &endp, 10)) && *endp == 0)) | 114 | if(!(s && *s && (uartclk = simple_strtoul(s, &endp, 10)) && *endp == 0)) |
114 | uartclk = MSP_BASE_BAUD; | 115 | uartclk = MSP_BASE_BAUD; |
115 | ppfinit("UART clock set to %d\n", uartclk); | 116 | ppfinit("UART clock set to %d\n", uartclk); |
116 | 117 | ||
117 | /* Initialize first serial port */ | 118 | /* Initialize first serial port */ |
118 | up.mapbase = MSP_UART0_BASE; | 119 | up.mapbase = MSP_UART0_BASE; |
119 | up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); | 120 | up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); |
120 | up.irq = MSP_INT_UART0; | 121 | up.irq = MSP_INT_UART0; |
121 | up.uartclk = uartclk; | 122 | up.uartclk = uartclk; |
122 | up.regshift = 2; | 123 | up.regshift = 2; |
123 | up.iotype = UPIO_DWAPB; /* UPIO_MEM like */ | 124 | up.iotype = UPIO_DWAPB; /* UPIO_MEM like */ |
124 | up.flags = STD_COM_FLAGS; | 125 | up.flags = STD_COM_FLAGS; |
125 | up.type = PORT_16550A; | 126 | up.type = PORT_16550A; |
126 | up.line = 0; | 127 | up.line = 0; |
127 | up.private_data = (void*)UART0_STATUS_REG; | 128 | up.private_data = (void*)UART0_STATUS_REG; |
128 | if (early_serial_setup(&up)) | 129 | if (early_serial_setup(&up)) |
129 | printk(KERN_ERR "Early serial init of port 0 failed\n"); | 130 | printk(KERN_ERR "Early serial init of port 0 failed\n"); |
130 | 131 | ||
131 | /* Initialize the second serial port, if one exists */ | 132 | /* Initialize the second serial port, if one exists */ |
132 | switch (mips_machtype) { | 133 | switch (mips_machtype) { |
133 | case MACH_MSP4200_EVAL: | 134 | case MACH_MSP4200_EVAL: |
134 | case MACH_MSP4200_GW: | 135 | case MACH_MSP4200_GW: |
135 | case MACH_MSP4200_FPGA: | 136 | case MACH_MSP4200_FPGA: |
136 | case MACH_MSP7120_EVAL: | 137 | case MACH_MSP7120_EVAL: |
137 | case MACH_MSP7120_GW: | 138 | case MACH_MSP7120_GW: |
138 | case MACH_MSP7120_FPGA: | 139 | case MACH_MSP7120_FPGA: |
139 | /* Enable UART1 on MSP4200 and MSP7120 */ | 140 | /* Enable UART1 on MSP4200 and MSP7120 */ |
140 | *GPIO_CFG2_REG = 0x00002299; | 141 | *GPIO_CFG2_REG = 0x00002299; |
141 | 142 | ||
142 | #ifdef CONFIG_KGDB | 143 | #ifdef CONFIG_KGDB |
143 | /* Initialize UART1 for kgdb since PMON doesn't */ | 144 | /* Initialize UART1 for kgdb since PMON doesn't */ |
144 | if( DEBUG_PORT_BASE == KSEG1ADDR(MSP_UART1_BASE) ) { | 145 | if( DEBUG_PORT_BASE == KSEG1ADDR(MSP_UART1_BASE) ) { |
145 | if( mips_machtype == MACH_MSP4200_FPGA | 146 | if( mips_machtype == MACH_MSP4200_FPGA |
146 | || mips_machtype == MACH_MSP7120_FPGA ) | 147 | || mips_machtype == MACH_MSP7120_FPGA ) |
147 | initDebugPort(uartclk,19200); | 148 | initDebugPort(uartclk,19200); |
148 | else | 149 | else |
149 | initDebugPort(uartclk,57600); | 150 | initDebugPort(uartclk,57600); |
150 | } | 151 | } |
151 | #endif | 152 | #endif |
152 | break; | 153 | break; |
153 | 154 | ||
154 | default: | 155 | default: |
155 | return; /* No second serial port, good-bye. */ | 156 | return; /* No second serial port, good-bye. */ |
156 | } | 157 | } |
157 | 158 | ||
158 | up.mapbase = MSP_UART1_BASE; | 159 | up.mapbase = MSP_UART1_BASE; |
159 | up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); | 160 | up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); |
160 | up.irq = MSP_INT_UART1; | 161 | up.irq = MSP_INT_UART1; |
161 | up.line = 1; | 162 | up.line = 1; |
162 | up.private_data = (void*)UART1_STATUS_REG; | 163 | up.private_data = (void*)UART1_STATUS_REG; |
163 | if (early_serial_setup(&up)) | 164 | if (early_serial_setup(&up)) |
164 | printk(KERN_ERR "Early serial init of port 1 failed\n"); | 165 | printk(KERN_ERR "Early serial init of port 1 failed\n"); |
165 | } | 166 | } |
166 | 167 |
arch/mips/pmc-sierra/yosemite/setup.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2003 PMC-Sierra Inc. | 2 | * Copyright (C) 2003 PMC-Sierra Inc. |
3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) | 3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) |
4 | * | 4 | * |
5 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) | 5 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
9 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * Free Software Foundation; either version 2 of the License, or (at your |
10 | * option) any later version. | 10 | * option) any later version. |
11 | * | 11 | * |
12 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | 12 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
13 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 13 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
14 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | 14 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN |
15 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 15 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
16 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 16 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
17 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | 17 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
18 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | 18 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
19 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 19 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
20 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 20 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
21 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 21 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
22 | * | 22 | * |
23 | * You should have received a copy of the GNU General Public License along | 23 | * You should have received a copy of the GNU General Public License along |
24 | * with this program; if not, write to the Free Software Foundation, Inc., | 24 | * with this program; if not, write to the Free Software Foundation, Inc., |
25 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | */ | 26 | */ |
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/bootmem.h> | 32 | #include <linux/bootmem.h> |
33 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
34 | #include <linux/ioport.h> | 34 | #include <linux/ioport.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/timex.h> | 37 | #include <linux/timex.h> |
38 | #include <linux/termios.h> | 38 | #include <linux/termios.h> |
39 | #include <linux/tty.h> | 39 | #include <linux/tty.h> |
40 | #include <linux/serial.h> | 40 | #include <linux/serial.h> |
41 | #include <linux/serial_core.h> | 41 | #include <linux/serial_core.h> |
42 | #include <linux/serial_8250.h> | ||
42 | 43 | ||
43 | #include <asm/time.h> | 44 | #include <asm/time.h> |
44 | #include <asm/bootinfo.h> | 45 | #include <asm/bootinfo.h> |
45 | #include <asm/page.h> | 46 | #include <asm/page.h> |
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
48 | #include <asm/processor.h> | 49 | #include <asm/processor.h> |
49 | #include <asm/reboot.h> | 50 | #include <asm/reboot.h> |
50 | #include <asm/serial.h> | 51 | #include <asm/serial.h> |
51 | #include <asm/titan_dep.h> | 52 | #include <asm/titan_dep.h> |
52 | #include <asm/m48t37.h> | 53 | #include <asm/m48t37.h> |
53 | 54 | ||
54 | #include "setup.h" | 55 | #include "setup.h" |
55 | 56 | ||
56 | unsigned char titan_ge_mac_addr_base[6] = { | 57 | unsigned char titan_ge_mac_addr_base[6] = { |
57 | // 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 | 58 | // 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 |
58 | 0x00, 0xe0, 0x04, 0x00, 0x00, 0x21 | 59 | 0x00, 0xe0, 0x04, 0x00, 0x00, 0x21 |
59 | }; | 60 | }; |
60 | 61 | ||
61 | unsigned long cpu_clock; | 62 | unsigned long cpu_clock; |
62 | unsigned long yosemite_base; | 63 | unsigned long yosemite_base; |
63 | 64 | ||
64 | static struct m48t37_rtc *m48t37_base; | 65 | static struct m48t37_rtc *m48t37_base; |
65 | 66 | ||
66 | void __init bus_error_init(void) | 67 | void __init bus_error_init(void) |
67 | { | 68 | { |
68 | /* Do nothing */ | 69 | /* Do nothing */ |
69 | } | 70 | } |
70 | 71 | ||
71 | 72 | ||
72 | unsigned long m48t37y_get_time(void) | 73 | unsigned long m48t37y_get_time(void) |
73 | { | 74 | { |
74 | unsigned int year, month, day, hour, min, sec; | 75 | unsigned int year, month, day, hour, min, sec; |
75 | unsigned long flags; | 76 | unsigned long flags; |
76 | 77 | ||
77 | spin_lock_irqsave(&rtc_lock, flags); | 78 | spin_lock_irqsave(&rtc_lock, flags); |
78 | /* Stop the update to the time */ | 79 | /* Stop the update to the time */ |
79 | m48t37_base->control = 0x40; | 80 | m48t37_base->control = 0x40; |
80 | 81 | ||
81 | year = BCD2BIN(m48t37_base->year); | 82 | year = BCD2BIN(m48t37_base->year); |
82 | year += BCD2BIN(m48t37_base->century) * 100; | 83 | year += BCD2BIN(m48t37_base->century) * 100; |
83 | 84 | ||
84 | month = BCD2BIN(m48t37_base->month); | 85 | month = BCD2BIN(m48t37_base->month); |
85 | day = BCD2BIN(m48t37_base->date); | 86 | day = BCD2BIN(m48t37_base->date); |
86 | hour = BCD2BIN(m48t37_base->hour); | 87 | hour = BCD2BIN(m48t37_base->hour); |
87 | min = BCD2BIN(m48t37_base->min); | 88 | min = BCD2BIN(m48t37_base->min); |
88 | sec = BCD2BIN(m48t37_base->sec); | 89 | sec = BCD2BIN(m48t37_base->sec); |
89 | 90 | ||
90 | /* Start the update to the time again */ | 91 | /* Start the update to the time again */ |
91 | m48t37_base->control = 0x00; | 92 | m48t37_base->control = 0x00; |
92 | spin_unlock_irqrestore(&rtc_lock, flags); | 93 | spin_unlock_irqrestore(&rtc_lock, flags); |
93 | 94 | ||
94 | return mktime(year, month, day, hour, min, sec); | 95 | return mktime(year, month, day, hour, min, sec); |
95 | } | 96 | } |
96 | 97 | ||
97 | int m48t37y_set_time(unsigned long sec) | 98 | int m48t37y_set_time(unsigned long sec) |
98 | { | 99 | { |
99 | struct rtc_time tm; | 100 | struct rtc_time tm; |
100 | unsigned long flags; | 101 | unsigned long flags; |
101 | 102 | ||
102 | /* convert to a more useful format -- note months count from 0 */ | 103 | /* convert to a more useful format -- note months count from 0 */ |
103 | to_tm(sec, &tm); | 104 | to_tm(sec, &tm); |
104 | tm.tm_mon += 1; | 105 | tm.tm_mon += 1; |
105 | 106 | ||
106 | spin_lock_irqsave(&rtc_lock, flags); | 107 | spin_lock_irqsave(&rtc_lock, flags); |
107 | /* enable writing */ | 108 | /* enable writing */ |
108 | m48t37_base->control = 0x80; | 109 | m48t37_base->control = 0x80; |
109 | 110 | ||
110 | /* year */ | 111 | /* year */ |
111 | m48t37_base->year = BIN2BCD(tm.tm_year % 100); | 112 | m48t37_base->year = BIN2BCD(tm.tm_year % 100); |
112 | m48t37_base->century = BIN2BCD(tm.tm_year / 100); | 113 | m48t37_base->century = BIN2BCD(tm.tm_year / 100); |
113 | 114 | ||
114 | /* month */ | 115 | /* month */ |
115 | m48t37_base->month = BIN2BCD(tm.tm_mon); | 116 | m48t37_base->month = BIN2BCD(tm.tm_mon); |
116 | 117 | ||
117 | /* day */ | 118 | /* day */ |
118 | m48t37_base->date = BIN2BCD(tm.tm_mday); | 119 | m48t37_base->date = BIN2BCD(tm.tm_mday); |
119 | 120 | ||
120 | /* hour/min/sec */ | 121 | /* hour/min/sec */ |
121 | m48t37_base->hour = BIN2BCD(tm.tm_hour); | 122 | m48t37_base->hour = BIN2BCD(tm.tm_hour); |
122 | m48t37_base->min = BIN2BCD(tm.tm_min); | 123 | m48t37_base->min = BIN2BCD(tm.tm_min); |
123 | m48t37_base->sec = BIN2BCD(tm.tm_sec); | 124 | m48t37_base->sec = BIN2BCD(tm.tm_sec); |
124 | 125 | ||
125 | /* day of week -- not really used, but let's keep it up-to-date */ | 126 | /* day of week -- not really used, but let's keep it up-to-date */ |
126 | m48t37_base->day = BIN2BCD(tm.tm_wday + 1); | 127 | m48t37_base->day = BIN2BCD(tm.tm_wday + 1); |
127 | 128 | ||
128 | /* disable writing */ | 129 | /* disable writing */ |
129 | m48t37_base->control = 0x00; | 130 | m48t37_base->control = 0x00; |
130 | spin_unlock_irqrestore(&rtc_lock, flags); | 131 | spin_unlock_irqrestore(&rtc_lock, flags); |
131 | 132 | ||
132 | return 0; | 133 | return 0; |
133 | } | 134 | } |
134 | 135 | ||
135 | void __init plat_timer_setup(struct irqaction *irq) | 136 | void __init plat_timer_setup(struct irqaction *irq) |
136 | { | 137 | { |
137 | setup_irq(7, irq); | 138 | setup_irq(7, irq); |
138 | } | 139 | } |
139 | 140 | ||
140 | void yosemite_time_init(void) | 141 | void yosemite_time_init(void) |
141 | { | 142 | { |
142 | mips_hpt_frequency = cpu_clock / 2; | 143 | mips_hpt_frequency = cpu_clock / 2; |
143 | mips_hpt_frequency = 33000000 * 3 * 5; | 144 | mips_hpt_frequency = 33000000 * 3 * 5; |
144 | } | 145 | } |
145 | 146 | ||
146 | /* No other usable initialization hook than this ... */ | 147 | /* No other usable initialization hook than this ... */ |
147 | extern void (*late_time_init)(void); | 148 | extern void (*late_time_init)(void); |
148 | 149 | ||
149 | unsigned long ocd_base; | 150 | unsigned long ocd_base; |
150 | 151 | ||
151 | EXPORT_SYMBOL(ocd_base); | 152 | EXPORT_SYMBOL(ocd_base); |
152 | 153 | ||
153 | /* | 154 | /* |
154 | * Common setup before any secondaries are started | 155 | * Common setup before any secondaries are started |
155 | */ | 156 | */ |
156 | 157 | ||
157 | #define TITAN_UART_CLK 3686400 | 158 | #define TITAN_UART_CLK 3686400 |
158 | #define TITAN_SERIAL_BASE_BAUD (TITAN_UART_CLK / 16) | 159 | #define TITAN_SERIAL_BASE_BAUD (TITAN_UART_CLK / 16) |
159 | #define TITAN_SERIAL_IRQ 4 | 160 | #define TITAN_SERIAL_IRQ 4 |
160 | #define TITAN_SERIAL_BASE 0xfd000008UL | 161 | #define TITAN_SERIAL_BASE 0xfd000008UL |
161 | 162 | ||
162 | static void __init py_map_ocd(void) | 163 | static void __init py_map_ocd(void) |
163 | { | 164 | { |
164 | ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE); | 165 | ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE); |
165 | if (!ocd_base) | 166 | if (!ocd_base) |
166 | panic("Mapping OCD failed - game over. Your score is 0."); | 167 | panic("Mapping OCD failed - game over. Your score is 0."); |
167 | 168 | ||
168 | /* Kludge for PMON bug ... */ | 169 | /* Kludge for PMON bug ... */ |
169 | OCD_WRITE(0x0710, 0x0ffff029); | 170 | OCD_WRITE(0x0710, 0x0ffff029); |
170 | } | 171 | } |
171 | 172 | ||
172 | static void __init py_uart_setup(void) | 173 | static void __init py_uart_setup(void) |
173 | { | 174 | { |
174 | #ifdef CONFIG_SERIAL_8250 | 175 | #ifdef CONFIG_SERIAL_8250 |
175 | struct uart_port up; | 176 | struct uart_port up; |
176 | 177 | ||
177 | /* | 178 | /* |
178 | * Register to interrupt zero because we share the interrupt with | 179 | * Register to interrupt zero because we share the interrupt with |
179 | * the serial driver which we don't properly support yet. | 180 | * the serial driver which we don't properly support yet. |
180 | */ | 181 | */ |
181 | memset(&up, 0, sizeof(up)); | 182 | memset(&up, 0, sizeof(up)); |
182 | up.membase = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8); | 183 | up.membase = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8); |
183 | up.irq = TITAN_SERIAL_IRQ; | 184 | up.irq = TITAN_SERIAL_IRQ; |
184 | up.uartclk = TITAN_UART_CLK; | 185 | up.uartclk = TITAN_UART_CLK; |
185 | up.regshift = 0; | 186 | up.regshift = 0; |
186 | up.iotype = UPIO_MEM; | 187 | up.iotype = UPIO_MEM; |
187 | up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 188 | up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
188 | up.line = 0; | 189 | up.line = 0; |
189 | 190 | ||
190 | if (early_serial_setup(&up)) | 191 | if (early_serial_setup(&up)) |
191 | printk(KERN_ERR "Early serial init of port 0 failed\n"); | 192 | printk(KERN_ERR "Early serial init of port 0 failed\n"); |
192 | #endif /* CONFIG_SERIAL_8250 */ | 193 | #endif /* CONFIG_SERIAL_8250 */ |
193 | } | 194 | } |
194 | 195 | ||
195 | static void __init py_rtc_setup(void) | 196 | static void __init py_rtc_setup(void) |
196 | { | 197 | { |
197 | m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE); | 198 | m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE); |
198 | if (!m48t37_base) | 199 | if (!m48t37_base) |
199 | printk(KERN_ERR "Mapping the RTC failed\n"); | 200 | printk(KERN_ERR "Mapping the RTC failed\n"); |
200 | 201 | ||
201 | rtc_mips_get_time = m48t37y_get_time; | 202 | rtc_mips_get_time = m48t37y_get_time; |
202 | rtc_mips_set_time = m48t37y_set_time; | 203 | rtc_mips_set_time = m48t37y_set_time; |
203 | 204 | ||
204 | write_seqlock(&xtime_lock); | 205 | write_seqlock(&xtime_lock); |
205 | xtime.tv_sec = m48t37y_get_time(); | 206 | xtime.tv_sec = m48t37y_get_time(); |
206 | xtime.tv_nsec = 0; | 207 | xtime.tv_nsec = 0; |
207 | 208 | ||
208 | set_normalized_timespec(&wall_to_monotonic, | 209 | set_normalized_timespec(&wall_to_monotonic, |
209 | -xtime.tv_sec, -xtime.tv_nsec); | 210 | -xtime.tv_sec, -xtime.tv_nsec); |
210 | write_sequnlock(&xtime_lock); | 211 | write_sequnlock(&xtime_lock); |
211 | } | 212 | } |
212 | 213 | ||
213 | /* Not only time init but that's what the hook it's called through is named */ | 214 | /* Not only time init but that's what the hook it's called through is named */ |
214 | static void __init py_late_time_init(void) | 215 | static void __init py_late_time_init(void) |
215 | { | 216 | { |
216 | py_map_ocd(); | 217 | py_map_ocd(); |
217 | py_uart_setup(); | 218 | py_uart_setup(); |
218 | py_rtc_setup(); | 219 | py_rtc_setup(); |
219 | } | 220 | } |
220 | 221 | ||
221 | void __init plat_mem_setup(void) | 222 | void __init plat_mem_setup(void) |
222 | { | 223 | { |
223 | board_time_init = yosemite_time_init; | 224 | board_time_init = yosemite_time_init; |
224 | late_time_init = py_late_time_init; | 225 | late_time_init = py_late_time_init; |
225 | 226 | ||
226 | /* Add memory regions */ | 227 | /* Add memory regions */ |
227 | add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); | 228 | add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); |
228 | 229 | ||
229 | #if 0 /* XXX Crash ... */ | 230 | #if 0 /* XXX Crash ... */ |
230 | OCD_WRITE(RM9000x2_OCD_HTSC, | 231 | OCD_WRITE(RM9000x2_OCD_HTSC, |
231 | OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE); | 232 | OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE); |
232 | 233 | ||
233 | /* Set the BAR. Shifted mode */ | 234 | /* Set the BAR. Shifted mode */ |
234 | OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR); | 235 | OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR); |
235 | OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0); | 236 | OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0); |
236 | #endif | 237 | #endif |
237 | } | 238 | } |
238 | 239 |
arch/ppc/platforms/4xx/bamboo.c
1 | /* | 1 | /* |
2 | * Bamboo board specific routines | 2 | * Bamboo board specific routines |
3 | * | 3 | * |
4 | * Wade Farnsworth <wfarnsworth@mvista.com> | 4 | * Wade Farnsworth <wfarnsworth@mvista.com> |
5 | * Copyright 2004 MontaVista Software Inc. | 5 | * Copyright 2004 MontaVista Software Inc. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
9 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * Free Software Foundation; either version 2 of the License, or (at your |
10 | * option) any later version. | 10 | * option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/reboot.h> | 17 | #include <linux/reboot.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/kdev_t.h> | 19 | #include <linux/kdev_t.h> |
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/major.h> | 21 | #include <linux/major.h> |
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/console.h> | 23 | #include <linux/console.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/ide.h> | 25 | #include <linux/ide.h> |
26 | #include <linux/initrd.h> | 26 | #include <linux/initrd.h> |
27 | #include <linux/seq_file.h> | 27 | #include <linux/seq_file.h> |
28 | #include <linux/root_dev.h> | 28 | #include <linux/root_dev.h> |
29 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
30 | #include <linux/serial.h> | 30 | #include <linux/serial.h> |
31 | #include <linux/serial_core.h> | 31 | #include <linux/serial_core.h> |
32 | #include <linux/serial_8250.h> | ||
32 | #include <linux/ethtool.h> | 33 | #include <linux/ethtool.h> |
33 | 34 | ||
34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
36 | #include <asm/page.h> | 37 | #include <asm/page.h> |
37 | #include <asm/dma.h> | 38 | #include <asm/dma.h> |
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
40 | #include <asm/ocp.h> | 41 | #include <asm/ocp.h> |
41 | #include <asm/pci-bridge.h> | 42 | #include <asm/pci-bridge.h> |
42 | #include <asm/time.h> | 43 | #include <asm/time.h> |
43 | #include <asm/todc.h> | 44 | #include <asm/todc.h> |
44 | #include <asm/bootinfo.h> | 45 | #include <asm/bootinfo.h> |
45 | #include <asm/ppc4xx_pic.h> | 46 | #include <asm/ppc4xx_pic.h> |
46 | #include <asm/ppcboot.h> | 47 | #include <asm/ppcboot.h> |
47 | 48 | ||
48 | #include <syslib/gen550.h> | 49 | #include <syslib/gen550.h> |
49 | #include <syslib/ibm440gx_common.h> | 50 | #include <syslib/ibm440gx_common.h> |
50 | 51 | ||
51 | extern bd_t __res; | 52 | extern bd_t __res; |
52 | 53 | ||
53 | static struct ibm44x_clocks clocks __initdata; | 54 | static struct ibm44x_clocks clocks __initdata; |
54 | 55 | ||
55 | /* | 56 | /* |
56 | * Bamboo external IRQ triggering/polarity settings | 57 | * Bamboo external IRQ triggering/polarity settings |
57 | */ | 58 | */ |
58 | unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = { | 59 | unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = { |
59 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: Ethernet transceiver */ | 60 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: Ethernet transceiver */ |
60 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ1: Expansion connector */ | 61 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ1: Expansion connector */ |
61 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 0 */ | 62 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 0 */ |
62 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 1 */ | 63 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 1 */ |
63 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ4: PCI slot 2 */ | 64 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ4: PCI slot 2 */ |
64 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ5: PCI slot 3 */ | 65 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ5: PCI slot 3 */ |
65 | (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* IRQ6: SMI pushbutton */ | 66 | (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* IRQ6: SMI pushbutton */ |
66 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ7: EXT */ | 67 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ7: EXT */ |
67 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */ | 68 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */ |
68 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */ | 69 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */ |
69 | }; | 70 | }; |
70 | 71 | ||
71 | static void __init | 72 | static void __init |
72 | bamboo_calibrate_decr(void) | 73 | bamboo_calibrate_decr(void) |
73 | { | 74 | { |
74 | unsigned int freq; | 75 | unsigned int freq; |
75 | 76 | ||
76 | if (mfspr(SPRN_CCR1) & CCR1_TCS) | 77 | if (mfspr(SPRN_CCR1) & CCR1_TCS) |
77 | freq = BAMBOO_TMRCLK; | 78 | freq = BAMBOO_TMRCLK; |
78 | else | 79 | else |
79 | freq = clocks.cpu; | 80 | freq = clocks.cpu; |
80 | 81 | ||
81 | ibm44x_calibrate_decr(freq); | 82 | ibm44x_calibrate_decr(freq); |
82 | 83 | ||
83 | } | 84 | } |
84 | 85 | ||
85 | static int | 86 | static int |
86 | bamboo_show_cpuinfo(struct seq_file *m) | 87 | bamboo_show_cpuinfo(struct seq_file *m) |
87 | { | 88 | { |
88 | seq_printf(m, "vendor\t\t: IBM\n"); | 89 | seq_printf(m, "vendor\t\t: IBM\n"); |
89 | seq_printf(m, "machine\t\t: PPC440EP EVB (Bamboo)\n"); | 90 | seq_printf(m, "machine\t\t: PPC440EP EVB (Bamboo)\n"); |
90 | 91 | ||
91 | return 0; | 92 | return 0; |
92 | } | 93 | } |
93 | 94 | ||
94 | static inline int | 95 | static inline int |
95 | bamboo_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 96 | bamboo_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
96 | { | 97 | { |
97 | static char pci_irq_table[][4] = | 98 | static char pci_irq_table[][4] = |
98 | /* | 99 | /* |
99 | * PCI IDSEL/INTPIN->INTLINE | 100 | * PCI IDSEL/INTPIN->INTLINE |
100 | * A B C D | 101 | * A B C D |
101 | */ | 102 | */ |
102 | { | 103 | { |
103 | { 28, 28, 28, 28 }, /* IDSEL 1 - PCI Slot 0 */ | 104 | { 28, 28, 28, 28 }, /* IDSEL 1 - PCI Slot 0 */ |
104 | { 27, 27, 27, 27 }, /* IDSEL 2 - PCI Slot 1 */ | 105 | { 27, 27, 27, 27 }, /* IDSEL 2 - PCI Slot 1 */ |
105 | { 26, 26, 26, 26 }, /* IDSEL 3 - PCI Slot 2 */ | 106 | { 26, 26, 26, 26 }, /* IDSEL 3 - PCI Slot 2 */ |
106 | { 25, 25, 25, 25 }, /* IDSEL 4 - PCI Slot 3 */ | 107 | { 25, 25, 25, 25 }, /* IDSEL 4 - PCI Slot 3 */ |
107 | }; | 108 | }; |
108 | 109 | ||
109 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 110 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
110 | return PCI_IRQ_TABLE_LOOKUP; | 111 | return PCI_IRQ_TABLE_LOOKUP; |
111 | } | 112 | } |
112 | 113 | ||
113 | static void __init bamboo_set_emacdata(void) | 114 | static void __init bamboo_set_emacdata(void) |
114 | { | 115 | { |
115 | u8 * base_addr; | 116 | u8 * base_addr; |
116 | struct ocp_def *def; | 117 | struct ocp_def *def; |
117 | struct ocp_func_emac_data *emacdata; | 118 | struct ocp_func_emac_data *emacdata; |
118 | u8 val; | 119 | u8 val; |
119 | int mode; | 120 | int mode; |
120 | u32 excluded = 0; | 121 | u32 excluded = 0; |
121 | 122 | ||
122 | base_addr = ioremap64(BAMBOO_FPGA_SELECTION1_REG_ADDR, 16); | 123 | base_addr = ioremap64(BAMBOO_FPGA_SELECTION1_REG_ADDR, 16); |
123 | val = readb(base_addr); | 124 | val = readb(base_addr); |
124 | iounmap((void *) base_addr); | 125 | iounmap((void *) base_addr); |
125 | if (BAMBOO_SEL_MII(val)) | 126 | if (BAMBOO_SEL_MII(val)) |
126 | mode = PHY_MODE_MII; | 127 | mode = PHY_MODE_MII; |
127 | else if (BAMBOO_SEL_RMII(val)) | 128 | else if (BAMBOO_SEL_RMII(val)) |
128 | mode = PHY_MODE_RMII; | 129 | mode = PHY_MODE_RMII; |
129 | else | 130 | else |
130 | mode = PHY_MODE_SMII; | 131 | mode = PHY_MODE_SMII; |
131 | 132 | ||
132 | /* | 133 | /* |
133 | * SW2 on the Bamboo is used for ethernet configuration and is accessed | 134 | * SW2 on the Bamboo is used for ethernet configuration and is accessed |
134 | * via the CONFIG2 register in the FPGA. If the ANEG pin is set, | 135 | * via the CONFIG2 register in the FPGA. If the ANEG pin is set, |
135 | * overwrite the supported features with the settings in SW2. | 136 | * overwrite the supported features with the settings in SW2. |
136 | * | 137 | * |
137 | * This is used as a workaround for the improperly biased RJ-45 sockets | 138 | * This is used as a workaround for the improperly biased RJ-45 sockets |
138 | * on the Rev. 0 Bamboo. By default only 10baseT is functional. | 139 | * on the Rev. 0 Bamboo. By default only 10baseT is functional. |
139 | * Removing inductors L17 and L18 from the board allows 100baseT, but | 140 | * Removing inductors L17 and L18 from the board allows 100baseT, but |
140 | * disables 10baseT. The Rev. 1 has no such limitations. | 141 | * disables 10baseT. The Rev. 1 has no such limitations. |
141 | */ | 142 | */ |
142 | 143 | ||
143 | base_addr = ioremap64(BAMBOO_FPGA_CONFIG2_REG_ADDR, 8); | 144 | base_addr = ioremap64(BAMBOO_FPGA_CONFIG2_REG_ADDR, 8); |
144 | val = readb(base_addr); | 145 | val = readb(base_addr); |
145 | iounmap((void *) base_addr); | 146 | iounmap((void *) base_addr); |
146 | if (!BAMBOO_AUTONEGOTIATE(val)) { | 147 | if (!BAMBOO_AUTONEGOTIATE(val)) { |
147 | excluded |= SUPPORTED_Autoneg; | 148 | excluded |= SUPPORTED_Autoneg; |
148 | if (BAMBOO_FORCE_100Mbps(val)) { | 149 | if (BAMBOO_FORCE_100Mbps(val)) { |
149 | excluded |= SUPPORTED_10baseT_Full; | 150 | excluded |= SUPPORTED_10baseT_Full; |
150 | excluded |= SUPPORTED_10baseT_Half; | 151 | excluded |= SUPPORTED_10baseT_Half; |
151 | if (BAMBOO_FULL_DUPLEX_EN(val)) | 152 | if (BAMBOO_FULL_DUPLEX_EN(val)) |
152 | excluded |= SUPPORTED_100baseT_Half; | 153 | excluded |= SUPPORTED_100baseT_Half; |
153 | else | 154 | else |
154 | excluded |= SUPPORTED_100baseT_Full; | 155 | excluded |= SUPPORTED_100baseT_Full; |
155 | } else { | 156 | } else { |
156 | excluded |= SUPPORTED_100baseT_Full; | 157 | excluded |= SUPPORTED_100baseT_Full; |
157 | excluded |= SUPPORTED_100baseT_Half; | 158 | excluded |= SUPPORTED_100baseT_Half; |
158 | if (BAMBOO_FULL_DUPLEX_EN(val)) | 159 | if (BAMBOO_FULL_DUPLEX_EN(val)) |
159 | excluded |= SUPPORTED_10baseT_Half; | 160 | excluded |= SUPPORTED_10baseT_Half; |
160 | else | 161 | else |
161 | excluded |= SUPPORTED_10baseT_Full; | 162 | excluded |= SUPPORTED_10baseT_Full; |
162 | } | 163 | } |
163 | } | 164 | } |
164 | 165 | ||
165 | /* Set mac_addr, phy mode and unsupported phy features for each EMAC */ | 166 | /* Set mac_addr, phy mode and unsupported phy features for each EMAC */ |
166 | 167 | ||
167 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); | 168 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); |
168 | emacdata = def->additions; | 169 | emacdata = def->additions; |
169 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); | 170 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); |
170 | emacdata->phy_mode = mode; | 171 | emacdata->phy_mode = mode; |
171 | emacdata->phy_feat_exc = excluded; | 172 | emacdata->phy_feat_exc = excluded; |
172 | 173 | ||
173 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1); | 174 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1); |
174 | emacdata = def->additions; | 175 | emacdata = def->additions; |
175 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); | 176 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); |
176 | emacdata->phy_mode = mode; | 177 | emacdata->phy_mode = mode; |
177 | emacdata->phy_feat_exc = excluded; | 178 | emacdata->phy_feat_exc = excluded; |
178 | } | 179 | } |
179 | 180 | ||
180 | static int | 181 | static int |
181 | bamboo_exclude_device(unsigned char bus, unsigned char devfn) | 182 | bamboo_exclude_device(unsigned char bus, unsigned char devfn) |
182 | { | 183 | { |
183 | return (bus == 0 && devfn == 0); | 184 | return (bus == 0 && devfn == 0); |
184 | } | 185 | } |
185 | 186 | ||
186 | #define PCI_READW(offset) \ | 187 | #define PCI_READW(offset) \ |
187 | (readw((void *)((u32)pci_reg_base+offset))) | 188 | (readw((void *)((u32)pci_reg_base+offset))) |
188 | 189 | ||
189 | #define PCI_WRITEW(value, offset) \ | 190 | #define PCI_WRITEW(value, offset) \ |
190 | (writew(value, (void *)((u32)pci_reg_base+offset))) | 191 | (writew(value, (void *)((u32)pci_reg_base+offset))) |
191 | 192 | ||
192 | #define PCI_WRITEL(value, offset) \ | 193 | #define PCI_WRITEL(value, offset) \ |
193 | (writel(value, (void *)((u32)pci_reg_base+offset))) | 194 | (writel(value, (void *)((u32)pci_reg_base+offset))) |
194 | 195 | ||
195 | static void __init | 196 | static void __init |
196 | bamboo_setup_pci(void) | 197 | bamboo_setup_pci(void) |
197 | { | 198 | { |
198 | void *pci_reg_base; | 199 | void *pci_reg_base; |
199 | unsigned long memory_size; | 200 | unsigned long memory_size; |
200 | memory_size = ppc_md.find_end_of_memory(); | 201 | memory_size = ppc_md.find_end_of_memory(); |
201 | 202 | ||
202 | pci_reg_base = ioremap64(BAMBOO_PCIL0_BASE, BAMBOO_PCIL0_SIZE); | 203 | pci_reg_base = ioremap64(BAMBOO_PCIL0_BASE, BAMBOO_PCIL0_SIZE); |
203 | 204 | ||
204 | /* Enable PCI I/O, Mem, and Busmaster cycles */ | 205 | /* Enable PCI I/O, Mem, and Busmaster cycles */ |
205 | PCI_WRITEW(PCI_READW(PCI_COMMAND) | | 206 | PCI_WRITEW(PCI_READW(PCI_COMMAND) | |
206 | PCI_COMMAND_MEMORY | | 207 | PCI_COMMAND_MEMORY | |
207 | PCI_COMMAND_MASTER, PCI_COMMAND); | 208 | PCI_COMMAND_MASTER, PCI_COMMAND); |
208 | 209 | ||
209 | /* Disable region first */ | 210 | /* Disable region first */ |
210 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM0MA); | 211 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM0MA); |
211 | 212 | ||
212 | /* PLB starting addr: 0x00000000A0000000 */ | 213 | /* PLB starting addr: 0x00000000A0000000 */ |
213 | PCI_WRITEL(BAMBOO_PCI_PHY_MEM_BASE, BAMBOO_PCIL0_PMM0LA); | 214 | PCI_WRITEL(BAMBOO_PCI_PHY_MEM_BASE, BAMBOO_PCIL0_PMM0LA); |
214 | 215 | ||
215 | /* PCI start addr, 0xA0000000 (PCI Address) */ | 216 | /* PCI start addr, 0xA0000000 (PCI Address) */ |
216 | PCI_WRITEL(BAMBOO_PCI_MEM_BASE, BAMBOO_PCIL0_PMM0PCILA); | 217 | PCI_WRITEL(BAMBOO_PCI_MEM_BASE, BAMBOO_PCIL0_PMM0PCILA); |
217 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM0PCIHA); | 218 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM0PCIHA); |
218 | 219 | ||
219 | /* Enable no pre-fetch, enable region */ | 220 | /* Enable no pre-fetch, enable region */ |
220 | PCI_WRITEL(((0xffffffff - | 221 | PCI_WRITEL(((0xffffffff - |
221 | (BAMBOO_PCI_UPPER_MEM - BAMBOO_PCI_MEM_BASE)) | 0x01), | 222 | (BAMBOO_PCI_UPPER_MEM - BAMBOO_PCI_MEM_BASE)) | 0x01), |
222 | BAMBOO_PCIL0_PMM0MA); | 223 | BAMBOO_PCIL0_PMM0MA); |
223 | 224 | ||
224 | /* Disable region one */ | 225 | /* Disable region one */ |
225 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA); | 226 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA); |
226 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1LA); | 227 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1LA); |
227 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCILA); | 228 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCILA); |
228 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCIHA); | 229 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCIHA); |
229 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA); | 230 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA); |
230 | 231 | ||
231 | /* Disable region two */ | 232 | /* Disable region two */ |
232 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA); | 233 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA); |
233 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2LA); | 234 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2LA); |
234 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCILA); | 235 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCILA); |
235 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCIHA); | 236 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCIHA); |
236 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA); | 237 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA); |
237 | 238 | ||
238 | /* Now configure the PCI->PLB windows, we only use PTM1 | 239 | /* Now configure the PCI->PLB windows, we only use PTM1 |
239 | * | 240 | * |
240 | * For Inbound flow, set the window size to all available memory | 241 | * For Inbound flow, set the window size to all available memory |
241 | * This is required because if size is smaller, | 242 | * This is required because if size is smaller, |
242 | * then Eth/PCI DD would fail as PCI card not able to access | 243 | * then Eth/PCI DD would fail as PCI card not able to access |
243 | * the memory allocated by DD. | 244 | * the memory allocated by DD. |
244 | */ | 245 | */ |
245 | 246 | ||
246 | PCI_WRITEL(0, BAMBOO_PCIL0_PTM1MS); /* disabled region 1 */ | 247 | PCI_WRITEL(0, BAMBOO_PCIL0_PTM1MS); /* disabled region 1 */ |
247 | PCI_WRITEL(0, BAMBOO_PCIL0_PTM1LA); /* begin of address map */ | 248 | PCI_WRITEL(0, BAMBOO_PCIL0_PTM1LA); /* begin of address map */ |
248 | 249 | ||
249 | memory_size = 1 << fls(memory_size - 1); | 250 | memory_size = 1 << fls(memory_size - 1); |
250 | 251 | ||
251 | /* Size low + Enabled */ | 252 | /* Size low + Enabled */ |
252 | PCI_WRITEL((0xffffffff - (memory_size - 1)) | 0x1, BAMBOO_PCIL0_PTM1MS); | 253 | PCI_WRITEL((0xffffffff - (memory_size - 1)) | 0x1, BAMBOO_PCIL0_PTM1MS); |
253 | 254 | ||
254 | eieio(); | 255 | eieio(); |
255 | iounmap(pci_reg_base); | 256 | iounmap(pci_reg_base); |
256 | } | 257 | } |
257 | 258 | ||
258 | static void __init | 259 | static void __init |
259 | bamboo_setup_hose(void) | 260 | bamboo_setup_hose(void) |
260 | { | 261 | { |
261 | unsigned int bar_response, bar; | 262 | unsigned int bar_response, bar; |
262 | struct pci_controller *hose; | 263 | struct pci_controller *hose; |
263 | 264 | ||
264 | bamboo_setup_pci(); | 265 | bamboo_setup_pci(); |
265 | 266 | ||
266 | hose = pcibios_alloc_controller(); | 267 | hose = pcibios_alloc_controller(); |
267 | 268 | ||
268 | if (!hose) | 269 | if (!hose) |
269 | return; | 270 | return; |
270 | 271 | ||
271 | hose->first_busno = 0; | 272 | hose->first_busno = 0; |
272 | hose->last_busno = 0xff; | 273 | hose->last_busno = 0xff; |
273 | 274 | ||
274 | hose->pci_mem_offset = BAMBOO_PCI_MEM_OFFSET; | 275 | hose->pci_mem_offset = BAMBOO_PCI_MEM_OFFSET; |
275 | 276 | ||
276 | pci_init_resource(&hose->io_resource, | 277 | pci_init_resource(&hose->io_resource, |
277 | BAMBOO_PCI_LOWER_IO, | 278 | BAMBOO_PCI_LOWER_IO, |
278 | BAMBOO_PCI_UPPER_IO, | 279 | BAMBOO_PCI_UPPER_IO, |
279 | IORESOURCE_IO, | 280 | IORESOURCE_IO, |
280 | "PCI host bridge"); | 281 | "PCI host bridge"); |
281 | 282 | ||
282 | pci_init_resource(&hose->mem_resources[0], | 283 | pci_init_resource(&hose->mem_resources[0], |
283 | BAMBOO_PCI_LOWER_MEM, | 284 | BAMBOO_PCI_LOWER_MEM, |
284 | BAMBOO_PCI_UPPER_MEM, | 285 | BAMBOO_PCI_UPPER_MEM, |
285 | IORESOURCE_MEM, | 286 | IORESOURCE_MEM, |
286 | "PCI host bridge"); | 287 | "PCI host bridge"); |
287 | 288 | ||
288 | ppc_md.pci_exclude_device = bamboo_exclude_device; | 289 | ppc_md.pci_exclude_device = bamboo_exclude_device; |
289 | 290 | ||
290 | hose->io_space.start = BAMBOO_PCI_LOWER_IO; | 291 | hose->io_space.start = BAMBOO_PCI_LOWER_IO; |
291 | hose->io_space.end = BAMBOO_PCI_UPPER_IO; | 292 | hose->io_space.end = BAMBOO_PCI_UPPER_IO; |
292 | hose->mem_space.start = BAMBOO_PCI_LOWER_MEM; | 293 | hose->mem_space.start = BAMBOO_PCI_LOWER_MEM; |
293 | hose->mem_space.end = BAMBOO_PCI_UPPER_MEM; | 294 | hose->mem_space.end = BAMBOO_PCI_UPPER_MEM; |
294 | isa_io_base = | 295 | isa_io_base = |
295 | (unsigned long)ioremap64(BAMBOO_PCI_IO_BASE, BAMBOO_PCI_IO_SIZE); | 296 | (unsigned long)ioremap64(BAMBOO_PCI_IO_BASE, BAMBOO_PCI_IO_SIZE); |
296 | hose->io_base_virt = (void *)isa_io_base; | 297 | hose->io_base_virt = (void *)isa_io_base; |
297 | 298 | ||
298 | setup_indirect_pci(hose, | 299 | setup_indirect_pci(hose, |
299 | BAMBOO_PCI_CFGA_PLB32, | 300 | BAMBOO_PCI_CFGA_PLB32, |
300 | BAMBOO_PCI_CFGD_PLB32); | 301 | BAMBOO_PCI_CFGD_PLB32); |
301 | hose->set_cfg_type = 1; | 302 | hose->set_cfg_type = 1; |
302 | 303 | ||
303 | /* Zero config bars */ | 304 | /* Zero config bars */ |
304 | for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { | 305 | for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { |
305 | early_write_config_dword(hose, hose->first_busno, | 306 | early_write_config_dword(hose, hose->first_busno, |
306 | PCI_FUNC(hose->first_busno), bar, | 307 | PCI_FUNC(hose->first_busno), bar, |
307 | 0x00000000); | 308 | 0x00000000); |
308 | early_read_config_dword(hose, hose->first_busno, | 309 | early_read_config_dword(hose, hose->first_busno, |
309 | PCI_FUNC(hose->first_busno), bar, | 310 | PCI_FUNC(hose->first_busno), bar, |
310 | &bar_response); | 311 | &bar_response); |
311 | } | 312 | } |
312 | 313 | ||
313 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | 314 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); |
314 | 315 | ||
315 | ppc_md.pci_swizzle = common_swizzle; | 316 | ppc_md.pci_swizzle = common_swizzle; |
316 | ppc_md.pci_map_irq = bamboo_map_irq; | 317 | ppc_md.pci_map_irq = bamboo_map_irq; |
317 | } | 318 | } |
318 | 319 | ||
319 | TODC_ALLOC(); | 320 | TODC_ALLOC(); |
320 | 321 | ||
321 | static void __init | 322 | static void __init |
322 | bamboo_early_serial_map(void) | 323 | bamboo_early_serial_map(void) |
323 | { | 324 | { |
324 | struct uart_port port; | 325 | struct uart_port port; |
325 | 326 | ||
326 | /* Setup ioremapped serial port access */ | 327 | /* Setup ioremapped serial port access */ |
327 | memset(&port, 0, sizeof(port)); | 328 | memset(&port, 0, sizeof(port)); |
328 | port.membase = ioremap64(PPC440EP_UART0_ADDR, 8); | 329 | port.membase = ioremap64(PPC440EP_UART0_ADDR, 8); |
329 | port.irq = 0; | 330 | port.irq = 0; |
330 | port.uartclk = clocks.uart0; | 331 | port.uartclk = clocks.uart0; |
331 | port.regshift = 0; | 332 | port.regshift = 0; |
332 | port.iotype = UPIO_MEM; | 333 | port.iotype = UPIO_MEM; |
333 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 334 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
334 | port.line = 0; | 335 | port.line = 0; |
335 | 336 | ||
336 | if (early_serial_setup(&port) != 0) { | 337 | if (early_serial_setup(&port) != 0) { |
337 | printk("Early serial init of port 0 failed\n"); | 338 | printk("Early serial init of port 0 failed\n"); |
338 | } | 339 | } |
339 | 340 | ||
340 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 341 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
341 | /* Configure debug serial access */ | 342 | /* Configure debug serial access */ |
342 | gen550_init(0, &port); | 343 | gen550_init(0, &port); |
343 | #endif | 344 | #endif |
344 | 345 | ||
345 | port.membase = ioremap64(PPC440EP_UART1_ADDR, 8); | 346 | port.membase = ioremap64(PPC440EP_UART1_ADDR, 8); |
346 | port.irq = 1; | 347 | port.irq = 1; |
347 | port.uartclk = clocks.uart1; | 348 | port.uartclk = clocks.uart1; |
348 | port.line = 1; | 349 | port.line = 1; |
349 | 350 | ||
350 | if (early_serial_setup(&port) != 0) { | 351 | if (early_serial_setup(&port) != 0) { |
351 | printk("Early serial init of port 1 failed\n"); | 352 | printk("Early serial init of port 1 failed\n"); |
352 | } | 353 | } |
353 | 354 | ||
354 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 355 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
355 | /* Configure debug serial access */ | 356 | /* Configure debug serial access */ |
356 | gen550_init(1, &port); | 357 | gen550_init(1, &port); |
357 | #endif | 358 | #endif |
358 | 359 | ||
359 | port.membase = ioremap64(PPC440EP_UART2_ADDR, 8); | 360 | port.membase = ioremap64(PPC440EP_UART2_ADDR, 8); |
360 | port.irq = 3; | 361 | port.irq = 3; |
361 | port.uartclk = clocks.uart2; | 362 | port.uartclk = clocks.uart2; |
362 | port.line = 2; | 363 | port.line = 2; |
363 | 364 | ||
364 | if (early_serial_setup(&port) != 0) { | 365 | if (early_serial_setup(&port) != 0) { |
365 | printk("Early serial init of port 2 failed\n"); | 366 | printk("Early serial init of port 2 failed\n"); |
366 | } | 367 | } |
367 | 368 | ||
368 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 369 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
369 | /* Configure debug serial access */ | 370 | /* Configure debug serial access */ |
370 | gen550_init(2, &port); | 371 | gen550_init(2, &port); |
371 | #endif | 372 | #endif |
372 | 373 | ||
373 | port.membase = ioremap64(PPC440EP_UART3_ADDR, 8); | 374 | port.membase = ioremap64(PPC440EP_UART3_ADDR, 8); |
374 | port.irq = 4; | 375 | port.irq = 4; |
375 | port.uartclk = clocks.uart3; | 376 | port.uartclk = clocks.uart3; |
376 | port.line = 3; | 377 | port.line = 3; |
377 | 378 | ||
378 | if (early_serial_setup(&port) != 0) { | 379 | if (early_serial_setup(&port) != 0) { |
379 | printk("Early serial init of port 3 failed\n"); | 380 | printk("Early serial init of port 3 failed\n"); |
380 | } | 381 | } |
381 | } | 382 | } |
382 | 383 | ||
383 | static void __init | 384 | static void __init |
384 | bamboo_setup_arch(void) | 385 | bamboo_setup_arch(void) |
385 | { | 386 | { |
386 | 387 | ||
387 | bamboo_set_emacdata(); | 388 | bamboo_set_emacdata(); |
388 | 389 | ||
389 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); | 390 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); |
390 | ocp_sys_info.opb_bus_freq = clocks.opb; | 391 | ocp_sys_info.opb_bus_freq = clocks.opb; |
391 | 392 | ||
392 | /* Setup TODC access */ | 393 | /* Setup TODC access */ |
393 | TODC_INIT(TODC_TYPE_DS1743, | 394 | TODC_INIT(TODC_TYPE_DS1743, |
394 | 0, | 395 | 0, |
395 | 0, | 396 | 0, |
396 | ioremap64(BAMBOO_RTC_ADDR, BAMBOO_RTC_SIZE), | 397 | ioremap64(BAMBOO_RTC_ADDR, BAMBOO_RTC_SIZE), |
397 | 8); | 398 | 8); |
398 | 399 | ||
399 | /* init to some ~sane value until calibrate_delay() runs */ | 400 | /* init to some ~sane value until calibrate_delay() runs */ |
400 | loops_per_jiffy = 50000000/HZ; | 401 | loops_per_jiffy = 50000000/HZ; |
401 | 402 | ||
402 | /* Setup PCI host bridge */ | 403 | /* Setup PCI host bridge */ |
403 | bamboo_setup_hose(); | 404 | bamboo_setup_hose(); |
404 | 405 | ||
405 | #ifdef CONFIG_BLK_DEV_INITRD | 406 | #ifdef CONFIG_BLK_DEV_INITRD |
406 | if (initrd_start) | 407 | if (initrd_start) |
407 | ROOT_DEV = Root_RAM0; | 408 | ROOT_DEV = Root_RAM0; |
408 | else | 409 | else |
409 | #endif | 410 | #endif |
410 | #ifdef CONFIG_ROOT_NFS | 411 | #ifdef CONFIG_ROOT_NFS |
411 | ROOT_DEV = Root_NFS; | 412 | ROOT_DEV = Root_NFS; |
412 | #else | 413 | #else |
413 | ROOT_DEV = Root_HDA1; | 414 | ROOT_DEV = Root_HDA1; |
414 | #endif | 415 | #endif |
415 | 416 | ||
416 | bamboo_early_serial_map(); | 417 | bamboo_early_serial_map(); |
417 | 418 | ||
418 | /* Identify the system */ | 419 | /* Identify the system */ |
419 | printk("IBM Bamboo port (MontaVista Software, Inc. (source@mvista.com))\n"); | 420 | printk("IBM Bamboo port (MontaVista Software, Inc. (source@mvista.com))\n"); |
420 | } | 421 | } |
421 | 422 | ||
422 | void __init platform_init(unsigned long r3, unsigned long r4, | 423 | void __init platform_init(unsigned long r3, unsigned long r4, |
423 | unsigned long r5, unsigned long r6, unsigned long r7) | 424 | unsigned long r5, unsigned long r6, unsigned long r7) |
424 | { | 425 | { |
425 | ibm44x_platform_init(r3, r4, r5, r6, r7); | 426 | ibm44x_platform_init(r3, r4, r5, r6, r7); |
426 | 427 | ||
427 | ppc_md.setup_arch = bamboo_setup_arch; | 428 | ppc_md.setup_arch = bamboo_setup_arch; |
428 | ppc_md.show_cpuinfo = bamboo_show_cpuinfo; | 429 | ppc_md.show_cpuinfo = bamboo_show_cpuinfo; |
429 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ | 430 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ |
430 | 431 | ||
431 | ppc_md.calibrate_decr = bamboo_calibrate_decr; | 432 | ppc_md.calibrate_decr = bamboo_calibrate_decr; |
432 | ppc_md.time_init = todc_time_init; | 433 | ppc_md.time_init = todc_time_init; |
433 | ppc_md.set_rtc_time = todc_set_rtc_time; | 434 | ppc_md.set_rtc_time = todc_set_rtc_time; |
434 | ppc_md.get_rtc_time = todc_get_rtc_time; | 435 | ppc_md.get_rtc_time = todc_get_rtc_time; |
435 | 436 | ||
436 | ppc_md.nvram_read_val = todc_direct_read_val; | 437 | ppc_md.nvram_read_val = todc_direct_read_val; |
437 | ppc_md.nvram_write_val = todc_direct_write_val; | 438 | ppc_md.nvram_write_val = todc_direct_write_val; |
438 | #ifdef CONFIG_KGDB | 439 | #ifdef CONFIG_KGDB |
439 | ppc_md.early_serial_map = bamboo_early_serial_map; | 440 | ppc_md.early_serial_map = bamboo_early_serial_map; |
440 | #endif | 441 | #endif |
441 | } | 442 | } |
442 | 443 | ||
443 | 444 |
arch/ppc/platforms/4xx/bubinga.c
1 | /* | 1 | /* |
2 | * Support for IBM PPC 405EP evaluation board (Bubinga). | 2 | * Support for IBM PPC 405EP evaluation board (Bubinga). |
3 | * | 3 | * |
4 | * Author: SAW (IBM), derived from walnut.c. | 4 | * Author: SAW (IBM), derived from walnut.c. |
5 | * Maintained by MontaVista Software <source@mvista.com> | 5 | * Maintained by MontaVista Software <source@mvista.com> |
6 | * | 6 | * |
7 | * 2003 (c) MontaVista Softare Inc. This file is licensed under the | 7 | * 2003 (c) MontaVista Softare Inc. This file is licensed under the |
8 | * terms of the GNU General Public License version 2. This program is | 8 | * terms of the GNU General Public License version 2. This program is |
9 | * licensed "as is" without any warranty of any kind, whether express | 9 | * licensed "as is" without any warranty of any kind, whether express |
10 | * or implied. | 10 | * or implied. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
15 | #include <linux/threads.h> | 15 | #include <linux/threads.h> |
16 | #include <linux/param.h> | 16 | #include <linux/param.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/blkdev.h> | 18 | #include <linux/blkdev.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
21 | #include <linux/tty.h> | 21 | #include <linux/tty.h> |
22 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
23 | #include <linux/serial_core.h> | 23 | #include <linux/serial_core.h> |
24 | #include <linux/serial_8250.h> | ||
24 | 25 | ||
25 | #include <asm/system.h> | 26 | #include <asm/system.h> |
26 | #include <asm/pci-bridge.h> | 27 | #include <asm/pci-bridge.h> |
27 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
28 | #include <asm/machdep.h> | 29 | #include <asm/machdep.h> |
29 | #include <asm/page.h> | 30 | #include <asm/page.h> |
30 | #include <asm/time.h> | 31 | #include <asm/time.h> |
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | #include <asm/todc.h> | 33 | #include <asm/todc.h> |
33 | #include <asm/kgdb.h> | 34 | #include <asm/kgdb.h> |
34 | #include <asm/ocp.h> | 35 | #include <asm/ocp.h> |
35 | #include <asm/ibm_ocp_pci.h> | 36 | #include <asm/ibm_ocp_pci.h> |
36 | 37 | ||
37 | #include <platforms/4xx/ibm405ep.h> | 38 | #include <platforms/4xx/ibm405ep.h> |
38 | 39 | ||
39 | #undef DEBUG | 40 | #undef DEBUG |
40 | 41 | ||
41 | #ifdef DEBUG | 42 | #ifdef DEBUG |
42 | #define DBG(x...) printk(x) | 43 | #define DBG(x...) printk(x) |
43 | #else | 44 | #else |
44 | #define DBG(x...) | 45 | #define DBG(x...) |
45 | #endif | 46 | #endif |
46 | 47 | ||
47 | extern bd_t __res; | 48 | extern bd_t __res; |
48 | 49 | ||
49 | void *bubinga_rtc_base; | 50 | void *bubinga_rtc_base; |
50 | 51 | ||
51 | /* Some IRQs unique to the board | 52 | /* Some IRQs unique to the board |
52 | * Used by the generic 405 PCI setup functions in ppc4xx_pci.c | 53 | * Used by the generic 405 PCI setup functions in ppc4xx_pci.c |
53 | */ | 54 | */ |
54 | int __init | 55 | int __init |
55 | ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 56 | ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
56 | { | 57 | { |
57 | static char pci_irq_table[][4] = | 58 | static char pci_irq_table[][4] = |
58 | /* | 59 | /* |
59 | * PCI IDSEL/INTPIN->INTLINE | 60 | * PCI IDSEL/INTPIN->INTLINE |
60 | * A B C D | 61 | * A B C D |
61 | */ | 62 | */ |
62 | { | 63 | { |
63 | {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */ | 64 | {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */ |
64 | {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */ | 65 | {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */ |
65 | {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */ | 66 | {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */ |
66 | {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */ | 67 | {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */ |
67 | }; | 68 | }; |
68 | 69 | ||
69 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 70 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
70 | return PCI_IRQ_TABLE_LOOKUP; | 71 | return PCI_IRQ_TABLE_LOOKUP; |
71 | }; | 72 | }; |
72 | 73 | ||
73 | /* The serial clock for the chip is an internal clock determined by | 74 | /* The serial clock for the chip is an internal clock determined by |
74 | * different clock speeds/dividers. | 75 | * different clock speeds/dividers. |
75 | * Calculate the proper input baud rate and setup the serial driver. | 76 | * Calculate the proper input baud rate and setup the serial driver. |
76 | */ | 77 | */ |
77 | static void __init | 78 | static void __init |
78 | bubinga_early_serial_map(void) | 79 | bubinga_early_serial_map(void) |
79 | { | 80 | { |
80 | u32 uart_div; | 81 | u32 uart_div; |
81 | int uart_clock; | 82 | int uart_clock; |
82 | struct uart_port port; | 83 | struct uart_port port; |
83 | 84 | ||
84 | /* Calculate the serial clock input frequency | 85 | /* Calculate the serial clock input frequency |
85 | * | 86 | * |
86 | * The base baud is the PLL OUTA (provided in the board info | 87 | * The base baud is the PLL OUTA (provided in the board info |
87 | * structure) divided by the external UART Divisor, divided | 88 | * structure) divided by the external UART Divisor, divided |
88 | * by 16. | 89 | * by 16. |
89 | */ | 90 | */ |
90 | uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV); | 91 | uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV); |
91 | uart_clock = __res.bi_procfreq / uart_div; | 92 | uart_clock = __res.bi_procfreq / uart_div; |
92 | 93 | ||
93 | /* Setup serial port access */ | 94 | /* Setup serial port access */ |
94 | memset(&port, 0, sizeof(port)); | 95 | memset(&port, 0, sizeof(port)); |
95 | port.membase = (void*)ACTING_UART0_IO_BASE; | 96 | port.membase = (void*)ACTING_UART0_IO_BASE; |
96 | port.irq = ACTING_UART0_INT; | 97 | port.irq = ACTING_UART0_INT; |
97 | port.uartclk = uart_clock; | 98 | port.uartclk = uart_clock; |
98 | port.regshift = 0; | 99 | port.regshift = 0; |
99 | port.iotype = UPIO_MEM; | 100 | port.iotype = UPIO_MEM; |
100 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 101 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
101 | port.line = 0; | 102 | port.line = 0; |
102 | 103 | ||
103 | if (early_serial_setup(&port) != 0) { | 104 | if (early_serial_setup(&port) != 0) { |
104 | printk("Early serial init of port 0 failed\n"); | 105 | printk("Early serial init of port 0 failed\n"); |
105 | } | 106 | } |
106 | 107 | ||
107 | port.membase = (void*)ACTING_UART1_IO_BASE; | 108 | port.membase = (void*)ACTING_UART1_IO_BASE; |
108 | port.irq = ACTING_UART1_INT; | 109 | port.irq = ACTING_UART1_INT; |
109 | port.line = 1; | 110 | port.line = 1; |
110 | 111 | ||
111 | if (early_serial_setup(&port) != 0) { | 112 | if (early_serial_setup(&port) != 0) { |
112 | printk("Early serial init of port 1 failed\n"); | 113 | printk("Early serial init of port 1 failed\n"); |
113 | } | 114 | } |
114 | } | 115 | } |
115 | 116 | ||
116 | void __init | 117 | void __init |
117 | bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) | 118 | bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) |
118 | { | 119 | { |
119 | #ifdef CONFIG_PCI | 120 | #ifdef CONFIG_PCI |
120 | 121 | ||
121 | unsigned int bar_response, bar; | 122 | unsigned int bar_response, bar; |
122 | /* | 123 | /* |
123 | * Expected PCI mapping: | 124 | * Expected PCI mapping: |
124 | * | 125 | * |
125 | * PLB addr PCI memory addr | 126 | * PLB addr PCI memory addr |
126 | * --------------------- --------------------- | 127 | * --------------------- --------------------- |
127 | * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff | 128 | * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff |
128 | * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff | 129 | * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff |
129 | * | 130 | * |
130 | * PLB addr PCI io addr | 131 | * PLB addr PCI io addr |
131 | * --------------------- --------------------- | 132 | * --------------------- --------------------- |
132 | * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000 | 133 | * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000 |
133 | * | 134 | * |
134 | * The following code is simplified by assuming that the bootrom | 135 | * The following code is simplified by assuming that the bootrom |
135 | * has been well behaved in following this mapping. | 136 | * has been well behaved in following this mapping. |
136 | */ | 137 | */ |
137 | 138 | ||
138 | #ifdef DEBUG | 139 | #ifdef DEBUG |
139 | int i; | 140 | int i; |
140 | 141 | ||
141 | printk("ioremap PCLIO_BASE = 0x%x\n", pcip); | 142 | printk("ioremap PCLIO_BASE = 0x%x\n", pcip); |
142 | printk("PCI bridge regs before fixup \n"); | 143 | printk("PCI bridge regs before fixup \n"); |
143 | for (i = 0; i <= 3; i++) { | 144 | for (i = 0; i <= 3; i++) { |
144 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); | 145 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); |
145 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); | 146 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); |
146 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); | 147 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); |
147 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); | 148 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); |
148 | } | 149 | } |
149 | printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); | 150 | printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); |
150 | printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); | 151 | printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); |
151 | printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); | 152 | printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); |
152 | printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); | 153 | printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); |
153 | 154 | ||
154 | #endif | 155 | #endif |
155 | 156 | ||
156 | /* added for IBM boot rom version 1.15 bios bar changes -AK */ | 157 | /* added for IBM boot rom version 1.15 bios bar changes -AK */ |
157 | 158 | ||
158 | /* Disable region first */ | 159 | /* Disable region first */ |
159 | out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); | 160 | out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); |
160 | /* PLB starting addr, PCI: 0x80000000 */ | 161 | /* PLB starting addr, PCI: 0x80000000 */ |
161 | out_le32((void *) &(pcip->pmm[0].la), 0x80000000); | 162 | out_le32((void *) &(pcip->pmm[0].la), 0x80000000); |
162 | /* PCI start addr, 0x80000000 */ | 163 | /* PCI start addr, 0x80000000 */ |
163 | out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); | 164 | out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); |
164 | /* 512MB range of PLB to PCI */ | 165 | /* 512MB range of PLB to PCI */ |
165 | out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); | 166 | out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); |
166 | /* Enable no pre-fetch, enable region */ | 167 | /* Enable no pre-fetch, enable region */ |
167 | out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - | 168 | out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - |
168 | (PPC405_PCI_UPPER_MEM - | 169 | (PPC405_PCI_UPPER_MEM - |
169 | PPC405_PCI_MEM_BASE)) | 0x01)); | 170 | PPC405_PCI_MEM_BASE)) | 0x01)); |
170 | 171 | ||
171 | /* Disable region one */ | 172 | /* Disable region one */ |
172 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); | 173 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); |
173 | out_le32((void *) &(pcip->pmm[1].la), 0x00000000); | 174 | out_le32((void *) &(pcip->pmm[1].la), 0x00000000); |
174 | out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); | 175 | out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); |
175 | out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); | 176 | out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); |
176 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); | 177 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); |
177 | out_le32((void *) &(pcip->ptm1ms), 0x00000001); | 178 | out_le32((void *) &(pcip->ptm1ms), 0x00000001); |
178 | 179 | ||
179 | /* Disable region two */ | 180 | /* Disable region two */ |
180 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); | 181 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); |
181 | out_le32((void *) &(pcip->pmm[2].la), 0x00000000); | 182 | out_le32((void *) &(pcip->pmm[2].la), 0x00000000); |
182 | out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); | 183 | out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); |
183 | out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); | 184 | out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); |
184 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); | 185 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); |
185 | out_le32((void *) &(pcip->ptm2ms), 0x00000000); | 186 | out_le32((void *) &(pcip->ptm2ms), 0x00000000); |
186 | out_le32((void *) &(pcip->ptm2la), 0x00000000); | 187 | out_le32((void *) &(pcip->ptm2la), 0x00000000); |
187 | 188 | ||
188 | /* Zero config bars */ | 189 | /* Zero config bars */ |
189 | for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { | 190 | for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { |
190 | early_write_config_dword(hose, hose->first_busno, | 191 | early_write_config_dword(hose, hose->first_busno, |
191 | PCI_FUNC(hose->first_busno), bar, | 192 | PCI_FUNC(hose->first_busno), bar, |
192 | 0x00000000); | 193 | 0x00000000); |
193 | early_read_config_dword(hose, hose->first_busno, | 194 | early_read_config_dword(hose, hose->first_busno, |
194 | PCI_FUNC(hose->first_busno), bar, | 195 | PCI_FUNC(hose->first_busno), bar, |
195 | &bar_response); | 196 | &bar_response); |
196 | DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n", | 197 | DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n", |
197 | hose->first_busno, PCI_SLOT(hose->first_busno), | 198 | hose->first_busno, PCI_SLOT(hose->first_busno), |
198 | PCI_FUNC(hose->first_busno), bar, bar_response); | 199 | PCI_FUNC(hose->first_busno), bar, bar_response); |
199 | } | 200 | } |
200 | /* end workaround */ | 201 | /* end workaround */ |
201 | 202 | ||
202 | #ifdef DEBUG | 203 | #ifdef DEBUG |
203 | printk("PCI bridge regs after fixup \n"); | 204 | printk("PCI bridge regs after fixup \n"); |
204 | for (i = 0; i <= 3; i++) { | 205 | for (i = 0; i <= 3; i++) { |
205 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); | 206 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); |
206 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); | 207 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); |
207 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); | 208 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); |
208 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); | 209 | printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); |
209 | } | 210 | } |
210 | printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); | 211 | printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); |
211 | printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); | 212 | printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); |
212 | printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); | 213 | printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); |
213 | printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); | 214 | printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); |
214 | 215 | ||
215 | #endif | 216 | #endif |
216 | #endif | 217 | #endif |
217 | } | 218 | } |
218 | 219 | ||
219 | void __init | 220 | void __init |
220 | bubinga_setup_arch(void) | 221 | bubinga_setup_arch(void) |
221 | { | 222 | { |
222 | ppc4xx_setup_arch(); | 223 | ppc4xx_setup_arch(); |
223 | 224 | ||
224 | ibm_ocp_set_emac(0, 1); | 225 | ibm_ocp_set_emac(0, 1); |
225 | 226 | ||
226 | bubinga_early_serial_map(); | 227 | bubinga_early_serial_map(); |
227 | 228 | ||
228 | /* RTC step for the evb405ep */ | 229 | /* RTC step for the evb405ep */ |
229 | bubinga_rtc_base = (void *) BUBINGA_RTC_VADDR; | 230 | bubinga_rtc_base = (void *) BUBINGA_RTC_VADDR; |
230 | TODC_INIT(TODC_TYPE_DS1743, bubinga_rtc_base, bubinga_rtc_base, | 231 | TODC_INIT(TODC_TYPE_DS1743, bubinga_rtc_base, bubinga_rtc_base, |
231 | bubinga_rtc_base, 8); | 232 | bubinga_rtc_base, 8); |
232 | /* Identify the system */ | 233 | /* Identify the system */ |
233 | printk("IBM Bubinga port (MontaVista Software, Inc. <source@mvista.com>)\n"); | 234 | printk("IBM Bubinga port (MontaVista Software, Inc. <source@mvista.com>)\n"); |
234 | } | 235 | } |
235 | 236 | ||
236 | void __init | 237 | void __init |
237 | bubinga_map_io(void) | 238 | bubinga_map_io(void) |
238 | { | 239 | { |
239 | ppc4xx_map_io(); | 240 | ppc4xx_map_io(); |
240 | io_block_mapping(BUBINGA_RTC_VADDR, | 241 | io_block_mapping(BUBINGA_RTC_VADDR, |
241 | BUBINGA_RTC_PADDR, BUBINGA_RTC_SIZE, _PAGE_IO); | 242 | BUBINGA_RTC_PADDR, BUBINGA_RTC_SIZE, _PAGE_IO); |
242 | } | 243 | } |
243 | 244 | ||
244 | void __init | 245 | void __init |
245 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 246 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
246 | unsigned long r6, unsigned long r7) | 247 | unsigned long r6, unsigned long r7) |
247 | { | 248 | { |
248 | ppc4xx_init(r3, r4, r5, r6, r7); | 249 | ppc4xx_init(r3, r4, r5, r6, r7); |
249 | 250 | ||
250 | ppc_md.setup_arch = bubinga_setup_arch; | 251 | ppc_md.setup_arch = bubinga_setup_arch; |
251 | ppc_md.setup_io_mappings = bubinga_map_io; | 252 | ppc_md.setup_io_mappings = bubinga_map_io; |
252 | 253 | ||
253 | #ifdef CONFIG_GEN_RTC | 254 | #ifdef CONFIG_GEN_RTC |
254 | ppc_md.time_init = todc_time_init; | 255 | ppc_md.time_init = todc_time_init; |
255 | ppc_md.set_rtc_time = todc_set_rtc_time; | 256 | ppc_md.set_rtc_time = todc_set_rtc_time; |
256 | ppc_md.get_rtc_time = todc_get_rtc_time; | 257 | ppc_md.get_rtc_time = todc_get_rtc_time; |
257 | ppc_md.nvram_read_val = todc_direct_read_val; | 258 | ppc_md.nvram_read_val = todc_direct_read_val; |
258 | ppc_md.nvram_write_val = todc_direct_write_val; | 259 | ppc_md.nvram_write_val = todc_direct_write_val; |
259 | #endif | 260 | #endif |
260 | #ifdef CONFIG_KGDB | 261 | #ifdef CONFIG_KGDB |
261 | ppc_md.early_serial_map = bubinga_early_serial_map; | 262 | ppc_md.early_serial_map = bubinga_early_serial_map; |
262 | #endif | 263 | #endif |
263 | } | 264 | } |
264 | 265 | ||
265 | 266 |
arch/ppc/platforms/4xx/cpci405.c
1 | /* | 1 | /* |
2 | * Board setup routines for the esd CPCI-405 cPCI Board. | 2 | * Board setup routines for the esd CPCI-405 cPCI Board. |
3 | * | 3 | * |
4 | * Copyright 2001-2006 esd electronic system design - hannover germany | 4 | * Copyright 2001-2006 esd electronic system design - hannover germany |
5 | * | 5 | * |
6 | * Authors: Matthias Fuchs | 6 | * Authors: Matthias Fuchs |
7 | * matthias.fuchs@esd-electronics.com | 7 | * matthias.fuchs@esd-electronics.com |
8 | * Stefan Roese | 8 | * Stefan Roese |
9 | * stefan.roese@esd-electronics.com | 9 | * stefan.roese@esd-electronics.com |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
13 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * Free Software Foundation; either version 2 of the License, or (at your |
14 | * option) any later version. | 14 | * option) any later version. |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <asm/system.h> | 20 | #include <asm/system.h> |
21 | #include <asm/pci-bridge.h> | 21 | #include <asm/pci-bridge.h> |
22 | #include <asm/machdep.h> | 22 | #include <asm/machdep.h> |
23 | #include <asm/todc.h> | 23 | #include <asm/todc.h> |
24 | #include <linux/serial.h> | 24 | #include <linux/serial.h> |
25 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
26 | #include <linux/serial_8250.h> | ||
26 | #include <asm/ocp.h> | 27 | #include <asm/ocp.h> |
27 | #include <asm/ibm_ocp_pci.h> | 28 | #include <asm/ibm_ocp_pci.h> |
28 | #include <platforms/4xx/ibm405gp.h> | 29 | #include <platforms/4xx/ibm405gp.h> |
29 | 30 | ||
30 | #ifdef CONFIG_GEN_RTC | 31 | #ifdef CONFIG_GEN_RTC |
31 | void *cpci405_nvram; | 32 | void *cpci405_nvram; |
32 | #endif | 33 | #endif |
33 | 34 | ||
34 | extern bd_t __res; | 35 | extern bd_t __res; |
35 | 36 | ||
36 | /* | 37 | /* |
37 | * Some IRQs unique to CPCI-405. | 38 | * Some IRQs unique to CPCI-405. |
38 | */ | 39 | */ |
39 | int __init | 40 | int __init |
40 | ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 41 | ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
41 | { | 42 | { |
42 | static char pci_irq_table[][4] = | 43 | static char pci_irq_table[][4] = |
43 | /* | 44 | /* |
44 | * PCI IDSEL/INTPIN->INTLINE | 45 | * PCI IDSEL/INTPIN->INTLINE |
45 | * A B C D | 46 | * A B C D |
46 | */ | 47 | */ |
47 | { | 48 | { |
48 | {28, 29, 30, 27}, /* IDSEL 15 - cPCI slot 8 */ | 49 | {28, 29, 30, 27}, /* IDSEL 15 - cPCI slot 8 */ |
49 | {29, 30, 27, 28}, /* IDSEL 16 - cPCI slot 7 */ | 50 | {29, 30, 27, 28}, /* IDSEL 16 - cPCI slot 7 */ |
50 | {30, 27, 28, 29}, /* IDSEL 17 - cPCI slot 6 */ | 51 | {30, 27, 28, 29}, /* IDSEL 17 - cPCI slot 6 */ |
51 | {27, 28, 29, 30}, /* IDSEL 18 - cPCI slot 5 */ | 52 | {27, 28, 29, 30}, /* IDSEL 18 - cPCI slot 5 */ |
52 | {28, 29, 30, 27}, /* IDSEL 19 - cPCI slot 4 */ | 53 | {28, 29, 30, 27}, /* IDSEL 19 - cPCI slot 4 */ |
53 | {29, 30, 27, 28}, /* IDSEL 20 - cPCI slot 3 */ | 54 | {29, 30, 27, 28}, /* IDSEL 20 - cPCI slot 3 */ |
54 | {30, 27, 28, 29}, /* IDSEL 21 - cPCI slot 2 */ | 55 | {30, 27, 28, 29}, /* IDSEL 21 - cPCI slot 2 */ |
55 | }; | 56 | }; |
56 | const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4; | 57 | const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4; |
57 | return PCI_IRQ_TABLE_LOOKUP; | 58 | return PCI_IRQ_TABLE_LOOKUP; |
58 | }; | 59 | }; |
59 | 60 | ||
60 | /* The serial clock for the chip is an internal clock determined by | 61 | /* The serial clock for the chip is an internal clock determined by |
61 | * different clock speeds/dividers. | 62 | * different clock speeds/dividers. |
62 | * Calculate the proper input baud rate and setup the serial driver. | 63 | * Calculate the proper input baud rate and setup the serial driver. |
63 | */ | 64 | */ |
64 | static void __init | 65 | static void __init |
65 | cpci405_early_serial_map(void) | 66 | cpci405_early_serial_map(void) |
66 | { | 67 | { |
67 | u32 uart_div; | 68 | u32 uart_div; |
68 | int uart_clock; | 69 | int uart_clock; |
69 | struct uart_port port; | 70 | struct uart_port port; |
70 | 71 | ||
71 | /* Calculate the serial clock input frequency | 72 | /* Calculate the serial clock input frequency |
72 | * | 73 | * |
73 | * The uart clock is the cpu frequency (provided in the board info | 74 | * The uart clock is the cpu frequency (provided in the board info |
74 | * structure) divided by the external UART Divisor. | 75 | * structure) divided by the external UART Divisor. |
75 | */ | 76 | */ |
76 | uart_div = ((mfdcr(DCRN_CHCR_BASE) & CHR0_UDIV) >> 1) + 1; | 77 | uart_div = ((mfdcr(DCRN_CHCR_BASE) & CHR0_UDIV) >> 1) + 1; |
77 | uart_clock = __res.bi_procfreq / uart_div; | 78 | uart_clock = __res.bi_procfreq / uart_div; |
78 | 79 | ||
79 | /* Setup serial port access */ | 80 | /* Setup serial port access */ |
80 | memset(&port, 0, sizeof(port)); | 81 | memset(&port, 0, sizeof(port)); |
81 | #if defined(CONFIG_UART0_TTYS0) | 82 | #if defined(CONFIG_UART0_TTYS0) |
82 | port.membase = (void*)UART0_IO_BASE; | 83 | port.membase = (void*)UART0_IO_BASE; |
83 | port.irq = UART0_INT; | 84 | port.irq = UART0_INT; |
84 | #else | 85 | #else |
85 | port.membase = (void*)UART1_IO_BASE; | 86 | port.membase = (void*)UART1_IO_BASE; |
86 | port.irq = UART1_INT; | 87 | port.irq = UART1_INT; |
87 | #endif | 88 | #endif |
88 | port.uartclk = uart_clock; | 89 | port.uartclk = uart_clock; |
89 | port.regshift = 0; | 90 | port.regshift = 0; |
90 | port.iotype = UPIO_MEM; | 91 | port.iotype = UPIO_MEM; |
91 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 92 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
92 | port.line = 0; | 93 | port.line = 0; |
93 | 94 | ||
94 | if (early_serial_setup(&port) != 0) { | 95 | if (early_serial_setup(&port) != 0) { |
95 | printk("Early serial init of port 0 failed\n"); | 96 | printk("Early serial init of port 0 failed\n"); |
96 | } | 97 | } |
97 | #if defined(CONFIG_UART0_TTYS0) | 98 | #if defined(CONFIG_UART0_TTYS0) |
98 | port.membase = (void*)UART1_IO_BASE; | 99 | port.membase = (void*)UART1_IO_BASE; |
99 | port.irq = UART1_INT; | 100 | port.irq = UART1_INT; |
100 | #else | 101 | #else |
101 | port.membase = (void*)UART0_IO_BASE; | 102 | port.membase = (void*)UART0_IO_BASE; |
102 | port.irq = UART0_INT; | 103 | port.irq = UART0_INT; |
103 | #endif | 104 | #endif |
104 | port.line = 1; | 105 | port.line = 1; |
105 | 106 | ||
106 | if (early_serial_setup(&port) != 0) { | 107 | if (early_serial_setup(&port) != 0) { |
107 | printk("Early serial init of port 1 failed\n"); | 108 | printk("Early serial init of port 1 failed\n"); |
108 | } | 109 | } |
109 | } | 110 | } |
110 | 111 | ||
111 | void __init | 112 | void __init |
112 | cpci405_setup_arch(void) | 113 | cpci405_setup_arch(void) |
113 | { | 114 | { |
114 | ppc4xx_setup_arch(); | 115 | ppc4xx_setup_arch(); |
115 | 116 | ||
116 | ibm_ocp_set_emac(0, 0); | 117 | ibm_ocp_set_emac(0, 0); |
117 | 118 | ||
118 | cpci405_early_serial_map(); | 119 | cpci405_early_serial_map(); |
119 | 120 | ||
120 | #ifdef CONFIG_GEN_RTC | 121 | #ifdef CONFIG_GEN_RTC |
121 | TODC_INIT(TODC_TYPE_MK48T35, | 122 | TODC_INIT(TODC_TYPE_MK48T35, |
122 | cpci405_nvram, cpci405_nvram, cpci405_nvram, 8); | 123 | cpci405_nvram, cpci405_nvram, cpci405_nvram, 8); |
123 | #endif | 124 | #endif |
124 | } | 125 | } |
125 | 126 | ||
126 | void __init | 127 | void __init |
127 | bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) | 128 | bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) |
128 | { | 129 | { |
129 | #ifdef CONFIG_PCI | 130 | #ifdef CONFIG_PCI |
130 | unsigned int bar_response, bar; | 131 | unsigned int bar_response, bar; |
131 | 132 | ||
132 | /* Disable region first */ | 133 | /* Disable region first */ |
133 | out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); | 134 | out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); |
134 | /* PLB starting addr, PCI: 0x80000000 */ | 135 | /* PLB starting addr, PCI: 0x80000000 */ |
135 | out_le32((void *) &(pcip->pmm[0].la), 0x80000000); | 136 | out_le32((void *) &(pcip->pmm[0].la), 0x80000000); |
136 | /* PCI start addr, 0x80000000 */ | 137 | /* PCI start addr, 0x80000000 */ |
137 | out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); | 138 | out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); |
138 | /* 512MB range of PLB to PCI */ | 139 | /* 512MB range of PLB to PCI */ |
139 | out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); | 140 | out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); |
140 | /* Enable no pre-fetch, enable region */ | 141 | /* Enable no pre-fetch, enable region */ |
141 | out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - | 142 | out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - |
142 | (PPC405_PCI_UPPER_MEM - | 143 | (PPC405_PCI_UPPER_MEM - |
143 | PPC405_PCI_MEM_BASE)) | 0x01)); | 144 | PPC405_PCI_MEM_BASE)) | 0x01)); |
144 | 145 | ||
145 | /* Disable region one */ | 146 | /* Disable region one */ |
146 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); | 147 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); |
147 | out_le32((void *) &(pcip->pmm[1].la), 0x00000000); | 148 | out_le32((void *) &(pcip->pmm[1].la), 0x00000000); |
148 | out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); | 149 | out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); |
149 | out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); | 150 | out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); |
150 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); | 151 | out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); |
151 | out_le32((void *) &(pcip->ptm1ms), 0x00000001); | 152 | out_le32((void *) &(pcip->ptm1ms), 0x00000001); |
152 | 153 | ||
153 | /* Disable region two */ | 154 | /* Disable region two */ |
154 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); | 155 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); |
155 | out_le32((void *) &(pcip->pmm[2].la), 0x00000000); | 156 | out_le32((void *) &(pcip->pmm[2].la), 0x00000000); |
156 | out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); | 157 | out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); |
157 | out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); | 158 | out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); |
158 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); | 159 | out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); |
159 | out_le32((void *) &(pcip->ptm2ms), 0x00000000); | 160 | out_le32((void *) &(pcip->ptm2ms), 0x00000000); |
160 | out_le32((void *) &(pcip->ptm2la), 0x00000000); | 161 | out_le32((void *) &(pcip->ptm2la), 0x00000000); |
161 | 162 | ||
162 | /* Zero config bars */ | 163 | /* Zero config bars */ |
163 | for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { | 164 | for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { |
164 | early_write_config_dword(hose, hose->first_busno, | 165 | early_write_config_dword(hose, hose->first_busno, |
165 | PCI_FUNC(hose->first_busno), bar, | 166 | PCI_FUNC(hose->first_busno), bar, |
166 | 0x00000000); | 167 | 0x00000000); |
167 | early_read_config_dword(hose, hose->first_busno, | 168 | early_read_config_dword(hose, hose->first_busno, |
168 | PCI_FUNC(hose->first_busno), bar, | 169 | PCI_FUNC(hose->first_busno), bar, |
169 | &bar_response); | 170 | &bar_response); |
170 | } | 171 | } |
171 | #endif | 172 | #endif |
172 | } | 173 | } |
173 | 174 | ||
174 | void __init | 175 | void __init |
175 | cpci405_map_io(void) | 176 | cpci405_map_io(void) |
176 | { | 177 | { |
177 | ppc4xx_map_io(); | 178 | ppc4xx_map_io(); |
178 | 179 | ||
179 | #ifdef CONFIG_GEN_RTC | 180 | #ifdef CONFIG_GEN_RTC |
180 | cpci405_nvram = ioremap(CPCI405_NVRAM_PADDR, CPCI405_NVRAM_SIZE); | 181 | cpci405_nvram = ioremap(CPCI405_NVRAM_PADDR, CPCI405_NVRAM_SIZE); |
181 | #endif | 182 | #endif |
182 | } | 183 | } |
183 | 184 | ||
184 | void __init | 185 | void __init |
185 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 186 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
186 | unsigned long r6, unsigned long r7) | 187 | unsigned long r6, unsigned long r7) |
187 | { | 188 | { |
188 | ppc4xx_init(r3, r4, r5, r6, r7); | 189 | ppc4xx_init(r3, r4, r5, r6, r7); |
189 | 190 | ||
190 | ppc_md.setup_arch = cpci405_setup_arch; | 191 | ppc_md.setup_arch = cpci405_setup_arch; |
191 | ppc_md.setup_io_mappings = cpci405_map_io; | 192 | ppc_md.setup_io_mappings = cpci405_map_io; |
192 | 193 | ||
193 | #ifdef CONFIG_GEN_RTC | 194 | #ifdef CONFIG_GEN_RTC |
194 | ppc_md.time_init = todc_time_init; | 195 | ppc_md.time_init = todc_time_init; |
195 | ppc_md.set_rtc_time = todc_set_rtc_time; | 196 | ppc_md.set_rtc_time = todc_set_rtc_time; |
196 | ppc_md.get_rtc_time = todc_get_rtc_time; | 197 | ppc_md.get_rtc_time = todc_get_rtc_time; |
197 | ppc_md.nvram_read_val = todc_direct_read_val; | 198 | ppc_md.nvram_read_val = todc_direct_read_val; |
198 | ppc_md.nvram_write_val = todc_direct_write_val; | 199 | ppc_md.nvram_write_val = todc_direct_write_val; |
199 | #endif | 200 | #endif |
200 | } | 201 | } |
201 | 202 |
arch/ppc/platforms/4xx/ebony.c
1 | /* | 1 | /* |
2 | * Ebony board specific routines | 2 | * Ebony board specific routines |
3 | * | 3 | * |
4 | * Matt Porter <mporter@kernel.crashing.org> | 4 | * Matt Porter <mporter@kernel.crashing.org> |
5 | * Copyright 2002-2005 MontaVista Software Inc. | 5 | * Copyright 2002-2005 MontaVista Software Inc. |
6 | * | 6 | * |
7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | 7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> |
8 | * Copyright (c) 2003-2005 Zultys Technologies | 8 | * Copyright (c) 2003-2005 Zultys Technologies |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
11 | * under the terms of the GNU General Public License as published by the | 11 | * under the terms of the GNU General Public License as published by the |
12 | * Free Software Foundation; either version 2 of the License, or (at your | 12 | * Free Software Foundation; either version 2 of the License, or (at your |
13 | * option) any later version. | 13 | * option) any later version. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/stddef.h> | 16 | #include <linux/stddef.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
20 | #include <linux/reboot.h> | 20 | #include <linux/reboot.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/kdev_t.h> | 22 | #include <linux/kdev_t.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/major.h> | 24 | #include <linux/major.h> |
25 | #include <linux/blkdev.h> | 25 | #include <linux/blkdev.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/ide.h> | 28 | #include <linux/ide.h> |
29 | #include <linux/initrd.h> | 29 | #include <linux/initrd.h> |
30 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
31 | #include <linux/root_dev.h> | 31 | #include <linux/root_dev.h> |
32 | #include <linux/tty.h> | 32 | #include <linux/tty.h> |
33 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
34 | #include <linux/serial_core.h> | 34 | #include <linux/serial_core.h> |
35 | #include <linux/serial_8250.h> | ||
35 | 36 | ||
36 | #include <asm/system.h> | 37 | #include <asm/system.h> |
37 | #include <asm/pgtable.h> | 38 | #include <asm/pgtable.h> |
38 | #include <asm/page.h> | 39 | #include <asm/page.h> |
39 | #include <asm/dma.h> | 40 | #include <asm/dma.h> |
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/machdep.h> | 42 | #include <asm/machdep.h> |
42 | #include <asm/ocp.h> | 43 | #include <asm/ocp.h> |
43 | #include <asm/pci-bridge.h> | 44 | #include <asm/pci-bridge.h> |
44 | #include <asm/time.h> | 45 | #include <asm/time.h> |
45 | #include <asm/todc.h> | 46 | #include <asm/todc.h> |
46 | #include <asm/bootinfo.h> | 47 | #include <asm/bootinfo.h> |
47 | #include <asm/ppc4xx_pic.h> | 48 | #include <asm/ppc4xx_pic.h> |
48 | #include <asm/ppcboot.h> | 49 | #include <asm/ppcboot.h> |
49 | #include <asm/tlbflush.h> | 50 | #include <asm/tlbflush.h> |
50 | 51 | ||
51 | #include <syslib/gen550.h> | 52 | #include <syslib/gen550.h> |
52 | #include <syslib/ibm440gp_common.h> | 53 | #include <syslib/ibm440gp_common.h> |
53 | 54 | ||
54 | extern bd_t __res; | 55 | extern bd_t __res; |
55 | 56 | ||
56 | static struct ibm44x_clocks clocks __initdata; | 57 | static struct ibm44x_clocks clocks __initdata; |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * Ebony external IRQ triggering/polarity settings | 60 | * Ebony external IRQ triggering/polarity settings |
60 | */ | 61 | */ |
61 | unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = { | 62 | unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = { |
62 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: PCI slot 0 */ | 63 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: PCI slot 0 */ |
63 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ1: PCI slot 1 */ | 64 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ1: PCI slot 1 */ |
64 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 2 */ | 65 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 2 */ |
65 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 3 */ | 66 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 3 */ |
66 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ4: IRDA */ | 67 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ4: IRDA */ |
67 | (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* IRQ5: SMI pushbutton */ | 68 | (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* IRQ5: SMI pushbutton */ |
68 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ6: PHYs */ | 69 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ6: PHYs */ |
69 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ7: AUX */ | 70 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ7: AUX */ |
70 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */ | 71 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */ |
71 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */ | 72 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */ |
72 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ10: EXT */ | 73 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ10: EXT */ |
73 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ11: EXT */ | 74 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ11: EXT */ |
74 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ12: EXT */ | 75 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ12: EXT */ |
75 | }; | 76 | }; |
76 | 77 | ||
77 | static void __init | 78 | static void __init |
78 | ebony_calibrate_decr(void) | 79 | ebony_calibrate_decr(void) |
79 | { | 80 | { |
80 | unsigned int freq; | 81 | unsigned int freq; |
81 | 82 | ||
82 | /* | 83 | /* |
83 | * Determine system clock speed | 84 | * Determine system clock speed |
84 | * | 85 | * |
85 | * If we are on Rev. B silicon, then use | 86 | * If we are on Rev. B silicon, then use |
86 | * default external system clock. If we are | 87 | * default external system clock. If we are |
87 | * on Rev. C silicon then errata forces us to | 88 | * on Rev. C silicon then errata forces us to |
88 | * use the internal clock. | 89 | * use the internal clock. |
89 | */ | 90 | */ |
90 | if (strcmp(cur_cpu_spec->cpu_name, "440GP Rev. B") == 0) | 91 | if (strcmp(cur_cpu_spec->cpu_name, "440GP Rev. B") == 0) |
91 | freq = EBONY_440GP_RB_SYSCLK; | 92 | freq = EBONY_440GP_RB_SYSCLK; |
92 | else | 93 | else |
93 | freq = EBONY_440GP_RC_SYSCLK; | 94 | freq = EBONY_440GP_RC_SYSCLK; |
94 | 95 | ||
95 | ibm44x_calibrate_decr(freq); | 96 | ibm44x_calibrate_decr(freq); |
96 | } | 97 | } |
97 | 98 | ||
98 | static int | 99 | static int |
99 | ebony_show_cpuinfo(struct seq_file *m) | 100 | ebony_show_cpuinfo(struct seq_file *m) |
100 | { | 101 | { |
101 | seq_printf(m, "vendor\t\t: IBM\n"); | 102 | seq_printf(m, "vendor\t\t: IBM\n"); |
102 | seq_printf(m, "machine\t\t: Ebony\n"); | 103 | seq_printf(m, "machine\t\t: Ebony\n"); |
103 | 104 | ||
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |
106 | 107 | ||
107 | static inline int | 108 | static inline int |
108 | ebony_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 109 | ebony_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
109 | { | 110 | { |
110 | static char pci_irq_table[][4] = | 111 | static char pci_irq_table[][4] = |
111 | /* | 112 | /* |
112 | * PCI IDSEL/INTPIN->INTLINE | 113 | * PCI IDSEL/INTPIN->INTLINE |
113 | * A B C D | 114 | * A B C D |
114 | */ | 115 | */ |
115 | { | 116 | { |
116 | { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ | 117 | { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ |
117 | { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ | 118 | { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ |
118 | { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ | 119 | { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ |
119 | { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ | 120 | { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ |
120 | }; | 121 | }; |
121 | 122 | ||
122 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 123 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
123 | return PCI_IRQ_TABLE_LOOKUP; | 124 | return PCI_IRQ_TABLE_LOOKUP; |
124 | } | 125 | } |
125 | 126 | ||
126 | #define PCIX_WRITEL(value, offset) \ | 127 | #define PCIX_WRITEL(value, offset) \ |
127 | (writel(value, pcix_reg_base + offset)) | 128 | (writel(value, pcix_reg_base + offset)) |
128 | 129 | ||
129 | /* | 130 | /* |
130 | * FIXME: This is only here to "make it work". This will move | 131 | * FIXME: This is only here to "make it work". This will move |
131 | * to a ibm_pcix.c which will contain a generic IBM PCIX bridge | 132 | * to a ibm_pcix.c which will contain a generic IBM PCIX bridge |
132 | * configuration library. -Matt | 133 | * configuration library. -Matt |
133 | */ | 134 | */ |
134 | static void __init | 135 | static void __init |
135 | ebony_setup_pcix(void) | 136 | ebony_setup_pcix(void) |
136 | { | 137 | { |
137 | void __iomem *pcix_reg_base; | 138 | void __iomem *pcix_reg_base; |
138 | 139 | ||
139 | pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE); | 140 | pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE); |
140 | 141 | ||
141 | /* Disable all windows */ | 142 | /* Disable all windows */ |
142 | PCIX_WRITEL(0, PCIX0_POM0SA); | 143 | PCIX_WRITEL(0, PCIX0_POM0SA); |
143 | PCIX_WRITEL(0, PCIX0_POM1SA); | 144 | PCIX_WRITEL(0, PCIX0_POM1SA); |
144 | PCIX_WRITEL(0, PCIX0_POM2SA); | 145 | PCIX_WRITEL(0, PCIX0_POM2SA); |
145 | PCIX_WRITEL(0, PCIX0_PIM0SA); | 146 | PCIX_WRITEL(0, PCIX0_PIM0SA); |
146 | PCIX_WRITEL(0, PCIX0_PIM1SA); | 147 | PCIX_WRITEL(0, PCIX0_PIM1SA); |
147 | PCIX_WRITEL(0, PCIX0_PIM2SA); | 148 | PCIX_WRITEL(0, PCIX0_PIM2SA); |
148 | 149 | ||
149 | /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ | 150 | /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ |
150 | PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); | 151 | PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); |
151 | PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); | 152 | PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); |
152 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); | 153 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); |
153 | PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); | 154 | PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); |
154 | PCIX_WRITEL(0x80000001, PCIX0_POM0SA); | 155 | PCIX_WRITEL(0x80000001, PCIX0_POM0SA); |
155 | 156 | ||
156 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ | 157 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ |
157 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); | 158 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); |
158 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); | 159 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); |
159 | PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); | 160 | PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); |
160 | 161 | ||
161 | eieio(); | 162 | eieio(); |
162 | } | 163 | } |
163 | 164 | ||
164 | static void __init | 165 | static void __init |
165 | ebony_setup_hose(void) | 166 | ebony_setup_hose(void) |
166 | { | 167 | { |
167 | struct pci_controller *hose; | 168 | struct pci_controller *hose; |
168 | 169 | ||
169 | /* Configure windows on the PCI-X host bridge */ | 170 | /* Configure windows on the PCI-X host bridge */ |
170 | ebony_setup_pcix(); | 171 | ebony_setup_pcix(); |
171 | 172 | ||
172 | hose = pcibios_alloc_controller(); | 173 | hose = pcibios_alloc_controller(); |
173 | 174 | ||
174 | if (!hose) | 175 | if (!hose) |
175 | return; | 176 | return; |
176 | 177 | ||
177 | hose->first_busno = 0; | 178 | hose->first_busno = 0; |
178 | hose->last_busno = 0xff; | 179 | hose->last_busno = 0xff; |
179 | 180 | ||
180 | hose->pci_mem_offset = EBONY_PCI_MEM_OFFSET; | 181 | hose->pci_mem_offset = EBONY_PCI_MEM_OFFSET; |
181 | 182 | ||
182 | pci_init_resource(&hose->io_resource, | 183 | pci_init_resource(&hose->io_resource, |
183 | EBONY_PCI_LOWER_IO, | 184 | EBONY_PCI_LOWER_IO, |
184 | EBONY_PCI_UPPER_IO, | 185 | EBONY_PCI_UPPER_IO, |
185 | IORESOURCE_IO, | 186 | IORESOURCE_IO, |
186 | "PCI host bridge"); | 187 | "PCI host bridge"); |
187 | 188 | ||
188 | pci_init_resource(&hose->mem_resources[0], | 189 | pci_init_resource(&hose->mem_resources[0], |
189 | EBONY_PCI_LOWER_MEM, | 190 | EBONY_PCI_LOWER_MEM, |
190 | EBONY_PCI_UPPER_MEM, | 191 | EBONY_PCI_UPPER_MEM, |
191 | IORESOURCE_MEM, | 192 | IORESOURCE_MEM, |
192 | "PCI host bridge"); | 193 | "PCI host bridge"); |
193 | 194 | ||
194 | hose->io_space.start = EBONY_PCI_LOWER_IO; | 195 | hose->io_space.start = EBONY_PCI_LOWER_IO; |
195 | hose->io_space.end = EBONY_PCI_UPPER_IO; | 196 | hose->io_space.end = EBONY_PCI_UPPER_IO; |
196 | hose->mem_space.start = EBONY_PCI_LOWER_MEM; | 197 | hose->mem_space.start = EBONY_PCI_LOWER_MEM; |
197 | hose->mem_space.end = EBONY_PCI_UPPER_MEM; | 198 | hose->mem_space.end = EBONY_PCI_UPPER_MEM; |
198 | hose->io_base_virt = ioremap64(EBONY_PCI_IO_BASE, EBONY_PCI_IO_SIZE); | 199 | hose->io_base_virt = ioremap64(EBONY_PCI_IO_BASE, EBONY_PCI_IO_SIZE); |
199 | isa_io_base = (unsigned long)hose->io_base_virt; | 200 | isa_io_base = (unsigned long)hose->io_base_virt; |
200 | 201 | ||
201 | setup_indirect_pci(hose, | 202 | setup_indirect_pci(hose, |
202 | EBONY_PCI_CFGA_PLB32, | 203 | EBONY_PCI_CFGA_PLB32, |
203 | EBONY_PCI_CFGD_PLB32); | 204 | EBONY_PCI_CFGD_PLB32); |
204 | hose->set_cfg_type = 1; | 205 | hose->set_cfg_type = 1; |
205 | 206 | ||
206 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | 207 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); |
207 | 208 | ||
208 | ppc_md.pci_swizzle = common_swizzle; | 209 | ppc_md.pci_swizzle = common_swizzle; |
209 | ppc_md.pci_map_irq = ebony_map_irq; | 210 | ppc_md.pci_map_irq = ebony_map_irq; |
210 | } | 211 | } |
211 | 212 | ||
212 | TODC_ALLOC(); | 213 | TODC_ALLOC(); |
213 | 214 | ||
214 | static void __init | 215 | static void __init |
215 | ebony_early_serial_map(void) | 216 | ebony_early_serial_map(void) |
216 | { | 217 | { |
217 | struct uart_port port; | 218 | struct uart_port port; |
218 | 219 | ||
219 | /* Setup ioremapped serial port access */ | 220 | /* Setup ioremapped serial port access */ |
220 | memset(&port, 0, sizeof(port)); | 221 | memset(&port, 0, sizeof(port)); |
221 | port.membase = ioremap64(PPC440GP_UART0_ADDR, 8); | 222 | port.membase = ioremap64(PPC440GP_UART0_ADDR, 8); |
222 | port.irq = 0; | 223 | port.irq = 0; |
223 | port.uartclk = clocks.uart0; | 224 | port.uartclk = clocks.uart0; |
224 | port.regshift = 0; | 225 | port.regshift = 0; |
225 | port.iotype = UPIO_MEM; | 226 | port.iotype = UPIO_MEM; |
226 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 227 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
227 | port.line = 0; | 228 | port.line = 0; |
228 | 229 | ||
229 | if (early_serial_setup(&port) != 0) { | 230 | if (early_serial_setup(&port) != 0) { |
230 | printk("Early serial init of port 0 failed\n"); | 231 | printk("Early serial init of port 0 failed\n"); |
231 | } | 232 | } |
232 | 233 | ||
233 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 234 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
234 | /* Configure debug serial access */ | 235 | /* Configure debug serial access */ |
235 | gen550_init(0, &port); | 236 | gen550_init(0, &port); |
236 | 237 | ||
237 | /* Purge TLB entry added in head_44x.S for early serial access */ | 238 | /* Purge TLB entry added in head_44x.S for early serial access */ |
238 | _tlbie(UART0_IO_BASE); | 239 | _tlbie(UART0_IO_BASE); |
239 | #endif | 240 | #endif |
240 | 241 | ||
241 | port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); | 242 | port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); |
242 | port.irq = 1; | 243 | port.irq = 1; |
243 | port.uartclk = clocks.uart1; | 244 | port.uartclk = clocks.uart1; |
244 | port.line = 1; | 245 | port.line = 1; |
245 | 246 | ||
246 | if (early_serial_setup(&port) != 0) { | 247 | if (early_serial_setup(&port) != 0) { |
247 | printk("Early serial init of port 1 failed\n"); | 248 | printk("Early serial init of port 1 failed\n"); |
248 | } | 249 | } |
249 | 250 | ||
250 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 251 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
251 | /* Configure debug serial access */ | 252 | /* Configure debug serial access */ |
252 | gen550_init(1, &port); | 253 | gen550_init(1, &port); |
253 | #endif | 254 | #endif |
254 | } | 255 | } |
255 | 256 | ||
256 | static void __init | 257 | static void __init |
257 | ebony_setup_arch(void) | 258 | ebony_setup_arch(void) |
258 | { | 259 | { |
259 | struct ocp_def *def; | 260 | struct ocp_def *def; |
260 | struct ocp_func_emac_data *emacdata; | 261 | struct ocp_func_emac_data *emacdata; |
261 | 262 | ||
262 | /* Set mac_addr for each EMAC */ | 263 | /* Set mac_addr for each EMAC */ |
263 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); | 264 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); |
264 | emacdata = def->additions; | 265 | emacdata = def->additions; |
265 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ | 266 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ |
266 | emacdata->phy_mode = PHY_MODE_RMII; | 267 | emacdata->phy_mode = PHY_MODE_RMII; |
267 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); | 268 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); |
268 | 269 | ||
269 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1); | 270 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1); |
270 | emacdata = def->additions; | 271 | emacdata = def->additions; |
271 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ | 272 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ |
272 | emacdata->phy_mode = PHY_MODE_RMII; | 273 | emacdata->phy_mode = PHY_MODE_RMII; |
273 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); | 274 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); |
274 | 275 | ||
275 | /* | 276 | /* |
276 | * Determine various clocks. | 277 | * Determine various clocks. |
277 | * To be completely correct we should get SysClk | 278 | * To be completely correct we should get SysClk |
278 | * from FPGA, because it can be changed by on-board switches | 279 | * from FPGA, because it can be changed by on-board switches |
279 | * --ebs | 280 | * --ebs |
280 | */ | 281 | */ |
281 | ibm440gp_get_clocks(&clocks, 33333333, 6 * 1843200); | 282 | ibm440gp_get_clocks(&clocks, 33333333, 6 * 1843200); |
282 | ocp_sys_info.opb_bus_freq = clocks.opb; | 283 | ocp_sys_info.opb_bus_freq = clocks.opb; |
283 | 284 | ||
284 | /* Setup TODC access */ | 285 | /* Setup TODC access */ |
285 | TODC_INIT(TODC_TYPE_DS1743, | 286 | TODC_INIT(TODC_TYPE_DS1743, |
286 | 0, | 287 | 0, |
287 | 0, | 288 | 0, |
288 | ioremap64(EBONY_RTC_ADDR, EBONY_RTC_SIZE), | 289 | ioremap64(EBONY_RTC_ADDR, EBONY_RTC_SIZE), |
289 | 8); | 290 | 8); |
290 | 291 | ||
291 | /* init to some ~sane value until calibrate_delay() runs */ | 292 | /* init to some ~sane value until calibrate_delay() runs */ |
292 | loops_per_jiffy = 50000000/HZ; | 293 | loops_per_jiffy = 50000000/HZ; |
293 | 294 | ||
294 | /* Setup PCI host bridge */ | 295 | /* Setup PCI host bridge */ |
295 | ebony_setup_hose(); | 296 | ebony_setup_hose(); |
296 | 297 | ||
297 | #ifdef CONFIG_BLK_DEV_INITRD | 298 | #ifdef CONFIG_BLK_DEV_INITRD |
298 | if (initrd_start) | 299 | if (initrd_start) |
299 | ROOT_DEV = Root_RAM0; | 300 | ROOT_DEV = Root_RAM0; |
300 | else | 301 | else |
301 | #endif | 302 | #endif |
302 | #ifdef CONFIG_ROOT_NFS | 303 | #ifdef CONFIG_ROOT_NFS |
303 | ROOT_DEV = Root_NFS; | 304 | ROOT_DEV = Root_NFS; |
304 | #else | 305 | #else |
305 | ROOT_DEV = Root_HDA1; | 306 | ROOT_DEV = Root_HDA1; |
306 | #endif | 307 | #endif |
307 | 308 | ||
308 | ebony_early_serial_map(); | 309 | ebony_early_serial_map(); |
309 | 310 | ||
310 | /* Identify the system */ | 311 | /* Identify the system */ |
311 | printk("IBM Ebony port (MontaVista Software, Inc. (source@mvista.com))\n"); | 312 | printk("IBM Ebony port (MontaVista Software, Inc. (source@mvista.com))\n"); |
312 | } | 313 | } |
313 | 314 | ||
314 | void __init platform_init(unsigned long r3, unsigned long r4, | 315 | void __init platform_init(unsigned long r3, unsigned long r4, |
315 | unsigned long r5, unsigned long r6, unsigned long r7) | 316 | unsigned long r5, unsigned long r6, unsigned long r7) |
316 | { | 317 | { |
317 | ibm44x_platform_init(r3, r4, r5, r6, r7); | 318 | ibm44x_platform_init(r3, r4, r5, r6, r7); |
318 | 319 | ||
319 | ppc_md.setup_arch = ebony_setup_arch; | 320 | ppc_md.setup_arch = ebony_setup_arch; |
320 | ppc_md.show_cpuinfo = ebony_show_cpuinfo; | 321 | ppc_md.show_cpuinfo = ebony_show_cpuinfo; |
321 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ | 322 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ |
322 | 323 | ||
323 | ppc_md.calibrate_decr = ebony_calibrate_decr; | 324 | ppc_md.calibrate_decr = ebony_calibrate_decr; |
324 | ppc_md.time_init = todc_time_init; | 325 | ppc_md.time_init = todc_time_init; |
325 | ppc_md.set_rtc_time = todc_set_rtc_time; | 326 | ppc_md.set_rtc_time = todc_set_rtc_time; |
326 | ppc_md.get_rtc_time = todc_get_rtc_time; | 327 | ppc_md.get_rtc_time = todc_get_rtc_time; |
327 | 328 | ||
328 | ppc_md.nvram_read_val = todc_direct_read_val; | 329 | ppc_md.nvram_read_val = todc_direct_read_val; |
329 | ppc_md.nvram_write_val = todc_direct_write_val; | 330 | ppc_md.nvram_write_val = todc_direct_write_val; |
330 | #ifdef CONFIG_KGDB | 331 | #ifdef CONFIG_KGDB |
331 | ppc_md.early_serial_map = ebony_early_serial_map; | 332 | ppc_md.early_serial_map = ebony_early_serial_map; |
332 | #endif | 333 | #endif |
333 | } | 334 | } |
334 | 335 | ||
335 | 336 |
arch/ppc/platforms/4xx/luan.c
1 | /* | 1 | /* |
2 | * Luan board specific routines | 2 | * Luan board specific routines |
3 | * | 3 | * |
4 | * Matt Porter <mporter@kernel.crashing.org> | 4 | * Matt Porter <mporter@kernel.crashing.org> |
5 | * | 5 | * |
6 | * Copyright 2004-2005 MontaVista Software Inc. | 6 | * Copyright 2004-2005 MontaVista Software Inc. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
10 | * Free Software Foundation; either version 2 of the License, or (at your | 10 | * Free Software Foundation; either version 2 of the License, or (at your |
11 | * option) any later version. | 11 | * option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/stddef.h> | 14 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/kdev_t.h> | 20 | #include <linux/kdev_t.h> |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/major.h> | 22 | #include <linux/major.h> |
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <linux/console.h> | 24 | #include <linux/console.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/ide.h> | 26 | #include <linux/ide.h> |
27 | #include <linux/initrd.h> | 27 | #include <linux/initrd.h> |
28 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
29 | #include <linux/root_dev.h> | 29 | #include <linux/root_dev.h> |
30 | #include <linux/tty.h> | 30 | #include <linux/tty.h> |
31 | #include <linux/serial.h> | 31 | #include <linux/serial.h> |
32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
33 | #include <linux/serial_8250.h> | ||
33 | 34 | ||
34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
36 | #include <asm/page.h> | 37 | #include <asm/page.h> |
37 | #include <asm/dma.h> | 38 | #include <asm/dma.h> |
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
40 | #include <asm/ocp.h> | 41 | #include <asm/ocp.h> |
41 | #include <asm/pci-bridge.h> | 42 | #include <asm/pci-bridge.h> |
42 | #include <asm/time.h> | 43 | #include <asm/time.h> |
43 | #include <asm/todc.h> | 44 | #include <asm/todc.h> |
44 | #include <asm/bootinfo.h> | 45 | #include <asm/bootinfo.h> |
45 | #include <asm/ppc4xx_pic.h> | 46 | #include <asm/ppc4xx_pic.h> |
46 | #include <asm/ppcboot.h> | 47 | #include <asm/ppcboot.h> |
47 | 48 | ||
48 | #include <syslib/ibm44x_common.h> | 49 | #include <syslib/ibm44x_common.h> |
49 | #include <syslib/ibm440gx_common.h> | 50 | #include <syslib/ibm440gx_common.h> |
50 | #include <syslib/ibm440sp_common.h> | 51 | #include <syslib/ibm440sp_common.h> |
51 | 52 | ||
52 | extern bd_t __res; | 53 | extern bd_t __res; |
53 | 54 | ||
54 | static struct ibm44x_clocks clocks __initdata; | 55 | static struct ibm44x_clocks clocks __initdata; |
55 | 56 | ||
56 | static void __init | 57 | static void __init |
57 | luan_calibrate_decr(void) | 58 | luan_calibrate_decr(void) |
58 | { | 59 | { |
59 | unsigned int freq; | 60 | unsigned int freq; |
60 | 61 | ||
61 | if (mfspr(SPRN_CCR1) & CCR1_TCS) | 62 | if (mfspr(SPRN_CCR1) & CCR1_TCS) |
62 | freq = LUAN_TMR_CLK; | 63 | freq = LUAN_TMR_CLK; |
63 | else | 64 | else |
64 | freq = clocks.cpu; | 65 | freq = clocks.cpu; |
65 | 66 | ||
66 | ibm44x_calibrate_decr(freq); | 67 | ibm44x_calibrate_decr(freq); |
67 | } | 68 | } |
68 | 69 | ||
69 | static int | 70 | static int |
70 | luan_show_cpuinfo(struct seq_file *m) | 71 | luan_show_cpuinfo(struct seq_file *m) |
71 | { | 72 | { |
72 | seq_printf(m, "vendor\t\t: IBM\n"); | 73 | seq_printf(m, "vendor\t\t: IBM\n"); |
73 | seq_printf(m, "machine\t\t: PPC440SP EVB (Luan)\n"); | 74 | seq_printf(m, "machine\t\t: PPC440SP EVB (Luan)\n"); |
74 | 75 | ||
75 | return 0; | 76 | return 0; |
76 | } | 77 | } |
77 | 78 | ||
78 | static inline int | 79 | static inline int |
79 | luan_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 80 | luan_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
80 | { | 81 | { |
81 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | 82 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); |
82 | 83 | ||
83 | /* PCIX0 in adapter mode, no host interrupt routing */ | 84 | /* PCIX0 in adapter mode, no host interrupt routing */ |
84 | 85 | ||
85 | /* PCIX1 */ | 86 | /* PCIX1 */ |
86 | if (hose->index == 0) { | 87 | if (hose->index == 0) { |
87 | static char pci_irq_table[][4] = | 88 | static char pci_irq_table[][4] = |
88 | /* | 89 | /* |
89 | * PCI IDSEL/INTPIN->INTLINE | 90 | * PCI IDSEL/INTPIN->INTLINE |
90 | * A B C D | 91 | * A B C D |
91 | */ | 92 | */ |
92 | { | 93 | { |
93 | { 49, 49, 49, 49 }, /* IDSEL 1 - PCIX1 Slot 0 */ | 94 | { 49, 49, 49, 49 }, /* IDSEL 1 - PCIX1 Slot 0 */ |
94 | { 49, 49, 49, 49 }, /* IDSEL 2 - PCIX1 Slot 1 */ | 95 | { 49, 49, 49, 49 }, /* IDSEL 2 - PCIX1 Slot 1 */ |
95 | { 49, 49, 49, 49 }, /* IDSEL 3 - PCIX1 Slot 2 */ | 96 | { 49, 49, 49, 49 }, /* IDSEL 3 - PCIX1 Slot 2 */ |
96 | { 49, 49, 49, 49 }, /* IDSEL 4 - PCIX1 Slot 3 */ | 97 | { 49, 49, 49, 49 }, /* IDSEL 4 - PCIX1 Slot 3 */ |
97 | }; | 98 | }; |
98 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 99 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
99 | return PCI_IRQ_TABLE_LOOKUP; | 100 | return PCI_IRQ_TABLE_LOOKUP; |
100 | /* PCIX2 */ | 101 | /* PCIX2 */ |
101 | } else if (hose->index == 1) { | 102 | } else if (hose->index == 1) { |
102 | static char pci_irq_table[][4] = | 103 | static char pci_irq_table[][4] = |
103 | /* | 104 | /* |
104 | * PCI IDSEL/INTPIN->INTLINE | 105 | * PCI IDSEL/INTPIN->INTLINE |
105 | * A B C D | 106 | * A B C D |
106 | */ | 107 | */ |
107 | { | 108 | { |
108 | { 50, 50, 50, 50 }, /* IDSEL 1 - PCIX2 Slot 0 */ | 109 | { 50, 50, 50, 50 }, /* IDSEL 1 - PCIX2 Slot 0 */ |
109 | { 50, 50, 50, 50 }, /* IDSEL 2 - PCIX2 Slot 1 */ | 110 | { 50, 50, 50, 50 }, /* IDSEL 2 - PCIX2 Slot 1 */ |
110 | { 50, 50, 50, 50 }, /* IDSEL 3 - PCIX2 Slot 2 */ | 111 | { 50, 50, 50, 50 }, /* IDSEL 3 - PCIX2 Slot 2 */ |
111 | { 50, 50, 50, 50 }, /* IDSEL 4 - PCIX2 Slot 3 */ | 112 | { 50, 50, 50, 50 }, /* IDSEL 4 - PCIX2 Slot 3 */ |
112 | }; | 113 | }; |
113 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 114 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
114 | return PCI_IRQ_TABLE_LOOKUP; | 115 | return PCI_IRQ_TABLE_LOOKUP; |
115 | } | 116 | } |
116 | return -1; | 117 | return -1; |
117 | } | 118 | } |
118 | 119 | ||
119 | static void __init luan_set_emacdata(void) | 120 | static void __init luan_set_emacdata(void) |
120 | { | 121 | { |
121 | struct ocp_def *def; | 122 | struct ocp_def *def; |
122 | struct ocp_func_emac_data *emacdata; | 123 | struct ocp_func_emac_data *emacdata; |
123 | 124 | ||
124 | /* Set phy_map, phy_mode, and mac_addr for the EMAC */ | 125 | /* Set phy_map, phy_mode, and mac_addr for the EMAC */ |
125 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); | 126 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); |
126 | emacdata = def->additions; | 127 | emacdata = def->additions; |
127 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ | 128 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ |
128 | emacdata->phy_mode = PHY_MODE_GMII; | 129 | emacdata->phy_mode = PHY_MODE_GMII; |
129 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); | 130 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); |
130 | } | 131 | } |
131 | 132 | ||
132 | #define PCIX_READW(offset) \ | 133 | #define PCIX_READW(offset) \ |
133 | (readw((void *)((u32)pcix_reg_base+offset))) | 134 | (readw((void *)((u32)pcix_reg_base+offset))) |
134 | 135 | ||
135 | #define PCIX_WRITEW(value, offset) \ | 136 | #define PCIX_WRITEW(value, offset) \ |
136 | (writew(value, (void *)((u32)pcix_reg_base+offset))) | 137 | (writew(value, (void *)((u32)pcix_reg_base+offset))) |
137 | 138 | ||
138 | #define PCIX_WRITEL(value, offset) \ | 139 | #define PCIX_WRITEL(value, offset) \ |
139 | (writel(value, (void *)((u32)pcix_reg_base+offset))) | 140 | (writel(value, (void *)((u32)pcix_reg_base+offset))) |
140 | 141 | ||
141 | static void __init | 142 | static void __init |
142 | luan_setup_pcix(void) | 143 | luan_setup_pcix(void) |
143 | { | 144 | { |
144 | int i; | 145 | int i; |
145 | void *pcix_reg_base; | 146 | void *pcix_reg_base; |
146 | 147 | ||
147 | for (i=0;i<3;i++) { | 148 | for (i=0;i<3;i++) { |
148 | pcix_reg_base = ioremap64(PCIX0_REG_BASE + i*PCIX_REG_OFFSET, PCIX_REG_SIZE); | 149 | pcix_reg_base = ioremap64(PCIX0_REG_BASE + i*PCIX_REG_OFFSET, PCIX_REG_SIZE); |
149 | 150 | ||
150 | /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ | 151 | /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ |
151 | PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); | 152 | PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); |
152 | 153 | ||
153 | /* Disable all windows */ | 154 | /* Disable all windows */ |
154 | PCIX_WRITEL(0, PCIX0_POM0SA); | 155 | PCIX_WRITEL(0, PCIX0_POM0SA); |
155 | PCIX_WRITEL(0, PCIX0_POM1SA); | 156 | PCIX_WRITEL(0, PCIX0_POM1SA); |
156 | PCIX_WRITEL(0, PCIX0_POM2SA); | 157 | PCIX_WRITEL(0, PCIX0_POM2SA); |
157 | PCIX_WRITEL(0, PCIX0_PIM0SA); | 158 | PCIX_WRITEL(0, PCIX0_PIM0SA); |
158 | PCIX_WRITEL(0, PCIX0_PIM0SAH); | 159 | PCIX_WRITEL(0, PCIX0_PIM0SAH); |
159 | PCIX_WRITEL(0, PCIX0_PIM1SA); | 160 | PCIX_WRITEL(0, PCIX0_PIM1SA); |
160 | PCIX_WRITEL(0, PCIX0_PIM2SA); | 161 | PCIX_WRITEL(0, PCIX0_PIM2SA); |
161 | PCIX_WRITEL(0, PCIX0_PIM2SAH); | 162 | PCIX_WRITEL(0, PCIX0_PIM2SAH); |
162 | 163 | ||
163 | /* | 164 | /* |
164 | * Setup 512MB PLB->PCI outbound mem window | 165 | * Setup 512MB PLB->PCI outbound mem window |
165 | * (a_n000_0000->0_n000_0000) | 166 | * (a_n000_0000->0_n000_0000) |
166 | * */ | 167 | * */ |
167 | PCIX_WRITEL(0x0000000a, PCIX0_POM0LAH); | 168 | PCIX_WRITEL(0x0000000a, PCIX0_POM0LAH); |
168 | PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0LAL); | 169 | PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0LAL); |
169 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); | 170 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); |
170 | PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0PCIAL); | 171 | PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0PCIAL); |
171 | PCIX_WRITEL(0xe0000001, PCIX0_POM0SA); | 172 | PCIX_WRITEL(0xe0000001, PCIX0_POM0SA); |
172 | 173 | ||
173 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ | 174 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ |
174 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); | 175 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); |
175 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); | 176 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); |
176 | PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA); | 177 | PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA); |
177 | PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH); | 178 | PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH); |
178 | 179 | ||
179 | iounmap(pcix_reg_base); | 180 | iounmap(pcix_reg_base); |
180 | } | 181 | } |
181 | 182 | ||
182 | eieio(); | 183 | eieio(); |
183 | } | 184 | } |
184 | 185 | ||
185 | static void __init | 186 | static void __init |
186 | luan_setup_hose(struct pci_controller *hose, | 187 | luan_setup_hose(struct pci_controller *hose, |
187 | int lower_mem, | 188 | int lower_mem, |
188 | int upper_mem, | 189 | int upper_mem, |
189 | int cfga, | 190 | int cfga, |
190 | int cfgd, | 191 | int cfgd, |
191 | u64 pcix_io_base) | 192 | u64 pcix_io_base) |
192 | { | 193 | { |
193 | char name[20]; | 194 | char name[20]; |
194 | 195 | ||
195 | sprintf(name, "PCIX%d host bridge", hose->index); | 196 | sprintf(name, "PCIX%d host bridge", hose->index); |
196 | 197 | ||
197 | hose->pci_mem_offset = LUAN_PCIX_MEM_OFFSET; | 198 | hose->pci_mem_offset = LUAN_PCIX_MEM_OFFSET; |
198 | 199 | ||
199 | pci_init_resource(&hose->io_resource, | 200 | pci_init_resource(&hose->io_resource, |
200 | LUAN_PCIX_LOWER_IO, | 201 | LUAN_PCIX_LOWER_IO, |
201 | LUAN_PCIX_UPPER_IO, | 202 | LUAN_PCIX_UPPER_IO, |
202 | IORESOURCE_IO, | 203 | IORESOURCE_IO, |
203 | name); | 204 | name); |
204 | 205 | ||
205 | pci_init_resource(&hose->mem_resources[0], | 206 | pci_init_resource(&hose->mem_resources[0], |
206 | lower_mem, | 207 | lower_mem, |
207 | upper_mem, | 208 | upper_mem, |
208 | IORESOURCE_MEM, | 209 | IORESOURCE_MEM, |
209 | name); | 210 | name); |
210 | 211 | ||
211 | hose->io_space.start = LUAN_PCIX_LOWER_IO; | 212 | hose->io_space.start = LUAN_PCIX_LOWER_IO; |
212 | hose->io_space.end = LUAN_PCIX_UPPER_IO; | 213 | hose->io_space.end = LUAN_PCIX_UPPER_IO; |
213 | hose->mem_space.start = lower_mem; | 214 | hose->mem_space.start = lower_mem; |
214 | hose->mem_space.end = upper_mem; | 215 | hose->mem_space.end = upper_mem; |
215 | hose->io_base_virt = ioremap64(pcix_io_base, PCIX_IO_SIZE); | 216 | hose->io_base_virt = ioremap64(pcix_io_base, PCIX_IO_SIZE); |
216 | isa_io_base = (unsigned long) hose->io_base_virt; | 217 | isa_io_base = (unsigned long) hose->io_base_virt; |
217 | 218 | ||
218 | setup_indirect_pci(hose, cfga, cfgd); | 219 | setup_indirect_pci(hose, cfga, cfgd); |
219 | hose->set_cfg_type = 1; | 220 | hose->set_cfg_type = 1; |
220 | } | 221 | } |
221 | 222 | ||
222 | static void __init | 223 | static void __init |
223 | luan_setup_hoses(void) | 224 | luan_setup_hoses(void) |
224 | { | 225 | { |
225 | struct pci_controller *hose1, *hose2; | 226 | struct pci_controller *hose1, *hose2; |
226 | 227 | ||
227 | /* Configure windows on the PCI-X host bridge */ | 228 | /* Configure windows on the PCI-X host bridge */ |
228 | luan_setup_pcix(); | 229 | luan_setup_pcix(); |
229 | 230 | ||
230 | /* Allocate hoses for PCIX1 and PCIX2 */ | 231 | /* Allocate hoses for PCIX1 and PCIX2 */ |
231 | hose1 = pcibios_alloc_controller(); | 232 | hose1 = pcibios_alloc_controller(); |
232 | hose2 = pcibios_alloc_controller(); | 233 | hose2 = pcibios_alloc_controller(); |
233 | if (!hose1 || !hose2) | 234 | if (!hose1 || !hose2) |
234 | return; | 235 | return; |
235 | 236 | ||
236 | /* Setup PCIX1 */ | 237 | /* Setup PCIX1 */ |
237 | hose1->first_busno = 0; | 238 | hose1->first_busno = 0; |
238 | hose1->last_busno = 0xff; | 239 | hose1->last_busno = 0xff; |
239 | 240 | ||
240 | luan_setup_hose(hose1, | 241 | luan_setup_hose(hose1, |
241 | LUAN_PCIX1_LOWER_MEM, | 242 | LUAN_PCIX1_LOWER_MEM, |
242 | LUAN_PCIX1_UPPER_MEM, | 243 | LUAN_PCIX1_UPPER_MEM, |
243 | PCIX1_CFGA, | 244 | PCIX1_CFGA, |
244 | PCIX1_CFGD, | 245 | PCIX1_CFGD, |
245 | PCIX1_IO_BASE); | 246 | PCIX1_IO_BASE); |
246 | 247 | ||
247 | hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno); | 248 | hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno); |
248 | 249 | ||
249 | /* Setup PCIX2 */ | 250 | /* Setup PCIX2 */ |
250 | hose2->first_busno = hose1->last_busno + 1; | 251 | hose2->first_busno = hose1->last_busno + 1; |
251 | hose2->last_busno = 0xff; | 252 | hose2->last_busno = 0xff; |
252 | 253 | ||
253 | luan_setup_hose(hose2, | 254 | luan_setup_hose(hose2, |
254 | LUAN_PCIX2_LOWER_MEM, | 255 | LUAN_PCIX2_LOWER_MEM, |
255 | LUAN_PCIX2_UPPER_MEM, | 256 | LUAN_PCIX2_UPPER_MEM, |
256 | PCIX2_CFGA, | 257 | PCIX2_CFGA, |
257 | PCIX2_CFGD, | 258 | PCIX2_CFGD, |
258 | PCIX2_IO_BASE); | 259 | PCIX2_IO_BASE); |
259 | 260 | ||
260 | hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno); | 261 | hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno); |
261 | 262 | ||
262 | ppc_md.pci_swizzle = common_swizzle; | 263 | ppc_md.pci_swizzle = common_swizzle; |
263 | ppc_md.pci_map_irq = luan_map_irq; | 264 | ppc_md.pci_map_irq = luan_map_irq; |
264 | } | 265 | } |
265 | 266 | ||
266 | TODC_ALLOC(); | 267 | TODC_ALLOC(); |
267 | 268 | ||
268 | static void __init | 269 | static void __init |
269 | luan_early_serial_map(void) | 270 | luan_early_serial_map(void) |
270 | { | 271 | { |
271 | struct uart_port port; | 272 | struct uart_port port; |
272 | 273 | ||
273 | /* Setup ioremapped serial port access */ | 274 | /* Setup ioremapped serial port access */ |
274 | memset(&port, 0, sizeof(port)); | 275 | memset(&port, 0, sizeof(port)); |
275 | port.membase = ioremap64(PPC440SP_UART0_ADDR, 8); | 276 | port.membase = ioremap64(PPC440SP_UART0_ADDR, 8); |
276 | port.irq = UART0_INT; | 277 | port.irq = UART0_INT; |
277 | port.uartclk = clocks.uart0; | 278 | port.uartclk = clocks.uart0; |
278 | port.regshift = 0; | 279 | port.regshift = 0; |
279 | port.iotype = UPIO_MEM; | 280 | port.iotype = UPIO_MEM; |
280 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 281 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
281 | port.line = 0; | 282 | port.line = 0; |
282 | 283 | ||
283 | if (early_serial_setup(&port) != 0) { | 284 | if (early_serial_setup(&port) != 0) { |
284 | printk("Early serial init of port 0 failed\n"); | 285 | printk("Early serial init of port 0 failed\n"); |
285 | } | 286 | } |
286 | 287 | ||
287 | port.membase = ioremap64(PPC440SP_UART1_ADDR, 8); | 288 | port.membase = ioremap64(PPC440SP_UART1_ADDR, 8); |
288 | port.irq = UART1_INT; | 289 | port.irq = UART1_INT; |
289 | port.uartclk = clocks.uart1; | 290 | port.uartclk = clocks.uart1; |
290 | port.line = 1; | 291 | port.line = 1; |
291 | 292 | ||
292 | if (early_serial_setup(&port) != 0) { | 293 | if (early_serial_setup(&port) != 0) { |
293 | printk("Early serial init of port 1 failed\n"); | 294 | printk("Early serial init of port 1 failed\n"); |
294 | } | 295 | } |
295 | 296 | ||
296 | port.membase = ioremap64(PPC440SP_UART2_ADDR, 8); | 297 | port.membase = ioremap64(PPC440SP_UART2_ADDR, 8); |
297 | port.irq = UART2_INT; | 298 | port.irq = UART2_INT; |
298 | port.uartclk = BASE_BAUD; | 299 | port.uartclk = BASE_BAUD; |
299 | port.line = 2; | 300 | port.line = 2; |
300 | 301 | ||
301 | if (early_serial_setup(&port) != 0) { | 302 | if (early_serial_setup(&port) != 0) { |
302 | printk("Early serial init of port 2 failed\n"); | 303 | printk("Early serial init of port 2 failed\n"); |
303 | } | 304 | } |
304 | } | 305 | } |
305 | 306 | ||
306 | static void __init | 307 | static void __init |
307 | luan_setup_arch(void) | 308 | luan_setup_arch(void) |
308 | { | 309 | { |
309 | luan_set_emacdata(); | 310 | luan_set_emacdata(); |
310 | 311 | ||
311 | #if !defined(CONFIG_BDI_SWITCH) | 312 | #if !defined(CONFIG_BDI_SWITCH) |
312 | /* | 313 | /* |
313 | * The Abatron BDI JTAG debugger does not tolerate others | 314 | * The Abatron BDI JTAG debugger does not tolerate others |
314 | * mucking with the debug registers. | 315 | * mucking with the debug registers. |
315 | */ | 316 | */ |
316 | mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); | 317 | mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); |
317 | #endif | 318 | #endif |
318 | 319 | ||
319 | /* | 320 | /* |
320 | * Determine various clocks. | 321 | * Determine various clocks. |
321 | * To be completely correct we should get SysClk | 322 | * To be completely correct we should get SysClk |
322 | * from FPGA, because it can be changed by on-board switches | 323 | * from FPGA, because it can be changed by on-board switches |
323 | * --ebs | 324 | * --ebs |
324 | */ | 325 | */ |
325 | /* 440GX and 440SP clocking is the same -mdp */ | 326 | /* 440GX and 440SP clocking is the same -mdp */ |
326 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); | 327 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); |
327 | ocp_sys_info.opb_bus_freq = clocks.opb; | 328 | ocp_sys_info.opb_bus_freq = clocks.opb; |
328 | 329 | ||
329 | /* init to some ~sane value until calibrate_delay() runs */ | 330 | /* init to some ~sane value until calibrate_delay() runs */ |
330 | loops_per_jiffy = 50000000/HZ; | 331 | loops_per_jiffy = 50000000/HZ; |
331 | 332 | ||
332 | /* Setup PCIXn host bridges */ | 333 | /* Setup PCIXn host bridges */ |
333 | luan_setup_hoses(); | 334 | luan_setup_hoses(); |
334 | 335 | ||
335 | #ifdef CONFIG_BLK_DEV_INITRD | 336 | #ifdef CONFIG_BLK_DEV_INITRD |
336 | if (initrd_start) | 337 | if (initrd_start) |
337 | ROOT_DEV = Root_RAM0; | 338 | ROOT_DEV = Root_RAM0; |
338 | else | 339 | else |
339 | #endif | 340 | #endif |
340 | #ifdef CONFIG_ROOT_NFS | 341 | #ifdef CONFIG_ROOT_NFS |
341 | ROOT_DEV = Root_NFS; | 342 | ROOT_DEV = Root_NFS; |
342 | #else | 343 | #else |
343 | ROOT_DEV = Root_HDA1; | 344 | ROOT_DEV = Root_HDA1; |
344 | #endif | 345 | #endif |
345 | 346 | ||
346 | luan_early_serial_map(); | 347 | luan_early_serial_map(); |
347 | 348 | ||
348 | /* Identify the system */ | 349 | /* Identify the system */ |
349 | printk("Luan port (MontaVista Software, Inc. <source@mvista.com>)\n"); | 350 | printk("Luan port (MontaVista Software, Inc. <source@mvista.com>)\n"); |
350 | } | 351 | } |
351 | 352 | ||
352 | void __init platform_init(unsigned long r3, unsigned long r4, | 353 | void __init platform_init(unsigned long r3, unsigned long r4, |
353 | unsigned long r5, unsigned long r6, unsigned long r7) | 354 | unsigned long r5, unsigned long r6, unsigned long r7) |
354 | { | 355 | { |
355 | ibm44x_platform_init(r3, r4, r5, r6, r7); | 356 | ibm44x_platform_init(r3, r4, r5, r6, r7); |
356 | 357 | ||
357 | ppc_md.setup_arch = luan_setup_arch; | 358 | ppc_md.setup_arch = luan_setup_arch; |
358 | ppc_md.show_cpuinfo = luan_show_cpuinfo; | 359 | ppc_md.show_cpuinfo = luan_show_cpuinfo; |
359 | ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory; | 360 | ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory; |
360 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ | 361 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ |
361 | 362 | ||
362 | ppc_md.calibrate_decr = luan_calibrate_decr; | 363 | ppc_md.calibrate_decr = luan_calibrate_decr; |
363 | #ifdef CONFIG_KGDB | 364 | #ifdef CONFIG_KGDB |
364 | ppc_md.early_serial_map = luan_early_serial_map; | 365 | ppc_md.early_serial_map = luan_early_serial_map; |
365 | #endif | 366 | #endif |
366 | } | 367 | } |
367 | 368 |
arch/ppc/platforms/4xx/ocotea.c
1 | /* | 1 | /* |
2 | * Ocotea board specific routines | 2 | * Ocotea board specific routines |
3 | * | 3 | * |
4 | * Matt Porter <mporter@kernel.crashing.org> | 4 | * Matt Porter <mporter@kernel.crashing.org> |
5 | * | 5 | * |
6 | * Copyright 2003-2005 MontaVista Software Inc. | 6 | * Copyright 2003-2005 MontaVista Software Inc. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
10 | * Free Software Foundation; either version 2 of the License, or (at your | 10 | * Free Software Foundation; either version 2 of the License, or (at your |
11 | * option) any later version. | 11 | * option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/stddef.h> | 14 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/kdev_t.h> | 20 | #include <linux/kdev_t.h> |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/major.h> | 22 | #include <linux/major.h> |
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <linux/console.h> | 24 | #include <linux/console.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/ide.h> | 26 | #include <linux/ide.h> |
27 | #include <linux/initrd.h> | 27 | #include <linux/initrd.h> |
28 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
29 | #include <linux/root_dev.h> | 29 | #include <linux/root_dev.h> |
30 | #include <linux/tty.h> | 30 | #include <linux/tty.h> |
31 | #include <linux/serial.h> | 31 | #include <linux/serial.h> |
32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
33 | #include <linux/serial_8250.h> | ||
33 | 34 | ||
34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
36 | #include <asm/page.h> | 37 | #include <asm/page.h> |
37 | #include <asm/dma.h> | 38 | #include <asm/dma.h> |
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
40 | #include <asm/ocp.h> | 41 | #include <asm/ocp.h> |
41 | #include <asm/pci-bridge.h> | 42 | #include <asm/pci-bridge.h> |
42 | #include <asm/time.h> | 43 | #include <asm/time.h> |
43 | #include <asm/todc.h> | 44 | #include <asm/todc.h> |
44 | #include <asm/bootinfo.h> | 45 | #include <asm/bootinfo.h> |
45 | #include <asm/ppc4xx_pic.h> | 46 | #include <asm/ppc4xx_pic.h> |
46 | #include <asm/ppcboot.h> | 47 | #include <asm/ppcboot.h> |
47 | #include <asm/tlbflush.h> | 48 | #include <asm/tlbflush.h> |
48 | 49 | ||
49 | #include <syslib/gen550.h> | 50 | #include <syslib/gen550.h> |
50 | #include <syslib/ibm440gx_common.h> | 51 | #include <syslib/ibm440gx_common.h> |
51 | 52 | ||
52 | extern bd_t __res; | 53 | extern bd_t __res; |
53 | 54 | ||
54 | static struct ibm44x_clocks clocks __initdata; | 55 | static struct ibm44x_clocks clocks __initdata; |
55 | 56 | ||
56 | static void __init | 57 | static void __init |
57 | ocotea_calibrate_decr(void) | 58 | ocotea_calibrate_decr(void) |
58 | { | 59 | { |
59 | unsigned int freq; | 60 | unsigned int freq; |
60 | 61 | ||
61 | if (mfspr(SPRN_CCR1) & CCR1_TCS) | 62 | if (mfspr(SPRN_CCR1) & CCR1_TCS) |
62 | freq = OCOTEA_TMR_CLK; | 63 | freq = OCOTEA_TMR_CLK; |
63 | else | 64 | else |
64 | freq = clocks.cpu; | 65 | freq = clocks.cpu; |
65 | 66 | ||
66 | ibm44x_calibrate_decr(freq); | 67 | ibm44x_calibrate_decr(freq); |
67 | } | 68 | } |
68 | 69 | ||
69 | static int | 70 | static int |
70 | ocotea_show_cpuinfo(struct seq_file *m) | 71 | ocotea_show_cpuinfo(struct seq_file *m) |
71 | { | 72 | { |
72 | seq_printf(m, "vendor\t\t: IBM\n"); | 73 | seq_printf(m, "vendor\t\t: IBM\n"); |
73 | seq_printf(m, "machine\t\t: PPC440GX EVB (Ocotea)\n"); | 74 | seq_printf(m, "machine\t\t: PPC440GX EVB (Ocotea)\n"); |
74 | ibm440gx_show_cpuinfo(m); | 75 | ibm440gx_show_cpuinfo(m); |
75 | return 0; | 76 | return 0; |
76 | } | 77 | } |
77 | 78 | ||
78 | static inline int | 79 | static inline int |
79 | ocotea_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 80 | ocotea_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
80 | { | 81 | { |
81 | static char pci_irq_table[][4] = | 82 | static char pci_irq_table[][4] = |
82 | /* | 83 | /* |
83 | * PCI IDSEL/INTPIN->INTLINE | 84 | * PCI IDSEL/INTPIN->INTLINE |
84 | * A B C D | 85 | * A B C D |
85 | */ | 86 | */ |
86 | { | 87 | { |
87 | { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ | 88 | { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ |
88 | { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ | 89 | { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ |
89 | { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ | 90 | { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ |
90 | { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ | 91 | { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ |
91 | }; | 92 | }; |
92 | 93 | ||
93 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 94 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
94 | return PCI_IRQ_TABLE_LOOKUP; | 95 | return PCI_IRQ_TABLE_LOOKUP; |
95 | } | 96 | } |
96 | 97 | ||
97 | static void __init ocotea_set_emacdata(void) | 98 | static void __init ocotea_set_emacdata(void) |
98 | { | 99 | { |
99 | struct ocp_def *def; | 100 | struct ocp_def *def; |
100 | struct ocp_func_emac_data *emacdata; | 101 | struct ocp_func_emac_data *emacdata; |
101 | int i; | 102 | int i; |
102 | 103 | ||
103 | /* | 104 | /* |
104 | * Note: Current rev. board only operates in Group 4a | 105 | * Note: Current rev. board only operates in Group 4a |
105 | * mode, so we always set EMAC0-1 for SMII and EMAC2-3 | 106 | * mode, so we always set EMAC0-1 for SMII and EMAC2-3 |
106 | * for RGMII (though these could run in RTBI just the same). | 107 | * for RGMII (though these could run in RTBI just the same). |
107 | * | 108 | * |
108 | * The FPGA reg 3 information isn't even suitable for | 109 | * The FPGA reg 3 information isn't even suitable for |
109 | * determining the phy_mode, so if the board becomes | 110 | * determining the phy_mode, so if the board becomes |
110 | * usable in !4a, it will be necessary to parse an environment | 111 | * usable in !4a, it will be necessary to parse an environment |
111 | * variable from the firmware or similar to properly configure | 112 | * variable from the firmware or similar to properly configure |
112 | * the phy_map/phy_mode. | 113 | * the phy_map/phy_mode. |
113 | */ | 114 | */ |
114 | /* Set phy_map, phy_mode, and mac_addr for each EMAC */ | 115 | /* Set phy_map, phy_mode, and mac_addr for each EMAC */ |
115 | for (i=0; i<4; i++) { | 116 | for (i=0; i<4; i++) { |
116 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i); | 117 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i); |
117 | emacdata = def->additions; | 118 | emacdata = def->additions; |
118 | if (i < 2) { | 119 | if (i < 2) { |
119 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ | 120 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ |
120 | emacdata->phy_mode = PHY_MODE_SMII; | 121 | emacdata->phy_mode = PHY_MODE_SMII; |
121 | } | 122 | } |
122 | else { | 123 | else { |
123 | emacdata->phy_map = 0x0000ffff; /* Skip 0x00-0x0f */ | 124 | emacdata->phy_map = 0x0000ffff; /* Skip 0x00-0x0f */ |
124 | emacdata->phy_mode = PHY_MODE_RGMII; | 125 | emacdata->phy_mode = PHY_MODE_RGMII; |
125 | } | 126 | } |
126 | if (i == 0) | 127 | if (i == 0) |
127 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); | 128 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); |
128 | else if (i == 1) | 129 | else if (i == 1) |
129 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); | 130 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); |
130 | else if (i == 2) | 131 | else if (i == 2) |
131 | memcpy(emacdata->mac_addr, __res.bi_enet2addr, 6); | 132 | memcpy(emacdata->mac_addr, __res.bi_enet2addr, 6); |
132 | else if (i == 3) | 133 | else if (i == 3) |
133 | memcpy(emacdata->mac_addr, __res.bi_enet3addr, 6); | 134 | memcpy(emacdata->mac_addr, __res.bi_enet3addr, 6); |
134 | } | 135 | } |
135 | } | 136 | } |
136 | 137 | ||
137 | #define PCIX_READW(offset) \ | 138 | #define PCIX_READW(offset) \ |
138 | (readw(pcix_reg_base+offset)) | 139 | (readw(pcix_reg_base+offset)) |
139 | 140 | ||
140 | #define PCIX_WRITEW(value, offset) \ | 141 | #define PCIX_WRITEW(value, offset) \ |
141 | (writew(value, pcix_reg_base+offset)) | 142 | (writew(value, pcix_reg_base+offset)) |
142 | 143 | ||
143 | #define PCIX_WRITEL(value, offset) \ | 144 | #define PCIX_WRITEL(value, offset) \ |
144 | (writel(value, pcix_reg_base+offset)) | 145 | (writel(value, pcix_reg_base+offset)) |
145 | 146 | ||
146 | /* | 147 | /* |
147 | * FIXME: This is only here to "make it work". This will move | 148 | * FIXME: This is only here to "make it work". This will move |
148 | * to a ibm_pcix.c which will contain a generic IBM PCIX bridge | 149 | * to a ibm_pcix.c which will contain a generic IBM PCIX bridge |
149 | * configuration library. -Matt | 150 | * configuration library. -Matt |
150 | */ | 151 | */ |
151 | static void __init | 152 | static void __init |
152 | ocotea_setup_pcix(void) | 153 | ocotea_setup_pcix(void) |
153 | { | 154 | { |
154 | void *pcix_reg_base; | 155 | void *pcix_reg_base; |
155 | 156 | ||
156 | pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE); | 157 | pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE); |
157 | 158 | ||
158 | /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ | 159 | /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ |
159 | PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); | 160 | PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); |
160 | 161 | ||
161 | /* Disable all windows */ | 162 | /* Disable all windows */ |
162 | PCIX_WRITEL(0, PCIX0_POM0SA); | 163 | PCIX_WRITEL(0, PCIX0_POM0SA); |
163 | PCIX_WRITEL(0, PCIX0_POM1SA); | 164 | PCIX_WRITEL(0, PCIX0_POM1SA); |
164 | PCIX_WRITEL(0, PCIX0_POM2SA); | 165 | PCIX_WRITEL(0, PCIX0_POM2SA); |
165 | PCIX_WRITEL(0, PCIX0_PIM0SA); | 166 | PCIX_WRITEL(0, PCIX0_PIM0SA); |
166 | PCIX_WRITEL(0, PCIX0_PIM0SAH); | 167 | PCIX_WRITEL(0, PCIX0_PIM0SAH); |
167 | PCIX_WRITEL(0, PCIX0_PIM1SA); | 168 | PCIX_WRITEL(0, PCIX0_PIM1SA); |
168 | PCIX_WRITEL(0, PCIX0_PIM2SA); | 169 | PCIX_WRITEL(0, PCIX0_PIM2SA); |
169 | PCIX_WRITEL(0, PCIX0_PIM2SAH); | 170 | PCIX_WRITEL(0, PCIX0_PIM2SAH); |
170 | 171 | ||
171 | /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ | 172 | /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ |
172 | PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); | 173 | PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); |
173 | PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); | 174 | PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); |
174 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); | 175 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); |
175 | PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); | 176 | PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); |
176 | PCIX_WRITEL(0x80000001, PCIX0_POM0SA); | 177 | PCIX_WRITEL(0x80000001, PCIX0_POM0SA); |
177 | 178 | ||
178 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ | 179 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ |
179 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); | 180 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); |
180 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); | 181 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); |
181 | PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); | 182 | PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); |
182 | 183 | ||
183 | eieio(); | 184 | eieio(); |
184 | } | 185 | } |
185 | 186 | ||
186 | static void __init | 187 | static void __init |
187 | ocotea_setup_hose(void) | 188 | ocotea_setup_hose(void) |
188 | { | 189 | { |
189 | struct pci_controller *hose; | 190 | struct pci_controller *hose; |
190 | 191 | ||
191 | /* Configure windows on the PCI-X host bridge */ | 192 | /* Configure windows on the PCI-X host bridge */ |
192 | ocotea_setup_pcix(); | 193 | ocotea_setup_pcix(); |
193 | 194 | ||
194 | hose = pcibios_alloc_controller(); | 195 | hose = pcibios_alloc_controller(); |
195 | 196 | ||
196 | if (!hose) | 197 | if (!hose) |
197 | return; | 198 | return; |
198 | 199 | ||
199 | hose->first_busno = 0; | 200 | hose->first_busno = 0; |
200 | hose->last_busno = 0xff; | 201 | hose->last_busno = 0xff; |
201 | 202 | ||
202 | hose->pci_mem_offset = OCOTEA_PCI_MEM_OFFSET; | 203 | hose->pci_mem_offset = OCOTEA_PCI_MEM_OFFSET; |
203 | 204 | ||
204 | pci_init_resource(&hose->io_resource, | 205 | pci_init_resource(&hose->io_resource, |
205 | OCOTEA_PCI_LOWER_IO, | 206 | OCOTEA_PCI_LOWER_IO, |
206 | OCOTEA_PCI_UPPER_IO, | 207 | OCOTEA_PCI_UPPER_IO, |
207 | IORESOURCE_IO, | 208 | IORESOURCE_IO, |
208 | "PCI host bridge"); | 209 | "PCI host bridge"); |
209 | 210 | ||
210 | pci_init_resource(&hose->mem_resources[0], | 211 | pci_init_resource(&hose->mem_resources[0], |
211 | OCOTEA_PCI_LOWER_MEM, | 212 | OCOTEA_PCI_LOWER_MEM, |
212 | OCOTEA_PCI_UPPER_MEM, | 213 | OCOTEA_PCI_UPPER_MEM, |
213 | IORESOURCE_MEM, | 214 | IORESOURCE_MEM, |
214 | "PCI host bridge"); | 215 | "PCI host bridge"); |
215 | 216 | ||
216 | hose->io_space.start = OCOTEA_PCI_LOWER_IO; | 217 | hose->io_space.start = OCOTEA_PCI_LOWER_IO; |
217 | hose->io_space.end = OCOTEA_PCI_UPPER_IO; | 218 | hose->io_space.end = OCOTEA_PCI_UPPER_IO; |
218 | hose->mem_space.start = OCOTEA_PCI_LOWER_MEM; | 219 | hose->mem_space.start = OCOTEA_PCI_LOWER_MEM; |
219 | hose->mem_space.end = OCOTEA_PCI_UPPER_MEM; | 220 | hose->mem_space.end = OCOTEA_PCI_UPPER_MEM; |
220 | hose->io_base_virt = ioremap64(OCOTEA_PCI_IO_BASE, OCOTEA_PCI_IO_SIZE); | 221 | hose->io_base_virt = ioremap64(OCOTEA_PCI_IO_BASE, OCOTEA_PCI_IO_SIZE); |
221 | isa_io_base = (unsigned long) hose->io_base_virt; | 222 | isa_io_base = (unsigned long) hose->io_base_virt; |
222 | 223 | ||
223 | setup_indirect_pci(hose, | 224 | setup_indirect_pci(hose, |
224 | OCOTEA_PCI_CFGA_PLB32, | 225 | OCOTEA_PCI_CFGA_PLB32, |
225 | OCOTEA_PCI_CFGD_PLB32); | 226 | OCOTEA_PCI_CFGD_PLB32); |
226 | hose->set_cfg_type = 1; | 227 | hose->set_cfg_type = 1; |
227 | 228 | ||
228 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | 229 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); |
229 | 230 | ||
230 | ppc_md.pci_swizzle = common_swizzle; | 231 | ppc_md.pci_swizzle = common_swizzle; |
231 | ppc_md.pci_map_irq = ocotea_map_irq; | 232 | ppc_md.pci_map_irq = ocotea_map_irq; |
232 | } | 233 | } |
233 | 234 | ||
234 | 235 | ||
235 | TODC_ALLOC(); | 236 | TODC_ALLOC(); |
236 | 237 | ||
237 | static void __init | 238 | static void __init |
238 | ocotea_early_serial_map(void) | 239 | ocotea_early_serial_map(void) |
239 | { | 240 | { |
240 | struct uart_port port; | 241 | struct uart_port port; |
241 | 242 | ||
242 | /* Setup ioremapped serial port access */ | 243 | /* Setup ioremapped serial port access */ |
243 | memset(&port, 0, sizeof(port)); | 244 | memset(&port, 0, sizeof(port)); |
244 | port.membase = ioremap64(PPC440GX_UART0_ADDR, 8); | 245 | port.membase = ioremap64(PPC440GX_UART0_ADDR, 8); |
245 | port.irq = UART0_INT; | 246 | port.irq = UART0_INT; |
246 | port.uartclk = clocks.uart0; | 247 | port.uartclk = clocks.uart0; |
247 | port.regshift = 0; | 248 | port.regshift = 0; |
248 | port.iotype = UPIO_MEM; | 249 | port.iotype = UPIO_MEM; |
249 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 250 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
250 | port.line = 0; | 251 | port.line = 0; |
251 | 252 | ||
252 | if (early_serial_setup(&port) != 0) { | 253 | if (early_serial_setup(&port) != 0) { |
253 | printk("Early serial init of port 0 failed\n"); | 254 | printk("Early serial init of port 0 failed\n"); |
254 | } | 255 | } |
255 | 256 | ||
256 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 257 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
257 | /* Configure debug serial access */ | 258 | /* Configure debug serial access */ |
258 | gen550_init(0, &port); | 259 | gen550_init(0, &port); |
259 | 260 | ||
260 | /* Purge TLB entry added in head_44x.S for early serial access */ | 261 | /* Purge TLB entry added in head_44x.S for early serial access */ |
261 | _tlbie(UART0_IO_BASE); | 262 | _tlbie(UART0_IO_BASE); |
262 | #endif | 263 | #endif |
263 | 264 | ||
264 | port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); | 265 | port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); |
265 | port.irq = UART1_INT; | 266 | port.irq = UART1_INT; |
266 | port.uartclk = clocks.uart1; | 267 | port.uartclk = clocks.uart1; |
267 | port.line = 1; | 268 | port.line = 1; |
268 | 269 | ||
269 | if (early_serial_setup(&port) != 0) { | 270 | if (early_serial_setup(&port) != 0) { |
270 | printk("Early serial init of port 1 failed\n"); | 271 | printk("Early serial init of port 1 failed\n"); |
271 | } | 272 | } |
272 | 273 | ||
273 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 274 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
274 | /* Configure debug serial access */ | 275 | /* Configure debug serial access */ |
275 | gen550_init(1, &port); | 276 | gen550_init(1, &port); |
276 | #endif | 277 | #endif |
277 | } | 278 | } |
278 | 279 | ||
279 | static void __init | 280 | static void __init |
280 | ocotea_setup_arch(void) | 281 | ocotea_setup_arch(void) |
281 | { | 282 | { |
282 | ocotea_set_emacdata(); | 283 | ocotea_set_emacdata(); |
283 | 284 | ||
284 | ibm440gx_tah_enable(); | 285 | ibm440gx_tah_enable(); |
285 | 286 | ||
286 | /* | 287 | /* |
287 | * Determine various clocks. | 288 | * Determine various clocks. |
288 | * To be completely correct we should get SysClk | 289 | * To be completely correct we should get SysClk |
289 | * from FPGA, because it can be changed by on-board switches | 290 | * from FPGA, because it can be changed by on-board switches |
290 | * --ebs | 291 | * --ebs |
291 | */ | 292 | */ |
292 | ibm440gx_get_clocks(&clocks, 33300000, 6 * 1843200); | 293 | ibm440gx_get_clocks(&clocks, 33300000, 6 * 1843200); |
293 | ocp_sys_info.opb_bus_freq = clocks.opb; | 294 | ocp_sys_info.opb_bus_freq = clocks.opb; |
294 | 295 | ||
295 | /* Setup TODC access */ | 296 | /* Setup TODC access */ |
296 | TODC_INIT(TODC_TYPE_DS1743, | 297 | TODC_INIT(TODC_TYPE_DS1743, |
297 | 0, | 298 | 0, |
298 | 0, | 299 | 0, |
299 | ioremap64(OCOTEA_RTC_ADDR, OCOTEA_RTC_SIZE), | 300 | ioremap64(OCOTEA_RTC_ADDR, OCOTEA_RTC_SIZE), |
300 | 8); | 301 | 8); |
301 | 302 | ||
302 | /* init to some ~sane value until calibrate_delay() runs */ | 303 | /* init to some ~sane value until calibrate_delay() runs */ |
303 | loops_per_jiffy = 50000000/HZ; | 304 | loops_per_jiffy = 50000000/HZ; |
304 | 305 | ||
305 | /* Setup PCI host bridge */ | 306 | /* Setup PCI host bridge */ |
306 | ocotea_setup_hose(); | 307 | ocotea_setup_hose(); |
307 | 308 | ||
308 | #ifdef CONFIG_BLK_DEV_INITRD | 309 | #ifdef CONFIG_BLK_DEV_INITRD |
309 | if (initrd_start) | 310 | if (initrd_start) |
310 | ROOT_DEV = Root_RAM0; | 311 | ROOT_DEV = Root_RAM0; |
311 | else | 312 | else |
312 | #endif | 313 | #endif |
313 | #ifdef CONFIG_ROOT_NFS | 314 | #ifdef CONFIG_ROOT_NFS |
314 | ROOT_DEV = Root_NFS; | 315 | ROOT_DEV = Root_NFS; |
315 | #else | 316 | #else |
316 | ROOT_DEV = Root_HDA1; | 317 | ROOT_DEV = Root_HDA1; |
317 | #endif | 318 | #endif |
318 | 319 | ||
319 | ocotea_early_serial_map(); | 320 | ocotea_early_serial_map(); |
320 | 321 | ||
321 | /* Identify the system */ | 322 | /* Identify the system */ |
322 | printk("IBM Ocotea port (MontaVista Software, Inc. <source@mvista.com>)\n"); | 323 | printk("IBM Ocotea port (MontaVista Software, Inc. <source@mvista.com>)\n"); |
323 | } | 324 | } |
324 | 325 | ||
325 | static void __init ocotea_init(void) | 326 | static void __init ocotea_init(void) |
326 | { | 327 | { |
327 | ibm440gx_l2c_setup(&clocks); | 328 | ibm440gx_l2c_setup(&clocks); |
328 | } | 329 | } |
329 | 330 | ||
330 | void __init platform_init(unsigned long r3, unsigned long r4, | 331 | void __init platform_init(unsigned long r3, unsigned long r4, |
331 | unsigned long r5, unsigned long r6, unsigned long r7) | 332 | unsigned long r5, unsigned long r6, unsigned long r7) |
332 | { | 333 | { |
333 | ibm440gx_platform_init(r3, r4, r5, r6, r7); | 334 | ibm440gx_platform_init(r3, r4, r5, r6, r7); |
334 | 335 | ||
335 | ppc_md.setup_arch = ocotea_setup_arch; | 336 | ppc_md.setup_arch = ocotea_setup_arch; |
336 | ppc_md.show_cpuinfo = ocotea_show_cpuinfo; | 337 | ppc_md.show_cpuinfo = ocotea_show_cpuinfo; |
337 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ | 338 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ |
338 | 339 | ||
339 | ppc_md.calibrate_decr = ocotea_calibrate_decr; | 340 | ppc_md.calibrate_decr = ocotea_calibrate_decr; |
340 | ppc_md.time_init = todc_time_init; | 341 | ppc_md.time_init = todc_time_init; |
341 | ppc_md.set_rtc_time = todc_set_rtc_time; | 342 | ppc_md.set_rtc_time = todc_set_rtc_time; |
342 | ppc_md.get_rtc_time = todc_get_rtc_time; | 343 | ppc_md.get_rtc_time = todc_get_rtc_time; |
343 | 344 | ||
344 | ppc_md.nvram_read_val = todc_direct_read_val; | 345 | ppc_md.nvram_read_val = todc_direct_read_val; |
345 | ppc_md.nvram_write_val = todc_direct_write_val; | 346 | ppc_md.nvram_write_val = todc_direct_write_val; |
346 | #ifdef CONFIG_KGDB | 347 | #ifdef CONFIG_KGDB |
347 | ppc_md.early_serial_map = ocotea_early_serial_map; | 348 | ppc_md.early_serial_map = ocotea_early_serial_map; |
348 | #endif | 349 | #endif |
349 | ppc_md.init = ocotea_init; | 350 | ppc_md.init = ocotea_init; |
350 | } | 351 | } |
351 | 352 |
arch/ppc/platforms/4xx/taishan.c
1 | /* | 1 | /* |
2 | * arch/ppc/platforms/4xx/taishan.c | 2 | * arch/ppc/platforms/4xx/taishan.c |
3 | * | 3 | * |
4 | * AMCC Taishan board specific routines | 4 | * AMCC Taishan board specific routines |
5 | * | 5 | * |
6 | * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de> | 6 | * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
10 | * Free Software Foundation; either version 2 of the License, or (at your | 10 | * Free Software Foundation; either version 2 of the License, or (at your |
11 | * option) any later version. | 11 | * option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/stddef.h> | 14 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/kdev_t.h> | 20 | #include <linux/kdev_t.h> |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/major.h> | 22 | #include <linux/major.h> |
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <linux/console.h> | 24 | #include <linux/console.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/ide.h> | 26 | #include <linux/ide.h> |
27 | #include <linux/initrd.h> | 27 | #include <linux/initrd.h> |
28 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
29 | #include <linux/root_dev.h> | 29 | #include <linux/root_dev.h> |
30 | #include <linux/tty.h> | 30 | #include <linux/tty.h> |
31 | #include <linux/serial.h> | 31 | #include <linux/serial.h> |
32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
33 | #include <linux/serial_8250.h> | ||
33 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
34 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
35 | #include <linux/mtd/nand.h> | 36 | #include <linux/mtd/nand.h> |
36 | #include <linux/mtd/ndfc.h> | 37 | #include <linux/mtd/ndfc.h> |
37 | #include <linux/mtd/physmap.h> | 38 | #include <linux/mtd/physmap.h> |
38 | 39 | ||
39 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
40 | #include <asm/ocp.h> | 41 | #include <asm/ocp.h> |
41 | #include <asm/bootinfo.h> | 42 | #include <asm/bootinfo.h> |
42 | #include <asm/ppcboot.h> | 43 | #include <asm/ppcboot.h> |
43 | 44 | ||
44 | #include <syslib/gen550.h> | 45 | #include <syslib/gen550.h> |
45 | #include <syslib/ibm440gx_common.h> | 46 | #include <syslib/ibm440gx_common.h> |
46 | 47 | ||
47 | extern bd_t __res; | 48 | extern bd_t __res; |
48 | 49 | ||
49 | static struct ibm44x_clocks clocks __initdata; | 50 | static struct ibm44x_clocks clocks __initdata; |
50 | 51 | ||
51 | /* | 52 | /* |
52 | * NOR FLASH configuration (using mtd physmap driver) | 53 | * NOR FLASH configuration (using mtd physmap driver) |
53 | */ | 54 | */ |
54 | 55 | ||
55 | /* start will be added dynamically, end is always fixed */ | 56 | /* start will be added dynamically, end is always fixed */ |
56 | static struct resource taishan_nor_resource = { | 57 | static struct resource taishan_nor_resource = { |
57 | .start = TAISHAN_FLASH_ADDR, | 58 | .start = TAISHAN_FLASH_ADDR, |
58 | .end = 0x1ffffffffULL, | 59 | .end = 0x1ffffffffULL, |
59 | .flags = IORESOURCE_MEM, | 60 | .flags = IORESOURCE_MEM, |
60 | }; | 61 | }; |
61 | 62 | ||
62 | #define RW_PART0_OF 0 | 63 | #define RW_PART0_OF 0 |
63 | #define RW_PART0_SZ 0x180000 | 64 | #define RW_PART0_SZ 0x180000 |
64 | #define RW_PART1_SZ 0x200000 | 65 | #define RW_PART1_SZ 0x200000 |
65 | /* Partition 2 will be autosized dynamically... */ | 66 | /* Partition 2 will be autosized dynamically... */ |
66 | #define RW_PART3_SZ 0x80000 | 67 | #define RW_PART3_SZ 0x80000 |
67 | #define RW_PART4_SZ 0x40000 | 68 | #define RW_PART4_SZ 0x40000 |
68 | 69 | ||
69 | static struct mtd_partition taishan_nor_parts[] = { | 70 | static struct mtd_partition taishan_nor_parts[] = { |
70 | { | 71 | { |
71 | .name = "kernel", | 72 | .name = "kernel", |
72 | .offset = 0, | 73 | .offset = 0, |
73 | .size = RW_PART0_SZ | 74 | .size = RW_PART0_SZ |
74 | }, | 75 | }, |
75 | { | 76 | { |
76 | .name = "root", | 77 | .name = "root", |
77 | .offset = MTDPART_OFS_APPEND, | 78 | .offset = MTDPART_OFS_APPEND, |
78 | .size = RW_PART1_SZ, | 79 | .size = RW_PART1_SZ, |
79 | }, | 80 | }, |
80 | { | 81 | { |
81 | .name = "user", | 82 | .name = "user", |
82 | .offset = MTDPART_OFS_APPEND, | 83 | .offset = MTDPART_OFS_APPEND, |
83 | /* .size = RW_PART2_SZ */ /* will be adjusted dynamically */ | 84 | /* .size = RW_PART2_SZ */ /* will be adjusted dynamically */ |
84 | }, | 85 | }, |
85 | { | 86 | { |
86 | .name = "env", | 87 | .name = "env", |
87 | .offset = MTDPART_OFS_APPEND, | 88 | .offset = MTDPART_OFS_APPEND, |
88 | .size = RW_PART3_SZ, | 89 | .size = RW_PART3_SZ, |
89 | }, | 90 | }, |
90 | { | 91 | { |
91 | .name = "u-boot", | 92 | .name = "u-boot", |
92 | .offset = MTDPART_OFS_APPEND, | 93 | .offset = MTDPART_OFS_APPEND, |
93 | .size = RW_PART4_SZ, | 94 | .size = RW_PART4_SZ, |
94 | } | 95 | } |
95 | }; | 96 | }; |
96 | 97 | ||
97 | static struct physmap_flash_data taishan_nor_data = { | 98 | static struct physmap_flash_data taishan_nor_data = { |
98 | .width = 4, | 99 | .width = 4, |
99 | .parts = taishan_nor_parts, | 100 | .parts = taishan_nor_parts, |
100 | .nr_parts = ARRAY_SIZE(taishan_nor_parts), | 101 | .nr_parts = ARRAY_SIZE(taishan_nor_parts), |
101 | }; | 102 | }; |
102 | 103 | ||
103 | static struct platform_device taishan_nor_device = { | 104 | static struct platform_device taishan_nor_device = { |
104 | .name = "physmap-flash", | 105 | .name = "physmap-flash", |
105 | .id = 0, | 106 | .id = 0, |
106 | .dev = { | 107 | .dev = { |
107 | .platform_data = &taishan_nor_data, | 108 | .platform_data = &taishan_nor_data, |
108 | }, | 109 | }, |
109 | .num_resources = 1, | 110 | .num_resources = 1, |
110 | .resource = &taishan_nor_resource, | 111 | .resource = &taishan_nor_resource, |
111 | }; | 112 | }; |
112 | 113 | ||
113 | static int taishan_setup_flash(void) | 114 | static int taishan_setup_flash(void) |
114 | { | 115 | { |
115 | /* | 116 | /* |
116 | * Adjust partition 2 to flash size | 117 | * Adjust partition 2 to flash size |
117 | */ | 118 | */ |
118 | taishan_nor_parts[2].size = __res.bi_flashsize - | 119 | taishan_nor_parts[2].size = __res.bi_flashsize - |
119 | RW_PART0_SZ - RW_PART1_SZ - RW_PART3_SZ - RW_PART4_SZ; | 120 | RW_PART0_SZ - RW_PART1_SZ - RW_PART3_SZ - RW_PART4_SZ; |
120 | 121 | ||
121 | platform_device_register(&taishan_nor_device); | 122 | platform_device_register(&taishan_nor_device); |
122 | 123 | ||
123 | return 0; | 124 | return 0; |
124 | } | 125 | } |
125 | arch_initcall(taishan_setup_flash); | 126 | arch_initcall(taishan_setup_flash); |
126 | 127 | ||
127 | static void __init | 128 | static void __init |
128 | taishan_calibrate_decr(void) | 129 | taishan_calibrate_decr(void) |
129 | { | 130 | { |
130 | unsigned int freq; | 131 | unsigned int freq; |
131 | 132 | ||
132 | if (mfspr(SPRN_CCR1) & CCR1_TCS) | 133 | if (mfspr(SPRN_CCR1) & CCR1_TCS) |
133 | freq = TAISHAN_TMR_CLK; | 134 | freq = TAISHAN_TMR_CLK; |
134 | else | 135 | else |
135 | freq = clocks.cpu; | 136 | freq = clocks.cpu; |
136 | 137 | ||
137 | ibm44x_calibrate_decr(freq); | 138 | ibm44x_calibrate_decr(freq); |
138 | } | 139 | } |
139 | 140 | ||
140 | static int | 141 | static int |
141 | taishan_show_cpuinfo(struct seq_file *m) | 142 | taishan_show_cpuinfo(struct seq_file *m) |
142 | { | 143 | { |
143 | seq_printf(m, "vendor\t\t: AMCC\n"); | 144 | seq_printf(m, "vendor\t\t: AMCC\n"); |
144 | seq_printf(m, "machine\t\t: PPC440GX EVB (Taishan)\n"); | 145 | seq_printf(m, "machine\t\t: PPC440GX EVB (Taishan)\n"); |
145 | ibm440gx_show_cpuinfo(m); | 146 | ibm440gx_show_cpuinfo(m); |
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
148 | 149 | ||
149 | static inline int | 150 | static inline int |
150 | taishan_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 151 | taishan_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
151 | { | 152 | { |
152 | static char pci_irq_table[][4] = | 153 | static char pci_irq_table[][4] = |
153 | /* | 154 | /* |
154 | * PCI IDSEL/INTPIN->INTLINE | 155 | * PCI IDSEL/INTPIN->INTLINE |
155 | * A B C D | 156 | * A B C D |
156 | */ | 157 | */ |
157 | { | 158 | { |
158 | { 23, 24, 25, 26 }, /* IDSEL 1 - PCI Slot 0 */ | 159 | { 23, 24, 25, 26 }, /* IDSEL 1 - PCI Slot 0 */ |
159 | { 24, 25, 26, 23 }, /* IDSEL 2 - PCI Slot 1 */ | 160 | { 24, 25, 26, 23 }, /* IDSEL 2 - PCI Slot 1 */ |
160 | }; | 161 | }; |
161 | 162 | ||
162 | const long min_idsel = 1, max_idsel = 2, irqs_per_slot = 4; | 163 | const long min_idsel = 1, max_idsel = 2, irqs_per_slot = 4; |
163 | return PCI_IRQ_TABLE_LOOKUP; | 164 | return PCI_IRQ_TABLE_LOOKUP; |
164 | } | 165 | } |
165 | 166 | ||
166 | static void __init taishan_set_emacdata(void) | 167 | static void __init taishan_set_emacdata(void) |
167 | { | 168 | { |
168 | struct ocp_def *def; | 169 | struct ocp_def *def; |
169 | struct ocp_func_emac_data *emacdata; | 170 | struct ocp_func_emac_data *emacdata; |
170 | int i; | 171 | int i; |
171 | 172 | ||
172 | /* Set phy_map, phy_mode, and mac_addr for each EMAC */ | 173 | /* Set phy_map, phy_mode, and mac_addr for each EMAC */ |
173 | for (i=2; i<4; i++) { | 174 | for (i=2; i<4; i++) { |
174 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i); | 175 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i); |
175 | emacdata = def->additions; | 176 | emacdata = def->additions; |
176 | if (i < 2) { | 177 | if (i < 2) { |
177 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ | 178 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ |
178 | emacdata->phy_mode = PHY_MODE_SMII; | 179 | emacdata->phy_mode = PHY_MODE_SMII; |
179 | } else { | 180 | } else { |
180 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ | 181 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ |
181 | emacdata->phy_mode = PHY_MODE_RGMII; | 182 | emacdata->phy_mode = PHY_MODE_RGMII; |
182 | } | 183 | } |
183 | if (i == 0) | 184 | if (i == 0) |
184 | memcpy(emacdata->mac_addr, "\0\0\0\0\0\0", 6); | 185 | memcpy(emacdata->mac_addr, "\0\0\0\0\0\0", 6); |
185 | else if (i == 1) | 186 | else if (i == 1) |
186 | memcpy(emacdata->mac_addr, "\0\0\0\0\0\0", 6); | 187 | memcpy(emacdata->mac_addr, "\0\0\0\0\0\0", 6); |
187 | else if (i == 2) | 188 | else if (i == 2) |
188 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); | 189 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); |
189 | else if (i == 3) | 190 | else if (i == 3) |
190 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); | 191 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); |
191 | } | 192 | } |
192 | } | 193 | } |
193 | 194 | ||
194 | #define PCIX_READW(offset) \ | 195 | #define PCIX_READW(offset) \ |
195 | (readw(pcix_reg_base+offset)) | 196 | (readw(pcix_reg_base+offset)) |
196 | 197 | ||
197 | #define PCIX_WRITEW(value, offset) \ | 198 | #define PCIX_WRITEW(value, offset) \ |
198 | (writew(value, pcix_reg_base+offset)) | 199 | (writew(value, pcix_reg_base+offset)) |
199 | 200 | ||
200 | #define PCIX_WRITEL(value, offset) \ | 201 | #define PCIX_WRITEL(value, offset) \ |
201 | (writel(value, pcix_reg_base+offset)) | 202 | (writel(value, pcix_reg_base+offset)) |
202 | 203 | ||
203 | /* | 204 | /* |
204 | * FIXME: This is only here to "make it work". This will move | 205 | * FIXME: This is only here to "make it work". This will move |
205 | * to a ibm_pcix.c which will contain a generic IBM PCIX bridge | 206 | * to a ibm_pcix.c which will contain a generic IBM PCIX bridge |
206 | * configuration library. -Matt | 207 | * configuration library. -Matt |
207 | */ | 208 | */ |
208 | static void __init | 209 | static void __init |
209 | taishan_setup_pcix(void) | 210 | taishan_setup_pcix(void) |
210 | { | 211 | { |
211 | void *pcix_reg_base; | 212 | void *pcix_reg_base; |
212 | 213 | ||
213 | pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE); | 214 | pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE); |
214 | 215 | ||
215 | /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ | 216 | /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ |
216 | PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); | 217 | PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); |
217 | 218 | ||
218 | /* Disable all windows */ | 219 | /* Disable all windows */ |
219 | PCIX_WRITEL(0, PCIX0_POM0SA); | 220 | PCIX_WRITEL(0, PCIX0_POM0SA); |
220 | PCIX_WRITEL(0, PCIX0_POM1SA); | 221 | PCIX_WRITEL(0, PCIX0_POM1SA); |
221 | PCIX_WRITEL(0, PCIX0_POM2SA); | 222 | PCIX_WRITEL(0, PCIX0_POM2SA); |
222 | PCIX_WRITEL(0, PCIX0_PIM0SA); | 223 | PCIX_WRITEL(0, PCIX0_PIM0SA); |
223 | PCIX_WRITEL(0, PCIX0_PIM0SAH); | 224 | PCIX_WRITEL(0, PCIX0_PIM0SAH); |
224 | PCIX_WRITEL(0, PCIX0_PIM1SA); | 225 | PCIX_WRITEL(0, PCIX0_PIM1SA); |
225 | PCIX_WRITEL(0, PCIX0_PIM2SA); | 226 | PCIX_WRITEL(0, PCIX0_PIM2SA); |
226 | PCIX_WRITEL(0, PCIX0_PIM2SAH); | 227 | PCIX_WRITEL(0, PCIX0_PIM2SAH); |
227 | 228 | ||
228 | /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ | 229 | /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ |
229 | PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); | 230 | PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); |
230 | PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); | 231 | PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); |
231 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); | 232 | PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); |
232 | PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); | 233 | PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); |
233 | PCIX_WRITEL(0x80000001, PCIX0_POM0SA); | 234 | PCIX_WRITEL(0x80000001, PCIX0_POM0SA); |
234 | 235 | ||
235 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ | 236 | /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ |
236 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); | 237 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); |
237 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); | 238 | PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); |
238 | PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); | 239 | PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); |
239 | PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH); | 240 | PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH); |
240 | 241 | ||
241 | iounmap(pcix_reg_base); | 242 | iounmap(pcix_reg_base); |
242 | 243 | ||
243 | eieio(); | 244 | eieio(); |
244 | } | 245 | } |
245 | 246 | ||
246 | static void __init | 247 | static void __init |
247 | taishan_setup_hose(void) | 248 | taishan_setup_hose(void) |
248 | { | 249 | { |
249 | struct pci_controller *hose; | 250 | struct pci_controller *hose; |
250 | 251 | ||
251 | /* Configure windows on the PCI-X host bridge */ | 252 | /* Configure windows on the PCI-X host bridge */ |
252 | taishan_setup_pcix(); | 253 | taishan_setup_pcix(); |
253 | 254 | ||
254 | hose = pcibios_alloc_controller(); | 255 | hose = pcibios_alloc_controller(); |
255 | 256 | ||
256 | if (!hose) | 257 | if (!hose) |
257 | return; | 258 | return; |
258 | 259 | ||
259 | hose->first_busno = 0; | 260 | hose->first_busno = 0; |
260 | hose->last_busno = 0xff; | 261 | hose->last_busno = 0xff; |
261 | 262 | ||
262 | hose->pci_mem_offset = TAISHAN_PCI_MEM_OFFSET; | 263 | hose->pci_mem_offset = TAISHAN_PCI_MEM_OFFSET; |
263 | 264 | ||
264 | pci_init_resource(&hose->io_resource, | 265 | pci_init_resource(&hose->io_resource, |
265 | TAISHAN_PCI_LOWER_IO, | 266 | TAISHAN_PCI_LOWER_IO, |
266 | TAISHAN_PCI_UPPER_IO, | 267 | TAISHAN_PCI_UPPER_IO, |
267 | IORESOURCE_IO, | 268 | IORESOURCE_IO, |
268 | "PCI host bridge"); | 269 | "PCI host bridge"); |
269 | 270 | ||
270 | pci_init_resource(&hose->mem_resources[0], | 271 | pci_init_resource(&hose->mem_resources[0], |
271 | TAISHAN_PCI_LOWER_MEM, | 272 | TAISHAN_PCI_LOWER_MEM, |
272 | TAISHAN_PCI_UPPER_MEM, | 273 | TAISHAN_PCI_UPPER_MEM, |
273 | IORESOURCE_MEM, | 274 | IORESOURCE_MEM, |
274 | "PCI host bridge"); | 275 | "PCI host bridge"); |
275 | 276 | ||
276 | hose->io_space.start = TAISHAN_PCI_LOWER_IO; | 277 | hose->io_space.start = TAISHAN_PCI_LOWER_IO; |
277 | hose->io_space.end = TAISHAN_PCI_UPPER_IO; | 278 | hose->io_space.end = TAISHAN_PCI_UPPER_IO; |
278 | hose->mem_space.start = TAISHAN_PCI_LOWER_MEM; | 279 | hose->mem_space.start = TAISHAN_PCI_LOWER_MEM; |
279 | hose->mem_space.end = TAISHAN_PCI_UPPER_MEM; | 280 | hose->mem_space.end = TAISHAN_PCI_UPPER_MEM; |
280 | hose->io_base_virt = ioremap64(TAISHAN_PCI_IO_BASE, TAISHAN_PCI_IO_SIZE); | 281 | hose->io_base_virt = ioremap64(TAISHAN_PCI_IO_BASE, TAISHAN_PCI_IO_SIZE); |
281 | isa_io_base = (unsigned long) hose->io_base_virt; | 282 | isa_io_base = (unsigned long) hose->io_base_virt; |
282 | 283 | ||
283 | setup_indirect_pci(hose, | 284 | setup_indirect_pci(hose, |
284 | TAISHAN_PCI_CFGA_PLB32, | 285 | TAISHAN_PCI_CFGA_PLB32, |
285 | TAISHAN_PCI_CFGD_PLB32); | 286 | TAISHAN_PCI_CFGD_PLB32); |
286 | hose->set_cfg_type = 1; | 287 | hose->set_cfg_type = 1; |
287 | 288 | ||
288 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | 289 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); |
289 | 290 | ||
290 | ppc_md.pci_swizzle = common_swizzle; | 291 | ppc_md.pci_swizzle = common_swizzle; |
291 | ppc_md.pci_map_irq = taishan_map_irq; | 292 | ppc_md.pci_map_irq = taishan_map_irq; |
292 | } | 293 | } |
293 | 294 | ||
294 | 295 | ||
295 | static void __init | 296 | static void __init |
296 | taishan_early_serial_map(void) | 297 | taishan_early_serial_map(void) |
297 | { | 298 | { |
298 | struct uart_port port; | 299 | struct uart_port port; |
299 | 300 | ||
300 | /* Setup ioremapped serial port access */ | 301 | /* Setup ioremapped serial port access */ |
301 | memset(&port, 0, sizeof(port)); | 302 | memset(&port, 0, sizeof(port)); |
302 | port.membase = ioremap64(PPC440GX_UART0_ADDR, 8); | 303 | port.membase = ioremap64(PPC440GX_UART0_ADDR, 8); |
303 | port.irq = UART0_INT; | 304 | port.irq = UART0_INT; |
304 | port.uartclk = clocks.uart0; | 305 | port.uartclk = clocks.uart0; |
305 | port.regshift = 0; | 306 | port.regshift = 0; |
306 | port.iotype = UPIO_MEM; | 307 | port.iotype = UPIO_MEM; |
307 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 308 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
308 | port.line = 0; | 309 | port.line = 0; |
309 | 310 | ||
310 | if (early_serial_setup(&port) != 0) | 311 | if (early_serial_setup(&port) != 0) |
311 | printk("Early serial init of port 0 failed\n"); | 312 | printk("Early serial init of port 0 failed\n"); |
312 | 313 | ||
313 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 314 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
314 | /* Configure debug serial access */ | 315 | /* Configure debug serial access */ |
315 | gen550_init(0, &port); | 316 | gen550_init(0, &port); |
316 | 317 | ||
317 | /* Purge TLB entry added in head_44x.S for early serial access */ | 318 | /* Purge TLB entry added in head_44x.S for early serial access */ |
318 | _tlbie(UART0_IO_BASE); | 319 | _tlbie(UART0_IO_BASE); |
319 | #endif | 320 | #endif |
320 | 321 | ||
321 | port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); | 322 | port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); |
322 | port.irq = UART1_INT; | 323 | port.irq = UART1_INT; |
323 | port.uartclk = clocks.uart1; | 324 | port.uartclk = clocks.uart1; |
324 | port.line = 1; | 325 | port.line = 1; |
325 | 326 | ||
326 | if (early_serial_setup(&port) != 0) | 327 | if (early_serial_setup(&port) != 0) |
327 | printk("Early serial init of port 1 failed\n"); | 328 | printk("Early serial init of port 1 failed\n"); |
328 | 329 | ||
329 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 330 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
330 | /* Configure debug serial access */ | 331 | /* Configure debug serial access */ |
331 | gen550_init(1, &port); | 332 | gen550_init(1, &port); |
332 | #endif | 333 | #endif |
333 | } | 334 | } |
334 | 335 | ||
335 | static void __init | 336 | static void __init |
336 | taishan_setup_arch(void) | 337 | taishan_setup_arch(void) |
337 | { | 338 | { |
338 | taishan_set_emacdata(); | 339 | taishan_set_emacdata(); |
339 | 340 | ||
340 | ibm440gx_tah_enable(); | 341 | ibm440gx_tah_enable(); |
341 | 342 | ||
342 | /* | 343 | /* |
343 | * Determine various clocks. | 344 | * Determine various clocks. |
344 | * To be completely correct we should get SysClk | 345 | * To be completely correct we should get SysClk |
345 | * from FPGA, because it can be changed by on-board switches | 346 | * from FPGA, because it can be changed by on-board switches |
346 | * --ebs | 347 | * --ebs |
347 | */ | 348 | */ |
348 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); | 349 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); |
349 | ocp_sys_info.opb_bus_freq = clocks.opb; | 350 | ocp_sys_info.opb_bus_freq = clocks.opb; |
350 | 351 | ||
351 | /* init to some ~sane value until calibrate_delay() runs */ | 352 | /* init to some ~sane value until calibrate_delay() runs */ |
352 | loops_per_jiffy = 50000000/HZ; | 353 | loops_per_jiffy = 50000000/HZ; |
353 | 354 | ||
354 | /* Setup PCI host bridge */ | 355 | /* Setup PCI host bridge */ |
355 | taishan_setup_hose(); | 356 | taishan_setup_hose(); |
356 | 357 | ||
357 | #ifdef CONFIG_BLK_DEV_INITRD | 358 | #ifdef CONFIG_BLK_DEV_INITRD |
358 | if (initrd_start) | 359 | if (initrd_start) |
359 | ROOT_DEV = Root_RAM0; | 360 | ROOT_DEV = Root_RAM0; |
360 | else | 361 | else |
361 | #endif | 362 | #endif |
362 | #ifdef CONFIG_ROOT_NFS | 363 | #ifdef CONFIG_ROOT_NFS |
363 | ROOT_DEV = Root_NFS; | 364 | ROOT_DEV = Root_NFS; |
364 | #else | 365 | #else |
365 | ROOT_DEV = Root_HDA1; | 366 | ROOT_DEV = Root_HDA1; |
366 | #endif | 367 | #endif |
367 | 368 | ||
368 | taishan_early_serial_map(); | 369 | taishan_early_serial_map(); |
369 | 370 | ||
370 | /* Identify the system */ | 371 | /* Identify the system */ |
371 | printk("AMCC PowerPC 440GX Taishan Platform\n"); | 372 | printk("AMCC PowerPC 440GX Taishan Platform\n"); |
372 | } | 373 | } |
373 | 374 | ||
374 | static void __init taishan_init(void) | 375 | static void __init taishan_init(void) |
375 | { | 376 | { |
376 | ibm440gx_l2c_setup(&clocks); | 377 | ibm440gx_l2c_setup(&clocks); |
377 | } | 378 | } |
378 | 379 | ||
379 | void __init platform_init(unsigned long r3, unsigned long r4, | 380 | void __init platform_init(unsigned long r3, unsigned long r4, |
380 | unsigned long r5, unsigned long r6, unsigned long r7) | 381 | unsigned long r5, unsigned long r6, unsigned long r7) |
381 | { | 382 | { |
382 | ibm44x_platform_init(r3, r4, r5, r6, r7); | 383 | ibm44x_platform_init(r3, r4, r5, r6, r7); |
383 | 384 | ||
384 | ppc_md.setup_arch = taishan_setup_arch; | 385 | ppc_md.setup_arch = taishan_setup_arch; |
385 | ppc_md.show_cpuinfo = taishan_show_cpuinfo; | 386 | ppc_md.show_cpuinfo = taishan_show_cpuinfo; |
386 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ | 387 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ |
387 | 388 | ||
388 | ppc_md.calibrate_decr = taishan_calibrate_decr; | 389 | ppc_md.calibrate_decr = taishan_calibrate_decr; |
389 | 390 | ||
390 | #ifdef CONFIG_KGDB | 391 | #ifdef CONFIG_KGDB |
391 | ppc_md.early_serial_map = taishan_early_serial_map; | 392 | ppc_md.early_serial_map = taishan_early_serial_map; |
392 | #endif | 393 | #endif |
393 | ppc_md.init = taishan_init; | 394 | ppc_md.init = taishan_init; |
394 | } | 395 | } |
395 | 396 | ||
396 | 397 |
arch/ppc/platforms/4xx/yucca.c
1 | /* | 1 | /* |
2 | * Yucca board specific routines | 2 | * Yucca board specific routines |
3 | * | 3 | * |
4 | * Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter) | 4 | * Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter) |
5 | * | 5 | * |
6 | * Copyright 2004-2005 MontaVista Software Inc. | 6 | * Copyright 2004-2005 MontaVista Software Inc. |
7 | * Copyright (c) 2005 Cisco Systems. All rights reserved. | 7 | * Copyright (c) 2005 Cisco Systems. All rights reserved. |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the | 10 | * under the terms of the GNU General Public License as published by the |
11 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/stddef.h> | 15 | #include <linux/stddef.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/reboot.h> | 19 | #include <linux/reboot.h> |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/kdev_t.h> | 21 | #include <linux/kdev_t.h> |
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | #include <linux/major.h> | 23 | #include <linux/major.h> |
24 | #include <linux/blkdev.h> | 24 | #include <linux/blkdev.h> |
25 | #include <linux/console.h> | 25 | #include <linux/console.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/ide.h> | 27 | #include <linux/ide.h> |
28 | #include <linux/initrd.h> | 28 | #include <linux/initrd.h> |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/root_dev.h> | 30 | #include <linux/root_dev.h> |
31 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
32 | #include <linux/serial.h> | 32 | #include <linux/serial.h> |
33 | #include <linux/serial_core.h> | 33 | #include <linux/serial_core.h> |
34 | #include <linux/serial_8250.h> | ||
34 | 35 | ||
35 | #include <asm/system.h> | 36 | #include <asm/system.h> |
36 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
37 | #include <asm/page.h> | 38 | #include <asm/page.h> |
38 | #include <asm/dma.h> | 39 | #include <asm/dma.h> |
39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
40 | #include <asm/machdep.h> | 41 | #include <asm/machdep.h> |
41 | #include <asm/ocp.h> | 42 | #include <asm/ocp.h> |
42 | #include <asm/pci-bridge.h> | 43 | #include <asm/pci-bridge.h> |
43 | #include <asm/time.h> | 44 | #include <asm/time.h> |
44 | #include <asm/todc.h> | 45 | #include <asm/todc.h> |
45 | #include <asm/bootinfo.h> | 46 | #include <asm/bootinfo.h> |
46 | #include <asm/ppc4xx_pic.h> | 47 | #include <asm/ppc4xx_pic.h> |
47 | #include <asm/ppcboot.h> | 48 | #include <asm/ppcboot.h> |
48 | 49 | ||
49 | #include <syslib/ibm44x_common.h> | 50 | #include <syslib/ibm44x_common.h> |
50 | #include <syslib/ibm440gx_common.h> | 51 | #include <syslib/ibm440gx_common.h> |
51 | #include <syslib/ibm440sp_common.h> | 52 | #include <syslib/ibm440sp_common.h> |
52 | #include <syslib/ppc440spe_pcie.h> | 53 | #include <syslib/ppc440spe_pcie.h> |
53 | 54 | ||
54 | extern bd_t __res; | 55 | extern bd_t __res; |
55 | 56 | ||
56 | static struct ibm44x_clocks clocks __initdata; | 57 | static struct ibm44x_clocks clocks __initdata; |
57 | 58 | ||
58 | static void __init | 59 | static void __init |
59 | yucca_calibrate_decr(void) | 60 | yucca_calibrate_decr(void) |
60 | { | 61 | { |
61 | unsigned int freq; | 62 | unsigned int freq; |
62 | 63 | ||
63 | if (mfspr(SPRN_CCR1) & CCR1_TCS) | 64 | if (mfspr(SPRN_CCR1) & CCR1_TCS) |
64 | freq = YUCCA_TMR_CLK; | 65 | freq = YUCCA_TMR_CLK; |
65 | else | 66 | else |
66 | freq = clocks.cpu; | 67 | freq = clocks.cpu; |
67 | 68 | ||
68 | ibm44x_calibrate_decr(freq); | 69 | ibm44x_calibrate_decr(freq); |
69 | } | 70 | } |
70 | 71 | ||
71 | static int | 72 | static int |
72 | yucca_show_cpuinfo(struct seq_file *m) | 73 | yucca_show_cpuinfo(struct seq_file *m) |
73 | { | 74 | { |
74 | seq_printf(m, "vendor\t\t: AMCC\n"); | 75 | seq_printf(m, "vendor\t\t: AMCC\n"); |
75 | seq_printf(m, "machine\t\t: PPC440SPe EVB (Yucca)\n"); | 76 | seq_printf(m, "machine\t\t: PPC440SPe EVB (Yucca)\n"); |
76 | 77 | ||
77 | return 0; | 78 | return 0; |
78 | } | 79 | } |
79 | 80 | ||
80 | static enum { | 81 | static enum { |
81 | HOSE_UNKNOWN, | 82 | HOSE_UNKNOWN, |
82 | HOSE_PCIX, | 83 | HOSE_PCIX, |
83 | HOSE_PCIE0, | 84 | HOSE_PCIE0, |
84 | HOSE_PCIE1, | 85 | HOSE_PCIE1, |
85 | HOSE_PCIE2 | 86 | HOSE_PCIE2 |
86 | } hose_type[4]; | 87 | } hose_type[4]; |
87 | 88 | ||
88 | static inline int | 89 | static inline int |
89 | yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 90 | yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
90 | { | 91 | { |
91 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | 92 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); |
92 | 93 | ||
93 | if (hose_type[hose->index] == HOSE_PCIX) { | 94 | if (hose_type[hose->index] == HOSE_PCIX) { |
94 | static char pci_irq_table[][4] = | 95 | static char pci_irq_table[][4] = |
95 | /* | 96 | /* |
96 | * PCI IDSEL/INTPIN->INTLINE | 97 | * PCI IDSEL/INTPIN->INTLINE |
97 | * A B C D | 98 | * A B C D |
98 | */ | 99 | */ |
99 | { | 100 | { |
100 | { 81, -1, -1, -1 }, /* IDSEL 1 - PCIX0 Slot 0 */ | 101 | { 81, -1, -1, -1 }, /* IDSEL 1 - PCIX0 Slot 0 */ |
101 | }; | 102 | }; |
102 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; | 103 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; |
103 | return PCI_IRQ_TABLE_LOOKUP; | 104 | return PCI_IRQ_TABLE_LOOKUP; |
104 | } else if (hose_type[hose->index] == HOSE_PCIE0) { | 105 | } else if (hose_type[hose->index] == HOSE_PCIE0) { |
105 | static char pci_irq_table[][4] = | 106 | static char pci_irq_table[][4] = |
106 | /* | 107 | /* |
107 | * PCI IDSEL/INTPIN->INTLINE | 108 | * PCI IDSEL/INTPIN->INTLINE |
108 | * A B C D | 109 | * A B C D |
109 | */ | 110 | */ |
110 | { | 111 | { |
111 | { 96, 97, 98, 99 }, | 112 | { 96, 97, 98, 99 }, |
112 | }; | 113 | }; |
113 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; | 114 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; |
114 | return PCI_IRQ_TABLE_LOOKUP; | 115 | return PCI_IRQ_TABLE_LOOKUP; |
115 | } else if (hose_type[hose->index] == HOSE_PCIE1) { | 116 | } else if (hose_type[hose->index] == HOSE_PCIE1) { |
116 | static char pci_irq_table[][4] = | 117 | static char pci_irq_table[][4] = |
117 | /* | 118 | /* |
118 | * PCI IDSEL/INTPIN->INTLINE | 119 | * PCI IDSEL/INTPIN->INTLINE |
119 | * A B C D | 120 | * A B C D |
120 | */ | 121 | */ |
121 | { | 122 | { |
122 | { 100, 101, 102, 103 }, | 123 | { 100, 101, 102, 103 }, |
123 | }; | 124 | }; |
124 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; | 125 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; |
125 | return PCI_IRQ_TABLE_LOOKUP; | 126 | return PCI_IRQ_TABLE_LOOKUP; |
126 | } else if (hose_type[hose->index] == HOSE_PCIE2) { | 127 | } else if (hose_type[hose->index] == HOSE_PCIE2) { |
127 | static char pci_irq_table[][4] = | 128 | static char pci_irq_table[][4] = |
128 | /* | 129 | /* |
129 | * PCI IDSEL/INTPIN->INTLINE | 130 | * PCI IDSEL/INTPIN->INTLINE |
130 | * A B C D | 131 | * A B C D |
131 | */ | 132 | */ |
132 | { | 133 | { |
133 | { 104, 105, 106, 107 }, | 134 | { 104, 105, 106, 107 }, |
134 | }; | 135 | }; |
135 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; | 136 | const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4; |
136 | return PCI_IRQ_TABLE_LOOKUP; | 137 | return PCI_IRQ_TABLE_LOOKUP; |
137 | } | 138 | } |
138 | return -1; | 139 | return -1; |
139 | } | 140 | } |
140 | 141 | ||
141 | static void __init yucca_set_emacdata(void) | 142 | static void __init yucca_set_emacdata(void) |
142 | { | 143 | { |
143 | struct ocp_def *def; | 144 | struct ocp_def *def; |
144 | struct ocp_func_emac_data *emacdata; | 145 | struct ocp_func_emac_data *emacdata; |
145 | 146 | ||
146 | /* Set phy_map, phy_mode, and mac_addr for the EMAC */ | 147 | /* Set phy_map, phy_mode, and mac_addr for the EMAC */ |
147 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); | 148 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); |
148 | emacdata = def->additions; | 149 | emacdata = def->additions; |
149 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ | 150 | emacdata->phy_map = 0x00000001; /* Skip 0x00 */ |
150 | emacdata->phy_mode = PHY_MODE_GMII; | 151 | emacdata->phy_mode = PHY_MODE_GMII; |
151 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); | 152 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); |
152 | } | 153 | } |
153 | 154 | ||
154 | static int __init yucca_pcie_card_present(int port) | 155 | static int __init yucca_pcie_card_present(int port) |
155 | { | 156 | { |
156 | void __iomem *pcie_fpga_base; | 157 | void __iomem *pcie_fpga_base; |
157 | u16 reg; | 158 | u16 reg; |
158 | 159 | ||
159 | pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE); | 160 | pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE); |
160 | reg = in_be16(pcie_fpga_base + FPGA_REG1C); | 161 | reg = in_be16(pcie_fpga_base + FPGA_REG1C); |
161 | iounmap(pcie_fpga_base); | 162 | iounmap(pcie_fpga_base); |
162 | 163 | ||
163 | switch(port) { | 164 | switch(port) { |
164 | case 0: return !(reg & FPGA_REG1C_PE0_PRSNT); | 165 | case 0: return !(reg & FPGA_REG1C_PE0_PRSNT); |
165 | case 1: return !(reg & FPGA_REG1C_PE1_PRSNT); | 166 | case 1: return !(reg & FPGA_REG1C_PE1_PRSNT); |
166 | case 2: return !(reg & FPGA_REG1C_PE2_PRSNT); | 167 | case 2: return !(reg & FPGA_REG1C_PE2_PRSNT); |
167 | default: return 0; | 168 | default: return 0; |
168 | } | 169 | } |
169 | } | 170 | } |
170 | 171 | ||
171 | /* | 172 | /* |
172 | * For the given slot, set rootpoint mode, send power to the slot, | 173 | * For the given slot, set rootpoint mode, send power to the slot, |
173 | * turn on the green LED and turn off the yellow LED, enable the clock | 174 | * turn on the green LED and turn off the yellow LED, enable the clock |
174 | * and turn off reset. | 175 | * and turn off reset. |
175 | */ | 176 | */ |
176 | static void __init yucca_setup_pcie_fpga_rootpoint(int port) | 177 | static void __init yucca_setup_pcie_fpga_rootpoint(int port) |
177 | { | 178 | { |
178 | void __iomem *pcie_reg_fpga_base; | 179 | void __iomem *pcie_reg_fpga_base; |
179 | u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint; | 180 | u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint; |
180 | 181 | ||
181 | pcie_reg_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE); | 182 | pcie_reg_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE); |
182 | 183 | ||
183 | switch(port) { | 184 | switch(port) { |
184 | case 0: | 185 | case 0: |
185 | rootpoint = FPGA_REG1C_PE0_ROOTPOINT; | 186 | rootpoint = FPGA_REG1C_PE0_ROOTPOINT; |
186 | endpoint = 0; | 187 | endpoint = 0; |
187 | power = FPGA_REG1A_PE0_PWRON; | 188 | power = FPGA_REG1A_PE0_PWRON; |
188 | green_led = FPGA_REG1A_PE0_GLED; | 189 | green_led = FPGA_REG1A_PE0_GLED; |
189 | clock = FPGA_REG1A_PE0_REFCLK_ENABLE; | 190 | clock = FPGA_REG1A_PE0_REFCLK_ENABLE; |
190 | yellow_led = FPGA_REG1A_PE0_YLED; | 191 | yellow_led = FPGA_REG1A_PE0_YLED; |
191 | reset_off = FPGA_REG1C_PE0_PERST; | 192 | reset_off = FPGA_REG1C_PE0_PERST; |
192 | break; | 193 | break; |
193 | case 1: | 194 | case 1: |
194 | rootpoint = 0; | 195 | rootpoint = 0; |
195 | endpoint = FPGA_REG1C_PE1_ENDPOINT; | 196 | endpoint = FPGA_REG1C_PE1_ENDPOINT; |
196 | power = FPGA_REG1A_PE1_PWRON; | 197 | power = FPGA_REG1A_PE1_PWRON; |
197 | green_led = FPGA_REG1A_PE1_GLED; | 198 | green_led = FPGA_REG1A_PE1_GLED; |
198 | clock = FPGA_REG1A_PE1_REFCLK_ENABLE; | 199 | clock = FPGA_REG1A_PE1_REFCLK_ENABLE; |
199 | yellow_led = FPGA_REG1A_PE1_YLED; | 200 | yellow_led = FPGA_REG1A_PE1_YLED; |
200 | reset_off = FPGA_REG1C_PE1_PERST; | 201 | reset_off = FPGA_REG1C_PE1_PERST; |
201 | break; | 202 | break; |
202 | case 2: | 203 | case 2: |
203 | rootpoint = 0; | 204 | rootpoint = 0; |
204 | endpoint = FPGA_REG1C_PE2_ENDPOINT; | 205 | endpoint = FPGA_REG1C_PE2_ENDPOINT; |
205 | power = FPGA_REG1A_PE2_PWRON; | 206 | power = FPGA_REG1A_PE2_PWRON; |
206 | green_led = FPGA_REG1A_PE2_GLED; | 207 | green_led = FPGA_REG1A_PE2_GLED; |
207 | clock = FPGA_REG1A_PE2_REFCLK_ENABLE; | 208 | clock = FPGA_REG1A_PE2_REFCLK_ENABLE; |
208 | yellow_led = FPGA_REG1A_PE2_YLED; | 209 | yellow_led = FPGA_REG1A_PE2_YLED; |
209 | reset_off = FPGA_REG1C_PE2_PERST; | 210 | reset_off = FPGA_REG1C_PE2_PERST; |
210 | break; | 211 | break; |
211 | 212 | ||
212 | default: | 213 | default: |
213 | return; | 214 | return; |
214 | } | 215 | } |
215 | 216 | ||
216 | out_be16(pcie_reg_fpga_base + FPGA_REG1A, | 217 | out_be16(pcie_reg_fpga_base + FPGA_REG1A, |
217 | ~(power | clock | green_led) & | 218 | ~(power | clock | green_led) & |
218 | (yellow_led | in_be16(pcie_reg_fpga_base + FPGA_REG1A))); | 219 | (yellow_led | in_be16(pcie_reg_fpga_base + FPGA_REG1A))); |
219 | out_be16(pcie_reg_fpga_base + FPGA_REG1C, | 220 | out_be16(pcie_reg_fpga_base + FPGA_REG1C, |
220 | ~(endpoint | reset_off) & | 221 | ~(endpoint | reset_off) & |
221 | (rootpoint | in_be16(pcie_reg_fpga_base + FPGA_REG1C))); | 222 | (rootpoint | in_be16(pcie_reg_fpga_base + FPGA_REG1C))); |
222 | 223 | ||
223 | /* | 224 | /* |
224 | * Leave device in reset for a while after powering on the | 225 | * Leave device in reset for a while after powering on the |
225 | * slot to give it a chance to initialize. | 226 | * slot to give it a chance to initialize. |
226 | */ | 227 | */ |
227 | mdelay(250); | 228 | mdelay(250); |
228 | 229 | ||
229 | out_be16(pcie_reg_fpga_base + FPGA_REG1C, | 230 | out_be16(pcie_reg_fpga_base + FPGA_REG1C, |
230 | reset_off | in_be16(pcie_reg_fpga_base + FPGA_REG1C)); | 231 | reset_off | in_be16(pcie_reg_fpga_base + FPGA_REG1C)); |
231 | 232 | ||
232 | iounmap(pcie_reg_fpga_base); | 233 | iounmap(pcie_reg_fpga_base); |
233 | } | 234 | } |
234 | 235 | ||
235 | static void __init | 236 | static void __init |
236 | yucca_setup_hoses(void) | 237 | yucca_setup_hoses(void) |
237 | { | 238 | { |
238 | struct pci_controller *hose; | 239 | struct pci_controller *hose; |
239 | char name[20]; | 240 | char name[20]; |
240 | int i; | 241 | int i; |
241 | 242 | ||
242 | if (0 && ppc440spe_init_pcie()) { | 243 | if (0 && ppc440spe_init_pcie()) { |
243 | printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n"); | 244 | printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n"); |
244 | return; | 245 | return; |
245 | } | 246 | } |
246 | 247 | ||
247 | for (i = 0; i <= 2; ++i) { | 248 | for (i = 0; i <= 2; ++i) { |
248 | if (!yucca_pcie_card_present(i)) | 249 | if (!yucca_pcie_card_present(i)) |
249 | continue; | 250 | continue; |
250 | 251 | ||
251 | printk(KERN_INFO "PCIE%d: card present\n", i); | 252 | printk(KERN_INFO "PCIE%d: card present\n", i); |
252 | yucca_setup_pcie_fpga_rootpoint(i); | 253 | yucca_setup_pcie_fpga_rootpoint(i); |
253 | if (ppc440spe_init_pcie_rootport(i)) { | 254 | if (ppc440spe_init_pcie_rootport(i)) { |
254 | printk(KERN_WARNING "PCIE%d: initialization failed\n", i); | 255 | printk(KERN_WARNING "PCIE%d: initialization failed\n", i); |
255 | continue; | 256 | continue; |
256 | } | 257 | } |
257 | 258 | ||
258 | hose = pcibios_alloc_controller(); | 259 | hose = pcibios_alloc_controller(); |
259 | if (!hose) | 260 | if (!hose) |
260 | return; | 261 | return; |
261 | 262 | ||
262 | sprintf(name, "PCIE%d host bridge", i); | 263 | sprintf(name, "PCIE%d host bridge", i); |
263 | pci_init_resource(&hose->io_resource, | 264 | pci_init_resource(&hose->io_resource, |
264 | YUCCA_PCIX_LOWER_IO, | 265 | YUCCA_PCIX_LOWER_IO, |
265 | YUCCA_PCIX_UPPER_IO, | 266 | YUCCA_PCIX_UPPER_IO, |
266 | IORESOURCE_IO, | 267 | IORESOURCE_IO, |
267 | name); | 268 | name); |
268 | 269 | ||
269 | hose->mem_space.start = YUCCA_PCIE_LOWER_MEM + | 270 | hose->mem_space.start = YUCCA_PCIE_LOWER_MEM + |
270 | i * YUCCA_PCIE_MEM_SIZE; | 271 | i * YUCCA_PCIE_MEM_SIZE; |
271 | hose->mem_space.end = hose->mem_space.start + | 272 | hose->mem_space.end = hose->mem_space.start + |
272 | YUCCA_PCIE_MEM_SIZE - 1; | 273 | YUCCA_PCIE_MEM_SIZE - 1; |
273 | 274 | ||
274 | pci_init_resource(&hose->mem_resources[0], | 275 | pci_init_resource(&hose->mem_resources[0], |
275 | hose->mem_space.start, | 276 | hose->mem_space.start, |
276 | hose->mem_space.end, | 277 | hose->mem_space.end, |
277 | IORESOURCE_MEM, | 278 | IORESOURCE_MEM, |
278 | name); | 279 | name); |
279 | 280 | ||
280 | hose->first_busno = 0; | 281 | hose->first_busno = 0; |
281 | hose->last_busno = 15; | 282 | hose->last_busno = 15; |
282 | hose_type[hose->index] = HOSE_PCIE0 + i; | 283 | hose_type[hose->index] = HOSE_PCIE0 + i; |
283 | 284 | ||
284 | ppc440spe_setup_pcie(hose, i); | 285 | ppc440spe_setup_pcie(hose, i); |
285 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | 286 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); |
286 | } | 287 | } |
287 | 288 | ||
288 | ppc_md.pci_swizzle = common_swizzle; | 289 | ppc_md.pci_swizzle = common_swizzle; |
289 | ppc_md.pci_map_irq = yucca_map_irq; | 290 | ppc_md.pci_map_irq = yucca_map_irq; |
290 | } | 291 | } |
291 | 292 | ||
292 | TODC_ALLOC(); | 293 | TODC_ALLOC(); |
293 | 294 | ||
294 | static void __init | 295 | static void __init |
295 | yucca_early_serial_map(void) | 296 | yucca_early_serial_map(void) |
296 | { | 297 | { |
297 | struct uart_port port; | 298 | struct uart_port port; |
298 | 299 | ||
299 | /* Setup ioremapped serial port access */ | 300 | /* Setup ioremapped serial port access */ |
300 | memset(&port, 0, sizeof(port)); | 301 | memset(&port, 0, sizeof(port)); |
301 | port.membase = ioremap64(PPC440SPE_UART0_ADDR, 8); | 302 | port.membase = ioremap64(PPC440SPE_UART0_ADDR, 8); |
302 | port.irq = UART0_INT; | 303 | port.irq = UART0_INT; |
303 | port.uartclk = clocks.uart0; | 304 | port.uartclk = clocks.uart0; |
304 | port.regshift = 0; | 305 | port.regshift = 0; |
305 | port.iotype = UPIO_MEM; | 306 | port.iotype = UPIO_MEM; |
306 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | 307 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
307 | port.line = 0; | 308 | port.line = 0; |
308 | 309 | ||
309 | if (early_serial_setup(&port) != 0) { | 310 | if (early_serial_setup(&port) != 0) { |
310 | printk("Early serial init of port 0 failed\n"); | 311 | printk("Early serial init of port 0 failed\n"); |
311 | } | 312 | } |
312 | 313 | ||
313 | port.membase = ioremap64(PPC440SPE_UART1_ADDR, 8); | 314 | port.membase = ioremap64(PPC440SPE_UART1_ADDR, 8); |
314 | port.irq = UART1_INT; | 315 | port.irq = UART1_INT; |
315 | port.uartclk = clocks.uart1; | 316 | port.uartclk = clocks.uart1; |
316 | port.line = 1; | 317 | port.line = 1; |
317 | 318 | ||
318 | if (early_serial_setup(&port) != 0) { | 319 | if (early_serial_setup(&port) != 0) { |
319 | printk("Early serial init of port 1 failed\n"); | 320 | printk("Early serial init of port 1 failed\n"); |
320 | } | 321 | } |
321 | 322 | ||
322 | port.membase = ioremap64(PPC440SPE_UART2_ADDR, 8); | 323 | port.membase = ioremap64(PPC440SPE_UART2_ADDR, 8); |
323 | port.irq = UART2_INT; | 324 | port.irq = UART2_INT; |
324 | port.uartclk = BASE_BAUD; | 325 | port.uartclk = BASE_BAUD; |
325 | port.line = 2; | 326 | port.line = 2; |
326 | 327 | ||
327 | if (early_serial_setup(&port) != 0) { | 328 | if (early_serial_setup(&port) != 0) { |
328 | printk("Early serial init of port 2 failed\n"); | 329 | printk("Early serial init of port 2 failed\n"); |
329 | } | 330 | } |
330 | } | 331 | } |
331 | 332 | ||
332 | static void __init | 333 | static void __init |
333 | yucca_setup_arch(void) | 334 | yucca_setup_arch(void) |
334 | { | 335 | { |
335 | yucca_set_emacdata(); | 336 | yucca_set_emacdata(); |
336 | 337 | ||
337 | #if !defined(CONFIG_BDI_SWITCH) | 338 | #if !defined(CONFIG_BDI_SWITCH) |
338 | /* | 339 | /* |
339 | * The Abatron BDI JTAG debugger does not tolerate others | 340 | * The Abatron BDI JTAG debugger does not tolerate others |
340 | * mucking with the debug registers. | 341 | * mucking with the debug registers. |
341 | */ | 342 | */ |
342 | mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); | 343 | mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); |
343 | #endif | 344 | #endif |
344 | 345 | ||
345 | /* | 346 | /* |
346 | * Determine various clocks. | 347 | * Determine various clocks. |
347 | * To be completely correct we should get SysClk | 348 | * To be completely correct we should get SysClk |
348 | * from FPGA, because it can be changed by on-board switches | 349 | * from FPGA, because it can be changed by on-board switches |
349 | * --ebs | 350 | * --ebs |
350 | */ | 351 | */ |
351 | /* 440GX and 440SPe clocking is the same - rd */ | 352 | /* 440GX and 440SPe clocking is the same - rd */ |
352 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); | 353 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); |
353 | ocp_sys_info.opb_bus_freq = clocks.opb; | 354 | ocp_sys_info.opb_bus_freq = clocks.opb; |
354 | 355 | ||
355 | /* init to some ~sane value until calibrate_delay() runs */ | 356 | /* init to some ~sane value until calibrate_delay() runs */ |
356 | loops_per_jiffy = 50000000/HZ; | 357 | loops_per_jiffy = 50000000/HZ; |
357 | 358 | ||
358 | /* Setup PCIXn host bridges */ | 359 | /* Setup PCIXn host bridges */ |
359 | yucca_setup_hoses(); | 360 | yucca_setup_hoses(); |
360 | 361 | ||
361 | #ifdef CONFIG_BLK_DEV_INITRD | 362 | #ifdef CONFIG_BLK_DEV_INITRD |
362 | if (initrd_start) | 363 | if (initrd_start) |
363 | ROOT_DEV = Root_RAM0; | 364 | ROOT_DEV = Root_RAM0; |
364 | else | 365 | else |
365 | #endif | 366 | #endif |
366 | #ifdef CONFIG_ROOT_NFS | 367 | #ifdef CONFIG_ROOT_NFS |
367 | ROOT_DEV = Root_NFS; | 368 | ROOT_DEV = Root_NFS; |
368 | #else | 369 | #else |
369 | ROOT_DEV = Root_HDA1; | 370 | ROOT_DEV = Root_HDA1; |
370 | #endif | 371 | #endif |
371 | 372 | ||
372 | yucca_early_serial_map(); | 373 | yucca_early_serial_map(); |
373 | 374 | ||
374 | /* Identify the system */ | 375 | /* Identify the system */ |
375 | printk("Yucca port (Roland Dreier <rolandd@cisco.com>)\n"); | 376 | printk("Yucca port (Roland Dreier <rolandd@cisco.com>)\n"); |
376 | } | 377 | } |
377 | 378 | ||
378 | void __init platform_init(unsigned long r3, unsigned long r4, | 379 | void __init platform_init(unsigned long r3, unsigned long r4, |
379 | unsigned long r5, unsigned long r6, unsigned long r7) | 380 | unsigned long r5, unsigned long r6, unsigned long r7) |
380 | { | 381 | { |
381 | ibm44x_platform_init(r3, r4, r5, r6, r7); | 382 | ibm44x_platform_init(r3, r4, r5, r6, r7); |
382 | 383 | ||
383 | ppc_md.setup_arch = yucca_setup_arch; | 384 | ppc_md.setup_arch = yucca_setup_arch; |
384 | ppc_md.show_cpuinfo = yucca_show_cpuinfo; | 385 | ppc_md.show_cpuinfo = yucca_show_cpuinfo; |
385 | ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory; | 386 | ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory; |
386 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ | 387 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ |
387 | 388 | ||
388 | ppc_md.calibrate_decr = yucca_calibrate_decr; | 389 | ppc_md.calibrate_decr = yucca_calibrate_decr; |
389 | #ifdef CONFIG_KGDB | 390 | #ifdef CONFIG_KGDB |
390 | ppc_md.early_serial_map = yucca_early_serial_map; | 391 | ppc_md.early_serial_map = yucca_early_serial_map; |
391 | #endif | 392 | #endif |
392 | } | 393 | } |
393 | 394 |
arch/ppc/platforms/85xx/sbc8560.c
1 | /* | 1 | /* |
2 | * Wind River SBC8560 board specific routines | 2 | * Wind River SBC8560 board specific routines |
3 | * | 3 | * |
4 | * Maintainer: Kumar Gala | 4 | * Maintainer: Kumar Gala |
5 | * | 5 | * |
6 | * Copyright 2004 Freescale Semiconductor Inc. | 6 | * Copyright 2004 Freescale Semiconductor Inc. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
10 | * Free Software Foundation; either version 2 of the License, or (at your | 10 | * Free Software Foundation; either version 2 of the License, or (at your |
11 | * option) any later version. | 11 | * option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/stddef.h> | 14 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/kdev_t.h> | 20 | #include <linux/kdev_t.h> |
21 | #include <linux/major.h> | 21 | #include <linux/major.h> |
22 | #include <linux/console.h> | 22 | #include <linux/console.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/root_dev.h> | 25 | #include <linux/root_dev.h> |
26 | #include <linux/serial.h> | 26 | #include <linux/serial.h> |
27 | #include <linux/tty.h> /* for linux/serial_core.h */ | 27 | #include <linux/tty.h> /* for linux/serial_core.h */ |
28 | #include <linux/serial_core.h> | 28 | #include <linux/serial_core.h> |
29 | #include <linux/serial_8250.h> | ||
29 | #include <linux/initrd.h> | 30 | #include <linux/initrd.h> |
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/fsl_devices.h> | 32 | #include <linux/fsl_devices.h> |
32 | 33 | ||
33 | #include <asm/system.h> | 34 | #include <asm/system.h> |
34 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
35 | #include <asm/page.h> | 36 | #include <asm/page.h> |
36 | #include <asm/atomic.h> | 37 | #include <asm/atomic.h> |
37 | #include <asm/time.h> | 38 | #include <asm/time.h> |
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
40 | #include <asm/open_pic.h> | 41 | #include <asm/open_pic.h> |
41 | #include <asm/bootinfo.h> | 42 | #include <asm/bootinfo.h> |
42 | #include <asm/pci-bridge.h> | 43 | #include <asm/pci-bridge.h> |
43 | #include <asm/mpc85xx.h> | 44 | #include <asm/mpc85xx.h> |
44 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
45 | #include <asm/immap_85xx.h> | 46 | #include <asm/immap_85xx.h> |
46 | #include <asm/kgdb.h> | 47 | #include <asm/kgdb.h> |
47 | #include <asm/ppc_sys.h> | 48 | #include <asm/ppc_sys.h> |
48 | #include <mm/mmu_decl.h> | 49 | #include <mm/mmu_decl.h> |
49 | 50 | ||
50 | #include <syslib/ppc85xx_common.h> | 51 | #include <syslib/ppc85xx_common.h> |
51 | #include <syslib/ppc85xx_setup.h> | 52 | #include <syslib/ppc85xx_setup.h> |
52 | 53 | ||
53 | #ifdef CONFIG_SERIAL_8250 | 54 | #ifdef CONFIG_SERIAL_8250 |
54 | static void __init | 55 | static void __init |
55 | sbc8560_early_serial_map(void) | 56 | sbc8560_early_serial_map(void) |
56 | { | 57 | { |
57 | struct uart_port uart_req; | 58 | struct uart_port uart_req; |
58 | 59 | ||
59 | /* Setup serial port access */ | 60 | /* Setup serial port access */ |
60 | memset(&uart_req, 0, sizeof (uart_req)); | 61 | memset(&uart_req, 0, sizeof (uart_req)); |
61 | uart_req.irq = MPC85xx_IRQ_EXT9; | 62 | uart_req.irq = MPC85xx_IRQ_EXT9; |
62 | uart_req.flags = STD_COM_FLAGS; | 63 | uart_req.flags = STD_COM_FLAGS; |
63 | uart_req.uartclk = BASE_BAUD * 16; | 64 | uart_req.uartclk = BASE_BAUD * 16; |
64 | uart_req.iotype = UPIO_MEM; | 65 | uart_req.iotype = UPIO_MEM; |
65 | uart_req.mapbase = UARTA_ADDR; | 66 | uart_req.mapbase = UARTA_ADDR; |
66 | uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE); | 67 | uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE); |
67 | uart_req.type = PORT_16650; | 68 | uart_req.type = PORT_16650; |
68 | 69 | ||
69 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 70 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
70 | gen550_init(0, &uart_req); | 71 | gen550_init(0, &uart_req); |
71 | #endif | 72 | #endif |
72 | 73 | ||
73 | if (early_serial_setup(&uart_req) != 0) | 74 | if (early_serial_setup(&uart_req) != 0) |
74 | printk("Early serial init of port 0 failed\n"); | 75 | printk("Early serial init of port 0 failed\n"); |
75 | 76 | ||
76 | /* Assume early_serial_setup() doesn't modify uart_req */ | 77 | /* Assume early_serial_setup() doesn't modify uart_req */ |
77 | uart_req.line = 1; | 78 | uart_req.line = 1; |
78 | uart_req.mapbase = UARTB_ADDR; | 79 | uart_req.mapbase = UARTB_ADDR; |
79 | uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART1_SIZE); | 80 | uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART1_SIZE); |
80 | uart_req.irq = MPC85xx_IRQ_EXT10; | 81 | uart_req.irq = MPC85xx_IRQ_EXT10; |
81 | 82 | ||
82 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 83 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
83 | gen550_init(1, &uart_req); | 84 | gen550_init(1, &uart_req); |
84 | #endif | 85 | #endif |
85 | 86 | ||
86 | if (early_serial_setup(&uart_req) != 0) | 87 | if (early_serial_setup(&uart_req) != 0) |
87 | printk("Early serial init of port 1 failed\n"); | 88 | printk("Early serial init of port 1 failed\n"); |
88 | } | 89 | } |
89 | #endif | 90 | #endif |
90 | 91 | ||
91 | /* ************************************************************************ | 92 | /* ************************************************************************ |
92 | * | 93 | * |
93 | * Setup the architecture | 94 | * Setup the architecture |
94 | * | 95 | * |
95 | */ | 96 | */ |
96 | static void __init | 97 | static void __init |
97 | sbc8560_setup_arch(void) | 98 | sbc8560_setup_arch(void) |
98 | { | 99 | { |
99 | bd_t *binfo = (bd_t *) __res; | 100 | bd_t *binfo = (bd_t *) __res; |
100 | unsigned int freq; | 101 | unsigned int freq; |
101 | struct gianfar_platform_data *pdata; | 102 | struct gianfar_platform_data *pdata; |
102 | struct gianfar_mdio_data *mdata; | 103 | struct gianfar_mdio_data *mdata; |
103 | 104 | ||
104 | /* get the core frequency */ | 105 | /* get the core frequency */ |
105 | freq = binfo->bi_intfreq; | 106 | freq = binfo->bi_intfreq; |
106 | 107 | ||
107 | if (ppc_md.progress) | 108 | if (ppc_md.progress) |
108 | ppc_md.progress("sbc8560_setup_arch()", 0); | 109 | ppc_md.progress("sbc8560_setup_arch()", 0); |
109 | 110 | ||
110 | /* Set loops_per_jiffy to a half-way reasonable value, | 111 | /* Set loops_per_jiffy to a half-way reasonable value, |
111 | for use until calibrate_delay gets called. */ | 112 | for use until calibrate_delay gets called. */ |
112 | loops_per_jiffy = freq / HZ; | 113 | loops_per_jiffy = freq / HZ; |
113 | 114 | ||
114 | #ifdef CONFIG_PCI | 115 | #ifdef CONFIG_PCI |
115 | /* setup PCI host bridges */ | 116 | /* setup PCI host bridges */ |
116 | mpc85xx_setup_hose(); | 117 | mpc85xx_setup_hose(); |
117 | #endif | 118 | #endif |
118 | #ifdef CONFIG_SERIAL_8250 | 119 | #ifdef CONFIG_SERIAL_8250 |
119 | sbc8560_early_serial_map(); | 120 | sbc8560_early_serial_map(); |
120 | #endif | 121 | #endif |
121 | #ifdef CONFIG_SERIAL_TEXT_DEBUG | 122 | #ifdef CONFIG_SERIAL_TEXT_DEBUG |
122 | /* Invalidate the entry we stole earlier the serial ports | 123 | /* Invalidate the entry we stole earlier the serial ports |
123 | * should be properly mapped */ | 124 | * should be properly mapped */ |
124 | invalidate_tlbcam_entry(num_tlbcam_entries - 1); | 125 | invalidate_tlbcam_entry(num_tlbcam_entries - 1); |
125 | #endif | 126 | #endif |
126 | 127 | ||
127 | /* setup the board related info for the MDIO bus */ | 128 | /* setup the board related info for the MDIO bus */ |
128 | mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); | 129 | mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); |
129 | 130 | ||
130 | mdata->irq[25] = MPC85xx_IRQ_EXT6; | 131 | mdata->irq[25] = MPC85xx_IRQ_EXT6; |
131 | mdata->irq[26] = MPC85xx_IRQ_EXT7; | 132 | mdata->irq[26] = MPC85xx_IRQ_EXT7; |
132 | mdata->irq[31] = PHY_POLL; | 133 | mdata->irq[31] = PHY_POLL; |
133 | 134 | ||
134 | /* setup the board related information for the enet controllers */ | 135 | /* setup the board related information for the enet controllers */ |
135 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 136 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
136 | if (pdata) { | 137 | if (pdata) { |
137 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 138 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
138 | pdata->bus_id = 0; | 139 | pdata->bus_id = 0; |
139 | pdata->phy_id = 25; | 140 | pdata->phy_id = 25; |
140 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 141 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
141 | } | 142 | } |
142 | 143 | ||
143 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 144 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
144 | if (pdata) { | 145 | if (pdata) { |
145 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 146 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
146 | pdata->bus_id = 0; | 147 | pdata->bus_id = 0; |
147 | pdata->phy_id = 26; | 148 | pdata->phy_id = 26; |
148 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 149 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
149 | } | 150 | } |
150 | 151 | ||
151 | #ifdef CONFIG_BLK_DEV_INITRD | 152 | #ifdef CONFIG_BLK_DEV_INITRD |
152 | if (initrd_start) | 153 | if (initrd_start) |
153 | ROOT_DEV = Root_RAM0; | 154 | ROOT_DEV = Root_RAM0; |
154 | else | 155 | else |
155 | #endif | 156 | #endif |
156 | #ifdef CONFIG_ROOT_NFS | 157 | #ifdef CONFIG_ROOT_NFS |
157 | ROOT_DEV = Root_NFS; | 158 | ROOT_DEV = Root_NFS; |
158 | #else | 159 | #else |
159 | ROOT_DEV = Root_HDA1; | 160 | ROOT_DEV = Root_HDA1; |
160 | #endif | 161 | #endif |
161 | } | 162 | } |
162 | 163 | ||
163 | /* ************************************************************************ */ | 164 | /* ************************************************************************ */ |
164 | void __init | 165 | void __init |
165 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 166 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
166 | unsigned long r6, unsigned long r7) | 167 | unsigned long r6, unsigned long r7) |
167 | { | 168 | { |
168 | /* parse_bootinfo must always be called first */ | 169 | /* parse_bootinfo must always be called first */ |
169 | parse_bootinfo(find_bootinfo()); | 170 | parse_bootinfo(find_bootinfo()); |
170 | 171 | ||
171 | /* | 172 | /* |
172 | * If we were passed in a board information, copy it into the | 173 | * If we were passed in a board information, copy it into the |
173 | * residual data area. | 174 | * residual data area. |
174 | */ | 175 | */ |
175 | if (r3) { | 176 | if (r3) { |
176 | memcpy((void *) __res, (void *) (r3 + KERNELBASE), | 177 | memcpy((void *) __res, (void *) (r3 + KERNELBASE), |
177 | sizeof (bd_t)); | 178 | sizeof (bd_t)); |
178 | } | 179 | } |
179 | 180 | ||
180 | #ifdef CONFIG_SERIAL_TEXT_DEBUG | 181 | #ifdef CONFIG_SERIAL_TEXT_DEBUG |
181 | /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ | 182 | /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ |
182 | settlbcam(num_tlbcam_entries - 1, UARTA_ADDR, | 183 | settlbcam(num_tlbcam_entries - 1, UARTA_ADDR, |
183 | UARTA_ADDR, 0x1000, _PAGE_IO, 0); | 184 | UARTA_ADDR, 0x1000, _PAGE_IO, 0); |
184 | #endif | 185 | #endif |
185 | 186 | ||
186 | #if defined(CONFIG_BLK_DEV_INITRD) | 187 | #if defined(CONFIG_BLK_DEV_INITRD) |
187 | /* | 188 | /* |
188 | * If the init RAM disk has been configured in, and there's a valid | 189 | * If the init RAM disk has been configured in, and there's a valid |
189 | * starting address for it, set it up. | 190 | * starting address for it, set it up. |
190 | */ | 191 | */ |
191 | if (r4) { | 192 | if (r4) { |
192 | initrd_start = r4 + KERNELBASE; | 193 | initrd_start = r4 + KERNELBASE; |
193 | initrd_end = r5 + KERNELBASE; | 194 | initrd_end = r5 + KERNELBASE; |
194 | } | 195 | } |
195 | #endif /* CONFIG_BLK_DEV_INITRD */ | 196 | #endif /* CONFIG_BLK_DEV_INITRD */ |
196 | 197 | ||
197 | /* Copy the kernel command line arguments to a safe place. */ | 198 | /* Copy the kernel command line arguments to a safe place. */ |
198 | 199 | ||
199 | if (r6) { | 200 | if (r6) { |
200 | *(char *) (r7 + KERNELBASE) = 0; | 201 | *(char *) (r7 + KERNELBASE) = 0; |
201 | strcpy(cmd_line, (char *) (r6 + KERNELBASE)); | 202 | strcpy(cmd_line, (char *) (r6 + KERNELBASE)); |
202 | } | 203 | } |
203 | 204 | ||
204 | identify_ppc_sys_by_id(mfspr(SPRN_SVR)); | 205 | identify_ppc_sys_by_id(mfspr(SPRN_SVR)); |
205 | 206 | ||
206 | /* setup the PowerPC module struct */ | 207 | /* setup the PowerPC module struct */ |
207 | ppc_md.setup_arch = sbc8560_setup_arch; | 208 | ppc_md.setup_arch = sbc8560_setup_arch; |
208 | ppc_md.show_cpuinfo = sbc8560_show_cpuinfo; | 209 | ppc_md.show_cpuinfo = sbc8560_show_cpuinfo; |
209 | 210 | ||
210 | ppc_md.init_IRQ = sbc8560_init_IRQ; | 211 | ppc_md.init_IRQ = sbc8560_init_IRQ; |
211 | ppc_md.get_irq = openpic_get_irq; | 212 | ppc_md.get_irq = openpic_get_irq; |
212 | 213 | ||
213 | ppc_md.restart = mpc85xx_restart; | 214 | ppc_md.restart = mpc85xx_restart; |
214 | ppc_md.power_off = mpc85xx_power_off; | 215 | ppc_md.power_off = mpc85xx_power_off; |
215 | ppc_md.halt = mpc85xx_halt; | 216 | ppc_md.halt = mpc85xx_halt; |
216 | 217 | ||
217 | ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory; | 218 | ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory; |
218 | 219 | ||
219 | ppc_md.time_init = NULL; | 220 | ppc_md.time_init = NULL; |
220 | ppc_md.set_rtc_time = NULL; | 221 | ppc_md.set_rtc_time = NULL; |
221 | ppc_md.get_rtc_time = NULL; | 222 | ppc_md.get_rtc_time = NULL; |
222 | ppc_md.calibrate_decr = mpc85xx_calibrate_decr; | 223 | ppc_md.calibrate_decr = mpc85xx_calibrate_decr; |
223 | 224 | ||
224 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 225 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
225 | ppc_md.progress = gen550_progress; | 226 | ppc_md.progress = gen550_progress; |
226 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 227 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
227 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | 228 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) |
228 | ppc_md.early_serial_map = sbc8560_early_serial_map; | 229 | ppc_md.early_serial_map = sbc8560_early_serial_map; |
229 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | 230 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ |
230 | 231 | ||
231 | if (ppc_md.progress) | 232 | if (ppc_md.progress) |
232 | ppc_md.progress("sbc8560_init(): exit", 0); | 233 | ppc_md.progress("sbc8560_init(): exit", 0); |
233 | } | 234 | } |
234 | 235 |
arch/ppc/platforms/chestnut.c
1 | /* | 1 | /* |
2 | * Board setup routines for IBM Chestnut | 2 | * Board setup routines for IBM Chestnut |
3 | * | 3 | * |
4 | * Author: <source@mvista.com> | 4 | * Author: <source@mvista.com> |
5 | * | 5 | * |
6 | * <2004> (c) MontaVista Software, Inc. This file is licensed under | 6 | * <2004> (c) MontaVista Software, Inc. This file is licensed under |
7 | * the terms of the GNU General Public License version 2. This program | 7 | * the terms of the GNU General Public License version 2. This program |
8 | * is licensed "as is" without any warranty of any kind, whether express | 8 | * is licensed "as is" without any warranty of any kind, whether express |
9 | * or implied. | 9 | * or implied. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/stddef.h> | 12 | #include <linux/stddef.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/reboot.h> | 16 | #include <linux/reboot.h> |
17 | #include <linux/kdev_t.h> | 17 | #include <linux/kdev_t.h> |
18 | #include <linux/major.h> | 18 | #include <linux/major.h> |
19 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
20 | #include <linux/console.h> | 20 | #include <linux/console.h> |
21 | #include <linux/root_dev.h> | 21 | #include <linux/root_dev.h> |
22 | #include <linux/initrd.h> | 22 | #include <linux/initrd.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/ide.h> | 25 | #include <linux/ide.h> |
26 | #include <linux/serial.h> | 26 | #include <linux/serial.h> |
27 | #include <linux/serial_core.h> | 27 | #include <linux/serial_core.h> |
28 | #include <linux/serial_8250.h> | ||
28 | #include <linux/mtd/physmap.h> | 29 | #include <linux/mtd/physmap.h> |
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
30 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
31 | #include <asm/page.h> | 32 | #include <asm/page.h> |
32 | #include <asm/time.h> | 33 | #include <asm/time.h> |
33 | #include <asm/dma.h> | 34 | #include <asm/dma.h> |
34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
35 | #include <asm/hw_irq.h> | 36 | #include <asm/hw_irq.h> |
36 | #include <asm/machdep.h> | 37 | #include <asm/machdep.h> |
37 | #include <asm/kgdb.h> | 38 | #include <asm/kgdb.h> |
38 | #include <asm/bootinfo.h> | 39 | #include <asm/bootinfo.h> |
39 | #include <asm/mv64x60.h> | 40 | #include <asm/mv64x60.h> |
40 | #include <platforms/chestnut.h> | 41 | #include <platforms/chestnut.h> |
41 | 42 | ||
42 | static void __iomem *sram_base; /* Virtual addr of Internal SRAM */ | 43 | static void __iomem *sram_base; /* Virtual addr of Internal SRAM */ |
43 | static void __iomem *cpld_base; /* Virtual addr of CPLD Regs */ | 44 | static void __iomem *cpld_base; /* Virtual addr of CPLD Regs */ |
44 | 45 | ||
45 | static mv64x60_handle_t bh; | 46 | static mv64x60_handle_t bh; |
46 | 47 | ||
47 | extern void gen550_progress(char *, unsigned short); | 48 | extern void gen550_progress(char *, unsigned short); |
48 | extern void gen550_init(int, struct uart_port *); | 49 | extern void gen550_init(int, struct uart_port *); |
49 | extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh); | 50 | extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh); |
50 | 51 | ||
51 | #define BIT(x) (1<<x) | 52 | #define BIT(x) (1<<x) |
52 | #define CHESTNUT_PRESERVE_MASK (BIT(MV64x60_CPU2DEV_0_WIN) | \ | 53 | #define CHESTNUT_PRESERVE_MASK (BIT(MV64x60_CPU2DEV_0_WIN) | \ |
53 | BIT(MV64x60_CPU2DEV_1_WIN) | \ | 54 | BIT(MV64x60_CPU2DEV_1_WIN) | \ |
54 | BIT(MV64x60_CPU2DEV_2_WIN) | \ | 55 | BIT(MV64x60_CPU2DEV_2_WIN) | \ |
55 | BIT(MV64x60_CPU2DEV_3_WIN) | \ | 56 | BIT(MV64x60_CPU2DEV_3_WIN) | \ |
56 | BIT(MV64x60_CPU2BOOT_WIN)) | 57 | BIT(MV64x60_CPU2BOOT_WIN)) |
57 | /************************************************************************** | 58 | /************************************************************************** |
58 | * FUNCTION: chestnut_calibrate_decr | 59 | * FUNCTION: chestnut_calibrate_decr |
59 | * | 60 | * |
60 | * DESCRIPTION: initialize decrementer interrupt frequency (used as system | 61 | * DESCRIPTION: initialize decrementer interrupt frequency (used as system |
61 | * timer) | 62 | * timer) |
62 | * | 63 | * |
63 | ****/ | 64 | ****/ |
64 | static void __init | 65 | static void __init |
65 | chestnut_calibrate_decr(void) | 66 | chestnut_calibrate_decr(void) |
66 | { | 67 | { |
67 | ulong freq; | 68 | ulong freq; |
68 | 69 | ||
69 | freq = CHESTNUT_BUS_SPEED / 4; | 70 | freq = CHESTNUT_BUS_SPEED / 4; |
70 | 71 | ||
71 | printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", | 72 | printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", |
72 | freq/1000000, freq%1000000); | 73 | freq/1000000, freq%1000000); |
73 | 74 | ||
74 | tb_ticks_per_jiffy = freq / HZ; | 75 | tb_ticks_per_jiffy = freq / HZ; |
75 | tb_to_us = mulhwu_scale_factor(freq, 1000000); | 76 | tb_to_us = mulhwu_scale_factor(freq, 1000000); |
76 | } | 77 | } |
77 | 78 | ||
78 | static int | 79 | static int |
79 | chestnut_show_cpuinfo(struct seq_file *m) | 80 | chestnut_show_cpuinfo(struct seq_file *m) |
80 | { | 81 | { |
81 | seq_printf(m, "vendor\t\t: IBM\n"); | 82 | seq_printf(m, "vendor\t\t: IBM\n"); |
82 | seq_printf(m, "machine\t\t: 750FX/GX Eval Board (Chestnut/Buckeye)\n"); | 83 | seq_printf(m, "machine\t\t: 750FX/GX Eval Board (Chestnut/Buckeye)\n"); |
83 | 84 | ||
84 | return 0; | 85 | return 0; |
85 | } | 86 | } |
86 | 87 | ||
87 | /************************************************************************** | 88 | /************************************************************************** |
88 | * FUNCTION: chestnut_find_end_of_memory | 89 | * FUNCTION: chestnut_find_end_of_memory |
89 | * | 90 | * |
90 | * DESCRIPTION: ppc_md memory size callback | 91 | * DESCRIPTION: ppc_md memory size callback |
91 | * | 92 | * |
92 | ****/ | 93 | ****/ |
93 | unsigned long __init | 94 | unsigned long __init |
94 | chestnut_find_end_of_memory(void) | 95 | chestnut_find_end_of_memory(void) |
95 | { | 96 | { |
96 | static int mem_size = 0; | 97 | static int mem_size = 0; |
97 | 98 | ||
98 | if (mem_size == 0) { | 99 | if (mem_size == 0) { |
99 | mem_size = mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE, | 100 | mem_size = mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE, |
100 | MV64x60_TYPE_MV64460); | 101 | MV64x60_TYPE_MV64460); |
101 | } | 102 | } |
102 | return mem_size; | 103 | return mem_size; |
103 | } | 104 | } |
104 | 105 | ||
105 | #if defined(CONFIG_SERIAL_8250) | 106 | #if defined(CONFIG_SERIAL_8250) |
106 | static void __init | 107 | static void __init |
107 | chestnut_early_serial_map(void) | 108 | chestnut_early_serial_map(void) |
108 | { | 109 | { |
109 | struct uart_port port; | 110 | struct uart_port port; |
110 | 111 | ||
111 | /* Setup serial port access */ | 112 | /* Setup serial port access */ |
112 | memset(&port, 0, sizeof(port)); | 113 | memset(&port, 0, sizeof(port)); |
113 | port.uartclk = BASE_BAUD * 16; | 114 | port.uartclk = BASE_BAUD * 16; |
114 | port.irq = UART0_INT; | 115 | port.irq = UART0_INT; |
115 | port.flags = STD_COM_FLAGS | UPF_IOREMAP; | 116 | port.flags = STD_COM_FLAGS | UPF_IOREMAP; |
116 | port.iotype = UPIO_MEM; | 117 | port.iotype = UPIO_MEM; |
117 | port.mapbase = CHESTNUT_UART0_IO_BASE; | 118 | port.mapbase = CHESTNUT_UART0_IO_BASE; |
118 | port.regshift = 0; | 119 | port.regshift = 0; |
119 | 120 | ||
120 | if (early_serial_setup(&port) != 0) | 121 | if (early_serial_setup(&port) != 0) |
121 | printk("Early serial init of port 0 failed\n"); | 122 | printk("Early serial init of port 0 failed\n"); |
122 | 123 | ||
123 | /* Assume early_serial_setup() doesn't modify serial_req */ | 124 | /* Assume early_serial_setup() doesn't modify serial_req */ |
124 | port.line = 1; | 125 | port.line = 1; |
125 | port.irq = UART1_INT; | 126 | port.irq = UART1_INT; |
126 | port.mapbase = CHESTNUT_UART1_IO_BASE; | 127 | port.mapbase = CHESTNUT_UART1_IO_BASE; |
127 | 128 | ||
128 | if (early_serial_setup(&port) != 0) | 129 | if (early_serial_setup(&port) != 0) |
129 | printk("Early serial init of port 1 failed\n"); | 130 | printk("Early serial init of port 1 failed\n"); |
130 | } | 131 | } |
131 | #endif | 132 | #endif |
132 | 133 | ||
133 | /************************************************************************** | 134 | /************************************************************************** |
134 | * FUNCTION: chestnut_map_irq | 135 | * FUNCTION: chestnut_map_irq |
135 | * | 136 | * |
136 | * DESCRIPTION: 0 return since PCI IRQs not needed | 137 | * DESCRIPTION: 0 return since PCI IRQs not needed |
137 | * | 138 | * |
138 | ****/ | 139 | ****/ |
139 | static int __init | 140 | static int __init |
140 | chestnut_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 141 | chestnut_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
141 | { | 142 | { |
142 | static char pci_irq_table[][4] = { | 143 | static char pci_irq_table[][4] = { |
143 | {CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ, | 144 | {CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ, |
144 | CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ}, | 145 | CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ}, |
145 | {CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ, | 146 | {CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ, |
146 | CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ}, | 147 | CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ}, |
147 | {CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ, | 148 | {CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ, |
148 | CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ}, | 149 | CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ}, |
149 | {CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ, | 150 | {CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ, |
150 | CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ}, | 151 | CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ}, |
151 | }; | 152 | }; |
152 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 153 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
153 | 154 | ||
154 | return PCI_IRQ_TABLE_LOOKUP; | 155 | return PCI_IRQ_TABLE_LOOKUP; |
155 | } | 156 | } |
156 | 157 | ||
157 | 158 | ||
158 | /************************************************************************** | 159 | /************************************************************************** |
159 | * FUNCTION: chestnut_setup_bridge | 160 | * FUNCTION: chestnut_setup_bridge |
160 | * | 161 | * |
161 | * DESCRIPTION: initalize board-specific settings on the MV64360 | 162 | * DESCRIPTION: initalize board-specific settings on the MV64360 |
162 | * | 163 | * |
163 | ****/ | 164 | ****/ |
164 | static void __init | 165 | static void __init |
165 | chestnut_setup_bridge(void) | 166 | chestnut_setup_bridge(void) |
166 | { | 167 | { |
167 | struct mv64x60_setup_info si; | 168 | struct mv64x60_setup_info si; |
168 | int i; | 169 | int i; |
169 | 170 | ||
170 | if ( ppc_md.progress ) | 171 | if ( ppc_md.progress ) |
171 | ppc_md.progress("chestnut_setup_bridge: enter", 0); | 172 | ppc_md.progress("chestnut_setup_bridge: enter", 0); |
172 | 173 | ||
173 | memset(&si, 0, sizeof(si)); | 174 | memset(&si, 0, sizeof(si)); |
174 | 175 | ||
175 | si.phys_reg_base = CONFIG_MV64X60_NEW_BASE; | 176 | si.phys_reg_base = CONFIG_MV64X60_NEW_BASE; |
176 | 177 | ||
177 | /* setup only PCI bus 0 (bus 1 not used) */ | 178 | /* setup only PCI bus 0 (bus 1 not used) */ |
178 | si.pci_0.enable_bus = 1; | 179 | si.pci_0.enable_bus = 1; |
179 | si.pci_0.pci_io.cpu_base = CHESTNUT_PCI0_IO_PROC_ADDR; | 180 | si.pci_0.pci_io.cpu_base = CHESTNUT_PCI0_IO_PROC_ADDR; |
180 | si.pci_0.pci_io.pci_base_hi = 0; | 181 | si.pci_0.pci_io.pci_base_hi = 0; |
181 | si.pci_0.pci_io.pci_base_lo = CHESTNUT_PCI0_IO_PCI_ADDR; | 182 | si.pci_0.pci_io.pci_base_lo = CHESTNUT_PCI0_IO_PCI_ADDR; |
182 | si.pci_0.pci_io.size = CHESTNUT_PCI0_IO_SIZE; | 183 | si.pci_0.pci_io.size = CHESTNUT_PCI0_IO_SIZE; |
183 | si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */ | 184 | si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */ |
184 | si.pci_0.pci_mem[0].cpu_base = CHESTNUT_PCI0_MEM_PROC_ADDR; | 185 | si.pci_0.pci_mem[0].cpu_base = CHESTNUT_PCI0_MEM_PROC_ADDR; |
185 | si.pci_0.pci_mem[0].pci_base_hi = CHESTNUT_PCI0_MEM_PCI_HI_ADDR; | 186 | si.pci_0.pci_mem[0].pci_base_hi = CHESTNUT_PCI0_MEM_PCI_HI_ADDR; |
186 | si.pci_0.pci_mem[0].pci_base_lo = CHESTNUT_PCI0_MEM_PCI_LO_ADDR; | 187 | si.pci_0.pci_mem[0].pci_base_lo = CHESTNUT_PCI0_MEM_PCI_LO_ADDR; |
187 | si.pci_0.pci_mem[0].size = CHESTNUT_PCI0_MEM_SIZE; | 188 | si.pci_0.pci_mem[0].size = CHESTNUT_PCI0_MEM_SIZE; |
188 | si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */ | 189 | si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */ |
189 | si.pci_0.pci_cmd_bits = 0; | 190 | si.pci_0.pci_cmd_bits = 0; |
190 | si.pci_0.latency_timer = 0x80; | 191 | si.pci_0.latency_timer = 0x80; |
191 | 192 | ||
192 | for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) { | 193 | for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) { |
193 | #if defined(CONFIG_NOT_COHERENT_CACHE) | 194 | #if defined(CONFIG_NOT_COHERENT_CACHE) |
194 | si.cpu_prot_options[i] = 0; | 195 | si.cpu_prot_options[i] = 0; |
195 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; | 196 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; |
196 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; | 197 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; |
197 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; | 198 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; |
198 | 199 | ||
199 | si.pci_1.acc_cntl_options[i] = | 200 | si.pci_1.acc_cntl_options[i] = |
200 | MV64360_PCI_ACC_CNTL_SNOOP_NONE | | 201 | MV64360_PCI_ACC_CNTL_SNOOP_NONE | |
201 | MV64360_PCI_ACC_CNTL_SWAP_NONE | | 202 | MV64360_PCI_ACC_CNTL_SWAP_NONE | |
202 | MV64360_PCI_ACC_CNTL_MBURST_128_BYTES | | 203 | MV64360_PCI_ACC_CNTL_MBURST_128_BYTES | |
203 | MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES; | 204 | MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES; |
204 | #else | 205 | #else |
205 | si.cpu_prot_options[i] = 0; | 206 | si.cpu_prot_options[i] = 0; |
206 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; /* errata */ | 207 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; /* errata */ |
207 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; /* errata */ | 208 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; /* errata */ |
208 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; /* errata */ | 209 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; /* errata */ |
209 | 210 | ||
210 | si.pci_1.acc_cntl_options[i] = | 211 | si.pci_1.acc_cntl_options[i] = |
211 | MV64360_PCI_ACC_CNTL_SNOOP_WB | | 212 | MV64360_PCI_ACC_CNTL_SNOOP_WB | |
212 | MV64360_PCI_ACC_CNTL_SWAP_NONE | | 213 | MV64360_PCI_ACC_CNTL_SWAP_NONE | |
213 | MV64360_PCI_ACC_CNTL_MBURST_32_BYTES | | 214 | MV64360_PCI_ACC_CNTL_MBURST_32_BYTES | |
214 | MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES; | 215 | MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES; |
215 | #endif | 216 | #endif |
216 | } | 217 | } |
217 | 218 | ||
218 | /* Lookup host bridge - on CPU 0 - no SMP support */ | 219 | /* Lookup host bridge - on CPU 0 - no SMP support */ |
219 | if (mv64x60_init(&bh, &si)) { | 220 | if (mv64x60_init(&bh, &si)) { |
220 | printk("\n\nPCI Bridge initialization failed!\n"); | 221 | printk("\n\nPCI Bridge initialization failed!\n"); |
221 | } | 222 | } |
222 | 223 | ||
223 | pci_dram_offset = 0; | 224 | pci_dram_offset = 0; |
224 | ppc_md.pci_swizzle = common_swizzle; | 225 | ppc_md.pci_swizzle = common_swizzle; |
225 | ppc_md.pci_map_irq = chestnut_map_irq; | 226 | ppc_md.pci_map_irq = chestnut_map_irq; |
226 | ppc_md.pci_exclude_device = mv64x60_pci_exclude_device; | 227 | ppc_md.pci_exclude_device = mv64x60_pci_exclude_device; |
227 | 228 | ||
228 | mv64x60_set_bus(&bh, 0, 0); | 229 | mv64x60_set_bus(&bh, 0, 0); |
229 | bh.hose_a->first_busno = 0; | 230 | bh.hose_a->first_busno = 0; |
230 | bh.hose_a->last_busno = 0xff; | 231 | bh.hose_a->last_busno = 0xff; |
231 | bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0); | 232 | bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0); |
232 | } | 233 | } |
233 | 234 | ||
234 | void __init | 235 | void __init |
235 | chestnut_setup_peripherals(void) | 236 | chestnut_setup_peripherals(void) |
236 | { | 237 | { |
237 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, | 238 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, |
238 | CHESTNUT_BOOT_8BIT_BASE, CHESTNUT_BOOT_8BIT_SIZE, 0); | 239 | CHESTNUT_BOOT_8BIT_BASE, CHESTNUT_BOOT_8BIT_SIZE, 0); |
239 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); | 240 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); |
240 | 241 | ||
241 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, | 242 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, |
242 | CHESTNUT_32BIT_BASE, CHESTNUT_32BIT_SIZE, 0); | 243 | CHESTNUT_32BIT_BASE, CHESTNUT_32BIT_SIZE, 0); |
243 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN); | 244 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN); |
244 | 245 | ||
245 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, | 246 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, |
246 | CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE, 0); | 247 | CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE, 0); |
247 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); | 248 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); |
248 | cpld_base = ioremap(CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE); | 249 | cpld_base = ioremap(CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE); |
249 | 250 | ||
250 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, | 251 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, |
251 | CHESTNUT_UART_BASE, CHESTNUT_UART_SIZE, 0); | 252 | CHESTNUT_UART_BASE, CHESTNUT_UART_SIZE, 0); |
252 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); | 253 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); |
253 | 254 | ||
254 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, | 255 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, |
255 | CHESTNUT_FRAM_BASE, CHESTNUT_FRAM_SIZE, 0); | 256 | CHESTNUT_FRAM_BASE, CHESTNUT_FRAM_SIZE, 0); |
256 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); | 257 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); |
257 | 258 | ||
258 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN, | 259 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN, |
259 | CHESTNUT_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0); | 260 | CHESTNUT_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0); |
260 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN); | 261 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN); |
261 | 262 | ||
262 | #ifdef CONFIG_NOT_COHERENT_CACHE | 263 | #ifdef CONFIG_NOT_COHERENT_CACHE |
263 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b0); | 264 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b0); |
264 | #else | 265 | #else |
265 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2); | 266 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2); |
266 | #endif | 267 | #endif |
267 | sram_base = ioremap(CHESTNUT_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE); | 268 | sram_base = ioremap(CHESTNUT_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE); |
268 | memset(sram_base, 0, MV64360_SRAM_SIZE); | 269 | memset(sram_base, 0, MV64360_SRAM_SIZE); |
269 | 270 | ||
270 | /* | 271 | /* |
271 | * Configure MPP pins for PCI DMA | 272 | * Configure MPP pins for PCI DMA |
272 | * | 273 | * |
273 | * PCI Slot GNT pin REQ pin | 274 | * PCI Slot GNT pin REQ pin |
274 | * 0 MPP16 MPP17 | 275 | * 0 MPP16 MPP17 |
275 | * 1 MPP18 MPP19 | 276 | * 1 MPP18 MPP19 |
276 | * 2 MPP20 MPP21 | 277 | * 2 MPP20 MPP21 |
277 | * 3 MPP22 MPP23 | 278 | * 3 MPP22 MPP23 |
278 | */ | 279 | */ |
279 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, | 280 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, |
280 | (0x1 << 0) | /* MPPSel16 PCI0_GNT[0] */ | 281 | (0x1 << 0) | /* MPPSel16 PCI0_GNT[0] */ |
281 | (0x1 << 4) | /* MPPSel17 PCI0_REQ[0] */ | 282 | (0x1 << 4) | /* MPPSel17 PCI0_REQ[0] */ |
282 | (0x1 << 8) | /* MPPSel18 PCI0_GNT[1] */ | 283 | (0x1 << 8) | /* MPPSel18 PCI0_GNT[1] */ |
283 | (0x1 << 12) | /* MPPSel19 PCI0_REQ[1] */ | 284 | (0x1 << 12) | /* MPPSel19 PCI0_REQ[1] */ |
284 | (0x1 << 16) | /* MPPSel20 PCI0_GNT[2] */ | 285 | (0x1 << 16) | /* MPPSel20 PCI0_GNT[2] */ |
285 | (0x1 << 20) | /* MPPSel21 PCI0_REQ[2] */ | 286 | (0x1 << 20) | /* MPPSel21 PCI0_REQ[2] */ |
286 | (0x1 << 24) | /* MPPSel22 PCI0_GNT[3] */ | 287 | (0x1 << 24) | /* MPPSel22 PCI0_GNT[3] */ |
287 | (0x1 << 28)); /* MPPSel23 PCI0_REQ[3] */ | 288 | (0x1 << 28)); /* MPPSel23 PCI0_REQ[3] */ |
288 | /* | 289 | /* |
289 | * Set unused MPP pins for output, as per schematic note | 290 | * Set unused MPP pins for output, as per schematic note |
290 | * | 291 | * |
291 | * Unused Pins: MPP01, MPP02, MPP04, MPP05, MPP06 | 292 | * Unused Pins: MPP01, MPP02, MPP04, MPP05, MPP06 |
292 | * MPP09, MPP10, MPP13, MPP14, MPP15 | 293 | * MPP09, MPP10, MPP13, MPP14, MPP15 |
293 | */ | 294 | */ |
294 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_0, | 295 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_0, |
295 | (0xf << 4) | /* MPPSel01 GPIO[1] */ | 296 | (0xf << 4) | /* MPPSel01 GPIO[1] */ |
296 | (0xf << 8) | /* MPPSel02 GPIO[2] */ | 297 | (0xf << 8) | /* MPPSel02 GPIO[2] */ |
297 | (0xf << 16) | /* MPPSel04 GPIO[4] */ | 298 | (0xf << 16) | /* MPPSel04 GPIO[4] */ |
298 | (0xf << 20) | /* MPPSel05 GPIO[5] */ | 299 | (0xf << 20) | /* MPPSel05 GPIO[5] */ |
299 | (0xf << 24)); /* MPPSel06 GPIO[6] */ | 300 | (0xf << 24)); /* MPPSel06 GPIO[6] */ |
300 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, | 301 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, |
301 | (0xf << 4) | /* MPPSel09 GPIO[9] */ | 302 | (0xf << 4) | /* MPPSel09 GPIO[9] */ |
302 | (0xf << 8) | /* MPPSel10 GPIO[10] */ | 303 | (0xf << 8) | /* MPPSel10 GPIO[10] */ |
303 | (0xf << 20) | /* MPPSel13 GPIO[13] */ | 304 | (0xf << 20) | /* MPPSel13 GPIO[13] */ |
304 | (0xf << 24) | /* MPPSel14 GPIO[14] */ | 305 | (0xf << 24) | /* MPPSel14 GPIO[14] */ |
305 | (0xf << 28)); /* MPPSel15 GPIO[15] */ | 306 | (0xf << 28)); /* MPPSel15 GPIO[15] */ |
306 | mv64x60_set_bits(&bh, MV64x60_GPP_IO_CNTL, /* Output */ | 307 | mv64x60_set_bits(&bh, MV64x60_GPP_IO_CNTL, /* Output */ |
307 | BIT(1) | BIT(2) | BIT(4) | BIT(5) | BIT(6) | | 308 | BIT(1) | BIT(2) | BIT(4) | BIT(5) | BIT(6) | |
308 | BIT(9) | BIT(10) | BIT(13) | BIT(14) | BIT(15)); | 309 | BIT(9) | BIT(10) | BIT(13) | BIT(14) | BIT(15)); |
309 | 310 | ||
310 | /* | 311 | /* |
311 | * Configure the following MPP pins to indicate a level | 312 | * Configure the following MPP pins to indicate a level |
312 | * triggered interrupt | 313 | * triggered interrupt |
313 | * | 314 | * |
314 | * MPP24 - Board Reset (just map the MPP & GPP for chestnut_reset) | 315 | * MPP24 - Board Reset (just map the MPP & GPP for chestnut_reset) |
315 | * MPP25 - UART A (high) | 316 | * MPP25 - UART A (high) |
316 | * MPP26 - UART B (high) | 317 | * MPP26 - UART B (high) |
317 | * MPP28 - PCI Slot 3 (low) | 318 | * MPP28 - PCI Slot 3 (low) |
318 | * MPP29 - PCI Slot 2 (low) | 319 | * MPP29 - PCI Slot 2 (low) |
319 | * MPP30 - PCI Slot 1 (low) | 320 | * MPP30 - PCI Slot 1 (low) |
320 | * MPP31 - PCI Slot 0 (low) | 321 | * MPP31 - PCI Slot 0 (low) |
321 | */ | 322 | */ |
322 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3, | 323 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3, |
323 | BIT(3) | BIT(2) | BIT(1) | BIT(0) | /* MPP 24 */ | 324 | BIT(3) | BIT(2) | BIT(1) | BIT(0) | /* MPP 24 */ |
324 | BIT(7) | BIT(6) | BIT(5) | BIT(4) | /* MPP 25 */ | 325 | BIT(7) | BIT(6) | BIT(5) | BIT(4) | /* MPP 25 */ |
325 | BIT(11) | BIT(10) | BIT(9) | BIT(8) | /* MPP 26 */ | 326 | BIT(11) | BIT(10) | BIT(9) | BIT(8) | /* MPP 26 */ |
326 | BIT(19) | BIT(18) | BIT(17) | BIT(16) | /* MPP 28 */ | 327 | BIT(19) | BIT(18) | BIT(17) | BIT(16) | /* MPP 28 */ |
327 | BIT(23) | BIT(22) | BIT(21) | BIT(20) | /* MPP 29 */ | 328 | BIT(23) | BIT(22) | BIT(21) | BIT(20) | /* MPP 29 */ |
328 | BIT(27) | BIT(26) | BIT(25) | BIT(24) | /* MPP 30 */ | 329 | BIT(27) | BIT(26) | BIT(25) | BIT(24) | /* MPP 30 */ |
329 | BIT(31) | BIT(30) | BIT(29) | BIT(28)); /* MPP 31 */ | 330 | BIT(31) | BIT(30) | BIT(29) | BIT(28)); /* MPP 31 */ |
330 | 331 | ||
331 | /* | 332 | /* |
332 | * Define GPP 25 (high), 26 (high), 28 (low), 29 (low), 30 (low), | 333 | * Define GPP 25 (high), 26 (high), 28 (low), 29 (low), 30 (low), |
333 | * 31 (low) interrupt polarity input signal and level triggered | 334 | * 31 (low) interrupt polarity input signal and level triggered |
334 | */ | 335 | */ |
335 | mv64x60_clr_bits(&bh, MV64x60_GPP_LEVEL_CNTL, BIT(25) | BIT(26)); | 336 | mv64x60_clr_bits(&bh, MV64x60_GPP_LEVEL_CNTL, BIT(25) | BIT(26)); |
336 | mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, | 337 | mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, |
337 | BIT(28) | BIT(29) | BIT(30) | BIT(31)); | 338 | BIT(28) | BIT(29) | BIT(30) | BIT(31)); |
338 | mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, | 339 | mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, |
339 | BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) | | 340 | BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) | |
340 | BIT(31)); | 341 | BIT(31)); |
341 | 342 | ||
342 | /* Config GPP interrupt controller to respond to level trigger */ | 343 | /* Config GPP interrupt controller to respond to level trigger */ |
343 | mv64x60_set_bits(&bh, MV64360_COMM_ARBITER_CNTL, BIT(10)); | 344 | mv64x60_set_bits(&bh, MV64360_COMM_ARBITER_CNTL, BIT(10)); |
344 | 345 | ||
345 | /* | 346 | /* |
346 | * Dismiss and then enable interrupt on GPP interrupt cause for CPU #0 | 347 | * Dismiss and then enable interrupt on GPP interrupt cause for CPU #0 |
347 | */ | 348 | */ |
348 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, | 349 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, |
349 | ~(BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) | | 350 | ~(BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) | |
350 | BIT(31))); | 351 | BIT(31))); |
351 | mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, | 352 | mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, |
352 | BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) | | 353 | BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) | |
353 | BIT(31)); | 354 | BIT(31)); |
354 | 355 | ||
355 | /* | 356 | /* |
356 | * Dismiss and then enable interrupt on CPU #0 high cause register | 357 | * Dismiss and then enable interrupt on CPU #0 high cause register |
357 | * BIT27 summarizes GPP interrupts 24-31 | 358 | * BIT27 summarizes GPP interrupts 24-31 |
358 | */ | 359 | */ |
359 | mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, BIT(27)); | 360 | mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, BIT(27)); |
360 | 361 | ||
361 | if (ppc_md.progress) | 362 | if (ppc_md.progress) |
362 | ppc_md.progress("chestnut_setup_bridge: exit", 0); | 363 | ppc_md.progress("chestnut_setup_bridge: exit", 0); |
363 | } | 364 | } |
364 | 365 | ||
365 | /************************************************************************** | 366 | /************************************************************************** |
366 | * FUNCTION: chestnut_setup_arch | 367 | * FUNCTION: chestnut_setup_arch |
367 | * | 368 | * |
368 | * DESCRIPTION: ppc_md machine configuration callback | 369 | * DESCRIPTION: ppc_md machine configuration callback |
369 | * | 370 | * |
370 | ****/ | 371 | ****/ |
371 | static void __init | 372 | static void __init |
372 | chestnut_setup_arch(void) | 373 | chestnut_setup_arch(void) |
373 | { | 374 | { |
374 | if (ppc_md.progress) | 375 | if (ppc_md.progress) |
375 | ppc_md.progress("chestnut_setup_arch: enter", 0); | 376 | ppc_md.progress("chestnut_setup_arch: enter", 0); |
376 | 377 | ||
377 | /* init to some ~sane value until calibrate_delay() runs */ | 378 | /* init to some ~sane value until calibrate_delay() runs */ |
378 | loops_per_jiffy = 50000000 / HZ; | 379 | loops_per_jiffy = 50000000 / HZ; |
379 | 380 | ||
380 | /* if the time base value is greater than bus freq/4 (the TB and | 381 | /* if the time base value is greater than bus freq/4 (the TB and |
381 | * decrementer tick rate) + signed integer rollover value, we | 382 | * decrementer tick rate) + signed integer rollover value, we |
382 | * can spend a fair amount of time waiting for the rollover to | 383 | * can spend a fair amount of time waiting for the rollover to |
383 | * happen. To get around this, initialize the time base register | 384 | * happen. To get around this, initialize the time base register |
384 | * to a "safe" value. | 385 | * to a "safe" value. |
385 | */ | 386 | */ |
386 | set_tb(0, 0); | 387 | set_tb(0, 0); |
387 | 388 | ||
388 | #ifdef CONFIG_BLK_DEV_INITRD | 389 | #ifdef CONFIG_BLK_DEV_INITRD |
389 | if (initrd_start) | 390 | if (initrd_start) |
390 | ROOT_DEV = Root_RAM0; | 391 | ROOT_DEV = Root_RAM0; |
391 | else | 392 | else |
392 | #endif | 393 | #endif |
393 | #ifdef CONFIG_ROOT_NFS | 394 | #ifdef CONFIG_ROOT_NFS |
394 | ROOT_DEV = Root_NFS; | 395 | ROOT_DEV = Root_NFS; |
395 | #else | 396 | #else |
396 | ROOT_DEV = Root_SDA2; | 397 | ROOT_DEV = Root_SDA2; |
397 | #endif | 398 | #endif |
398 | 399 | ||
399 | /* | 400 | /* |
400 | * Set up the L2CR register. | 401 | * Set up the L2CR register. |
401 | */ | 402 | */ |
402 | _set_L2CR(_get_L2CR() | L2CR_L2E); | 403 | _set_L2CR(_get_L2CR() | L2CR_L2E); |
403 | 404 | ||
404 | chestnut_setup_bridge(); | 405 | chestnut_setup_bridge(); |
405 | chestnut_setup_peripherals(); | 406 | chestnut_setup_peripherals(); |
406 | 407 | ||
407 | #ifdef CONFIG_DUMMY_CONSOLE | 408 | #ifdef CONFIG_DUMMY_CONSOLE |
408 | conswitchp = &dummy_con; | 409 | conswitchp = &dummy_con; |
409 | #endif | 410 | #endif |
410 | 411 | ||
411 | #if defined(CONFIG_SERIAL_8250) | 412 | #if defined(CONFIG_SERIAL_8250) |
412 | chestnut_early_serial_map(); | 413 | chestnut_early_serial_map(); |
413 | #endif | 414 | #endif |
414 | 415 | ||
415 | /* Identify the system */ | 416 | /* Identify the system */ |
416 | printk(KERN_INFO "System Identification: IBM 750FX/GX Eval Board\n"); | 417 | printk(KERN_INFO "System Identification: IBM 750FX/GX Eval Board\n"); |
417 | printk(KERN_INFO "IBM 750FX/GX port (C) 2004 MontaVista Software, Inc." | 418 | printk(KERN_INFO "IBM 750FX/GX port (C) 2004 MontaVista Software, Inc." |
418 | " (source@mvista.com)\n"); | 419 | " (source@mvista.com)\n"); |
419 | 420 | ||
420 | if (ppc_md.progress) | 421 | if (ppc_md.progress) |
421 | ppc_md.progress("chestnut_setup_arch: exit", 0); | 422 | ppc_md.progress("chestnut_setup_arch: exit", 0); |
422 | } | 423 | } |
423 | 424 | ||
424 | #ifdef CONFIG_MTD_PHYSMAP | 425 | #ifdef CONFIG_MTD_PHYSMAP |
425 | static struct mtd_partition ptbl; | 426 | static struct mtd_partition ptbl; |
426 | 427 | ||
427 | static int __init | 428 | static int __init |
428 | chestnut_setup_mtd(void) | 429 | chestnut_setup_mtd(void) |
429 | { | 430 | { |
430 | memset(&ptbl, 0, sizeof(ptbl)); | 431 | memset(&ptbl, 0, sizeof(ptbl)); |
431 | 432 | ||
432 | ptbl.name = "User FS"; | 433 | ptbl.name = "User FS"; |
433 | ptbl.size = CHESTNUT_32BIT_SIZE; | 434 | ptbl.size = CHESTNUT_32BIT_SIZE; |
434 | 435 | ||
435 | physmap_map.size = CHESTNUT_32BIT_SIZE; | 436 | physmap_map.size = CHESTNUT_32BIT_SIZE; |
436 | physmap_set_partitions(&ptbl, 1); | 437 | physmap_set_partitions(&ptbl, 1); |
437 | return 0; | 438 | return 0; |
438 | } | 439 | } |
439 | 440 | ||
440 | arch_initcall(chestnut_setup_mtd); | 441 | arch_initcall(chestnut_setup_mtd); |
441 | #endif | 442 | #endif |
442 | 443 | ||
443 | /************************************************************************** | 444 | /************************************************************************** |
444 | * FUNCTION: chestnut_restart | 445 | * FUNCTION: chestnut_restart |
445 | * | 446 | * |
446 | * DESCRIPTION: ppc_md machine reset callback | 447 | * DESCRIPTION: ppc_md machine reset callback |
447 | * reset the board via the CPLD command register | 448 | * reset the board via the CPLD command register |
448 | * | 449 | * |
449 | ****/ | 450 | ****/ |
450 | static void | 451 | static void |
451 | chestnut_restart(char *cmd) | 452 | chestnut_restart(char *cmd) |
452 | { | 453 | { |
453 | volatile ulong i = 10000000; | 454 | volatile ulong i = 10000000; |
454 | 455 | ||
455 | local_irq_disable(); | 456 | local_irq_disable(); |
456 | 457 | ||
457 | /* | 458 | /* |
458 | * Set CPLD Reg 3 bit 0 to 1 to allow MPP signals on reset to work | 459 | * Set CPLD Reg 3 bit 0 to 1 to allow MPP signals on reset to work |
459 | * | 460 | * |
460 | * MPP24 - board reset | 461 | * MPP24 - board reset |
461 | */ | 462 | */ |
462 | writeb(0x1, cpld_base + 3); | 463 | writeb(0x1, cpld_base + 3); |
463 | 464 | ||
464 | /* GPP pin tied to MPP earlier */ | 465 | /* GPP pin tied to MPP earlier */ |
465 | mv64x60_set_bits(&bh, MV64x60_GPP_VALUE_SET, BIT(24)); | 466 | mv64x60_set_bits(&bh, MV64x60_GPP_VALUE_SET, BIT(24)); |
466 | 467 | ||
467 | while (i-- > 0); | 468 | while (i-- > 0); |
468 | panic("restart failed\n"); | 469 | panic("restart failed\n"); |
469 | } | 470 | } |
470 | 471 | ||
471 | static void | 472 | static void |
472 | chestnut_halt(void) | 473 | chestnut_halt(void) |
473 | { | 474 | { |
474 | local_irq_disable(); | 475 | local_irq_disable(); |
475 | for (;;); | 476 | for (;;); |
476 | /* NOTREACHED */ | 477 | /* NOTREACHED */ |
477 | } | 478 | } |
478 | 479 | ||
479 | static void | 480 | static void |
480 | chestnut_power_off(void) | 481 | chestnut_power_off(void) |
481 | { | 482 | { |
482 | chestnut_halt(); | 483 | chestnut_halt(); |
483 | /* NOTREACHED */ | 484 | /* NOTREACHED */ |
484 | } | 485 | } |
485 | 486 | ||
486 | /************************************************************************** | 487 | /************************************************************************** |
487 | * FUNCTION: chestnut_map_io | 488 | * FUNCTION: chestnut_map_io |
488 | * | 489 | * |
489 | * DESCRIPTION: configure fixed memory-mapped IO | 490 | * DESCRIPTION: configure fixed memory-mapped IO |
490 | * | 491 | * |
491 | ****/ | 492 | ****/ |
492 | static void __init | 493 | static void __init |
493 | chestnut_map_io(void) | 494 | chestnut_map_io(void) |
494 | { | 495 | { |
495 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 496 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
496 | io_block_mapping(CHESTNUT_UART_BASE, CHESTNUT_UART_BASE, 0x100000, | 497 | io_block_mapping(CHESTNUT_UART_BASE, CHESTNUT_UART_BASE, 0x100000, |
497 | _PAGE_IO); | 498 | _PAGE_IO); |
498 | #endif | 499 | #endif |
499 | } | 500 | } |
500 | 501 | ||
501 | /************************************************************************** | 502 | /************************************************************************** |
502 | * FUNCTION: chestnut_set_bat | 503 | * FUNCTION: chestnut_set_bat |
503 | * | 504 | * |
504 | * DESCRIPTION: configures a (temporary) bat mapping for early access to | 505 | * DESCRIPTION: configures a (temporary) bat mapping for early access to |
505 | * device I/O | 506 | * device I/O |
506 | * | 507 | * |
507 | ****/ | 508 | ****/ |
508 | static __inline__ void | 509 | static __inline__ void |
509 | chestnut_set_bat(void) | 510 | chestnut_set_bat(void) |
510 | { | 511 | { |
511 | mb(); | 512 | mb(); |
512 | mtspr(SPRN_DBAT3U, 0xf0001ffe); | 513 | mtspr(SPRN_DBAT3U, 0xf0001ffe); |
513 | mtspr(SPRN_DBAT3L, 0xf000002a); | 514 | mtspr(SPRN_DBAT3L, 0xf000002a); |
514 | mb(); | 515 | mb(); |
515 | } | 516 | } |
516 | 517 | ||
517 | /************************************************************************** | 518 | /************************************************************************** |
518 | * FUNCTION: platform_init | 519 | * FUNCTION: platform_init |
519 | * | 520 | * |
520 | * DESCRIPTION: main entry point for configuring board-specific machine | 521 | * DESCRIPTION: main entry point for configuring board-specific machine |
521 | * callbacks | 522 | * callbacks |
522 | * | 523 | * |
523 | ****/ | 524 | ****/ |
524 | void __init | 525 | void __init |
525 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 526 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
526 | unsigned long r6, unsigned long r7) | 527 | unsigned long r6, unsigned long r7) |
527 | { | 528 | { |
528 | parse_bootinfo(find_bootinfo()); | 529 | parse_bootinfo(find_bootinfo()); |
529 | 530 | ||
530 | /* Copy the kernel command line arguments to a safe place. */ | 531 | /* Copy the kernel command line arguments to a safe place. */ |
531 | 532 | ||
532 | if (r6) { | 533 | if (r6) { |
533 | *(char *) (r7 + KERNELBASE) = 0; | 534 | *(char *) (r7 + KERNELBASE) = 0; |
534 | strcpy(cmd_line, (char *) (r6 + KERNELBASE)); | 535 | strcpy(cmd_line, (char *) (r6 + KERNELBASE)); |
535 | } | 536 | } |
536 | 537 | ||
537 | isa_mem_base = 0; | 538 | isa_mem_base = 0; |
538 | 539 | ||
539 | ppc_md.setup_arch = chestnut_setup_arch; | 540 | ppc_md.setup_arch = chestnut_setup_arch; |
540 | ppc_md.show_cpuinfo = chestnut_show_cpuinfo; | 541 | ppc_md.show_cpuinfo = chestnut_show_cpuinfo; |
541 | ppc_md.init_IRQ = mv64360_init_irq; | 542 | ppc_md.init_IRQ = mv64360_init_irq; |
542 | ppc_md.get_irq = mv64360_get_irq; | 543 | ppc_md.get_irq = mv64360_get_irq; |
543 | ppc_md.init = NULL; | 544 | ppc_md.init = NULL; |
544 | 545 | ||
545 | ppc_md.find_end_of_memory = chestnut_find_end_of_memory; | 546 | ppc_md.find_end_of_memory = chestnut_find_end_of_memory; |
546 | ppc_md.setup_io_mappings = chestnut_map_io; | 547 | ppc_md.setup_io_mappings = chestnut_map_io; |
547 | 548 | ||
548 | ppc_md.restart = chestnut_restart; | 549 | ppc_md.restart = chestnut_restart; |
549 | ppc_md.power_off = chestnut_power_off; | 550 | ppc_md.power_off = chestnut_power_off; |
550 | ppc_md.halt = chestnut_halt; | 551 | ppc_md.halt = chestnut_halt; |
551 | 552 | ||
552 | ppc_md.time_init = NULL; | 553 | ppc_md.time_init = NULL; |
553 | ppc_md.set_rtc_time = NULL; | 554 | ppc_md.set_rtc_time = NULL; |
554 | ppc_md.get_rtc_time = NULL; | 555 | ppc_md.get_rtc_time = NULL; |
555 | ppc_md.calibrate_decr = chestnut_calibrate_decr; | 556 | ppc_md.calibrate_decr = chestnut_calibrate_decr; |
556 | 557 | ||
557 | ppc_md.nvram_read_val = NULL; | 558 | ppc_md.nvram_read_val = NULL; |
558 | ppc_md.nvram_write_val = NULL; | 559 | ppc_md.nvram_write_val = NULL; |
559 | 560 | ||
560 | ppc_md.heartbeat = NULL; | 561 | ppc_md.heartbeat = NULL; |
561 | 562 | ||
562 | bh.p_base = CONFIG_MV64X60_NEW_BASE; | 563 | bh.p_base = CONFIG_MV64X60_NEW_BASE; |
563 | 564 | ||
564 | chestnut_set_bat(); | 565 | chestnut_set_bat(); |
565 | 566 | ||
566 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) | 567 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) |
567 | ppc_md.progress = gen550_progress; | 568 | ppc_md.progress = gen550_progress; |
568 | #endif | 569 | #endif |
569 | #if defined(CONFIG_KGDB) | 570 | #if defined(CONFIG_KGDB) |
570 | ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; | 571 | ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; |
571 | #endif | 572 | #endif |
572 | 573 | ||
573 | if (ppc_md.progress) | 574 | if (ppc_md.progress) |
574 | ppc_md.progress("chestnut_init(): exit", 0); | 575 | ppc_md.progress("chestnut_init(): exit", 0); |
575 | } | 576 | } |
576 | 577 |
arch/ppc/platforms/ev64260.c
1 | /* | 1 | /* |
2 | * Board setup routines for the Marvell/Galileo EV-64260-BP Evaluation Board. | 2 | * Board setup routines for the Marvell/Galileo EV-64260-BP Evaluation Board. |
3 | * | 3 | * |
4 | * Author: Mark A. Greer <mgreer@mvista.com> | 4 | * Author: Mark A. Greer <mgreer@mvista.com> |
5 | * | 5 | * |
6 | * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under | 6 | * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under |
7 | * the terms of the GNU General Public License version 2. This program | 7 | * the terms of the GNU General Public License version 2. This program |
8 | * is licensed "as is" without any warranty of any kind, whether express | 8 | * is licensed "as is" without any warranty of any kind, whether express |
9 | * or implied. | 9 | * or implied. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * The EV-64260-BP port is the result of hard work from many people from | 13 | * The EV-64260-BP port is the result of hard work from many people from |
14 | * many companies. In particular, employees of Marvell/Galileo, Mission | 14 | * many companies. In particular, employees of Marvell/Galileo, Mission |
15 | * Critical Linux, Xyterra, and MontaVista Software were heavily involved. | 15 | * Critical Linux, Xyterra, and MontaVista Software were heavily involved. |
16 | * | 16 | * |
17 | * Note: I have not been able to get *all* PCI slots to work reliably | 17 | * Note: I have not been able to get *all* PCI slots to work reliably |
18 | * at 66 MHz. I recommend setting jumpers J15 & J16 to short pins 1&2 | 18 | * at 66 MHz. I recommend setting jumpers J15 & J16 to short pins 1&2 |
19 | * so that 33 MHz is used. --MAG | 19 | * so that 33 MHz is used. --MAG |
20 | * Note: The 750CXe and 7450 are not stable with a 125MHz or 133MHz TCLK/SYSCLK. | 20 | * Note: The 750CXe and 7450 are not stable with a 125MHz or 133MHz TCLK/SYSCLK. |
21 | * At 100MHz, they are solid. | 21 | * At 100MHz, they are solid. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/ide.h> | 26 | #include <linux/ide.h> |
27 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/console.h> | 30 | #include <linux/console.h> |
31 | #include <linux/initrd.h> | 31 | #include <linux/initrd.h> |
32 | #include <linux/root_dev.h> | 32 | #include <linux/root_dev.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #if !defined(CONFIG_SERIAL_MPSC_CONSOLE) | 34 | #if !defined(CONFIG_SERIAL_MPSC_CONSOLE) |
35 | #include <linux/serial.h> | 35 | #include <linux/serial.h> |
36 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
37 | #include <linux/serial_core.h> | 37 | #include <linux/serial_core.h> |
38 | #include <linux/serial_8250.h> | ||
38 | #else | 39 | #else |
39 | #include <linux/mv643xx.h> | 40 | #include <linux/mv643xx.h> |
40 | #endif | 41 | #endif |
41 | #include <asm/bootinfo.h> | 42 | #include <asm/bootinfo.h> |
42 | #include <asm/machdep.h> | 43 | #include <asm/machdep.h> |
43 | #include <asm/mv64x60.h> | 44 | #include <asm/mv64x60.h> |
44 | #include <asm/todc.h> | 45 | #include <asm/todc.h> |
45 | #include <asm/time.h> | 46 | #include <asm/time.h> |
46 | 47 | ||
47 | #include <platforms/ev64260.h> | 48 | #include <platforms/ev64260.h> |
48 | 49 | ||
49 | #define BOARD_VENDOR "Marvell/Galileo" | 50 | #define BOARD_VENDOR "Marvell/Galileo" |
50 | #define BOARD_MACHINE "EV-64260-BP" | 51 | #define BOARD_MACHINE "EV-64260-BP" |
51 | 52 | ||
52 | static struct mv64x60_handle bh; | 53 | static struct mv64x60_handle bh; |
53 | 54 | ||
54 | #if !defined(CONFIG_SERIAL_MPSC_CONSOLE) | 55 | #if !defined(CONFIG_SERIAL_MPSC_CONSOLE) |
55 | extern void gen550_progress(char *, unsigned short); | 56 | extern void gen550_progress(char *, unsigned short); |
56 | extern void gen550_init(int, struct uart_port *); | 57 | extern void gen550_init(int, struct uart_port *); |
57 | #endif | 58 | #endif |
58 | 59 | ||
59 | static const unsigned int cpu_7xx[16] = { /* 7xx & 74xx (but not 745x) */ | 60 | static const unsigned int cpu_7xx[16] = { /* 7xx & 74xx (but not 745x) */ |
60 | 18, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 | 61 | 18, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 |
61 | }; | 62 | }; |
62 | static const unsigned int cpu_745x[2][16] = { /* PLL_EXT 0 & 1 */ | 63 | static const unsigned int cpu_745x[2][16] = { /* PLL_EXT 0 & 1 */ |
63 | { 1, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 }, | 64 | { 1, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 }, |
64 | { 0, 30, 0, 2, 0, 26, 0, 18, 0, 22, 20, 24, 28, 32, 0, 0 } | 65 | { 0, 30, 0, 2, 0, 26, 0, 18, 0, 22, 20, 24, 28, 32, 0, 0 } |
65 | }; | 66 | }; |
66 | 67 | ||
67 | 68 | ||
68 | TODC_ALLOC(); | 69 | TODC_ALLOC(); |
69 | 70 | ||
70 | static int | 71 | static int |
71 | ev64260_get_bus_speed(void) | 72 | ev64260_get_bus_speed(void) |
72 | { | 73 | { |
73 | return 100000000; | 74 | return 100000000; |
74 | } | 75 | } |
75 | 76 | ||
76 | static int | 77 | static int |
77 | ev64260_get_cpu_speed(void) | 78 | ev64260_get_cpu_speed(void) |
78 | { | 79 | { |
79 | unsigned long pvr, hid1, pll_ext; | 80 | unsigned long pvr, hid1, pll_ext; |
80 | 81 | ||
81 | pvr = PVR_VER(mfspr(SPRN_PVR)); | 82 | pvr = PVR_VER(mfspr(SPRN_PVR)); |
82 | 83 | ||
83 | if (pvr != PVR_VER(PVR_7450)) { | 84 | if (pvr != PVR_VER(PVR_7450)) { |
84 | hid1 = mfspr(SPRN_HID1) >> 28; | 85 | hid1 = mfspr(SPRN_HID1) >> 28; |
85 | return ev64260_get_bus_speed() * cpu_7xx[hid1]/2; | 86 | return ev64260_get_bus_speed() * cpu_7xx[hid1]/2; |
86 | } | 87 | } |
87 | else { | 88 | else { |
88 | hid1 = (mfspr(SPRN_HID1) & 0x0001e000) >> 13; | 89 | hid1 = (mfspr(SPRN_HID1) & 0x0001e000) >> 13; |
89 | pll_ext = 0; /* No way to read; must get from schematic */ | 90 | pll_ext = 0; /* No way to read; must get from schematic */ |
90 | return ev64260_get_bus_speed() * cpu_745x[pll_ext][hid1]/2; | 91 | return ev64260_get_bus_speed() * cpu_745x[pll_ext][hid1]/2; |
91 | } | 92 | } |
92 | } | 93 | } |
93 | 94 | ||
94 | unsigned long __init | 95 | unsigned long __init |
95 | ev64260_find_end_of_memory(void) | 96 | ev64260_find_end_of_memory(void) |
96 | { | 97 | { |
97 | return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE, | 98 | return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE, |
98 | MV64x60_TYPE_GT64260A); | 99 | MV64x60_TYPE_GT64260A); |
99 | } | 100 | } |
100 | 101 | ||
101 | /* | 102 | /* |
102 | * Marvell/Galileo EV-64260-BP Evaluation Board PCI interrupt routing. | 103 | * Marvell/Galileo EV-64260-BP Evaluation Board PCI interrupt routing. |
103 | * Note: By playing with J8 and JP1-4, you can get 2 IRQ's from the first | 104 | * Note: By playing with J8 and JP1-4, you can get 2 IRQ's from the first |
104 | * PCI bus (in which cast, INTPIN B would be EV64260_PCI_1_IRQ). | 105 | * PCI bus (in which cast, INTPIN B would be EV64260_PCI_1_IRQ). |
105 | * This is the most IRQs you can get from one bus with this board, though. | 106 | * This is the most IRQs you can get from one bus with this board, though. |
106 | */ | 107 | */ |
107 | static int __init | 108 | static int __init |
108 | ev64260_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 109 | ev64260_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
109 | { | 110 | { |
110 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | 111 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); |
111 | 112 | ||
112 | if (hose->index == 0) { | 113 | if (hose->index == 0) { |
113 | static char pci_irq_table[][4] = | 114 | static char pci_irq_table[][4] = |
114 | /* | 115 | /* |
115 | * PCI IDSEL/INTPIN->INTLINE | 116 | * PCI IDSEL/INTPIN->INTLINE |
116 | * A B C D | 117 | * A B C D |
117 | */ | 118 | */ |
118 | { | 119 | { |
119 | {EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 0 */ | 120 | {EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 0 */ |
120 | {EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 0 */ | 121 | {EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 0 */ |
121 | }; | 122 | }; |
122 | 123 | ||
123 | const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4; | 124 | const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4; |
124 | return PCI_IRQ_TABLE_LOOKUP; | 125 | return PCI_IRQ_TABLE_LOOKUP; |
125 | } | 126 | } |
126 | else { | 127 | else { |
127 | static char pci_irq_table[][4] = | 128 | static char pci_irq_table[][4] = |
128 | /* | 129 | /* |
129 | * PCI IDSEL/INTPIN->INTLINE | 130 | * PCI IDSEL/INTPIN->INTLINE |
130 | * A B C D | 131 | * A B C D |
131 | */ | 132 | */ |
132 | { | 133 | { |
133 | { EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 1 */ | 134 | { EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 1 */ |
134 | { EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 1 */ | 135 | { EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 1 */ |
135 | }; | 136 | }; |
136 | 137 | ||
137 | const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4; | 138 | const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4; |
138 | return PCI_IRQ_TABLE_LOOKUP; | 139 | return PCI_IRQ_TABLE_LOOKUP; |
139 | } | 140 | } |
140 | } | 141 | } |
141 | 142 | ||
142 | static void __init | 143 | static void __init |
143 | ev64260_setup_peripherals(void) | 144 | ev64260_setup_peripherals(void) |
144 | { | 145 | { |
145 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, | 146 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, |
146 | EV64260_EMB_FLASH_BASE, EV64260_EMB_FLASH_SIZE, 0); | 147 | EV64260_EMB_FLASH_BASE, EV64260_EMB_FLASH_SIZE, 0); |
147 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); | 148 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); |
148 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, | 149 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, |
149 | EV64260_EXT_SRAM_BASE, EV64260_EXT_SRAM_SIZE, 0); | 150 | EV64260_EXT_SRAM_BASE, EV64260_EXT_SRAM_SIZE, 0); |
150 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN); | 151 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN); |
151 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, | 152 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, |
152 | EV64260_TODC_BASE, EV64260_TODC_SIZE, 0); | 153 | EV64260_TODC_BASE, EV64260_TODC_SIZE, 0); |
153 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); | 154 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); |
154 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, | 155 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, |
155 | EV64260_UART_BASE, EV64260_UART_SIZE, 0); | 156 | EV64260_UART_BASE, EV64260_UART_SIZE, 0); |
156 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); | 157 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); |
157 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, | 158 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, |
158 | EV64260_EXT_FLASH_BASE, EV64260_EXT_FLASH_SIZE, 0); | 159 | EV64260_EXT_FLASH_BASE, EV64260_EXT_FLASH_SIZE, 0); |
159 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); | 160 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); |
160 | 161 | ||
161 | TODC_INIT(TODC_TYPE_DS1501, 0, 0, | 162 | TODC_INIT(TODC_TYPE_DS1501, 0, 0, |
162 | ioremap(EV64260_TODC_BASE, EV64260_TODC_SIZE), 8); | 163 | ioremap(EV64260_TODC_BASE, EV64260_TODC_SIZE), 8); |
163 | 164 | ||
164 | mv64x60_clr_bits(&bh, MV64x60_CPU_CONFIG,((1<<12) | (1<<28) | (1<<29))); | 165 | mv64x60_clr_bits(&bh, MV64x60_CPU_CONFIG,((1<<12) | (1<<28) | (1<<29))); |
165 | mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<27)); | 166 | mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<27)); |
166 | 167 | ||
167 | if (ev64260_get_bus_speed() > 100000000) | 168 | if (ev64260_get_bus_speed() > 100000000) |
168 | mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<23)); | 169 | mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<23)); |
169 | 170 | ||
170 | mv64x60_set_bits(&bh, MV64x60_PCI0_PCI_DECODE_CNTL, ((1<<0) | (1<<3))); | 171 | mv64x60_set_bits(&bh, MV64x60_PCI0_PCI_DECODE_CNTL, ((1<<0) | (1<<3))); |
171 | mv64x60_set_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, ((1<<0) | (1<<3))); | 172 | mv64x60_set_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, ((1<<0) | (1<<3))); |
172 | 173 | ||
173 | /* | 174 | /* |
174 | * Enabling of PCI internal-vs-external arbitration | 175 | * Enabling of PCI internal-vs-external arbitration |
175 | * is a platform- and errata-dependent decision. | 176 | * is a platform- and errata-dependent decision. |
176 | */ | 177 | */ |
177 | if (bh.type == MV64x60_TYPE_GT64260A ) { | 178 | if (bh.type == MV64x60_TYPE_GT64260A ) { |
178 | mv64x60_set_bits(&bh, MV64x60_PCI0_ARBITER_CNTL, (1<<31)); | 179 | mv64x60_set_bits(&bh, MV64x60_PCI0_ARBITER_CNTL, (1<<31)); |
179 | mv64x60_set_bits(&bh, MV64x60_PCI1_ARBITER_CNTL, (1<<31)); | 180 | mv64x60_set_bits(&bh, MV64x60_PCI1_ARBITER_CNTL, (1<<31)); |
180 | } | 181 | } |
181 | 182 | ||
182 | mv64x60_set_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */ | 183 | mv64x60_set_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */ |
183 | 184 | ||
184 | /* | 185 | /* |
185 | * Turn off timer/counters. Not turning off watchdog timer because | 186 | * Turn off timer/counters. Not turning off watchdog timer because |
186 | * can't read its reg on the 64260A so don't know if we'll be enabling | 187 | * can't read its reg on the 64260A so don't know if we'll be enabling |
187 | * or disabling. | 188 | * or disabling. |
188 | */ | 189 | */ |
189 | mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL, | 190 | mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL, |
190 | ((1<<0) | (1<<8) | (1<<16) | (1<<24))); | 191 | ((1<<0) | (1<<8) | (1<<16) | (1<<24))); |
191 | mv64x60_clr_bits(&bh, GT64260_TIMR_CNTR_4_7_CNTL, | 192 | mv64x60_clr_bits(&bh, GT64260_TIMR_CNTR_4_7_CNTL, |
192 | ((1<<0) | (1<<8) | (1<<16) | (1<<24))); | 193 | ((1<<0) | (1<<8) | (1<<16) | (1<<24))); |
193 | 194 | ||
194 | /* | 195 | /* |
195 | * Set MPSC Multiplex RMII | 196 | * Set MPSC Multiplex RMII |
196 | * NOTE: ethernet driver modifies bit 0 and 1 | 197 | * NOTE: ethernet driver modifies bit 0 and 1 |
197 | */ | 198 | */ |
198 | mv64x60_write(&bh, GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); | 199 | mv64x60_write(&bh, GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); |
199 | 200 | ||
200 | /* | 201 | /* |
201 | * The EV-64260-BP uses several Multi-Purpose Pins (MPP) on the 64260 | 202 | * The EV-64260-BP uses several Multi-Purpose Pins (MPP) on the 64260 |
202 | * bridge as interrupt inputs (via the General Purpose Ports (GPP) | 203 | * bridge as interrupt inputs (via the General Purpose Ports (GPP) |
203 | * register). Need to route the MPP inputs to the GPP and set the | 204 | * register). Need to route the MPP inputs to the GPP and set the |
204 | * polarity correctly. | 205 | * polarity correctly. |
205 | * | 206 | * |
206 | * In MPP Control 2 Register | 207 | * In MPP Control 2 Register |
207 | * MPP 21 -> GPP 21 (DUART channel A intr) bits 20-23 -> 0 | 208 | * MPP 21 -> GPP 21 (DUART channel A intr) bits 20-23 -> 0 |
208 | * MPP 22 -> GPP 22 (DUART channel B intr) bits 24-27 -> 0 | 209 | * MPP 22 -> GPP 22 (DUART channel B intr) bits 24-27 -> 0 |
209 | */ | 210 | */ |
210 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_2, (0xf<<20) | (0xf<<24) ); | 211 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_2, (0xf<<20) | (0xf<<24) ); |
211 | 212 | ||
212 | /* | 213 | /* |
213 | * In MPP Control 3 Register | 214 | * In MPP Control 3 Register |
214 | * MPP 26 -> GPP 26 (RTC INT) bits 8-11 -> 0 | 215 | * MPP 26 -> GPP 26 (RTC INT) bits 8-11 -> 0 |
215 | * MPP 27 -> GPP 27 (PCI 0 INTA) bits 12-15 -> 0 | 216 | * MPP 27 -> GPP 27 (PCI 0 INTA) bits 12-15 -> 0 |
216 | * MPP 29 -> GPP 29 (PCI 1 INTA) bits 20-23 -> 0 | 217 | * MPP 29 -> GPP 29 (PCI 1 INTA) bits 20-23 -> 0 |
217 | */ | 218 | */ |
218 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3, (0xf<<8)|(0xf<<12)|(0xf<<20)); | 219 | mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3, (0xf<<8)|(0xf<<12)|(0xf<<20)); |
219 | 220 | ||
220 | #define GPP_EXTERNAL_INTERRUPTS \ | 221 | #define GPP_EXTERNAL_INTERRUPTS \ |
221 | ((1<<21) | (1<<22) | (1<<26) | (1<<27) | (1<<29)) | 222 | ((1<<21) | (1<<22) | (1<<26) | (1<<27) | (1<<29)) |
222 | /* DUART & PCI interrupts are inputs */ | 223 | /* DUART & PCI interrupts are inputs */ |
223 | mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, GPP_EXTERNAL_INTERRUPTS); | 224 | mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, GPP_EXTERNAL_INTERRUPTS); |
224 | /* DUART & PCI interrupts are active low */ | 225 | /* DUART & PCI interrupts are active low */ |
225 | mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, GPP_EXTERNAL_INTERRUPTS); | 226 | mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, GPP_EXTERNAL_INTERRUPTS); |
226 | 227 | ||
227 | /* Clear any pending interrupts for these inputs and enable them. */ | 228 | /* Clear any pending interrupts for these inputs and enable them. */ |
228 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~GPP_EXTERNAL_INTERRUPTS); | 229 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~GPP_EXTERNAL_INTERRUPTS); |
229 | mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, GPP_EXTERNAL_INTERRUPTS); | 230 | mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, GPP_EXTERNAL_INTERRUPTS); |
230 | 231 | ||
231 | return; | 232 | return; |
232 | } | 233 | } |
233 | 234 | ||
234 | static void __init | 235 | static void __init |
235 | ev64260_setup_bridge(void) | 236 | ev64260_setup_bridge(void) |
236 | { | 237 | { |
237 | struct mv64x60_setup_info si; | 238 | struct mv64x60_setup_info si; |
238 | int i; | 239 | int i; |
239 | 240 | ||
240 | memset(&si, 0, sizeof(si)); | 241 | memset(&si, 0, sizeof(si)); |
241 | 242 | ||
242 | si.phys_reg_base = CONFIG_MV64X60_NEW_BASE; | 243 | si.phys_reg_base = CONFIG_MV64X60_NEW_BASE; |
243 | 244 | ||
244 | si.pci_0.enable_bus = 1; | 245 | si.pci_0.enable_bus = 1; |
245 | si.pci_0.pci_io.cpu_base = EV64260_PCI0_IO_CPU_BASE; | 246 | si.pci_0.pci_io.cpu_base = EV64260_PCI0_IO_CPU_BASE; |
246 | si.pci_0.pci_io.pci_base_hi = 0; | 247 | si.pci_0.pci_io.pci_base_hi = 0; |
247 | si.pci_0.pci_io.pci_base_lo = EV64260_PCI0_IO_PCI_BASE; | 248 | si.pci_0.pci_io.pci_base_lo = EV64260_PCI0_IO_PCI_BASE; |
248 | si.pci_0.pci_io.size = EV64260_PCI0_IO_SIZE; | 249 | si.pci_0.pci_io.size = EV64260_PCI0_IO_SIZE; |
249 | si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; | 250 | si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; |
250 | si.pci_0.pci_mem[0].cpu_base = EV64260_PCI0_MEM_CPU_BASE; | 251 | si.pci_0.pci_mem[0].cpu_base = EV64260_PCI0_MEM_CPU_BASE; |
251 | si.pci_0.pci_mem[0].pci_base_hi = 0; | 252 | si.pci_0.pci_mem[0].pci_base_hi = 0; |
252 | si.pci_0.pci_mem[0].pci_base_lo = EV64260_PCI0_MEM_PCI_BASE; | 253 | si.pci_0.pci_mem[0].pci_base_lo = EV64260_PCI0_MEM_PCI_BASE; |
253 | si.pci_0.pci_mem[0].size = EV64260_PCI0_MEM_SIZE; | 254 | si.pci_0.pci_mem[0].size = EV64260_PCI0_MEM_SIZE; |
254 | si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; | 255 | si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; |
255 | si.pci_0.pci_cmd_bits = 0; | 256 | si.pci_0.pci_cmd_bits = 0; |
256 | si.pci_0.latency_timer = 0x8; | 257 | si.pci_0.latency_timer = 0x8; |
257 | 258 | ||
258 | si.pci_1.enable_bus = 1; | 259 | si.pci_1.enable_bus = 1; |
259 | si.pci_1.pci_io.cpu_base = EV64260_PCI1_IO_CPU_BASE; | 260 | si.pci_1.pci_io.cpu_base = EV64260_PCI1_IO_CPU_BASE; |
260 | si.pci_1.pci_io.pci_base_hi = 0; | 261 | si.pci_1.pci_io.pci_base_hi = 0; |
261 | si.pci_1.pci_io.pci_base_lo = EV64260_PCI1_IO_PCI_BASE; | 262 | si.pci_1.pci_io.pci_base_lo = EV64260_PCI1_IO_PCI_BASE; |
262 | si.pci_1.pci_io.size = EV64260_PCI1_IO_SIZE; | 263 | si.pci_1.pci_io.size = EV64260_PCI1_IO_SIZE; |
263 | si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; | 264 | si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; |
264 | si.pci_1.pci_mem[0].cpu_base = EV64260_PCI1_MEM_CPU_BASE; | 265 | si.pci_1.pci_mem[0].cpu_base = EV64260_PCI1_MEM_CPU_BASE; |
265 | si.pci_1.pci_mem[0].pci_base_hi = 0; | 266 | si.pci_1.pci_mem[0].pci_base_hi = 0; |
266 | si.pci_1.pci_mem[0].pci_base_lo = EV64260_PCI1_MEM_PCI_BASE; | 267 | si.pci_1.pci_mem[0].pci_base_lo = EV64260_PCI1_MEM_PCI_BASE; |
267 | si.pci_1.pci_mem[0].size = EV64260_PCI1_MEM_SIZE; | 268 | si.pci_1.pci_mem[0].size = EV64260_PCI1_MEM_SIZE; |
268 | si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; | 269 | si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; |
269 | si.pci_1.pci_cmd_bits = 0; | 270 | si.pci_1.pci_cmd_bits = 0; |
270 | si.pci_1.latency_timer = 0x8; | 271 | si.pci_1.latency_timer = 0x8; |
271 | 272 | ||
272 | for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) { | 273 | for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) { |
273 | si.cpu_prot_options[i] = 0; | 274 | si.cpu_prot_options[i] = 0; |
274 | si.cpu_snoop_options[i] = GT64260_CPU_SNOOP_WB; | 275 | si.cpu_snoop_options[i] = GT64260_CPU_SNOOP_WB; |
275 | si.pci_0.acc_cntl_options[i] = | 276 | si.pci_0.acc_cntl_options[i] = |
276 | GT64260_PCI_ACC_CNTL_DREADEN | | 277 | GT64260_PCI_ACC_CNTL_DREADEN | |
277 | GT64260_PCI_ACC_CNTL_RDPREFETCH | | 278 | GT64260_PCI_ACC_CNTL_RDPREFETCH | |
278 | GT64260_PCI_ACC_CNTL_RDLINEPREFETCH | | 279 | GT64260_PCI_ACC_CNTL_RDLINEPREFETCH | |
279 | GT64260_PCI_ACC_CNTL_RDMULPREFETCH | | 280 | GT64260_PCI_ACC_CNTL_RDMULPREFETCH | |
280 | GT64260_PCI_ACC_CNTL_SWAP_NONE | | 281 | GT64260_PCI_ACC_CNTL_SWAP_NONE | |
281 | GT64260_PCI_ACC_CNTL_MBURST_32_BTYES; | 282 | GT64260_PCI_ACC_CNTL_MBURST_32_BTYES; |
282 | si.pci_0.snoop_options[i] = GT64260_PCI_SNOOP_WB; | 283 | si.pci_0.snoop_options[i] = GT64260_PCI_SNOOP_WB; |
283 | si.pci_1.acc_cntl_options[i] = | 284 | si.pci_1.acc_cntl_options[i] = |
284 | GT64260_PCI_ACC_CNTL_DREADEN | | 285 | GT64260_PCI_ACC_CNTL_DREADEN | |
285 | GT64260_PCI_ACC_CNTL_RDPREFETCH | | 286 | GT64260_PCI_ACC_CNTL_RDPREFETCH | |
286 | GT64260_PCI_ACC_CNTL_RDLINEPREFETCH | | 287 | GT64260_PCI_ACC_CNTL_RDLINEPREFETCH | |
287 | GT64260_PCI_ACC_CNTL_RDMULPREFETCH | | 288 | GT64260_PCI_ACC_CNTL_RDMULPREFETCH | |
288 | GT64260_PCI_ACC_CNTL_SWAP_NONE | | 289 | GT64260_PCI_ACC_CNTL_SWAP_NONE | |
289 | GT64260_PCI_ACC_CNTL_MBURST_32_BTYES; | 290 | GT64260_PCI_ACC_CNTL_MBURST_32_BTYES; |
290 | si.pci_1.snoop_options[i] = GT64260_PCI_SNOOP_WB; | 291 | si.pci_1.snoop_options[i] = GT64260_PCI_SNOOP_WB; |
291 | } | 292 | } |
292 | 293 | ||
293 | /* Lookup PCI host bridges */ | 294 | /* Lookup PCI host bridges */ |
294 | if (mv64x60_init(&bh, &si)) | 295 | if (mv64x60_init(&bh, &si)) |
295 | printk(KERN_ERR "Bridge initialization failed.\n"); | 296 | printk(KERN_ERR "Bridge initialization failed.\n"); |
296 | 297 | ||
297 | pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */ | 298 | pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */ |
298 | ppc_md.pci_swizzle = common_swizzle; | 299 | ppc_md.pci_swizzle = common_swizzle; |
299 | ppc_md.pci_map_irq = ev64260_map_irq; | 300 | ppc_md.pci_map_irq = ev64260_map_irq; |
300 | ppc_md.pci_exclude_device = mv64x60_pci_exclude_device; | 301 | ppc_md.pci_exclude_device = mv64x60_pci_exclude_device; |
301 | 302 | ||
302 | mv64x60_set_bus(&bh, 0, 0); | 303 | mv64x60_set_bus(&bh, 0, 0); |
303 | bh.hose_a->first_busno = 0; | 304 | bh.hose_a->first_busno = 0; |
304 | bh.hose_a->last_busno = 0xff; | 305 | bh.hose_a->last_busno = 0xff; |
305 | bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0); | 306 | bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0); |
306 | 307 | ||
307 | bh.hose_b->first_busno = bh.hose_a->last_busno + 1; | 308 | bh.hose_b->first_busno = bh.hose_a->last_busno + 1; |
308 | mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno); | 309 | mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno); |
309 | bh.hose_b->last_busno = 0xff; | 310 | bh.hose_b->last_busno = 0xff; |
310 | bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b, | 311 | bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b, |
311 | bh.hose_b->first_busno); | 312 | bh.hose_b->first_busno); |
312 | 313 | ||
313 | return; | 314 | return; |
314 | } | 315 | } |
315 | 316 | ||
316 | #if defined(CONFIG_SERIAL_8250) && !defined(CONFIG_SERIAL_MPSC_CONSOLE) | 317 | #if defined(CONFIG_SERIAL_8250) && !defined(CONFIG_SERIAL_MPSC_CONSOLE) |
317 | static void __init | 318 | static void __init |
318 | ev64260_early_serial_map(void) | 319 | ev64260_early_serial_map(void) |
319 | { | 320 | { |
320 | struct uart_port port; | 321 | struct uart_port port; |
321 | static char first_time = 1; | 322 | static char first_time = 1; |
322 | 323 | ||
323 | if (first_time) { | 324 | if (first_time) { |
324 | memset(&port, 0, sizeof(port)); | 325 | memset(&port, 0, sizeof(port)); |
325 | 326 | ||
326 | port.membase = ioremap(EV64260_SERIAL_0, EV64260_UART_SIZE); | 327 | port.membase = ioremap(EV64260_SERIAL_0, EV64260_UART_SIZE); |
327 | port.irq = EV64260_UART_0_IRQ; | 328 | port.irq = EV64260_UART_0_IRQ; |
328 | port.uartclk = BASE_BAUD * 16; | 329 | port.uartclk = BASE_BAUD * 16; |
329 | port.regshift = 2; | 330 | port.regshift = 2; |
330 | port.iotype = UPIO_MEM; | 331 | port.iotype = UPIO_MEM; |
331 | port.flags = STD_COM_FLAGS; | 332 | port.flags = STD_COM_FLAGS; |
332 | 333 | ||
333 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 334 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
334 | gen550_init(0, &port); | 335 | gen550_init(0, &port); |
335 | #endif | 336 | #endif |
336 | 337 | ||
337 | if (early_serial_setup(&port) != 0) | 338 | if (early_serial_setup(&port) != 0) |
338 | printk(KERN_WARNING "Early serial init of port 0" | 339 | printk(KERN_WARNING "Early serial init of port 0" |
339 | "failed\n"); | 340 | "failed\n"); |
340 | 341 | ||
341 | first_time = 0; | 342 | first_time = 0; |
342 | } | 343 | } |
343 | 344 | ||
344 | return; | 345 | return; |
345 | } | 346 | } |
346 | #elif defined(CONFIG_SERIAL_MPSC_CONSOLE) | 347 | #elif defined(CONFIG_SERIAL_MPSC_CONSOLE) |
347 | static void __init | 348 | static void __init |
348 | ev64260_early_serial_map(void) | 349 | ev64260_early_serial_map(void) |
349 | { | 350 | { |
350 | } | 351 | } |
351 | #endif | 352 | #endif |
352 | 353 | ||
353 | static void __init | 354 | static void __init |
354 | ev64260_setup_arch(void) | 355 | ev64260_setup_arch(void) |
355 | { | 356 | { |
356 | if (ppc_md.progress) | 357 | if (ppc_md.progress) |
357 | ppc_md.progress("ev64260_setup_arch: enter", 0); | 358 | ppc_md.progress("ev64260_setup_arch: enter", 0); |
358 | 359 | ||
359 | #ifdef CONFIG_BLK_DEV_INITRD | 360 | #ifdef CONFIG_BLK_DEV_INITRD |
360 | if (initrd_start) | 361 | if (initrd_start) |
361 | ROOT_DEV = Root_RAM0; | 362 | ROOT_DEV = Root_RAM0; |
362 | else | 363 | else |
363 | #endif | 364 | #endif |
364 | #ifdef CONFIG_ROOT_NFS | 365 | #ifdef CONFIG_ROOT_NFS |
365 | ROOT_DEV = Root_NFS; | 366 | ROOT_DEV = Root_NFS; |
366 | #else | 367 | #else |
367 | ROOT_DEV = Root_SDA2; | 368 | ROOT_DEV = Root_SDA2; |
368 | #endif | 369 | #endif |
369 | 370 | ||
370 | if (ppc_md.progress) | 371 | if (ppc_md.progress) |
371 | ppc_md.progress("ev64260_setup_arch: Enabling L2 cache", 0); | 372 | ppc_md.progress("ev64260_setup_arch: Enabling L2 cache", 0); |
372 | 373 | ||
373 | /* Enable L2 and L3 caches (if 745x) */ | 374 | /* Enable L2 and L3 caches (if 745x) */ |
374 | _set_L2CR(_get_L2CR() | L2CR_L2E); | 375 | _set_L2CR(_get_L2CR() | L2CR_L2E); |
375 | _set_L3CR(_get_L3CR() | L3CR_L3E); | 376 | _set_L3CR(_get_L3CR() | L3CR_L3E); |
376 | 377 | ||
377 | if (ppc_md.progress) | 378 | if (ppc_md.progress) |
378 | ppc_md.progress("ev64260_setup_arch: Initializing bridge", 0); | 379 | ppc_md.progress("ev64260_setup_arch: Initializing bridge", 0); |
379 | 380 | ||
380 | ev64260_setup_bridge(); /* set up PCI bridge(s) */ | 381 | ev64260_setup_bridge(); /* set up PCI bridge(s) */ |
381 | ev64260_setup_peripherals(); /* set up chip selects/GPP/MPP etc */ | 382 | ev64260_setup_peripherals(); /* set up chip selects/GPP/MPP etc */ |
382 | 383 | ||
383 | if (ppc_md.progress) | 384 | if (ppc_md.progress) |
384 | ppc_md.progress("ev64260_setup_arch: bridge init complete", 0); | 385 | ppc_md.progress("ev64260_setup_arch: bridge init complete", 0); |
385 | 386 | ||
386 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_MPSC_CONSOLE) | 387 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_MPSC_CONSOLE) |
387 | ev64260_early_serial_map(); | 388 | ev64260_early_serial_map(); |
388 | #endif | 389 | #endif |
389 | 390 | ||
390 | printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc." | 391 | printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc." |
391 | "(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE); | 392 | "(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE); |
392 | 393 | ||
393 | if (ppc_md.progress) | 394 | if (ppc_md.progress) |
394 | ppc_md.progress("ev64260_setup_arch: exit", 0); | 395 | ppc_md.progress("ev64260_setup_arch: exit", 0); |
395 | 396 | ||
396 | return; | 397 | return; |
397 | } | 398 | } |
398 | 399 | ||
399 | /* Platform device data fixup routines. */ | 400 | /* Platform device data fixup routines. */ |
400 | #if defined(CONFIG_SERIAL_MPSC) | 401 | #if defined(CONFIG_SERIAL_MPSC) |
401 | static void __init | 402 | static void __init |
402 | ev64260_fixup_mpsc_pdata(struct platform_device *pdev) | 403 | ev64260_fixup_mpsc_pdata(struct platform_device *pdev) |
403 | { | 404 | { |
404 | struct mpsc_pdata *pdata; | 405 | struct mpsc_pdata *pdata; |
405 | 406 | ||
406 | pdata = (struct mpsc_pdata *)pdev->dev.platform_data; | 407 | pdata = (struct mpsc_pdata *)pdev->dev.platform_data; |
407 | 408 | ||
408 | pdata->max_idle = 40; | 409 | pdata->max_idle = 40; |
409 | pdata->default_baud = EV64260_DEFAULT_BAUD; | 410 | pdata->default_baud = EV64260_DEFAULT_BAUD; |
410 | pdata->brg_clk_src = EV64260_MPSC_CLK_SRC; | 411 | pdata->brg_clk_src = EV64260_MPSC_CLK_SRC; |
411 | pdata->brg_clk_freq = EV64260_MPSC_CLK_FREQ; | 412 | pdata->brg_clk_freq = EV64260_MPSC_CLK_FREQ; |
412 | 413 | ||
413 | return; | 414 | return; |
414 | } | 415 | } |
415 | 416 | ||
416 | static int | 417 | static int |
417 | ev64260_platform_notify(struct device *dev) | 418 | ev64260_platform_notify(struct device *dev) |
418 | { | 419 | { |
419 | static struct { | 420 | static struct { |
420 | char *bus_id; | 421 | char *bus_id; |
421 | void ((*rtn)(struct platform_device *pdev)); | 422 | void ((*rtn)(struct platform_device *pdev)); |
422 | } dev_map[] = { | 423 | } dev_map[] = { |
423 | { MPSC_CTLR_NAME ".0", ev64260_fixup_mpsc_pdata }, | 424 | { MPSC_CTLR_NAME ".0", ev64260_fixup_mpsc_pdata }, |
424 | { MPSC_CTLR_NAME ".1", ev64260_fixup_mpsc_pdata }, | 425 | { MPSC_CTLR_NAME ".1", ev64260_fixup_mpsc_pdata }, |
425 | }; | 426 | }; |
426 | struct platform_device *pdev; | 427 | struct platform_device *pdev; |
427 | int i; | 428 | int i; |
428 | 429 | ||
429 | if (dev && dev->bus_id) | 430 | if (dev && dev->bus_id) |
430 | for (i=0; i<ARRAY_SIZE(dev_map); i++) | 431 | for (i=0; i<ARRAY_SIZE(dev_map); i++) |
431 | if (!strncmp(dev->bus_id, dev_map[i].bus_id, | 432 | if (!strncmp(dev->bus_id, dev_map[i].bus_id, |
432 | BUS_ID_SIZE)) { | 433 | BUS_ID_SIZE)) { |
433 | 434 | ||
434 | pdev = container_of(dev, | 435 | pdev = container_of(dev, |
435 | struct platform_device, dev); | 436 | struct platform_device, dev); |
436 | dev_map[i].rtn(pdev); | 437 | dev_map[i].rtn(pdev); |
437 | } | 438 | } |
438 | 439 | ||
439 | return 0; | 440 | return 0; |
440 | } | 441 | } |
441 | #endif | 442 | #endif |
442 | 443 | ||
443 | static void | 444 | static void |
444 | ev64260_reset_board(void *addr) | 445 | ev64260_reset_board(void *addr) |
445 | { | 446 | { |
446 | local_irq_disable(); | 447 | local_irq_disable(); |
447 | 448 | ||
448 | /* disable and invalidate the L2 cache */ | 449 | /* disable and invalidate the L2 cache */ |
449 | _set_L2CR(0); | 450 | _set_L2CR(0); |
450 | _set_L2CR(0x200000); | 451 | _set_L2CR(0x200000); |
451 | 452 | ||
452 | /* flush and disable L1 I/D cache */ | 453 | /* flush and disable L1 I/D cache */ |
453 | __asm__ __volatile__ | 454 | __asm__ __volatile__ |
454 | ("mfspr 3,1008\n\t" | 455 | ("mfspr 3,1008\n\t" |
455 | "ori 5,5,0xcc00\n\t" | 456 | "ori 5,5,0xcc00\n\t" |
456 | "ori 4,3,0xc00\n\t" | 457 | "ori 4,3,0xc00\n\t" |
457 | "andc 5,3,5\n\t" | 458 | "andc 5,3,5\n\t" |
458 | "sync\n\t" | 459 | "sync\n\t" |
459 | "mtspr 1008,4\n\t" | 460 | "mtspr 1008,4\n\t" |
460 | "isync\n\t" | 461 | "isync\n\t" |
461 | "sync\n\t" | 462 | "sync\n\t" |
462 | "mtspr 1008,5\n\t" | 463 | "mtspr 1008,5\n\t" |
463 | "isync\n\t" | 464 | "isync\n\t" |
464 | "sync\n\t"); | 465 | "sync\n\t"); |
465 | 466 | ||
466 | /* unmap any other random cs's that might overlap with bootcs */ | 467 | /* unmap any other random cs's that might overlap with bootcs */ |
467 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, 0, 0, 0); | 468 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, 0, 0, 0); |
468 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN); | 469 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN); |
469 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, 0, 0, 0); | 470 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, 0, 0, 0); |
470 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); | 471 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); |
471 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, 0, 0, 0); | 472 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, 0, 0, 0); |
472 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); | 473 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); |
473 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, 0, 0, 0); | 474 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, 0, 0, 0); |
474 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); | 475 | bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); |
475 | 476 | ||
476 | /* map bootrom back in to gt @ reset defaults */ | 477 | /* map bootrom back in to gt @ reset defaults */ |
477 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, | 478 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, |
478 | 0xff800000, 8*1024*1024, 0); | 479 | 0xff800000, 8*1024*1024, 0); |
479 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); | 480 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); |
480 | 481 | ||
481 | /* move reg base back to default, setup default pci0 */ | 482 | /* move reg base back to default, setup default pci0 */ |
482 | mv64x60_write(&bh, MV64x60_INTERNAL_SPACE_DECODE, | 483 | mv64x60_write(&bh, MV64x60_INTERNAL_SPACE_DECODE, |
483 | (1<<24) | CONFIG_MV64X60_BASE >> 20); | 484 | (1<<24) | CONFIG_MV64X60_BASE >> 20); |
484 | 485 | ||
485 | /* NOTE: FROM NOW ON no more GT_REGS accesses.. 0x1 is not mapped | 486 | /* NOTE: FROM NOW ON no more GT_REGS accesses.. 0x1 is not mapped |
486 | * via BAT or MMU, and MSR IR/DR is ON */ | 487 | * via BAT or MMU, and MSR IR/DR is ON */ |
487 | /* SRR0 has system reset vector, SRR1 has default MSR value */ | 488 | /* SRR0 has system reset vector, SRR1 has default MSR value */ |
488 | /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ | 489 | /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ |
489 | /* NOTE: assumes reset vector is at 0xfff00100 */ | 490 | /* NOTE: assumes reset vector is at 0xfff00100 */ |
490 | __asm__ __volatile__ | 491 | __asm__ __volatile__ |
491 | ("mtspr 26, %0\n\t" | 492 | ("mtspr 26, %0\n\t" |
492 | "li 4,(1<<6)\n\t" | 493 | "li 4,(1<<6)\n\t" |
493 | "mtspr 27,4\n\t" | 494 | "mtspr 27,4\n\t" |
494 | "rfi\n\t" | 495 | "rfi\n\t" |
495 | :: "r" (addr):"r4"); | 496 | :: "r" (addr):"r4"); |
496 | 497 | ||
497 | return; | 498 | return; |
498 | } | 499 | } |
499 | 500 | ||
500 | static void | 501 | static void |
501 | ev64260_restart(char *cmd) | 502 | ev64260_restart(char *cmd) |
502 | { | 503 | { |
503 | volatile ulong i = 10000000; | 504 | volatile ulong i = 10000000; |
504 | 505 | ||
505 | ev64260_reset_board((void *)0xfff00100); | 506 | ev64260_reset_board((void *)0xfff00100); |
506 | 507 | ||
507 | while (i-- > 0); | 508 | while (i-- > 0); |
508 | panic("restart failed\n"); | 509 | panic("restart failed\n"); |
509 | } | 510 | } |
510 | 511 | ||
511 | static void | 512 | static void |
512 | ev64260_halt(void) | 513 | ev64260_halt(void) |
513 | { | 514 | { |
514 | local_irq_disable(); | 515 | local_irq_disable(); |
515 | while (1); | 516 | while (1); |
516 | /* NOTREACHED */ | 517 | /* NOTREACHED */ |
517 | } | 518 | } |
518 | 519 | ||
519 | static void | 520 | static void |
520 | ev64260_power_off(void) | 521 | ev64260_power_off(void) |
521 | { | 522 | { |
522 | ev64260_halt(); | 523 | ev64260_halt(); |
523 | /* NOTREACHED */ | 524 | /* NOTREACHED */ |
524 | } | 525 | } |
525 | 526 | ||
526 | static int | 527 | static int |
527 | ev64260_show_cpuinfo(struct seq_file *m) | 528 | ev64260_show_cpuinfo(struct seq_file *m) |
528 | { | 529 | { |
529 | uint pvid; | 530 | uint pvid; |
530 | 531 | ||
531 | pvid = mfspr(SPRN_PVR); | 532 | pvid = mfspr(SPRN_PVR); |
532 | seq_printf(m, "vendor\t\t: " BOARD_VENDOR "\n"); | 533 | seq_printf(m, "vendor\t\t: " BOARD_VENDOR "\n"); |
533 | seq_printf(m, "machine\t\t: " BOARD_MACHINE "\n"); | 534 | seq_printf(m, "machine\t\t: " BOARD_MACHINE "\n"); |
534 | seq_printf(m, "cpu MHz\t\t: %d\n", ev64260_get_cpu_speed()/1000/1000); | 535 | seq_printf(m, "cpu MHz\t\t: %d\n", ev64260_get_cpu_speed()/1000/1000); |
535 | seq_printf(m, "bus MHz\t\t: %d\n", ev64260_get_bus_speed()/1000/1000); | 536 | seq_printf(m, "bus MHz\t\t: %d\n", ev64260_get_bus_speed()/1000/1000); |
536 | 537 | ||
537 | return 0; | 538 | return 0; |
538 | } | 539 | } |
539 | 540 | ||
540 | /* DS1501 RTC has too much variation to use RTC for calibration */ | 541 | /* DS1501 RTC has too much variation to use RTC for calibration */ |
541 | static void __init | 542 | static void __init |
542 | ev64260_calibrate_decr(void) | 543 | ev64260_calibrate_decr(void) |
543 | { | 544 | { |
544 | ulong freq; | 545 | ulong freq; |
545 | 546 | ||
546 | freq = ev64260_get_bus_speed()/4; | 547 | freq = ev64260_get_bus_speed()/4; |
547 | 548 | ||
548 | printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", | 549 | printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", |
549 | freq/1000000, freq%1000000); | 550 | freq/1000000, freq%1000000); |
550 | 551 | ||
551 | tb_ticks_per_jiffy = freq / HZ; | 552 | tb_ticks_per_jiffy = freq / HZ; |
552 | tb_to_us = mulhwu_scale_factor(freq, 1000000); | 553 | tb_to_us = mulhwu_scale_factor(freq, 1000000); |
553 | 554 | ||
554 | return; | 555 | return; |
555 | } | 556 | } |
556 | 557 | ||
557 | /* | 558 | /* |
558 | * Set BAT 3 to map 0xfb000000 to 0xfc000000 of physical memory space. | 559 | * Set BAT 3 to map 0xfb000000 to 0xfc000000 of physical memory space. |
559 | */ | 560 | */ |
560 | static __inline__ void | 561 | static __inline__ void |
561 | ev64260_set_bat(void) | 562 | ev64260_set_bat(void) |
562 | { | 563 | { |
563 | mb(); | 564 | mb(); |
564 | mtspr(SPRN_DBAT1U, 0xfb0001fe); | 565 | mtspr(SPRN_DBAT1U, 0xfb0001fe); |
565 | mtspr(SPRN_DBAT1L, 0xfb00002a); | 566 | mtspr(SPRN_DBAT1L, 0xfb00002a); |
566 | mb(); | 567 | mb(); |
567 | 568 | ||
568 | return; | 569 | return; |
569 | } | 570 | } |
570 | 571 | ||
571 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 572 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
572 | static void __init | 573 | static void __init |
573 | ev64260_map_io(void) | 574 | ev64260_map_io(void) |
574 | { | 575 | { |
575 | io_block_mapping(0xfb000000, 0xfb000000, 0x01000000, _PAGE_IO); | 576 | io_block_mapping(0xfb000000, 0xfb000000, 0x01000000, _PAGE_IO); |
576 | } | 577 | } |
577 | #endif | 578 | #endif |
578 | 579 | ||
579 | void __init | 580 | void __init |
580 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 581 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
581 | unsigned long r6, unsigned long r7) | 582 | unsigned long r6, unsigned long r7) |
582 | { | 583 | { |
583 | #ifdef CONFIG_BLK_DEV_INITRD | 584 | #ifdef CONFIG_BLK_DEV_INITRD |
584 | extern int initrd_below_start_ok; | 585 | extern int initrd_below_start_ok; |
585 | 586 | ||
586 | initrd_start=initrd_end=0; | 587 | initrd_start=initrd_end=0; |
587 | initrd_below_start_ok=0; | 588 | initrd_below_start_ok=0; |
588 | #endif /* CONFIG_BLK_DEV_INITRD */ | 589 | #endif /* CONFIG_BLK_DEV_INITRD */ |
589 | 590 | ||
590 | parse_bootinfo(find_bootinfo()); | 591 | parse_bootinfo(find_bootinfo()); |
591 | 592 | ||
592 | isa_mem_base = 0; | 593 | isa_mem_base = 0; |
593 | isa_io_base = EV64260_PCI0_IO_CPU_BASE; | 594 | isa_io_base = EV64260_PCI0_IO_CPU_BASE; |
594 | pci_dram_offset = EV64260_PCI0_MEM_CPU_BASE; | 595 | pci_dram_offset = EV64260_PCI0_MEM_CPU_BASE; |
595 | 596 | ||
596 | loops_per_jiffy = ev64260_get_cpu_speed() / HZ; | 597 | loops_per_jiffy = ev64260_get_cpu_speed() / HZ; |
597 | 598 | ||
598 | ppc_md.setup_arch = ev64260_setup_arch; | 599 | ppc_md.setup_arch = ev64260_setup_arch; |
599 | ppc_md.show_cpuinfo = ev64260_show_cpuinfo; | 600 | ppc_md.show_cpuinfo = ev64260_show_cpuinfo; |
600 | ppc_md.init_IRQ = gt64260_init_irq; | 601 | ppc_md.init_IRQ = gt64260_init_irq; |
601 | ppc_md.get_irq = gt64260_get_irq; | 602 | ppc_md.get_irq = gt64260_get_irq; |
602 | 603 | ||
603 | ppc_md.restart = ev64260_restart; | 604 | ppc_md.restart = ev64260_restart; |
604 | ppc_md.power_off = ev64260_power_off; | 605 | ppc_md.power_off = ev64260_power_off; |
605 | ppc_md.halt = ev64260_halt; | 606 | ppc_md.halt = ev64260_halt; |
606 | 607 | ||
607 | ppc_md.find_end_of_memory = ev64260_find_end_of_memory; | 608 | ppc_md.find_end_of_memory = ev64260_find_end_of_memory; |
608 | 609 | ||
609 | ppc_md.init = NULL; | 610 | ppc_md.init = NULL; |
610 | 611 | ||
611 | ppc_md.time_init = todc_time_init; | 612 | ppc_md.time_init = todc_time_init; |
612 | ppc_md.set_rtc_time = todc_set_rtc_time; | 613 | ppc_md.set_rtc_time = todc_set_rtc_time; |
613 | ppc_md.get_rtc_time = todc_get_rtc_time; | 614 | ppc_md.get_rtc_time = todc_get_rtc_time; |
614 | ppc_md.nvram_read_val = todc_direct_read_val; | 615 | ppc_md.nvram_read_val = todc_direct_read_val; |
615 | ppc_md.nvram_write_val = todc_direct_write_val; | 616 | ppc_md.nvram_write_val = todc_direct_write_val; |
616 | ppc_md.calibrate_decr = ev64260_calibrate_decr; | 617 | ppc_md.calibrate_decr = ev64260_calibrate_decr; |
617 | 618 | ||
618 | bh.p_base = CONFIG_MV64X60_NEW_BASE; | 619 | bh.p_base = CONFIG_MV64X60_NEW_BASE; |
619 | 620 | ||
620 | ev64260_set_bat(); | 621 | ev64260_set_bat(); |
621 | 622 | ||
622 | #ifdef CONFIG_SERIAL_8250 | 623 | #ifdef CONFIG_SERIAL_8250 |
623 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) | 624 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) |
624 | ppc_md.setup_io_mappings = ev64260_map_io; | 625 | ppc_md.setup_io_mappings = ev64260_map_io; |
625 | ppc_md.progress = gen550_progress; | 626 | ppc_md.progress = gen550_progress; |
626 | #endif | 627 | #endif |
627 | #if defined(CONFIG_KGDB) | 628 | #if defined(CONFIG_KGDB) |
628 | ppc_md.setup_io_mappings = ev64260_map_io; | 629 | ppc_md.setup_io_mappings = ev64260_map_io; |
629 | ppc_md.early_serial_map = ev64260_early_serial_map; | 630 | ppc_md.early_serial_map = ev64260_early_serial_map; |
630 | #endif | 631 | #endif |
631 | #elif defined(CONFIG_SERIAL_MPSC_CONSOLE) | 632 | #elif defined(CONFIG_SERIAL_MPSC_CONSOLE) |
632 | #ifdef CONFIG_SERIAL_TEXT_DEBUG | 633 | #ifdef CONFIG_SERIAL_TEXT_DEBUG |
633 | ppc_md.setup_io_mappings = ev64260_map_io; | 634 | ppc_md.setup_io_mappings = ev64260_map_io; |
634 | ppc_md.progress = mv64x60_mpsc_progress; | 635 | ppc_md.progress = mv64x60_mpsc_progress; |
635 | mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE); | 636 | mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE); |
636 | #endif /* CONFIG_SERIAL_TEXT_DEBUG */ | 637 | #endif /* CONFIG_SERIAL_TEXT_DEBUG */ |
637 | #ifdef CONFIG_KGDB | 638 | #ifdef CONFIG_KGDB |
638 | ppc_md.setup_io_mappings = ev64260_map_io; | 639 | ppc_md.setup_io_mappings = ev64260_map_io; |
639 | ppc_md.early_serial_map = ev64260_early_serial_map; | 640 | ppc_md.early_serial_map = ev64260_early_serial_map; |
640 | #endif /* CONFIG_KGDB */ | 641 | #endif /* CONFIG_KGDB */ |
641 | 642 | ||
642 | #endif | 643 | #endif |
643 | 644 | ||
644 | #if defined(CONFIG_SERIAL_MPSC) | 645 | #if defined(CONFIG_SERIAL_MPSC) |
645 | platform_notify = ev64260_platform_notify; | 646 | platform_notify = ev64260_platform_notify; |
646 | #endif | 647 | #endif |
647 | 648 | ||
648 | return; | 649 | return; |
649 | } | 650 | } |
650 | 651 |
arch/ppc/platforms/radstone_ppc7d.c
1 | /* | 1 | /* |
2 | * Board setup routines for the Radstone PPC7D boards. | 2 | * Board setup routines for the Radstone PPC7D boards. |
3 | * | 3 | * |
4 | * Author: James Chapman <jchapman@katalix.com> | 4 | * Author: James Chapman <jchapman@katalix.com> |
5 | * | 5 | * |
6 | * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il | 6 | * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il |
7 | * Based on code done by - Mark A. Greer <mgreer@mvista.com> | 7 | * Based on code done by - Mark A. Greer <mgreer@mvista.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the | 10 | * under the terms of the GNU General Public License as published by the |
11 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | /* Radstone PPC7D boards are rugged VME boards with PPC 7447A CPUs, | 15 | /* Radstone PPC7D boards are rugged VME boards with PPC 7447A CPUs, |
16 | * Discovery-II, dual gigabit ethernet, dual PMC, USB, keyboard/mouse, | 16 | * Discovery-II, dual gigabit ethernet, dual PMC, USB, keyboard/mouse, |
17 | * 4 serial ports, 2 high speed serial ports (MPSCs) and optional | 17 | * 4 serial ports, 2 high speed serial ports (MPSCs) and optional |
18 | * SCSI / VGA. | 18 | * SCSI / VGA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/stddef.h> | 21 | #include <linux/stddef.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/reboot.h> | 25 | #include <linux/reboot.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/kdev_t.h> | 27 | #include <linux/kdev_t.h> |
28 | #include <linux/major.h> | 28 | #include <linux/major.h> |
29 | #include <linux/initrd.h> | 29 | #include <linux/initrd.h> |
30 | #include <linux/console.h> | 30 | #include <linux/console.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/ide.h> | 32 | #include <linux/ide.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | #include <linux/root_dev.h> | 34 | #include <linux/root_dev.h> |
35 | #include <linux/serial.h> | 35 | #include <linux/serial.h> |
36 | #include <linux/tty.h> /* for linux/serial_core.h */ | 36 | #include <linux/tty.h> /* for linux/serial_core.h */ |
37 | #include <linux/serial_core.h> | 37 | #include <linux/serial_core.h> |
38 | #include <linux/serial_8250.h> | ||
38 | #include <linux/mv643xx.h> | 39 | #include <linux/mv643xx.h> |
39 | #include <linux/netdevice.h> | 40 | #include <linux/netdevice.h> |
40 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
41 | 42 | ||
42 | #include <asm/system.h> | 43 | #include <asm/system.h> |
43 | #include <asm/pgtable.h> | 44 | #include <asm/pgtable.h> |
44 | #include <asm/page.h> | 45 | #include <asm/page.h> |
45 | #include <asm/time.h> | 46 | #include <asm/time.h> |
46 | #include <asm/dma.h> | 47 | #include <asm/dma.h> |
47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
48 | #include <asm/machdep.h> | 49 | #include <asm/machdep.h> |
49 | #include <asm/prom.h> | 50 | #include <asm/prom.h> |
50 | #include <asm/smp.h> | 51 | #include <asm/smp.h> |
51 | #include <asm/vga.h> | 52 | #include <asm/vga.h> |
52 | #include <asm/open_pic.h> | 53 | #include <asm/open_pic.h> |
53 | #include <asm/i8259.h> | 54 | #include <asm/i8259.h> |
54 | #include <asm/todc.h> | 55 | #include <asm/todc.h> |
55 | #include <asm/bootinfo.h> | 56 | #include <asm/bootinfo.h> |
56 | #include <asm/mpc10x.h> | 57 | #include <asm/mpc10x.h> |
57 | #include <asm/pci-bridge.h> | 58 | #include <asm/pci-bridge.h> |
58 | #include <asm/mv64x60.h> | 59 | #include <asm/mv64x60.h> |
59 | 60 | ||
60 | #include "radstone_ppc7d.h" | 61 | #include "radstone_ppc7d.h" |
61 | 62 | ||
62 | #undef DEBUG | 63 | #undef DEBUG |
63 | 64 | ||
64 | #define PPC7D_RST_PIN 17 /* GPP17 */ | 65 | #define PPC7D_RST_PIN 17 /* GPP17 */ |
65 | 66 | ||
66 | extern u32 mv64360_irq_base; | 67 | extern u32 mv64360_irq_base; |
67 | extern spinlock_t rtc_lock; | 68 | extern spinlock_t rtc_lock; |
68 | 69 | ||
69 | static struct mv64x60_handle bh; | 70 | static struct mv64x60_handle bh; |
70 | static int ppc7d_has_alma; | 71 | static int ppc7d_has_alma; |
71 | 72 | ||
72 | extern void gen550_progress(char *, unsigned short); | 73 | extern void gen550_progress(char *, unsigned short); |
73 | extern void gen550_init(int, struct uart_port *); | 74 | extern void gen550_init(int, struct uart_port *); |
74 | 75 | ||
75 | /* FIXME - move to h file */ | 76 | /* FIXME - move to h file */ |
76 | extern int ds1337_do_command(int id, int cmd, void *arg); | 77 | extern int ds1337_do_command(int id, int cmd, void *arg); |
77 | #define DS1337_GET_DATE 0 | 78 | #define DS1337_GET_DATE 0 |
78 | #define DS1337_SET_DATE 1 | 79 | #define DS1337_SET_DATE 1 |
79 | 80 | ||
80 | /* residual data */ | 81 | /* residual data */ |
81 | unsigned char __res[sizeof(bd_t)]; | 82 | unsigned char __res[sizeof(bd_t)]; |
82 | 83 | ||
83 | /***************************************************************************** | 84 | /***************************************************************************** |
84 | * Serial port code | 85 | * Serial port code |
85 | *****************************************************************************/ | 86 | *****************************************************************************/ |
86 | 87 | ||
87 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) | 88 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) |
88 | static void __init ppc7d_early_serial_map(void) | 89 | static void __init ppc7d_early_serial_map(void) |
89 | { | 90 | { |
90 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) | 91 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) |
91 | mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE); | 92 | mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE); |
92 | #elif defined(CONFIG_SERIAL_8250) | 93 | #elif defined(CONFIG_SERIAL_8250) |
93 | struct uart_port serial_req; | 94 | struct uart_port serial_req; |
94 | 95 | ||
95 | /* Setup serial port access */ | 96 | /* Setup serial port access */ |
96 | memset(&serial_req, 0, sizeof(serial_req)); | 97 | memset(&serial_req, 0, sizeof(serial_req)); |
97 | serial_req.uartclk = UART_CLK; | 98 | serial_req.uartclk = UART_CLK; |
98 | serial_req.irq = 4; | 99 | serial_req.irq = 4; |
99 | serial_req.flags = STD_COM_FLAGS; | 100 | serial_req.flags = STD_COM_FLAGS; |
100 | serial_req.iotype = UPIO_MEM; | 101 | serial_req.iotype = UPIO_MEM; |
101 | serial_req.membase = (u_char *) PPC7D_SERIAL_0; | 102 | serial_req.membase = (u_char *) PPC7D_SERIAL_0; |
102 | 103 | ||
103 | gen550_init(0, &serial_req); | 104 | gen550_init(0, &serial_req); |
104 | if (early_serial_setup(&serial_req) != 0) | 105 | if (early_serial_setup(&serial_req) != 0) |
105 | printk(KERN_ERR "Early serial init of port 0 failed\n"); | 106 | printk(KERN_ERR "Early serial init of port 0 failed\n"); |
106 | 107 | ||
107 | /* Assume early_serial_setup() doesn't modify serial_req */ | 108 | /* Assume early_serial_setup() doesn't modify serial_req */ |
108 | serial_req.line = 1; | 109 | serial_req.line = 1; |
109 | serial_req.irq = 3; | 110 | serial_req.irq = 3; |
110 | serial_req.membase = (u_char *) PPC7D_SERIAL_1; | 111 | serial_req.membase = (u_char *) PPC7D_SERIAL_1; |
111 | 112 | ||
112 | gen550_init(1, &serial_req); | 113 | gen550_init(1, &serial_req); |
113 | if (early_serial_setup(&serial_req) != 0) | 114 | if (early_serial_setup(&serial_req) != 0) |
114 | printk(KERN_ERR "Early serial init of port 1 failed\n"); | 115 | printk(KERN_ERR "Early serial init of port 1 failed\n"); |
115 | #else | 116 | #else |
116 | #error CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG has no supported CONFIG_SERIAL_XXX | 117 | #error CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG has no supported CONFIG_SERIAL_XXX |
117 | #endif | 118 | #endif |
118 | } | 119 | } |
119 | #endif /* CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG */ | 120 | #endif /* CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG */ |
120 | 121 | ||
121 | /***************************************************************************** | 122 | /***************************************************************************** |
122 | * Low-level board support code | 123 | * Low-level board support code |
123 | *****************************************************************************/ | 124 | *****************************************************************************/ |
124 | 125 | ||
125 | static unsigned long __init ppc7d_find_end_of_memory(void) | 126 | static unsigned long __init ppc7d_find_end_of_memory(void) |
126 | { | 127 | { |
127 | bd_t *bp = (bd_t *) __res; | 128 | bd_t *bp = (bd_t *) __res; |
128 | 129 | ||
129 | if (bp->bi_memsize) | 130 | if (bp->bi_memsize) |
130 | return bp->bi_memsize; | 131 | return bp->bi_memsize; |
131 | 132 | ||
132 | return (256 * 1024 * 1024); | 133 | return (256 * 1024 * 1024); |
133 | } | 134 | } |
134 | 135 | ||
135 | static void __init ppc7d_map_io(void) | 136 | static void __init ppc7d_map_io(void) |
136 | { | 137 | { |
137 | /* remove temporary mapping */ | 138 | /* remove temporary mapping */ |
138 | mtspr(SPRN_DBAT3U, 0x00000000); | 139 | mtspr(SPRN_DBAT3U, 0x00000000); |
139 | mtspr(SPRN_DBAT3L, 0x00000000); | 140 | mtspr(SPRN_DBAT3L, 0x00000000); |
140 | 141 | ||
141 | io_block_mapping(0xe8000000, 0xe8000000, 0x08000000, _PAGE_IO); | 142 | io_block_mapping(0xe8000000, 0xe8000000, 0x08000000, _PAGE_IO); |
142 | io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); | 143 | io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); |
143 | } | 144 | } |
144 | 145 | ||
145 | static void ppc7d_restart(char *cmd) | 146 | static void ppc7d_restart(char *cmd) |
146 | { | 147 | { |
147 | u32 data; | 148 | u32 data; |
148 | 149 | ||
149 | /* Disable GPP17 interrupt */ | 150 | /* Disable GPP17 interrupt */ |
150 | data = mv64x60_read(&bh, MV64x60_GPP_INTR_MASK); | 151 | data = mv64x60_read(&bh, MV64x60_GPP_INTR_MASK); |
151 | data &= ~(1 << PPC7D_RST_PIN); | 152 | data &= ~(1 << PPC7D_RST_PIN); |
152 | mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, data); | 153 | mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, data); |
153 | 154 | ||
154 | /* Configure MPP17 as GPP */ | 155 | /* Configure MPP17 as GPP */ |
155 | data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); | 156 | data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); |
156 | data &= ~(0x0000000f << 4); | 157 | data &= ~(0x0000000f << 4); |
157 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); | 158 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); |
158 | 159 | ||
159 | /* Enable pin GPP17 for output */ | 160 | /* Enable pin GPP17 for output */ |
160 | data = mv64x60_read(&bh, MV64x60_GPP_IO_CNTL); | 161 | data = mv64x60_read(&bh, MV64x60_GPP_IO_CNTL); |
161 | data |= (1 << PPC7D_RST_PIN); | 162 | data |= (1 << PPC7D_RST_PIN); |
162 | mv64x60_write(&bh, MV64x60_GPP_IO_CNTL, data); | 163 | mv64x60_write(&bh, MV64x60_GPP_IO_CNTL, data); |
163 | 164 | ||
164 | /* Toggle GPP9 pin to reset the board */ | 165 | /* Toggle GPP9 pin to reset the board */ |
165 | mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, 1 << PPC7D_RST_PIN); | 166 | mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, 1 << PPC7D_RST_PIN); |
166 | mv64x60_write(&bh, MV64x60_GPP_VALUE_SET, 1 << PPC7D_RST_PIN); | 167 | mv64x60_write(&bh, MV64x60_GPP_VALUE_SET, 1 << PPC7D_RST_PIN); |
167 | 168 | ||
168 | for (;;) ; /* Spin until reset happens */ | 169 | for (;;) ; /* Spin until reset happens */ |
169 | /* NOTREACHED */ | 170 | /* NOTREACHED */ |
170 | } | 171 | } |
171 | 172 | ||
172 | static void ppc7d_power_off(void) | 173 | static void ppc7d_power_off(void) |
173 | { | 174 | { |
174 | u32 data; | 175 | u32 data; |
175 | 176 | ||
176 | local_irq_disable(); | 177 | local_irq_disable(); |
177 | 178 | ||
178 | /* Ensure that internal MV643XX watchdog is disabled. | 179 | /* Ensure that internal MV643XX watchdog is disabled. |
179 | * The Disco watchdog uses MPP17 on this hardware. | 180 | * The Disco watchdog uses MPP17 on this hardware. |
180 | */ | 181 | */ |
181 | data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); | 182 | data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); |
182 | data &= ~(0x0000000f << 4); | 183 | data &= ~(0x0000000f << 4); |
183 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); | 184 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); |
184 | 185 | ||
185 | data = mv64x60_read(&bh, MV64x60_WDT_WDC); | 186 | data = mv64x60_read(&bh, MV64x60_WDT_WDC); |
186 | if (data & 0x80000000) { | 187 | if (data & 0x80000000) { |
187 | mv64x60_write(&bh, MV64x60_WDT_WDC, 1 << 24); | 188 | mv64x60_write(&bh, MV64x60_WDT_WDC, 1 << 24); |
188 | mv64x60_write(&bh, MV64x60_WDT_WDC, 2 << 24); | 189 | mv64x60_write(&bh, MV64x60_WDT_WDC, 2 << 24); |
189 | } | 190 | } |
190 | 191 | ||
191 | for (;;) ; /* No way to shut power off with software */ | 192 | for (;;) ; /* No way to shut power off with software */ |
192 | /* NOTREACHED */ | 193 | /* NOTREACHED */ |
193 | } | 194 | } |
194 | 195 | ||
195 | static void ppc7d_halt(void) | 196 | static void ppc7d_halt(void) |
196 | { | 197 | { |
197 | ppc7d_power_off(); | 198 | ppc7d_power_off(); |
198 | /* NOTREACHED */ | 199 | /* NOTREACHED */ |
199 | } | 200 | } |
200 | 201 | ||
201 | static unsigned long ppc7d_led_no_pulse; | 202 | static unsigned long ppc7d_led_no_pulse; |
202 | 203 | ||
203 | static int __init ppc7d_led_pulse_disable(char *str) | 204 | static int __init ppc7d_led_pulse_disable(char *str) |
204 | { | 205 | { |
205 | ppc7d_led_no_pulse = 1; | 206 | ppc7d_led_no_pulse = 1; |
206 | return 1; | 207 | return 1; |
207 | } | 208 | } |
208 | 209 | ||
209 | /* This kernel option disables the heartbeat pulsing of a board LED */ | 210 | /* This kernel option disables the heartbeat pulsing of a board LED */ |
210 | __setup("ledoff", ppc7d_led_pulse_disable); | 211 | __setup("ledoff", ppc7d_led_pulse_disable); |
211 | 212 | ||
212 | static void ppc7d_heartbeat(void) | 213 | static void ppc7d_heartbeat(void) |
213 | { | 214 | { |
214 | u32 data32; | 215 | u32 data32; |
215 | u8 data8; | 216 | u8 data8; |
216 | static int max706_wdog = 0; | 217 | static int max706_wdog = 0; |
217 | 218 | ||
218 | /* Unfortunately we can't access the LED control registers | 219 | /* Unfortunately we can't access the LED control registers |
219 | * during early init because they're on the CPLD which is the | 220 | * during early init because they're on the CPLD which is the |
220 | * other side of a PCI bridge which goes unreachable during | 221 | * other side of a PCI bridge which goes unreachable during |
221 | * PCI scan. So write the LEDs only if the MV64360 watchdog is | 222 | * PCI scan. So write the LEDs only if the MV64360 watchdog is |
222 | * enabled (i.e. userspace apps are running so kernel is up).. | 223 | * enabled (i.e. userspace apps are running so kernel is up).. |
223 | */ | 224 | */ |
224 | data32 = mv64x60_read(&bh, MV64x60_WDT_WDC); | 225 | data32 = mv64x60_read(&bh, MV64x60_WDT_WDC); |
225 | if (data32 & 0x80000000) { | 226 | if (data32 & 0x80000000) { |
226 | /* Enable MAX706 watchdog if not done already */ | 227 | /* Enable MAX706 watchdog if not done already */ |
227 | if (!max706_wdog) { | 228 | if (!max706_wdog) { |
228 | outb(3, PPC7D_CPLD_RESET); | 229 | outb(3, PPC7D_CPLD_RESET); |
229 | max706_wdog = 1; | 230 | max706_wdog = 1; |
230 | } | 231 | } |
231 | 232 | ||
232 | /* Hit the MAX706 watchdog */ | 233 | /* Hit the MAX706 watchdog */ |
233 | outb(0, PPC7D_CPLD_WATCHDOG_TRIG); | 234 | outb(0, PPC7D_CPLD_WATCHDOG_TRIG); |
234 | 235 | ||
235 | /* Pulse LED DS219 if not disabled */ | 236 | /* Pulse LED DS219 if not disabled */ |
236 | if (!ppc7d_led_no_pulse) { | 237 | if (!ppc7d_led_no_pulse) { |
237 | static int led_on = 0; | 238 | static int led_on = 0; |
238 | 239 | ||
239 | data8 = inb(PPC7D_CPLD_LEDS); | 240 | data8 = inb(PPC7D_CPLD_LEDS); |
240 | if (led_on) | 241 | if (led_on) |
241 | data8 &= ~PPC7D_CPLD_LEDS_DS219_MASK; | 242 | data8 &= ~PPC7D_CPLD_LEDS_DS219_MASK; |
242 | else | 243 | else |
243 | data8 |= PPC7D_CPLD_LEDS_DS219_MASK; | 244 | data8 |= PPC7D_CPLD_LEDS_DS219_MASK; |
244 | 245 | ||
245 | outb(data8, PPC7D_CPLD_LEDS); | 246 | outb(data8, PPC7D_CPLD_LEDS); |
246 | led_on = !led_on; | 247 | led_on = !led_on; |
247 | } | 248 | } |
248 | } | 249 | } |
249 | ppc_md.heartbeat_count = ppc_md.heartbeat_reset; | 250 | ppc_md.heartbeat_count = ppc_md.heartbeat_reset; |
250 | } | 251 | } |
251 | 252 | ||
252 | static int ppc7d_show_cpuinfo(struct seq_file *m) | 253 | static int ppc7d_show_cpuinfo(struct seq_file *m) |
253 | { | 254 | { |
254 | u8 val; | 255 | u8 val; |
255 | u8 val1, val2; | 256 | u8 val1, val2; |
256 | static int flash_sizes[4] = { 64, 32, 0, 16 }; | 257 | static int flash_sizes[4] = { 64, 32, 0, 16 }; |
257 | static int flash_banks[4] = { 4, 3, 2, 1 }; | 258 | static int flash_banks[4] = { 4, 3, 2, 1 }; |
258 | static int sdram_bank_sizes[4] = { 128, 256, 512, 1 }; | 259 | static int sdram_bank_sizes[4] = { 128, 256, 512, 1 }; |
259 | int sdram_num_banks = 2; | 260 | int sdram_num_banks = 2; |
260 | static char *pci_modes[] = { "PCI33", "PCI66", | 261 | static char *pci_modes[] = { "PCI33", "PCI66", |
261 | "Unknown", "Unknown", | 262 | "Unknown", "Unknown", |
262 | "PCIX33", "PCIX66", | 263 | "PCIX33", "PCIX66", |
263 | "PCIX100", "PCIX133" | 264 | "PCIX100", "PCIX133" |
264 | }; | 265 | }; |
265 | 266 | ||
266 | seq_printf(m, "vendor\t\t: Radstone Technology\n"); | 267 | seq_printf(m, "vendor\t\t: Radstone Technology\n"); |
267 | seq_printf(m, "machine\t\t: PPC7D\n"); | 268 | seq_printf(m, "machine\t\t: PPC7D\n"); |
268 | 269 | ||
269 | val = inb(PPC7D_CPLD_BOARD_REVISION); | 270 | val = inb(PPC7D_CPLD_BOARD_REVISION); |
270 | val1 = (val & PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK) >> 5; | 271 | val1 = (val & PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK) >> 5; |
271 | val2 = (val & PPC7D_CPLD_BOARD_REVISION_LETTER_MASK); | 272 | val2 = (val & PPC7D_CPLD_BOARD_REVISION_LETTER_MASK); |
272 | seq_printf(m, "revision\t: %hd%c%c\n", | 273 | seq_printf(m, "revision\t: %hd%c%c\n", |
273 | val1, | 274 | val1, |
274 | (val2 <= 0x18) ? 'A' + val2 : 'Y', | 275 | (val2 <= 0x18) ? 'A' + val2 : 'Y', |
275 | (val2 > 0x18) ? 'A' + (val2 - 0x19) : ' '); | 276 | (val2 > 0x18) ? 'A' + (val2 - 0x19) : ' '); |
276 | 277 | ||
277 | val = inb(PPC7D_CPLD_MOTHERBOARD_TYPE); | 278 | val = inb(PPC7D_CPLD_MOTHERBOARD_TYPE); |
278 | val1 = val & PPC7D_CPLD_MB_TYPE_PLL_MASK; | 279 | val1 = val & PPC7D_CPLD_MB_TYPE_PLL_MASK; |
279 | val2 = val & (PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK | | 280 | val2 = val & (PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK | |
280 | PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK); | 281 | PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK); |
281 | seq_printf(m, "bus speed\t: %dMHz\n", | 282 | seq_printf(m, "bus speed\t: %dMHz\n", |
282 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_133) ? 133 : | 283 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_133) ? 133 : |
283 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 : | 284 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 : |
284 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0); | 285 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0); |
285 | 286 | ||
286 | val = inb(PPC7D_CPLD_MEM_CONFIG); | 287 | val = inb(PPC7D_CPLD_MEM_CONFIG); |
287 | if (val & PPC7D_CPLD_SDRAM_BANK_NUM_MASK) sdram_num_banks--; | 288 | if (val & PPC7D_CPLD_SDRAM_BANK_NUM_MASK) sdram_num_banks--; |
288 | 289 | ||
289 | val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND); | 290 | val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND); |
290 | val1 = (val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK) >> 6; | 291 | val1 = (val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK) >> 6; |
291 | seq_printf(m, "SDRAM\t\t: %d banks of %d%c, total %d%c", | 292 | seq_printf(m, "SDRAM\t\t: %d banks of %d%c, total %d%c", |
292 | sdram_num_banks, | 293 | sdram_num_banks, |
293 | sdram_bank_sizes[val1], | 294 | sdram_bank_sizes[val1], |
294 | (sdram_bank_sizes[val1] < 128) ? 'G' : 'M', | 295 | (sdram_bank_sizes[val1] < 128) ? 'G' : 'M', |
295 | sdram_num_banks * sdram_bank_sizes[val1], | 296 | sdram_num_banks * sdram_bank_sizes[val1], |
296 | (sdram_bank_sizes[val1] < 128) ? 'G' : 'M'); | 297 | (sdram_bank_sizes[val1] < 128) ? 'G' : 'M'); |
297 | if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) { | 298 | if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) { |
298 | seq_printf(m, " [ECC %sabled]", | 299 | seq_printf(m, " [ECC %sabled]", |
299 | (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" : | 300 | (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" : |
300 | "dis"); | 301 | "dis"); |
301 | } | 302 | } |
302 | seq_printf(m, "\n"); | 303 | seq_printf(m, "\n"); |
303 | 304 | ||
304 | val1 = (val & PPC7D_CPLD_FLASH_DEV_SIZE_MASK); | 305 | val1 = (val & PPC7D_CPLD_FLASH_DEV_SIZE_MASK); |
305 | val2 = (val & PPC7D_CPLD_FLASH_BANK_NUM_MASK) >> 2; | 306 | val2 = (val & PPC7D_CPLD_FLASH_BANK_NUM_MASK) >> 2; |
306 | seq_printf(m, "FLASH\t\t: %d banks of %dM, total %dM\n", | 307 | seq_printf(m, "FLASH\t\t: %d banks of %dM, total %dM\n", |
307 | flash_banks[val2], flash_sizes[val1], | 308 | flash_banks[val2], flash_sizes[val1], |
308 | flash_banks[val2] * flash_sizes[val1]); | 309 | flash_banks[val2] * flash_sizes[val1]); |
309 | 310 | ||
310 | val = inb(PPC7D_CPLD_FLASH_WRITE_CNTL); | 311 | val = inb(PPC7D_CPLD_FLASH_WRITE_CNTL); |
311 | val1 = inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT); | 312 | val1 = inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT); |
312 | seq_printf(m, " write links\t: %s%s%s%s\n", | 313 | seq_printf(m, " write links\t: %s%s%s%s\n", |
313 | (val & PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK) ? "WRITE " : "", | 314 | (val & PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK) ? "WRITE " : "", |
314 | (val & PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK) ? "BOOT " : "", | 315 | (val & PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK) ? "BOOT " : "", |
315 | (val & PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK) ? "USER " : "", | 316 | (val & PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK) ? "USER " : "", |
316 | (val & (PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK | | 317 | (val & (PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK | |
317 | PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK | | 318 | PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK | |
318 | PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK)) == | 319 | PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK)) == |
319 | 0 ? "NONE" : ""); | 320 | 0 ? "NONE" : ""); |
320 | seq_printf(m, " write sector h/w enables: %s%s%s%s%s\n", | 321 | seq_printf(m, " write sector h/w enables: %s%s%s%s%s\n", |
321 | (val & PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK) ? "RECOVERY " : | 322 | (val & PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK) ? "RECOVERY " : |
322 | "", | 323 | "", |
323 | (val & PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK) ? "BOOT " : "", | 324 | (val & PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK) ? "BOOT " : "", |
324 | (val & PPD7D_CPLD_FLASH_CNTL_USER_WR_MASK) ? "USER " : "", | 325 | (val & PPD7D_CPLD_FLASH_CNTL_USER_WR_MASK) ? "USER " : "", |
325 | (val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) ? "NVRAM " : | 326 | (val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) ? "NVRAM " : |
326 | "", | 327 | "", |
327 | (((val & | 328 | (((val & |
328 | (PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK | | 329 | (PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK | |
329 | PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK | | 330 | PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK | |
330 | PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK)) == 0) | 331 | PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK)) == 0) |
331 | && ((val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) == | 332 | && ((val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) == |
332 | 0)) ? "NONE" : ""); | 333 | 0)) ? "NONE" : ""); |
333 | val1 = | 334 | val1 = |
334 | inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT) & | 335 | inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT) & |
335 | (PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK | | 336 | (PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK | |
336 | PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK); | 337 | PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK); |
337 | seq_printf(m, " software sector enables: %s%s%s\n", | 338 | seq_printf(m, " software sector enables: %s%s%s\n", |
338 | (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK) ? "SYSBOOT " | 339 | (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK) ? "SYSBOOT " |
339 | : "", | 340 | : "", |
340 | (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK) ? "USER " : "", | 341 | (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK) ? "USER " : "", |
341 | (val1 == 0) ? "NONE " : ""); | 342 | (val1 == 0) ? "NONE " : ""); |
342 | 343 | ||
343 | seq_printf(m, "Boot options\t: %s%s%s%s\n", | 344 | seq_printf(m, "Boot options\t: %s%s%s%s\n", |
344 | (val & PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK) ? | 345 | (val & PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK) ? |
345 | "ALTERNATE " : "", | 346 | "ALTERNATE " : "", |
346 | (val & PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK) ? "VME " : | 347 | (val & PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK) ? "VME " : |
347 | "", | 348 | "", |
348 | (val & PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK) ? "RECOVERY " | 349 | (val & PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK) ? "RECOVERY " |
349 | : "", | 350 | : "", |
350 | ((val & | 351 | ((val & |
351 | (PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK | | 352 | (PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK | |
352 | PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK | | 353 | PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK | |
353 | PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK)) == | 354 | PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK)) == |
354 | 0) ? "NONE" : ""); | 355 | 0) ? "NONE" : ""); |
355 | 356 | ||
356 | val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_1); | 357 | val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_1); |
357 | seq_printf(m, "Fitted modules\t: %s%s%s%s\n", | 358 | seq_printf(m, "Fitted modules\t: %s%s%s%s\n", |
358 | (val & PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK) ? "" : "PMC1 ", | 359 | (val & PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK) ? "" : "PMC1 ", |
359 | (val & PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK) ? "" : "PMC2 ", | 360 | (val & PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK) ? "" : "PMC2 ", |
360 | (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) ? "AFIX " : "", | 361 | (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) ? "AFIX " : "", |
361 | ((val & (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK | | 362 | ((val & (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK | |
362 | PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK | | 363 | PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK | |
363 | PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK)) == | 364 | PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK)) == |
364 | (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK | | 365 | (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK | |
365 | PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK)) ? "NONE" : ""); | 366 | PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK)) ? "NONE" : ""); |
366 | 367 | ||
367 | if (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) { | 368 | if (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) { |
368 | static const char *ids[] = { | 369 | static const char *ids[] = { |
369 | "unknown", | 370 | "unknown", |
370 | "1553 (Dual Channel)", | 371 | "1553 (Dual Channel)", |
371 | "1553 (Single Channel)", | 372 | "1553 (Single Channel)", |
372 | "8-bit SCSI + VGA", | 373 | "8-bit SCSI + VGA", |
373 | "16-bit SCSI + VGA", | 374 | "16-bit SCSI + VGA", |
374 | "1553 (Single Channel with sideband)", | 375 | "1553 (Single Channel with sideband)", |
375 | "1553 (Dual Channel with sideband)", | 376 | "1553 (Dual Channel with sideband)", |
376 | NULL | 377 | NULL |
377 | }; | 378 | }; |
378 | u8 id = __raw_readb((void *)PPC7D_AFIX_REG_BASE + 0x03); | 379 | u8 id = __raw_readb((void *)PPC7D_AFIX_REG_BASE + 0x03); |
379 | seq_printf(m, "AFIX module\t: 0x%hx [%s]\n", id, | 380 | seq_printf(m, "AFIX module\t: 0x%hx [%s]\n", id, |
380 | id < 7 ? ids[id] : "unknown"); | 381 | id < 7 ? ids[id] : "unknown"); |
381 | } | 382 | } |
382 | 383 | ||
383 | val = inb(PPC7D_CPLD_PCI_CONFIG); | 384 | val = inb(PPC7D_CPLD_PCI_CONFIG); |
384 | val1 = (val & PPC7D_CPLD_PCI_CONFIG_PCI0_MASK) >> 4; | 385 | val1 = (val & PPC7D_CPLD_PCI_CONFIG_PCI0_MASK) >> 4; |
385 | val2 = (val & PPC7D_CPLD_PCI_CONFIG_PCI1_MASK); | 386 | val2 = (val & PPC7D_CPLD_PCI_CONFIG_PCI1_MASK); |
386 | seq_printf(m, "PCI#0\t\t: %s\nPCI#1\t\t: %s\n", | 387 | seq_printf(m, "PCI#0\t\t: %s\nPCI#1\t\t: %s\n", |
387 | pci_modes[val1], pci_modes[val2]); | 388 | pci_modes[val1], pci_modes[val2]); |
388 | 389 | ||
389 | val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_2); | 390 | val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_2); |
390 | seq_printf(m, "PMC1\t\t: %s\nPMC2\t\t: %s\n", | 391 | seq_printf(m, "PMC1\t\t: %s\nPMC2\t\t: %s\n", |
391 | (val & PPC7D_CPLD_EQPT_PRES_3_PMC1_V_MASK) ? "3.3v" : "5v", | 392 | (val & PPC7D_CPLD_EQPT_PRES_3_PMC1_V_MASK) ? "3.3v" : "5v", |
392 | (val & PPC7D_CPLD_EQPT_PRES_3_PMC2_V_MASK) ? "3.3v" : "5v"); | 393 | (val & PPC7D_CPLD_EQPT_PRES_3_PMC2_V_MASK) ? "3.3v" : "5v"); |
393 | seq_printf(m, "PMC power source: %s\n", | 394 | seq_printf(m, "PMC power source: %s\n", |
394 | (val & PPC7D_CPLD_EQPT_PRES_3_PMC_POWER_MASK) ? "VME" : | 395 | (val & PPC7D_CPLD_EQPT_PRES_3_PMC_POWER_MASK) ? "VME" : |
395 | "internal"); | 396 | "internal"); |
396 | 397 | ||
397 | val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_4); | 398 | val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_4); |
398 | val2 = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_2); | 399 | val2 = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_2); |
399 | seq_printf(m, "Fit options\t: %s%s%s%s%s%s%s\n", | 400 | seq_printf(m, "Fit options\t: %s%s%s%s%s%s%s\n", |
400 | (val & PPC7D_CPLD_EQPT_PRES_4_LPT_MASK) ? "LPT " : "", | 401 | (val & PPC7D_CPLD_EQPT_PRES_4_LPT_MASK) ? "LPT " : "", |
401 | (val & PPC7D_CPLD_EQPT_PRES_4_PS2_FITTED) ? "PS2 " : "", | 402 | (val & PPC7D_CPLD_EQPT_PRES_4_PS2_FITTED) ? "PS2 " : "", |
402 | (val & PPC7D_CPLD_EQPT_PRES_4_USB2_FITTED) ? "USB2 " : "", | 403 | (val & PPC7D_CPLD_EQPT_PRES_4_USB2_FITTED) ? "USB2 " : "", |
403 | (val2 & PPC7D_CPLD_EQPT_PRES_2_UNIVERSE_MASK) ? "VME " : "", | 404 | (val2 & PPC7D_CPLD_EQPT_PRES_2_UNIVERSE_MASK) ? "VME " : "", |
404 | (val2 & PPC7D_CPLD_EQPT_PRES_2_COM36_MASK) ? "COM3-6 " : "", | 405 | (val2 & PPC7D_CPLD_EQPT_PRES_2_COM36_MASK) ? "COM3-6 " : "", |
405 | (val2 & PPC7D_CPLD_EQPT_PRES_2_GIGE_MASK) ? "eth0 " : "", | 406 | (val2 & PPC7D_CPLD_EQPT_PRES_2_GIGE_MASK) ? "eth0 " : "", |
406 | (val2 & PPC7D_CPLD_EQPT_PRES_2_DUALGIGE_MASK) ? "eth1 " : | 407 | (val2 & PPC7D_CPLD_EQPT_PRES_2_DUALGIGE_MASK) ? "eth1 " : |
407 | ""); | 408 | ""); |
408 | 409 | ||
409 | val = inb(PPC7D_CPLD_ID_LINK); | 410 | val = inb(PPC7D_CPLD_ID_LINK); |
410 | val1 = val & (PPC7D_CPLD_ID_LINK_E6_MASK | | 411 | val1 = val & (PPC7D_CPLD_ID_LINK_E6_MASK | |
411 | PPC7D_CPLD_ID_LINK_E7_MASK | | 412 | PPC7D_CPLD_ID_LINK_E7_MASK | |
412 | PPC7D_CPLD_ID_LINK_E12_MASK | | 413 | PPC7D_CPLD_ID_LINK_E12_MASK | |
413 | PPC7D_CPLD_ID_LINK_E13_MASK); | 414 | PPC7D_CPLD_ID_LINK_E13_MASK); |
414 | 415 | ||
415 | val = inb(PPC7D_CPLD_FLASH_WRITE_CNTL) & | 416 | val = inb(PPC7D_CPLD_FLASH_WRITE_CNTL) & |
416 | (PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK | | 417 | (PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK | |
417 | PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK | | 418 | PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK | |
418 | PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK); | 419 | PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK); |
419 | 420 | ||
420 | seq_printf(m, "Board links present: %s%s%s%s%s%s%s%s\n", | 421 | seq_printf(m, "Board links present: %s%s%s%s%s%s%s%s\n", |
421 | (val1 & PPC7D_CPLD_ID_LINK_E6_MASK) ? "E6 " : "", | 422 | (val1 & PPC7D_CPLD_ID_LINK_E6_MASK) ? "E6 " : "", |
422 | (val1 & PPC7D_CPLD_ID_LINK_E7_MASK) ? "E7 " : "", | 423 | (val1 & PPC7D_CPLD_ID_LINK_E7_MASK) ? "E7 " : "", |
423 | (val & PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK) ? "E9 " : "", | 424 | (val & PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK) ? "E9 " : "", |
424 | (val & PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK) ? "E10 " : "", | 425 | (val & PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK) ? "E10 " : "", |
425 | (val & PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK) ? "E11 " : "", | 426 | (val & PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK) ? "E11 " : "", |
426 | (val1 & PPC7D_CPLD_ID_LINK_E12_MASK) ? "E12 " : "", | 427 | (val1 & PPC7D_CPLD_ID_LINK_E12_MASK) ? "E12 " : "", |
427 | (val1 & PPC7D_CPLD_ID_LINK_E13_MASK) ? "E13 " : "", | 428 | (val1 & PPC7D_CPLD_ID_LINK_E13_MASK) ? "E13 " : "", |
428 | ((val == 0) && (val1 == 0)) ? "NONE" : ""); | 429 | ((val == 0) && (val1 == 0)) ? "NONE" : ""); |
429 | 430 | ||
430 | val = inb(PPC7D_CPLD_WDOG_RESETSW_MASK); | 431 | val = inb(PPC7D_CPLD_WDOG_RESETSW_MASK); |
431 | seq_printf(m, "Front panel reset switch: %sabled\n", | 432 | seq_printf(m, "Front panel reset switch: %sabled\n", |
432 | (val & PPC7D_CPLD_WDOG_RESETSW_MASK) ? "dis" : "en"); | 433 | (val & PPC7D_CPLD_WDOG_RESETSW_MASK) ? "dis" : "en"); |
433 | 434 | ||
434 | return 0; | 435 | return 0; |
435 | } | 436 | } |
436 | 437 | ||
437 | static void __init ppc7d_calibrate_decr(void) | 438 | static void __init ppc7d_calibrate_decr(void) |
438 | { | 439 | { |
439 | ulong freq; | 440 | ulong freq; |
440 | 441 | ||
441 | freq = 100000000 / 4; | 442 | freq = 100000000 / 4; |
442 | 443 | ||
443 | pr_debug("time_init: decrementer frequency = %lu.%.6lu MHz\n", | 444 | pr_debug("time_init: decrementer frequency = %lu.%.6lu MHz\n", |
444 | freq / 1000000, freq % 1000000); | 445 | freq / 1000000, freq % 1000000); |
445 | 446 | ||
446 | tb_ticks_per_jiffy = freq / HZ; | 447 | tb_ticks_per_jiffy = freq / HZ; |
447 | tb_to_us = mulhwu_scale_factor(freq, 1000000); | 448 | tb_to_us = mulhwu_scale_factor(freq, 1000000); |
448 | } | 449 | } |
449 | 450 | ||
450 | /***************************************************************************** | 451 | /***************************************************************************** |
451 | * Interrupt stuff | 452 | * Interrupt stuff |
452 | *****************************************************************************/ | 453 | *****************************************************************************/ |
453 | 454 | ||
454 | static irqreturn_t ppc7d_i8259_intr(int irq, void *dev_id) | 455 | static irqreturn_t ppc7d_i8259_intr(int irq, void *dev_id) |
455 | { | 456 | { |
456 | u32 temp = mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE); | 457 | u32 temp = mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE); |
457 | if (temp & (1 << 28)) { | 458 | if (temp & (1 << 28)) { |
458 | i8259_irq(); | 459 | i8259_irq(); |
459 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, temp & (~(1 << 28))); | 460 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, temp & (~(1 << 28))); |
460 | return IRQ_HANDLED; | 461 | return IRQ_HANDLED; |
461 | } | 462 | } |
462 | 463 | ||
463 | return IRQ_NONE; | 464 | return IRQ_NONE; |
464 | } | 465 | } |
465 | 466 | ||
466 | /* | 467 | /* |
467 | * Each interrupt cause is assigned an IRQ number. | 468 | * Each interrupt cause is assigned an IRQ number. |
468 | * Southbridge has 16*2 (two 8259's) interrupts. | 469 | * Southbridge has 16*2 (two 8259's) interrupts. |
469 | * Discovery-II has 96 interrupts (cause-hi, cause-lo, gpp x 32). | 470 | * Discovery-II has 96 interrupts (cause-hi, cause-lo, gpp x 32). |
470 | * If multiple interrupts are pending, get_irq() returns the | 471 | * If multiple interrupts are pending, get_irq() returns the |
471 | * lowest pending irq number first. | 472 | * lowest pending irq number first. |
472 | * | 473 | * |
473 | * | 474 | * |
474 | * IRQ # Source Trig Active | 475 | * IRQ # Source Trig Active |
475 | * ============================================================= | 476 | * ============================================================= |
476 | * | 477 | * |
477 | * Southbridge | 478 | * Southbridge |
478 | * ----------- | 479 | * ----------- |
479 | * IRQ # Source Trig | 480 | * IRQ # Source Trig |
480 | * ============================================================= | 481 | * ============================================================= |
481 | * 0 ISA High Resolution Counter Edge | 482 | * 0 ISA High Resolution Counter Edge |
482 | * 1 Keyboard Edge | 483 | * 1 Keyboard Edge |
483 | * 2 Cascade From (IRQ 8-15) Edge | 484 | * 2 Cascade From (IRQ 8-15) Edge |
484 | * 3 Com 2 (Uart 2) Edge | 485 | * 3 Com 2 (Uart 2) Edge |
485 | * 4 Com 1 (Uart 1) Edge | 486 | * 4 Com 1 (Uart 1) Edge |
486 | * 5 PCI Int D/AFIX IRQZ ID4 (2,7) Level | 487 | * 5 PCI Int D/AFIX IRQZ ID4 (2,7) Level |
487 | * 6 GPIO Level | 488 | * 6 GPIO Level |
488 | * 7 LPT Edge | 489 | * 7 LPT Edge |
489 | * 8 RTC Alarm Edge | 490 | * 8 RTC Alarm Edge |
490 | * 9 PCI Int A/PMC 2/AFIX IRQW ID1 (2,0) Level | 491 | * 9 PCI Int A/PMC 2/AFIX IRQW ID1 (2,0) Level |
491 | * 10 PCI Int B/PMC 1/AFIX IRQX ID2 (2,1) Level | 492 | * 10 PCI Int B/PMC 1/AFIX IRQX ID2 (2,1) Level |
492 | * 11 USB2 Level | 493 | * 11 USB2 Level |
493 | * 12 Mouse Edge | 494 | * 12 Mouse Edge |
494 | * 13 Reserved internally by Ali M1535+ | 495 | * 13 Reserved internally by Ali M1535+ |
495 | * 14 PCI Int C/VME/AFIX IRQY ID3 (2,6) Level | 496 | * 14 PCI Int C/VME/AFIX IRQY ID3 (2,6) Level |
496 | * 15 COM 5/6 Level | 497 | * 15 COM 5/6 Level |
497 | * | 498 | * |
498 | * 16..112 Discovery-II... | 499 | * 16..112 Discovery-II... |
499 | * | 500 | * |
500 | * MPP28 Southbridge Edge High | 501 | * MPP28 Southbridge Edge High |
501 | * | 502 | * |
502 | * | 503 | * |
503 | * Interrupts are cascaded through to the Discovery-II. | 504 | * Interrupts are cascaded through to the Discovery-II. |
504 | * | 505 | * |
505 | * PCI --- | 506 | * PCI --- |
506 | * \ | 507 | * \ |
507 | * CPLD --> ALI1535 -------> DISCOVERY-II | 508 | * CPLD --> ALI1535 -------> DISCOVERY-II |
508 | * INTF MPP28 | 509 | * INTF MPP28 |
509 | */ | 510 | */ |
510 | static void __init ppc7d_init_irq(void) | 511 | static void __init ppc7d_init_irq(void) |
511 | { | 512 | { |
512 | int irq; | 513 | int irq; |
513 | 514 | ||
514 | pr_debug("%s\n", __FUNCTION__); | 515 | pr_debug("%s\n", __FUNCTION__); |
515 | i8259_init(0, 0); | 516 | i8259_init(0, 0); |
516 | mv64360_init_irq(); | 517 | mv64360_init_irq(); |
517 | 518 | ||
518 | /* IRQs 5,6,9,10,11,14,15 are level sensitive */ | 519 | /* IRQs 5,6,9,10,11,14,15 are level sensitive */ |
519 | irq_desc[5].status |= IRQ_LEVEL; | 520 | irq_desc[5].status |= IRQ_LEVEL; |
520 | irq_desc[6].status |= IRQ_LEVEL; | 521 | irq_desc[6].status |= IRQ_LEVEL; |
521 | irq_desc[9].status |= IRQ_LEVEL; | 522 | irq_desc[9].status |= IRQ_LEVEL; |
522 | irq_desc[10].status |= IRQ_LEVEL; | 523 | irq_desc[10].status |= IRQ_LEVEL; |
523 | irq_desc[11].status |= IRQ_LEVEL; | 524 | irq_desc[11].status |= IRQ_LEVEL; |
524 | irq_desc[14].status |= IRQ_LEVEL; | 525 | irq_desc[14].status |= IRQ_LEVEL; |
525 | irq_desc[15].status |= IRQ_LEVEL; | 526 | irq_desc[15].status |= IRQ_LEVEL; |
526 | 527 | ||
527 | /* GPP28 is edge triggered */ | 528 | /* GPP28 is edge triggered */ |
528 | irq_desc[mv64360_irq_base + MV64x60_IRQ_GPP28].status &= ~IRQ_LEVEL; | 529 | irq_desc[mv64360_irq_base + MV64x60_IRQ_GPP28].status &= ~IRQ_LEVEL; |
529 | } | 530 | } |
530 | 531 | ||
531 | static u32 ppc7d_irq_canonicalize(u32 irq) | 532 | static u32 ppc7d_irq_canonicalize(u32 irq) |
532 | { | 533 | { |
533 | if ((irq >= 16) && (irq < (16 + 96))) | 534 | if ((irq >= 16) && (irq < (16 + 96))) |
534 | irq -= 16; | 535 | irq -= 16; |
535 | 536 | ||
536 | return irq; | 537 | return irq; |
537 | } | 538 | } |
538 | 539 | ||
539 | static int ppc7d_get_irq(void) | 540 | static int ppc7d_get_irq(void) |
540 | { | 541 | { |
541 | int irq; | 542 | int irq; |
542 | 543 | ||
543 | irq = mv64360_get_irq(); | 544 | irq = mv64360_get_irq(); |
544 | if (irq == (mv64360_irq_base + MV64x60_IRQ_GPP28)) | 545 | if (irq == (mv64360_irq_base + MV64x60_IRQ_GPP28)) |
545 | irq = i8259_irq(); | 546 | irq = i8259_irq(); |
546 | return irq; | 547 | return irq; |
547 | } | 548 | } |
548 | 549 | ||
549 | /* | 550 | /* |
550 | * 9 PCI Int A/PMC 2/AFIX IRQW ID1 (2,0) Level | 551 | * 9 PCI Int A/PMC 2/AFIX IRQW ID1 (2,0) Level |
551 | * 10 PCI Int B/PMC 1/AFIX IRQX ID2 (2,1) Level | 552 | * 10 PCI Int B/PMC 1/AFIX IRQX ID2 (2,1) Level |
552 | * 14 PCI Int C/VME/AFIX IRQY ID3 (2,6) Level | 553 | * 14 PCI Int C/VME/AFIX IRQY ID3 (2,6) Level |
553 | * 5 PCI Int D/AFIX IRQZ ID4 (2,7) Level | 554 | * 5 PCI Int D/AFIX IRQZ ID4 (2,7) Level |
554 | */ | 555 | */ |
555 | static int __init ppc7d_map_irq(struct pci_dev *dev, unsigned char idsel, | 556 | static int __init ppc7d_map_irq(struct pci_dev *dev, unsigned char idsel, |
556 | unsigned char pin) | 557 | unsigned char pin) |
557 | { | 558 | { |
558 | static const char pci_irq_table[][4] = | 559 | static const char pci_irq_table[][4] = |
559 | /* | 560 | /* |
560 | * PCI IDSEL/INTPIN->INTLINE | 561 | * PCI IDSEL/INTPIN->INTLINE |
561 | * A B C D | 562 | * A B C D |
562 | */ | 563 | */ |
563 | { | 564 | { |
564 | {10, 14, 5, 9}, /* IDSEL 10 - PMC2 / AFIX IRQW */ | 565 | {10, 14, 5, 9}, /* IDSEL 10 - PMC2 / AFIX IRQW */ |
565 | {9, 10, 14, 5}, /* IDSEL 11 - PMC1 / AFIX IRQX */ | 566 | {9, 10, 14, 5}, /* IDSEL 11 - PMC1 / AFIX IRQX */ |
566 | {5, 9, 10, 14}, /* IDSEL 12 - AFIX IRQY */ | 567 | {5, 9, 10, 14}, /* IDSEL 12 - AFIX IRQY */ |
567 | {14, 5, 9, 10}, /* IDSEL 13 - AFIX IRQZ */ | 568 | {14, 5, 9, 10}, /* IDSEL 13 - AFIX IRQZ */ |
568 | }; | 569 | }; |
569 | const long min_idsel = 10, max_idsel = 14, irqs_per_slot = 4; | 570 | const long min_idsel = 10, max_idsel = 14, irqs_per_slot = 4; |
570 | 571 | ||
571 | pr_debug("%s: %04x/%04x/%x: idsel=%hx pin=%hu\n", __FUNCTION__, | 572 | pr_debug("%s: %04x/%04x/%x: idsel=%hx pin=%hu\n", __FUNCTION__, |
572 | dev->vendor, dev->device, PCI_FUNC(dev->devfn), idsel, pin); | 573 | dev->vendor, dev->device, PCI_FUNC(dev->devfn), idsel, pin); |
573 | 574 | ||
574 | return PCI_IRQ_TABLE_LOOKUP; | 575 | return PCI_IRQ_TABLE_LOOKUP; |
575 | } | 576 | } |
576 | 577 | ||
577 | void __init ppc7d_intr_setup(void) | 578 | void __init ppc7d_intr_setup(void) |
578 | { | 579 | { |
579 | u32 data; | 580 | u32 data; |
580 | 581 | ||
581 | /* | 582 | /* |
582 | * Define GPP 28 interrupt polarity as active high | 583 | * Define GPP 28 interrupt polarity as active high |
583 | * input signal and level triggered | 584 | * input signal and level triggered |
584 | */ | 585 | */ |
585 | data = mv64x60_read(&bh, MV64x60_GPP_LEVEL_CNTL); | 586 | data = mv64x60_read(&bh, MV64x60_GPP_LEVEL_CNTL); |
586 | data &= ~(1 << 28); | 587 | data &= ~(1 << 28); |
587 | mv64x60_write(&bh, MV64x60_GPP_LEVEL_CNTL, data); | 588 | mv64x60_write(&bh, MV64x60_GPP_LEVEL_CNTL, data); |
588 | data = mv64x60_read(&bh, MV64x60_GPP_IO_CNTL); | 589 | data = mv64x60_read(&bh, MV64x60_GPP_IO_CNTL); |
589 | data &= ~(1 << 28); | 590 | data &= ~(1 << 28); |
590 | mv64x60_write(&bh, MV64x60_GPP_IO_CNTL, data); | 591 | mv64x60_write(&bh, MV64x60_GPP_IO_CNTL, data); |
591 | 592 | ||
592 | /* Config GPP intr ctlr to respond to level trigger */ | 593 | /* Config GPP intr ctlr to respond to level trigger */ |
593 | data = mv64x60_read(&bh, MV64x60_COMM_ARBITER_CNTL); | 594 | data = mv64x60_read(&bh, MV64x60_COMM_ARBITER_CNTL); |
594 | data |= (1 << 10); | 595 | data |= (1 << 10); |
595 | mv64x60_write(&bh, MV64x60_COMM_ARBITER_CNTL, data); | 596 | mv64x60_write(&bh, MV64x60_COMM_ARBITER_CNTL, data); |
596 | 597 | ||
597 | /* XXXX Erranum FEr PCI-#8 */ | 598 | /* XXXX Erranum FEr PCI-#8 */ |
598 | data = mv64x60_read(&bh, MV64x60_PCI0_CMD); | 599 | data = mv64x60_read(&bh, MV64x60_PCI0_CMD); |
599 | data &= ~((1 << 5) | (1 << 9)); | 600 | data &= ~((1 << 5) | (1 << 9)); |
600 | mv64x60_write(&bh, MV64x60_PCI0_CMD, data); | 601 | mv64x60_write(&bh, MV64x60_PCI0_CMD, data); |
601 | data = mv64x60_read(&bh, MV64x60_PCI1_CMD); | 602 | data = mv64x60_read(&bh, MV64x60_PCI1_CMD); |
602 | data &= ~((1 << 5) | (1 << 9)); | 603 | data &= ~((1 << 5) | (1 << 9)); |
603 | mv64x60_write(&bh, MV64x60_PCI1_CMD, data); | 604 | mv64x60_write(&bh, MV64x60_PCI1_CMD, data); |
604 | 605 | ||
605 | /* | 606 | /* |
606 | * Dismiss and then enable interrupt on GPP interrupt cause | 607 | * Dismiss and then enable interrupt on GPP interrupt cause |
607 | * for CPU #0 | 608 | * for CPU #0 |
608 | */ | 609 | */ |
609 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~(1 << 28)); | 610 | mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~(1 << 28)); |
610 | data = mv64x60_read(&bh, MV64x60_GPP_INTR_MASK); | 611 | data = mv64x60_read(&bh, MV64x60_GPP_INTR_MASK); |
611 | data |= (1 << 28); | 612 | data |= (1 << 28); |
612 | mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, data); | 613 | mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, data); |
613 | 614 | ||
614 | /* | 615 | /* |
615 | * Dismiss and then enable interrupt on CPU #0 high cause reg | 616 | * Dismiss and then enable interrupt on CPU #0 high cause reg |
616 | * BIT27 summarizes GPP interrupts 23-31 | 617 | * BIT27 summarizes GPP interrupts 23-31 |
617 | */ | 618 | */ |
618 | mv64x60_write(&bh, MV64360_IC_MAIN_CAUSE_HI, ~(1 << 27)); | 619 | mv64x60_write(&bh, MV64360_IC_MAIN_CAUSE_HI, ~(1 << 27)); |
619 | data = mv64x60_read(&bh, MV64360_IC_CPU0_INTR_MASK_HI); | 620 | data = mv64x60_read(&bh, MV64360_IC_CPU0_INTR_MASK_HI); |
620 | data |= (1 << 27); | 621 | data |= (1 << 27); |
621 | mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI, data); | 622 | mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI, data); |
622 | } | 623 | } |
623 | 624 | ||
624 | /***************************************************************************** | 625 | /***************************************************************************** |
625 | * Platform device data fixup routines. | 626 | * Platform device data fixup routines. |
626 | *****************************************************************************/ | 627 | *****************************************************************************/ |
627 | 628 | ||
628 | #if defined(CONFIG_SERIAL_MPSC) | 629 | #if defined(CONFIG_SERIAL_MPSC) |
629 | static void __init ppc7d_fixup_mpsc_pdata(struct platform_device *pdev) | 630 | static void __init ppc7d_fixup_mpsc_pdata(struct platform_device *pdev) |
630 | { | 631 | { |
631 | struct mpsc_pdata *pdata; | 632 | struct mpsc_pdata *pdata; |
632 | 633 | ||
633 | pdata = (struct mpsc_pdata *)pdev->dev.platform_data; | 634 | pdata = (struct mpsc_pdata *)pdev->dev.platform_data; |
634 | 635 | ||
635 | pdata->max_idle = 40; | 636 | pdata->max_idle = 40; |
636 | pdata->default_baud = PPC7D_DEFAULT_BAUD; | 637 | pdata->default_baud = PPC7D_DEFAULT_BAUD; |
637 | pdata->brg_clk_src = PPC7D_MPSC_CLK_SRC; | 638 | pdata->brg_clk_src = PPC7D_MPSC_CLK_SRC; |
638 | pdata->brg_clk_freq = PPC7D_MPSC_CLK_FREQ; | 639 | pdata->brg_clk_freq = PPC7D_MPSC_CLK_FREQ; |
639 | 640 | ||
640 | return; | 641 | return; |
641 | } | 642 | } |
642 | #endif | 643 | #endif |
643 | 644 | ||
644 | #if defined(CONFIG_MV643XX_ETH) | 645 | #if defined(CONFIG_MV643XX_ETH) |
645 | static void __init ppc7d_fixup_eth_pdata(struct platform_device *pdev) | 646 | static void __init ppc7d_fixup_eth_pdata(struct platform_device *pdev) |
646 | { | 647 | { |
647 | struct mv643xx_eth_platform_data *eth_pd; | 648 | struct mv643xx_eth_platform_data *eth_pd; |
648 | static u16 phy_addr[] = { | 649 | static u16 phy_addr[] = { |
649 | PPC7D_ETH0_PHY_ADDR, | 650 | PPC7D_ETH0_PHY_ADDR, |
650 | PPC7D_ETH1_PHY_ADDR, | 651 | PPC7D_ETH1_PHY_ADDR, |
651 | PPC7D_ETH2_PHY_ADDR, | 652 | PPC7D_ETH2_PHY_ADDR, |
652 | }; | 653 | }; |
653 | int i; | 654 | int i; |
654 | 655 | ||
655 | eth_pd = pdev->dev.platform_data; | 656 | eth_pd = pdev->dev.platform_data; |
656 | eth_pd->force_phy_addr = 1; | 657 | eth_pd->force_phy_addr = 1; |
657 | eth_pd->phy_addr = phy_addr[pdev->id]; | 658 | eth_pd->phy_addr = phy_addr[pdev->id]; |
658 | eth_pd->tx_queue_size = PPC7D_ETH_TX_QUEUE_SIZE; | 659 | eth_pd->tx_queue_size = PPC7D_ETH_TX_QUEUE_SIZE; |
659 | eth_pd->rx_queue_size = PPC7D_ETH_RX_QUEUE_SIZE; | 660 | eth_pd->rx_queue_size = PPC7D_ETH_RX_QUEUE_SIZE; |
660 | 661 | ||
661 | /* Adjust IRQ by mv64360_irq_base */ | 662 | /* Adjust IRQ by mv64360_irq_base */ |
662 | for (i = 0; i < pdev->num_resources; i++) { | 663 | for (i = 0; i < pdev->num_resources; i++) { |
663 | struct resource *r = &pdev->resource[i]; | 664 | struct resource *r = &pdev->resource[i]; |
664 | 665 | ||
665 | if (r->flags & IORESOURCE_IRQ) { | 666 | if (r->flags & IORESOURCE_IRQ) { |
666 | r->start += mv64360_irq_base; | 667 | r->start += mv64360_irq_base; |
667 | r->end += mv64360_irq_base; | 668 | r->end += mv64360_irq_base; |
668 | pr_debug("%s, uses IRQ %d\n", pdev->name, | 669 | pr_debug("%s, uses IRQ %d\n", pdev->name, |
669 | (int)r->start); | 670 | (int)r->start); |
670 | } | 671 | } |
671 | } | 672 | } |
672 | 673 | ||
673 | } | 674 | } |
674 | #endif | 675 | #endif |
675 | 676 | ||
676 | #if defined(CONFIG_I2C_MV64XXX) | 677 | #if defined(CONFIG_I2C_MV64XXX) |
677 | static void __init | 678 | static void __init |
678 | ppc7d_fixup_i2c_pdata(struct platform_device *pdev) | 679 | ppc7d_fixup_i2c_pdata(struct platform_device *pdev) |
679 | { | 680 | { |
680 | struct mv64xxx_i2c_pdata *pdata; | 681 | struct mv64xxx_i2c_pdata *pdata; |
681 | int i; | 682 | int i; |
682 | 683 | ||
683 | pdata = pdev->dev.platform_data; | 684 | pdata = pdev->dev.platform_data; |
684 | if (pdata == NULL) { | 685 | if (pdata == NULL) { |
685 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 686 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
686 | if (pdata == NULL) | 687 | if (pdata == NULL) |
687 | return; | 688 | return; |
688 | 689 | ||
689 | pdev->dev.platform_data = pdata; | 690 | pdev->dev.platform_data = pdata; |
690 | } | 691 | } |
691 | 692 | ||
692 | /* divisors M=8, N=3 for 100kHz I2C from 133MHz system clock */ | 693 | /* divisors M=8, N=3 for 100kHz I2C from 133MHz system clock */ |
693 | pdata->freq_m = 8; | 694 | pdata->freq_m = 8; |
694 | pdata->freq_n = 3; | 695 | pdata->freq_n = 3; |
695 | pdata->timeout = 500; | 696 | pdata->timeout = 500; |
696 | pdata->retries = 3; | 697 | pdata->retries = 3; |
697 | 698 | ||
698 | /* Adjust IRQ by mv64360_irq_base */ | 699 | /* Adjust IRQ by mv64360_irq_base */ |
699 | for (i = 0; i < pdev->num_resources; i++) { | 700 | for (i = 0; i < pdev->num_resources; i++) { |
700 | struct resource *r = &pdev->resource[i]; | 701 | struct resource *r = &pdev->resource[i]; |
701 | 702 | ||
702 | if (r->flags & IORESOURCE_IRQ) { | 703 | if (r->flags & IORESOURCE_IRQ) { |
703 | r->start += mv64360_irq_base; | 704 | r->start += mv64360_irq_base; |
704 | r->end += mv64360_irq_base; | 705 | r->end += mv64360_irq_base; |
705 | pr_debug("%s, uses IRQ %d\n", pdev->name, (int) r->start); | 706 | pr_debug("%s, uses IRQ %d\n", pdev->name, (int) r->start); |
706 | } | 707 | } |
707 | } | 708 | } |
708 | } | 709 | } |
709 | #endif | 710 | #endif |
710 | 711 | ||
711 | static int ppc7d_platform_notify(struct device *dev) | 712 | static int ppc7d_platform_notify(struct device *dev) |
712 | { | 713 | { |
713 | static struct { | 714 | static struct { |
714 | char *bus_id; | 715 | char *bus_id; |
715 | void ((*rtn) (struct platform_device * pdev)); | 716 | void ((*rtn) (struct platform_device * pdev)); |
716 | } dev_map[] = { | 717 | } dev_map[] = { |
717 | #if defined(CONFIG_SERIAL_MPSC) | 718 | #if defined(CONFIG_SERIAL_MPSC) |
718 | { MPSC_CTLR_NAME ".0", ppc7d_fixup_mpsc_pdata }, | 719 | { MPSC_CTLR_NAME ".0", ppc7d_fixup_mpsc_pdata }, |
719 | { MPSC_CTLR_NAME ".1", ppc7d_fixup_mpsc_pdata }, | 720 | { MPSC_CTLR_NAME ".1", ppc7d_fixup_mpsc_pdata }, |
720 | #endif | 721 | #endif |
721 | #if defined(CONFIG_MV643XX_ETH) | 722 | #if defined(CONFIG_MV643XX_ETH) |
722 | { MV643XX_ETH_NAME ".0", ppc7d_fixup_eth_pdata }, | 723 | { MV643XX_ETH_NAME ".0", ppc7d_fixup_eth_pdata }, |
723 | { MV643XX_ETH_NAME ".1", ppc7d_fixup_eth_pdata }, | 724 | { MV643XX_ETH_NAME ".1", ppc7d_fixup_eth_pdata }, |
724 | { MV643XX_ETH_NAME ".2", ppc7d_fixup_eth_pdata }, | 725 | { MV643XX_ETH_NAME ".2", ppc7d_fixup_eth_pdata }, |
725 | #endif | 726 | #endif |
726 | #if defined(CONFIG_I2C_MV64XXX) | 727 | #if defined(CONFIG_I2C_MV64XXX) |
727 | { MV64XXX_I2C_CTLR_NAME ".0", ppc7d_fixup_i2c_pdata }, | 728 | { MV64XXX_I2C_CTLR_NAME ".0", ppc7d_fixup_i2c_pdata }, |
728 | #endif | 729 | #endif |
729 | }; | 730 | }; |
730 | struct platform_device *pdev; | 731 | struct platform_device *pdev; |
731 | int i; | 732 | int i; |
732 | 733 | ||
733 | if (dev && dev->bus_id) | 734 | if (dev && dev->bus_id) |
734 | for (i = 0; i < ARRAY_SIZE(dev_map); i++) | 735 | for (i = 0; i < ARRAY_SIZE(dev_map); i++) |
735 | if (!strncmp(dev->bus_id, dev_map[i].bus_id, | 736 | if (!strncmp(dev->bus_id, dev_map[i].bus_id, |
736 | BUS_ID_SIZE)) { | 737 | BUS_ID_SIZE)) { |
737 | 738 | ||
738 | pdev = container_of(dev, | 739 | pdev = container_of(dev, |
739 | struct platform_device, | 740 | struct platform_device, |
740 | dev); | 741 | dev); |
741 | dev_map[i].rtn(pdev); | 742 | dev_map[i].rtn(pdev); |
742 | } | 743 | } |
743 | 744 | ||
744 | return 0; | 745 | return 0; |
745 | } | 746 | } |
746 | 747 | ||
747 | /***************************************************************************** | 748 | /***************************************************************************** |
748 | * PCI device fixups. | 749 | * PCI device fixups. |
749 | * These aren't really fixups per se. They are used to init devices as they | 750 | * These aren't really fixups per se. They are used to init devices as they |
750 | * are found during PCI scan. | 751 | * are found during PCI scan. |
751 | * | 752 | * |
752 | * The PPC7D has an HB8 PCI-X bridge which must be set up during a PCI | 753 | * The PPC7D has an HB8 PCI-X bridge which must be set up during a PCI |
753 | * scan in order to find other devices on its secondary side. | 754 | * scan in order to find other devices on its secondary side. |
754 | *****************************************************************************/ | 755 | *****************************************************************************/ |
755 | 756 | ||
756 | static void __init ppc7d_fixup_hb8(struct pci_dev *dev) | 757 | static void __init ppc7d_fixup_hb8(struct pci_dev *dev) |
757 | { | 758 | { |
758 | u16 val16; | 759 | u16 val16; |
759 | 760 | ||
760 | if (dev->bus->number == 0) { | 761 | if (dev->bus->number == 0) { |
761 | pr_debug("PCI: HB8 init\n"); | 762 | pr_debug("PCI: HB8 init\n"); |
762 | 763 | ||
763 | pci_write_config_byte(dev, 0x1c, | 764 | pci_write_config_byte(dev, 0x1c, |
764 | ((PPC7D_PCI0_IO_START_PCI_ADDR & 0xf000) | 765 | ((PPC7D_PCI0_IO_START_PCI_ADDR & 0xf000) |
765 | >> 8) | 0x01); | 766 | >> 8) | 0x01); |
766 | pci_write_config_byte(dev, 0x1d, | 767 | pci_write_config_byte(dev, 0x1d, |
767 | (((PPC7D_PCI0_IO_START_PCI_ADDR + | 768 | (((PPC7D_PCI0_IO_START_PCI_ADDR + |
768 | PPC7D_PCI0_IO_SIZE - | 769 | PPC7D_PCI0_IO_SIZE - |
769 | 1) & 0xf000) >> 8) | 0x01); | 770 | 1) & 0xf000) >> 8) | 0x01); |
770 | pci_write_config_word(dev, 0x30, | 771 | pci_write_config_word(dev, 0x30, |
771 | PPC7D_PCI0_IO_START_PCI_ADDR >> 16); | 772 | PPC7D_PCI0_IO_START_PCI_ADDR >> 16); |
772 | pci_write_config_word(dev, 0x32, | 773 | pci_write_config_word(dev, 0x32, |
773 | ((PPC7D_PCI0_IO_START_PCI_ADDR + | 774 | ((PPC7D_PCI0_IO_START_PCI_ADDR + |
774 | PPC7D_PCI0_IO_SIZE - | 775 | PPC7D_PCI0_IO_SIZE - |
775 | 1) >> 16) & 0xffff); | 776 | 1) >> 16) & 0xffff); |
776 | 777 | ||
777 | pci_write_config_word(dev, 0x20, | 778 | pci_write_config_word(dev, 0x20, |
778 | PPC7D_PCI0_MEM0_START_PCI_LO_ADDR >> 16); | 779 | PPC7D_PCI0_MEM0_START_PCI_LO_ADDR >> 16); |
779 | pci_write_config_word(dev, 0x22, | 780 | pci_write_config_word(dev, 0x22, |
780 | ((PPC7D_PCI0_MEM0_START_PCI_LO_ADDR + | 781 | ((PPC7D_PCI0_MEM0_START_PCI_LO_ADDR + |
781 | PPC7D_PCI0_MEM0_SIZE - | 782 | PPC7D_PCI0_MEM0_SIZE - |
782 | 1) >> 16) & 0xffff); | 783 | 1) >> 16) & 0xffff); |
783 | pci_write_config_word(dev, 0x24, 0); | 784 | pci_write_config_word(dev, 0x24, 0); |
784 | pci_write_config_word(dev, 0x26, 0); | 785 | pci_write_config_word(dev, 0x26, 0); |
785 | pci_write_config_dword(dev, 0x28, 0); | 786 | pci_write_config_dword(dev, 0x28, 0); |
786 | pci_write_config_dword(dev, 0x2c, 0); | 787 | pci_write_config_dword(dev, 0x2c, 0); |
787 | 788 | ||
788 | pci_read_config_word(dev, 0x3e, &val16); | 789 | pci_read_config_word(dev, 0x3e, &val16); |
789 | val16 |= ((1 << 5) | (1 << 1)); /* signal master aborts and | 790 | val16 |= ((1 << 5) | (1 << 1)); /* signal master aborts and |
790 | * SERR to primary | 791 | * SERR to primary |
791 | */ | 792 | */ |
792 | val16 &= ~(1 << 2); /* ISA disable, so all ISA | 793 | val16 &= ~(1 << 2); /* ISA disable, so all ISA |
793 | * ports forwarded to secondary | 794 | * ports forwarded to secondary |
794 | */ | 795 | */ |
795 | pci_write_config_word(dev, 0x3e, val16); | 796 | pci_write_config_word(dev, 0x3e, val16); |
796 | } | 797 | } |
797 | } | 798 | } |
798 | 799 | ||
799 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0028, ppc7d_fixup_hb8); | 800 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0028, ppc7d_fixup_hb8); |
800 | 801 | ||
801 | /* This should perhaps be a separate driver as we're actually initializing | 802 | /* This should perhaps be a separate driver as we're actually initializing |
802 | * the chip for this board here. It's hardly a fixup... | 803 | * the chip for this board here. It's hardly a fixup... |
803 | */ | 804 | */ |
804 | static void __init ppc7d_fixup_ali1535(struct pci_dev *dev) | 805 | static void __init ppc7d_fixup_ali1535(struct pci_dev *dev) |
805 | { | 806 | { |
806 | pr_debug("PCI: ALI1535 init\n"); | 807 | pr_debug("PCI: ALI1535 init\n"); |
807 | 808 | ||
808 | if (dev->bus->number == 1) { | 809 | if (dev->bus->number == 1) { |
809 | /* Configure the ISA Port Settings */ | 810 | /* Configure the ISA Port Settings */ |
810 | pci_write_config_byte(dev, 0x43, 0x00); | 811 | pci_write_config_byte(dev, 0x43, 0x00); |
811 | 812 | ||
812 | /* Disable PCI Interrupt polling mode */ | 813 | /* Disable PCI Interrupt polling mode */ |
813 | pci_write_config_byte(dev, 0x45, 0x00); | 814 | pci_write_config_byte(dev, 0x45, 0x00); |
814 | 815 | ||
815 | /* Multifunction pin select INTFJ -> INTF */ | 816 | /* Multifunction pin select INTFJ -> INTF */ |
816 | pci_write_config_byte(dev, 0x78, 0x00); | 817 | pci_write_config_byte(dev, 0x78, 0x00); |
817 | 818 | ||
818 | /* Set PCI INT -> IRQ Routing control in for external | 819 | /* Set PCI INT -> IRQ Routing control in for external |
819 | * pins south bridge. | 820 | * pins south bridge. |
820 | */ | 821 | */ |
821 | pci_write_config_byte(dev, 0x48, 0x31); /* [7-4] INT B -> IRQ10 | 822 | pci_write_config_byte(dev, 0x48, 0x31); /* [7-4] INT B -> IRQ10 |
822 | * [3-0] INT A -> IRQ9 | 823 | * [3-0] INT A -> IRQ9 |
823 | */ | 824 | */ |
824 | pci_write_config_byte(dev, 0x49, 0x5D); /* [7-4] INT D -> IRQ5 | 825 | pci_write_config_byte(dev, 0x49, 0x5D); /* [7-4] INT D -> IRQ5 |
825 | * [3-0] INT C -> IRQ14 | 826 | * [3-0] INT C -> IRQ14 |
826 | */ | 827 | */ |
827 | 828 | ||
828 | /* PPC7D setup */ | 829 | /* PPC7D setup */ |
829 | /* NEC USB device on IRQ 11 (INTE) - INTF disabled */ | 830 | /* NEC USB device on IRQ 11 (INTE) - INTF disabled */ |
830 | pci_write_config_byte(dev, 0x4A, 0x09); | 831 | pci_write_config_byte(dev, 0x4A, 0x09); |
831 | 832 | ||
832 | /* GPIO on IRQ 6 */ | 833 | /* GPIO on IRQ 6 */ |
833 | pci_write_config_byte(dev, 0x76, 0x07); | 834 | pci_write_config_byte(dev, 0x76, 0x07); |
834 | 835 | ||
835 | /* SIRQ I (COMS 5/6) use IRQ line 15. | 836 | /* SIRQ I (COMS 5/6) use IRQ line 15. |
836 | * Positive (not subtractive) address decode. | 837 | * Positive (not subtractive) address decode. |
837 | */ | 838 | */ |
838 | pci_write_config_byte(dev, 0x44, 0x0f); | 839 | pci_write_config_byte(dev, 0x44, 0x0f); |
839 | 840 | ||
840 | /* SIRQ II disabled */ | 841 | /* SIRQ II disabled */ |
841 | pci_write_config_byte(dev, 0x75, 0x0); | 842 | pci_write_config_byte(dev, 0x75, 0x0); |
842 | 843 | ||
843 | /* On board USB and RTC disabled */ | 844 | /* On board USB and RTC disabled */ |
844 | pci_write_config_word(dev, 0x52, (1 << 14)); | 845 | pci_write_config_word(dev, 0x52, (1 << 14)); |
845 | pci_write_config_byte(dev, 0x74, 0x00); | 846 | pci_write_config_byte(dev, 0x74, 0x00); |
846 | 847 | ||
847 | /* On board IDE disabled */ | 848 | /* On board IDE disabled */ |
848 | pci_write_config_byte(dev, 0x58, 0x00); | 849 | pci_write_config_byte(dev, 0x58, 0x00); |
849 | 850 | ||
850 | /* Decode 32-bit addresses */ | 851 | /* Decode 32-bit addresses */ |
851 | pci_write_config_byte(dev, 0x5b, 0); | 852 | pci_write_config_byte(dev, 0x5b, 0); |
852 | 853 | ||
853 | /* Disable docking IO */ | 854 | /* Disable docking IO */ |
854 | pci_write_config_word(dev, 0x5c, 0x0000); | 855 | pci_write_config_word(dev, 0x5c, 0x0000); |
855 | 856 | ||
856 | /* Disable modem, enable sound */ | 857 | /* Disable modem, enable sound */ |
857 | pci_write_config_byte(dev, 0x77, (1 << 6)); | 858 | pci_write_config_byte(dev, 0x77, (1 << 6)); |
858 | 859 | ||
859 | /* Disable hot-docking mode */ | 860 | /* Disable hot-docking mode */ |
860 | pci_write_config_byte(dev, 0x7d, 0x00); | 861 | pci_write_config_byte(dev, 0x7d, 0x00); |
861 | } | 862 | } |
862 | } | 863 | } |
863 | 864 | ||
864 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1533, ppc7d_fixup_ali1535); | 865 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1533, ppc7d_fixup_ali1535); |
865 | 866 | ||
866 | static int ppc7d_pci_exclude_device(u8 bus, u8 devfn) | 867 | static int ppc7d_pci_exclude_device(u8 bus, u8 devfn) |
867 | { | 868 | { |
868 | /* Early versions of this board were fitted with IBM ALMA | 869 | /* Early versions of this board were fitted with IBM ALMA |
869 | * PCI-VME bridge chips. The PCI config space of these devices | 870 | * PCI-VME bridge chips. The PCI config space of these devices |
870 | * was not set up correctly and causes PCI scan problems. | 871 | * was not set up correctly and causes PCI scan problems. |
871 | */ | 872 | */ |
872 | if ((bus == 1) && (PCI_SLOT(devfn) == 4) && ppc7d_has_alma) | 873 | if ((bus == 1) && (PCI_SLOT(devfn) == 4) && ppc7d_has_alma) |
873 | return PCIBIOS_DEVICE_NOT_FOUND; | 874 | return PCIBIOS_DEVICE_NOT_FOUND; |
874 | 875 | ||
875 | return mv64x60_pci_exclude_device(bus, devfn); | 876 | return mv64x60_pci_exclude_device(bus, devfn); |
876 | } | 877 | } |
877 | 878 | ||
878 | /* This hook is called when each PCI bus is probed. | 879 | /* This hook is called when each PCI bus is probed. |
879 | */ | 880 | */ |
880 | static void ppc7d_pci_fixup_bus(struct pci_bus *bus) | 881 | static void ppc7d_pci_fixup_bus(struct pci_bus *bus) |
881 | { | 882 | { |
882 | pr_debug("PCI BUS %hu: %lx/%lx %lx/%lx %lx/%lx %lx/%lx\n", | 883 | pr_debug("PCI BUS %hu: %lx/%lx %lx/%lx %lx/%lx %lx/%lx\n", |
883 | bus->number, | 884 | bus->number, |
884 | bus->resource[0] ? bus->resource[0]->start : 0, | 885 | bus->resource[0] ? bus->resource[0]->start : 0, |
885 | bus->resource[0] ? bus->resource[0]->end : 0, | 886 | bus->resource[0] ? bus->resource[0]->end : 0, |
886 | bus->resource[1] ? bus->resource[1]->start : 0, | 887 | bus->resource[1] ? bus->resource[1]->start : 0, |
887 | bus->resource[1] ? bus->resource[1]->end : 0, | 888 | bus->resource[1] ? bus->resource[1]->end : 0, |
888 | bus->resource[2] ? bus->resource[2]->start : 0, | 889 | bus->resource[2] ? bus->resource[2]->start : 0, |
889 | bus->resource[2] ? bus->resource[2]->end : 0, | 890 | bus->resource[2] ? bus->resource[2]->end : 0, |
890 | bus->resource[3] ? bus->resource[3]->start : 0, | 891 | bus->resource[3] ? bus->resource[3]->start : 0, |
891 | bus->resource[3] ? bus->resource[3]->end : 0); | 892 | bus->resource[3] ? bus->resource[3]->end : 0); |
892 | 893 | ||
893 | if ((bus->number == 1) && (bus->resource[2] != NULL)) { | 894 | if ((bus->number == 1) && (bus->resource[2] != NULL)) { |
894 | /* Hide PCI window 2 of Bus 1 which is used only to | 895 | /* Hide PCI window 2 of Bus 1 which is used only to |
895 | * map legacy ISA memory space. | 896 | * map legacy ISA memory space. |
896 | */ | 897 | */ |
897 | bus->resource[2]->start = 0; | 898 | bus->resource[2]->start = 0; |
898 | bus->resource[2]->end = 0; | 899 | bus->resource[2]->end = 0; |
899 | bus->resource[2]->flags = 0; | 900 | bus->resource[2]->flags = 0; |
900 | } | 901 | } |
901 | } | 902 | } |
902 | 903 | ||
903 | /***************************************************************************** | 904 | /***************************************************************************** |
904 | * Board device setup code | 905 | * Board device setup code |
905 | *****************************************************************************/ | 906 | *****************************************************************************/ |
906 | 907 | ||
907 | void __init ppc7d_setup_peripherals(void) | 908 | void __init ppc7d_setup_peripherals(void) |
908 | { | 909 | { |
909 | u32 val32; | 910 | u32 val32; |
910 | 911 | ||
911 | /* Set up windows for boot CS */ | 912 | /* Set up windows for boot CS */ |
912 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, | 913 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, |
913 | PPC7D_BOOT_WINDOW_BASE, PPC7D_BOOT_WINDOW_SIZE, | 914 | PPC7D_BOOT_WINDOW_BASE, PPC7D_BOOT_WINDOW_SIZE, |
914 | 0); | 915 | 0); |
915 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); | 916 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); |
916 | 917 | ||
917 | /* Boot firmware configures the following DevCS addresses. | 918 | /* Boot firmware configures the following DevCS addresses. |
918 | * DevCS0 - board control/status | 919 | * DevCS0 - board control/status |
919 | * DevCS1 - test registers | 920 | * DevCS1 - test registers |
920 | * DevCS2 - AFIX port/address registers (for identifying) | 921 | * DevCS2 - AFIX port/address registers (for identifying) |
921 | * DevCS3 - FLASH | 922 | * DevCS3 - FLASH |
922 | * | 923 | * |
923 | * We don't use DevCS0, DevCS1. | 924 | * We don't use DevCS0, DevCS1. |
924 | */ | 925 | */ |
925 | val32 = mv64x60_read(&bh, MV64360_CPU_BAR_ENABLE); | 926 | val32 = mv64x60_read(&bh, MV64360_CPU_BAR_ENABLE); |
926 | val32 |= ((1 << 4) | (1 << 5)); | 927 | val32 |= ((1 << 4) | (1 << 5)); |
927 | mv64x60_write(&bh, MV64360_CPU_BAR_ENABLE, val32); | 928 | mv64x60_write(&bh, MV64360_CPU_BAR_ENABLE, val32); |
928 | mv64x60_write(&bh, MV64x60_CPU2DEV_0_BASE, 0); | 929 | mv64x60_write(&bh, MV64x60_CPU2DEV_0_BASE, 0); |
929 | mv64x60_write(&bh, MV64x60_CPU2DEV_0_SIZE, 0); | 930 | mv64x60_write(&bh, MV64x60_CPU2DEV_0_SIZE, 0); |
930 | mv64x60_write(&bh, MV64x60_CPU2DEV_1_BASE, 0); | 931 | mv64x60_write(&bh, MV64x60_CPU2DEV_1_BASE, 0); |
931 | mv64x60_write(&bh, MV64x60_CPU2DEV_1_SIZE, 0); | 932 | mv64x60_write(&bh, MV64x60_CPU2DEV_1_SIZE, 0); |
932 | 933 | ||
933 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, | 934 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, |
934 | PPC7D_AFIX_REG_BASE, PPC7D_AFIX_REG_SIZE, 0); | 935 | PPC7D_AFIX_REG_BASE, PPC7D_AFIX_REG_SIZE, 0); |
935 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); | 936 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN); |
936 | 937 | ||
937 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, | 938 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, |
938 | PPC7D_FLASH_BASE, PPC7D_FLASH_SIZE_ACTUAL, 0); | 939 | PPC7D_FLASH_BASE, PPC7D_FLASH_SIZE_ACTUAL, 0); |
939 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); | 940 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN); |
940 | 941 | ||
941 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN, | 942 | mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN, |
942 | PPC7D_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, | 943 | PPC7D_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, |
943 | 0); | 944 | 0); |
944 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN); | 945 | bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN); |
945 | 946 | ||
946 | /* Set up Enet->SRAM window */ | 947 | /* Set up Enet->SRAM window */ |
947 | mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN, | 948 | mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN, |
948 | PPC7D_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, | 949 | PPC7D_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, |
949 | 0x2); | 950 | 0x2); |
950 | bh.ci->enable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN); | 951 | bh.ci->enable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN); |
951 | 952 | ||
952 | /* Give enet r/w access to memory region */ | 953 | /* Give enet r/w access to memory region */ |
953 | val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_0); | 954 | val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_0); |
954 | val32 |= (0x3 << (4 << 1)); | 955 | val32 |= (0x3 << (4 << 1)); |
955 | mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_0, val32); | 956 | mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_0, val32); |
956 | val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_1); | 957 | val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_1); |
957 | val32 |= (0x3 << (4 << 1)); | 958 | val32 |= (0x3 << (4 << 1)); |
958 | mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_1, val32); | 959 | mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_1, val32); |
959 | val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_2); | 960 | val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_2); |
960 | val32 |= (0x3 << (4 << 1)); | 961 | val32 |= (0x3 << (4 << 1)); |
961 | mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_2, val32); | 962 | mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_2, val32); |
962 | 963 | ||
963 | val32 = mv64x60_read(&bh, MV64x60_TIMR_CNTR_0_3_CNTL); | 964 | val32 = mv64x60_read(&bh, MV64x60_TIMR_CNTR_0_3_CNTL); |
964 | val32 &= ~((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)); | 965 | val32 &= ~((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)); |
965 | mv64x60_write(&bh, MV64x60_TIMR_CNTR_0_3_CNTL, val32); | 966 | mv64x60_write(&bh, MV64x60_TIMR_CNTR_0_3_CNTL, val32); |
966 | 967 | ||
967 | /* Enumerate pci bus. | 968 | /* Enumerate pci bus. |
968 | * | 969 | * |
969 | * We scan PCI#0 first (the bus with the HB8 and other | 970 | * We scan PCI#0 first (the bus with the HB8 and other |
970 | * on-board peripherals). We must configure the 64360 before | 971 | * on-board peripherals). We must configure the 64360 before |
971 | * each scan, according to the bus number assignments. Busses | 972 | * each scan, according to the bus number assignments. Busses |
972 | * are assigned incrementally, starting at 0. PCI#0 is | 973 | * are assigned incrementally, starting at 0. PCI#0 is |
973 | * usually assigned bus#0, the secondary side of the HB8 gets | 974 | * usually assigned bus#0, the secondary side of the HB8 gets |
974 | * bus#1 and PCI#1 (second PMC site) gets bus#2. However, if | 975 | * bus#1 and PCI#1 (second PMC site) gets bus#2. However, if |
975 | * any PMC card has a PCI bridge, these bus assignments will | 976 | * any PMC card has a PCI bridge, these bus assignments will |
976 | * change. | 977 | * change. |
977 | */ | 978 | */ |
978 | 979 | ||
979 | /* Turn off PCI retries */ | 980 | /* Turn off PCI retries */ |
980 | val32 = mv64x60_read(&bh, MV64x60_CPU_CONFIG); | 981 | val32 = mv64x60_read(&bh, MV64x60_CPU_CONFIG); |
981 | val32 |= (1 << 17); | 982 | val32 |= (1 << 17); |
982 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, val32); | 983 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, val32); |
983 | 984 | ||
984 | /* Scan PCI#0 */ | 985 | /* Scan PCI#0 */ |
985 | mv64x60_set_bus(&bh, 0, 0); | 986 | mv64x60_set_bus(&bh, 0, 0); |
986 | bh.hose_a->first_busno = 0; | 987 | bh.hose_a->first_busno = 0; |
987 | bh.hose_a->last_busno = 0xff; | 988 | bh.hose_a->last_busno = 0xff; |
988 | bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0); | 989 | bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0); |
989 | printk(KERN_INFO "PCI#0: first=%d last=%d\n", | 990 | printk(KERN_INFO "PCI#0: first=%d last=%d\n", |
990 | bh.hose_a->first_busno, bh.hose_a->last_busno); | 991 | bh.hose_a->first_busno, bh.hose_a->last_busno); |
991 | 992 | ||
992 | /* Scan PCI#1 */ | 993 | /* Scan PCI#1 */ |
993 | bh.hose_b->first_busno = bh.hose_a->last_busno + 1; | 994 | bh.hose_b->first_busno = bh.hose_a->last_busno + 1; |
994 | mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno); | 995 | mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno); |
995 | bh.hose_b->last_busno = 0xff; | 996 | bh.hose_b->last_busno = 0xff; |
996 | bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b, | 997 | bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b, |
997 | bh.hose_b->first_busno); | 998 | bh.hose_b->first_busno); |
998 | printk(KERN_INFO "PCI#1: first=%d last=%d\n", | 999 | printk(KERN_INFO "PCI#1: first=%d last=%d\n", |
999 | bh.hose_b->first_busno, bh.hose_b->last_busno); | 1000 | bh.hose_b->first_busno, bh.hose_b->last_busno); |
1000 | 1001 | ||
1001 | /* Turn on PCI retries */ | 1002 | /* Turn on PCI retries */ |
1002 | val32 = mv64x60_read(&bh, MV64x60_CPU_CONFIG); | 1003 | val32 = mv64x60_read(&bh, MV64x60_CPU_CONFIG); |
1003 | val32 &= ~(1 << 17); | 1004 | val32 &= ~(1 << 17); |
1004 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, val32); | 1005 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, val32); |
1005 | 1006 | ||
1006 | /* Setup interrupts */ | 1007 | /* Setup interrupts */ |
1007 | ppc7d_intr_setup(); | 1008 | ppc7d_intr_setup(); |
1008 | } | 1009 | } |
1009 | 1010 | ||
1010 | static void __init ppc7d_setup_bridge(void) | 1011 | static void __init ppc7d_setup_bridge(void) |
1011 | { | 1012 | { |
1012 | struct mv64x60_setup_info si; | 1013 | struct mv64x60_setup_info si; |
1013 | int i; | 1014 | int i; |
1014 | u32 temp; | 1015 | u32 temp; |
1015 | 1016 | ||
1016 | mv64360_irq_base = 16; /* first 16 intrs are 2 x 8259's */ | 1017 | mv64360_irq_base = 16; /* first 16 intrs are 2 x 8259's */ |
1017 | 1018 | ||
1018 | memset(&si, 0, sizeof(si)); | 1019 | memset(&si, 0, sizeof(si)); |
1019 | 1020 | ||
1020 | si.phys_reg_base = CONFIG_MV64X60_NEW_BASE; | 1021 | si.phys_reg_base = CONFIG_MV64X60_NEW_BASE; |
1021 | 1022 | ||
1022 | si.pci_0.enable_bus = 1; | 1023 | si.pci_0.enable_bus = 1; |
1023 | si.pci_0.pci_io.cpu_base = PPC7D_PCI0_IO_START_PROC_ADDR; | 1024 | si.pci_0.pci_io.cpu_base = PPC7D_PCI0_IO_START_PROC_ADDR; |
1024 | si.pci_0.pci_io.pci_base_hi = 0; | 1025 | si.pci_0.pci_io.pci_base_hi = 0; |
1025 | si.pci_0.pci_io.pci_base_lo = PPC7D_PCI0_IO_START_PCI_ADDR; | 1026 | si.pci_0.pci_io.pci_base_lo = PPC7D_PCI0_IO_START_PCI_ADDR; |
1026 | si.pci_0.pci_io.size = PPC7D_PCI0_IO_SIZE; | 1027 | si.pci_0.pci_io.size = PPC7D_PCI0_IO_SIZE; |
1027 | si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; | 1028 | si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; |
1028 | si.pci_0.pci_mem[0].cpu_base = PPC7D_PCI0_MEM0_START_PROC_ADDR; | 1029 | si.pci_0.pci_mem[0].cpu_base = PPC7D_PCI0_MEM0_START_PROC_ADDR; |
1029 | si.pci_0.pci_mem[0].pci_base_hi = PPC7D_PCI0_MEM0_START_PCI_HI_ADDR; | 1030 | si.pci_0.pci_mem[0].pci_base_hi = PPC7D_PCI0_MEM0_START_PCI_HI_ADDR; |
1030 | si.pci_0.pci_mem[0].pci_base_lo = PPC7D_PCI0_MEM0_START_PCI_LO_ADDR; | 1031 | si.pci_0.pci_mem[0].pci_base_lo = PPC7D_PCI0_MEM0_START_PCI_LO_ADDR; |
1031 | si.pci_0.pci_mem[0].size = PPC7D_PCI0_MEM0_SIZE; | 1032 | si.pci_0.pci_mem[0].size = PPC7D_PCI0_MEM0_SIZE; |
1032 | si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; | 1033 | si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; |
1033 | si.pci_0.pci_mem[1].cpu_base = PPC7D_PCI0_MEM1_START_PROC_ADDR; | 1034 | si.pci_0.pci_mem[1].cpu_base = PPC7D_PCI0_MEM1_START_PROC_ADDR; |
1034 | si.pci_0.pci_mem[1].pci_base_hi = PPC7D_PCI0_MEM1_START_PCI_HI_ADDR; | 1035 | si.pci_0.pci_mem[1].pci_base_hi = PPC7D_PCI0_MEM1_START_PCI_HI_ADDR; |
1035 | si.pci_0.pci_mem[1].pci_base_lo = PPC7D_PCI0_MEM1_START_PCI_LO_ADDR; | 1036 | si.pci_0.pci_mem[1].pci_base_lo = PPC7D_PCI0_MEM1_START_PCI_LO_ADDR; |
1036 | si.pci_0.pci_mem[1].size = PPC7D_PCI0_MEM1_SIZE; | 1037 | si.pci_0.pci_mem[1].size = PPC7D_PCI0_MEM1_SIZE; |
1037 | si.pci_0.pci_mem[1].swap = MV64x60_CPU2PCI_SWAP_NONE; | 1038 | si.pci_0.pci_mem[1].swap = MV64x60_CPU2PCI_SWAP_NONE; |
1038 | si.pci_0.pci_cmd_bits = 0; | 1039 | si.pci_0.pci_cmd_bits = 0; |
1039 | si.pci_0.latency_timer = 0x80; | 1040 | si.pci_0.latency_timer = 0x80; |
1040 | 1041 | ||
1041 | si.pci_1.enable_bus = 1; | 1042 | si.pci_1.enable_bus = 1; |
1042 | si.pci_1.pci_io.cpu_base = PPC7D_PCI1_IO_START_PROC_ADDR; | 1043 | si.pci_1.pci_io.cpu_base = PPC7D_PCI1_IO_START_PROC_ADDR; |
1043 | si.pci_1.pci_io.pci_base_hi = 0; | 1044 | si.pci_1.pci_io.pci_base_hi = 0; |
1044 | si.pci_1.pci_io.pci_base_lo = PPC7D_PCI1_IO_START_PCI_ADDR; | 1045 | si.pci_1.pci_io.pci_base_lo = PPC7D_PCI1_IO_START_PCI_ADDR; |
1045 | si.pci_1.pci_io.size = PPC7D_PCI1_IO_SIZE; | 1046 | si.pci_1.pci_io.size = PPC7D_PCI1_IO_SIZE; |
1046 | si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; | 1047 | si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; |
1047 | si.pci_1.pci_mem[0].cpu_base = PPC7D_PCI1_MEM0_START_PROC_ADDR; | 1048 | si.pci_1.pci_mem[0].cpu_base = PPC7D_PCI1_MEM0_START_PROC_ADDR; |
1048 | si.pci_1.pci_mem[0].pci_base_hi = PPC7D_PCI1_MEM0_START_PCI_HI_ADDR; | 1049 | si.pci_1.pci_mem[0].pci_base_hi = PPC7D_PCI1_MEM0_START_PCI_HI_ADDR; |
1049 | si.pci_1.pci_mem[0].pci_base_lo = PPC7D_PCI1_MEM0_START_PCI_LO_ADDR; | 1050 | si.pci_1.pci_mem[0].pci_base_lo = PPC7D_PCI1_MEM0_START_PCI_LO_ADDR; |
1050 | si.pci_1.pci_mem[0].size = PPC7D_PCI1_MEM0_SIZE; | 1051 | si.pci_1.pci_mem[0].size = PPC7D_PCI1_MEM0_SIZE; |
1051 | si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; | 1052 | si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; |
1052 | si.pci_1.pci_mem[1].cpu_base = PPC7D_PCI1_MEM1_START_PROC_ADDR; | 1053 | si.pci_1.pci_mem[1].cpu_base = PPC7D_PCI1_MEM1_START_PROC_ADDR; |
1053 | si.pci_1.pci_mem[1].pci_base_hi = PPC7D_PCI1_MEM1_START_PCI_HI_ADDR; | 1054 | si.pci_1.pci_mem[1].pci_base_hi = PPC7D_PCI1_MEM1_START_PCI_HI_ADDR; |
1054 | si.pci_1.pci_mem[1].pci_base_lo = PPC7D_PCI1_MEM1_START_PCI_LO_ADDR; | 1055 | si.pci_1.pci_mem[1].pci_base_lo = PPC7D_PCI1_MEM1_START_PCI_LO_ADDR; |
1055 | si.pci_1.pci_mem[1].size = PPC7D_PCI1_MEM1_SIZE; | 1056 | si.pci_1.pci_mem[1].size = PPC7D_PCI1_MEM1_SIZE; |
1056 | si.pci_1.pci_mem[1].swap = MV64x60_CPU2PCI_SWAP_NONE; | 1057 | si.pci_1.pci_mem[1].swap = MV64x60_CPU2PCI_SWAP_NONE; |
1057 | si.pci_1.pci_cmd_bits = 0; | 1058 | si.pci_1.pci_cmd_bits = 0; |
1058 | si.pci_1.latency_timer = 0x80; | 1059 | si.pci_1.latency_timer = 0x80; |
1059 | 1060 | ||
1060 | /* Don't clear the SRAM window since we use it for debug */ | 1061 | /* Don't clear the SRAM window since we use it for debug */ |
1061 | si.window_preserve_mask_32_lo = (1 << MV64x60_CPU2SRAM_WIN); | 1062 | si.window_preserve_mask_32_lo = (1 << MV64x60_CPU2SRAM_WIN); |
1062 | 1063 | ||
1063 | printk(KERN_INFO "PCI: MV64360 PCI#0 IO at %x, size %x\n", | 1064 | printk(KERN_INFO "PCI: MV64360 PCI#0 IO at %x, size %x\n", |
1064 | si.pci_0.pci_io.cpu_base, si.pci_0.pci_io.size); | 1065 | si.pci_0.pci_io.cpu_base, si.pci_0.pci_io.size); |
1065 | printk(KERN_INFO "PCI: MV64360 PCI#1 IO at %x, size %x\n", | 1066 | printk(KERN_INFO "PCI: MV64360 PCI#1 IO at %x, size %x\n", |
1066 | si.pci_1.pci_io.cpu_base, si.pci_1.pci_io.size); | 1067 | si.pci_1.pci_io.cpu_base, si.pci_1.pci_io.size); |
1067 | 1068 | ||
1068 | for (i = 0; i < MV64x60_CPU2MEM_WINDOWS; i++) { | 1069 | for (i = 0; i < MV64x60_CPU2MEM_WINDOWS; i++) { |
1069 | #if defined(CONFIG_NOT_COHERENT_CACHE) | 1070 | #if defined(CONFIG_NOT_COHERENT_CACHE) |
1070 | si.cpu_prot_options[i] = 0; | 1071 | si.cpu_prot_options[i] = 0; |
1071 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; | 1072 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; |
1072 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; | 1073 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; |
1073 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; | 1074 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; |
1074 | 1075 | ||
1075 | si.pci_0.acc_cntl_options[i] = | 1076 | si.pci_0.acc_cntl_options[i] = |
1076 | MV64360_PCI_ACC_CNTL_SNOOP_NONE | | 1077 | MV64360_PCI_ACC_CNTL_SNOOP_NONE | |
1077 | MV64360_PCI_ACC_CNTL_SWAP_NONE | | 1078 | MV64360_PCI_ACC_CNTL_SWAP_NONE | |
1078 | MV64360_PCI_ACC_CNTL_MBURST_128_BYTES | | 1079 | MV64360_PCI_ACC_CNTL_MBURST_128_BYTES | |
1079 | MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES; | 1080 | MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES; |
1080 | 1081 | ||
1081 | si.pci_1.acc_cntl_options[i] = | 1082 | si.pci_1.acc_cntl_options[i] = |
1082 | MV64360_PCI_ACC_CNTL_SNOOP_NONE | | 1083 | MV64360_PCI_ACC_CNTL_SNOOP_NONE | |
1083 | MV64360_PCI_ACC_CNTL_SWAP_NONE | | 1084 | MV64360_PCI_ACC_CNTL_SWAP_NONE | |
1084 | MV64360_PCI_ACC_CNTL_MBURST_128_BYTES | | 1085 | MV64360_PCI_ACC_CNTL_MBURST_128_BYTES | |
1085 | MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES; | 1086 | MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES; |
1086 | #else | 1087 | #else |
1087 | si.cpu_prot_options[i] = 0; | 1088 | si.cpu_prot_options[i] = 0; |
1088 | /* All PPC7D hardware uses B0 or newer MV64360 silicon which | 1089 | /* All PPC7D hardware uses B0 or newer MV64360 silicon which |
1089 | * does not have snoop bugs. | 1090 | * does not have snoop bugs. |
1090 | */ | 1091 | */ |
1091 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_WB; | 1092 | si.enet_options[i] = MV64360_ENET2MEM_SNOOP_WB; |
1092 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_WB; | 1093 | si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_WB; |
1093 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_WB; | 1094 | si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_WB; |
1094 | 1095 | ||
1095 | si.pci_0.acc_cntl_options[i] = | 1096 | si.pci_0.acc_cntl_options[i] = |
1096 | MV64360_PCI_ACC_CNTL_SNOOP_WB | | 1097 | MV64360_PCI_ACC_CNTL_SNOOP_WB | |
1097 | MV64360_PCI_ACC_CNTL_SWAP_NONE | | 1098 | MV64360_PCI_ACC_CNTL_SWAP_NONE | |
1098 | MV64360_PCI_ACC_CNTL_MBURST_32_BYTES | | 1099 | MV64360_PCI_ACC_CNTL_MBURST_32_BYTES | |
1099 | MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES; | 1100 | MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES; |
1100 | 1101 | ||
1101 | si.pci_1.acc_cntl_options[i] = | 1102 | si.pci_1.acc_cntl_options[i] = |
1102 | MV64360_PCI_ACC_CNTL_SNOOP_WB | | 1103 | MV64360_PCI_ACC_CNTL_SNOOP_WB | |
1103 | MV64360_PCI_ACC_CNTL_SWAP_NONE | | 1104 | MV64360_PCI_ACC_CNTL_SWAP_NONE | |
1104 | MV64360_PCI_ACC_CNTL_MBURST_32_BYTES | | 1105 | MV64360_PCI_ACC_CNTL_MBURST_32_BYTES | |
1105 | MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES; | 1106 | MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES; |
1106 | #endif | 1107 | #endif |
1107 | } | 1108 | } |
1108 | 1109 | ||
1109 | /* Lookup PCI host bridges */ | 1110 | /* Lookup PCI host bridges */ |
1110 | if (mv64x60_init(&bh, &si)) | 1111 | if (mv64x60_init(&bh, &si)) |
1111 | printk(KERN_ERR "MV64360 initialization failed.\n"); | 1112 | printk(KERN_ERR "MV64360 initialization failed.\n"); |
1112 | 1113 | ||
1113 | pr_debug("MV64360 regs @ %lx/%p\n", bh.p_base, bh.v_base); | 1114 | pr_debug("MV64360 regs @ %lx/%p\n", bh.p_base, bh.v_base); |
1114 | 1115 | ||
1115 | /* Enable WB Cache coherency on SRAM */ | 1116 | /* Enable WB Cache coherency on SRAM */ |
1116 | temp = mv64x60_read(&bh, MV64360_SRAM_CONFIG); | 1117 | temp = mv64x60_read(&bh, MV64360_SRAM_CONFIG); |
1117 | pr_debug("SRAM_CONFIG: %x\n", temp); | 1118 | pr_debug("SRAM_CONFIG: %x\n", temp); |
1118 | #if defined(CONFIG_NOT_COHERENT_CACHE) | 1119 | #if defined(CONFIG_NOT_COHERENT_CACHE) |
1119 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, temp & ~0x2); | 1120 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, temp & ~0x2); |
1120 | #else | 1121 | #else |
1121 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, temp | 0x2); | 1122 | mv64x60_write(&bh, MV64360_SRAM_CONFIG, temp | 0x2); |
1122 | #endif | 1123 | #endif |
1123 | /* If system operates with internal bus arbiter (CPU master | 1124 | /* If system operates with internal bus arbiter (CPU master |
1124 | * control bit8) clear AACK Delay bit [25] in CPU | 1125 | * control bit8) clear AACK Delay bit [25] in CPU |
1125 | * configuration register. | 1126 | * configuration register. |
1126 | */ | 1127 | */ |
1127 | temp = mv64x60_read(&bh, MV64x60_CPU_MASTER_CNTL); | 1128 | temp = mv64x60_read(&bh, MV64x60_CPU_MASTER_CNTL); |
1128 | if (temp & (1 << 8)) { | 1129 | if (temp & (1 << 8)) { |
1129 | temp = mv64x60_read(&bh, MV64x60_CPU_CONFIG); | 1130 | temp = mv64x60_read(&bh, MV64x60_CPU_CONFIG); |
1130 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, (temp & ~(1 << 25))); | 1131 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, (temp & ~(1 << 25))); |
1131 | } | 1132 | } |
1132 | 1133 | ||
1133 | /* Data and address parity is enabled */ | 1134 | /* Data and address parity is enabled */ |
1134 | temp = mv64x60_read(&bh, MV64x60_CPU_CONFIG); | 1135 | temp = mv64x60_read(&bh, MV64x60_CPU_CONFIG); |
1135 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, | 1136 | mv64x60_write(&bh, MV64x60_CPU_CONFIG, |
1136 | (temp | (1 << 26) | (1 << 19))); | 1137 | (temp | (1 << 26) | (1 << 19))); |
1137 | 1138 | ||
1138 | pci_dram_offset = 0; /* sys mem at same addr on PCI & cpu bus */ | 1139 | pci_dram_offset = 0; /* sys mem at same addr on PCI & cpu bus */ |
1139 | ppc_md.pci_swizzle = common_swizzle; | 1140 | ppc_md.pci_swizzle = common_swizzle; |
1140 | ppc_md.pci_map_irq = ppc7d_map_irq; | 1141 | ppc_md.pci_map_irq = ppc7d_map_irq; |
1141 | ppc_md.pci_exclude_device = ppc7d_pci_exclude_device; | 1142 | ppc_md.pci_exclude_device = ppc7d_pci_exclude_device; |
1142 | 1143 | ||
1143 | mv64x60_set_bus(&bh, 0, 0); | 1144 | mv64x60_set_bus(&bh, 0, 0); |
1144 | bh.hose_a->first_busno = 0; | 1145 | bh.hose_a->first_busno = 0; |
1145 | bh.hose_a->last_busno = 0xff; | 1146 | bh.hose_a->last_busno = 0xff; |
1146 | bh.hose_a->mem_space.start = PPC7D_PCI0_MEM0_START_PCI_LO_ADDR; | 1147 | bh.hose_a->mem_space.start = PPC7D_PCI0_MEM0_START_PCI_LO_ADDR; |
1147 | bh.hose_a->mem_space.end = | 1148 | bh.hose_a->mem_space.end = |
1148 | PPC7D_PCI0_MEM0_START_PCI_LO_ADDR + PPC7D_PCI0_MEM0_SIZE; | 1149 | PPC7D_PCI0_MEM0_START_PCI_LO_ADDR + PPC7D_PCI0_MEM0_SIZE; |
1149 | 1150 | ||
1150 | /* These will be set later, as a result of PCI0 scan */ | 1151 | /* These will be set later, as a result of PCI0 scan */ |
1151 | bh.hose_b->first_busno = 0; | 1152 | bh.hose_b->first_busno = 0; |
1152 | bh.hose_b->last_busno = 0xff; | 1153 | bh.hose_b->last_busno = 0xff; |
1153 | bh.hose_b->mem_space.start = PPC7D_PCI1_MEM0_START_PCI_LO_ADDR; | 1154 | bh.hose_b->mem_space.start = PPC7D_PCI1_MEM0_START_PCI_LO_ADDR; |
1154 | bh.hose_b->mem_space.end = | 1155 | bh.hose_b->mem_space.end = |
1155 | PPC7D_PCI1_MEM0_START_PCI_LO_ADDR + PPC7D_PCI1_MEM0_SIZE; | 1156 | PPC7D_PCI1_MEM0_START_PCI_LO_ADDR + PPC7D_PCI1_MEM0_SIZE; |
1156 | 1157 | ||
1157 | pr_debug("MV64360: PCI#0 IO decode %08x/%08x IO remap %08x\n", | 1158 | pr_debug("MV64360: PCI#0 IO decode %08x/%08x IO remap %08x\n", |
1158 | mv64x60_read(&bh, 0x48), mv64x60_read(&bh, 0x50), | 1159 | mv64x60_read(&bh, 0x48), mv64x60_read(&bh, 0x50), |
1159 | mv64x60_read(&bh, 0xf0)); | 1160 | mv64x60_read(&bh, 0xf0)); |
1160 | } | 1161 | } |
1161 | 1162 | ||
1162 | static void __init ppc7d_setup_arch(void) | 1163 | static void __init ppc7d_setup_arch(void) |
1163 | { | 1164 | { |
1164 | int port; | 1165 | int port; |
1165 | 1166 | ||
1166 | loops_per_jiffy = 100000000 / HZ; | 1167 | loops_per_jiffy = 100000000 / HZ; |
1167 | 1168 | ||
1168 | #ifdef CONFIG_BLK_DEV_INITRD | 1169 | #ifdef CONFIG_BLK_DEV_INITRD |
1169 | if (initrd_start) | 1170 | if (initrd_start) |
1170 | ROOT_DEV = Root_RAM0; | 1171 | ROOT_DEV = Root_RAM0; |
1171 | else | 1172 | else |
1172 | #endif | 1173 | #endif |
1173 | #ifdef CONFIG_ROOT_NFS | 1174 | #ifdef CONFIG_ROOT_NFS |
1174 | ROOT_DEV = Root_NFS; | 1175 | ROOT_DEV = Root_NFS; |
1175 | #else | 1176 | #else |
1176 | ROOT_DEV = Root_HDA1; | 1177 | ROOT_DEV = Root_HDA1; |
1177 | #endif | 1178 | #endif |
1178 | 1179 | ||
1179 | if ((cur_cpu_spec->cpu_features & CPU_FTR_SPEC7450) || | 1180 | if ((cur_cpu_spec->cpu_features & CPU_FTR_SPEC7450) || |
1180 | (cur_cpu_spec->cpu_features & CPU_FTR_L3CR)) | 1181 | (cur_cpu_spec->cpu_features & CPU_FTR_L3CR)) |
1181 | /* 745x is different. We only want to pass along enable. */ | 1182 | /* 745x is different. We only want to pass along enable. */ |
1182 | _set_L2CR(L2CR_L2E); | 1183 | _set_L2CR(L2CR_L2E); |
1183 | else if (cur_cpu_spec->cpu_features & CPU_FTR_L2CR) | 1184 | else if (cur_cpu_spec->cpu_features & CPU_FTR_L2CR) |
1184 | /* All modules have 1MB of L2. We also assume that an | 1185 | /* All modules have 1MB of L2. We also assume that an |
1185 | * L2 divisor of 3 will work. | 1186 | * L2 divisor of 3 will work. |
1186 | */ | 1187 | */ |
1187 | _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3 | 1188 | _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3 |
1188 | | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); | 1189 | | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); |
1189 | 1190 | ||
1190 | if (cur_cpu_spec->cpu_features & CPU_FTR_L3CR) | 1191 | if (cur_cpu_spec->cpu_features & CPU_FTR_L3CR) |
1191 | /* No L3 cache */ | 1192 | /* No L3 cache */ |
1192 | _set_L3CR(0); | 1193 | _set_L3CR(0); |
1193 | 1194 | ||
1194 | #ifdef CONFIG_DUMMY_CONSOLE | 1195 | #ifdef CONFIG_DUMMY_CONSOLE |
1195 | conswitchp = &dummy_con; | 1196 | conswitchp = &dummy_con; |
1196 | #endif | 1197 | #endif |
1197 | 1198 | ||
1198 | /* Lookup PCI host bridges */ | 1199 | /* Lookup PCI host bridges */ |
1199 | if (ppc_md.progress) | 1200 | if (ppc_md.progress) |
1200 | ppc_md.progress("ppc7d_setup_arch: calling setup_bridge", 0); | 1201 | ppc_md.progress("ppc7d_setup_arch: calling setup_bridge", 0); |
1201 | 1202 | ||
1202 | ppc7d_setup_bridge(); | 1203 | ppc7d_setup_bridge(); |
1203 | ppc7d_setup_peripherals(); | 1204 | ppc7d_setup_peripherals(); |
1204 | 1205 | ||
1205 | /* Disable ethernet. It might have been setup by the bootrom */ | 1206 | /* Disable ethernet. It might have been setup by the bootrom */ |
1206 | for (port = 0; port < 3; port++) | 1207 | for (port = 0; port < 3; port++) |
1207 | mv64x60_write(&bh, MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port), | 1208 | mv64x60_write(&bh, MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port), |
1208 | 0x0000ff00); | 1209 | 0x0000ff00); |
1209 | 1210 | ||
1210 | /* Clear queue pointers to ensure they are all initialized, | 1211 | /* Clear queue pointers to ensure they are all initialized, |
1211 | * otherwise since queues 1-7 are unused, they have random | 1212 | * otherwise since queues 1-7 are unused, they have random |
1212 | * pointers which look strange in register dumps. Don't bother | 1213 | * pointers which look strange in register dumps. Don't bother |
1213 | * with queue 0 since it will be initialized later. | 1214 | * with queue 0 since it will be initialized later. |
1214 | */ | 1215 | */ |
1215 | for (port = 0; port < 3; port++) { | 1216 | for (port = 0; port < 3; port++) { |
1216 | mv64x60_write(&bh, | 1217 | mv64x60_write(&bh, |
1217 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port), | 1218 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port), |
1218 | 0x00000000); | 1219 | 0x00000000); |
1219 | mv64x60_write(&bh, | 1220 | mv64x60_write(&bh, |
1220 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port), | 1221 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port), |
1221 | 0x00000000); | 1222 | 0x00000000); |
1222 | mv64x60_write(&bh, | 1223 | mv64x60_write(&bh, |
1223 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port), | 1224 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port), |
1224 | 0x00000000); | 1225 | 0x00000000); |
1225 | mv64x60_write(&bh, | 1226 | mv64x60_write(&bh, |
1226 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port), | 1227 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port), |
1227 | 0x00000000); | 1228 | 0x00000000); |
1228 | mv64x60_write(&bh, | 1229 | mv64x60_write(&bh, |
1229 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port), | 1230 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port), |
1230 | 0x00000000); | 1231 | 0x00000000); |
1231 | mv64x60_write(&bh, | 1232 | mv64x60_write(&bh, |
1232 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port), | 1233 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port), |
1233 | 0x00000000); | 1234 | 0x00000000); |
1234 | mv64x60_write(&bh, | 1235 | mv64x60_write(&bh, |
1235 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port), | 1236 | MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port), |
1236 | 0x00000000); | 1237 | 0x00000000); |
1237 | } | 1238 | } |
1238 | 1239 | ||
1239 | printk(KERN_INFO "Radstone Technology PPC7D\n"); | 1240 | printk(KERN_INFO "Radstone Technology PPC7D\n"); |
1240 | if (ppc_md.progress) | 1241 | if (ppc_md.progress) |
1241 | ppc_md.progress("ppc7d_setup_arch: exit", 0); | 1242 | ppc_md.progress("ppc7d_setup_arch: exit", 0); |
1242 | 1243 | ||
1243 | } | 1244 | } |
1244 | 1245 | ||
1245 | /* Real Time Clock support. | 1246 | /* Real Time Clock support. |
1246 | * PPC7D has a DS1337 accessed by I2C. | 1247 | * PPC7D has a DS1337 accessed by I2C. |
1247 | */ | 1248 | */ |
1248 | static ulong ppc7d_get_rtc_time(void) | 1249 | static ulong ppc7d_get_rtc_time(void) |
1249 | { | 1250 | { |
1250 | struct rtc_time tm; | 1251 | struct rtc_time tm; |
1251 | int result; | 1252 | int result; |
1252 | 1253 | ||
1253 | spin_lock(&rtc_lock); | 1254 | spin_lock(&rtc_lock); |
1254 | result = ds1337_do_command(0, DS1337_GET_DATE, &tm); | 1255 | result = ds1337_do_command(0, DS1337_GET_DATE, &tm); |
1255 | spin_unlock(&rtc_lock); | 1256 | spin_unlock(&rtc_lock); |
1256 | 1257 | ||
1257 | if (result == 0) | 1258 | if (result == 0) |
1258 | result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); | 1259 | result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); |
1259 | 1260 | ||
1260 | return result; | 1261 | return result; |
1261 | } | 1262 | } |
1262 | 1263 | ||
1263 | static int ppc7d_set_rtc_time(unsigned long nowtime) | 1264 | static int ppc7d_set_rtc_time(unsigned long nowtime) |
1264 | { | 1265 | { |
1265 | struct rtc_time tm; | 1266 | struct rtc_time tm; |
1266 | int result; | 1267 | int result; |
1267 | 1268 | ||
1268 | spin_lock(&rtc_lock); | 1269 | spin_lock(&rtc_lock); |
1269 | to_tm(nowtime, &tm); | 1270 | to_tm(nowtime, &tm); |
1270 | result = ds1337_do_command(0, DS1337_SET_DATE, &tm); | 1271 | result = ds1337_do_command(0, DS1337_SET_DATE, &tm); |
1271 | spin_unlock(&rtc_lock); | 1272 | spin_unlock(&rtc_lock); |
1272 | 1273 | ||
1273 | return result; | 1274 | return result; |
1274 | } | 1275 | } |
1275 | 1276 | ||
1276 | /* This kernel command line parameter can be used to have the target | 1277 | /* This kernel command line parameter can be used to have the target |
1277 | * wait for a JTAG debugger to attach. Of course, a JTAG debugger | 1278 | * wait for a JTAG debugger to attach. Of course, a JTAG debugger |
1278 | * with hardware breakpoint support can have the target stop at any | 1279 | * with hardware breakpoint support can have the target stop at any |
1279 | * location during init, but this is a convenience feature that makes | 1280 | * location during init, but this is a convenience feature that makes |
1280 | * it easier in the common case of loading the code using the ppcboot | 1281 | * it easier in the common case of loading the code using the ppcboot |
1281 | * bootloader.. | 1282 | * bootloader.. |
1282 | */ | 1283 | */ |
1283 | static unsigned long ppc7d_wait_debugger; | 1284 | static unsigned long ppc7d_wait_debugger; |
1284 | 1285 | ||
1285 | static int __init ppc7d_waitdbg(char *str) | 1286 | static int __init ppc7d_waitdbg(char *str) |
1286 | { | 1287 | { |
1287 | ppc7d_wait_debugger = 1; | 1288 | ppc7d_wait_debugger = 1; |
1288 | return 1; | 1289 | return 1; |
1289 | } | 1290 | } |
1290 | 1291 | ||
1291 | __setup("waitdbg", ppc7d_waitdbg); | 1292 | __setup("waitdbg", ppc7d_waitdbg); |
1292 | 1293 | ||
1293 | /* Second phase board init, called after other (architecture common) | 1294 | /* Second phase board init, called after other (architecture common) |
1294 | * low-level services have been initialized. | 1295 | * low-level services have been initialized. |
1295 | */ | 1296 | */ |
1296 | static void ppc7d_init2(void) | 1297 | static void ppc7d_init2(void) |
1297 | { | 1298 | { |
1298 | unsigned long flags; | 1299 | unsigned long flags; |
1299 | u32 data; | 1300 | u32 data; |
1300 | u8 data8; | 1301 | u8 data8; |
1301 | 1302 | ||
1302 | pr_debug("%s: enter\n", __FUNCTION__); | 1303 | pr_debug("%s: enter\n", __FUNCTION__); |
1303 | 1304 | ||
1304 | /* Wait for debugger? */ | 1305 | /* Wait for debugger? */ |
1305 | if (ppc7d_wait_debugger) { | 1306 | if (ppc7d_wait_debugger) { |
1306 | printk("Waiting for debugger...\n"); | 1307 | printk("Waiting for debugger...\n"); |
1307 | 1308 | ||
1308 | while (readl(&ppc7d_wait_debugger)) ; | 1309 | while (readl(&ppc7d_wait_debugger)) ; |
1309 | } | 1310 | } |
1310 | 1311 | ||
1311 | /* Hook up i8259 interrupt which is connected to GPP28 */ | 1312 | /* Hook up i8259 interrupt which is connected to GPP28 */ |
1312 | request_irq(mv64360_irq_base + MV64x60_IRQ_GPP28, ppc7d_i8259_intr, | 1313 | request_irq(mv64360_irq_base + MV64x60_IRQ_GPP28, ppc7d_i8259_intr, |
1313 | IRQF_DISABLED, "I8259 (GPP28) interrupt", (void *)0); | 1314 | IRQF_DISABLED, "I8259 (GPP28) interrupt", (void *)0); |
1314 | 1315 | ||
1315 | /* Configure MPP16 as watchdog NMI, MPP17 as watchdog WDE */ | 1316 | /* Configure MPP16 as watchdog NMI, MPP17 as watchdog WDE */ |
1316 | spin_lock_irqsave(&mv64x60_lock, flags); | 1317 | spin_lock_irqsave(&mv64x60_lock, flags); |
1317 | data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); | 1318 | data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); |
1318 | data &= ~(0x0000000f << 0); | 1319 | data &= ~(0x0000000f << 0); |
1319 | data |= (0x00000004 << 0); | 1320 | data |= (0x00000004 << 0); |
1320 | data &= ~(0x0000000f << 4); | 1321 | data &= ~(0x0000000f << 4); |
1321 | data |= (0x00000004 << 4); | 1322 | data |= (0x00000004 << 4); |
1322 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); | 1323 | mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); |
1323 | spin_unlock_irqrestore(&mv64x60_lock, flags); | 1324 | spin_unlock_irqrestore(&mv64x60_lock, flags); |
1324 | 1325 | ||
1325 | /* All LEDs off */ | 1326 | /* All LEDs off */ |
1326 | data8 = inb(PPC7D_CPLD_LEDS); | 1327 | data8 = inb(PPC7D_CPLD_LEDS); |
1327 | data8 &= ~0x08; | 1328 | data8 &= ~0x08; |
1328 | data8 |= 0x07; | 1329 | data8 |= 0x07; |
1329 | outb(data8, PPC7D_CPLD_LEDS); | 1330 | outb(data8, PPC7D_CPLD_LEDS); |
1330 | 1331 | ||
1331 | /* Hook up RTC. We couldn't do this earlier because we need the I2C subsystem */ | 1332 | /* Hook up RTC. We couldn't do this earlier because we need the I2C subsystem */ |
1332 | ppc_md.set_rtc_time = ppc7d_set_rtc_time; | 1333 | ppc_md.set_rtc_time = ppc7d_set_rtc_time; |
1333 | ppc_md.get_rtc_time = ppc7d_get_rtc_time; | 1334 | ppc_md.get_rtc_time = ppc7d_get_rtc_time; |
1334 | 1335 | ||
1335 | pr_debug("%s: exit\n", __FUNCTION__); | 1336 | pr_debug("%s: exit\n", __FUNCTION__); |
1336 | } | 1337 | } |
1337 | 1338 | ||
1338 | /* Called from machine_init(), early, before any of the __init functions | 1339 | /* Called from machine_init(), early, before any of the __init functions |
1339 | * have run. We must init software-configurable pins before other functions | 1340 | * have run. We must init software-configurable pins before other functions |
1340 | * such as interrupt controllers are initialised. | 1341 | * such as interrupt controllers are initialised. |
1341 | */ | 1342 | */ |
1342 | void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 1343 | void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
1343 | unsigned long r6, unsigned long r7) | 1344 | unsigned long r6, unsigned long r7) |
1344 | { | 1345 | { |
1345 | u8 val8; | 1346 | u8 val8; |
1346 | u8 rev_num; | 1347 | u8 rev_num; |
1347 | 1348 | ||
1348 | /* Map 0xe0000000-0xffffffff early because we need access to SRAM | 1349 | /* Map 0xe0000000-0xffffffff early because we need access to SRAM |
1349 | * and the ISA memory space (for serial port) here. This mapping | 1350 | * and the ISA memory space (for serial port) here. This mapping |
1350 | * is redone properly in ppc7d_map_io() later. | 1351 | * is redone properly in ppc7d_map_io() later. |
1351 | */ | 1352 | */ |
1352 | mtspr(SPRN_DBAT3U, 0xe0003fff); | 1353 | mtspr(SPRN_DBAT3U, 0xe0003fff); |
1353 | mtspr(SPRN_DBAT3L, 0xe000002a); | 1354 | mtspr(SPRN_DBAT3L, 0xe000002a); |
1354 | 1355 | ||
1355 | /* | 1356 | /* |
1356 | * Zero SRAM. Note that this generates parity errors on | 1357 | * Zero SRAM. Note that this generates parity errors on |
1357 | * internal data path in SRAM if it's first time accessing it | 1358 | * internal data path in SRAM if it's first time accessing it |
1358 | * after reset. | 1359 | * after reset. |
1359 | * | 1360 | * |
1360 | * We do this ASAP to avoid parity errors when reading | 1361 | * We do this ASAP to avoid parity errors when reading |
1361 | * uninitialized SRAM. | 1362 | * uninitialized SRAM. |
1362 | */ | 1363 | */ |
1363 | memset((void *)PPC7D_INTERNAL_SRAM_BASE, 0, MV64360_SRAM_SIZE); | 1364 | memset((void *)PPC7D_INTERNAL_SRAM_BASE, 0, MV64360_SRAM_SIZE); |
1364 | 1365 | ||
1365 | pr_debug("platform_init: r3-r7: %lx %lx %lx %lx %lx\n", | 1366 | pr_debug("platform_init: r3-r7: %lx %lx %lx %lx %lx\n", |
1366 | r3, r4, r5, r6, r7); | 1367 | r3, r4, r5, r6, r7); |
1367 | 1368 | ||
1368 | parse_bootinfo(find_bootinfo()); | 1369 | parse_bootinfo(find_bootinfo()); |
1369 | 1370 | ||
1370 | /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer) | 1371 | /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer) |
1371 | * are non-zero, then we should use the board info from the bd_t | 1372 | * are non-zero, then we should use the board info from the bd_t |
1372 | * structure and the cmdline pointed to by r6 instead of the | 1373 | * structure and the cmdline pointed to by r6 instead of the |
1373 | * information from birecs, if any. Otherwise, use the information | 1374 | * information from birecs, if any. Otherwise, use the information |
1374 | * from birecs as discovered by the preceding call to | 1375 | * from birecs as discovered by the preceding call to |
1375 | * parse_bootinfo(). This rule should work with both PPCBoot, which | 1376 | * parse_bootinfo(). This rule should work with both PPCBoot, which |
1376 | * uses a bd_t board info structure, and the kernel boot wrapper, | 1377 | * uses a bd_t board info structure, and the kernel boot wrapper, |
1377 | * which uses birecs. | 1378 | * which uses birecs. |
1378 | */ | 1379 | */ |
1379 | if (r3 && r6) { | 1380 | if (r3 && r6) { |
1380 | bd_t *bp = (bd_t *) __res; | 1381 | bd_t *bp = (bd_t *) __res; |
1381 | 1382 | ||
1382 | /* copy board info structure */ | 1383 | /* copy board info structure */ |
1383 | memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t)); | 1384 | memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t)); |
1384 | /* copy command line */ | 1385 | /* copy command line */ |
1385 | *(char *)(r7 + KERNELBASE) = 0; | 1386 | *(char *)(r7 + KERNELBASE) = 0; |
1386 | strcpy(cmd_line, (char *)(r6 + KERNELBASE)); | 1387 | strcpy(cmd_line, (char *)(r6 + KERNELBASE)); |
1387 | 1388 | ||
1388 | printk(KERN_INFO "Board info data:-\n"); | 1389 | printk(KERN_INFO "Board info data:-\n"); |
1389 | printk(KERN_INFO " Internal freq: %lu MHz, bus freq: %lu MHz\n", | 1390 | printk(KERN_INFO " Internal freq: %lu MHz, bus freq: %lu MHz\n", |
1390 | bp->bi_intfreq, bp->bi_busfreq); | 1391 | bp->bi_intfreq, bp->bi_busfreq); |
1391 | printk(KERN_INFO " Memory: %lx, size %lx\n", bp->bi_memstart, | 1392 | printk(KERN_INFO " Memory: %lx, size %lx\n", bp->bi_memstart, |
1392 | bp->bi_memsize); | 1393 | bp->bi_memsize); |
1393 | printk(KERN_INFO " Console baudrate: %lu\n", bp->bi_baudrate); | 1394 | printk(KERN_INFO " Console baudrate: %lu\n", bp->bi_baudrate); |
1394 | printk(KERN_INFO " Ethernet address: " | 1395 | printk(KERN_INFO " Ethernet address: " |
1395 | "%02x:%02x:%02x:%02x:%02x:%02x\n", | 1396 | "%02x:%02x:%02x:%02x:%02x:%02x\n", |
1396 | bp->bi_enetaddr[0], bp->bi_enetaddr[1], | 1397 | bp->bi_enetaddr[0], bp->bi_enetaddr[1], |
1397 | bp->bi_enetaddr[2], bp->bi_enetaddr[3], | 1398 | bp->bi_enetaddr[2], bp->bi_enetaddr[3], |
1398 | bp->bi_enetaddr[4], bp->bi_enetaddr[5]); | 1399 | bp->bi_enetaddr[4], bp->bi_enetaddr[5]); |
1399 | } | 1400 | } |
1400 | #ifdef CONFIG_BLK_DEV_INITRD | 1401 | #ifdef CONFIG_BLK_DEV_INITRD |
1401 | /* take care of initrd if we have one */ | 1402 | /* take care of initrd if we have one */ |
1402 | if (r4) { | 1403 | if (r4) { |
1403 | initrd_start = r4 + KERNELBASE; | 1404 | initrd_start = r4 + KERNELBASE; |
1404 | initrd_end = r5 + KERNELBASE; | 1405 | initrd_end = r5 + KERNELBASE; |
1405 | printk(KERN_INFO "INITRD @ %lx/%lx\n", initrd_start, initrd_end); | 1406 | printk(KERN_INFO "INITRD @ %lx/%lx\n", initrd_start, initrd_end); |
1406 | } | 1407 | } |
1407 | #endif /* CONFIG_BLK_DEV_INITRD */ | 1408 | #endif /* CONFIG_BLK_DEV_INITRD */ |
1408 | 1409 | ||
1409 | /* Map in board regs, etc. */ | 1410 | /* Map in board regs, etc. */ |
1410 | isa_io_base = 0xe8000000; | 1411 | isa_io_base = 0xe8000000; |
1411 | isa_mem_base = 0xe8000000; | 1412 | isa_mem_base = 0xe8000000; |
1412 | pci_dram_offset = 0x00000000; | 1413 | pci_dram_offset = 0x00000000; |
1413 | ISA_DMA_THRESHOLD = 0x00ffffff; | 1414 | ISA_DMA_THRESHOLD = 0x00ffffff; |
1414 | DMA_MODE_READ = 0x44; | 1415 | DMA_MODE_READ = 0x44; |
1415 | DMA_MODE_WRITE = 0x48; | 1416 | DMA_MODE_WRITE = 0x48; |
1416 | 1417 | ||
1417 | ppc_md.setup_arch = ppc7d_setup_arch; | 1418 | ppc_md.setup_arch = ppc7d_setup_arch; |
1418 | ppc_md.init = ppc7d_init2; | 1419 | ppc_md.init = ppc7d_init2; |
1419 | ppc_md.show_cpuinfo = ppc7d_show_cpuinfo; | 1420 | ppc_md.show_cpuinfo = ppc7d_show_cpuinfo; |
1420 | /* XXX this is broken... */ | 1421 | /* XXX this is broken... */ |
1421 | ppc_md.irq_canonicalize = ppc7d_irq_canonicalize; | 1422 | ppc_md.irq_canonicalize = ppc7d_irq_canonicalize; |
1422 | ppc_md.init_IRQ = ppc7d_init_irq; | 1423 | ppc_md.init_IRQ = ppc7d_init_irq; |
1423 | ppc_md.get_irq = ppc7d_get_irq; | 1424 | ppc_md.get_irq = ppc7d_get_irq; |
1424 | 1425 | ||
1425 | ppc_md.restart = ppc7d_restart; | 1426 | ppc_md.restart = ppc7d_restart; |
1426 | ppc_md.power_off = ppc7d_power_off; | 1427 | ppc_md.power_off = ppc7d_power_off; |
1427 | ppc_md.halt = ppc7d_halt; | 1428 | ppc_md.halt = ppc7d_halt; |
1428 | 1429 | ||
1429 | ppc_md.find_end_of_memory = ppc7d_find_end_of_memory; | 1430 | ppc_md.find_end_of_memory = ppc7d_find_end_of_memory; |
1430 | ppc_md.setup_io_mappings = ppc7d_map_io; | 1431 | ppc_md.setup_io_mappings = ppc7d_map_io; |
1431 | 1432 | ||
1432 | ppc_md.time_init = NULL; | 1433 | ppc_md.time_init = NULL; |
1433 | ppc_md.set_rtc_time = NULL; | 1434 | ppc_md.set_rtc_time = NULL; |
1434 | ppc_md.get_rtc_time = NULL; | 1435 | ppc_md.get_rtc_time = NULL; |
1435 | ppc_md.calibrate_decr = ppc7d_calibrate_decr; | 1436 | ppc_md.calibrate_decr = ppc7d_calibrate_decr; |
1436 | ppc_md.nvram_read_val = NULL; | 1437 | ppc_md.nvram_read_val = NULL; |
1437 | ppc_md.nvram_write_val = NULL; | 1438 | ppc_md.nvram_write_val = NULL; |
1438 | 1439 | ||
1439 | ppc_md.heartbeat = ppc7d_heartbeat; | 1440 | ppc_md.heartbeat = ppc7d_heartbeat; |
1440 | ppc_md.heartbeat_reset = HZ; | 1441 | ppc_md.heartbeat_reset = HZ; |
1441 | ppc_md.heartbeat_count = ppc_md.heartbeat_reset; | 1442 | ppc_md.heartbeat_count = ppc_md.heartbeat_reset; |
1442 | 1443 | ||
1443 | ppc_md.pcibios_fixup_bus = ppc7d_pci_fixup_bus; | 1444 | ppc_md.pcibios_fixup_bus = ppc7d_pci_fixup_bus; |
1444 | 1445 | ||
1445 | #if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH) || \ | 1446 | #if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH) || \ |
1446 | defined(CONFIG_I2C_MV64XXX) | 1447 | defined(CONFIG_I2C_MV64XXX) |
1447 | platform_notify = ppc7d_platform_notify; | 1448 | platform_notify = ppc7d_platform_notify; |
1448 | #endif | 1449 | #endif |
1449 | 1450 | ||
1450 | #ifdef CONFIG_SERIAL_MPSC | 1451 | #ifdef CONFIG_SERIAL_MPSC |
1451 | /* On PPC7D, we must configure MPSC support via CPLD control | 1452 | /* On PPC7D, we must configure MPSC support via CPLD control |
1452 | * registers. | 1453 | * registers. |
1453 | */ | 1454 | */ |
1454 | outb(PPC7D_CPLD_RTS_COM4_SCLK | | 1455 | outb(PPC7D_CPLD_RTS_COM4_SCLK | |
1455 | PPC7D_CPLD_RTS_COM56_ENABLED, PPC7D_CPLD_RTS); | 1456 | PPC7D_CPLD_RTS_COM56_ENABLED, PPC7D_CPLD_RTS); |
1456 | outb(PPC7D_CPLD_COMS_COM3_TCLKEN | | 1457 | outb(PPC7D_CPLD_COMS_COM3_TCLKEN | |
1457 | PPC7D_CPLD_COMS_COM3_TXEN | | 1458 | PPC7D_CPLD_COMS_COM3_TXEN | |
1458 | PPC7D_CPLD_COMS_COM4_TCLKEN | | 1459 | PPC7D_CPLD_COMS_COM4_TCLKEN | |
1459 | PPC7D_CPLD_COMS_COM4_TXEN, PPC7D_CPLD_COMS); | 1460 | PPC7D_CPLD_COMS_COM4_TXEN, PPC7D_CPLD_COMS); |
1460 | #endif /* CONFIG_SERIAL_MPSC */ | 1461 | #endif /* CONFIG_SERIAL_MPSC */ |
1461 | 1462 | ||
1462 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) | 1463 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) |
1463 | ppc7d_early_serial_map(); | 1464 | ppc7d_early_serial_map(); |
1464 | #ifdef CONFIG_SERIAL_TEXT_DEBUG | 1465 | #ifdef CONFIG_SERIAL_TEXT_DEBUG |
1465 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) | 1466 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) |
1466 | ppc_md.progress = mv64x60_mpsc_progress; | 1467 | ppc_md.progress = mv64x60_mpsc_progress; |
1467 | #elif defined(CONFIG_SERIAL_8250) | 1468 | #elif defined(CONFIG_SERIAL_8250) |
1468 | ppc_md.progress = gen550_progress; | 1469 | ppc_md.progress = gen550_progress; |
1469 | #else | 1470 | #else |
1470 | #error CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG has no supported CONFIG_SERIAL_XXX | 1471 | #error CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG has no supported CONFIG_SERIAL_XXX |
1471 | #endif /* CONFIG_SERIAL_8250 */ | 1472 | #endif /* CONFIG_SERIAL_8250 */ |
1472 | #endif /* CONFIG_SERIAL_TEXT_DEBUG */ | 1473 | #endif /* CONFIG_SERIAL_TEXT_DEBUG */ |
1473 | #endif /* CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG */ | 1474 | #endif /* CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG */ |
1474 | 1475 | ||
1475 | /* Enable write access to user flash. This is necessary for | 1476 | /* Enable write access to user flash. This is necessary for |
1476 | * flash probe. | 1477 | * flash probe. |
1477 | */ | 1478 | */ |
1478 | val8 = readb((void *)isa_io_base + PPC7D_CPLD_SW_FLASH_WRITE_PROTECT); | 1479 | val8 = readb((void *)isa_io_base + PPC7D_CPLD_SW_FLASH_WRITE_PROTECT); |
1479 | writeb(val8 | (PPC7D_CPLD_SW_FLASH_WRPROT_ENABLED & | 1480 | writeb(val8 | (PPC7D_CPLD_SW_FLASH_WRPROT_ENABLED & |
1480 | PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK), | 1481 | PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK), |
1481 | (void *)isa_io_base + PPC7D_CPLD_SW_FLASH_WRITE_PROTECT); | 1482 | (void *)isa_io_base + PPC7D_CPLD_SW_FLASH_WRITE_PROTECT); |
1482 | 1483 | ||
1483 | /* Determine if this board has IBM ALMA VME devices */ | 1484 | /* Determine if this board has IBM ALMA VME devices */ |
1484 | val8 = readb((void *)isa_io_base + PPC7D_CPLD_BOARD_REVISION); | 1485 | val8 = readb((void *)isa_io_base + PPC7D_CPLD_BOARD_REVISION); |
1485 | rev_num = (val8 & PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK) >> 5; | 1486 | rev_num = (val8 & PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK) >> 5; |
1486 | if (rev_num <= 1) | 1487 | if (rev_num <= 1) |
1487 | ppc7d_has_alma = 1; | 1488 | ppc7d_has_alma = 1; |
1488 | 1489 | ||
1489 | #ifdef DEBUG | 1490 | #ifdef DEBUG |
1490 | console_printk[0] = 8; | 1491 | console_printk[0] = 8; |
1491 | #endif | 1492 | #endif |
1492 | } | 1493 | } |
1493 | 1494 |
arch/ppc/platforms/spruce.c
1 | /* | 1 | /* |
2 | * Board and PCI setup routines for IBM Spruce | 2 | * Board and PCI setup routines for IBM Spruce |
3 | * | 3 | * |
4 | * Author: MontaVista Software <source@mvista.com> | 4 | * Author: MontaVista Software <source@mvista.com> |
5 | * | 5 | * |
6 | * 2000-2004 (c) MontaVista, Software, Inc. This file is licensed under | 6 | * 2000-2004 (c) MontaVista, Software, Inc. This file is licensed under |
7 | * the terms of the GNU General Public License version 2. This program | 7 | * the terms of the GNU General Public License version 2. This program |
8 | * is licensed "as is" without any warranty of any kind, whether express | 8 | * is licensed "as is" without any warranty of any kind, whether express |
9 | * or implied. | 9 | * or implied. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/stddef.h> | 12 | #include <linux/stddef.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/reboot.h> | 16 | #include <linux/reboot.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/kdev_t.h> | 18 | #include <linux/kdev_t.h> |
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/major.h> | 20 | #include <linux/major.h> |
21 | #include <linux/initrd.h> | 21 | #include <linux/initrd.h> |
22 | #include <linux/console.h> | 22 | #include <linux/console.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/ide.h> | 25 | #include <linux/ide.h> |
26 | #include <linux/root_dev.h> | 26 | #include <linux/root_dev.h> |
27 | #include <linux/serial.h> | 27 | #include <linux/serial.h> |
28 | #include <linux/tty.h> | 28 | #include <linux/tty.h> |
29 | #include <linux/serial_core.h> | 29 | #include <linux/serial_core.h> |
30 | #include <linux/serial_8250.h> | ||
30 | 31 | ||
31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
32 | #include <asm/pgtable.h> | 33 | #include <asm/pgtable.h> |
33 | #include <asm/page.h> | 34 | #include <asm/page.h> |
34 | #include <asm/dma.h> | 35 | #include <asm/dma.h> |
35 | #include <asm/io.h> | 36 | #include <asm/io.h> |
36 | #include <asm/machdep.h> | 37 | #include <asm/machdep.h> |
37 | #include <asm/time.h> | 38 | #include <asm/time.h> |
38 | #include <asm/todc.h> | 39 | #include <asm/todc.h> |
39 | #include <asm/bootinfo.h> | 40 | #include <asm/bootinfo.h> |
40 | #include <asm/kgdb.h> | 41 | #include <asm/kgdb.h> |
41 | 42 | ||
42 | #include <syslib/cpc700.h> | 43 | #include <syslib/cpc700.h> |
43 | 44 | ||
44 | #include "spruce.h" | 45 | #include "spruce.h" |
45 | 46 | ||
46 | static inline int | 47 | static inline int |
47 | spruce_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 48 | spruce_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) |
48 | { | 49 | { |
49 | static char pci_irq_table[][4] = | 50 | static char pci_irq_table[][4] = |
50 | /* | 51 | /* |
51 | * PCI IDSEL/INTPIN->INTLINE | 52 | * PCI IDSEL/INTPIN->INTLINE |
52 | * A B C D | 53 | * A B C D |
53 | */ | 54 | */ |
54 | { | 55 | { |
55 | {23, 24, 25, 26}, /* IDSEL 1 - PCI slot 3 */ | 56 | {23, 24, 25, 26}, /* IDSEL 1 - PCI slot 3 */ |
56 | {24, 25, 26, 23}, /* IDSEL 2 - PCI slot 2 */ | 57 | {24, 25, 26, 23}, /* IDSEL 2 - PCI slot 2 */ |
57 | {25, 26, 23, 24}, /* IDSEL 3 - PCI slot 1 */ | 58 | {25, 26, 23, 24}, /* IDSEL 3 - PCI slot 1 */ |
58 | {26, 23, 24, 25}, /* IDSEL 4 - PCI slot 0 */ | 59 | {26, 23, 24, 25}, /* IDSEL 4 - PCI slot 0 */ |
59 | }; | 60 | }; |
60 | 61 | ||
61 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | 62 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; |
62 | return PCI_IRQ_TABLE_LOOKUP; | 63 | return PCI_IRQ_TABLE_LOOKUP; |
63 | } | 64 | } |
64 | 65 | ||
65 | static void __init | 66 | static void __init |
66 | spruce_setup_hose(void) | 67 | spruce_setup_hose(void) |
67 | { | 68 | { |
68 | struct pci_controller *hose; | 69 | struct pci_controller *hose; |
69 | 70 | ||
70 | /* Setup hose */ | 71 | /* Setup hose */ |
71 | hose = pcibios_alloc_controller(); | 72 | hose = pcibios_alloc_controller(); |
72 | if (!hose) | 73 | if (!hose) |
73 | return; | 74 | return; |
74 | 75 | ||
75 | hose->first_busno = 0; | 76 | hose->first_busno = 0; |
76 | hose->last_busno = 0xff; | 77 | hose->last_busno = 0xff; |
77 | 78 | ||
78 | pci_init_resource(&hose->io_resource, | 79 | pci_init_resource(&hose->io_resource, |
79 | SPRUCE_PCI_LOWER_IO, | 80 | SPRUCE_PCI_LOWER_IO, |
80 | SPRUCE_PCI_UPPER_IO, | 81 | SPRUCE_PCI_UPPER_IO, |
81 | IORESOURCE_IO, | 82 | IORESOURCE_IO, |
82 | "PCI host bridge"); | 83 | "PCI host bridge"); |
83 | 84 | ||
84 | pci_init_resource(&hose->mem_resources[0], | 85 | pci_init_resource(&hose->mem_resources[0], |
85 | SPRUCE_PCI_LOWER_MEM, | 86 | SPRUCE_PCI_LOWER_MEM, |
86 | SPRUCE_PCI_UPPER_MEM, | 87 | SPRUCE_PCI_UPPER_MEM, |
87 | IORESOURCE_MEM, | 88 | IORESOURCE_MEM, |
88 | "PCI host bridge"); | 89 | "PCI host bridge"); |
89 | 90 | ||
90 | hose->io_space.start = SPRUCE_PCI_LOWER_IO; | 91 | hose->io_space.start = SPRUCE_PCI_LOWER_IO; |
91 | hose->io_space.end = SPRUCE_PCI_UPPER_IO; | 92 | hose->io_space.end = SPRUCE_PCI_UPPER_IO; |
92 | hose->mem_space.start = SPRUCE_PCI_LOWER_MEM; | 93 | hose->mem_space.start = SPRUCE_PCI_LOWER_MEM; |
93 | hose->mem_space.end = SPRUCE_PCI_UPPER_MEM; | 94 | hose->mem_space.end = SPRUCE_PCI_UPPER_MEM; |
94 | hose->io_base_virt = (void *)SPRUCE_ISA_IO_BASE; | 95 | hose->io_base_virt = (void *)SPRUCE_ISA_IO_BASE; |
95 | 96 | ||
96 | setup_indirect_pci(hose, | 97 | setup_indirect_pci(hose, |
97 | SPRUCE_PCI_CONFIG_ADDR, | 98 | SPRUCE_PCI_CONFIG_ADDR, |
98 | SPRUCE_PCI_CONFIG_DATA); | 99 | SPRUCE_PCI_CONFIG_DATA); |
99 | 100 | ||
100 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | 101 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); |
101 | 102 | ||
102 | ppc_md.pci_swizzle = common_swizzle; | 103 | ppc_md.pci_swizzle = common_swizzle; |
103 | ppc_md.pci_map_irq = spruce_map_irq; | 104 | ppc_md.pci_map_irq = spruce_map_irq; |
104 | } | 105 | } |
105 | 106 | ||
106 | /* | 107 | /* |
107 | * CPC700 PIC interrupt programming table | 108 | * CPC700 PIC interrupt programming table |
108 | * | 109 | * |
109 | * First entry is the sensitivity (level/edge), second is the polarity. | 110 | * First entry is the sensitivity (level/edge), second is the polarity. |
110 | */ | 111 | */ |
111 | unsigned int cpc700_irq_assigns[32][2] = { | 112 | unsigned int cpc700_irq_assigns[32][2] = { |
112 | { 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */ | 113 | { 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */ |
113 | { 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */ | 114 | { 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */ |
114 | { 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */ | 115 | { 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */ |
115 | { 0, 1 }, /* IRQ 3: UART 0 - active high */ | 116 | { 0, 1 }, /* IRQ 3: UART 0 - active high */ |
116 | { 0, 1 }, /* IRQ 4: UART 1 - active high */ | 117 | { 0, 1 }, /* IRQ 4: UART 1 - active high */ |
117 | { 0, 1 }, /* IRQ 5: ICC 0 - active high */ | 118 | { 0, 1 }, /* IRQ 5: ICC 0 - active high */ |
118 | { 0, 1 }, /* IRQ 6: ICC 1 - active high */ | 119 | { 0, 1 }, /* IRQ 6: ICC 1 - active high */ |
119 | { 0, 1 }, /* IRQ 7: GPT Compare 0 - active high */ | 120 | { 0, 1 }, /* IRQ 7: GPT Compare 0 - active high */ |
120 | { 0, 1 }, /* IRQ 8: GPT Compare 1 - active high */ | 121 | { 0, 1 }, /* IRQ 8: GPT Compare 1 - active high */ |
121 | { 0, 1 }, /* IRQ 9: GPT Compare 2 - active high */ | 122 | { 0, 1 }, /* IRQ 9: GPT Compare 2 - active high */ |
122 | { 0, 1 }, /* IRQ 10: GPT Compare 3 - active high */ | 123 | { 0, 1 }, /* IRQ 10: GPT Compare 3 - active high */ |
123 | { 0, 1 }, /* IRQ 11: GPT Compare 4 - active high */ | 124 | { 0, 1 }, /* IRQ 11: GPT Compare 4 - active high */ |
124 | { 0, 1 }, /* IRQ 12: GPT Capture 0 - active high */ | 125 | { 0, 1 }, /* IRQ 12: GPT Capture 0 - active high */ |
125 | { 0, 1 }, /* IRQ 13: GPT Capture 1 - active high */ | 126 | { 0, 1 }, /* IRQ 13: GPT Capture 1 - active high */ |
126 | { 0, 1 }, /* IRQ 14: GPT Capture 2 - active high */ | 127 | { 0, 1 }, /* IRQ 14: GPT Capture 2 - active high */ |
127 | { 0, 1 }, /* IRQ 15: GPT Capture 3 - active high */ | 128 | { 0, 1 }, /* IRQ 15: GPT Capture 3 - active high */ |
128 | { 0, 1 }, /* IRQ 16: GPT Capture 4 - active high */ | 129 | { 0, 1 }, /* IRQ 16: GPT Capture 4 - active high */ |
129 | { 0, 0 }, /* IRQ 17: Reserved */ | 130 | { 0, 0 }, /* IRQ 17: Reserved */ |
130 | { 0, 0 }, /* IRQ 18: Reserved */ | 131 | { 0, 0 }, /* IRQ 18: Reserved */ |
131 | { 0, 0 }, /* IRQ 19: Reserved */ | 132 | { 0, 0 }, /* IRQ 19: Reserved */ |
132 | { 0, 1 }, /* IRQ 20: FPGA EXT_IRQ0 - active high */ | 133 | { 0, 1 }, /* IRQ 20: FPGA EXT_IRQ0 - active high */ |
133 | { 1, 1 }, /* IRQ 21: Mouse - rising edge */ | 134 | { 1, 1 }, /* IRQ 21: Mouse - rising edge */ |
134 | { 1, 1 }, /* IRQ 22: Keyboard - rising edge */ | 135 | { 1, 1 }, /* IRQ 22: Keyboard - rising edge */ |
135 | { 0, 0 }, /* IRQ 23: PCI Slot 3 - active low */ | 136 | { 0, 0 }, /* IRQ 23: PCI Slot 3 - active low */ |
136 | { 0, 0 }, /* IRQ 24: PCI Slot 2 - active low */ | 137 | { 0, 0 }, /* IRQ 24: PCI Slot 2 - active low */ |
137 | { 0, 0 }, /* IRQ 25: PCI Slot 1 - active low */ | 138 | { 0, 0 }, /* IRQ 25: PCI Slot 1 - active low */ |
138 | { 0, 0 }, /* IRQ 26: PCI Slot 0 - active low */ | 139 | { 0, 0 }, /* IRQ 26: PCI Slot 0 - active low */ |
139 | }; | 140 | }; |
140 | 141 | ||
141 | static void __init | 142 | static void __init |
142 | spruce_calibrate_decr(void) | 143 | spruce_calibrate_decr(void) |
143 | { | 144 | { |
144 | int freq, divisor = 4; | 145 | int freq, divisor = 4; |
145 | 146 | ||
146 | /* determine processor bus speed */ | 147 | /* determine processor bus speed */ |
147 | freq = SPRUCE_BUS_SPEED; | 148 | freq = SPRUCE_BUS_SPEED; |
148 | tb_ticks_per_jiffy = freq / HZ / divisor; | 149 | tb_ticks_per_jiffy = freq / HZ / divisor; |
149 | tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); | 150 | tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); |
150 | } | 151 | } |
151 | 152 | ||
152 | static int | 153 | static int |
153 | spruce_show_cpuinfo(struct seq_file *m) | 154 | spruce_show_cpuinfo(struct seq_file *m) |
154 | { | 155 | { |
155 | seq_printf(m, "vendor\t\t: IBM\n"); | 156 | seq_printf(m, "vendor\t\t: IBM\n"); |
156 | seq_printf(m, "machine\t\t: Spruce\n"); | 157 | seq_printf(m, "machine\t\t: Spruce\n"); |
157 | 158 | ||
158 | return 0; | 159 | return 0; |
159 | } | 160 | } |
160 | 161 | ||
161 | static void __init | 162 | static void __init |
162 | spruce_early_serial_map(void) | 163 | spruce_early_serial_map(void) |
163 | { | 164 | { |
164 | u32 uart_clk; | 165 | u32 uart_clk; |
165 | struct uart_port serial_req; | 166 | struct uart_port serial_req; |
166 | 167 | ||
167 | if (SPRUCE_UARTCLK_IS_33M(readb(SPRUCE_FPGA_REG_A))) | 168 | if (SPRUCE_UARTCLK_IS_33M(readb(SPRUCE_FPGA_REG_A))) |
168 | uart_clk = SPRUCE_BAUD_33M * 16; | 169 | uart_clk = SPRUCE_BAUD_33M * 16; |
169 | else | 170 | else |
170 | uart_clk = SPRUCE_BAUD_30M * 16; | 171 | uart_clk = SPRUCE_BAUD_30M * 16; |
171 | 172 | ||
172 | /* Setup serial port access */ | 173 | /* Setup serial port access */ |
173 | memset(&serial_req, 0, sizeof(serial_req)); | 174 | memset(&serial_req, 0, sizeof(serial_req)); |
174 | serial_req.uartclk = uart_clk; | 175 | serial_req.uartclk = uart_clk; |
175 | serial_req.irq = UART0_INT; | 176 | serial_req.irq = UART0_INT; |
176 | serial_req.flags = UPF_BOOT_AUTOCONF; | 177 | serial_req.flags = UPF_BOOT_AUTOCONF; |
177 | serial_req.iotype = UPIO_MEM; | 178 | serial_req.iotype = UPIO_MEM; |
178 | serial_req.membase = (u_char *)UART0_IO_BASE; | 179 | serial_req.membase = (u_char *)UART0_IO_BASE; |
179 | serial_req.regshift = 0; | 180 | serial_req.regshift = 0; |
180 | 181 | ||
181 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) | 182 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) |
182 | gen550_init(0, &serial_req); | 183 | gen550_init(0, &serial_req); |
183 | #endif | 184 | #endif |
184 | #ifdef CONFIG_SERIAL_8250 | 185 | #ifdef CONFIG_SERIAL_8250 |
185 | if (early_serial_setup(&serial_req) != 0) | 186 | if (early_serial_setup(&serial_req) != 0) |
186 | printk("Early serial init of port 0 failed\n"); | 187 | printk("Early serial init of port 0 failed\n"); |
187 | #endif | 188 | #endif |
188 | 189 | ||
189 | /* Assume early_serial_setup() doesn't modify serial_req */ | 190 | /* Assume early_serial_setup() doesn't modify serial_req */ |
190 | serial_req.line = 1; | 191 | serial_req.line = 1; |
191 | serial_req.irq = UART1_INT; | 192 | serial_req.irq = UART1_INT; |
192 | serial_req.membase = (u_char *)UART1_IO_BASE; | 193 | serial_req.membase = (u_char *)UART1_IO_BASE; |
193 | 194 | ||
194 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) | 195 | #if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) |
195 | gen550_init(1, &serial_req); | 196 | gen550_init(1, &serial_req); |
196 | #endif | 197 | #endif |
197 | #ifdef CONFIG_SERIAL_8250 | 198 | #ifdef CONFIG_SERIAL_8250 |
198 | if (early_serial_setup(&serial_req) != 0) | 199 | if (early_serial_setup(&serial_req) != 0) |
199 | printk("Early serial init of port 1 failed\n"); | 200 | printk("Early serial init of port 1 failed\n"); |
200 | #endif | 201 | #endif |
201 | } | 202 | } |
202 | 203 | ||
203 | TODC_ALLOC(); | 204 | TODC_ALLOC(); |
204 | 205 | ||
205 | static void __init | 206 | static void __init |
206 | spruce_setup_arch(void) | 207 | spruce_setup_arch(void) |
207 | { | 208 | { |
208 | /* Setup TODC access */ | 209 | /* Setup TODC access */ |
209 | TODC_INIT(TODC_TYPE_DS1643, 0, 0, SPRUCE_RTC_BASE_ADDR, 8); | 210 | TODC_INIT(TODC_TYPE_DS1643, 0, 0, SPRUCE_RTC_BASE_ADDR, 8); |
210 | 211 | ||
211 | /* init to some ~sane value until calibrate_delay() runs */ | 212 | /* init to some ~sane value until calibrate_delay() runs */ |
212 | loops_per_jiffy = 50000000 / HZ; | 213 | loops_per_jiffy = 50000000 / HZ; |
213 | 214 | ||
214 | /* Setup PCI host bridge */ | 215 | /* Setup PCI host bridge */ |
215 | spruce_setup_hose(); | 216 | spruce_setup_hose(); |
216 | 217 | ||
217 | #ifdef CONFIG_BLK_DEV_INITRD | 218 | #ifdef CONFIG_BLK_DEV_INITRD |
218 | if (initrd_start) | 219 | if (initrd_start) |
219 | ROOT_DEV = Root_RAM0; | 220 | ROOT_DEV = Root_RAM0; |
220 | else | 221 | else |
221 | #endif | 222 | #endif |
222 | #ifdef CONFIG_ROOT_NFS | 223 | #ifdef CONFIG_ROOT_NFS |
223 | ROOT_DEV = Root_NFS; | 224 | ROOT_DEV = Root_NFS; |
224 | #else | 225 | #else |
225 | ROOT_DEV = Root_SDA1; | 226 | ROOT_DEV = Root_SDA1; |
226 | #endif | 227 | #endif |
227 | 228 | ||
228 | /* Identify the system */ | 229 | /* Identify the system */ |
229 | printk(KERN_INFO "System Identification: IBM Spruce\n"); | 230 | printk(KERN_INFO "System Identification: IBM Spruce\n"); |
230 | printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); | 231 | printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); |
231 | } | 232 | } |
232 | 233 | ||
233 | static void | 234 | static void |
234 | spruce_restart(char *cmd) | 235 | spruce_restart(char *cmd) |
235 | { | 236 | { |
236 | local_irq_disable(); | 237 | local_irq_disable(); |
237 | 238 | ||
238 | /* SRR0 has system reset vector, SRR1 has default MSR value */ | 239 | /* SRR0 has system reset vector, SRR1 has default MSR value */ |
239 | /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ | 240 | /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ |
240 | __asm__ __volatile__ | 241 | __asm__ __volatile__ |
241 | ("\n\ | 242 | ("\n\ |
242 | lis 3,0xfff0 \n\ | 243 | lis 3,0xfff0 \n\ |
243 | ori 3,3,0x0100 \n\ | 244 | ori 3,3,0x0100 \n\ |
244 | mtspr 26,3 \n\ | 245 | mtspr 26,3 \n\ |
245 | li 3,0 \n\ | 246 | li 3,0 \n\ |
246 | mtspr 27,3 \n\ | 247 | mtspr 27,3 \n\ |
247 | rfi \n\ | 248 | rfi \n\ |
248 | "); | 249 | "); |
249 | for(;;); | 250 | for(;;); |
250 | } | 251 | } |
251 | 252 | ||
252 | static void | 253 | static void |
253 | spruce_power_off(void) | 254 | spruce_power_off(void) |
254 | { | 255 | { |
255 | for(;;); | 256 | for(;;); |
256 | } | 257 | } |
257 | 258 | ||
258 | static void | 259 | static void |
259 | spruce_halt(void) | 260 | spruce_halt(void) |
260 | { | 261 | { |
261 | spruce_restart(NULL); | 262 | spruce_restart(NULL); |
262 | } | 263 | } |
263 | 264 | ||
264 | static void __init | 265 | static void __init |
265 | spruce_map_io(void) | 266 | spruce_map_io(void) |
266 | { | 267 | { |
267 | io_block_mapping(SPRUCE_PCI_IO_BASE, SPRUCE_PCI_PHY_IO_BASE, | 268 | io_block_mapping(SPRUCE_PCI_IO_BASE, SPRUCE_PCI_PHY_IO_BASE, |
268 | 0x08000000, _PAGE_IO); | 269 | 0x08000000, _PAGE_IO); |
269 | } | 270 | } |
270 | 271 | ||
271 | /* | 272 | /* |
272 | * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1. | 273 | * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1. |
273 | */ | 274 | */ |
274 | static __inline__ void | 275 | static __inline__ void |
275 | spruce_set_bat(void) | 276 | spruce_set_bat(void) |
276 | { | 277 | { |
277 | mb(); | 278 | mb(); |
278 | mtspr(SPRN_DBAT1U, 0xf8000ffe); | 279 | mtspr(SPRN_DBAT1U, 0xf8000ffe); |
279 | mtspr(SPRN_DBAT1L, 0xf800002a); | 280 | mtspr(SPRN_DBAT1L, 0xf800002a); |
280 | mb(); | 281 | mb(); |
281 | } | 282 | } |
282 | 283 | ||
283 | void __init | 284 | void __init |
284 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 285 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
285 | unsigned long r6, unsigned long r7) | 286 | unsigned long r6, unsigned long r7) |
286 | { | 287 | { |
287 | parse_bootinfo(find_bootinfo()); | 288 | parse_bootinfo(find_bootinfo()); |
288 | 289 | ||
289 | /* Map in board regs, etc. */ | 290 | /* Map in board regs, etc. */ |
290 | spruce_set_bat(); | 291 | spruce_set_bat(); |
291 | 292 | ||
292 | isa_io_base = SPRUCE_ISA_IO_BASE; | 293 | isa_io_base = SPRUCE_ISA_IO_BASE; |
293 | pci_dram_offset = SPRUCE_PCI_SYS_MEM_BASE; | 294 | pci_dram_offset = SPRUCE_PCI_SYS_MEM_BASE; |
294 | 295 | ||
295 | ppc_md.setup_arch = spruce_setup_arch; | 296 | ppc_md.setup_arch = spruce_setup_arch; |
296 | ppc_md.show_cpuinfo = spruce_show_cpuinfo; | 297 | ppc_md.show_cpuinfo = spruce_show_cpuinfo; |
297 | ppc_md.init_IRQ = cpc700_init_IRQ; | 298 | ppc_md.init_IRQ = cpc700_init_IRQ; |
298 | ppc_md.get_irq = cpc700_get_irq; | 299 | ppc_md.get_irq = cpc700_get_irq; |
299 | 300 | ||
300 | ppc_md.setup_io_mappings = spruce_map_io; | 301 | ppc_md.setup_io_mappings = spruce_map_io; |
301 | 302 | ||
302 | ppc_md.restart = spruce_restart; | 303 | ppc_md.restart = spruce_restart; |
303 | ppc_md.power_off = spruce_power_off; | 304 | ppc_md.power_off = spruce_power_off; |
304 | ppc_md.halt = spruce_halt; | 305 | ppc_md.halt = spruce_halt; |
305 | 306 | ||
306 | ppc_md.time_init = todc_time_init; | 307 | ppc_md.time_init = todc_time_init; |
307 | ppc_md.set_rtc_time = todc_set_rtc_time; | 308 | ppc_md.set_rtc_time = todc_set_rtc_time; |
308 | ppc_md.get_rtc_time = todc_get_rtc_time; | 309 | ppc_md.get_rtc_time = todc_get_rtc_time; |
309 | ppc_md.calibrate_decr = spruce_calibrate_decr; | 310 | ppc_md.calibrate_decr = spruce_calibrate_decr; |
310 | 311 | ||
311 | ppc_md.nvram_read_val = todc_direct_read_val; | 312 | ppc_md.nvram_read_val = todc_direct_read_val; |
312 | ppc_md.nvram_write_val = todc_direct_write_val; | 313 | ppc_md.nvram_write_val = todc_direct_write_val; |
313 | 314 | ||
314 | spruce_early_serial_map(); | 315 | spruce_early_serial_map(); |
315 | 316 | ||
316 | #ifdef CONFIG_SERIAL_TEXT_DEBUG | 317 | #ifdef CONFIG_SERIAL_TEXT_DEBUG |
317 | ppc_md.progress = gen550_progress; | 318 | ppc_md.progress = gen550_progress; |
318 | #endif /* CONFIG_SERIAL_TEXT_DEBUG */ | 319 | #endif /* CONFIG_SERIAL_TEXT_DEBUG */ |
319 | #ifdef CONFIG_KGDB | 320 | #ifdef CONFIG_KGDB |
320 | ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; | 321 | ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; |
321 | #endif | 322 | #endif |
322 | } | 323 | } |
323 | 324 |
drivers/parisc/superio.c
1 | /* National Semiconductor NS87560UBD Super I/O controller used in | 1 | /* National Semiconductor NS87560UBD Super I/O controller used in |
2 | * HP [BCJ]x000 workstations. | 2 | * HP [BCJ]x000 workstations. |
3 | * | 3 | * |
4 | * This chip is a horrid piece of engineering, and National | 4 | * This chip is a horrid piece of engineering, and National |
5 | * denies any knowledge of its existence. Thus no datasheet is | 5 | * denies any knowledge of its existence. Thus no datasheet is |
6 | * available off www.national.com. | 6 | * available off www.national.com. |
7 | * | 7 | * |
8 | * (C) Copyright 2000 Linuxcare, Inc. | 8 | * (C) Copyright 2000 Linuxcare, Inc. |
9 | * (C) Copyright 2000 Linuxcare Canada, Inc. | 9 | * (C) Copyright 2000 Linuxcare Canada, Inc. |
10 | * (C) Copyright 2000 Martin K. Petersen <mkp@linuxcare.com> | 10 | * (C) Copyright 2000 Martin K. Petersen <mkp@linuxcare.com> |
11 | * (C) Copyright 2000 Alex deVries <alex@onefishtwo.ca> | 11 | * (C) Copyright 2000 Alex deVries <alex@onefishtwo.ca> |
12 | * (C) Copyright 2001 John Marvin <jsm fc hp com> | 12 | * (C) Copyright 2001 John Marvin <jsm fc hp com> |
13 | * (C) Copyright 2003 Grant Grundler <grundler parisc-linux org> | 13 | * (C) Copyright 2003 Grant Grundler <grundler parisc-linux org> |
14 | * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> | 14 | * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> |
15 | * (C) Copyright 2006 Helge Deller <deller@gmx.de> | 15 | * (C) Copyright 2006 Helge Deller <deller@gmx.de> |
16 | * | 16 | * |
17 | * This program is free software; you can redistribute it and/or | 17 | * This program is free software; you can redistribute it and/or |
18 | * modify it under the terms of the GNU General Public License as | 18 | * modify it under the terms of the GNU General Public License as |
19 | * published by the Free Software Foundation; either version 2 of | 19 | * published by the Free Software Foundation; either version 2 of |
20 | * the License, or (at your option) any later version. | 20 | * the License, or (at your option) any later version. |
21 | * | 21 | * |
22 | * The initial version of this is by Martin Peterson. Alex deVries | 22 | * The initial version of this is by Martin Peterson. Alex deVries |
23 | * has spent a bit of time trying to coax it into working. | 23 | * has spent a bit of time trying to coax it into working. |
24 | * | 24 | * |
25 | * Major changes to get basic interrupt infrastructure working to | 25 | * Major changes to get basic interrupt infrastructure working to |
26 | * hopefully be able to support all SuperIO devices. Currently | 26 | * hopefully be able to support all SuperIO devices. Currently |
27 | * works with serial. -- John Marvin <jsm@fc.hp.com> | 27 | * works with serial. -- John Marvin <jsm@fc.hp.com> |
28 | * | 28 | * |
29 | * Converted superio_init() to be a PCI_FIXUP_FINAL callee. | 29 | * Converted superio_init() to be a PCI_FIXUP_FINAL callee. |
30 | * -- Kyle McMartin <kyle@parisc-linux.org> | 30 | * -- Kyle McMartin <kyle@parisc-linux.org> |
31 | */ | 31 | */ |
32 | 32 | ||
33 | 33 | ||
34 | /* NOTES: | 34 | /* NOTES: |
35 | * | 35 | * |
36 | * Function 0 is an IDE controller. It is identical to a PC87415 IDE | 36 | * Function 0 is an IDE controller. It is identical to a PC87415 IDE |
37 | * controller (and identifies itself as such). | 37 | * controller (and identifies itself as such). |
38 | * | 38 | * |
39 | * Function 1 is a "Legacy I/O" controller. Under this function is a | 39 | * Function 1 is a "Legacy I/O" controller. Under this function is a |
40 | * whole mess of legacy I/O peripherals. Of course, HP hasn't enabled | 40 | * whole mess of legacy I/O peripherals. Of course, HP hasn't enabled |
41 | * all the functionality in hardware, but the following is available: | 41 | * all the functionality in hardware, but the following is available: |
42 | * | 42 | * |
43 | * Two 16550A compatible serial controllers | 43 | * Two 16550A compatible serial controllers |
44 | * An IEEE 1284 compatible parallel port | 44 | * An IEEE 1284 compatible parallel port |
45 | * A floppy disk controller | 45 | * A floppy disk controller |
46 | * | 46 | * |
47 | * Function 2 is a USB controller. | 47 | * Function 2 is a USB controller. |
48 | * | 48 | * |
49 | * We must be incredibly careful during initialization. Since all | 49 | * We must be incredibly careful during initialization. Since all |
50 | * interrupts are routed through function 1 (which is not allowed by | 50 | * interrupts are routed through function 1 (which is not allowed by |
51 | * the PCI spec), we need to program the PICs on the legacy I/O port | 51 | * the PCI spec), we need to program the PICs on the legacy I/O port |
52 | * *before* we attempt to set up IDE and USB. @#$!& | 52 | * *before* we attempt to set up IDE and USB. @#$!& |
53 | * | 53 | * |
54 | * According to HP, devices are only enabled by firmware if they have | 54 | * According to HP, devices are only enabled by firmware if they have |
55 | * a physical device connected. | 55 | * a physical device connected. |
56 | * | 56 | * |
57 | * Configuration register bits: | 57 | * Configuration register bits: |
58 | * 0x5A: FDC, SP1, IDE1, SP2, IDE2, PAR, Reserved, P92 | 58 | * 0x5A: FDC, SP1, IDE1, SP2, IDE2, PAR, Reserved, P92 |
59 | * 0x5B: RTC, 8259, 8254, DMA1, DMA2, KBC, P61, APM | 59 | * 0x5B: RTC, 8259, 8254, DMA1, DMA2, KBC, P61, APM |
60 | * | 60 | * |
61 | */ | 61 | */ |
62 | 62 | ||
63 | #include <linux/errno.h> | 63 | #include <linux/errno.h> |
64 | #include <linux/init.h> | 64 | #include <linux/init.h> |
65 | #include <linux/module.h> | 65 | #include <linux/module.h> |
66 | #include <linux/types.h> | 66 | #include <linux/types.h> |
67 | #include <linux/interrupt.h> | 67 | #include <linux/interrupt.h> |
68 | #include <linux/ioport.h> | 68 | #include <linux/ioport.h> |
69 | #include <linux/serial.h> | 69 | #include <linux/serial.h> |
70 | #include <linux/pci.h> | 70 | #include <linux/pci.h> |
71 | #include <linux/parport.h> | 71 | #include <linux/parport.h> |
72 | #include <linux/parport_pc.h> | 72 | #include <linux/parport_pc.h> |
73 | #include <linux/termios.h> | 73 | #include <linux/termios.h> |
74 | #include <linux/tty.h> | 74 | #include <linux/tty.h> |
75 | #include <linux/serial_core.h> | 75 | #include <linux/serial_core.h> |
76 | #include <linux/serial_8250.h> | ||
76 | #include <linux/delay.h> | 77 | #include <linux/delay.h> |
77 | 78 | ||
78 | #include <asm/io.h> | 79 | #include <asm/io.h> |
79 | #include <asm/hardware.h> | 80 | #include <asm/hardware.h> |
80 | #include <asm/superio.h> | 81 | #include <asm/superio.h> |
81 | 82 | ||
82 | static struct superio_device sio_dev; | 83 | static struct superio_device sio_dev; |
83 | 84 | ||
84 | 85 | ||
85 | #undef DEBUG_SUPERIO_INIT | 86 | #undef DEBUG_SUPERIO_INIT |
86 | 87 | ||
87 | #ifdef DEBUG_SUPERIO_INIT | 88 | #ifdef DEBUG_SUPERIO_INIT |
88 | #define DBG_INIT(x...) printk(x) | 89 | #define DBG_INIT(x...) printk(x) |
89 | #else | 90 | #else |
90 | #define DBG_INIT(x...) | 91 | #define DBG_INIT(x...) |
91 | #endif | 92 | #endif |
92 | 93 | ||
93 | #define SUPERIO "SuperIO" | 94 | #define SUPERIO "SuperIO" |
94 | #define PFX SUPERIO ": " | 95 | #define PFX SUPERIO ": " |
95 | 96 | ||
96 | static irqreturn_t | 97 | static irqreturn_t |
97 | superio_interrupt(int parent_irq, void *devp) | 98 | superio_interrupt(int parent_irq, void *devp) |
98 | { | 99 | { |
99 | u8 results; | 100 | u8 results; |
100 | u8 local_irq; | 101 | u8 local_irq; |
101 | 102 | ||
102 | /* Poll the 8259 to see if there's an interrupt. */ | 103 | /* Poll the 8259 to see if there's an interrupt. */ |
103 | outb (OCW3_POLL,IC_PIC1+0); | 104 | outb (OCW3_POLL,IC_PIC1+0); |
104 | 105 | ||
105 | results = inb(IC_PIC1+0); | 106 | results = inb(IC_PIC1+0); |
106 | 107 | ||
107 | /* | 108 | /* |
108 | * Bit 7: 1 = active Interrupt; 0 = no Interrupt pending | 109 | * Bit 7: 1 = active Interrupt; 0 = no Interrupt pending |
109 | * Bits 6-3: zero | 110 | * Bits 6-3: zero |
110 | * Bits 2-0: highest priority, active requesting interrupt ID (0-7) | 111 | * Bits 2-0: highest priority, active requesting interrupt ID (0-7) |
111 | */ | 112 | */ |
112 | if ((results & 0x80) == 0) { | 113 | if ((results & 0x80) == 0) { |
113 | /* I suspect "spurious" interrupts are from unmasking an IRQ. | 114 | /* I suspect "spurious" interrupts are from unmasking an IRQ. |
114 | * We don't know if an interrupt was/is pending and thus | 115 | * We don't know if an interrupt was/is pending and thus |
115 | * just call the handler for that IRQ as if it were pending. | 116 | * just call the handler for that IRQ as if it were pending. |
116 | */ | 117 | */ |
117 | return IRQ_NONE; | 118 | return IRQ_NONE; |
118 | } | 119 | } |
119 | 120 | ||
120 | /* Check to see which device is interrupting */ | 121 | /* Check to see which device is interrupting */ |
121 | local_irq = results & 0x0f; | 122 | local_irq = results & 0x0f; |
122 | 123 | ||
123 | if (local_irq == 2 || local_irq > 7) { | 124 | if (local_irq == 2 || local_irq > 7) { |
124 | printk(KERN_ERR PFX "slave interrupted!\n"); | 125 | printk(KERN_ERR PFX "slave interrupted!\n"); |
125 | return IRQ_HANDLED; | 126 | return IRQ_HANDLED; |
126 | } | 127 | } |
127 | 128 | ||
128 | if (local_irq == 7) { | 129 | if (local_irq == 7) { |
129 | 130 | ||
130 | /* Could be spurious. Check in service bits */ | 131 | /* Could be spurious. Check in service bits */ |
131 | 132 | ||
132 | outb(OCW3_ISR,IC_PIC1+0); | 133 | outb(OCW3_ISR,IC_PIC1+0); |
133 | results = inb(IC_PIC1+0); | 134 | results = inb(IC_PIC1+0); |
134 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ | 135 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ |
135 | printk(KERN_WARNING PFX "spurious interrupt!\n"); | 136 | printk(KERN_WARNING PFX "spurious interrupt!\n"); |
136 | return IRQ_HANDLED; | 137 | return IRQ_HANDLED; |
137 | } | 138 | } |
138 | } | 139 | } |
139 | 140 | ||
140 | /* Call the appropriate device's interrupt */ | 141 | /* Call the appropriate device's interrupt */ |
141 | __do_IRQ(local_irq); | 142 | __do_IRQ(local_irq); |
142 | 143 | ||
143 | /* set EOI - forces a new interrupt if a lower priority device | 144 | /* set EOI - forces a new interrupt if a lower priority device |
144 | * still needs service. | 145 | * still needs service. |
145 | */ | 146 | */ |
146 | outb((OCW2_SEOI|local_irq),IC_PIC1 + 0); | 147 | outb((OCW2_SEOI|local_irq),IC_PIC1 + 0); |
147 | return IRQ_HANDLED; | 148 | return IRQ_HANDLED; |
148 | } | 149 | } |
149 | 150 | ||
150 | /* Initialize Super I/O device */ | 151 | /* Initialize Super I/O device */ |
151 | static void | 152 | static void |
152 | superio_init(struct pci_dev *pcidev) | 153 | superio_init(struct pci_dev *pcidev) |
153 | { | 154 | { |
154 | struct superio_device *sio = &sio_dev; | 155 | struct superio_device *sio = &sio_dev; |
155 | struct pci_dev *pdev = sio->lio_pdev; | 156 | struct pci_dev *pdev = sio->lio_pdev; |
156 | u16 word; | 157 | u16 word; |
157 | 158 | ||
158 | if (sio->suckyio_irq_enabled) | 159 | if (sio->suckyio_irq_enabled) |
159 | return; | 160 | return; |
160 | 161 | ||
161 | BUG_ON(!pdev); | 162 | BUG_ON(!pdev); |
162 | BUG_ON(!sio->usb_pdev); | 163 | BUG_ON(!sio->usb_pdev); |
163 | 164 | ||
164 | /* use the IRQ iosapic found for USB INT D... */ | 165 | /* use the IRQ iosapic found for USB INT D... */ |
165 | pdev->irq = sio->usb_pdev->irq; | 166 | pdev->irq = sio->usb_pdev->irq; |
166 | 167 | ||
167 | /* ...then properly fixup the USB to point at suckyio PIC */ | 168 | /* ...then properly fixup the USB to point at suckyio PIC */ |
168 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); | 169 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); |
169 | 170 | ||
170 | printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", | 171 | printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", |
171 | pci_name(pdev), pdev->irq); | 172 | pci_name(pdev), pdev->irq); |
172 | 173 | ||
173 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); | 174 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); |
174 | sio->sp1_base &= ~1; | 175 | sio->sp1_base &= ~1; |
175 | printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base); | 176 | printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base); |
176 | 177 | ||
177 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); | 178 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); |
178 | sio->sp2_base &= ~1; | 179 | sio->sp2_base &= ~1; |
179 | printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base); | 180 | printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base); |
180 | 181 | ||
181 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); | 182 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); |
182 | sio->pp_base &= ~1; | 183 | sio->pp_base &= ~1; |
183 | printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base); | 184 | printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base); |
184 | 185 | ||
185 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); | 186 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); |
186 | sio->fdc_base &= ~1; | 187 | sio->fdc_base &= ~1; |
187 | printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base); | 188 | printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base); |
188 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); | 189 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); |
189 | sio->acpi_base &= ~1; | 190 | sio->acpi_base &= ~1; |
190 | printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base); | 191 | printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base); |
191 | 192 | ||
192 | request_region (IC_PIC1, 0x1f, "pic1"); | 193 | request_region (IC_PIC1, 0x1f, "pic1"); |
193 | request_region (IC_PIC2, 0x1f, "pic2"); | 194 | request_region (IC_PIC2, 0x1f, "pic2"); |
194 | request_region (sio->acpi_base, 0x1f, "acpi"); | 195 | request_region (sio->acpi_base, 0x1f, "acpi"); |
195 | 196 | ||
196 | /* Enable the legacy I/O function */ | 197 | /* Enable the legacy I/O function */ |
197 | pci_read_config_word (pdev, PCI_COMMAND, &word); | 198 | pci_read_config_word (pdev, PCI_COMMAND, &word); |
198 | word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO; | 199 | word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO; |
199 | pci_write_config_word (pdev, PCI_COMMAND, word); | 200 | pci_write_config_word (pdev, PCI_COMMAND, word); |
200 | 201 | ||
201 | pci_set_master (pdev); | 202 | pci_set_master (pdev); |
202 | pci_enable_device(pdev); | 203 | pci_enable_device(pdev); |
203 | 204 | ||
204 | /* | 205 | /* |
205 | * Next project is programming the onboard interrupt controllers. | 206 | * Next project is programming the onboard interrupt controllers. |
206 | * PDC hasn't done this for us, since it's using polled I/O. | 207 | * PDC hasn't done this for us, since it's using polled I/O. |
207 | * | 208 | * |
208 | * XXX Use dword writes to avoid bugs in Elroy or Suckyio Config | 209 | * XXX Use dword writes to avoid bugs in Elroy or Suckyio Config |
209 | * space access. PCI is by nature a 32-bit bus and config | 210 | * space access. PCI is by nature a 32-bit bus and config |
210 | * space can be sensitive to that. | 211 | * space can be sensitive to that. |
211 | */ | 212 | */ |
212 | 213 | ||
213 | /* 0x64 - 0x67 : | 214 | /* 0x64 - 0x67 : |
214 | DMA Rtg 2 | 215 | DMA Rtg 2 |
215 | DMA Rtg 3 | 216 | DMA Rtg 3 |
216 | DMA Chan Ctl | 217 | DMA Chan Ctl |
217 | TRIGGER_1 == 0x82 USB & IDE level triggered, rest to edge | 218 | TRIGGER_1 == 0x82 USB & IDE level triggered, rest to edge |
218 | */ | 219 | */ |
219 | pci_write_config_dword (pdev, 0x64, 0x82000000U); | 220 | pci_write_config_dword (pdev, 0x64, 0x82000000U); |
220 | 221 | ||
221 | /* 0x68 - 0x6b : | 222 | /* 0x68 - 0x6b : |
222 | TRIGGER_2 == 0x00 all edge triggered (not used) | 223 | TRIGGER_2 == 0x00 all edge triggered (not used) |
223 | CFG_IR_SER == 0x43 SerPort1 = IRQ3, SerPort2 = IRQ4 | 224 | CFG_IR_SER == 0x43 SerPort1 = IRQ3, SerPort2 = IRQ4 |
224 | CFG_IR_PF == 0x65 ParPort = IRQ5, FloppyCtlr = IRQ6 | 225 | CFG_IR_PF == 0x65 ParPort = IRQ5, FloppyCtlr = IRQ6 |
225 | CFG_IR_IDE == 0x07 IDE1 = IRQ7, reserved | 226 | CFG_IR_IDE == 0x07 IDE1 = IRQ7, reserved |
226 | */ | 227 | */ |
227 | pci_write_config_dword (pdev, TRIGGER_2, 0x07654300U); | 228 | pci_write_config_dword (pdev, TRIGGER_2, 0x07654300U); |
228 | 229 | ||
229 | /* 0x6c - 0x6f : | 230 | /* 0x6c - 0x6f : |
230 | CFG_IR_INTAB == 0x00 | 231 | CFG_IR_INTAB == 0x00 |
231 | CFG_IR_INTCD == 0x10 USB = IRQ1 | 232 | CFG_IR_INTCD == 0x10 USB = IRQ1 |
232 | CFG_IR_PS2 == 0x00 | 233 | CFG_IR_PS2 == 0x00 |
233 | CFG_IR_FXBUS == 0x00 | 234 | CFG_IR_FXBUS == 0x00 |
234 | */ | 235 | */ |
235 | pci_write_config_dword (pdev, CFG_IR_INTAB, 0x00001000U); | 236 | pci_write_config_dword (pdev, CFG_IR_INTAB, 0x00001000U); |
236 | 237 | ||
237 | /* 0x70 - 0x73 : | 238 | /* 0x70 - 0x73 : |
238 | CFG_IR_USB == 0x00 not used. USB is connected to INTD. | 239 | CFG_IR_USB == 0x00 not used. USB is connected to INTD. |
239 | CFG_IR_ACPI == 0x00 not used. | 240 | CFG_IR_ACPI == 0x00 not used. |
240 | DMA Priority == 0x4c88 Power on default value. NFC. | 241 | DMA Priority == 0x4c88 Power on default value. NFC. |
241 | */ | 242 | */ |
242 | pci_write_config_dword (pdev, CFG_IR_USB, 0x4c880000U); | 243 | pci_write_config_dword (pdev, CFG_IR_USB, 0x4c880000U); |
243 | 244 | ||
244 | /* PIC1 Initialization Command Word register programming */ | 245 | /* PIC1 Initialization Command Word register programming */ |
245 | outb (0x11,IC_PIC1+0); /* ICW1: ICW4 write req | ICW1 */ | 246 | outb (0x11,IC_PIC1+0); /* ICW1: ICW4 write req | ICW1 */ |
246 | outb (0x00,IC_PIC1+1); /* ICW2: interrupt vector table - not used */ | 247 | outb (0x00,IC_PIC1+1); /* ICW2: interrupt vector table - not used */ |
247 | outb (0x04,IC_PIC1+1); /* ICW3: Cascade */ | 248 | outb (0x04,IC_PIC1+1); /* ICW3: Cascade */ |
248 | outb (0x01,IC_PIC1+1); /* ICW4: x86 mode */ | 249 | outb (0x01,IC_PIC1+1); /* ICW4: x86 mode */ |
249 | 250 | ||
250 | /* PIC1 Program Operational Control Words */ | 251 | /* PIC1 Program Operational Control Words */ |
251 | outb (0xff,IC_PIC1+1); /* OCW1: Mask all interrupts */ | 252 | outb (0xff,IC_PIC1+1); /* OCW1: Mask all interrupts */ |
252 | outb (0xc2,IC_PIC1+0); /* OCW2: priority (3-7,0-2) */ | 253 | outb (0xc2,IC_PIC1+0); /* OCW2: priority (3-7,0-2) */ |
253 | 254 | ||
254 | /* PIC2 Initialization Command Word register programming */ | 255 | /* PIC2 Initialization Command Word register programming */ |
255 | outb (0x11,IC_PIC2+0); /* ICW1: ICW4 write req | ICW1 */ | 256 | outb (0x11,IC_PIC2+0); /* ICW1: ICW4 write req | ICW1 */ |
256 | outb (0x00,IC_PIC2+1); /* ICW2: N/A */ | 257 | outb (0x00,IC_PIC2+1); /* ICW2: N/A */ |
257 | outb (0x02,IC_PIC2+1); /* ICW3: Slave ID code */ | 258 | outb (0x02,IC_PIC2+1); /* ICW3: Slave ID code */ |
258 | outb (0x01,IC_PIC2+1); /* ICW4: x86 mode */ | 259 | outb (0x01,IC_PIC2+1); /* ICW4: x86 mode */ |
259 | 260 | ||
260 | /* Program Operational Control Words */ | 261 | /* Program Operational Control Words */ |
261 | outb (0xff,IC_PIC1+1); /* OCW1: Mask all interrupts */ | 262 | outb (0xff,IC_PIC1+1); /* OCW1: Mask all interrupts */ |
262 | outb (0x68,IC_PIC1+0); /* OCW3: OCW3 select | ESMM | SMM */ | 263 | outb (0x68,IC_PIC1+0); /* OCW3: OCW3 select | ESMM | SMM */ |
263 | 264 | ||
264 | /* Write master mask reg */ | 265 | /* Write master mask reg */ |
265 | outb (0xff,IC_PIC1+1); | 266 | outb (0xff,IC_PIC1+1); |
266 | 267 | ||
267 | /* Setup USB power regulation */ | 268 | /* Setup USB power regulation */ |
268 | outb(1, sio->acpi_base + USB_REG_CR); | 269 | outb(1, sio->acpi_base + USB_REG_CR); |
269 | if (inb(sio->acpi_base + USB_REG_CR) & 1) | 270 | if (inb(sio->acpi_base + USB_REG_CR) & 1) |
270 | printk(KERN_INFO PFX "USB regulator enabled\n"); | 271 | printk(KERN_INFO PFX "USB regulator enabled\n"); |
271 | else | 272 | else |
272 | printk(KERN_ERR PFX "USB regulator not initialized!\n"); | 273 | printk(KERN_ERR PFX "USB regulator not initialized!\n"); |
273 | 274 | ||
274 | if (request_irq(pdev->irq, superio_interrupt, IRQF_DISABLED, | 275 | if (request_irq(pdev->irq, superio_interrupt, IRQF_DISABLED, |
275 | SUPERIO, (void *)sio)) { | 276 | SUPERIO, (void *)sio)) { |
276 | 277 | ||
277 | printk(KERN_ERR PFX "could not get irq\n"); | 278 | printk(KERN_ERR PFX "could not get irq\n"); |
278 | BUG(); | 279 | BUG(); |
279 | return; | 280 | return; |
280 | } | 281 | } |
281 | 282 | ||
282 | sio->suckyio_irq_enabled = 1; | 283 | sio->suckyio_irq_enabled = 1; |
283 | } | 284 | } |
284 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init); | 285 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init); |
285 | 286 | ||
286 | static void superio_disable_irq(unsigned int irq) | 287 | static void superio_disable_irq(unsigned int irq) |
287 | { | 288 | { |
288 | u8 r8; | 289 | u8 r8; |
289 | 290 | ||
290 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 291 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
291 | printk(KERN_ERR PFX "Illegal irq number.\n"); | 292 | printk(KERN_ERR PFX "Illegal irq number.\n"); |
292 | BUG(); | 293 | BUG(); |
293 | return; | 294 | return; |
294 | } | 295 | } |
295 | 296 | ||
296 | /* Mask interrupt */ | 297 | /* Mask interrupt */ |
297 | 298 | ||
298 | r8 = inb(IC_PIC1+1); | 299 | r8 = inb(IC_PIC1+1); |
299 | r8 |= (1 << irq); | 300 | r8 |= (1 << irq); |
300 | outb (r8,IC_PIC1+1); | 301 | outb (r8,IC_PIC1+1); |
301 | } | 302 | } |
302 | 303 | ||
303 | static void superio_enable_irq(unsigned int irq) | 304 | static void superio_enable_irq(unsigned int irq) |
304 | { | 305 | { |
305 | u8 r8; | 306 | u8 r8; |
306 | 307 | ||
307 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 308 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
308 | printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq); | 309 | printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq); |
309 | BUG(); | 310 | BUG(); |
310 | return; | 311 | return; |
311 | } | 312 | } |
312 | 313 | ||
313 | /* Unmask interrupt */ | 314 | /* Unmask interrupt */ |
314 | r8 = inb(IC_PIC1+1); | 315 | r8 = inb(IC_PIC1+1); |
315 | r8 &= ~(1 << irq); | 316 | r8 &= ~(1 << irq); |
316 | outb (r8,IC_PIC1+1); | 317 | outb (r8,IC_PIC1+1); |
317 | } | 318 | } |
318 | 319 | ||
319 | static unsigned int superio_startup_irq(unsigned int irq) | 320 | static unsigned int superio_startup_irq(unsigned int irq) |
320 | { | 321 | { |
321 | superio_enable_irq(irq); | 322 | superio_enable_irq(irq); |
322 | return 0; | 323 | return 0; |
323 | } | 324 | } |
324 | 325 | ||
325 | static struct hw_interrupt_type superio_interrupt_type = { | 326 | static struct hw_interrupt_type superio_interrupt_type = { |
326 | .typename = SUPERIO, | 327 | .typename = SUPERIO, |
327 | .startup = superio_startup_irq, | 328 | .startup = superio_startup_irq, |
328 | .shutdown = superio_disable_irq, | 329 | .shutdown = superio_disable_irq, |
329 | .enable = superio_enable_irq, | 330 | .enable = superio_enable_irq, |
330 | .disable = superio_disable_irq, | 331 | .disable = superio_disable_irq, |
331 | .ack = no_ack_irq, | 332 | .ack = no_ack_irq, |
332 | .end = no_end_irq, | 333 | .end = no_end_irq, |
333 | }; | 334 | }; |
334 | 335 | ||
335 | #ifdef DEBUG_SUPERIO_INIT | 336 | #ifdef DEBUG_SUPERIO_INIT |
336 | static unsigned short expected_device[3] = { | 337 | static unsigned short expected_device[3] = { |
337 | PCI_DEVICE_ID_NS_87415, | 338 | PCI_DEVICE_ID_NS_87415, |
338 | PCI_DEVICE_ID_NS_87560_LIO, | 339 | PCI_DEVICE_ID_NS_87560_LIO, |
339 | PCI_DEVICE_ID_NS_87560_USB | 340 | PCI_DEVICE_ID_NS_87560_USB |
340 | }; | 341 | }; |
341 | #endif | 342 | #endif |
342 | 343 | ||
343 | int superio_fixup_irq(struct pci_dev *pcidev) | 344 | int superio_fixup_irq(struct pci_dev *pcidev) |
344 | { | 345 | { |
345 | int local_irq, i; | 346 | int local_irq, i; |
346 | 347 | ||
347 | #ifdef DEBUG_SUPERIO_INIT | 348 | #ifdef DEBUG_SUPERIO_INIT |
348 | int fn; | 349 | int fn; |
349 | fn = PCI_FUNC(pcidev->devfn); | 350 | fn = PCI_FUNC(pcidev->devfn); |
350 | 351 | ||
351 | /* Verify the function number matches the expected device id. */ | 352 | /* Verify the function number matches the expected device id. */ |
352 | if (expected_device[fn] != pcidev->device) { | 353 | if (expected_device[fn] != pcidev->device) { |
353 | BUG(); | 354 | BUG(); |
354 | return -1; | 355 | return -1; |
355 | } | 356 | } |
356 | printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %p\n", | 357 | printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %p\n", |
357 | pci_name(pcidev), | 358 | pci_name(pcidev), |
358 | pcidev->vendor, pcidev->device, | 359 | pcidev->vendor, pcidev->device, |
359 | __builtin_return_address(0)); | 360 | __builtin_return_address(0)); |
360 | #endif | 361 | #endif |
361 | 362 | ||
362 | for (i = 0; i < 16; i++) { | 363 | for (i = 0; i < 16; i++) { |
363 | irq_desc[i].chip = &superio_interrupt_type; | 364 | irq_desc[i].chip = &superio_interrupt_type; |
364 | } | 365 | } |
365 | 366 | ||
366 | /* | 367 | /* |
367 | * We don't allocate a SuperIO irq for the legacy IO function, | 368 | * We don't allocate a SuperIO irq for the legacy IO function, |
368 | * since it is a "bridge". Instead, we will allocate irq's for | 369 | * since it is a "bridge". Instead, we will allocate irq's for |
369 | * each legacy device as they are initialized. | 370 | * each legacy device as they are initialized. |
370 | */ | 371 | */ |
371 | 372 | ||
372 | switch(pcidev->device) { | 373 | switch(pcidev->device) { |
373 | case PCI_DEVICE_ID_NS_87415: /* Function 0 */ | 374 | case PCI_DEVICE_ID_NS_87415: /* Function 0 */ |
374 | local_irq = IDE_IRQ; | 375 | local_irq = IDE_IRQ; |
375 | break; | 376 | break; |
376 | case PCI_DEVICE_ID_NS_87560_LIO: /* Function 1 */ | 377 | case PCI_DEVICE_ID_NS_87560_LIO: /* Function 1 */ |
377 | sio_dev.lio_pdev = pcidev; /* save for superio_init() */ | 378 | sio_dev.lio_pdev = pcidev; /* save for superio_init() */ |
378 | return -1; | 379 | return -1; |
379 | case PCI_DEVICE_ID_NS_87560_USB: /* Function 2 */ | 380 | case PCI_DEVICE_ID_NS_87560_USB: /* Function 2 */ |
380 | sio_dev.usb_pdev = pcidev; /* save for superio_init() */ | 381 | sio_dev.usb_pdev = pcidev; /* save for superio_init() */ |
381 | local_irq = USB_IRQ; | 382 | local_irq = USB_IRQ; |
382 | break; | 383 | break; |
383 | default: | 384 | default: |
384 | local_irq = -1; | 385 | local_irq = -1; |
385 | BUG(); | 386 | BUG(); |
386 | break; | 387 | break; |
387 | } | 388 | } |
388 | 389 | ||
389 | return local_irq; | 390 | return local_irq; |
390 | } | 391 | } |
391 | 392 | ||
392 | static void __init superio_serial_init(void) | 393 | static void __init superio_serial_init(void) |
393 | { | 394 | { |
394 | #ifdef CONFIG_SERIAL_8250 | 395 | #ifdef CONFIG_SERIAL_8250 |
395 | int retval; | 396 | int retval; |
396 | struct uart_port serial_port; | 397 | struct uart_port serial_port; |
397 | 398 | ||
398 | memset(&serial_port, 0, sizeof(serial_port)); | 399 | memset(&serial_port, 0, sizeof(serial_port)); |
399 | serial_port.iotype = UPIO_PORT; | 400 | serial_port.iotype = UPIO_PORT; |
400 | serial_port.type = PORT_16550A; | 401 | serial_port.type = PORT_16550A; |
401 | serial_port.uartclk = 115200*16; | 402 | serial_port.uartclk = 115200*16; |
402 | serial_port.fifosize = 16; | 403 | serial_port.fifosize = 16; |
403 | spin_lock_init(&serial_port.lock); | 404 | spin_lock_init(&serial_port.lock); |
404 | 405 | ||
405 | /* serial port #1 */ | 406 | /* serial port #1 */ |
406 | serial_port.iobase = sio_dev.sp1_base; | 407 | serial_port.iobase = sio_dev.sp1_base; |
407 | serial_port.irq = SP1_IRQ; | 408 | serial_port.irq = SP1_IRQ; |
408 | serial_port.line = 0; | 409 | serial_port.line = 0; |
409 | retval = early_serial_setup(&serial_port); | 410 | retval = early_serial_setup(&serial_port); |
410 | if (retval < 0) { | 411 | if (retval < 0) { |
411 | printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); | 412 | printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); |
412 | return; | 413 | return; |
413 | } | 414 | } |
414 | 415 | ||
415 | /* serial port #2 */ | 416 | /* serial port #2 */ |
416 | serial_port.iobase = sio_dev.sp2_base; | 417 | serial_port.iobase = sio_dev.sp2_base; |
417 | serial_port.irq = SP2_IRQ; | 418 | serial_port.irq = SP2_IRQ; |
418 | serial_port.line = 1; | 419 | serial_port.line = 1; |
419 | retval = early_serial_setup(&serial_port); | 420 | retval = early_serial_setup(&serial_port); |
420 | if (retval < 0) | 421 | if (retval < 0) |
421 | printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); | 422 | printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); |
422 | #endif /* CONFIG_SERIAL_8250 */ | 423 | #endif /* CONFIG_SERIAL_8250 */ |
423 | } | 424 | } |
424 | 425 | ||
425 | 426 | ||
426 | static void __init superio_parport_init(void) | 427 | static void __init superio_parport_init(void) |
427 | { | 428 | { |
428 | #ifdef CONFIG_PARPORT_PC | 429 | #ifdef CONFIG_PARPORT_PC |
429 | if (!parport_pc_probe_port(sio_dev.pp_base, | 430 | if (!parport_pc_probe_port(sio_dev.pp_base, |
430 | 0 /*base_hi*/, | 431 | 0 /*base_hi*/, |
431 | PAR_IRQ, | 432 | PAR_IRQ, |
432 | PARPORT_DMA_NONE /* dma */, | 433 | PARPORT_DMA_NONE /* dma */, |
433 | NULL /*struct pci_dev* */) ) | 434 | NULL /*struct pci_dev* */) ) |
434 | 435 | ||
435 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); | 436 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); |
436 | #endif /* CONFIG_PARPORT_PC */ | 437 | #endif /* CONFIG_PARPORT_PC */ |
437 | } | 438 | } |
438 | 439 | ||
439 | 440 | ||
440 | static void superio_fixup_pci(struct pci_dev *pdev) | 441 | static void superio_fixup_pci(struct pci_dev *pdev) |
441 | { | 442 | { |
442 | u8 prog; | 443 | u8 prog; |
443 | 444 | ||
444 | pdev->class |= 0x5; | 445 | pdev->class |= 0x5; |
445 | pci_write_config_byte(pdev, PCI_CLASS_PROG, pdev->class); | 446 | pci_write_config_byte(pdev, PCI_CLASS_PROG, pdev->class); |
446 | 447 | ||
447 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog); | 448 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog); |
448 | printk("PCI: Enabled native mode for NS87415 (pif=0x%x)\n", prog); | 449 | printk("PCI: Enabled native mode for NS87415 (pif=0x%x)\n", prog); |
449 | } | 450 | } |
450 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci); | 451 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci); |
451 | 452 | ||
452 | 453 | ||
453 | static int __init | 454 | static int __init |
454 | superio_probe(struct pci_dev *dev, const struct pci_device_id *id) | 455 | superio_probe(struct pci_dev *dev, const struct pci_device_id *id) |
455 | { | 456 | { |
456 | struct superio_device *sio = &sio_dev; | 457 | struct superio_device *sio = &sio_dev; |
457 | 458 | ||
458 | /* | 459 | /* |
459 | ** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a | 460 | ** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a |
460 | ** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000 | 461 | ** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000 |
461 | ** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310 | 462 | ** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310 |
462 | */ | 463 | */ |
463 | DBG_INIT("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n", | 464 | DBG_INIT("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n", |
464 | pci_name(dev), | 465 | pci_name(dev), |
465 | dev->vendor, dev->device, | 466 | dev->vendor, dev->device, |
466 | dev->subsystem_vendor, dev->subsystem_device, | 467 | dev->subsystem_vendor, dev->subsystem_device, |
467 | dev->class); | 468 | dev->class); |
468 | 469 | ||
469 | BUG_ON(!sio->suckyio_irq_enabled); /* Enabled by PCI_FIXUP_FINAL */ | 470 | BUG_ON(!sio->suckyio_irq_enabled); /* Enabled by PCI_FIXUP_FINAL */ |
470 | 471 | ||
471 | if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) { /* Function 1 */ | 472 | if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) { /* Function 1 */ |
472 | superio_parport_init(); | 473 | superio_parport_init(); |
473 | superio_serial_init(); | 474 | superio_serial_init(); |
474 | /* REVISIT XXX : superio_fdc_init() ? */ | 475 | /* REVISIT XXX : superio_fdc_init() ? */ |
475 | return 0; | 476 | return 0; |
476 | } else if (dev->device == PCI_DEVICE_ID_NS_87415) { /* Function 0 */ | 477 | } else if (dev->device == PCI_DEVICE_ID_NS_87415) { /* Function 0 */ |
477 | DBG_INIT("superio_probe: ignoring IDE 87415\n"); | 478 | DBG_INIT("superio_probe: ignoring IDE 87415\n"); |
478 | } else if (dev->device == PCI_DEVICE_ID_NS_87560_USB) { /* Function 2 */ | 479 | } else if (dev->device == PCI_DEVICE_ID_NS_87560_USB) { /* Function 2 */ |
479 | DBG_INIT("superio_probe: ignoring USB OHCI controller\n"); | 480 | DBG_INIT("superio_probe: ignoring USB OHCI controller\n"); |
480 | } else { | 481 | } else { |
481 | DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n"); | 482 | DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n"); |
482 | } | 483 | } |
483 | 484 | ||
484 | /* Let appropriate other driver claim this device. */ | 485 | /* Let appropriate other driver claim this device. */ |
485 | return -ENODEV; | 486 | return -ENODEV; |
486 | } | 487 | } |
487 | 488 | ||
488 | static const struct pci_device_id superio_tbl[] = { | 489 | static const struct pci_device_id superio_tbl[] = { |
489 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) }, | 490 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) }, |
490 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) }, | 491 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) }, |
491 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) }, | 492 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) }, |
492 | { 0, } | 493 | { 0, } |
493 | }; | 494 | }; |
494 | 495 | ||
495 | static struct pci_driver superio_driver = { | 496 | static struct pci_driver superio_driver = { |
496 | .name = SUPERIO, | 497 | .name = SUPERIO, |
497 | .id_table = superio_tbl, | 498 | .id_table = superio_tbl, |
498 | .probe = superio_probe, | 499 | .probe = superio_probe, |
499 | }; | 500 | }; |
500 | 501 | ||
501 | static int __init superio_modinit(void) | 502 | static int __init superio_modinit(void) |
502 | { | 503 | { |
503 | return pci_register_driver(&superio_driver); | 504 | return pci_register_driver(&superio_driver); |
504 | } | 505 | } |
505 | 506 | ||
506 | static void __exit superio_exit(void) | 507 | static void __exit superio_exit(void) |
507 | { | 508 | { |
508 | pci_unregister_driver(&superio_driver); | 509 | pci_unregister_driver(&superio_driver); |
509 | } | 510 | } |
510 | 511 | ||
511 | module_init(superio_modinit); | 512 | module_init(superio_modinit); |
512 | module_exit(superio_exit); | 513 | module_exit(superio_exit); |
513 | 514 |
drivers/serial/8250_hp300.c
1 | /* | 1 | /* |
2 | * Driver for the 98626/98644/internal serial interface on hp300/hp400 | 2 | * Driver for the 98626/98644/internal serial interface on hp300/hp400 |
3 | * (based on the National Semiconductor INS8250/NS16550AF/WD16C552 UARTs) | 3 | * (based on the National Semiconductor INS8250/NS16550AF/WD16C552 UARTs) |
4 | * | 4 | * |
5 | * Ported from 2.2 and modified to use the normal 8250 driver | 5 | * Ported from 2.2 and modified to use the normal 8250 driver |
6 | * by Kars de Jong <jongk@linux-m68k.org>, May 2004. | 6 | * by Kars de Jong <jongk@linux-m68k.org>, May 2004. |
7 | */ | 7 | */ |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/string.h> | 10 | #include <linux/string.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/serial.h> | 12 | #include <linux/serial.h> |
13 | #include <linux/serial_core.h> | 13 | #include <linux/serial_core.h> |
14 | #include <linux/serial_8250.h> | ||
14 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
15 | #include <linux/dio.h> | 16 | #include <linux/dio.h> |
16 | #include <linux/console.h> | 17 | #include <linux/console.h> |
17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
18 | 19 | ||
19 | #include "8250.h" | 20 | #include "8250.h" |
20 | 21 | ||
21 | #if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) | 22 | #if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) |
22 | #warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure? | 23 | #warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure? |
23 | #endif | 24 | #endif |
24 | 25 | ||
25 | #ifdef CONFIG_HPAPCI | 26 | #ifdef CONFIG_HPAPCI |
26 | struct hp300_port | 27 | struct hp300_port |
27 | { | 28 | { |
28 | struct hp300_port *next; /* next port */ | 29 | struct hp300_port *next; /* next port */ |
29 | int line; /* line (tty) number */ | 30 | int line; /* line (tty) number */ |
30 | }; | 31 | }; |
31 | 32 | ||
32 | static struct hp300_port *hp300_ports; | 33 | static struct hp300_port *hp300_ports; |
33 | #endif | 34 | #endif |
34 | 35 | ||
35 | #ifdef CONFIG_HPDCA | 36 | #ifdef CONFIG_HPDCA |
36 | 37 | ||
37 | static int __devinit hpdca_init_one(struct dio_dev *d, | 38 | static int __devinit hpdca_init_one(struct dio_dev *d, |
38 | const struct dio_device_id *ent); | 39 | const struct dio_device_id *ent); |
39 | static void __devexit hpdca_remove_one(struct dio_dev *d); | 40 | static void __devexit hpdca_remove_one(struct dio_dev *d); |
40 | 41 | ||
41 | static struct dio_device_id hpdca_dio_tbl[] = { | 42 | static struct dio_device_id hpdca_dio_tbl[] = { |
42 | { DIO_ID_DCA0 }, | 43 | { DIO_ID_DCA0 }, |
43 | { DIO_ID_DCA0REM }, | 44 | { DIO_ID_DCA0REM }, |
44 | { DIO_ID_DCA1 }, | 45 | { DIO_ID_DCA1 }, |
45 | { DIO_ID_DCA1REM }, | 46 | { DIO_ID_DCA1REM }, |
46 | { 0 } | 47 | { 0 } |
47 | }; | 48 | }; |
48 | 49 | ||
49 | static struct dio_driver hpdca_driver = { | 50 | static struct dio_driver hpdca_driver = { |
50 | .name = "hpdca", | 51 | .name = "hpdca", |
51 | .id_table = hpdca_dio_tbl, | 52 | .id_table = hpdca_dio_tbl, |
52 | .probe = hpdca_init_one, | 53 | .probe = hpdca_init_one, |
53 | .remove = __devexit_p(hpdca_remove_one), | 54 | .remove = __devexit_p(hpdca_remove_one), |
54 | }; | 55 | }; |
55 | 56 | ||
56 | #endif | 57 | #endif |
57 | 58 | ||
58 | static unsigned int num_ports; | 59 | static unsigned int num_ports; |
59 | 60 | ||
60 | extern int hp300_uart_scode; | 61 | extern int hp300_uart_scode; |
61 | 62 | ||
62 | /* Offset to UART registers from base of DCA */ | 63 | /* Offset to UART registers from base of DCA */ |
63 | #define UART_OFFSET 17 | 64 | #define UART_OFFSET 17 |
64 | 65 | ||
65 | #define DCA_ID 0x01 /* ID (read), reset (write) */ | 66 | #define DCA_ID 0x01 /* ID (read), reset (write) */ |
66 | #define DCA_IC 0x03 /* Interrupt control */ | 67 | #define DCA_IC 0x03 /* Interrupt control */ |
67 | 68 | ||
68 | /* Interrupt control */ | 69 | /* Interrupt control */ |
69 | #define DCA_IC_IE 0x80 /* Master interrupt enable */ | 70 | #define DCA_IC_IE 0x80 /* Master interrupt enable */ |
70 | 71 | ||
71 | #define HPDCA_BAUD_BASE 153600 | 72 | #define HPDCA_BAUD_BASE 153600 |
72 | 73 | ||
73 | /* Base address of the Frodo part */ | 74 | /* Base address of the Frodo part */ |
74 | #define FRODO_BASE (0x41c000) | 75 | #define FRODO_BASE (0x41c000) |
75 | 76 | ||
76 | /* | 77 | /* |
77 | * Where we find the 8250-like APCI ports, and how far apart they are. | 78 | * Where we find the 8250-like APCI ports, and how far apart they are. |
78 | */ | 79 | */ |
79 | #define FRODO_APCIBASE 0x0 | 80 | #define FRODO_APCIBASE 0x0 |
80 | #define FRODO_APCISPACE 0x20 | 81 | #define FRODO_APCISPACE 0x20 |
81 | #define FRODO_APCI_OFFSET(x) (FRODO_APCIBASE + ((x) * FRODO_APCISPACE)) | 82 | #define FRODO_APCI_OFFSET(x) (FRODO_APCIBASE + ((x) * FRODO_APCISPACE)) |
82 | 83 | ||
83 | #define HPAPCI_BAUD_BASE 500400 | 84 | #define HPAPCI_BAUD_BASE 500400 |
84 | 85 | ||
85 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 86 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
86 | /* | 87 | /* |
87 | * Parse the bootinfo to find descriptions for headless console and | 88 | * Parse the bootinfo to find descriptions for headless console and |
88 | * debug serial ports and register them with the 8250 driver. | 89 | * debug serial ports and register them with the 8250 driver. |
89 | * This function should be called before serial_console_init() is called | 90 | * This function should be called before serial_console_init() is called |
90 | * to make sure the serial console will be available for use. IA-64 kernel | 91 | * to make sure the serial console will be available for use. IA-64 kernel |
91 | * calls this function from setup_arch() after the EFI and ACPI tables have | 92 | * calls this function from setup_arch() after the EFI and ACPI tables have |
92 | * been parsed. | 93 | * been parsed. |
93 | */ | 94 | */ |
94 | int __init hp300_setup_serial_console(void) | 95 | int __init hp300_setup_serial_console(void) |
95 | { | 96 | { |
96 | int scode; | 97 | int scode; |
97 | struct uart_port port; | 98 | struct uart_port port; |
98 | 99 | ||
99 | memset(&port, 0, sizeof(port)); | 100 | memset(&port, 0, sizeof(port)); |
100 | 101 | ||
101 | if (hp300_uart_scode < 0 || hp300_uart_scode > DIO_SCMAX) | 102 | if (hp300_uart_scode < 0 || hp300_uart_scode > DIO_SCMAX) |
102 | return 0; | 103 | return 0; |
103 | 104 | ||
104 | if (DIO_SCINHOLE(hp300_uart_scode)) | 105 | if (DIO_SCINHOLE(hp300_uart_scode)) |
105 | return 0; | 106 | return 0; |
106 | 107 | ||
107 | scode = hp300_uart_scode; | 108 | scode = hp300_uart_scode; |
108 | 109 | ||
109 | /* Memory mapped I/O */ | 110 | /* Memory mapped I/O */ |
110 | port.iotype = UPIO_MEM; | 111 | port.iotype = UPIO_MEM; |
111 | port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; | 112 | port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; |
112 | port.type = PORT_UNKNOWN; | 113 | port.type = PORT_UNKNOWN; |
113 | 114 | ||
114 | /* Check for APCI console */ | 115 | /* Check for APCI console */ |
115 | if (scode == 256) { | 116 | if (scode == 256) { |
116 | #ifdef CONFIG_HPAPCI | 117 | #ifdef CONFIG_HPAPCI |
117 | printk(KERN_INFO "Serial console is HP APCI 1\n"); | 118 | printk(KERN_INFO "Serial console is HP APCI 1\n"); |
118 | 119 | ||
119 | port.uartclk = HPAPCI_BAUD_BASE * 16; | 120 | port.uartclk = HPAPCI_BAUD_BASE * 16; |
120 | port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1)); | 121 | port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1)); |
121 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); | 122 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); |
122 | port.regshift = 2; | 123 | port.regshift = 2; |
123 | add_preferred_console("ttyS", port.line, "9600n8"); | 124 | add_preferred_console("ttyS", port.line, "9600n8"); |
124 | #else | 125 | #else |
125 | printk(KERN_WARNING "Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n"); | 126 | printk(KERN_WARNING "Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n"); |
126 | return 0; | 127 | return 0; |
127 | #endif | 128 | #endif |
128 | } | 129 | } |
129 | else { | 130 | else { |
130 | #ifdef CONFIG_HPDCA | 131 | #ifdef CONFIG_HPDCA |
131 | unsigned long pa = dio_scodetophysaddr(scode); | 132 | unsigned long pa = dio_scodetophysaddr(scode); |
132 | if (!pa) { | 133 | if (!pa) { |
133 | return 0; | 134 | return 0; |
134 | } | 135 | } |
135 | 136 | ||
136 | printk(KERN_INFO "Serial console is HP DCA at select code %d\n", scode); | 137 | printk(KERN_INFO "Serial console is HP DCA at select code %d\n", scode); |
137 | 138 | ||
138 | port.uartclk = HPDCA_BAUD_BASE * 16; | 139 | port.uartclk = HPDCA_BAUD_BASE * 16; |
139 | port.mapbase = (pa + UART_OFFSET); | 140 | port.mapbase = (pa + UART_OFFSET); |
140 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); | 141 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); |
141 | port.regshift = 1; | 142 | port.regshift = 1; |
142 | port.irq = DIO_IPL(pa + DIO_VIRADDRBASE); | 143 | port.irq = DIO_IPL(pa + DIO_VIRADDRBASE); |
143 | 144 | ||
144 | /* Enable board-interrupts */ | 145 | /* Enable board-interrupts */ |
145 | out_8(pa + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE); | 146 | out_8(pa + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE); |
146 | 147 | ||
147 | if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80) { | 148 | if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80) { |
148 | add_preferred_console("ttyS", port.line, "9600n8"); | 149 | add_preferred_console("ttyS", port.line, "9600n8"); |
149 | } | 150 | } |
150 | #else | 151 | #else |
151 | printk(KERN_WARNING "Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n"); | 152 | printk(KERN_WARNING "Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n"); |
152 | return 0; | 153 | return 0; |
153 | #endif | 154 | #endif |
154 | } | 155 | } |
155 | 156 | ||
156 | if (early_serial_setup(&port) < 0) { | 157 | if (early_serial_setup(&port) < 0) { |
157 | printk(KERN_WARNING "hp300_setup_serial_console(): early_serial_setup() failed.\n"); | 158 | printk(KERN_WARNING "hp300_setup_serial_console(): early_serial_setup() failed.\n"); |
158 | } | 159 | } |
159 | 160 | ||
160 | return 0; | 161 | return 0; |
161 | } | 162 | } |
162 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ | 163 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ |
163 | 164 | ||
164 | #ifdef CONFIG_HPDCA | 165 | #ifdef CONFIG_HPDCA |
165 | static int __devinit hpdca_init_one(struct dio_dev *d, | 166 | static int __devinit hpdca_init_one(struct dio_dev *d, |
166 | const struct dio_device_id *ent) | 167 | const struct dio_device_id *ent) |
167 | { | 168 | { |
168 | struct uart_port port; | 169 | struct uart_port port; |
169 | int line; | 170 | int line; |
170 | 171 | ||
171 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 172 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
172 | if (hp300_uart_scode == d->scode) { | 173 | if (hp300_uart_scode == d->scode) { |
173 | /* Already got it. */ | 174 | /* Already got it. */ |
174 | return 0; | 175 | return 0; |
175 | } | 176 | } |
176 | #endif | 177 | #endif |
177 | memset(&port, 0, sizeof(struct uart_port)); | 178 | memset(&port, 0, sizeof(struct uart_port)); |
178 | 179 | ||
179 | /* Memory mapped I/O */ | 180 | /* Memory mapped I/O */ |
180 | port.iotype = UPIO_MEM; | 181 | port.iotype = UPIO_MEM; |
181 | port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; | 182 | port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; |
182 | port.irq = d->ipl; | 183 | port.irq = d->ipl; |
183 | port.uartclk = HPDCA_BAUD_BASE * 16; | 184 | port.uartclk = HPDCA_BAUD_BASE * 16; |
184 | port.mapbase = (d->resource.start + UART_OFFSET); | 185 | port.mapbase = (d->resource.start + UART_OFFSET); |
185 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); | 186 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); |
186 | port.regshift = 1; | 187 | port.regshift = 1; |
187 | port.dev = &d->dev; | 188 | port.dev = &d->dev; |
188 | line = serial8250_register_port(&port); | 189 | line = serial8250_register_port(&port); |
189 | 190 | ||
190 | if (line < 0) { | 191 | if (line < 0) { |
191 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" | 192 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" |
192 | " irq %d failed\n", d->scode, port.irq); | 193 | " irq %d failed\n", d->scode, port.irq); |
193 | return -ENOMEM; | 194 | return -ENOMEM; |
194 | } | 195 | } |
195 | 196 | ||
196 | /* Enable board-interrupts */ | 197 | /* Enable board-interrupts */ |
197 | out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE); | 198 | out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE); |
198 | dio_set_drvdata(d, (void *)line); | 199 | dio_set_drvdata(d, (void *)line); |
199 | 200 | ||
200 | /* Reset the DCA */ | 201 | /* Reset the DCA */ |
201 | out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff); | 202 | out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff); |
202 | udelay(100); | 203 | udelay(100); |
203 | 204 | ||
204 | num_ports++; | 205 | num_ports++; |
205 | 206 | ||
206 | return 0; | 207 | return 0; |
207 | } | 208 | } |
208 | #endif | 209 | #endif |
209 | 210 | ||
210 | static int __init hp300_8250_init(void) | 211 | static int __init hp300_8250_init(void) |
211 | { | 212 | { |
212 | static int called = 0; | 213 | static int called = 0; |
213 | #ifdef CONFIG_HPAPCI | 214 | #ifdef CONFIG_HPAPCI |
214 | int line; | 215 | int line; |
215 | unsigned long base; | 216 | unsigned long base; |
216 | struct uart_port uport; | 217 | struct uart_port uport; |
217 | struct hp300_port *port; | 218 | struct hp300_port *port; |
218 | int i; | 219 | int i; |
219 | #endif | 220 | #endif |
220 | if (called) | 221 | if (called) |
221 | return -ENODEV; | 222 | return -ENODEV; |
222 | called = 1; | 223 | called = 1; |
223 | 224 | ||
224 | if (!MACH_IS_HP300) | 225 | if (!MACH_IS_HP300) |
225 | return -ENODEV; | 226 | return -ENODEV; |
226 | 227 | ||
227 | #ifdef CONFIG_HPDCA | 228 | #ifdef CONFIG_HPDCA |
228 | dio_register_driver(&hpdca_driver); | 229 | dio_register_driver(&hpdca_driver); |
229 | #endif | 230 | #endif |
230 | #ifdef CONFIG_HPAPCI | 231 | #ifdef CONFIG_HPAPCI |
231 | if (hp300_model < HP_400) { | 232 | if (hp300_model < HP_400) { |
232 | if (!num_ports) | 233 | if (!num_ports) |
233 | return -ENODEV; | 234 | return -ENODEV; |
234 | return 0; | 235 | return 0; |
235 | } | 236 | } |
236 | /* These models have the Frodo chip. | 237 | /* These models have the Frodo chip. |
237 | * Port 0 is reserved for the Apollo Domain keyboard. | 238 | * Port 0 is reserved for the Apollo Domain keyboard. |
238 | * Port 1 is either the console or the DCA. | 239 | * Port 1 is either the console or the DCA. |
239 | */ | 240 | */ |
240 | for (i = 1; i < 4; i++) { | 241 | for (i = 1; i < 4; i++) { |
241 | /* Port 1 is the console on a 425e, on other machines it's mapped to | 242 | /* Port 1 is the console on a 425e, on other machines it's mapped to |
242 | * DCA. | 243 | * DCA. |
243 | */ | 244 | */ |
244 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 245 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
245 | if (i == 1) { | 246 | if (i == 1) { |
246 | continue; | 247 | continue; |
247 | } | 248 | } |
248 | #endif | 249 | #endif |
249 | 250 | ||
250 | /* Create new serial device */ | 251 | /* Create new serial device */ |
251 | port = kmalloc(sizeof(struct hp300_port), GFP_KERNEL); | 252 | port = kmalloc(sizeof(struct hp300_port), GFP_KERNEL); |
252 | if (!port) | 253 | if (!port) |
253 | return -ENOMEM; | 254 | return -ENOMEM; |
254 | 255 | ||
255 | memset(&uport, 0, sizeof(struct uart_port)); | 256 | memset(&uport, 0, sizeof(struct uart_port)); |
256 | 257 | ||
257 | base = (FRODO_BASE + FRODO_APCI_OFFSET(i)); | 258 | base = (FRODO_BASE + FRODO_APCI_OFFSET(i)); |
258 | 259 | ||
259 | /* Memory mapped I/O */ | 260 | /* Memory mapped I/O */ |
260 | uport.iotype = UPIO_MEM; | 261 | uport.iotype = UPIO_MEM; |
261 | uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; | 262 | uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; |
262 | /* XXX - no interrupt support yet */ | 263 | /* XXX - no interrupt support yet */ |
263 | uport.irq = 0; | 264 | uport.irq = 0; |
264 | uport.uartclk = HPAPCI_BAUD_BASE * 16; | 265 | uport.uartclk = HPAPCI_BAUD_BASE * 16; |
265 | uport.mapbase = base; | 266 | uport.mapbase = base; |
266 | uport.membase = (char *)(base + DIO_VIRADDRBASE); | 267 | uport.membase = (char *)(base + DIO_VIRADDRBASE); |
267 | uport.regshift = 2; | 268 | uport.regshift = 2; |
268 | 269 | ||
269 | line = serial8250_register_port(&uport); | 270 | line = serial8250_register_port(&uport); |
270 | 271 | ||
271 | if (line < 0) { | 272 | if (line < 0) { |
272 | printk(KERN_NOTICE "8250_hp300: register_serial() APCI %d" | 273 | printk(KERN_NOTICE "8250_hp300: register_serial() APCI %d" |
273 | " irq %d failed\n", i, uport.irq); | 274 | " irq %d failed\n", i, uport.irq); |
274 | kfree(port); | 275 | kfree(port); |
275 | continue; | 276 | continue; |
276 | } | 277 | } |
277 | 278 | ||
278 | port->line = line; | 279 | port->line = line; |
279 | port->next = hp300_ports; | 280 | port->next = hp300_ports; |
280 | hp300_ports = port; | 281 | hp300_ports = port; |
281 | 282 | ||
282 | num_ports++; | 283 | num_ports++; |
283 | } | 284 | } |
284 | #endif | 285 | #endif |
285 | 286 | ||
286 | /* Any boards found? */ | 287 | /* Any boards found? */ |
287 | if (!num_ports) | 288 | if (!num_ports) |
288 | return -ENODEV; | 289 | return -ENODEV; |
289 | 290 | ||
290 | return 0; | 291 | return 0; |
291 | } | 292 | } |
292 | 293 | ||
293 | #ifdef CONFIG_HPDCA | 294 | #ifdef CONFIG_HPDCA |
294 | static void __devexit hpdca_remove_one(struct dio_dev *d) | 295 | static void __devexit hpdca_remove_one(struct dio_dev *d) |
295 | { | 296 | { |
296 | int line; | 297 | int line; |
297 | 298 | ||
298 | line = (int) dio_get_drvdata(d); | 299 | line = (int) dio_get_drvdata(d); |
299 | if (d->resource.start) { | 300 | if (d->resource.start) { |
300 | /* Disable board-interrupts */ | 301 | /* Disable board-interrupts */ |
301 | out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0); | 302 | out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0); |
302 | } | 303 | } |
303 | serial8250_unregister_port(line); | 304 | serial8250_unregister_port(line); |
304 | } | 305 | } |
305 | #endif | 306 | #endif |
306 | 307 | ||
307 | static void __exit hp300_8250_exit(void) | 308 | static void __exit hp300_8250_exit(void) |
308 | { | 309 | { |
309 | #ifdef CONFIG_HPAPCI | 310 | #ifdef CONFIG_HPAPCI |
310 | struct hp300_port *port, *to_free; | 311 | struct hp300_port *port, *to_free; |
311 | 312 | ||
312 | for (port = hp300_ports; port; ) { | 313 | for (port = hp300_ports; port; ) { |
313 | serial8250_unregister_port(port->line); | 314 | serial8250_unregister_port(port->line); |
314 | to_free = port; | 315 | to_free = port; |
315 | port = port->next; | 316 | port = port->next; |
316 | kfree(to_free); | 317 | kfree(to_free); |
317 | } | 318 | } |
318 | 319 | ||
319 | hp300_ports = NULL; | 320 | hp300_ports = NULL; |
320 | #endif | 321 | #endif |
321 | #ifdef CONFIG_HPDCA | 322 | #ifdef CONFIG_HPDCA |
322 | dio_unregister_driver(&hpdca_driver); | 323 | dio_unregister_driver(&hpdca_driver); |
323 | #endif | 324 | #endif |
324 | } | 325 | } |
325 | 326 | ||
326 | module_init(hp300_8250_init); | 327 | module_init(hp300_8250_init); |
327 | module_exit(hp300_8250_exit); | 328 | module_exit(hp300_8250_exit); |
328 | MODULE_DESCRIPTION("HP DCA/APCI serial driver"); | 329 | MODULE_DESCRIPTION("HP DCA/APCI serial driver"); |
329 | MODULE_AUTHOR("Kars de Jong <jongk@linux-m68k.org>"); | 330 | MODULE_AUTHOR("Kars de Jong <jongk@linux-m68k.org>"); |
330 | MODULE_LICENSE("GPL"); | 331 | MODULE_LICENSE("GPL"); |
331 | 332 |
include/linux/serial_8250.h
1 | /* | 1 | /* |
2 | * linux/include/linux/serial_8250.h | 2 | * linux/include/linux/serial_8250.h |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Russell King | 4 | * Copyright (C) 2004 Russell King |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | */ | 10 | */ |
11 | #ifndef _LINUX_SERIAL_8250_H | 11 | #ifndef _LINUX_SERIAL_8250_H |
12 | #define _LINUX_SERIAL_8250_H | 12 | #define _LINUX_SERIAL_8250_H |
13 | 13 | ||
14 | #include <linux/serial_core.h> | 14 | #include <linux/serial_core.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | 16 | ||
17 | /* | 17 | /* |
18 | * This is the platform device platform_data structure | 18 | * This is the platform device platform_data structure |
19 | */ | 19 | */ |
20 | struct plat_serial8250_port { | 20 | struct plat_serial8250_port { |
21 | unsigned long iobase; /* io base address */ | 21 | unsigned long iobase; /* io base address */ |
22 | void __iomem *membase; /* ioremap cookie or NULL */ | 22 | void __iomem *membase; /* ioremap cookie or NULL */ |
23 | unsigned long mapbase; /* resource base */ | 23 | unsigned long mapbase; /* resource base */ |
24 | unsigned int irq; /* interrupt number */ | 24 | unsigned int irq; /* interrupt number */ |
25 | unsigned int uartclk; /* UART clock rate */ | 25 | unsigned int uartclk; /* UART clock rate */ |
26 | unsigned char regshift; /* register shift */ | 26 | unsigned char regshift; /* register shift */ |
27 | unsigned char iotype; /* UPIO_* */ | 27 | unsigned char iotype; /* UPIO_* */ |
28 | unsigned char hub6; | 28 | unsigned char hub6; |
29 | upf_t flags; /* UPF_* flags */ | 29 | upf_t flags; /* UPF_* flags */ |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Allocate 8250 platform device IDs. Nothing is implied by | 33 | * Allocate 8250 platform device IDs. Nothing is implied by |
34 | * the numbering here, except for the legacy entry being -1. | 34 | * the numbering here, except for the legacy entry being -1. |
35 | */ | 35 | */ |
36 | enum { | 36 | enum { |
37 | PLAT8250_DEV_LEGACY = -1, | 37 | PLAT8250_DEV_LEGACY = -1, |
38 | PLAT8250_DEV_PLATFORM, | 38 | PLAT8250_DEV_PLATFORM, |
39 | PLAT8250_DEV_PLATFORM1, | 39 | PLAT8250_DEV_PLATFORM1, |
40 | PLAT8250_DEV_PLATFORM2, | 40 | PLAT8250_DEV_PLATFORM2, |
41 | PLAT8250_DEV_FOURPORT, | 41 | PLAT8250_DEV_FOURPORT, |
42 | PLAT8250_DEV_ACCENT, | 42 | PLAT8250_DEV_ACCENT, |
43 | PLAT8250_DEV_BOCA, | 43 | PLAT8250_DEV_BOCA, |
44 | PLAT8250_DEV_EXAR_ST16C554, | 44 | PLAT8250_DEV_EXAR_ST16C554, |
45 | PLAT8250_DEV_HUB6, | 45 | PLAT8250_DEV_HUB6, |
46 | PLAT8250_DEV_MCA, | 46 | PLAT8250_DEV_MCA, |
47 | PLAT8250_DEV_AU1X00, | 47 | PLAT8250_DEV_AU1X00, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * This should be used by drivers which want to register | 51 | * This should be used by drivers which want to register |
52 | * their own 8250 ports without registering their own | 52 | * their own 8250 ports without registering their own |
53 | * platform device. Using these will make your driver | 53 | * platform device. Using these will make your driver |
54 | * dependent on the 8250 driver. | 54 | * dependent on the 8250 driver. |
55 | */ | 55 | */ |
56 | struct uart_port; | 56 | struct uart_port; |
57 | 57 | ||
58 | int serial8250_register_port(struct uart_port *); | 58 | int serial8250_register_port(struct uart_port *); |
59 | void serial8250_unregister_port(int line); | 59 | void serial8250_unregister_port(int line); |
60 | void serial8250_suspend_port(int line); | 60 | void serial8250_suspend_port(int line); |
61 | void serial8250_resume_port(int line); | 61 | void serial8250_resume_port(int line); |
62 | 62 | ||
63 | extern int early_serial_setup(struct uart_port *port); | ||
64 | |||
63 | extern int serial8250_find_port(struct uart_port *p); | 65 | extern int serial8250_find_port(struct uart_port *p); |
64 | extern int serial8250_find_port_for_earlycon(void); | 66 | extern int serial8250_find_port_for_earlycon(void); |
65 | extern int setup_early_serial8250_console(char *cmdline); | 67 | extern int setup_early_serial8250_console(char *cmdline); |
66 | 68 | ||
67 | #endif | 69 | #endif |
68 | 70 |