diff options
| author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-07-23 11:25:13 -0400 |
|---|---|---|
| committer | Ralf Baechle <ralf@linux-mips.org> | 2008-07-30 16:54:35 -0400 |
| commit | 32d00d0f933ea5d21c3cd0809461ebbf7ab89cef (patch) | |
| tree | 485581a75b87eaee5cb10184985f6293285cc8c5 | |
| parent | a0e31fb09056224c5d6fef09d25cb96b6149aa7c (diff) | |
[MIPS] TXx9: PCI fixes for tx3927/tx4927
* Fix tx3927 pci ops for Type-1 configuration
* Fix abort checking of tx3927 pci ops
* Flush write buffer to avoid spurious PCI error interrupt
* Add a quirk for FPCIB backplane
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
| -rw-r--r-- | arch/mips/pci/ops-tx3927.c | 46 | ||||
| -rw-r--r-- | arch/mips/pci/ops-tx4927.c | 34 |
2 files changed, 53 insertions, 27 deletions
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c index 8a17a39e5bf2..c6bd79e71e26 100644 --- a/arch/mips/pci/ops-tx3927.c +++ b/arch/mips/pci/ops-tx3927.c | |||
| @@ -41,41 +41,41 @@ | |||
| 41 | #include <asm/addrspace.h> | 41 | #include <asm/addrspace.h> |
| 42 | #include <asm/txx9/tx3927.h> | 42 | #include <asm/txx9/tx3927.h> |
| 43 | 43 | ||
| 44 | static inline int mkaddr(unsigned char bus, unsigned char dev_fn, | 44 | static int mkaddr(struct pci_bus *bus, unsigned char devfn, unsigned char where) |
| 45 | unsigned char where) | ||
| 46 | { | 45 | { |
| 47 | if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0)) | 46 | if (bus->parent == NULL && |
| 48 | return PCIBIOS_DEVICE_NOT_FOUND; | 47 | devfn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0)) |
| 49 | 48 | return -1; | |
| 50 | tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) | | 49 | tx3927_pcicptr->ica = |
| 51 | ((dev_fn & 0xff) << 0x08) | | 50 | ((bus->number & 0xff) << 0x10) | |
| 52 | (where & 0xfc); | 51 | ((devfn & 0xff) << 0x08) | |
| 52 | (where & 0xfc) | (bus->parent ? 1 : 0); | ||
| 53 | 53 | ||
| 54 | /* clear M_ABORT and Disable M_ABORT Int. */ | 54 | /* clear M_ABORT and Disable M_ABORT Int. */ |
| 55 | tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; | 55 | tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; |
| 56 | tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT; | 56 | tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT; |
| 57 | 57 | return 0; | |
| 58 | return PCIBIOS_SUCCESSFUL; | ||
| 59 | } | 58 | } |
| 60 | 59 | ||
| 61 | static inline int check_abort(void) | 60 | static inline int check_abort(void) |
| 62 | { | 61 | { |
| 63 | if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) | 62 | if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) { |
| 64 | tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; | 63 | tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; |
| 65 | tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; | 64 | tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; |
| 65 | /* flush write buffer */ | ||
| 66 | iob(); | ||
| 66 | return PCIBIOS_DEVICE_NOT_FOUND; | 67 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 67 | 68 | } | |
| 68 | return PCIBIOS_SUCCESSFUL; | 69 | return PCIBIOS_SUCCESSFUL; |
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, | 72 | static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, |
| 72 | int where, int size, u32 * val) | 73 | int where, int size, u32 * val) |
| 73 | { | 74 | { |
| 74 | int ret; | 75 | if (mkaddr(bus, devfn, where)) { |
| 75 | 76 | *val = 0xffffffff; | |
| 76 | ret = mkaddr(bus->number, devfn, where); | 77 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 77 | if (ret) | 78 | } |
| 78 | return ret; | ||
| 79 | 79 | ||
| 80 | switch (size) { | 80 | switch (size) { |
| 81 | case 1: | 81 | case 1: |
| @@ -97,11 +97,8 @@ static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 97 | static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, | 97 | static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, |
| 98 | int where, int size, u32 val) | 98 | int where, int size, u32 val) |
| 99 | { | 99 | { |
| 100 | int ret; | 100 | if (mkaddr(bus, devfn, where)) |
| 101 | 101 | return PCIBIOS_DEVICE_NOT_FOUND; | |
| 102 | ret = mkaddr(bus->number, devfn, where); | ||
| 103 | if (ret) | ||
| 104 | return ret; | ||
| 105 | 102 | ||
| 106 | switch (size) { | 103 | switch (size) { |
| 107 | case 1: | 104 | case 1: |
| @@ -117,11 +114,6 @@ static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 117 | tx3927_pcicptr->icd = cpu_to_le32(val); | 114 | tx3927_pcicptr->icd = cpu_to_le32(val); |
| 118 | } | 115 | } |
| 119 | 116 | ||
| 120 | if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) | ||
| 121 | tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; | ||
| 122 | tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; | ||
| 123 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 124 | |||
| 125 | return check_abort(); | 117 | return check_abort(); |
| 126 | } | 118 | } |
| 127 | 119 | ||
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index c6b49bccd274..6d844094ef5d 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c | |||
| @@ -85,6 +85,8 @@ static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr) | |||
| 85 | __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) | 85 | __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) |
| 86 | | (PCI_STATUS_REC_MASTER_ABORT << 16), | 86 | | (PCI_STATUS_REC_MASTER_ABORT << 16), |
| 87 | &pcicptr->pcistatus); | 87 | &pcicptr->pcistatus); |
| 88 | /* flush write buffer */ | ||
| 89 | iob(); | ||
| 88 | code = PCIBIOS_DEVICE_NOT_FOUND; | 90 | code = PCIBIOS_DEVICE_NOT_FOUND; |
| 89 | } | 91 | } |
| 90 | return code; | 92 | return code; |
| @@ -406,3 +408,35 @@ void tx4927_report_pcic_status(void) | |||
| 406 | tx4927_report_pcic_status1(pcicptrs[i].pcicptr); | 408 | tx4927_report_pcic_status1(pcicptrs[i].pcicptr); |
| 407 | } | 409 | } |
| 408 | } | 410 | } |
| 411 | |||
| 412 | #ifdef CONFIG_TOSHIBA_FPCIB0 | ||
| 413 | static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) | ||
| 414 | { | ||
| 415 | struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus); | ||
| 416 | |||
| 417 | if (!pcicptr) | ||
| 418 | return; | ||
| 419 | if (__raw_readl(&pcicptr->pbacfg) & TX4927_PCIC_PBACFG_PBAEN) { | ||
| 420 | /* Reset Bus Arbiter */ | ||
| 421 | __raw_writel(TX4927_PCIC_PBACFG_RPBA, &pcicptr->pbacfg); | ||
| 422 | /* | ||
| 423 | * swap reqBP and reqXP (raise priority of SLC90E66). | ||
| 424 | * SLC90E66(PCI-ISA bridge) is connected to REQ2 on | ||
| 425 | * PCI Backplane board. | ||
| 426 | */ | ||
| 427 | __raw_writel(0x72543610, &pcicptr->pbareqport); | ||
| 428 | __raw_writel(0, &pcicptr->pbabm); | ||
| 429 | /* Use Fixed ParkMaster (required by SLC90E66) */ | ||
| 430 | __raw_writel(TX4927_PCIC_PBACFG_FIXPA, &pcicptr->pbacfg); | ||
| 431 | /* Enable Bus Arbiter */ | ||
| 432 | __raw_writel(TX4927_PCIC_PBACFG_FIXPA | | ||
| 433 | TX4927_PCIC_PBACFG_PBAEN, | ||
| 434 | &pcicptr->pbacfg); | ||
| 435 | printk(KERN_INFO "PCI: Use Fixed Park Master (REQPORT %08x)\n", | ||
| 436 | __raw_readl(&pcicptr->pbareqport)); | ||
| 437 | } | ||
| 438 | } | ||
| 439 | #define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 | ||
| 440 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0, | ||
| 441 | tx4927_quirk_slc90e66_bridge); | ||
| 442 | #endif | ||
