Commit 32d00d0f authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by Ralf Baechle

[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: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent a0e31fb0
...@@ -41,41 +41,41 @@ ...@@ -41,41 +41,41 @@
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/txx9/tx3927.h> #include <asm/txx9/tx3927.h>
static inline int mkaddr(unsigned char bus, unsigned char dev_fn, static int mkaddr(struct pci_bus *bus, unsigned char devfn, unsigned char where)
unsigned char where)
{ {
if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0)) if (bus->parent == NULL &&
return PCIBIOS_DEVICE_NOT_FOUND; devfn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
return -1;
tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) | tx3927_pcicptr->ica =
((dev_fn & 0xff) << 0x08) | ((bus->number & 0xff) << 0x10) |
(where & 0xfc); ((devfn & 0xff) << 0x08) |
(where & 0xfc) | (bus->parent ? 1 : 0);
/* clear M_ABORT and Disable M_ABORT Int. */ /* clear M_ABORT and Disable M_ABORT Int. */
tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT; tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
return 0;
return PCIBIOS_SUCCESSFUL;
} }
static inline int check_abort(void) static inline int check_abort(void)
{ {
if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) {
tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
/* flush write buffer */
iob();
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 * val) int where, int size, u32 * val)
{ {
int ret; if (mkaddr(bus, devfn, where)) {
*val = 0xffffffff;
ret = mkaddr(bus->number, devfn, where); return PCIBIOS_DEVICE_NOT_FOUND;
if (ret) }
return ret;
switch (size) { switch (size) {
case 1: case 1:
...@@ -97,11 +97,8 @@ static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, ...@@ -97,11 +97,8 @@ static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val) int where, int size, u32 val)
{ {
int ret; if (mkaddr(bus, devfn, where))
return PCIBIOS_DEVICE_NOT_FOUND;
ret = mkaddr(bus->number, devfn, where);
if (ret)
return ret;
switch (size) { switch (size) {
case 1: case 1:
...@@ -117,11 +114,6 @@ static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, ...@@ -117,11 +114,6 @@ static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
tx3927_pcicptr->icd = cpu_to_le32(val); tx3927_pcicptr->icd = cpu_to_le32(val);
} }
if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
return PCIBIOS_DEVICE_NOT_FOUND;
return check_abort(); return check_abort();
} }
......
...@@ -85,6 +85,8 @@ static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr) ...@@ -85,6 +85,8 @@ static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr)
__raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff)
| (PCI_STATUS_REC_MASTER_ABORT << 16), | (PCI_STATUS_REC_MASTER_ABORT << 16),
&pcicptr->pcistatus); &pcicptr->pcistatus);
/* flush write buffer */
iob();
code = PCIBIOS_DEVICE_NOT_FOUND; code = PCIBIOS_DEVICE_NOT_FOUND;
} }
return code; return code;
...@@ -406,3 +408,35 @@ void tx4927_report_pcic_status(void) ...@@ -406,3 +408,35 @@ void tx4927_report_pcic_status(void)
tx4927_report_pcic_status1(pcicptrs[i].pcicptr); tx4927_report_pcic_status1(pcicptrs[i].pcicptr);
} }
} }
#ifdef CONFIG_TOSHIBA_FPCIB0
static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev)
{
struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus);
if (!pcicptr)
return;
if (__raw_readl(&pcicptr->pbacfg) & TX4927_PCIC_PBACFG_PBAEN) {
/* Reset Bus Arbiter */
__raw_writel(TX4927_PCIC_PBACFG_RPBA, &pcicptr->pbacfg);
/*
* swap reqBP and reqXP (raise priority of SLC90E66).
* SLC90E66(PCI-ISA bridge) is connected to REQ2 on
* PCI Backplane board.
*/
__raw_writel(0x72543610, &pcicptr->pbareqport);
__raw_writel(0, &pcicptr->pbabm);
/* Use Fixed ParkMaster (required by SLC90E66) */
__raw_writel(TX4927_PCIC_PBACFG_FIXPA, &pcicptr->pbacfg);
/* Enable Bus Arbiter */
__raw_writel(TX4927_PCIC_PBACFG_FIXPA |
TX4927_PCIC_PBACFG_PBAEN,
&pcicptr->pbacfg);
printk(KERN_INFO "PCI: Use Fixed Park Master (REQPORT %08x)\n",
__raw_readl(&pcicptr->pbareqport));
}
}
#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0,
tx4927_quirk_slc90e66_bridge);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment