1*5c263f43SRuslan Bukin /*- 2*5c263f43SRuslan Bukin * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com> 3*5c263f43SRuslan Bukin * All rights reserved. 4*5c263f43SRuslan Bukin * 5*5c263f43SRuslan Bukin * Redistribution and use in source and binary forms, with or without 6*5c263f43SRuslan Bukin * modification, are permitted provided that the following conditions 7*5c263f43SRuslan Bukin * are met: 8*5c263f43SRuslan Bukin * 1. Redistributions of source code must retain the above copyright 9*5c263f43SRuslan Bukin * notice, this list of conditions and the following disclaimer. 10*5c263f43SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 11*5c263f43SRuslan Bukin * notice, this list of conditions and the following disclaimer in the 12*5c263f43SRuslan Bukin * documentation and/or other materials provided with the distribution. 13*5c263f43SRuslan Bukin * 14*5c263f43SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*5c263f43SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*5c263f43SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*5c263f43SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*5c263f43SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*5c263f43SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*5c263f43SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*5c263f43SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*5c263f43SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*5c263f43SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*5c263f43SRuslan Bukin * SUCH DAMAGE. 25*5c263f43SRuslan Bukin */ 26*5c263f43SRuslan Bukin 27*5c263f43SRuslan Bukin /* 28*5c263f43SRuslan Bukin * Vybrid Family Universal Asynchronous Receiver/Transmitter 29*5c263f43SRuslan Bukin * Chapter 49, Vybrid Reference Manual, Rev. 5, 07/2013 30*5c263f43SRuslan Bukin */ 31*5c263f43SRuslan Bukin 32*5c263f43SRuslan Bukin #include <sys/cdefs.h> 33*5c263f43SRuslan Bukin __FBSDID("$FreeBSD$"); 34*5c263f43SRuslan Bukin 35*5c263f43SRuslan Bukin #include "opt_ddb.h" 36*5c263f43SRuslan Bukin 37*5c263f43SRuslan Bukin #include <sys/param.h> 38*5c263f43SRuslan Bukin #include <sys/systm.h> 39*5c263f43SRuslan Bukin #include <sys/bus.h> 40*5c263f43SRuslan Bukin #include <sys/conf.h> 41*5c263f43SRuslan Bukin #include <sys/kdb.h> 42*5c263f43SRuslan Bukin #include <machine/bus.h> 43*5c263f43SRuslan Bukin #include <machine/fdt.h> 44*5c263f43SRuslan Bukin 45*5c263f43SRuslan Bukin #include <dev/uart/uart.h> 46*5c263f43SRuslan Bukin #include <dev/uart/uart_cpu.h> 47*5c263f43SRuslan Bukin #include <dev/uart/uart_bus.h> 48*5c263f43SRuslan Bukin 49*5c263f43SRuslan Bukin #include "uart_if.h" 50*5c263f43SRuslan Bukin 51*5c263f43SRuslan Bukin #define UART_BDH 0x00 /* Baud Rate Registers: High */ 52*5c263f43SRuslan Bukin #define UART_BDL 0x01 /* Baud Rate Registers: Low */ 53*5c263f43SRuslan Bukin #define UART_C1 0x02 /* Control Register 1 */ 54*5c263f43SRuslan Bukin #define UART_C2 0x03 /* Control Register 2 */ 55*5c263f43SRuslan Bukin #define UART_S1 0x04 /* Status Register 1 */ 56*5c263f43SRuslan Bukin #define UART_S2 0x05 /* Status Register 2 */ 57*5c263f43SRuslan Bukin #define UART_C3 0x06 /* Control Register 3 */ 58*5c263f43SRuslan Bukin #define UART_D 0x07 /* Data Register */ 59*5c263f43SRuslan Bukin #define UART_MA1 0x08 /* Match Address Registers 1 */ 60*5c263f43SRuslan Bukin #define UART_MA2 0x09 /* Match Address Registers 2 */ 61*5c263f43SRuslan Bukin #define UART_C4 0x0A /* Control Register 4 */ 62*5c263f43SRuslan Bukin #define UART_C5 0x0B /* Control Register 5 */ 63*5c263f43SRuslan Bukin #define UART_ED 0x0C /* Extended Data Register */ 64*5c263f43SRuslan Bukin #define UART_MODEM 0x0D /* Modem Register */ 65*5c263f43SRuslan Bukin #define UART_IR 0x0E /* Infrared Register */ 66*5c263f43SRuslan Bukin #define UART_PFIFO 0x10 /* FIFO Parameters */ 67*5c263f43SRuslan Bukin #define UART_CFIFO 0x11 /* FIFO Control Register */ 68*5c263f43SRuslan Bukin #define UART_SFIFO 0x12 /* FIFO Status Register */ 69*5c263f43SRuslan Bukin #define UART_TWFIFO 0x13 /* FIFO Transmit Watermark */ 70*5c263f43SRuslan Bukin #define UART_TCFIFO 0x14 /* FIFO Transmit Count */ 71*5c263f43SRuslan Bukin #define UART_RWFIFO 0x15 /* FIFO Receive Watermark */ 72*5c263f43SRuslan Bukin #define UART_RCFIFO 0x16 /* FIFO Receive Count */ 73*5c263f43SRuslan Bukin #define UART_C7816 0x18 /* 7816 Control Register */ 74*5c263f43SRuslan Bukin #define UART_IE7816 0x19 /* 7816 Interrupt Enable Register */ 75*5c263f43SRuslan Bukin #define UART_IS7816 0x1A /* 7816 Interrupt Status Register */ 76*5c263f43SRuslan Bukin #define UART_WP7816T0 0x1B /* 7816 Wait Parameter Register */ 77*5c263f43SRuslan Bukin #define UART_WP7816T1 0x1B /* 7816 Wait Parameter Register */ 78*5c263f43SRuslan Bukin #define UART_WN7816 0x1C /* 7816 Wait N Register */ 79*5c263f43SRuslan Bukin #define UART_WF7816 0x1D /* 7816 Wait FD Register */ 80*5c263f43SRuslan Bukin #define UART_ET7816 0x1E /* 7816 Error Threshold Register */ 81*5c263f43SRuslan Bukin #define UART_TL7816 0x1F /* 7816 Transmit Length Register */ 82*5c263f43SRuslan Bukin #define UART_C6 0x21 /* CEA709.1-B Control Register 6 */ 83*5c263f43SRuslan Bukin #define UART_PCTH 0x22 /* CEA709.1-B Packet Cycle Time Counter High */ 84*5c263f43SRuslan Bukin #define UART_PCTL 0x23 /* CEA709.1-B Packet Cycle Time Counter Low */ 85*5c263f43SRuslan Bukin #define UART_B1T 0x24 /* CEA709.1-B Beta1 Timer */ 86*5c263f43SRuslan Bukin #define UART_SDTH 0x25 /* CEA709.1-B Secondary Delay Timer High */ 87*5c263f43SRuslan Bukin #define UART_SDTL 0x26 /* CEA709.1-B Secondary Delay Timer Low */ 88*5c263f43SRuslan Bukin #define UART_PRE 0x27 /* CEA709.1-B Preamble */ 89*5c263f43SRuslan Bukin #define UART_TPL 0x28 /* CEA709.1-B Transmit Packet Length */ 90*5c263f43SRuslan Bukin #define UART_IE 0x29 /* CEA709.1-B Interrupt Enable Register */ 91*5c263f43SRuslan Bukin #define UART_WB 0x2A /* CEA709.1-B WBASE */ 92*5c263f43SRuslan Bukin #define UART_S3 0x2B /* CEA709.1-B Status Register */ 93*5c263f43SRuslan Bukin #define UART_S4 0x2C /* CEA709.1-B Status Register */ 94*5c263f43SRuslan Bukin #define UART_RPL 0x2D /* CEA709.1-B Received Packet Length */ 95*5c263f43SRuslan Bukin #define UART_RPREL 0x2E /* CEA709.1-B Received Preamble Length */ 96*5c263f43SRuslan Bukin #define UART_CPW 0x2F /* CEA709.1-B Collision Pulse Width */ 97*5c263f43SRuslan Bukin #define UART_RIDT 0x30 /* CEA709.1-B Receive Indeterminate Time */ 98*5c263f43SRuslan Bukin #define UART_TIDT 0x31 /* CEA709.1-B Transmit Indeterminate Time */ 99*5c263f43SRuslan Bukin 100*5c263f43SRuslan Bukin #define UART_C2_TE (1 << 3) /* Transmitter Enable */ 101*5c263f43SRuslan Bukin #define UART_C2_TIE (1 << 7) /* Transmitter Interrupt Enable */ 102*5c263f43SRuslan Bukin #define UART_C2_RE (1 << 2) /* Receiver Enable */ 103*5c263f43SRuslan Bukin #define UART_C2_RIE (1 << 5) /* Receiver Interrupt Enable */ 104*5c263f43SRuslan Bukin #define UART_S1_TDRE (1 << 7) /* Transmit Data Register Empty Flag */ 105*5c263f43SRuslan Bukin #define UART_S1_RDRF (1 << 5) /* Receive Data Register Full Flag */ 106*5c263f43SRuslan Bukin #define UART_S2_LBKDIF (1 << 7) /* LIN Break Detect Interrupt Flag */ 107*5c263f43SRuslan Bukin 108*5c263f43SRuslan Bukin #define UART_C4_BRFA 0x1f /* Baud Rate Fine Adjust */ 109*5c263f43SRuslan Bukin #define UART_BDH_SBR 0x1f /* UART Baud Rate Bits */ 110*5c263f43SRuslan Bukin 111*5c263f43SRuslan Bukin /* 112*5c263f43SRuslan Bukin * Low-level UART interface. 113*5c263f43SRuslan Bukin */ 114*5c263f43SRuslan Bukin static int vf_uart_probe(struct uart_bas *bas); 115*5c263f43SRuslan Bukin static void vf_uart_init(struct uart_bas *bas, int, int, int, int); 116*5c263f43SRuslan Bukin static void vf_uart_term(struct uart_bas *bas); 117*5c263f43SRuslan Bukin static void vf_uart_putc(struct uart_bas *bas, int); 118*5c263f43SRuslan Bukin static int vf_uart_rxready(struct uart_bas *bas); 119*5c263f43SRuslan Bukin static int vf_uart_getc(struct uart_bas *bas, struct mtx *); 120*5c263f43SRuslan Bukin 121*5c263f43SRuslan Bukin void uart_reinit(struct uart_softc *,int,int); 122*5c263f43SRuslan Bukin 123*5c263f43SRuslan Bukin static struct uart_ops uart_vybrid_ops = { 124*5c263f43SRuslan Bukin .probe = vf_uart_probe, 125*5c263f43SRuslan Bukin .init = vf_uart_init, 126*5c263f43SRuslan Bukin .term = vf_uart_term, 127*5c263f43SRuslan Bukin .putc = vf_uart_putc, 128*5c263f43SRuslan Bukin .rxready = vf_uart_rxready, 129*5c263f43SRuslan Bukin .getc = vf_uart_getc, 130*5c263f43SRuslan Bukin }; 131*5c263f43SRuslan Bukin 132*5c263f43SRuslan Bukin static int 133*5c263f43SRuslan Bukin vf_uart_probe(struct uart_bas *bas) 134*5c263f43SRuslan Bukin { 135*5c263f43SRuslan Bukin 136*5c263f43SRuslan Bukin return (0); 137*5c263f43SRuslan Bukin } 138*5c263f43SRuslan Bukin 139*5c263f43SRuslan Bukin static void 140*5c263f43SRuslan Bukin vf_uart_init(struct uart_bas *bas, int baudrate, int databits, 141*5c263f43SRuslan Bukin int stopbits, int parity) 142*5c263f43SRuslan Bukin { 143*5c263f43SRuslan Bukin 144*5c263f43SRuslan Bukin } 145*5c263f43SRuslan Bukin 146*5c263f43SRuslan Bukin static void 147*5c263f43SRuslan Bukin vf_uart_term(struct uart_bas *bas) 148*5c263f43SRuslan Bukin { 149*5c263f43SRuslan Bukin 150*5c263f43SRuslan Bukin } 151*5c263f43SRuslan Bukin 152*5c263f43SRuslan Bukin static void 153*5c263f43SRuslan Bukin vf_uart_putc(struct uart_bas *bas, int c) 154*5c263f43SRuslan Bukin { 155*5c263f43SRuslan Bukin 156*5c263f43SRuslan Bukin while (!(uart_getreg(bas, UART_S1) & UART_S1_TDRE)) 157*5c263f43SRuslan Bukin ; 158*5c263f43SRuslan Bukin 159*5c263f43SRuslan Bukin uart_setreg(bas, UART_D, c); 160*5c263f43SRuslan Bukin } 161*5c263f43SRuslan Bukin 162*5c263f43SRuslan Bukin static int 163*5c263f43SRuslan Bukin vf_uart_rxready(struct uart_bas *bas) 164*5c263f43SRuslan Bukin { 165*5c263f43SRuslan Bukin int usr1; 166*5c263f43SRuslan Bukin 167*5c263f43SRuslan Bukin usr1 = uart_getreg(bas, UART_S1); 168*5c263f43SRuslan Bukin if (usr1 & UART_S1_RDRF) { 169*5c263f43SRuslan Bukin return (1); 170*5c263f43SRuslan Bukin } 171*5c263f43SRuslan Bukin 172*5c263f43SRuslan Bukin return (0); 173*5c263f43SRuslan Bukin } 174*5c263f43SRuslan Bukin 175*5c263f43SRuslan Bukin static int 176*5c263f43SRuslan Bukin vf_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) 177*5c263f43SRuslan Bukin { 178*5c263f43SRuslan Bukin int c; 179*5c263f43SRuslan Bukin 180*5c263f43SRuslan Bukin uart_lock(hwmtx); 181*5c263f43SRuslan Bukin 182*5c263f43SRuslan Bukin while (!(uart_getreg(bas, UART_S1) & UART_S1_RDRF)) 183*5c263f43SRuslan Bukin ; 184*5c263f43SRuslan Bukin 185*5c263f43SRuslan Bukin c = uart_getreg(bas, UART_D); 186*5c263f43SRuslan Bukin uart_unlock(hwmtx); 187*5c263f43SRuslan Bukin 188*5c263f43SRuslan Bukin return (c & 0xff); 189*5c263f43SRuslan Bukin } 190*5c263f43SRuslan Bukin 191*5c263f43SRuslan Bukin /* 192*5c263f43SRuslan Bukin * High-level UART interface. 193*5c263f43SRuslan Bukin */ 194*5c263f43SRuslan Bukin struct vf_uart_softc { 195*5c263f43SRuslan Bukin struct uart_softc base; 196*5c263f43SRuslan Bukin }; 197*5c263f43SRuslan Bukin 198*5c263f43SRuslan Bukin void 199*5c263f43SRuslan Bukin uart_reinit(struct uart_softc *sc, int clkspeed, int baud) 200*5c263f43SRuslan Bukin { 201*5c263f43SRuslan Bukin struct uart_bas *bas; 202*5c263f43SRuslan Bukin int sbr; 203*5c263f43SRuslan Bukin int brfa; 204*5c263f43SRuslan Bukin int reg; 205*5c263f43SRuslan Bukin 206*5c263f43SRuslan Bukin bas = &sc->sc_bas; 207*5c263f43SRuslan Bukin if (!bas) { 208*5c263f43SRuslan Bukin printf("Error: cant reconfigure bas\n"); 209*5c263f43SRuslan Bukin return; 210*5c263f43SRuslan Bukin } 211*5c263f43SRuslan Bukin 212*5c263f43SRuslan Bukin uart_setreg(bas, UART_MODEM, 0x00); 213*5c263f43SRuslan Bukin 214*5c263f43SRuslan Bukin /* 215*5c263f43SRuslan Bukin * Disable transmitter and receiver 216*5c263f43SRuslan Bukin * for a while. 217*5c263f43SRuslan Bukin */ 218*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 219*5c263f43SRuslan Bukin reg &= ~(UART_C2_RE | UART_C2_TE); 220*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, 0x00); 221*5c263f43SRuslan Bukin 222*5c263f43SRuslan Bukin uart_setreg(bas, UART_C1, 0x00); 223*5c263f43SRuslan Bukin 224*5c263f43SRuslan Bukin sbr = (uint16_t) (clkspeed / (baud * 16)); 225*5c263f43SRuslan Bukin brfa = (clkspeed / baud) - (sbr * 16); 226*5c263f43SRuslan Bukin 227*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_BDH); 228*5c263f43SRuslan Bukin reg &= ~UART_BDH_SBR; 229*5c263f43SRuslan Bukin reg |= ((sbr & 0x1f00) >> 8); 230*5c263f43SRuslan Bukin uart_setreg(bas, UART_BDH, reg); 231*5c263f43SRuslan Bukin 232*5c263f43SRuslan Bukin reg = sbr & 0x00ff; 233*5c263f43SRuslan Bukin uart_setreg(bas, UART_BDL, reg); 234*5c263f43SRuslan Bukin 235*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C4); 236*5c263f43SRuslan Bukin reg &= ~UART_C4_BRFA; 237*5c263f43SRuslan Bukin reg |= (brfa & UART_C4_BRFA); 238*5c263f43SRuslan Bukin uart_setreg(bas, UART_C4, reg); 239*5c263f43SRuslan Bukin 240*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 241*5c263f43SRuslan Bukin reg |= (UART_C2_RE | UART_C2_TE); 242*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg); 243*5c263f43SRuslan Bukin 244*5c263f43SRuslan Bukin } 245*5c263f43SRuslan Bukin 246*5c263f43SRuslan Bukin static int vf_uart_bus_attach(struct uart_softc *); 247*5c263f43SRuslan Bukin static int vf_uart_bus_detach(struct uart_softc *); 248*5c263f43SRuslan Bukin static int vf_uart_bus_flush(struct uart_softc *, int); 249*5c263f43SRuslan Bukin static int vf_uart_bus_getsig(struct uart_softc *); 250*5c263f43SRuslan Bukin static int vf_uart_bus_ioctl(struct uart_softc *, int, intptr_t); 251*5c263f43SRuslan Bukin static int vf_uart_bus_ipend(struct uart_softc *); 252*5c263f43SRuslan Bukin static int vf_uart_bus_param(struct uart_softc *, int, int, int, int); 253*5c263f43SRuslan Bukin static int vf_uart_bus_probe(struct uart_softc *); 254*5c263f43SRuslan Bukin static int vf_uart_bus_receive(struct uart_softc *); 255*5c263f43SRuslan Bukin static int vf_uart_bus_setsig(struct uart_softc *, int); 256*5c263f43SRuslan Bukin static int vf_uart_bus_transmit(struct uart_softc *); 257*5c263f43SRuslan Bukin 258*5c263f43SRuslan Bukin static kobj_method_t vf_uart_methods[] = { 259*5c263f43SRuslan Bukin KOBJMETHOD(uart_attach, vf_uart_bus_attach), 260*5c263f43SRuslan Bukin KOBJMETHOD(uart_detach, vf_uart_bus_detach), 261*5c263f43SRuslan Bukin KOBJMETHOD(uart_flush, vf_uart_bus_flush), 262*5c263f43SRuslan Bukin KOBJMETHOD(uart_getsig, vf_uart_bus_getsig), 263*5c263f43SRuslan Bukin KOBJMETHOD(uart_ioctl, vf_uart_bus_ioctl), 264*5c263f43SRuslan Bukin KOBJMETHOD(uart_ipend, vf_uart_bus_ipend), 265*5c263f43SRuslan Bukin KOBJMETHOD(uart_param, vf_uart_bus_param), 266*5c263f43SRuslan Bukin KOBJMETHOD(uart_probe, vf_uart_bus_probe), 267*5c263f43SRuslan Bukin KOBJMETHOD(uart_receive, vf_uart_bus_receive), 268*5c263f43SRuslan Bukin KOBJMETHOD(uart_setsig, vf_uart_bus_setsig), 269*5c263f43SRuslan Bukin KOBJMETHOD(uart_transmit, vf_uart_bus_transmit), 270*5c263f43SRuslan Bukin { 0, 0 } 271*5c263f43SRuslan Bukin }; 272*5c263f43SRuslan Bukin 273*5c263f43SRuslan Bukin struct uart_class uart_vybrid_class = { 274*5c263f43SRuslan Bukin "vybrid", 275*5c263f43SRuslan Bukin vf_uart_methods, 276*5c263f43SRuslan Bukin sizeof(struct vf_uart_softc), 277*5c263f43SRuslan Bukin .uc_ops = &uart_vybrid_ops, 278*5c263f43SRuslan Bukin .uc_range = 0x100, 279*5c263f43SRuslan Bukin .uc_rclk = 24000000 /* TODO: get value from CCM */ 280*5c263f43SRuslan Bukin }; 281*5c263f43SRuslan Bukin 282*5c263f43SRuslan Bukin static int 283*5c263f43SRuslan Bukin vf_uart_bus_attach(struct uart_softc *sc) 284*5c263f43SRuslan Bukin { 285*5c263f43SRuslan Bukin struct uart_bas *bas; 286*5c263f43SRuslan Bukin int reg; 287*5c263f43SRuslan Bukin 288*5c263f43SRuslan Bukin bas = &sc->sc_bas; 289*5c263f43SRuslan Bukin 290*5c263f43SRuslan Bukin sc->sc_hwiflow = 0; 291*5c263f43SRuslan Bukin sc->sc_hwoflow = 0; 292*5c263f43SRuslan Bukin 293*5c263f43SRuslan Bukin uart_reinit(sc, 66000000, 115200); 294*5c263f43SRuslan Bukin 295*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 296*5c263f43SRuslan Bukin if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { 297*5c263f43SRuslan Bukin reg &= ~UART_C2_RIE; 298*5c263f43SRuslan Bukin } else { 299*5c263f43SRuslan Bukin reg |= UART_C2_RIE; 300*5c263f43SRuslan Bukin } 301*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg); 302*5c263f43SRuslan Bukin 303*5c263f43SRuslan Bukin return (0); 304*5c263f43SRuslan Bukin } 305*5c263f43SRuslan Bukin 306*5c263f43SRuslan Bukin static int 307*5c263f43SRuslan Bukin vf_uart_bus_detach(struct uart_softc *sc) 308*5c263f43SRuslan Bukin { 309*5c263f43SRuslan Bukin 310*5c263f43SRuslan Bukin /* TODO */ 311*5c263f43SRuslan Bukin return (0); 312*5c263f43SRuslan Bukin } 313*5c263f43SRuslan Bukin 314*5c263f43SRuslan Bukin static int 315*5c263f43SRuslan Bukin vf_uart_bus_flush(struct uart_softc *sc, int what) 316*5c263f43SRuslan Bukin { 317*5c263f43SRuslan Bukin 318*5c263f43SRuslan Bukin /* TODO */ 319*5c263f43SRuslan Bukin return (0); 320*5c263f43SRuslan Bukin } 321*5c263f43SRuslan Bukin 322*5c263f43SRuslan Bukin static int 323*5c263f43SRuslan Bukin vf_uart_bus_getsig(struct uart_softc *sc) 324*5c263f43SRuslan Bukin { 325*5c263f43SRuslan Bukin 326*5c263f43SRuslan Bukin /* TODO */ 327*5c263f43SRuslan Bukin return (0); 328*5c263f43SRuslan Bukin } 329*5c263f43SRuslan Bukin 330*5c263f43SRuslan Bukin static int 331*5c263f43SRuslan Bukin vf_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 332*5c263f43SRuslan Bukin { 333*5c263f43SRuslan Bukin struct uart_bas *bas; 334*5c263f43SRuslan Bukin int error; 335*5c263f43SRuslan Bukin 336*5c263f43SRuslan Bukin bas = &sc->sc_bas; 337*5c263f43SRuslan Bukin error = 0; 338*5c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx); 339*5c263f43SRuslan Bukin switch (request) { 340*5c263f43SRuslan Bukin case UART_IOCTL_BREAK: 341*5c263f43SRuslan Bukin /* TODO */ 342*5c263f43SRuslan Bukin break; 343*5c263f43SRuslan Bukin case UART_IOCTL_BAUD: 344*5c263f43SRuslan Bukin /* TODO */ 345*5c263f43SRuslan Bukin *(int*)data = 115200; 346*5c263f43SRuslan Bukin break; 347*5c263f43SRuslan Bukin default: 348*5c263f43SRuslan Bukin error = EINVAL; 349*5c263f43SRuslan Bukin break; 350*5c263f43SRuslan Bukin } 351*5c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx); 352*5c263f43SRuslan Bukin 353*5c263f43SRuslan Bukin return (error); 354*5c263f43SRuslan Bukin } 355*5c263f43SRuslan Bukin 356*5c263f43SRuslan Bukin static int 357*5c263f43SRuslan Bukin vf_uart_bus_ipend(struct uart_softc *sc) 358*5c263f43SRuslan Bukin { 359*5c263f43SRuslan Bukin struct uart_bas *bas; 360*5c263f43SRuslan Bukin int ipend; 361*5c263f43SRuslan Bukin uint32_t usr1, usr2; 362*5c263f43SRuslan Bukin int reg; 363*5c263f43SRuslan Bukin int sfifo; 364*5c263f43SRuslan Bukin 365*5c263f43SRuslan Bukin bas = &sc->sc_bas; 366*5c263f43SRuslan Bukin ipend = 0; 367*5c263f43SRuslan Bukin 368*5c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx); 369*5c263f43SRuslan Bukin 370*5c263f43SRuslan Bukin usr1 = uart_getreg(bas, UART_S1); 371*5c263f43SRuslan Bukin usr2 = uart_getreg(bas, UART_S2); 372*5c263f43SRuslan Bukin sfifo = uart_getreg(bas, UART_SFIFO); 373*5c263f43SRuslan Bukin 374*5c263f43SRuslan Bukin /* ack usr2 */ 375*5c263f43SRuslan Bukin uart_setreg(bas, UART_S2, usr2); 376*5c263f43SRuslan Bukin 377*5c263f43SRuslan Bukin if (usr1 & UART_S1_TDRE) { 378*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 379*5c263f43SRuslan Bukin reg &= ~(UART_C2_TIE); 380*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg); 381*5c263f43SRuslan Bukin 382*5c263f43SRuslan Bukin if (sc->sc_txbusy != 0) { 383*5c263f43SRuslan Bukin ipend |= SER_INT_TXIDLE; 384*5c263f43SRuslan Bukin } 385*5c263f43SRuslan Bukin } 386*5c263f43SRuslan Bukin 387*5c263f43SRuslan Bukin if (usr1 & UART_S1_RDRF) { 388*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 389*5c263f43SRuslan Bukin reg &= ~(UART_C2_RIE); 390*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg); 391*5c263f43SRuslan Bukin 392*5c263f43SRuslan Bukin ipend |= SER_INT_RXREADY; 393*5c263f43SRuslan Bukin } 394*5c263f43SRuslan Bukin 395*5c263f43SRuslan Bukin if (usr2 & UART_S2_LBKDIF) { 396*5c263f43SRuslan Bukin ipend |= SER_INT_BREAK; 397*5c263f43SRuslan Bukin } 398*5c263f43SRuslan Bukin 399*5c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx); 400*5c263f43SRuslan Bukin 401*5c263f43SRuslan Bukin return (ipend); 402*5c263f43SRuslan Bukin } 403*5c263f43SRuslan Bukin 404*5c263f43SRuslan Bukin static int 405*5c263f43SRuslan Bukin vf_uart_bus_param(struct uart_softc *sc, int baudrate, int databits, 406*5c263f43SRuslan Bukin int stopbits, int parity) 407*5c263f43SRuslan Bukin { 408*5c263f43SRuslan Bukin 409*5c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx); 410*5c263f43SRuslan Bukin vf_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity); 411*5c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx); 412*5c263f43SRuslan Bukin 413*5c263f43SRuslan Bukin return (0); 414*5c263f43SRuslan Bukin } 415*5c263f43SRuslan Bukin 416*5c263f43SRuslan Bukin static int 417*5c263f43SRuslan Bukin vf_uart_bus_probe(struct uart_softc *sc) 418*5c263f43SRuslan Bukin { 419*5c263f43SRuslan Bukin int error; 420*5c263f43SRuslan Bukin 421*5c263f43SRuslan Bukin error = vf_uart_probe(&sc->sc_bas); 422*5c263f43SRuslan Bukin if (error) 423*5c263f43SRuslan Bukin return (error); 424*5c263f43SRuslan Bukin 425*5c263f43SRuslan Bukin sc->sc_rxfifosz = 1; 426*5c263f43SRuslan Bukin sc->sc_txfifosz = 1; 427*5c263f43SRuslan Bukin 428*5c263f43SRuslan Bukin device_set_desc(sc->sc_dev, "Vybrid Family UART"); 429*5c263f43SRuslan Bukin return (0); 430*5c263f43SRuslan Bukin } 431*5c263f43SRuslan Bukin 432*5c263f43SRuslan Bukin static int 433*5c263f43SRuslan Bukin vf_uart_bus_receive(struct uart_softc *sc) 434*5c263f43SRuslan Bukin { 435*5c263f43SRuslan Bukin struct uart_bas *bas; 436*5c263f43SRuslan Bukin int reg; 437*5c263f43SRuslan Bukin int c; 438*5c263f43SRuslan Bukin 439*5c263f43SRuslan Bukin bas = &sc->sc_bas; 440*5c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx); 441*5c263f43SRuslan Bukin 442*5c263f43SRuslan Bukin /* Read FIFO */ 443*5c263f43SRuslan Bukin while (uart_getreg(bas, UART_S1) & UART_S1_RDRF) { 444*5c263f43SRuslan Bukin if (uart_rx_full(sc)) { 445*5c263f43SRuslan Bukin /* No space left in input buffer */ 446*5c263f43SRuslan Bukin sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 447*5c263f43SRuslan Bukin break; 448*5c263f43SRuslan Bukin } 449*5c263f43SRuslan Bukin 450*5c263f43SRuslan Bukin c = uart_getreg(bas, UART_D); 451*5c263f43SRuslan Bukin uart_rx_put(sc, c); 452*5c263f43SRuslan Bukin } 453*5c263f43SRuslan Bukin 454*5c263f43SRuslan Bukin /* Reenable Data Ready interrupt */ 455*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 456*5c263f43SRuslan Bukin reg |= (UART_C2_RIE); 457*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg); 458*5c263f43SRuslan Bukin 459*5c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx); 460*5c263f43SRuslan Bukin return (0); 461*5c263f43SRuslan Bukin } 462*5c263f43SRuslan Bukin 463*5c263f43SRuslan Bukin static int 464*5c263f43SRuslan Bukin vf_uart_bus_setsig(struct uart_softc *sc, int sig) 465*5c263f43SRuslan Bukin { 466*5c263f43SRuslan Bukin struct uart_bas *bas; 467*5c263f43SRuslan Bukin int reg; 468*5c263f43SRuslan Bukin 469*5c263f43SRuslan Bukin /* TODO: implement (?) */ 470*5c263f43SRuslan Bukin 471*5c263f43SRuslan Bukin /* XXX workaround to have working console on mount prompt */ 472*5c263f43SRuslan Bukin /* Enable RX interrupt */ 473*5c263f43SRuslan Bukin bas = &sc->sc_bas; 474*5c263f43SRuslan Bukin if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { 475*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 476*5c263f43SRuslan Bukin reg |= (UART_C2_RIE); 477*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg); 478*5c263f43SRuslan Bukin } 479*5c263f43SRuslan Bukin 480*5c263f43SRuslan Bukin return (0); 481*5c263f43SRuslan Bukin } 482*5c263f43SRuslan Bukin 483*5c263f43SRuslan Bukin static int 484*5c263f43SRuslan Bukin vf_uart_bus_transmit(struct uart_softc *sc) 485*5c263f43SRuslan Bukin { 486*5c263f43SRuslan Bukin struct uart_bas *bas = &sc->sc_bas; 487*5c263f43SRuslan Bukin int i; 488*5c263f43SRuslan Bukin int reg; 489*5c263f43SRuslan Bukin 490*5c263f43SRuslan Bukin bas = &sc->sc_bas; 491*5c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx); 492*5c263f43SRuslan Bukin 493*5c263f43SRuslan Bukin /* Fill TX FIFO */ 494*5c263f43SRuslan Bukin for (i = 0; i < sc->sc_txdatasz; i++) { 495*5c263f43SRuslan Bukin uart_setreg(bas, UART_D, sc->sc_txbuf[i] & 0xff); 496*5c263f43SRuslan Bukin uart_barrier(&sc->sc_bas); 497*5c263f43SRuslan Bukin } 498*5c263f43SRuslan Bukin 499*5c263f43SRuslan Bukin sc->sc_txbusy = 1; 500*5c263f43SRuslan Bukin 501*5c263f43SRuslan Bukin /* Call me when ready */ 502*5c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2); 503*5c263f43SRuslan Bukin reg |= (UART_C2_TIE); 504*5c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg); 505*5c263f43SRuslan Bukin 506*5c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx); 507*5c263f43SRuslan Bukin 508*5c263f43SRuslan Bukin return (0); 509*5c263f43SRuslan Bukin } 510