From owner-p4-projects@FreeBSD.ORG Thu Aug 21 23:57:23 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E7E7116A4C1; Thu, 21 Aug 2003 23:57:22 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9B6F016A4BF for ; Thu, 21 Aug 2003 23:57:22 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2411143FBF for ; Thu, 21 Aug 2003 23:57:22 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h7M6vL0U071731 for ; Thu, 21 Aug 2003 23:57:21 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h7M6vLc3071728 for perforce@freebsd.org; Thu, 21 Aug 2003 23:57:21 -0700 (PDT) Date: Thu, 21 Aug 2003 23:57:21 -0700 (PDT) Message-Id: <200308220657.h7M6vLc3071728@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 36647 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Aug 2003 06:57:24 -0000 http://perforce.freebsd.org/chv.cgi?CH=36647 Change 36647 by marcel@marcel_nfs on 2003/08/21 23:56:39 Rough implementation of the sab82532 driver for bus access. This allows us to boot single- and multi-user. Lacking are: o reading and writing modem/line signals o flushing of the transmitter/receiver Affected files ... .. //depot/projects/uart/dev/uart/uart_dev_sab82532.c#10 edit Differences ... ==== //depot/projects/uart/dev/uart/uart_dev_sab82532.c#10 (text+ko) ==== @@ -180,7 +180,7 @@ sab82532_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, int parity) { - uint8_t pvr; + uint8_t ccr0, pvr; if (bas->rclk == 0) bas->rclk = DEFAULT_RCLK; @@ -188,18 +188,61 @@ /* Set all pins, except DTR pins to be inputs. */ uart_setreg(bas, SAB_PCR, ~(SAB_PVR_DTR_A | SAB_PVR_DTR_B)); uart_barrier(bas); - /* Disable port interrupts */ + /* Disable port interrupts. */ uart_setreg(bas, SAB_PIM, 0xff); uart_barrier(bas); /* Interrupts are active low. */ uart_setreg(bas, SAB_IPC, SAB_IPC_ICPL); uart_barrier(bas); + /* Set DTR. */ + pvr = uart_getreg(bas, SAB_PVR); + pvr |= IS_CHANNEL_A(bas) ? SAB_PVR_DTR_A : SAB_PVR_DTR_B; + uart_setreg(bas, SAB_PVR, pvr); + uart_barrier(bas); + + /* power down */ + uart_setreg(bas, SAB_CCR0, 0); + uart_barrier(bas); + + /* set basic configuration */ + ccr0 = SAB_CCR0_MCE|SAB_CCR0_SC_NRZ|SAB_CCR0_SM_ASYNC; + uart_setreg(bas, SAB_CCR0, ccr0); + uart_barrier(bas); + uart_setreg(bas, SAB_CCR1, SAB_CCR1_ODS|SAB_CCR1_BCR|SAB_CCR1_CM_7); + uart_barrier(bas); + uart_setreg(bas, SAB_CCR2, SAB_CCR2_BDF|SAB_CCR2_SSEL|SAB_CCR2_TOE); + uart_barrier(bas); + uart_setreg(bas, SAB_CCR3, 0); + uart_barrier(bas); + uart_setreg(bas, SAB_CCR4, SAB_CCR4_MCK4|SAB_CCR4_EBRG); + uart_barrier(bas); + uart_setreg(bas, SAB_MODE, SAB_MODE_RTS|SAB_MODE_FCTS|SAB_MODE_RAC); + uart_barrier(bas); + uart_setreg(bas, SAB_RFC, SAB_RFC_DPS|SAB_RFC_RFDF| + SAB_RFC_RFTH_32CHAR); + uart_barrier(bas); + while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) + ; + uart_setreg(bas, SAB_CMDR, SAB_CMDR_XRES); + uart_barrier(bas); + while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) + ; + uart_setreg(bas, SAB_CMDR, SAB_CMDR_RRES); + uart_barrier(bas); + sab82532_param(bas, baudrate, databits, stopbits, parity); - pvr = uart_getreg(bas, SAB_PVR); - pvr |= IS_CHANNEL_A(bas) ? SAB_PVR_DTR_A : SAB_PVR_DTR_B; - uart_setreg(bas, SAB_PVR, pvr); + /* Clear interrupts. */ + uart_setreg(bas, SAB_IMR0, 0xff); + uart_setreg(bas, SAB_IMR1, 0xff); + uart_barrier(bas); + uart_getreg(bas, SAB_ISR0); + uart_getreg(bas, SAB_ISR1); + uart_barrier(bas); + + /* Power up. */ + uart_setreg(bas, SAB_CCR0, ccr0|SAB_CCR0_PU); uart_barrier(bas); } @@ -250,8 +293,8 @@ while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE)) DELAY(delay); - while ((uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)) - DELAY(delay); + while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) + ; uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD); uart_barrier(bas); @@ -263,9 +306,8 @@ uart_barrier(bas); /* Blow away everything left in the FIFO... */ - while ((uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)) - DELAY(delay); - + while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) + ; uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC); uart_barrier(bas); return (c); @@ -318,10 +360,16 @@ struct uart_bas *bas; bas = &sc->sc_bas; - if (!sc->sc_console && !sc->sc_dbgport) sab82532_init(bas, 9600, 8, 1, UART_PARITY_NONE); + sc->sc_rxfifosz = 32; + sc->sc_txfifosz = 32; + + uart_setreg(bas, SAB_IMR0, SAB_IMR0_PERR|SAB_IMR0_FERR|SAB_IMR0_PLLA); + uart_setreg(bas, SAB_IMR1, SAB_IMR1_BRK|SAB_IMR1_XDU|SAB_IMR1_TIN| + SAB_IMR1_XMR|SAB_IMR1_XPR); + uart_barrier(bas); return (0); } @@ -331,9 +379,14 @@ struct uart_bas *bas; bas = &sc->sc_bas; - - uart_setreg(bas, SAB_IPC, SAB_IPC_ICPL | SAB_IPC_VIS); - uart_setreg(bas, SAB_RFC, uart_getreg(bas, SAB_RFC) & ~SAB_RFC_RFDF); + uart_setreg(bas, SAB_IMR0, 0xff); + uart_setreg(bas, SAB_IMR1, 0xff); + uart_barrier(bas); + uart_getreg(bas, SAB_ISR0); + uart_getreg(bas, SAB_ISR1); + uart_barrier(bas); + uart_setreg(bas, SAB_CCR0, 0); + uart_barrier(bas); return (0); } @@ -354,8 +407,35 @@ static int sab82532_bus_ipend(struct uart_softc *sc) { + struct uart_bas *bas; + int ipend; + uint8_t isr0, isr1; - return (0); + bas = &sc->sc_bas; + isr0 = uart_getreg(bas, SAB_ISR0); + isr1 = uart_getreg(bas, SAB_ISR1); + uart_barrier(bas); + + if (isr0 & SAB_ISR0_TIME) { + while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) + ; + uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD); + uart_barrier(bas); + } + + ipend = 0; + if (isr1 & SAB_ISR1_BRKT) + ipend |= UART_IPEND_BREAK; + if (isr0 & SAB_ISR0_RFO) + ipend |= UART_IPEND_OVERRUN; + if (isr0 & (SAB_ISR0_TCD|SAB_ISR0_RPF)) + ipend |= UART_IPEND_RXREADY; + if ((isr0 & SAB_ISR0_CDSC) || (isr1 & SAB_ISR1_CSC)) + ipend |= UART_IPEND_SIGCHG; + if (isr1 & SAB_ISR1_ALLS) + ipend |= UART_IPEND_TXIDLE; + + return (ipend); } static int @@ -397,7 +477,36 @@ static int sab82532_bus_receive(struct uart_softc *sc) { + struct uart_bas *bas; + int count, xc; + uint8_t s; + bas = &sc->sc_bas; + count = uart_getreg(bas, SAB_RBCL) & 31; + if (count == 0) + count = 32; + while (count && !uart_rx_full(sc)) { + xc = uart_getreg(bas, SAB_RFIFO); + s = uart_getreg(bas, SAB_RFIFO); + if (s & SAB_RSTAT_FE) + xc |= UART_STAT_FRAMERR; + if (s & SAB_RSTAT_PE) + xc |= UART_STAT_PARERR; + uart_rx_put(sc, xc); + count -= 2; + } + /* + * Oops, we couldn't get all data from the FIFO. Mark an overflow + * condition and let upper layers deal with this. We need to free + * the Rx FIFO. Sorry... + */ + if (count) + sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; + + while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) + ; + uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC); + uart_barrier(bas); return (0); } @@ -411,6 +520,16 @@ static int sab82532_bus_transmit(struct uart_softc *sc) { + struct uart_bas *bas; + int i; + bas = &sc->sc_bas; + for (i = 0; i < sc->sc_txdatasz; i++) + uart_setreg(bas, SAB_XFIFO + i, sc->sc_txbuf[i]); + uart_barrier(bas); + while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) + ; + uart_setreg(bas, SAB_CMDR, SAB_CMDR_XF); + sc->sc_txbusy = 1; return (0); }