patch-2.4.19 linux-2.4.19/arch/sparc64/kernel/pci_schizo.c
Next file: linux-2.4.19/arch/sparc64/kernel/power.c
Previous file: linux-2.4.19/arch/sparc64/kernel/pci_sabre.c
Back to the patch index
Back to the overall index
- Lines: 264
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/sparc64/kernel/pci_schizo.c
- Orig date:
Fri Dec 21 09:41:53 2001
diff -urN linux-2.4.18/arch/sparc64/kernel/pci_schizo.c linux-2.4.19/arch/sparc64/kernel/pci_schizo.c
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.23 2001/11/14 13:17:56 davem Exp $
+/* $Id: pci_schizo.c,v 1.23.2.2 2002/03/11 07:55:24 davem Exp $
* pci_schizo.c: SCHIZO specific PCI controller support.
*
* Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -291,8 +291,8 @@
/*0x0c*/0, 0, 0, 0, /* PCI slot 3 Int A, B, C, D */
/*0x10*/0, 0, 0, 0, /* PCI slot 4 Int A, B, C, D */
/*0x14*/0, 0, 0, 0, /* PCI slot 5 Int A, B, C, D */
-/*0x18*/3, /* SCSI */
-/*0x19*/3, /* second SCSI */
+/*0x18*/4, /* SCSI */
+/*0x19*/4, /* second SCSI */
/*0x1a*/0, /* UNKNOWN */
/*0x1b*/0, /* UNKNOWN */
/*0x1c*/8, /* Parallel */
@@ -302,7 +302,7 @@
/*0x20*/13, /* Audio Record */
/*0x21*/14, /* Audio Playback */
/*0x22*/12, /* Serial */
-/*0x23*/2, /* EBUS I2C */
+/*0x23*/4, /* EBUS I2C */
/*0x24*/10, /* RTC Clock */
/*0x25*/11, /* Floppy */
/*0x26*/0, /* UNKNOWN */
@@ -344,7 +344,7 @@
ret = schizo_pil_table[ino];
if (ret == 0 && pdev == NULL) {
- ret = 1;
+ ret = 4;
} else if (ret == 0) {
switch ((pdev->class >> 16) & 0xff) {
case PCI_BASE_CLASS_STORAGE:
@@ -367,7 +367,7 @@
break;
default:
- ret = 1;
+ ret = 4;
break;
};
}
@@ -383,7 +383,7 @@
struct ino_bucket *bucket;
unsigned long imap, iclr, pbm_off;
unsigned long imap_off, iclr_off;
- int pil, inofixup = 0;
+ int pil;
if (pbm == &p->pbm_A)
pbm_off = SCHIZO_PBM_A_REGS_OFF;
@@ -395,6 +395,10 @@
/* Now build the IRQ bucket. */
pil = schizo_ino_to_pil(pdev, ino);
+
+ if (PIL_RESERVED(pil))
+ BUG();
+
imap = p->controller_regs + pbm_off + imap_off;
imap += 4;
@@ -402,10 +406,13 @@
iclr = p->controller_regs + pbm_off + iclr_off;
iclr += 4;
- if (ino < 0x18)
- inofixup = ino & 0x03;
-
- bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
+ /* On Schizo, no inofixup occurs. This is because each
+ * INO has it's own IMAP register. On Psycho and Sabre
+ * there is only one IMAP register for each PCI slot even
+ * though four different INOs can be generated by each
+ * PCI slot.
+ */
+ bucket = __bucket(build_irq(pil, 0, iclr, imap));
bucket->flags |= IBF_PCI;
return __irq(bucket);
@@ -1078,15 +1085,22 @@
#define SCHIZO_PCIA_CTRL (SCHIZO_PBM_A_REGS_OFF + 0x2000UL)
#define SCHIZO_PCIB_CTRL (SCHIZO_PBM_B_REGS_OFF + 0x2000UL)
-#define SCHIZO_PCICTRL_BUNUS (1UL << 63UL)
+#define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL)
#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL)
+#define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL)
#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL)
#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL)
#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL)
#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL)
#define SCHIZO_PCICTRL_SERR (1UL << 34UL)
+#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL)
+#define SCHIZO_PCICTRL_PTO (3UL << 24UL)
+#define SCHIZO_PCICTRL_DTO_INT (1UL << 19UL)
#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL)
#define SCHIZO_PCICTRL_EEN (1UL << 17UL)
+#define SCHIZO_PCICTRL_PARK (1UL << 16UL)
+#define SCHIZO_PCICTRL_PCIRST (1UL << 8UL)
+#define SCHIZO_PCICTRL_ARB (0x3fUL << 0UL)
static void __init schizo_register_error_handlers(struct pci_controller_info *p)
{
@@ -1163,7 +1177,7 @@
* bits for each PBM.
*/
tmp = schizo_read(base + SCHIZO_PCIA_CTRL);
- tmp |= (SCHIZO_PCICTRL_BUNUS |
+ tmp |= (SCHIZO_PCICTRL_BUS_UNUS |
SCHIZO_PCICTRL_ESLCK |
SCHIZO_PCICTRL_TTO_ERR |
SCHIZO_PCICTRL_RTRY_ERR |
@@ -1175,7 +1189,7 @@
schizo_write(base + SCHIZO_PCIA_CTRL, tmp);
tmp = schizo_read(base + SCHIZO_PCIB_CTRL);
- tmp |= (SCHIZO_PCICTRL_BUNUS |
+ tmp |= (SCHIZO_PCICTRL_BUS_UNUS |
SCHIZO_PCICTRL_ESLCK |
SCHIZO_PCICTRL_TTO_ERR |
SCHIZO_PCICTRL_RTRY_ERR |
@@ -1412,7 +1426,14 @@
int where, size, is_64bit;
res = &pdev->resource[resource];
- where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ if (resource < 6) {
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ } else if (resource == PCI_ROM_RESOURCE) {
+ where = pdev->rom_base_reg;
+ } else {
+ /* Somebody might have asked allocation of a non-standard resource */
+ return;
+ }
is_64bit = 0;
if (res->flags & IORESOURCE_IO)
@@ -1428,6 +1449,10 @@
pci_read_config_dword(pdev, where, ®);
reg = ((reg & size) |
(((u32)(res->start - root->start)) & ~size));
+ if (resource == PCI_ROM_RESOURCE) {
+ reg |= PCI_ROM_ADDRESS_ENABLE;
+ res->flags |= PCI_ROM_ADDRESS_ENABLE;
+ }
pci_write_config_dword(pdev, where, reg);
/* This knows that the upper 32-bits of the address
@@ -1458,24 +1483,12 @@
#define SCHIZO_PCI_B_IO_MATCH 0x00070UL
#define SCHIZO_PCI_B_IO_MASK 0x00078UL
-/* VAL must be non-zero. */
-static unsigned long strip_to_lowest_bit_set(unsigned long val)
-{
- unsigned long tmp;
-
- tmp = 1UL;
- while (!(tmp & val))
- tmp <<= 1UL;
-
- return tmp;
-}
-
static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm,
int is_pbm_a, unsigned long reg_base)
{
u64 mem_match, mem_mask;
u64 io_match;
- u64 long a, b;
+ u64 a;
if (is_pbm_a) {
mem_match = reg_base + SCHIZO_PCI_A_MEM_MATCH;
@@ -1487,11 +1500,12 @@
mem_mask = mem_match + 0x8UL;
a = schizo_read(mem_match) & ~0x8000000000000000UL;
- b = strip_to_lowest_bit_set(schizo_read(mem_mask));
- /* It should be 2GB in size. */
+ /* It should be 2GB in size but the decode is set for the full
+ * 4GB so we have to add the 2G by hand.
+ */
pbm->mem_space.start = a;
- pbm->mem_space.end = a + (b - 1UL);
+ pbm->mem_space.end = a + 0x80000000;
pbm->mem_space.flags = IORESOURCE_MEM;
/* This 32MB area is divided into two pieces. The first
@@ -1738,6 +1752,22 @@
schizo_pbm_strbuf_init(p, pbm, is_pbm_a);
}
+#define SCHIZO_PCIA_IRQ_RETRY (SCHIZO_PBM_A_REGS_OFF + 0x1a00UL)
+#define SCHIZO_PCIB_IRQ_RETRY (SCHIZO_PBM_B_REGS_OFF + 0x1a00UL)
+#define SCHIZO_IRQ_RETRY_INF 0xffUL
+
+#define SCHIZO_PCIA_DIAG (SCHIZO_PBM_A_REGS_OFF + 0x2020UL)
+#define SCHIZO_PCIB_DIAG (SCHIZO_PBM_B_REGS_OFF + 0x2020UL)
+#define SCHIZO_PCIDIAG_D_BADECC (1UL << 10UL) /* Disable BAD ECC errors */
+#define SCHIZO_PCIDIAG_D_BYPASS (1UL << 9UL) /* Disable MMU bypass mode */
+#define SCHIZO_PCIDIAG_D_TTO (1UL << 8UL) /* Disable TTO errors */
+#define SCHIZO_PCIDIAG_D_RTRYARB (1UL << 7UL) /* Disable retry arbitration */
+#define SCHIZO_PCIDIAG_D_RETRY (1UL << 6UL) /* Disable retry limit */
+#define SCHIZO_PCIDIAG_D_INTSYNC (1UL << 5UL) /* Disable interrupt/DMA synch */
+#define SCHIZO_PCIDIAG_I_DMA_PARITY (1UL << 3UL) /* Invert DMA parity */
+#define SCHIZO_PCIDIAG_I_PIOD_PARITY (1UL << 2UL) /* Invert PIO data parity */
+#define SCHIZO_PCIDIAG_I_PIOA_PARITY (1UL << 1U)L /* Invert PIO address parity */
+
static void schizo_controller_hwinit(struct pci_controller_info *p)
{
unsigned long pbm_a_base, pbm_b_base;
@@ -1747,17 +1777,37 @@
pbm_b_base = p->controller_regs + SCHIZO_PBM_B_REGS_OFF;
/* Set IRQ retry to infinity. */
- schizo_write(pbm_a_base + 0x1a00UL, 0xff);
- schizo_write(pbm_b_base + 0x1a00UL, 0xff);
+ schizo_write(p->controller_regs + SCHIZO_PCIA_IRQ_RETRY,
+ SCHIZO_IRQ_RETRY_INF);
+ schizo_write(p->controller_regs + SCHIZO_PCIB_IRQ_RETRY,
+ SCHIZO_IRQ_RETRY_INF);
+
+ /* Enable arbiter for all PCI slots. Also, disable PCI interval
+ * timer so that DTO (Discard TimeOuts) are not reported because
+ * some Schizo revisions report them erroneously.
+ */
- /* Enable arbiter for all PCI slots. */
- tmp = schizo_read(pbm_a_base + 0x2000UL);
- tmp |= 0x3fUL;
- schizo_write(pbm_a_base + 0x2000UL, tmp);
-
- tmp = schizo_read(pbm_b_base + 0x2000UL);
- tmp |= 0x3fUL;
- schizo_write(pbm_b_base + 0x2000UL, tmp);
+ tmp = schizo_read(p->controller_regs + SCHIZO_PCIA_CTRL);
+ tmp |= SCHIZO_PCICTRL_ARB;
+ tmp &= ~SCHIZO_PCICTRL_PTO;
+ schizo_write(p->controller_regs + SCHIZO_PCIA_CTRL, tmp);
+
+ tmp = schizo_read(p->controller_regs + SCHIZO_PCIB_CTRL);
+ tmp |= SCHIZO_PCICTRL_ARB;
+ tmp &= ~SCHIZO_PCICTRL_PTO;
+ schizo_write(p->controller_regs + SCHIZO_PCIB_CTRL, tmp);
+
+ /* Disable TTO error reporting (won't happen anyway since we
+ * disabled the PCI interval timer above) and retry arbitration
+ * (can cause hangs in some Schizo revisions).
+ */
+ tmp = schizo_read(p->controller_regs + SCHIZO_PCIA_DIAG);
+ tmp |= (SCHIZO_PCIDIAG_D_TTO | SCHIZO_PCIDIAG_D_RTRYARB);
+ schizo_write(p->controller_regs + SCHIZO_PCIA_DIAG, tmp);
+
+ tmp = schizo_read(p->controller_regs + SCHIZO_PCIB_DIAG);
+ tmp |= (SCHIZO_PCIDIAG_D_TTO | SCHIZO_PCIDIAG_D_RTRYARB);
+ schizo_write(p->controller_regs + SCHIZO_PCIB_DIAG, tmp);
}
void __init schizo_init(int node, char *model_name)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)