summaryrefslogtreecommitdiff
path: root/sys/arch/loongson
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-01-31 19:12:13 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-01-31 19:12:13 +0000
commit49c6d38e4130acfdfdb7f256c2cc0f54546c06a2 (patch)
treeab9bbbf0d99c5c2081b5adf84f644caf2df856dd /sys/arch/loongson
parentf62f1306d674696bbc6d475fc53dd4a1b9d8f7bb (diff)
According to Linux, some magic programming is necessary to prevent deadlocks,
so do the same magic ourselves too.
Diffstat (limited to 'sys/arch/loongson')
-rw-r--r--sys/arch/loongson/dev/bonito.c85
-rw-r--r--sys/arch/loongson/dev/bonitoreg.h113
2 files changed, 105 insertions, 93 deletions
diff --git a/sys/arch/loongson/dev/bonito.c b/sys/arch/loongson/dev/bonito.c
index 78d0702ec03..b9cfbec1095 100644
--- a/sys/arch/loongson/dev/bonito.c
+++ b/sys/arch/loongson/dev/bonito.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bonito.c,v 1.3 2010/01/26 05:35:55 miod Exp $ */
+/* $OpenBSD: bonito.c,v 1.4 2010/01/31 19:12:12 miod Exp $ */
/* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */
/* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */
@@ -236,13 +236,10 @@ bonito_attach(struct device *parent, struct device *self, void *aux)
struct pcibus_attach_args pba;
pci_chipset_tag_t pc = &sc->sc_pc;
const struct bonito_config *bc;
- pcireg_t rev;
+ uint32_t reg;
- rev = PCI_REVISION(REGVAL(BONITO_PCICLASS));
-
- printf(": memory and PCI controller, %s rev. %d.%d\n",
- BONITO_REV_FPGA(rev) ? "FPGA" : "ASIC",
- BONITO_REV_MAJOR(rev), BONITO_REV_MINOR(rev));
+ printf(": memory and PCI-X controller, rev. %d\n",
+ PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG))));
bc = &yeelong_bonito;
@@ -250,16 +247,31 @@ bonito_attach(struct device *parent, struct device *self, void *aux)
SLIST_INIT(&sc->sc_hook);
/*
+ * Setup proper abitration.
+ */
+
+ /*
+ * according to linux, changing the value of this undocumented
+ * register ``avoids deadlock of PCI reading/writing lock operation''.
+ */
+ REGVAL(BONITO_PCI_REG(0x4c)) = 0xd2000001; /* instead of c2000001 */
+
+ /* all pci devices may need to hold the bus */
+ reg = REGVAL(LOONGSON_PXARB_CFG);
+ reg &= ~LOONGSON_PXARB_RUDE_DEV_MSK;
+ reg |= 0xfe << LOONGSON_PXARB_RUDE_DEV_SHFT;
+ REGVAL(LOONGSON_PXARB_CFG) = reg;
+ (void)REGVAL(LOONGSON_PXARB_CFG);
+
+ /*
* Setup interrupt handling.
*/
REGVAL(BONITO_GPIOIE) = bc->bc_gpioIE;
REGVAL(BONITO_INTEDGE) = bc->bc_intEdge;
- REGVAL(BONITO_INTSTEER) = 0;
REGVAL(BONITO_INTPOL) = bc->bc_intPol;
- REGVAL(BONITO_INTENCLR) = -1L;
+ REGVAL(BONITO_INTENCLR) = 0xffffffff;
(void)REGVAL(BONITO_INTENCLR);
- wbflush();
bonito_isaimr = bonito_get_isa_imr();
@@ -457,18 +469,17 @@ bonito_intr(uint32_t hwpend, struct trap_frame *frame)
isr = REGVAL(BONITO_INTISR) & YEELONG_INTRMASK_LVL4;
imr = REGVAL(BONITO_INTEN);
isr &= imr;
- if (isr == 0)
- return 0; /* not for us */
-
#ifdef DEBUG
printf("pci interrupt: imr %04x isr %04x\n", imr, isr);
#endif
+ if (isr == 0)
+ return 0; /* not for us */
+
/*
* Mask all pending interrupts.
*/
REGVAL(BONITO_INTENCLR) = isr;
(void)REGVAL(BONITO_INTENCLR);
- wbflush();
/*
* If interrupts are spl-masked, mask them and wait for splx()
@@ -508,18 +519,19 @@ bonito_intr(uint32_t hwpend, struct trap_frame *frame)
if (rc == 0)
printf("spurious interrupt %d\n", bit);
- isr ^= mask;
+ if ((isr ^= mask) == 0)
+ goto done;
if ((tmpisr ^= mask) == 0)
break;
}
}
+done:
/*
* Reenable interrupts which have been serviced.
*/
REGVAL(BONITO_INTENSET) = imr;
(void)REGVAL(BONITO_INTENSET);
- wbflush();
}
return hwpend;
@@ -603,11 +615,13 @@ bonito_isa_intr(uint32_t hwpend, struct trap_frame *frame)
bonito_isa_specific_eoi(bitno);
- isr ^= mask;
+ if ((isr ^= mask) == 0)
+ goto done;
if ((tmpisr ^= mask) == 0)
break;
}
}
+done:
/*
* Reenable interrupts which have been serviced.
@@ -622,15 +636,24 @@ bonito_isa_intr(uint32_t hwpend, struct trap_frame *frame)
void
bonito_setintrmask(int level)
{
- uint64_t active = bonito_intem & ~bonito_imask[level];
+ uint64_t active;
+ uint32_t clear, set;
uint32_t sr;
+ active = bonito_intem & ~bonito_imask[level];
+ clear = bonito_imask[level] & 0xffff;
+ set = active & 0xffff;
+
sr = disableintr();
- REGVAL(BONITO_INTENCLR) = bonito_imask[level] & 0xffff;
- REGVAL(BONITO_INTENSET) = active & 0xffff;
+
+ if (clear != 0)
+ REGVAL(BONITO_INTENCLR) = clear;
+ if (set != 0)
+ REGVAL(BONITO_INTENSET) = set;
(void)REGVAL(BONITO_INTENSET);
- wbflush();
+
bonito_set_isa_imr(active >> 16);
+
setsr(sr);
}
@@ -767,12 +790,11 @@ bonito_conf_read(void *v, pcitag_t tag, int offset)
sr = disableintr();
imr = REGVAL(BONITO_INTEN);
- REGVAL(BONITO_INTENCLR) = -1L;
+ REGVAL(BONITO_INTENCLR) = 0xffffffff;
(void)REGVAL(BONITO_INTENCLR);
- wbflush();
/* clear aborts */
- REGVAL(BONITO_PCICMD) |=
+ REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
/* high 16 bits of address go into PciMapCfg register */
@@ -784,16 +806,15 @@ bonito_conf_read(void *v, pcitag_t tag, int offset)
data = REGVAL(BONITO_PCICFG_BASE + (cfgoff & 0xfffc));
/* check for error */
- if (REGVAL(BONITO_PCICMD) &
+ if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) &
(PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT)) {
- REGVAL(BONITO_PCICMD) |=
+ REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
data = (pcireg_t) -1;
}
REGVAL(BONITO_INTENSET) = imr;
(void)REGVAL(BONITO_INTENSET);
- wbflush();
setsr(sr);
return data;
@@ -820,12 +841,11 @@ bonito_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
sr = disableintr();
imr = REGVAL(BONITO_INTEN);
- REGVAL(BONITO_INTENCLR) = -1L;
+ REGVAL(BONITO_INTENCLR) = 0xffffffff;
(void)REGVAL(BONITO_INTENCLR);
- wbflush();
/* clear aborts */
- REGVAL(BONITO_PCICMD) |=
+ REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
/* high 16 bits of address go into PciMapCfg register */
@@ -838,7 +858,6 @@ bonito_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
REGVAL(BONITO_INTENSET) = imr;
(void)REGVAL(BONITO_INTENSET);
- wbflush();
setsr(sr);
}
@@ -934,6 +953,10 @@ bonito_pci_intr_disestablish(void *cookie, void *ihp)
bonito_intr_disestablish(ihp);
}
+/*
+ * ISA Interrupt handling
+ */
+
uint
bonito_get_isa_imr()
{
diff --git a/sys/arch/loongson/dev/bonitoreg.h b/sys/arch/loongson/dev/bonitoreg.h
index ec7549ce391..0ece5e21c19 100644
--- a/sys/arch/loongson/dev/bonitoreg.h
+++ b/sys/arch/loongson/dev/bonitoreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bonitoreg.h,v 1.1 2009/11/26 15:50:07 miod Exp $ */
+/* $OpenBSD: bonitoreg.h,v 1.2 2010/01/31 19:12:12 miod Exp $ */
/* $NetBSD: bonitoreg.h,v 1.6 2005/12/24 20:07:19 perry Exp $ */
/*
@@ -66,89 +66,47 @@
#define BONITO_PCICONFIGBASE 0x00
#define BONITO_REGBASE 0x100
-
/* PCI Configuration Registers */
#define BONITO_PCI_REG(x) BONITO(BONITO_PCICONFIGBASE + (x))
-#define BONITO_PCIDID BONITO_PCI_REG(0x00)
-#define BONITO_PCICMD BONITO_PCI_REG(0x04)
-#define BONITO_PCICLASS BONITO_PCI_REG(0x08)
-#define BONITO_PCILTIMER BONITO_PCI_REG(0x0c)
-#define BONITO_PCIBASE0 BONITO_PCI_REG(0x10)
-#define BONITO_PCIBASE1 BONITO_PCI_REG(0x14)
-#define BONITO_PCIBASE2 BONITO_PCI_REG(0x18)
-#define BONITO_PCIEXPRBASE BONITO_PCI_REG(0x30)
-#define BONITO_PCIINT BONITO_PCI_REG(0x3c)
-
-#define BONITO_PCICMD_PERR_CLR 0x80000000
-#define BONITO_PCICMD_SERR_CLR 0x40000000
-#define BONITO_PCICMD_MABORT_CLR 0x20000000
-#define BONITO_PCICMD_MTABORT_CLR 0x10000000
-#define BONITO_PCICMD_TABORT_CLR 0x08000000
-#define BONITO_PCICMD_MPERR_CLR 0x01000000
-#define BONITO_PCICMD_PERRRESPEN 0x00000040
-#define BONITO_PCICMD_ASTEPEN 0x00000080
-#define BONITO_PCICMD_SERREN 0x00000100
-#define BONITO_PCILTIMER_BUSLATENCY 0x0000ff00
-#define BONITO_PCILTIMER_BUSLATENCY_SHIFT 8
-
-
-#define BONITO_REV_FPGA(x) ((x) & 0x80)
-#define BONITO_REV_MAJOR(x) (((x) >> 4) & 0x7)
-#define BONITO_REV_MINOR(x) ((x) & 0xf)
-
-
-/* Bonito configuration */
-
-#define BONITO_BONGENCFG_OFFSET 0x4
-#define BONITO_BONGENCFG BONITO(BONITO_REGBASE + BONITO_BONGENCFG_OFFSET)
-
-#define BONITO_BONGENCFG_DEBUGMODE 0x00000001
-#define BONITO_BONGENCFG_SNOOPEN 0x00000002
-#define BONITO_BONGENCFG_CPUSELFRESET 0x00000004
-
-#define BONITO_BONGENCFG_FORCE_IRQA 0x00000008
-#define BONITO_BONGENCFG_IRQA_ISOUT 0x00000010
-#define BONITO_BONGENCFG_IRQA_FROM_INT1 0x00000020
-#define BONITO_BONGENCFG_BYTESWAP 0x00000040
-
-#define BONITO_BONGENCFG_UNCACHED 0x00000080
-#define BONITO_BONGENCFG_PREFETCHEN 0x00000100
-#define BONITO_BONGENCFG_WBEHINDEN 0x00000200
-#define BONITO_BONGENCFG_CACHEALG 0x00000c00
-#define BONITO_BONGENCFG_CACHEALG_SHIFT 10
-#define BONITO_BONGENCFG_PCIQUEUE 0x00001000
-#define BONITO_BONGENCFG_CACHESTOP 0x00002000
-#define BONITO_BONGENCFG_MSTRBYTESWAP 0x00004000
-#define BONITO_BONGENCFG_BUSERREN 0x00008000
-#define BONITO_BONGENCFG_NORETRYTIMEOUT 0x00010000
-#define BONITO_BONGENCFG_SHORTCOPYTIMEOUT 0x00020000
+
+/* Controller configuration */
+
+#define LOONGSON_PONCFG BONITO(BONITO_REGBASE + 0x00)
+#define LOONGSON_GENCFG BONITO(BONITO_REGBASE + 0x04)
+#define LOONGSON_LIOCFG BONITO(BONITO_REGBASE + 0x08)
/* PCI address map control */
#define BONITO_PCIMAP BONITO(BONITO_REGBASE + 0x10)
-#define BONITO_PCIMEMBASECFG BONITO(BONITO_REGBASE + 0x14)
+#define LOONGSON_PCIX_BRIDGE_CFG BONITO(BONITO_REGBASE + 0x14)
#define BONITO_PCIMAP_CFG BONITO(BONITO_REGBASE + 0x18)
/* GPIO Regs - r/w */
-#define BONITO_GPIODATA_OFFSET 0x1c
-#define BONITO_GPIODATA BONITO(BONITO_REGBASE + BONITO_GPIODATA_OFFSET)
+#define BONITO_GPIODATA BONITO(BONITO_REGBASE + 0x1c)
#define BONITO_GPIOIE BONITO(BONITO_REGBASE + 0x20)
/* ICU Configuration Regs - r/w */
#define BONITO_INTEDGE BONITO(BONITO_REGBASE + 0x24)
-#define BONITO_INTSTEER BONITO(BONITO_REGBASE + 0x28)
+/* INTSTEER is not implemented */
#define BONITO_INTPOL BONITO(BONITO_REGBASE + 0x2c)
-/* ICU Enable Regs - IntEn & IntISR are r/o. */
+/* ICU Enable Regs - INTEN and INTISR are read only */
#define BONITO_INTENSET BONITO(BONITO_REGBASE + 0x30)
#define BONITO_INTENCLR BONITO(BONITO_REGBASE + 0x34)
#define BONITO_INTEN BONITO(BONITO_REGBASE + 0x38)
#define BONITO_INTISR BONITO(BONITO_REGBASE + 0x3c)
+/* Memory window */
+
+#define BONITO_MEM_WIN_BASE_L BONITO(BONITO_REGBASE + 0x40)
+#define BONITO_MEM_WIN_BASE_H BONITO(BONITO_REGBASE + 0x44)
+#define BONITO_MEM_WIN_MASK_L BONITO(BONITO_REGBASE + 0x48)
+#define BONITO_MEM_WIN_MASK_H BONITO(BONITO_REGBASE + 0x4c)
+
/* PCI_Hit*_Sel_* */
#define LOONGSON_PCI_HIT0_SEL_L BONITO(BONITO_REGBASE + 0x50)
@@ -158,8 +116,23 @@
#define LOONGSON_PCI_HIT2_SEL_L BONITO(BONITO_REGBASE + 0x60)
#define LOONGSON_PCI_HIT2_SEL_H BONITO(BONITO_REGBASE + 0x64)
+/* PCIX Arbitration */
+
+#define LOONGSON_PXARB_CFG BONITO(BONITO_REGBASE + 0x68)
+#define LOONGSON_PXARB_STS BONITO(BONITO_REGBASE + 0x6c)
+
+/* Chip configuration */
+
+#define LOONGSON_CHIP_CONFIG0 BONITO(BONITO_REGBASE + 0x80)
+#define LOONGSON_PAD1V8_CTRL BONITO(BONITO_REGBASE + 0x84)
+#define LOONGSON_PAD3V3_CTRL BONITO(BONITO_REGBASE + 0x88)
+
/* ###### Bit Definitions for individual Registers #### */
+/* gencfg */
+
+#define BONITO_GENCFG_OV_EN 0x00000001 /* video accel enable */
+
/* pcimap */
#define BONITO_PCIMAP_PCIMAP_LO0 0x0000003f
@@ -168,9 +141,7 @@
#define BONITO_PCIMAP_PCIMAP_LO1_SHIFT 6
#define BONITO_PCIMAP_PCIMAP_LO2 0x0003f000
#define BONITO_PCIMAP_PCIMAP_LO2_SHIFT 12
-#define BONITO_PCIMAP_PCIMAP_2 0x00040000
#define BONITO_PCIMAP_WIN(WIN,ADDR) ((((ADDR)>>26) & BONITO_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
-
#define BONITO_PCIMAP_WINSIZE (1<<26)
#define BONITO_PCIMAP_WINOFFSET(ADDR) ((ADDR) & (BONITO_PCIMAP_WINSIZE - 1))
#define BONITO_PCIMAP_WINBASE(ADDR) ((ADDR) << 26)
@@ -179,4 +150,22 @@
#define BONITO_PCIMAPCFG_TYPE1 0x00010000
+/* PXARB_CFG */
+
+#define LOONGSON_PXARB_DEVICE_EN 0x00000001
+#define LOONGSON_PXARB_DISABLE_BROKEN 0x00000002
+#define LOONGSON_PXARB_DEFAULT_MAS_EN 0x00000004
+#define LOONGSON_PXARB_DEFAULT_MAS_MSK 0x00000038
+#define LOONGSON_PXARB_DEFAULT_MAS_SHFT 3
+#define LOONGSON_PXARB_PARK_DELAY_MSK 0x000000c0
+#define LOONGSON_PXARB_PARK_DELAY_SHFT 6
+#define LOONGSON_PXARB_PARK_DELAY_0 0
+#define LOONGSON_PXARB_PARK_DELAY_8 1
+#define LOONGSON_PXARB_PARK_DELAY_32 2
+#define LOONGSON_PXARB_PARK_DELAY_128 3
+#define LOONGSON_PXARB_LEVEL_MSK 0x0000ff00
+#define LOONGSON_PXARB_LEVEL_SHFT 8
+#define LOONGSON_PXARB_RUDE_DEV_MSK 0x00ff0000
+#define LOONGSON_PXARB_RUDE_DEV_SHFT 16
+
#endif /* _BONITOREG_H_ */