diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-05 21:48:38 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-05 21:48:38 +0000 |
commit | a775f4636d8499c789ab2d9d25f13e0a3687c3b4 (patch) | |
tree | 30b723fd9413fc8171be3af16574773bd02c80eb /sys/arch/sgi | |
parent | 64c002ca285586ba041152f4b0babc516c60eeb8 (diff) |
Lower ZS_DELAY() back to what it was, but issue a bus_space_barrier() after
every register write. Hinted by IRIX' <sys/z8530.h>.
While there, flip the CTS, DCD, RTS and DTR bits in registers #0 and #5.
Aforementioned header says they are inverted due to a hardware bug.
Tested on IP20, IP22 and IP24.
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r-- | sys/arch/sgi/hpc/zs.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/sys/arch/sgi/hpc/zs.c b/sys/arch/sgi/hpc/zs.c index 9919c87bccc..fdf6eeef1b4 100644 --- a/sys/arch/sgi/hpc/zs.c +++ b/sys/arch/sgi/hpc/zs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zs.c,v 1.3 2012/04/01 16:37:08 miod Exp $ */ +/* $OpenBSD: zs.c,v 1.4 2012/04/05 21:48:37 miod Exp $ */ /* $NetBSD: zs.c,v 1.37 2011/02/20 07:59:50 matt Exp $ */ /*- @@ -84,7 +84,7 @@ int zs_major = 19; #define ZSHARD_PRI 64 /* SGI shouldn't need ZS_DELAY() as recovery time is done in hardware? */ -#define ZS_DELAY() delay(5) +#define ZS_DELAY() delay(2) /* The layout of this is hardware-dependent (padding, order). */ struct zschan { @@ -441,9 +441,19 @@ zs_read_reg(struct zs_chanstate *cs, uint8_t reg) struct zs_channel *zsc = (struct zs_channel *)cs; bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, reg); + bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); ZS_DELAY(); val = bus_space_read_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR); ZS_DELAY(); + + /* + * According to IRIX <sys/z8530.h>, on Indigo, the CTS and DCD bits + * are inverted. + */ + if (sys_config.system_type == SGI_IP20 && reg == 0) + val ^= ZSRR0_CTS | ZSRR0_DCD; + return val; } @@ -452,9 +462,20 @@ zs_write_reg(struct zs_chanstate *cs, uint8_t reg, uint8_t val) { struct zs_channel *zsc = (struct zs_channel *)cs; + /* + * According to IRIX <sys/z8530.h>, on Indigo, the RTS and DTR bits + * are inverted. + */ + if (sys_config.system_type == SGI_IP20 && reg == 5) + val ^= ZSWR5_DTR | ZSWR5_RTS; + bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, reg); + bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); ZS_DELAY(); bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, val); + bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); ZS_DELAY(); } @@ -475,6 +496,8 @@ zs_write_csr(struct zs_chanstate *cs, uint8_t val) struct zs_channel *zsc = (struct zs_channel *)cs; bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, val); + bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); ZS_DELAY(); } @@ -495,6 +518,8 @@ zs_write_data(struct zs_chanstate *cs, uint8_t val) struct zs_channel *zsc = (struct zs_channel *)cs; bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_DATA, val); + bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); ZS_DELAY(); } @@ -618,7 +643,14 @@ zs_putc(void *arg, int c) } while ((rr0 & ZSRR0_TX_READY) == 0); zc->zc_data = c; - __asm__ __volatile__ ("sync" ::: "memory"); /* wbflush(); */ + + /* inline bus_space_barrier() */ + __asm__ __volatile__ ("sync" ::: "memory"); + if (sys_config.system_type != SGI_IP20) { + (void)*(volatile uint32_t *)PHYS_TO_XKPHYS(HPC_BASE_ADDRESS_0 + + HPC3_INTRSTAT_40, CCA_NC); + } + ZS_DELAY(); splx(s); } |