From 41c7b6c82ed2ddd54f358c9e38664726599ac37f Mon Sep 17 00:00:00 2001 From: bde Date: Thu, 13 Aug 1998 13:54:10 +0000 Subject: Updated for not-so-new version of Cyclom-Y boards (with 60MHz clock and swapped RTS/DTR). Merge the vendor's modification of the 2.2.6-release version into -current for reference. Will be cleaned up in next commit. Obtained from: ftp://ftp.cyclades.com/pub/cyclades/cyclom-y/freebsd/2.2.6/cyy226.tar.gz --- sys/dev/cy/cy.c | 158 +++++++++++++++++++++++++++++++++++++++------------- sys/dev/cy/cy_isa.c | 158 +++++++++++++++++++++++++++++++++++++++------------- sys/dev/cy/cyreg.h | 10 +++- 3 files changed, 246 insertions(+), 80 deletions(-) (limited to 'sys/dev/cy') diff --git a/sys/dev/cy/cy.c b/sys/dev/cy/cy.c index afeeb52..a4ace21 100644 --- a/sys/dev/cy/cy.c +++ b/sys/dev/cy/cy.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: cy.c,v 1.65 1998/07/29 18:48:20 bde Exp $ + * $Id: cy.c,v 1.66 1998/08/11 17:01:32 bde Exp $ */ #include "opt_compat.h" @@ -272,6 +272,7 @@ struct com_s { int cy_align; /* index for register alignment */ cy_addr cy_iobase; /* base address of this port's cyclom */ + int cy_rflow; /* rflow flag */ cy_addr iobase; /* base address of this port's cd1400 */ struct tty *tp; /* cross reference */ @@ -344,7 +345,7 @@ static int comparam __P((struct tty *tp, struct termios *t)); static swihand_t siopoll; static int sioprobe __P((struct isa_device *dev)); static void siosettimeout __P((void)); -static int comspeed __P((speed_t speed, int *prescaler_io)); +static int comspeed __P((speed_t speed, long clock, int *prescaler_io)); static void comstart __P((struct tty *tp)); static timeout_t comwakeup; static void disc_optim __P((struct tty *tp, struct termios *t, @@ -536,9 +537,13 @@ cyattach_common(cy_iobase, cy_align) + (cy_chip_offset[cyu] << cy_align)); /* Set up a receive timeout period of than 1+ ms. */ - cd_outb(iobase, CD1400_PPR, cy_align, - howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000)); - + if (cd_inb(iobase,CD1400_GFRCR, cy_align) >= CD1400_REV_J) { + /* CD1400 rev. J or higher */ + cd_outb(iobase, CD1400_PPR, cy_align, CY_CLOCK_60_1MS); + } else { + cd_outb(iobase, CD1400_PPR, cy_align, CY_CLOCK_25_1MS); + } + for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) { struct com_s *com; int s; @@ -557,6 +562,13 @@ cyattach_common(cy_iobase, cy_align) com->cy_align = cy_align; com->cy_iobase = cy_iobase; + if (cd_inb(iobase,CD1400_GFRCR, cy_align) >= + CD1400_REV_J) { + /* CD1400 rev. J or higher */ + com->cy_rflow = 1; + } else { + com->cy_rflow = 0; + } com->iobase = iobase; /* @@ -1102,14 +1114,24 @@ siointr(unit) ioptr[CE_INPUT_OFFSET] = line_status; com->iptr = ++ioptr; if (ioptr == com->ihighwater - && com->state & CS_RTS_IFLOW) + && com->state & CS_RTS_IFLOW) { #if 0 outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, cy_align, - com->mcr_image &= ~MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, + cy_align, + com->mcr_image &= + ~MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, + cy_align, + com->mcr_image &= + ~MCR_RTS); + } #endif + } if (line_status & LSR_OE) CE_RECORD(com, CE_OVERRUN); } @@ -1165,8 +1187,17 @@ siointr(unit) outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, cy_align, - com->mcr_image &= ~MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, + cy_align, + com->mcr_image &= + ~MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, + cy_align, + com->mcr_image &= + ~MCR_RTS); + } #endif com_events += count; do { @@ -1602,8 +1633,9 @@ repeat: * there is room in the high-level buffer. */ if ((com->state & CS_RTS_IFLOW) - && !(com->mcr_image & MCR_RTS) - && !(tp->t_state & TS_TBLOCK)) + && (com->cy_rflow ? (!(com->mcr_image & MCR_DTR)) : + (!(com->mcr_image & MCR_RTS))) + && !(tp->t_state & TS_TBLOCK)) { #if 0 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); @@ -1611,9 +1643,15 @@ repeat: iobase = com->iobase, cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN), - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image |= MCR_RTS); + (com->cy_rflow ? + cd_outb(iobase, CD1400_MSVR2, + com->cy_align, + com->mcr_image |= MCR_DTR) : + cd_outb(iobase, CD1400_MSVR1, + com->cy_align, + com->mcr_image |= MCR_RTS)); #endif + } enable_intr(); com->ibuf = ibuf; } @@ -1716,25 +1754,35 @@ comparam(tp, t) u_char opt; int s; int unit; + long cy_clock; /* do historical conversions */ if (t->c_ispeed == 0) t->c_ispeed = t->c_ospeed; + unit = DEV_TO_UNIT(tp->t_dev); + com = com_addr(unit); + iobase = com->iobase; + s = spltty(); + cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN); + + /* Set Clock Reference */ + if (cd_inb(iobase, CD1400_GFRCR, com->cy_align) == CD1400_REV_J) { + /* CD1400 rev. J or higher */ + cy_clock = CY_CLOCK_60; + } else { + cy_clock = CY_CLOCK_25; + } + /* check requested parameters */ - idivisor = comspeed(t->c_ispeed, &iprescaler); + idivisor = comspeed(t->c_ispeed, cy_clock, &iprescaler); if (idivisor < 0) return (EINVAL); - odivisor = comspeed(t->c_ospeed, &oprescaler); + odivisor = comspeed(t->c_ospeed, cy_clock, &oprescaler); if (odivisor < 0) return (EINVAL); /* parameters are OK, convert them to the com struct and the device */ - unit = DEV_TO_UNIT(tp->t_dev); - com = com_addr(unit); - iobase = com->iobase; - s = spltty(); - cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN); if (odivisor == 0) (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */ else @@ -2002,8 +2050,13 @@ comparam(tp, t) #if 0 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image |= MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, com->cy_align, + com->mcr_image |= MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, com->cy_align, + com->mcr_image |= MCR_RTS); + } #endif } @@ -2085,21 +2138,35 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } if (tp->t_state & TS_TBLOCK) { - if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW) + if ((com->cy_rflow ? (com->mcr_image & MCR_DTR) : + (com->mcr_image & MCR_RTS)) + && com->state & CS_RTS_IFLOW) #if 0 outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image &= ~MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, com->cy_align, + com->mcr_image &= ~MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, com->cy_align, + com->mcr_image &= ~MCR_RTS); + } #endif } else { - if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater + if ((com->cy_rflow ? (!(com->mcr_image & MCR_DTR)) : + (!(com->mcr_image & MCR_RTS))) + && com->iptr < com->ihighwater && com->state & CS_RTS_IFLOW) #if 0 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image |= MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, com->cy_align, + com->mcr_image |= MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, com->cy_align, + com->mcr_image |= MCR_RTS); + } #endif } enable_intr(); @@ -2244,11 +2311,13 @@ commctl(com, bits, how) if (com->channel_control & CD1400_CCR_RCVEN) bits |= TIOCM_LE; mcr = com->mcr_image; - if (mcr & MCR_DTR) + if ((com->cy_rflow ? mcr & MCR_RTS : mcr & MCR_DTR)) { bits |= TIOCM_DTR; - if (mcr & MCR_RTS) + } + if ((com->cy_rflow ? mcr & MCR_DTR : mcr & MCR_RTS)) { /* XXX wired on for Cyclom-8Ys */ bits |= TIOCM_RTS; + } /* * We must read the modem status from the hardware because @@ -2272,10 +2341,20 @@ commctl(com, bits, how) return (bits); } mcr = 0; - if (bits & TIOCM_DTR) - mcr |= MCR_DTR; - if (bits & TIOCM_RTS) - mcr |= MCR_RTS; + if (bits & TIOCM_DTR) { + if (com->cy_rflow) { + mcr |= MCR_RTS; + } else { + mcr |= MCR_DTR; + } + } + if (bits & TIOCM_RTS) { + if (com->cy_rflow) { + mcr |= MCR_DTR; + } else { + mcr |= MCR_RTS; + } + } disable_intr(); switch (how) { case DMSET: @@ -2452,8 +2531,9 @@ cyinput(c, tp) #endif /* Smarts */ static int -comspeed(speed, prescaler_io) +comspeed(speed, clock, prescaler_io) speed_t speed; + long clock; int *prescaler_io; { int actual; @@ -2470,14 +2550,14 @@ comspeed(speed, prescaler_io) /* determine which prescaler to use */ for (prescaler_unit = 4, prescaler = 2048; prescaler_unit; prescaler_unit--, prescaler >>= 2) { - if (CY_CLOCK / prescaler / speed > 63) + if (clock / prescaler / speed > 63) break; } - divider = (CY_CLOCK / prescaler * 2 / speed + 1) / 2; /* round off */ + divider = (clock / prescaler * 2 / speed + 1) / 2; /* round off */ if (divider > 255) divider = 255; - actual = CY_CLOCK/prescaler/divider; + actual = clock/prescaler/divider; /* 10 times error in percent: */ error = ((actual - (long)speed) * 2000 / (long)speed + 1) / 2; diff --git a/sys/dev/cy/cy_isa.c b/sys/dev/cy/cy_isa.c index afeeb52..a4ace21 100644 --- a/sys/dev/cy/cy_isa.c +++ b/sys/dev/cy/cy_isa.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: cy.c,v 1.65 1998/07/29 18:48:20 bde Exp $ + * $Id: cy.c,v 1.66 1998/08/11 17:01:32 bde Exp $ */ #include "opt_compat.h" @@ -272,6 +272,7 @@ struct com_s { int cy_align; /* index for register alignment */ cy_addr cy_iobase; /* base address of this port's cyclom */ + int cy_rflow; /* rflow flag */ cy_addr iobase; /* base address of this port's cd1400 */ struct tty *tp; /* cross reference */ @@ -344,7 +345,7 @@ static int comparam __P((struct tty *tp, struct termios *t)); static swihand_t siopoll; static int sioprobe __P((struct isa_device *dev)); static void siosettimeout __P((void)); -static int comspeed __P((speed_t speed, int *prescaler_io)); +static int comspeed __P((speed_t speed, long clock, int *prescaler_io)); static void comstart __P((struct tty *tp)); static timeout_t comwakeup; static void disc_optim __P((struct tty *tp, struct termios *t, @@ -536,9 +537,13 @@ cyattach_common(cy_iobase, cy_align) + (cy_chip_offset[cyu] << cy_align)); /* Set up a receive timeout period of than 1+ ms. */ - cd_outb(iobase, CD1400_PPR, cy_align, - howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000)); - + if (cd_inb(iobase,CD1400_GFRCR, cy_align) >= CD1400_REV_J) { + /* CD1400 rev. J or higher */ + cd_outb(iobase, CD1400_PPR, cy_align, CY_CLOCK_60_1MS); + } else { + cd_outb(iobase, CD1400_PPR, cy_align, CY_CLOCK_25_1MS); + } + for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) { struct com_s *com; int s; @@ -557,6 +562,13 @@ cyattach_common(cy_iobase, cy_align) com->cy_align = cy_align; com->cy_iobase = cy_iobase; + if (cd_inb(iobase,CD1400_GFRCR, cy_align) >= + CD1400_REV_J) { + /* CD1400 rev. J or higher */ + com->cy_rflow = 1; + } else { + com->cy_rflow = 0; + } com->iobase = iobase; /* @@ -1102,14 +1114,24 @@ siointr(unit) ioptr[CE_INPUT_OFFSET] = line_status; com->iptr = ++ioptr; if (ioptr == com->ihighwater - && com->state & CS_RTS_IFLOW) + && com->state & CS_RTS_IFLOW) { #if 0 outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, cy_align, - com->mcr_image &= ~MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, + cy_align, + com->mcr_image &= + ~MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, + cy_align, + com->mcr_image &= + ~MCR_RTS); + } #endif + } if (line_status & LSR_OE) CE_RECORD(com, CE_OVERRUN); } @@ -1165,8 +1187,17 @@ siointr(unit) outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, cy_align, - com->mcr_image &= ~MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, + cy_align, + com->mcr_image &= + ~MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, + cy_align, + com->mcr_image &= + ~MCR_RTS); + } #endif com_events += count; do { @@ -1602,8 +1633,9 @@ repeat: * there is room in the high-level buffer. */ if ((com->state & CS_RTS_IFLOW) - && !(com->mcr_image & MCR_RTS) - && !(tp->t_state & TS_TBLOCK)) + && (com->cy_rflow ? (!(com->mcr_image & MCR_DTR)) : + (!(com->mcr_image & MCR_RTS))) + && !(tp->t_state & TS_TBLOCK)) { #if 0 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); @@ -1611,9 +1643,15 @@ repeat: iobase = com->iobase, cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN), - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image |= MCR_RTS); + (com->cy_rflow ? + cd_outb(iobase, CD1400_MSVR2, + com->cy_align, + com->mcr_image |= MCR_DTR) : + cd_outb(iobase, CD1400_MSVR1, + com->cy_align, + com->mcr_image |= MCR_RTS)); #endif + } enable_intr(); com->ibuf = ibuf; } @@ -1716,25 +1754,35 @@ comparam(tp, t) u_char opt; int s; int unit; + long cy_clock; /* do historical conversions */ if (t->c_ispeed == 0) t->c_ispeed = t->c_ospeed; + unit = DEV_TO_UNIT(tp->t_dev); + com = com_addr(unit); + iobase = com->iobase; + s = spltty(); + cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN); + + /* Set Clock Reference */ + if (cd_inb(iobase, CD1400_GFRCR, com->cy_align) == CD1400_REV_J) { + /* CD1400 rev. J or higher */ + cy_clock = CY_CLOCK_60; + } else { + cy_clock = CY_CLOCK_25; + } + /* check requested parameters */ - idivisor = comspeed(t->c_ispeed, &iprescaler); + idivisor = comspeed(t->c_ispeed, cy_clock, &iprescaler); if (idivisor < 0) return (EINVAL); - odivisor = comspeed(t->c_ospeed, &oprescaler); + odivisor = comspeed(t->c_ospeed, cy_clock, &oprescaler); if (odivisor < 0) return (EINVAL); /* parameters are OK, convert them to the com struct and the device */ - unit = DEV_TO_UNIT(tp->t_dev); - com = com_addr(unit); - iobase = com->iobase; - s = spltty(); - cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN); if (odivisor == 0) (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */ else @@ -2002,8 +2050,13 @@ comparam(tp, t) #if 0 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image |= MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, com->cy_align, + com->mcr_image |= MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, com->cy_align, + com->mcr_image |= MCR_RTS); + } #endif } @@ -2085,21 +2138,35 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } if (tp->t_state & TS_TBLOCK) { - if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW) + if ((com->cy_rflow ? (com->mcr_image & MCR_DTR) : + (com->mcr_image & MCR_RTS)) + && com->state & CS_RTS_IFLOW) #if 0 outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image &= ~MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, com->cy_align, + com->mcr_image &= ~MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, com->cy_align, + com->mcr_image &= ~MCR_RTS); + } #endif } else { - if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater + if ((com->cy_rflow ? (!(com->mcr_image & MCR_DTR)) : + (!(com->mcr_image & MCR_RTS))) + && com->iptr < com->ihighwater && com->state & CS_RTS_IFLOW) #if 0 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); #else - cd_outb(iobase, CD1400_MSVR1, com->cy_align, - com->mcr_image |= MCR_RTS); + if (com->cy_rflow) { + cd_outb(iobase, CD1400_MSVR2, com->cy_align, + com->mcr_image |= MCR_DTR); + } else { + cd_outb(iobase, CD1400_MSVR1, com->cy_align, + com->mcr_image |= MCR_RTS); + } #endif } enable_intr(); @@ -2244,11 +2311,13 @@ commctl(com, bits, how) if (com->channel_control & CD1400_CCR_RCVEN) bits |= TIOCM_LE; mcr = com->mcr_image; - if (mcr & MCR_DTR) + if ((com->cy_rflow ? mcr & MCR_RTS : mcr & MCR_DTR)) { bits |= TIOCM_DTR; - if (mcr & MCR_RTS) + } + if ((com->cy_rflow ? mcr & MCR_DTR : mcr & MCR_RTS)) { /* XXX wired on for Cyclom-8Ys */ bits |= TIOCM_RTS; + } /* * We must read the modem status from the hardware because @@ -2272,10 +2341,20 @@ commctl(com, bits, how) return (bits); } mcr = 0; - if (bits & TIOCM_DTR) - mcr |= MCR_DTR; - if (bits & TIOCM_RTS) - mcr |= MCR_RTS; + if (bits & TIOCM_DTR) { + if (com->cy_rflow) { + mcr |= MCR_RTS; + } else { + mcr |= MCR_DTR; + } + } + if (bits & TIOCM_RTS) { + if (com->cy_rflow) { + mcr |= MCR_DTR; + } else { + mcr |= MCR_RTS; + } + } disable_intr(); switch (how) { case DMSET: @@ -2452,8 +2531,9 @@ cyinput(c, tp) #endif /* Smarts */ static int -comspeed(speed, prescaler_io) +comspeed(speed, clock, prescaler_io) speed_t speed; + long clock; int *prescaler_io; { int actual; @@ -2470,14 +2550,14 @@ comspeed(speed, prescaler_io) /* determine which prescaler to use */ for (prescaler_unit = 4, prescaler = 2048; prescaler_unit; prescaler_unit--, prescaler >>= 2) { - if (CY_CLOCK / prescaler / speed > 63) + if (clock / prescaler / speed > 63) break; } - divider = (CY_CLOCK / prescaler * 2 / speed + 1) / 2; /* round off */ + divider = (clock / prescaler * 2 / speed + 1) / 2; /* round off */ if (divider > 255) divider = 255; - actual = CY_CLOCK/prescaler/divider; + actual = clock/prescaler/divider; /* 10 times error in percent: */ error = ((actual - (long)speed) * 2000 / (long)speed + 1) / 2; diff --git a/sys/dev/cy/cyreg.h b/sys/dev/cy/cyreg.h index 6aa6632..8b83258 100644 --- a/sys/dev/cy/cyreg.h +++ b/sys/dev/cy/cyreg.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: cyreg.h,v 1.3 1996/10/13 01:09:17 davidg Exp $ */ /* @@ -41,7 +41,13 @@ #define CY_MAX_CD1400s 8 /* for Cyclom-32Y */ -#define CY_CLOCK 25000000 /* baud rate clock */ +#define CD1400_REV_G 0x46 +#define CD1400_REV_J 0x48 + +#define CY_CLOCK_25 25000000 /* baud rate clock */ +#define CY_CLOCK_60 60000000 /* baud rate clock */ +#define CY_CLOCK_25_1MS 0x31 +#define CY_CLOCK_60_1MS 0x75 #ifdef CyDebug #define cd_inb(iobase, reg, cy_align) (++cd_inbs, *((iobase) + ((reg)*2 << (cy_align)))) -- cgit v1.1