diff options
-rw-r--r-- | arch/powerpc/boot/dts/mpc8544ds.dts | 88 | ||||
-rw-r--r-- | arch/powerpc/boot/dts/mpc8641_hpcn.dts | 114 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc8544_ds.c | 214 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 224 | ||||
-rw-r--r-- | arch/powerpc/platforms/Kconfig | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/Makefile | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/fsl_uli1575.c | 255 |
9 files changed, 363 insertions, 545 deletions
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts index 4680e2010887..3e79bf0a3159 100644 --- a/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/arch/powerpc/boot/dts/mpc8544ds.dts | |||
@@ -44,8 +44,18 @@ | |||
44 | #size-cells = <1>; | 44 | #size-cells = <1>; |
45 | #interrupt-cells = <2>; | 45 | #interrupt-cells = <2>; |
46 | device_type = "soc"; | 46 | device_type = "soc"; |
47 | ranges = <0 e0000000 00100000>; | 47 | |
48 | reg = <e0000000 00100000>; // CCSRBAR 1M | 48 | |
49 | ranges = <00001000 e0001000 000ff000 | ||
50 | 80000000 80000000 20000000 | ||
51 | a0000000 a0000000 10000000 | ||
52 | b0000000 b0000000 00100000 | ||
53 | c0000000 c0000000 20000000 | ||
54 | b0100000 b0100000 00100000 | ||
55 | e1000000 e1000000 00010000 | ||
56 | e1010000 e1010000 00010000 | ||
57 | e1020000 e1020000 00010000>; | ||
58 | reg = <e0000000 00001000>; // CCSRBAR 1M | ||
49 | bus-frequency = <0>; // Filled out by uboot. | 59 | bus-frequency = <0>; // Filled out by uboot. |
50 | 60 | ||
51 | memory-controller@2000 { | 61 | memory-controller@2000 { |
@@ -161,8 +171,8 @@ | |||
161 | interrupt-parent = <&mpic>; | 171 | interrupt-parent = <&mpic>; |
162 | interrupts = <18 2>; | 172 | interrupts = <18 2>; |
163 | bus-range = <0 ff>; | 173 | bus-range = <0 ff>; |
164 | ranges = <02000000 0 80000000 80000000 0 10000000 | 174 | ranges = <02000000 0 c0000000 c0000000 0 20000000 |
165 | 01000000 0 00000000 e2000000 0 00800000>; | 175 | 01000000 0 00000000 e1000000 0 00010000>; |
166 | clock-frequency = <3f940aa>; | 176 | clock-frequency = <3f940aa>; |
167 | #interrupt-cells = <1>; | 177 | #interrupt-cells = <1>; |
168 | #size-cells = <2>; | 178 | #size-cells = <2>; |
@@ -178,8 +188,8 @@ | |||
178 | #address-cells = <3>; | 188 | #address-cells = <3>; |
179 | reg = <9000 1000>; | 189 | reg = <9000 1000>; |
180 | bus-range = <0 ff>; | 190 | bus-range = <0 ff>; |
181 | ranges = <02000000 0 90000000 90000000 0 10000000 | 191 | ranges = <02000000 0 80000000 80000000 0 20000000 |
182 | 01000000 0 00000000 e3000000 0 00800000>; | 192 | 01000000 0 00000000 e1010000 0 00010000>; |
183 | clock-frequency = <1fca055>; | 193 | clock-frequency = <1fca055>; |
184 | interrupt-parent = <&mpic>; | 194 | interrupt-parent = <&mpic>; |
185 | interrupts = <1a 2>; | 195 | interrupts = <1a 2>; |
@@ -202,7 +212,7 @@ | |||
202 | reg = <a000 1000>; | 212 | reg = <a000 1000>; |
203 | bus-range = <0 ff>; | 213 | bus-range = <0 ff>; |
204 | ranges = <02000000 0 a0000000 a0000000 0 10000000 | 214 | ranges = <02000000 0 a0000000 a0000000 0 10000000 |
205 | 01000000 0 00000000 e2800000 0 00800000>; | 215 | 01000000 0 00000000 e1020000 0 00010000>; |
206 | clock-frequency = <1fca055>; | 216 | clock-frequency = <1fca055>; |
207 | interrupt-parent = <&mpic>; | 217 | interrupt-parent = <&mpic>; |
208 | interrupts = <19 2>; | 218 | interrupts = <19 2>; |
@@ -224,49 +234,29 @@ | |||
224 | #address-cells = <3>; | 234 | #address-cells = <3>; |
225 | reg = <b000 1000>; | 235 | reg = <b000 1000>; |
226 | bus-range = <0 ff>; | 236 | bus-range = <0 ff>; |
227 | ranges = <02000000 0 b0000000 b0000000 0 10000000 | 237 | ranges = <02000000 0 b0000000 b0000000 0 00100000 |
228 | 01000000 0 00000000 e3800000 0 00800000>; | 238 | 01000000 0 00000000 b0100000 0 00100000>; |
229 | clock-frequency = <1fca055>; | 239 | clock-frequency = <1fca055>; |
230 | interrupt-parent = <&mpic>; | 240 | interrupt-parent = <&mpic>; |
231 | interrupts = <1b 2>; | 241 | interrupts = <1b 2>; |
232 | interrupt-map-mask = <f800 0 0 7>; | 242 | interrupt-map-mask = <fb00 0 0 0>; |
233 | interrupt-map = < | 243 | interrupt-map = < |
234 | |||
235 | // IDSEL 0x1a | ||
236 | d000 0 0 1 &i8259 6 2 | ||
237 | d000 0 0 2 &i8259 3 2 | ||
238 | d000 0 0 3 &i8259 4 2 | ||
239 | d000 0 0 4 &i8259 5 2 | ||
240 | |||
241 | // IDSEL 0x1b | ||
242 | d800 0 0 1 &i8259 5 2 | ||
243 | d800 0 0 2 &i8259 0 0 | ||
244 | d800 0 0 3 &i8259 0 0 | ||
245 | d800 0 0 4 &i8259 0 0 | ||
246 | |||
247 | // IDSEL 0x1c USB | 244 | // IDSEL 0x1c USB |
248 | e000 0 0 1 &i8259 9 2 | 245 | e000 0 0 0 &i8259 c 2 |
249 | e000 0 0 2 &i8259 a 2 | 246 | e100 0 0 0 &i8259 9 2 |
250 | e000 0 0 3 &i8259 c 2 | 247 | e200 0 0 0 &i8259 a 2 |
251 | e000 0 0 4 &i8259 7 2 | 248 | e300 0 0 0 &i8259 b 2 |
252 | 249 | ||
253 | // IDSEL 0x1d Audio | 250 | // IDSEL 0x1d Audio |
254 | e800 0 0 1 &i8259 9 2 | 251 | e800 0 0 0 &i8259 6 2 |
255 | e800 0 0 2 &i8259 a 2 | ||
256 | e800 0 0 3 &i8259 b 2 | ||
257 | e800 0 0 4 &i8259 0 0 | ||
258 | 252 | ||
259 | // IDSEL 0x1e Legacy | 253 | // IDSEL 0x1e Legacy |
260 | f000 0 0 1 &i8259 c 2 | 254 | f000 0 0 0 &i8259 7 2 |
261 | f000 0 0 2 &i8259 0 0 | 255 | f100 0 0 0 &i8259 7 2 |
262 | f000 0 0 3 &i8259 0 0 | ||
263 | f000 0 0 4 &i8259 0 0 | ||
264 | 256 | ||
265 | // IDSEL 0x1f IDE/SATA | 257 | // IDSEL 0x1f IDE/SATA |
266 | f800 0 0 1 &i8259 6 2 | 258 | f800 0 0 0 &i8259 e 2 |
267 | f800 0 0 2 &i8259 0 0 | 259 | f900 0 0 0 &i8259 5 2 |
268 | f800 0 0 3 &i8259 0 0 | ||
269 | f800 0 0 4 &i8259 0 0 | ||
270 | >; | 260 | >; |
271 | uli1575@0 { | 261 | uli1575@0 { |
272 | reg = <0 0 0 0 0>; | 262 | reg = <0 0 0 0 0>; |
@@ -274,10 +264,10 @@ | |||
274 | #address-cells = <3>; | 264 | #address-cells = <3>; |
275 | ranges = <02000000 0 b0000000 | 265 | ranges = <02000000 0 b0000000 |
276 | 02000000 0 b0000000 | 266 | 02000000 0 b0000000 |
277 | 0 10000000 | 267 | 0 00100000 |
278 | 01000000 0 00000000 | 268 | 01000000 0 00000000 |
279 | 01000000 0 00000000 | 269 | 01000000 0 00000000 |
280 | 0 00080000>; | 270 | 0 00100000>; |
281 | 271 | ||
282 | pci_bridge@0 { | 272 | pci_bridge@0 { |
283 | reg = <0 0 0 0 0>; | 273 | reg = <0 0 0 0 0>; |
@@ -285,10 +275,10 @@ | |||
285 | #address-cells = <3>; | 275 | #address-cells = <3>; |
286 | ranges = <02000000 0 b0000000 | 276 | ranges = <02000000 0 b0000000 |
287 | 02000000 0 b0000000 | 277 | 02000000 0 b0000000 |
288 | 0 20000000 | 278 | 0 00100000 |
289 | 01000000 0 00000000 | 279 | 01000000 0 00000000 |
290 | 01000000 0 00000000 | 280 | 01000000 0 00000000 |
291 | 0 00100000>; | 281 | 0 00100000>; |
292 | 282 | ||
293 | isa@1e { | 283 | isa@1e { |
294 | device_type = "isa"; | 284 | device_type = "isa"; |
@@ -296,7 +286,8 @@ | |||
296 | #size-cells = <1>; | 286 | #size-cells = <1>; |
297 | #address-cells = <2>; | 287 | #address-cells = <2>; |
298 | reg = <f000 0 0 0 0>; | 288 | reg = <f000 0 0 0 0>; |
299 | ranges = <1 0 01000000 0 0 | 289 | ranges = <1 0 |
290 | 01000000 0 0 | ||
300 | 00001000>; | 291 | 00001000>; |
301 | interrupt-parent = <&i8259>; | 292 | interrupt-parent = <&i8259>; |
302 | 293 | ||
@@ -312,8 +303,7 @@ | |||
312 | built-in; | 303 | built-in; |
313 | compatible = "chrp,iic"; | 304 | compatible = "chrp,iic"; |
314 | interrupts = <9 2>; | 305 | interrupts = <9 2>; |
315 | interrupt-parent = | 306 | interrupt-parent = <&mpic>; |
316 | <&mpic>; | ||
317 | }; | 307 | }; |
318 | 308 | ||
319 | i8042@60 { | 309 | i8042@60 { |
@@ -321,8 +311,7 @@ | |||
321 | #address-cells = <1>; | 311 | #address-cells = <1>; |
322 | reg = <1 60 1 1 64 1>; | 312 | reg = <1 60 1 1 64 1>; |
323 | interrupts = <1 3 c 3>; | 313 | interrupts = <1 3 c 3>; |
324 | interrupt-parent = | 314 | interrupt-parent = <&i8259>; |
325 | <&i8259>; | ||
326 | 315 | ||
327 | keyboard@0 { | 316 | keyboard@0 { |
328 | reg = <0>; | 317 | reg = <0>; |
@@ -336,8 +325,7 @@ | |||
336 | }; | 325 | }; |
337 | 326 | ||
338 | rtc@70 { | 327 | rtc@70 { |
339 | compatible = | 328 | compatible = "pnpPNP,b00"; |
340 | "pnpPNP,b00"; | ||
341 | reg = <1 70 2>; | 329 | reg = <1 70 2>; |
342 | }; | 330 | }; |
343 | 331 | ||
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts index 5d82709cfcbb..b0166e5c177e 100644 --- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts +++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts | |||
@@ -224,98 +224,36 @@ | |||
224 | clock-frequency = <1fca055>; | 224 | clock-frequency = <1fca055>; |
225 | interrupt-parent = <&mpic>; | 225 | interrupt-parent = <&mpic>; |
226 | interrupts = <18 2>; | 226 | interrupts = <18 2>; |
227 | interrupt-map-mask = <f800 0 0 7>; | 227 | interrupt-map-mask = <fb00 0 0 0>; |
228 | interrupt-map = < | 228 | interrupt-map = < |
229 | /* IDSEL 0x11 */ | 229 | /* IDSEL 0x11 */ |
230 | 8800 0 0 1 &i8259 3 2 | 230 | 8800 0 0 1 &i8259 9 2 |
231 | 8800 0 0 2 &i8259 4 2 | 231 | 8800 0 0 2 &i8259 a 2 |
232 | 8800 0 0 3 &i8259 5 2 | 232 | 8800 0 0 3 &i8259 b 2 |
233 | 8800 0 0 4 &i8259 6 2 | 233 | 8800 0 0 4 &i8259 c 2 |
234 | 234 | ||
235 | /* IDSEL 0x12 */ | 235 | /* IDSEL 0x12 */ |
236 | 9000 0 0 1 &i8259 4 2 | 236 | 9000 0 0 1 &i8259 a 2 |
237 | 9000 0 0 2 &i8259 5 2 | 237 | 9000 0 0 2 &i8259 b 2 |
238 | 9000 0 0 3 &i8259 6 2 | 238 | 9000 0 0 3 &i8259 c 2 |
239 | 9000 0 0 4 &i8259 3 2 | 239 | 9000 0 0 4 &i8259 9 2 |
240 | 240 | ||
241 | /* IDSEL 0x13 */ | 241 | // IDSEL 0x1c USB |
242 | 9800 0 0 1 &i8259 0 0 | 242 | e000 0 0 0 &i8259 c 2 |
243 | 9800 0 0 2 &i8259 0 0 | 243 | e100 0 0 0 &i8259 9 2 |
244 | 9800 0 0 3 &i8259 0 0 | 244 | e200 0 0 0 &i8259 a 2 |
245 | 9800 0 0 4 &i8259 0 0 | 245 | e300 0 0 0 &i8259 b 2 |
246 | 246 | ||
247 | /* IDSEL 0x14 */ | 247 | // IDSEL 0x1d Audio |
248 | a000 0 0 1 &i8259 0 0 | 248 | e800 0 0 0 &i8259 6 2 |
249 | a000 0 0 2 &i8259 0 0 | 249 | |
250 | a000 0 0 3 &i8259 0 0 | 250 | // IDSEL 0x1e Legacy |
251 | a000 0 0 4 &i8259 0 0 | 251 | f000 0 0 0 &i8259 7 2 |
252 | 252 | f100 0 0 0 &i8259 7 2 | |
253 | /* IDSEL 0x15 */ | 253 | |
254 | a800 0 0 1 &i8259 0 0 | 254 | // IDSEL 0x1f IDE/SATA |
255 | a800 0 0 2 &i8259 0 0 | 255 | f800 0 0 0 &i8259 e 2 |
256 | a800 0 0 3 &i8259 0 0 | 256 | f900 0 0 0 &i8259 5 2 |
257 | a800 0 0 4 &i8259 0 0 | ||
258 | |||
259 | /* IDSEL 0x16 */ | ||
260 | b000 0 0 1 &i8259 0 0 | ||
261 | b000 0 0 2 &i8259 0 0 | ||
262 | b000 0 0 3 &i8259 0 0 | ||
263 | b000 0 0 4 &i8259 0 0 | ||
264 | |||
265 | /* IDSEL 0x17 */ | ||
266 | b800 0 0 1 &i8259 0 0 | ||
267 | b800 0 0 2 &i8259 0 0 | ||
268 | b800 0 0 3 &i8259 0 0 | ||
269 | b800 0 0 4 &i8259 0 0 | ||
270 | |||
271 | /* IDSEL 0x18 */ | ||
272 | c000 0 0 1 &i8259 0 0 | ||
273 | c000 0 0 2 &i8259 0 0 | ||
274 | c000 0 0 3 &i8259 0 0 | ||
275 | c000 0 0 4 &i8259 0 0 | ||
276 | |||
277 | /* IDSEL 0x19 */ | ||
278 | c800 0 0 1 &i8259 0 0 | ||
279 | c800 0 0 2 &i8259 0 0 | ||
280 | c800 0 0 3 &i8259 0 0 | ||
281 | c800 0 0 4 &i8259 0 0 | ||
282 | |||
283 | /* IDSEL 0x1a */ | ||
284 | d000 0 0 1 &i8259 6 2 | ||
285 | d000 0 0 2 &i8259 3 2 | ||
286 | d000 0 0 3 &i8259 4 2 | ||
287 | d000 0 0 4 &i8259 5 2 | ||
288 | |||
289 | |||
290 | /* IDSEL 0x1b */ | ||
291 | d800 0 0 1 &i8259 5 2 | ||
292 | d800 0 0 2 &i8259 0 0 | ||
293 | d800 0 0 3 &i8259 0 0 | ||
294 | d800 0 0 4 &i8259 0 0 | ||
295 | |||
296 | /* IDSEL 0x1c */ | ||
297 | e000 0 0 1 &i8259 9 2 | ||
298 | e000 0 0 2 &i8259 a 2 | ||
299 | e000 0 0 3 &i8259 c 2 | ||
300 | e000 0 0 4 &i8259 7 2 | ||
301 | |||
302 | /* IDSEL 0x1d */ | ||
303 | e800 0 0 1 &i8259 9 2 | ||
304 | e800 0 0 2 &i8259 a 2 | ||
305 | e800 0 0 3 &i8259 b 2 | ||
306 | e800 0 0 4 &i8259 0 0 | ||
307 | |||
308 | /* IDSEL 0x1e */ | ||
309 | f000 0 0 1 &i8259 c 2 | ||
310 | f000 0 0 2 &i8259 0 0 | ||
311 | f000 0 0 3 &i8259 0 0 | ||
312 | f000 0 0 4 &i8259 0 0 | ||
313 | |||
314 | /* IDSEL 0x1f */ | ||
315 | f800 0 0 1 &i8259 6 2 | ||
316 | f800 0 0 2 &i8259 0 0 | ||
317 | f800 0 0 3 &i8259 0 0 | ||
318 | f800 0 0 4 &i8259 0 0 | ||
319 | >; | 257 | >; |
320 | uli1575@0 { | 258 | uli1575@0 { |
321 | reg = <0 0 0 0 0>; | 259 | reg = <0 0 0 0 0>; |
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index f58184086c8c..f620171ad6b1 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -33,6 +33,7 @@ config MPC8544_DS | |||
33 | bool "Freescale MPC8544 DS" | 33 | bool "Freescale MPC8544 DS" |
34 | select PPC_I8259 | 34 | select PPC_I8259 |
35 | select DEFAULT_UIMAGE | 35 | select DEFAULT_UIMAGE |
36 | select FSL_ULI1575 | ||
36 | help | 37 | help |
37 | This option enables support for the MPC8544 DS board | 38 | This option enables support for the MPC8544 DS board |
38 | 39 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c index 4905f6f8903b..0f834d8be444 100644 --- a/arch/powerpc/platforms/85xx/mpc8544_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c | |||
@@ -114,211 +114,25 @@ void __init mpc8544_ds_pic_init(void) | |||
114 | } | 114 | } |
115 | 115 | ||
116 | #ifdef CONFIG_PCI | 116 | #ifdef CONFIG_PCI |
117 | enum pirq { PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH }; | 117 | extern int uses_fsl_uli_m1575; |
118 | extern int uli_exclude_device(struct pci_controller *hose, | ||
119 | u_char bus, u_char devfn); | ||
118 | 120 | ||
119 | /* | 121 | static int mpc85xx_exclude_device(struct pci_controller *hose, |
120 | * Value in table -- IRQ number | 122 | u_char bus, u_char devfn) |
121 | */ | ||
122 | const unsigned char uli1575_irq_route_table[16] = { | ||
123 | 0, /* 0: Reserved */ | ||
124 | 0x8, | ||
125 | 0, /* 2: Reserved */ | ||
126 | 0x2, | ||
127 | 0x4, | ||
128 | 0x5, | ||
129 | 0x7, | ||
130 | 0x6, | ||
131 | 0, /* 8: Reserved */ | ||
132 | 0x1, | ||
133 | 0x3, | ||
134 | 0x9, | ||
135 | 0xb, | ||
136 | 0, /* 13: Reserved */ | ||
137 | 0xd, | ||
138 | 0xf, | ||
139 | }; | ||
140 | |||
141 | static int __devinit | ||
142 | get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin) | ||
143 | { | ||
144 | struct of_irq oirq; | ||
145 | u32 laddr[3]; | ||
146 | struct device_node *hosenode = hose ? hose->arch_data : NULL; | ||
147 | |||
148 | if (!hosenode) | ||
149 | return -EINVAL; | ||
150 | |||
151 | laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8); | ||
152 | laddr[1] = laddr[2] = 0; | ||
153 | of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq); | ||
154 | DBG("mpc8544_ds: pci irq addr %x, slot %d, pin %d, irq %d\n", | ||
155 | laddr[0], slot, pin, oirq.specifier[0]); | ||
156 | return oirq.specifier[0]; | ||
157 | } | ||
158 | |||
159 | /*8259*/ | ||
160 | static void __devinit quirk_uli1575(struct pci_dev *dev) | ||
161 | { | ||
162 | unsigned short temp; | ||
163 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
164 | unsigned char irq2pin[16]; | ||
165 | unsigned long pirq_map_word = 0; | ||
166 | u32 irq; | ||
167 | int i; | ||
168 | |||
169 | /* | ||
170 | * ULI1575 interrupts route setup | ||
171 | */ | ||
172 | memset(irq2pin, 0, 16); /* Initialize default value 0 */ | ||
173 | |||
174 | irq2pin[6]=PIRQA+3; /* enabled mapping for IRQ6 to PIRQD, used by SATA */ | ||
175 | |||
176 | /* | ||
177 | * PIRQE -> PIRQF mapping set manually | ||
178 | * | ||
179 | * IRQ pin IRQ# | ||
180 | * PIRQE ---- 9 | ||
181 | * PIRQF ---- 10 | ||
182 | * PIRQG ---- 11 | ||
183 | * PIRQH ---- 12 | ||
184 | */ | ||
185 | for (i = 0; i < 4; i++) | ||
186 | irq2pin[i + 9] = PIRQE + i; | ||
187 | |||
188 | /* Set IRQ-PIRQ Mapping to ULI1575 */ | ||
189 | for (i = 0; i < 16; i++) | ||
190 | if (irq2pin[i]) | ||
191 | pirq_map_word |= (uli1575_irq_route_table[i] & 0xf) | ||
192 | << ((irq2pin[i] - PIRQA) * 4); | ||
193 | |||
194 | pirq_map_word |= 1<<26; /* disable INTx in EP mode*/ | ||
195 | |||
196 | /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */ | ||
197 | DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n", | ||
198 | (int)pirq_map_word); | ||
199 | pci_write_config_dword(dev, 0x48, pirq_map_word); | ||
200 | |||
201 | #define ULI1575_SET_DEV_IRQ(slot, pin, reg) \ | ||
202 | do { \ | ||
203 | int irq; \ | ||
204 | irq = get_pci_irq_from_of(hose, slot, pin); \ | ||
205 | if (irq > 0 && irq < 16) \ | ||
206 | pci_write_config_byte(dev, reg, irq2pin[irq]); \ | ||
207 | else \ | ||
208 | printk(KERN_WARNING "ULI1575 device" \ | ||
209 | "(slot %d, pin %d) irq %d is invalid.\n", \ | ||
210 | slot, pin, irq); \ | ||
211 | } while(0) | ||
212 | |||
213 | /* USB 1.1 OHCI controller 1, slot 28, pin 1 */ | ||
214 | ULI1575_SET_DEV_IRQ(28, 1, 0x86); | ||
215 | |||
216 | /* USB 1.1 OHCI controller 2, slot 28, pin 2 */ | ||
217 | ULI1575_SET_DEV_IRQ(28, 2, 0x87); | ||
218 | |||
219 | /* USB 1.1 OHCI controller 3, slot 28, pin 3 */ | ||
220 | ULI1575_SET_DEV_IRQ(28, 3, 0x88); | ||
221 | |||
222 | /* USB 2.0 controller, slot 28, pin 4 */ | ||
223 | irq = get_pci_irq_from_of(hose, 28, 4); | ||
224 | if (irq >= 0 && irq <= 15) | ||
225 | pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]); | ||
226 | |||
227 | /* Audio controller, slot 29, pin 1 */ | ||
228 | ULI1575_SET_DEV_IRQ(29, 1, 0x8a); | ||
229 | |||
230 | /* Modem controller, slot 29, pin 2 */ | ||
231 | ULI1575_SET_DEV_IRQ(29, 2, 0x8b); | ||
232 | |||
233 | /* HD audio controller, slot 29, pin 3 */ | ||
234 | ULI1575_SET_DEV_IRQ(29, 3, 0x8c); | ||
235 | |||
236 | /* SMB interrupt: slot 30, pin 1 */ | ||
237 | ULI1575_SET_DEV_IRQ(30, 1, 0x8e); | ||
238 | |||
239 | /* PMU ACPI SCI interrupt: slot 30, pin 2 */ | ||
240 | ULI1575_SET_DEV_IRQ(30, 2, 0x8f); | ||
241 | |||
242 | /* Serial ATA interrupt: slot 31, pin 1 */ | ||
243 | ULI1575_SET_DEV_IRQ(31, 1, 0x8d); | ||
244 | |||
245 | /* Primary PATA IDE IRQ: 14 | ||
246 | * Secondary PATA IDE IRQ: 15 | ||
247 | */ | ||
248 | pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]); | ||
249 | pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]); | ||
250 | |||
251 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | ||
252 | pci_read_config_word(dev, 0x46, &temp); | ||
253 | temp |= 0xc000; | ||
254 | pci_write_config_word(dev, 0x46, temp); | ||
255 | |||
256 | /* Set i8259 interrupt trigger | ||
257 | * IRQ 3: Level | ||
258 | * IRQ 4: Level | ||
259 | * IRQ 5: Level | ||
260 | * IRQ 6: Level | ||
261 | * IRQ 7: Level | ||
262 | * IRQ 9: Level | ||
263 | * IRQ 10: Level | ||
264 | * IRQ 11: Level | ||
265 | * IRQ 12: Level | ||
266 | * IRQ 14: Edge | ||
267 | * IRQ 15: Edge | ||
268 | */ | ||
269 | outb(0xfa, 0x4d0); | ||
270 | outb(0x1e, 0x4d1); | ||
271 | |||
272 | #undef ULI1575_SET_DEV_IRQ | ||
273 | } | ||
274 | |||
275 | /* SATA */ | ||
276 | static void __devinit quirk_uli5288(struct pci_dev *dev) | ||
277 | { | 123 | { |
278 | unsigned char c; | 124 | struct device_node* node; |
279 | 125 | struct resource rsrc; | |
280 | pci_read_config_byte(dev, 0x83, &c); | ||
281 | c |= 0x80; /* read/write lock */ | ||
282 | pci_write_config_byte(dev, 0x83, c); | ||
283 | |||
284 | pci_write_config_byte(dev, 0x09, 0x01); /* Base class code: storage */ | ||
285 | pci_write_config_byte(dev, 0x0a, 0x06); /* IDE disk */ | ||
286 | 126 | ||
287 | pci_read_config_byte(dev, 0x83, &c); | 127 | node = (struct device_node *)hose->arch_data; |
288 | c &= 0x7f; | 128 | of_address_to_resource(node, 0, &rsrc); |
289 | pci_write_config_byte(dev, 0x83, c); | ||
290 | |||
291 | pci_read_config_byte(dev, 0x84, &c); | ||
292 | c |= 0x01; /* emulated PATA mode enabled */ | ||
293 | pci_write_config_byte(dev, 0x84, c); | ||
294 | } | ||
295 | 129 | ||
296 | /* PATA */ | 130 | if ((rsrc.start & 0xfffff) == 0xb000) { |
297 | static void __devinit quirk_uli5229(struct pci_dev *dev) | 131 | return uli_exclude_device(hose, bus, devfn); |
298 | { | 132 | } |
299 | unsigned short temp; | ||
300 | pci_write_config_word(dev, 0x04, 0x0405); /* MEM IO MSI */ | ||
301 | pci_read_config_word(dev, 0x4a, &temp); | ||
302 | temp |= 0x1000; /* Enable Native IRQ 14/15 */ | ||
303 | pci_write_config_word(dev, 0x4a, temp); | ||
304 | } | ||
305 | 133 | ||
306 | /*Bridge*/ | 134 | return PCIBIOS_SUCCESSFUL; |
307 | static void __devinit early_uli5249(struct pci_dev *dev) | ||
308 | { | ||
309 | unsigned char temp; | ||
310 | pci_write_config_word(dev, 0x04, 0x0007); /* mem access */ | ||
311 | pci_read_config_byte(dev, 0x7c, &temp); | ||
312 | pci_write_config_byte(dev, 0x7c, 0x80); /* R/W lock control */ | ||
313 | pci_write_config_byte(dev, 0x09, 0x01); /* set as pci-pci bridge */ | ||
314 | pci_write_config_byte(dev, 0x7c, temp); /* restore pci bus debug control */ | ||
315 | dev->class |= 0x1; | ||
316 | } | 135 | } |
317 | |||
318 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); | ||
319 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
320 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
321 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
322 | #endif /* CONFIG_PCI */ | 136 | #endif /* CONFIG_PCI */ |
323 | 137 | ||
324 | /* | 138 | /* |
@@ -342,6 +156,8 @@ static void __init mpc8544_ds_setup_arch(void) | |||
342 | else | 156 | else |
343 | fsl_add_bridge(np, 0); | 157 | fsl_add_bridge(np, 0); |
344 | } | 158 | } |
159 | uses_fsl_uli_m1575 = 1; | ||
160 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | ||
345 | #endif | 161 | #endif |
346 | 162 | ||
347 | printk("MPC8544 DS board from Freescale Semiconductor\n"); | 163 | printk("MPC8544 DS board from Freescale Semiconductor\n"); |
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 343b76d0d793..685b2fbbbe00 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig | |||
@@ -7,6 +7,7 @@ config MPC8641_HPCN | |||
7 | bool "Freescale MPC8641 HPCN" | 7 | bool "Freescale MPC8641 HPCN" |
8 | select PPC_I8259 | 8 | select PPC_I8259 |
9 | select DEFAULT_UIMAGE | 9 | select DEFAULT_UIMAGE |
10 | select FSL_ULI1575 | ||
10 | help | 11 | help |
11 | This option enables support for the MPC8641 HPCN board. | 12 | This option enables support for the MPC8641 HPCN board. |
12 | 13 | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index e9eaa0749ae6..56b27caf7a27 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -107,220 +107,25 @@ mpc86xx_hpcn_init_irq(void) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | #ifdef CONFIG_PCI | 109 | #ifdef CONFIG_PCI |
110 | extern int uses_fsl_uli_m1575; | ||
111 | extern int uli_exclude_device(struct pci_controller *hose, | ||
112 | u_char bus, u_char devfn); | ||
110 | 113 | ||
111 | enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH}; | 114 | static int mpc86xx_exclude_device(struct pci_controller *hose, |
112 | const unsigned char uli1575_irq_route_table[16] = { | 115 | u_char bus, u_char devfn) |
113 | 0, /* 0: Reserved */ | ||
114 | 0x8, /* 1: 0b1000 */ | ||
115 | 0, /* 2: Reserved */ | ||
116 | 0x2, /* 3: 0b0010 */ | ||
117 | 0x4, /* 4: 0b0100 */ | ||
118 | 0x5, /* 5: 0b0101 */ | ||
119 | 0x7, /* 6: 0b0111 */ | ||
120 | 0x6, /* 7: 0b0110 */ | ||
121 | 0, /* 8: Reserved */ | ||
122 | 0x1, /* 9: 0b0001 */ | ||
123 | 0x3, /* 10: 0b0011 */ | ||
124 | 0x9, /* 11: 0b1001 */ | ||
125 | 0xb, /* 12: 0b1011 */ | ||
126 | 0, /* 13: Reserved */ | ||
127 | 0xd, /* 14, 0b1101 */ | ||
128 | 0xf, /* 15, 0b1111 */ | ||
129 | }; | ||
130 | |||
131 | static int __devinit | ||
132 | get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin) | ||
133 | { | ||
134 | struct of_irq oirq; | ||
135 | u32 laddr[3]; | ||
136 | struct device_node *hosenode = hose ? hose->arch_data : NULL; | ||
137 | |||
138 | if (!hosenode) return -EINVAL; | ||
139 | |||
140 | laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8); | ||
141 | laddr[1] = laddr[2] = 0; | ||
142 | of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq); | ||
143 | DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n", | ||
144 | laddr[0], slot, pin, oirq.specifier[0]); | ||
145 | return oirq.specifier[0]; | ||
146 | } | ||
147 | |||
148 | static void __devinit quirk_uli1575(struct pci_dev *dev) | ||
149 | { | ||
150 | unsigned short temp; | ||
151 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
152 | unsigned char irq2pin[16], c; | ||
153 | unsigned long pirq_map_word = 0; | ||
154 | u32 irq; | ||
155 | int i; | ||
156 | |||
157 | /* | ||
158 | * ULI1575 interrupts route setup | ||
159 | */ | ||
160 | memset(irq2pin, 0, 16); /* Initialize default value 0 */ | ||
161 | |||
162 | /* | ||
163 | * PIRQA -> PIRQD mapping read from OF-tree | ||
164 | * | ||
165 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
166 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
167 | */ | ||
168 | for (i = 0; i < 4; i++){ | ||
169 | irq = get_pci_irq_from_of(hose, 17, i + 1); | ||
170 | if (irq > 0 && irq < 16) | ||
171 | irq2pin[irq] = PIRQA + i; | ||
172 | else | ||
173 | printk(KERN_WARNING "ULI1575 device" | ||
174 | "(slot %d, pin %d) irq %d is invalid.\n", | ||
175 | 17, i, irq); | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * PIRQE -> PIRQF mapping set manually | ||
180 | * | ||
181 | * IRQ pin IRQ# | ||
182 | * PIRQE ---- 9 | ||
183 | * PIRQF ---- 10 | ||
184 | * PIRQG ---- 11 | ||
185 | * PIRQH ---- 12 | ||
186 | */ | ||
187 | for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i; | ||
188 | |||
189 | /* Set IRQ-PIRQ Mapping to ULI1575 */ | ||
190 | for (i = 0; i < 16; i++) | ||
191 | if (irq2pin[i]) | ||
192 | pirq_map_word |= (uli1575_irq_route_table[i] & 0xf) | ||
193 | << ((irq2pin[i] - PIRQA) * 4); | ||
194 | |||
195 | /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */ | ||
196 | DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n", | ||
197 | pirq_map_word); | ||
198 | pci_write_config_dword(dev, 0x48, pirq_map_word); | ||
199 | |||
200 | #define ULI1575_SET_DEV_IRQ(slot, pin, reg) \ | ||
201 | do { \ | ||
202 | int irq; \ | ||
203 | irq = get_pci_irq_from_of(hose, slot, pin); \ | ||
204 | if (irq > 0 && irq < 16) \ | ||
205 | pci_write_config_byte(dev, reg, irq2pin[irq]); \ | ||
206 | else \ | ||
207 | printk(KERN_WARNING "ULI1575 device" \ | ||
208 | "(slot %d, pin %d) irq %d is invalid.\n", \ | ||
209 | slot, pin, irq); \ | ||
210 | } while(0) | ||
211 | |||
212 | /* USB 1.1 OHCI controller 1, slot 28, pin 1 */ | ||
213 | ULI1575_SET_DEV_IRQ(28, 1, 0x86); | ||
214 | |||
215 | /* USB 1.1 OHCI controller 2, slot 28, pin 2 */ | ||
216 | ULI1575_SET_DEV_IRQ(28, 2, 0x87); | ||
217 | |||
218 | /* USB 1.1 OHCI controller 3, slot 28, pin 3 */ | ||
219 | ULI1575_SET_DEV_IRQ(28, 3, 0x88); | ||
220 | |||
221 | /* USB 2.0 controller, slot 28, pin 4 */ | ||
222 | irq = get_pci_irq_from_of(hose, 28, 4); | ||
223 | if (irq >= 0 && irq <=15) | ||
224 | pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]); | ||
225 | |||
226 | /* Audio controller, slot 29, pin 1 */ | ||
227 | ULI1575_SET_DEV_IRQ(29, 1, 0x8a); | ||
228 | |||
229 | /* Modem controller, slot 29, pin 2 */ | ||
230 | ULI1575_SET_DEV_IRQ(29, 2, 0x8b); | ||
231 | |||
232 | /* HD audio controller, slot 29, pin 3 */ | ||
233 | ULI1575_SET_DEV_IRQ(29, 3, 0x8c); | ||
234 | |||
235 | /* SMB interrupt: slot 30, pin 1 */ | ||
236 | ULI1575_SET_DEV_IRQ(30, 1, 0x8e); | ||
237 | |||
238 | /* PMU ACPI SCI interrupt: slot 30, pin 2 */ | ||
239 | ULI1575_SET_DEV_IRQ(30, 2, 0x8f); | ||
240 | |||
241 | /* Serial ATA interrupt: slot 31, pin 1 */ | ||
242 | ULI1575_SET_DEV_IRQ(31, 1, 0x8d); | ||
243 | |||
244 | /* Primary PATA IDE IRQ: 14 | ||
245 | * Secondary PATA IDE IRQ: 15 | ||
246 | */ | ||
247 | pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]); | ||
248 | pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]); | ||
249 | |||
250 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | ||
251 | pci_read_config_word(dev, 0x46, &temp); | ||
252 | temp |= 0xc000; | ||
253 | pci_write_config_word(dev, 0x46, temp); | ||
254 | |||
255 | /* Set i8259 interrupt trigger | ||
256 | * IRQ 3: Level | ||
257 | * IRQ 4: Level | ||
258 | * IRQ 5: Level | ||
259 | * IRQ 6: Level | ||
260 | * IRQ 7: Level | ||
261 | * IRQ 9: Level | ||
262 | * IRQ 10: Level | ||
263 | * IRQ 11: Level | ||
264 | * IRQ 12: Level | ||
265 | * IRQ 14: Edge | ||
266 | * IRQ 15: Edge | ||
267 | */ | ||
268 | outb(0xfa, 0x4d0); | ||
269 | outb(0x1e, 0x4d1); | ||
270 | |||
271 | #undef ULI1575_SET_DEV_IRQ | ||
272 | |||
273 | /* Disable the HD interface and enable the AC97 interface. */ | ||
274 | pci_read_config_byte(dev, 0xb8, &c); | ||
275 | c &= 0x7f; | ||
276 | pci_write_config_byte(dev, 0xb8, c); | ||
277 | } | ||
278 | |||
279 | static void __devinit quirk_uli5288(struct pci_dev *dev) | ||
280 | { | 116 | { |
281 | unsigned char c; | 117 | struct device_node* node; |
118 | struct resource rsrc; | ||
282 | 119 | ||
283 | pci_read_config_byte(dev,0x83,&c); | 120 | node = (struct device_node *)hose->arch_data; |
284 | c |= 0x80; | 121 | of_address_to_resource(node, 0, &rsrc); |
285 | pci_write_config_byte(dev, 0x83, c); | ||
286 | 122 | ||
287 | pci_write_config_byte(dev, 0x09, 0x01); | 123 | if ((rsrc.start & 0xfffff) == 0x8000) { |
288 | pci_write_config_byte(dev, 0x0a, 0x06); | 124 | return uli_exclude_device(hose, bus, devfn); |
289 | 125 | } | |
290 | pci_read_config_byte(dev,0x83,&c); | ||
291 | c &= 0x7f; | ||
292 | pci_write_config_byte(dev, 0x83, c); | ||
293 | |||
294 | pci_read_config_byte(dev,0x84,&c); | ||
295 | c |= 0x01; | ||
296 | pci_write_config_byte(dev, 0x84, c); | ||
297 | } | ||
298 | |||
299 | static void __devinit quirk_uli5229(struct pci_dev *dev) | ||
300 | { | ||
301 | unsigned short temp; | ||
302 | pci_write_config_word(dev, 0x04, 0x0405); | ||
303 | dev->class &= ~0x5; | ||
304 | pci_read_config_word(dev, 0x4a, &temp); | ||
305 | temp |= 0x1000; | ||
306 | pci_write_config_word(dev, 0x4a, temp); | ||
307 | } | ||
308 | 126 | ||
309 | static void __devinit early_uli5249(struct pci_dev *dev) | 127 | return PCIBIOS_SUCCESSFUL; |
310 | { | ||
311 | unsigned char temp; | ||
312 | pci_write_config_word(dev, 0x04, 0x0007); | ||
313 | pci_read_config_byte(dev, 0x7c, &temp); | ||
314 | pci_write_config_byte(dev, 0x7c, 0x80); | ||
315 | pci_write_config_byte(dev, 0x09, 0x01); | ||
316 | pci_write_config_byte(dev, 0x7c, temp); | ||
317 | dev->class |= 0x1; | ||
318 | } | 128 | } |
319 | |||
320 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); | ||
321 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
322 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
323 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
324 | #endif /* CONFIG_PCI */ | 129 | #endif /* CONFIG_PCI */ |
325 | 130 | ||
326 | 131 | ||
@@ -353,6 +158,9 @@ mpc86xx_hpcn_setup_arch(void) | |||
353 | else | 158 | else |
354 | fsl_add_bridge(np, 0); | 159 | fsl_add_bridge(np, 0); |
355 | } | 160 | } |
161 | uses_fsl_uli_m1575 = 1; | ||
162 | ppc_md.pci_exclude_device = mpc86xx_exclude_device; | ||
163 | |||
356 | #endif | 164 | #endif |
357 | 165 | ||
358 | printk("MPC86xx HPCN board from Freescale Semiconductor\n"); | 166 | printk("MPC86xx HPCN board from Freescale Semiconductor\n"); |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 932538a93c2b..cfc249741592 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -282,4 +282,12 @@ config AXON_RAM | |||
282 | minor numbers are available in /proc/devices, /proc/partitions or | 282 | minor numbers are available in /proc/devices, /proc/partitions or |
283 | in /sys/block/axonram?/dev. | 283 | in /sys/block/axonram?/dev. |
284 | 284 | ||
285 | config FSL_ULI1575 | ||
286 | bool | ||
287 | default n | ||
288 | help | ||
289 | Supports for the ULI1575 PCIe south bridge that exists on some | ||
290 | Freescale reference boards. The boards all use the ULI in pretty | ||
291 | much the same way. | ||
292 | |||
285 | endmenu | 293 | endmenu |
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index d6e041a46d25..d44e832b01f2 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile | |||
@@ -1,3 +1,6 @@ | |||
1 | |||
2 | obj-$(CONFIG_FSL_ULI1575) += fsl_uli1575.o | ||
3 | |||
1 | ifeq ($(CONFIG_PPC_MERGE),y) | 4 | ifeq ($(CONFIG_PPC_MERGE),y) |
2 | obj-$(CONFIG_PPC_PMAC) += powermac/ | 5 | obj-$(CONFIG_PPC_PMAC) += powermac/ |
3 | else | 6 | else |
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c new file mode 100644 index 000000000000..afc9141be63e --- /dev/null +++ b/arch/powerpc/platforms/fsl_uli1575.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * ULI M1575 setup code - specific to Freescale boards | ||
3 | * | ||
4 | * Copyright 2007 Freescale Semiconductor Inc. | ||
5 | * | ||
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 | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/stddef.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/mc146818rtc.h> | ||
17 | |||
18 | #include <asm/system.h> | ||
19 | #include <asm/pci-bridge.h> | ||
20 | |||
21 | #define ULI_PIRQA 0x08 | ||
22 | #define ULI_PIRQB 0x09 | ||
23 | #define ULI_PIRQC 0x0a | ||
24 | #define ULI_PIRQD 0x0b | ||
25 | #define ULI_PIRQE 0x0c | ||
26 | #define ULI_PIRQF 0x0d | ||
27 | #define ULI_PIRQG 0x0e | ||
28 | |||
29 | #define ULI_8259_NONE 0x00 | ||
30 | #define ULI_8259_IRQ1 0x08 | ||
31 | #define ULI_8259_IRQ3 0x02 | ||
32 | #define ULI_8259_IRQ4 0x04 | ||
33 | #define ULI_8259_IRQ5 0x05 | ||
34 | #define ULI_8259_IRQ6 0x07 | ||
35 | #define ULI_8259_IRQ7 0x06 | ||
36 | #define ULI_8259_IRQ9 0x01 | ||
37 | #define ULI_8259_IRQ10 0x03 | ||
38 | #define ULI_8259_IRQ11 0x09 | ||
39 | #define ULI_8259_IRQ12 0x0b | ||
40 | #define ULI_8259_IRQ14 0x0d | ||
41 | #define ULI_8259_IRQ15 0x0f | ||
42 | |||
43 | u8 uli_pirq_to_irq[8] = { | ||
44 | ULI_8259_IRQ9, /* PIRQA */ | ||
45 | ULI_8259_IRQ10, /* PIRQB */ | ||
46 | ULI_8259_IRQ11, /* PIRQC */ | ||
47 | ULI_8259_IRQ12, /* PIRQD */ | ||
48 | ULI_8259_IRQ5, /* PIRQE */ | ||
49 | ULI_8259_IRQ6, /* PIRQF */ | ||
50 | ULI_8259_IRQ7, /* PIRQG */ | ||
51 | ULI_8259_NONE, /* PIRQH */ | ||
52 | }; | ||
53 | |||
54 | /* set in board code if you want this quirks to do something */ | ||
55 | int uses_fsl_uli_m1575; | ||
56 | |||
57 | /* Bridge */ | ||
58 | static void __devinit early_uli5249(struct pci_dev *dev) | ||
59 | { | ||
60 | unsigned char temp; | ||
61 | |||
62 | if (!uses_fsl_uli_m1575) | ||
63 | return; | ||
64 | |||
65 | pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO | | ||
66 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); | ||
67 | |||
68 | /* read/write lock */ | ||
69 | pci_read_config_byte(dev, 0x7c, &temp); | ||
70 | pci_write_config_byte(dev, 0x7c, 0x80); | ||
71 | |||
72 | /* set as P2P bridge */ | ||
73 | pci_write_config_byte(dev, PCI_CLASS_PROG, 0x01); | ||
74 | dev->class |= 0x1; | ||
75 | |||
76 | /* restore lock */ | ||
77 | pci_write_config_byte(dev, 0x7c, temp); | ||
78 | } | ||
79 | |||
80 | |||
81 | static void __devinit quirk_uli1575(struct pci_dev *dev) | ||
82 | { | ||
83 | int i; | ||
84 | |||
85 | if (!uses_fsl_uli_m1575) | ||
86 | return; | ||
87 | |||
88 | /* | ||
89 | * ULI1575 interrupts route setup | ||
90 | */ | ||
91 | |||
92 | /* ULI1575 IRQ mapping conf register maps PIRQx to IRQn */ | ||
93 | for (i = 0; i < 4; i++) { | ||
94 | u8 val = uli_pirq_to_irq[i*2] | (uli_pirq_to_irq[i*2+1] << 4); | ||
95 | pci_write_config_byte(dev, 0x48 + i, val); | ||
96 | } | ||
97 | |||
98 | /* USB 1.1 OHCI controller 1: dev 28, func 0 - IRQ12 */ | ||
99 | pci_write_config_byte(dev, 0x86, ULI_PIRQD); | ||
100 | |||
101 | /* USB 1.1 OHCI controller 2: dev 28, func 1 - IRQ9 */ | ||
102 | pci_write_config_byte(dev, 0x87, ULI_PIRQA); | ||
103 | |||
104 | /* USB 1.1 OHCI controller 3: dev 28, func 2 - IRQ10 */ | ||
105 | pci_write_config_byte(dev, 0x88, ULI_PIRQB); | ||
106 | |||
107 | /* Lan controller: dev 27, func 0 - IRQ6 */ | ||
108 | pci_write_config_byte(dev, 0x89, ULI_PIRQF); | ||
109 | |||
110 | /* AC97 Audio controller: dev 29, func 0 - IRQ6 */ | ||
111 | pci_write_config_byte(dev, 0x8a, ULI_PIRQF); | ||
112 | |||
113 | /* Modem controller: dev 29, func 1 - IRQ6 */ | ||
114 | pci_write_config_byte(dev, 0x8b, ULI_PIRQF); | ||
115 | |||
116 | /* HD Audio controller: dev 29, func 2 - IRQ6 */ | ||
117 | pci_write_config_byte(dev, 0x8c, ULI_PIRQF); | ||
118 | |||
119 | /* SATA controller: dev 31, func 1 - IRQ5 */ | ||
120 | pci_write_config_byte(dev, 0x8d, ULI_PIRQE); | ||
121 | |||
122 | /* SMB interrupt: dev 30, func 1 - IRQ7 */ | ||
123 | pci_write_config_byte(dev, 0x8e, ULI_PIRQG); | ||
124 | |||
125 | /* PMU ACPI SCI interrupt: dev 30, func 2 - IRQ7 */ | ||
126 | pci_write_config_byte(dev, 0x8f, ULI_PIRQG); | ||
127 | |||
128 | /* USB 2.0 controller: dev 28, func 3 */ | ||
129 | pci_write_config_byte(dev, 0x74, ULI_8259_IRQ11); | ||
130 | |||
131 | /* Primary PATA IDE IRQ: 14 | ||
132 | * Secondary PATA IDE IRQ: 15 | ||
133 | */ | ||
134 | pci_write_config_byte(dev, 0x44, 0x30 | ULI_8259_IRQ14); | ||
135 | pci_write_config_byte(dev, 0x75, ULI_8259_IRQ15); | ||
136 | } | ||
137 | |||
138 | static void __devinit quirk_final_uli1575(struct pci_dev *dev) | ||
139 | { | ||
140 | /* Set i8259 interrupt trigger | ||
141 | * IRQ 3: Level | ||
142 | * IRQ 4: Level | ||
143 | * IRQ 5: Level | ||
144 | * IRQ 6: Level | ||
145 | * IRQ 7: Level | ||
146 | * IRQ 9: Level | ||
147 | * IRQ 10: Level | ||
148 | * IRQ 11: Level | ||
149 | * IRQ 12: Level | ||
150 | * IRQ 14: Edge | ||
151 | * IRQ 15: Edge | ||
152 | */ | ||
153 | if (!uses_fsl_uli_m1575) | ||
154 | return; | ||
155 | |||
156 | outb(0xfa, 0x4d0); | ||
157 | outb(0x1e, 0x4d1); | ||
158 | |||
159 | /* setup RTC */ | ||
160 | CMOS_WRITE(RTC_SET, RTC_CONTROL); | ||
161 | CMOS_WRITE(RTC_24H, RTC_CONTROL); | ||
162 | |||
163 | /* ensure month, date, and week alarm fields are ignored */ | ||
164 | CMOS_WRITE(0, RTC_VALID); | ||
165 | |||
166 | outb_p(0x7c, 0x72); | ||
167 | outb_p(RTC_ALARM_DONT_CARE, 0x73); | ||
168 | |||
169 | outb_p(0x7d, 0x72); | ||
170 | outb_p(RTC_ALARM_DONT_CARE, 0x73); | ||
171 | } | ||
172 | |||
173 | /* SATA */ | ||
174 | static void __devinit quirk_uli5288(struct pci_dev *dev) | ||
175 | { | ||
176 | unsigned char c; | ||
177 | unsigned int d; | ||
178 | |||
179 | if (!uses_fsl_uli_m1575) | ||
180 | return; | ||
181 | |||
182 | /* read/write lock */ | ||
183 | pci_read_config_byte(dev, 0x83, &c); | ||
184 | pci_write_config_byte(dev, 0x83, c|0x80); | ||
185 | |||
186 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &d); | ||
187 | d = (d & 0xff) | (PCI_CLASS_STORAGE_SATA_AHCI << 8); | ||
188 | pci_write_config_dword(dev, PCI_CLASS_REVISION, d); | ||
189 | |||
190 | /* restore lock */ | ||
191 | pci_write_config_byte(dev, 0x83, c); | ||
192 | |||
193 | /* disable emulated PATA mode enabled */ | ||
194 | pci_read_config_byte(dev, 0x84, &c); | ||
195 | pci_write_config_byte(dev, 0x84, c & ~0x01); | ||
196 | } | ||
197 | |||
198 | /* PATA */ | ||
199 | static void __devinit quirk_uli5229(struct pci_dev *dev) | ||
200 | { | ||
201 | unsigned short temp; | ||
202 | |||
203 | if (!uses_fsl_uli_m1575) | ||
204 | return; | ||
205 | |||
206 | pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE | | ||
207 | PCI_COMMAND_MASTER | PCI_COMMAND_IO); | ||
208 | |||
209 | /* Enable Native IRQ 14/15 */ | ||
210 | pci_read_config_word(dev, 0x4a, &temp); | ||
211 | pci_write_config_word(dev, 0x4a, temp | 0x1000); | ||
212 | } | ||
213 | |||
214 | /* We have to do a dummy read on the P2P for the RTC to work, WTF */ | ||
215 | static void __devinit quirk_final_uli5249(struct pci_dev *dev) | ||
216 | { | ||
217 | int i; | ||
218 | u8 *dummy; | ||
219 | struct pci_bus *bus = dev->bus; | ||
220 | |||
221 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | ||
222 | if ((bus->resource[i]) && | ||
223 | (bus->resource[i]->flags & IORESOURCE_MEM)) { | ||
224 | dummy = ioremap(bus->resource[i]->start, 0x4); | ||
225 | if (dummy) { | ||
226 | in_8(dummy); | ||
227 | iounmap(dummy); | ||
228 | } | ||
229 | break; | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | |||
234 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
235 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); | ||
236 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
237 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
238 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x5249, quirk_final_uli5249); | ||
239 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x1575, quirk_final_uli1575); | ||
240 | |||
241 | int uli_exclude_device(struct pci_controller *hose, | ||
242 | u_char bus, u_char devfn) | ||
243 | { | ||
244 | if (bus == (hose->first_busno + 2)) { | ||
245 | /* exclude Modem controller */ | ||
246 | if ((PCI_SLOT(devfn) == 29) && (PCI_FUNC(devfn) == 1)) | ||
247 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
248 | |||
249 | /* exclude HD Audio controller */ | ||
250 | if ((PCI_SLOT(devfn) == 29) && (PCI_FUNC(devfn) == 2)) | ||
251 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
252 | } | ||
253 | |||
254 | return PCIBIOS_SUCCESSFUL; | ||
255 | } | ||