Commit f8aac81f authored by David S. Miller's avatar David S. Miller Committed by David S. Miller

[SPARC64]: Tomatillo PCI controller bug fixes.

- Error handlers were mis-calculating ICLR register to
  ACK on Tomatillo.
- PCI error handlers should not ACK other IRQ.
- Fix Tomatillo version comparison for PCI Timeout
  Interval setting
- Tomatillo PCI control register prefetch enable bits
  were off.
- Tomatillo revs <= 1 need bit 61 set, all others should
  have it clear.  This is in the PCI control register.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent edc1ca20
......@@ -326,7 +326,7 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
return ret;
}
static unsigned int __init schizo_irq_build(struct pci_pbm_info *pbm,
static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
struct pci_dev *pdev,
unsigned int ino)
{
......@@ -382,19 +382,57 @@ static unsigned long stc_error_buf[128];
static unsigned long stc_tag_buf[16];
static unsigned long stc_line_buf[16];
/* These offsets look weird because I keep in pbm->controller_regs
* the second PROM register property minus 0x10000 which is the
* base of the Safari and UPA64S registers of SCHIZO.
*/
#define SCHIZO_PBM_A_REGS_OFF (0x600000UL - 0x400000UL)
#define SCHIZO_PBM_B_REGS_OFF (0x700000UL - 0x400000UL)
#define SCHIZO_UE_INO 0x30 /* Uncorrectable ECC error */
#define SCHIZO_CE_INO 0x31 /* Correctable ECC error */
#define SCHIZO_PCIERR_A_INO 0x32 /* PBM A PCI bus error */
#define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */
#define SCHIZO_SERR_INO 0x34 /* Safari interface error */
struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
{
ino &= IMAP_INO;
if (p->pbm_A.ino_bitmap & (1UL << ino))
return &p->pbm_A;
if (p->pbm_B.ino_bitmap & (1UL << ino))
return &p->pbm_B;
printk("PCI%d: No ino_bitmap entry for ino[%x], bitmaps "
"PBM_A[%016lx] PBM_B[%016lx]",
p->index, ino,
p->pbm_A.ino_bitmap,
p->pbm_B.ino_bitmap);
printk("PCI%d: Using PBM_A, report this problem immediately.\n",
p->index);
static void schizo_clear_other_err_intr(int irq)
return &p->pbm_A;
}
static void schizo_clear_other_err_intr(struct pci_controller_info *p, int irq)
{
struct ino_bucket *bucket = __bucket(irq);
unsigned long iclr = bucket->iclr;
struct pci_pbm_info *pbm;
struct ino_bucket *bucket;
unsigned long iclr;
/* Do not clear the interrupt for the other PCI bus.
*
* This "ACK both PBM IRQs" only needs to be performed
* for chip-wide error interrupts.
*/
if ((irq & IMAP_INO) == SCHIZO_PCIERR_A_INO ||
(irq & IMAP_INO) == SCHIZO_PCIERR_B_INO)
return;
pbm = pbm_for_ino(p, irq);
if (pbm == &p->pbm_A)
pbm = &p->pbm_B;
else
pbm = &p->pbm_A;
irq = schizo_irq_build(pbm, NULL,
(pbm->portid << 6) | (irq & IMAP_INO));
bucket = __bucket(irq);
iclr = bucket->iclr;
iclr += (SCHIZO_PBM_B_REGS_OFF - SCHIZO_PBM_A_REGS_OFF);
upa_writel(ICLR_IDLE, iclr);
}
......@@ -728,7 +766,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
/* Interrogate IOMMU for error status. */
schizo_check_iommu_error(p, UE_ERR);
schizo_clear_other_err_intr(irq);
schizo_clear_other_err_intr(p, irq);
return IRQ_HANDLED;
}
......@@ -819,7 +857,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
printk("(none)");
printk("]\n");
schizo_clear_other_err_intr(irq);
schizo_clear_other_err_intr(p, irq);
return IRQ_HANDLED;
}
......@@ -856,9 +894,9 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */
#define SCHIZO_PCICTRL_SERR (1UL << 34UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) /* Safari */
#define SCHIZO_PCICTRL_MRM_PREF (1UL << 28UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDO_PREF (1UL << 27UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDL_PREF (1UL << 26UL) /* Tomatillo */
#define SCHIZO_PCICTRL_MRM_PREF (1UL << 30UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDO_PREF (1UL << 29UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDL_PREF (1UL << 28UL) /* Tomatillo */
#define SCHIZO_PCICTRL_PTO (3UL << 24UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PTO_SHIFT 24UL
#define SCHIZO_PCICTRL_TRWSW (7UL << 21UL) /* Tomatillo */
......@@ -1040,7 +1078,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR))
pci_scan_for_parity_error(p, pbm, pbm->pci_bus);
schizo_clear_other_err_intr(irq);
schizo_clear_other_err_intr(p, irq);
return IRQ_HANDLED;
}
......@@ -1097,7 +1135,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n",
p->index, errlog);
schizo_clear_other_err_intr(irq);
schizo_clear_other_err_intr(p, irq);
return IRQ_HANDLED;
}
......@@ -1105,7 +1143,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
p->index);
schizo_check_iommu_error(p, SAFARI_ERR);
schizo_clear_other_err_intr(irq);
schizo_clear_other_err_intr(p, irq);
return IRQ_HANDLED;
}
......@@ -1120,26 +1158,6 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
#define SCHIZO_SAFARI_IRQCTRL 0x10010UL
#define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL
#define SCHIZO_UE_INO 0x30 /* Uncorrectable ECC error */
#define SCHIZO_CE_INO 0x31 /* Correctable ECC error */
#define SCHIZO_PCIERR_A_INO 0x32 /* PBM A PCI bus error */
#define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */
#define SCHIZO_SERR_INO 0x34 /* Safari interface error */
struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
{
ino &= IMAP_INO;
if (p->pbm_A.ino_bitmap & (1UL << ino))
return &p->pbm_A;
if (p->pbm_B.ino_bitmap & (1UL << ino))
return &p->pbm_B;
prom_printf("TOMATILLO%d: No entry in ino bitmap for %d\n",
p->index, ino);
prom_halt();
/* NOTREACHED */
return NULL;
}
/* How the Tomatillo IRQs are routed around is pure guesswork here.
*
* All the Tomatillo devices I see in prtconf dumps seem to have only
......@@ -1887,7 +1905,7 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
tmp &= ~SCHIZO_PCICTRL_PTO;
if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
pbm->chip_version == 0x2)
pbm->chip_version >= 0x2)
tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;
else
tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT;
......@@ -1895,8 +1913,16 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
if (!prom_getbool(pbm->prom_node, "no-bus-parking"))
tmp |= SCHIZO_PCICTRL_PARK;
if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
pbm->chip_version <= 0x1)
tmp |= (1UL << 61);
else
tmp &= ~(1UL << 61);
if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO)
tmp |= SCHIZO_PCICTRL_MRM_PREF;
tmp |= (SCHIZO_PCICTRL_MRM_PREF |
SCHIZO_PCICTRL_RDO_PREF |
SCHIZO_PCICTRL_RDL_PREF);
schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp);
......
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