aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_sabre.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/pci_sabre.c')
-rw-r--r--arch/sparc64/kernel/pci_sabre.c288
1 files changed, 2 insertions, 286 deletions
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 4cefe6e83b24..e2377796de89 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -205,294 +205,9 @@
205#define SABRE_MEMSPACE 0x100000000UL 205#define SABRE_MEMSPACE 0x100000000UL
206#define SABRE_MEMSPACE_SIZE 0x07fffffffUL 206#define SABRE_MEMSPACE_SIZE 0x07fffffffUL
207 207
208/* UltraSparc-IIi Programmer's Manual, page 325, PCI
209 * configuration space address format:
210 *
211 * 32 24 23 16 15 11 10 8 7 2 1 0
212 * ---------------------------------------------------------
213 * |0 0 0 0 0 0 0 0 1| bus | device | function | reg | 0 0 |
214 * ---------------------------------------------------------
215 */
216#define SABRE_CONFIG_BASE(PBM) \
217 ((PBM)->config_space | (1UL << 24))
218#define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \
219 (((unsigned long)(BUS) << 16) | \
220 ((unsigned long)(DEVFN) << 8) | \
221 ((unsigned long)(REG)))
222
223static int hummingbird_p; 208static int hummingbird_p;
224static struct pci_bus *sabre_root_bus; 209static struct pci_bus *sabre_root_bus;
225 210
226static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,
227 unsigned char bus,
228 unsigned int devfn,
229 int where)
230{
231 if (!pbm)
232 return NULL;
233 return (void *)
234 (SABRE_CONFIG_BASE(pbm) |
235 SABRE_CONFIG_ENCODE(bus, devfn, where));
236}
237
238static int sabre_out_of_range(unsigned char devfn)
239{
240 if (hummingbird_p)
241 return 0;
242
243 return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) ||
244 ((PCI_SLOT(devfn) == 1) && (PCI_FUNC(devfn) > 1)) ||
245 (PCI_SLOT(devfn) > 1));
246}
247
248static int __sabre_out_of_range(struct pci_pbm_info *pbm,
249 unsigned char bus,
250 unsigned char devfn)
251{
252 if (hummingbird_p)
253 return 0;
254
255 return ((pbm->parent == 0) ||
256 ((pbm == &pbm->parent->pbm_A) &&
257 (bus == pbm->pci_first_busno) &&
258 PCI_SLOT(devfn) > 8));
259}
260
261static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
262 int where, int size, u32 *value)
263{
264 struct pci_pbm_info *pbm = bus_dev->sysdata;
265 unsigned char bus = bus_dev->number;
266 u32 *addr;
267 u16 tmp16;
268 u8 tmp8;
269
270 switch (size) {
271 case 1:
272 *value = 0xff;
273 break;
274 case 2:
275 *value = 0xffff;
276 break;
277 case 4:
278 *value = 0xffffffff;
279 break;
280 }
281
282 addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
283 if (!addr)
284 return PCIBIOS_SUCCESSFUL;
285
286 if (__sabre_out_of_range(pbm, bus, devfn))
287 return PCIBIOS_SUCCESSFUL;
288
289 switch (size) {
290 case 1:
291 pci_config_read8((u8 *) addr, &tmp8);
292 *value = tmp8;
293 break;
294
295 case 2:
296 if (where & 0x01) {
297 printk("pci_read_config_word: misaligned reg [%x]\n",
298 where);
299 return PCIBIOS_SUCCESSFUL;
300 }
301 pci_config_read16((u16 *) addr, &tmp16);
302 *value = tmp16;
303 break;
304
305 case 4:
306 if (where & 0x03) {
307 printk("pci_read_config_dword: misaligned reg [%x]\n",
308 where);
309 return PCIBIOS_SUCCESSFUL;
310 }
311 pci_config_read32(addr, value);
312 break;
313 }
314
315 return PCIBIOS_SUCCESSFUL;
316}
317
318static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn,
319 int where, int size, u32 *value)
320{
321 struct pci_pbm_info *pbm = bus->sysdata;
322
323 if (bus == pbm->pci_bus && devfn == 0x00)
324 return pci_host_bridge_read_pci_cfg(bus, devfn, where,
325 size, value);
326
327 if (!bus->number && sabre_out_of_range(devfn)) {
328 switch (size) {
329 case 1:
330 *value = 0xff;
331 break;
332 case 2:
333 *value = 0xffff;
334 break;
335 case 4:
336 *value = 0xffffffff;
337 break;
338 }
339 return PCIBIOS_SUCCESSFUL;
340 }
341
342 if (bus->number || PCI_SLOT(devfn))
343 return __sabre_read_pci_cfg(bus, devfn, where, size, value);
344
345 /* When accessing PCI config space of the PCI controller itself (bus
346 * 0, device slot 0, function 0) there are restrictions. Each
347 * register must be accessed as it's natural size. Thus, for example
348 * the Vendor ID must be accessed as a 16-bit quantity.
349 */
350
351 switch (size) {
352 case 1:
353 if (where < 8) {
354 u32 tmp32;
355 u16 tmp16;
356
357 __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
358 tmp16 = (u16) tmp32;
359 if (where & 1)
360 *value = tmp16 >> 8;
361 else
362 *value = tmp16 & 0xff;
363 } else
364 return __sabre_read_pci_cfg(bus, devfn, where, 1, value);
365 break;
366
367 case 2:
368 if (where < 8)
369 return __sabre_read_pci_cfg(bus, devfn, where, 2, value);
370 else {
371 u32 tmp32;
372 u8 tmp8;
373
374 __sabre_read_pci_cfg(bus, devfn, where, 1, &tmp32);
375 tmp8 = (u8) tmp32;
376 *value = tmp8;
377 __sabre_read_pci_cfg(bus, devfn, where + 1, 1, &tmp32);
378 tmp8 = (u8) tmp32;
379 *value |= tmp8 << 8;
380 }
381 break;
382
383 case 4: {
384 u32 tmp32;
385 u16 tmp16;
386
387 sabre_read_pci_cfg(bus, devfn, where, 2, &tmp32);
388 tmp16 = (u16) tmp32;
389 *value = tmp16;
390 sabre_read_pci_cfg(bus, devfn, where + 2, 2, &tmp32);
391 tmp16 = (u16) tmp32;
392 *value |= tmp16 << 16;
393 break;
394 }
395 }
396 return PCIBIOS_SUCCESSFUL;
397}
398
399static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
400 int where, int size, u32 value)
401{
402 struct pci_pbm_info *pbm = bus_dev->sysdata;
403 unsigned char bus = bus_dev->number;
404 u32 *addr;
405
406 addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
407 if (!addr)
408 return PCIBIOS_SUCCESSFUL;
409
410 if (__sabre_out_of_range(pbm, bus, devfn))
411 return PCIBIOS_SUCCESSFUL;
412
413 switch (size) {
414 case 1:
415 pci_config_write8((u8 *) addr, value);
416 break;
417
418 case 2:
419 if (where & 0x01) {
420 printk("pci_write_config_word: misaligned reg [%x]\n",
421 where);
422 return PCIBIOS_SUCCESSFUL;
423 }
424 pci_config_write16((u16 *) addr, value);
425 break;
426
427 case 4:
428 if (where & 0x03) {
429 printk("pci_write_config_dword: misaligned reg [%x]\n",
430 where);
431 return PCIBIOS_SUCCESSFUL;
432 }
433 pci_config_write32(addr, value);
434 break;
435 }
436
437 return PCIBIOS_SUCCESSFUL;
438}
439
440static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn,
441 int where, int size, u32 value)
442{
443 struct pci_pbm_info *pbm = bus->sysdata;
444
445 if (bus == pbm->pci_bus && devfn == 0x00)
446 return pci_host_bridge_write_pci_cfg(bus, devfn, where,
447 size, value);
448
449 if (bus->number)
450 return __sabre_write_pci_cfg(bus, devfn, where, size, value);
451
452 if (sabre_out_of_range(devfn))
453 return PCIBIOS_SUCCESSFUL;
454
455 switch (size) {
456 case 1:
457 if (where < 8) {
458 u32 tmp32;
459 u16 tmp16;
460
461 __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
462 tmp16 = (u16) tmp32;
463 if (where & 1) {
464 value &= 0x00ff;
465 value |= tmp16 << 8;
466 } else {
467 value &= 0xff00;
468 value |= tmp16;
469 }
470 tmp32 = (u32) tmp16;
471 return __sabre_write_pci_cfg(bus, devfn, where & ~1, 2, tmp32);
472 } else
473 return __sabre_write_pci_cfg(bus, devfn, where, 1, value);
474 break;
475 case 2:
476 if (where < 8)
477 return __sabre_write_pci_cfg(bus, devfn, where, 2, value);
478 else {
479 __sabre_write_pci_cfg(bus, devfn, where, 1, value & 0xff);
480 __sabre_write_pci_cfg(bus, devfn, where + 1, 1, value >> 8);
481 }
482 break;
483 case 4:
484 sabre_write_pci_cfg(bus, devfn, where, 2, value & 0xffff);
485 sabre_write_pci_cfg(bus, devfn, where + 2, 2, value >> 16);
486 break;
487 }
488 return PCIBIOS_SUCCESSFUL;
489}
490
491static struct pci_ops sabre_ops = {
492 .read = sabre_read_pci_cfg,
493 .write = sabre_write_pci_cfg,
494};
495
496/* SABRE error handling support. */ 211/* SABRE error handling support. */
497static void sabre_check_iommu_error(struct pci_pbm_info *pbm, 212static void sabre_check_iommu_error(struct pci_pbm_info *pbm,
498 unsigned long afsr, 213 unsigned long afsr,
@@ -1010,7 +725,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *p
1010 printk("%s: SABRE PCI Bus Module\n", pbm->name); 725 printk("%s: SABRE PCI Bus Module\n", pbm->name);
1011 726
1012 pbm->scan_bus = sabre_scan_bus; 727 pbm->scan_bus = sabre_scan_bus;
1013 pbm->pci_ops = &sabre_ops; 728 pbm->pci_ops = &sun4u_pci_ops;
729 pbm->config_space_reg_bits = 8;
1014 730
1015 pbm->index = pci_num_pbms++; 731 pbm->index = pci_num_pbms++;
1016 732