diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-01-31 19:12:13 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-01-31 19:12:13 +0000 |
commit | 49c6d38e4130acfdfdb7f256c2cc0f54546c06a2 (patch) | |
tree | ab9bbbf0d99c5c2081b5adf84f644caf2df856dd /sys/arch/loongson | |
parent | f62f1306d674696bbc6d475fc53dd4a1b9d8f7bb (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.c | 85 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonitoreg.h | 113 |
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_ */ |