15c263f43SRuslan Bukin /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3af3dc4a7SPedro F. Giffuni *
45c263f43SRuslan Bukin * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
55c263f43SRuslan Bukin * All rights reserved.
65c263f43SRuslan Bukin *
75c263f43SRuslan Bukin * Redistribution and use in source and binary forms, with or without
85c263f43SRuslan Bukin * modification, are permitted provided that the following conditions
95c263f43SRuslan Bukin * are met:
105c263f43SRuslan Bukin * 1. Redistributions of source code must retain the above copyright
115c263f43SRuslan Bukin * notice, this list of conditions and the following disclaimer.
125c263f43SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright
135c263f43SRuslan Bukin * notice, this list of conditions and the following disclaimer in the
145c263f43SRuslan Bukin * documentation and/or other materials provided with the distribution.
155c263f43SRuslan Bukin *
165c263f43SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
175c263f43SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
185c263f43SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
195c263f43SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
205c263f43SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215c263f43SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
225c263f43SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
235c263f43SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
245c263f43SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
255c263f43SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
265c263f43SRuslan Bukin * SUCH DAMAGE.
275c263f43SRuslan Bukin */
285c263f43SRuslan Bukin
295c263f43SRuslan Bukin /*
305c263f43SRuslan Bukin * Vybrid Family Universal Asynchronous Receiver/Transmitter
315c263f43SRuslan Bukin * Chapter 49, Vybrid Reference Manual, Rev. 5, 07/2013
325c263f43SRuslan Bukin */
335c263f43SRuslan Bukin
345c263f43SRuslan Bukin #include <sys/cdefs.h>
355c263f43SRuslan Bukin #include "opt_ddb.h"
365c263f43SRuslan Bukin
375c263f43SRuslan Bukin #include <sys/param.h>
385c263f43SRuslan Bukin #include <sys/systm.h>
395c263f43SRuslan Bukin #include <sys/bus.h>
405c263f43SRuslan Bukin #include <sys/conf.h>
415c263f43SRuslan Bukin #include <sys/kdb.h>
425c263f43SRuslan Bukin #include <machine/bus.h>
435c263f43SRuslan Bukin
445c263f43SRuslan Bukin #include <dev/uart/uart.h>
455c263f43SRuslan Bukin #include <dev/uart/uart_cpu.h>
463bb693afSIan Lepore #include <dev/uart/uart_cpu_fdt.h>
475c263f43SRuslan Bukin #include <dev/uart/uart_bus.h>
485c263f43SRuslan Bukin
495c263f43SRuslan Bukin #include "uart_if.h"
505c263f43SRuslan Bukin
515c263f43SRuslan Bukin #define UART_BDH 0x00 /* Baud Rate Registers: High */
525c263f43SRuslan Bukin #define UART_BDL 0x01 /* Baud Rate Registers: Low */
535c263f43SRuslan Bukin #define UART_C1 0x02 /* Control Register 1 */
545c263f43SRuslan Bukin #define UART_C2 0x03 /* Control Register 2 */
555c263f43SRuslan Bukin #define UART_S1 0x04 /* Status Register 1 */
565c263f43SRuslan Bukin #define UART_S2 0x05 /* Status Register 2 */
575c263f43SRuslan Bukin #define UART_C3 0x06 /* Control Register 3 */
585c263f43SRuslan Bukin #define UART_D 0x07 /* Data Register */
595c263f43SRuslan Bukin #define UART_MA1 0x08 /* Match Address Registers 1 */
605c263f43SRuslan Bukin #define UART_MA2 0x09 /* Match Address Registers 2 */
615c263f43SRuslan Bukin #define UART_C4 0x0A /* Control Register 4 */
625c263f43SRuslan Bukin #define UART_C5 0x0B /* Control Register 5 */
635c263f43SRuslan Bukin #define UART_ED 0x0C /* Extended Data Register */
645c263f43SRuslan Bukin #define UART_MODEM 0x0D /* Modem Register */
655c263f43SRuslan Bukin #define UART_IR 0x0E /* Infrared Register */
665c263f43SRuslan Bukin #define UART_PFIFO 0x10 /* FIFO Parameters */
675c263f43SRuslan Bukin #define UART_CFIFO 0x11 /* FIFO Control Register */
685c263f43SRuslan Bukin #define UART_SFIFO 0x12 /* FIFO Status Register */
695c263f43SRuslan Bukin #define UART_TWFIFO 0x13 /* FIFO Transmit Watermark */
705c263f43SRuslan Bukin #define UART_TCFIFO 0x14 /* FIFO Transmit Count */
715c263f43SRuslan Bukin #define UART_RWFIFO 0x15 /* FIFO Receive Watermark */
725c263f43SRuslan Bukin #define UART_RCFIFO 0x16 /* FIFO Receive Count */
735c263f43SRuslan Bukin #define UART_C7816 0x18 /* 7816 Control Register */
745c263f43SRuslan Bukin #define UART_IE7816 0x19 /* 7816 Interrupt Enable Register */
755c263f43SRuslan Bukin #define UART_IS7816 0x1A /* 7816 Interrupt Status Register */
765c263f43SRuslan Bukin #define UART_WP7816T0 0x1B /* 7816 Wait Parameter Register */
775c263f43SRuslan Bukin #define UART_WP7816T1 0x1B /* 7816 Wait Parameter Register */
785c263f43SRuslan Bukin #define UART_WN7816 0x1C /* 7816 Wait N Register */
795c263f43SRuslan Bukin #define UART_WF7816 0x1D /* 7816 Wait FD Register */
805c263f43SRuslan Bukin #define UART_ET7816 0x1E /* 7816 Error Threshold Register */
815c263f43SRuslan Bukin #define UART_TL7816 0x1F /* 7816 Transmit Length Register */
825c263f43SRuslan Bukin #define UART_C6 0x21 /* CEA709.1-B Control Register 6 */
835c263f43SRuslan Bukin #define UART_PCTH 0x22 /* CEA709.1-B Packet Cycle Time Counter High */
845c263f43SRuslan Bukin #define UART_PCTL 0x23 /* CEA709.1-B Packet Cycle Time Counter Low */
855c263f43SRuslan Bukin #define UART_B1T 0x24 /* CEA709.1-B Beta1 Timer */
865c263f43SRuslan Bukin #define UART_SDTH 0x25 /* CEA709.1-B Secondary Delay Timer High */
875c263f43SRuslan Bukin #define UART_SDTL 0x26 /* CEA709.1-B Secondary Delay Timer Low */
885c263f43SRuslan Bukin #define UART_PRE 0x27 /* CEA709.1-B Preamble */
895c263f43SRuslan Bukin #define UART_TPL 0x28 /* CEA709.1-B Transmit Packet Length */
905c263f43SRuslan Bukin #define UART_IE 0x29 /* CEA709.1-B Interrupt Enable Register */
915c263f43SRuslan Bukin #define UART_WB 0x2A /* CEA709.1-B WBASE */
925c263f43SRuslan Bukin #define UART_S3 0x2B /* CEA709.1-B Status Register */
935c263f43SRuslan Bukin #define UART_S4 0x2C /* CEA709.1-B Status Register */
945c263f43SRuslan Bukin #define UART_RPL 0x2D /* CEA709.1-B Received Packet Length */
955c263f43SRuslan Bukin #define UART_RPREL 0x2E /* CEA709.1-B Received Preamble Length */
965c263f43SRuslan Bukin #define UART_CPW 0x2F /* CEA709.1-B Collision Pulse Width */
975c263f43SRuslan Bukin #define UART_RIDT 0x30 /* CEA709.1-B Receive Indeterminate Time */
985c263f43SRuslan Bukin #define UART_TIDT 0x31 /* CEA709.1-B Transmit Indeterminate Time */
995c263f43SRuslan Bukin
1005c263f43SRuslan Bukin #define UART_C2_TE (1 << 3) /* Transmitter Enable */
1015c263f43SRuslan Bukin #define UART_C2_TIE (1 << 7) /* Transmitter Interrupt Enable */
1025c263f43SRuslan Bukin #define UART_C2_RE (1 << 2) /* Receiver Enable */
1035c263f43SRuslan Bukin #define UART_C2_RIE (1 << 5) /* Receiver Interrupt Enable */
1045c263f43SRuslan Bukin #define UART_S1_TDRE (1 << 7) /* Transmit Data Register Empty Flag */
1055c263f43SRuslan Bukin #define UART_S1_RDRF (1 << 5) /* Receive Data Register Full Flag */
1065c263f43SRuslan Bukin #define UART_S2_LBKDIF (1 << 7) /* LIN Break Detect Interrupt Flag */
1075c263f43SRuslan Bukin
1085c263f43SRuslan Bukin #define UART_C4_BRFA 0x1f /* Baud Rate Fine Adjust */
1095c263f43SRuslan Bukin #define UART_BDH_SBR 0x1f /* UART Baud Rate Bits */
1105c263f43SRuslan Bukin
1115c263f43SRuslan Bukin /*
1125c263f43SRuslan Bukin * Low-level UART interface.
1135c263f43SRuslan Bukin */
1145c263f43SRuslan Bukin static int vf_uart_probe(struct uart_bas *bas);
1155c263f43SRuslan Bukin static void vf_uart_init(struct uart_bas *bas, int, int, int, int);
1165c263f43SRuslan Bukin static void vf_uart_term(struct uart_bas *bas);
1175c263f43SRuslan Bukin static void vf_uart_putc(struct uart_bas *bas, int);
1185c263f43SRuslan Bukin static int vf_uart_rxready(struct uart_bas *bas);
1195c263f43SRuslan Bukin static int vf_uart_getc(struct uart_bas *bas, struct mtx *);
1205c263f43SRuslan Bukin
1215c263f43SRuslan Bukin void uart_reinit(struct uart_softc *,int,int);
1225c263f43SRuslan Bukin
1235c263f43SRuslan Bukin static struct uart_ops uart_vybrid_ops = {
1245c263f43SRuslan Bukin .probe = vf_uart_probe,
1255c263f43SRuslan Bukin .init = vf_uart_init,
1265c263f43SRuslan Bukin .term = vf_uart_term,
1275c263f43SRuslan Bukin .putc = vf_uart_putc,
1285c263f43SRuslan Bukin .rxready = vf_uart_rxready,
1295c263f43SRuslan Bukin .getc = vf_uart_getc,
1305c263f43SRuslan Bukin };
1315c263f43SRuslan Bukin
1325c263f43SRuslan Bukin static int
vf_uart_probe(struct uart_bas * bas)1335c263f43SRuslan Bukin vf_uart_probe(struct uart_bas *bas)
1345c263f43SRuslan Bukin {
1355c263f43SRuslan Bukin
1365c263f43SRuslan Bukin return (0);
1375c263f43SRuslan Bukin }
1385c263f43SRuslan Bukin
1395c263f43SRuslan Bukin static void
vf_uart_init(struct uart_bas * bas,int baudrate,int databits,int stopbits,int parity)1405c263f43SRuslan Bukin vf_uart_init(struct uart_bas *bas, int baudrate, int databits,
1415c263f43SRuslan Bukin int stopbits, int parity)
1425c263f43SRuslan Bukin {
1435c263f43SRuslan Bukin
1445c263f43SRuslan Bukin }
1455c263f43SRuslan Bukin
1465c263f43SRuslan Bukin static void
vf_uart_term(struct uart_bas * bas)1475c263f43SRuslan Bukin vf_uart_term(struct uart_bas *bas)
1485c263f43SRuslan Bukin {
1495c263f43SRuslan Bukin
1505c263f43SRuslan Bukin }
1515c263f43SRuslan Bukin
1525c263f43SRuslan Bukin static void
vf_uart_putc(struct uart_bas * bas,int c)1535c263f43SRuslan Bukin vf_uart_putc(struct uart_bas *bas, int c)
1545c263f43SRuslan Bukin {
1555c263f43SRuslan Bukin
1565c263f43SRuslan Bukin while (!(uart_getreg(bas, UART_S1) & UART_S1_TDRE))
1575c263f43SRuslan Bukin ;
1585c263f43SRuslan Bukin
1595c263f43SRuslan Bukin uart_setreg(bas, UART_D, c);
1605c263f43SRuslan Bukin }
1615c263f43SRuslan Bukin
1625c263f43SRuslan Bukin static int
vf_uart_rxready(struct uart_bas * bas)1635c263f43SRuslan Bukin vf_uart_rxready(struct uart_bas *bas)
1645c263f43SRuslan Bukin {
1655c263f43SRuslan Bukin int usr1;
1665c263f43SRuslan Bukin
1675c263f43SRuslan Bukin usr1 = uart_getreg(bas, UART_S1);
1685c263f43SRuslan Bukin if (usr1 & UART_S1_RDRF) {
1695c263f43SRuslan Bukin return (1);
1705c263f43SRuslan Bukin }
1715c263f43SRuslan Bukin
1725c263f43SRuslan Bukin return (0);
1735c263f43SRuslan Bukin }
1745c263f43SRuslan Bukin
1755c263f43SRuslan Bukin static int
vf_uart_getc(struct uart_bas * bas,struct mtx * hwmtx)1765c263f43SRuslan Bukin vf_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
1775c263f43SRuslan Bukin {
1785c263f43SRuslan Bukin int c;
1795c263f43SRuslan Bukin
1805c263f43SRuslan Bukin uart_lock(hwmtx);
1815c263f43SRuslan Bukin
1825c263f43SRuslan Bukin while (!(uart_getreg(bas, UART_S1) & UART_S1_RDRF))
1835c263f43SRuslan Bukin ;
1845c263f43SRuslan Bukin
1855c263f43SRuslan Bukin c = uart_getreg(bas, UART_D);
1865c263f43SRuslan Bukin uart_unlock(hwmtx);
1875c263f43SRuslan Bukin
1885c263f43SRuslan Bukin return (c & 0xff);
1895c263f43SRuslan Bukin }
1905c263f43SRuslan Bukin
1915c263f43SRuslan Bukin /*
1925c263f43SRuslan Bukin * High-level UART interface.
1935c263f43SRuslan Bukin */
1945c263f43SRuslan Bukin struct vf_uart_softc {
1955c263f43SRuslan Bukin struct uart_softc base;
1965c263f43SRuslan Bukin };
1975c263f43SRuslan Bukin
1985c263f43SRuslan Bukin void
uart_reinit(struct uart_softc * sc,int clkspeed,int baud)1995c263f43SRuslan Bukin uart_reinit(struct uart_softc *sc, int clkspeed, int baud)
2005c263f43SRuslan Bukin {
2015c263f43SRuslan Bukin struct uart_bas *bas;
2025c263f43SRuslan Bukin int sbr;
2035c263f43SRuslan Bukin int brfa;
2045c263f43SRuslan Bukin int reg;
2055c263f43SRuslan Bukin
2065c263f43SRuslan Bukin bas = &sc->sc_bas;
2075c263f43SRuslan Bukin if (!bas) {
208255eff3bSPedro F. Giffuni printf("Error: can't reconfigure bas\n");
2095c263f43SRuslan Bukin return;
2105c263f43SRuslan Bukin }
2115c263f43SRuslan Bukin
2125c263f43SRuslan Bukin uart_setreg(bas, UART_MODEM, 0x00);
2135c263f43SRuslan Bukin
2145c263f43SRuslan Bukin /*
2155c263f43SRuslan Bukin * Disable transmitter and receiver
2165c263f43SRuslan Bukin * for a while.
2175c263f43SRuslan Bukin */
2185c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
2195c263f43SRuslan Bukin reg &= ~(UART_C2_RE | UART_C2_TE);
2205c263f43SRuslan Bukin uart_setreg(bas, UART_C2, 0x00);
2215c263f43SRuslan Bukin
2225c263f43SRuslan Bukin uart_setreg(bas, UART_C1, 0x00);
2235c263f43SRuslan Bukin
2245c263f43SRuslan Bukin sbr = (uint16_t) (clkspeed / (baud * 16));
2255c263f43SRuslan Bukin brfa = (clkspeed / baud) - (sbr * 16);
2265c263f43SRuslan Bukin
2275c263f43SRuslan Bukin reg = uart_getreg(bas, UART_BDH);
2285c263f43SRuslan Bukin reg &= ~UART_BDH_SBR;
2295c263f43SRuslan Bukin reg |= ((sbr & 0x1f00) >> 8);
2305c263f43SRuslan Bukin uart_setreg(bas, UART_BDH, reg);
2315c263f43SRuslan Bukin
2325c263f43SRuslan Bukin reg = sbr & 0x00ff;
2335c263f43SRuslan Bukin uart_setreg(bas, UART_BDL, reg);
2345c263f43SRuslan Bukin
2355c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C4);
2365c263f43SRuslan Bukin reg &= ~UART_C4_BRFA;
2375c263f43SRuslan Bukin reg |= (brfa & UART_C4_BRFA);
2385c263f43SRuslan Bukin uart_setreg(bas, UART_C4, reg);
2395c263f43SRuslan Bukin
2405c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
2415c263f43SRuslan Bukin reg |= (UART_C2_RE | UART_C2_TE);
2425c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg);
2435c263f43SRuslan Bukin
2445c263f43SRuslan Bukin }
2455c263f43SRuslan Bukin
2465c263f43SRuslan Bukin static int vf_uart_bus_attach(struct uart_softc *);
2475c263f43SRuslan Bukin static int vf_uart_bus_detach(struct uart_softc *);
2485c263f43SRuslan Bukin static int vf_uart_bus_flush(struct uart_softc *, int);
2495c263f43SRuslan Bukin static int vf_uart_bus_getsig(struct uart_softc *);
2505c263f43SRuslan Bukin static int vf_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
2515c263f43SRuslan Bukin static int vf_uart_bus_ipend(struct uart_softc *);
2525c263f43SRuslan Bukin static int vf_uart_bus_param(struct uart_softc *, int, int, int, int);
2535c263f43SRuslan Bukin static int vf_uart_bus_probe(struct uart_softc *);
2545c263f43SRuslan Bukin static int vf_uart_bus_receive(struct uart_softc *);
2555c263f43SRuslan Bukin static int vf_uart_bus_setsig(struct uart_softc *, int);
2565c263f43SRuslan Bukin static int vf_uart_bus_transmit(struct uart_softc *);
2575c263f43SRuslan Bukin
2585c263f43SRuslan Bukin static kobj_method_t vf_uart_methods[] = {
2595c263f43SRuslan Bukin KOBJMETHOD(uart_attach, vf_uart_bus_attach),
2605c263f43SRuslan Bukin KOBJMETHOD(uart_detach, vf_uart_bus_detach),
2615c263f43SRuslan Bukin KOBJMETHOD(uart_flush, vf_uart_bus_flush),
2625c263f43SRuslan Bukin KOBJMETHOD(uart_getsig, vf_uart_bus_getsig),
2635c263f43SRuslan Bukin KOBJMETHOD(uart_ioctl, vf_uart_bus_ioctl),
2645c263f43SRuslan Bukin KOBJMETHOD(uart_ipend, vf_uart_bus_ipend),
2655c263f43SRuslan Bukin KOBJMETHOD(uart_param, vf_uart_bus_param),
2665c263f43SRuslan Bukin KOBJMETHOD(uart_probe, vf_uart_bus_probe),
2675c263f43SRuslan Bukin KOBJMETHOD(uart_receive, vf_uart_bus_receive),
2685c263f43SRuslan Bukin KOBJMETHOD(uart_setsig, vf_uart_bus_setsig),
2695c263f43SRuslan Bukin KOBJMETHOD(uart_transmit, vf_uart_bus_transmit),
2705c263f43SRuslan Bukin { 0, 0 }
2715c263f43SRuslan Bukin };
2725c263f43SRuslan Bukin
2733bb693afSIan Lepore static struct uart_class uart_vybrid_class = {
2745c263f43SRuslan Bukin "vybrid",
2755c263f43SRuslan Bukin vf_uart_methods,
2765c263f43SRuslan Bukin sizeof(struct vf_uart_softc),
2775c263f43SRuslan Bukin .uc_ops = &uart_vybrid_ops,
2785c263f43SRuslan Bukin .uc_range = 0x100,
279405ada37SAndrew Turner .uc_rclk = 24000000, /* TODO: get value from CCM */
280405ada37SAndrew Turner .uc_rshift = 0
2815c263f43SRuslan Bukin };
2825c263f43SRuslan Bukin
2833bb693afSIan Lepore static struct ofw_compat_data compat_data[] = {
2843bb693afSIan Lepore {"fsl,mvf600-uart", (uintptr_t)&uart_vybrid_class},
2853bb693afSIan Lepore {NULL, (uintptr_t)NULL},
2863bb693afSIan Lepore };
2873bb693afSIan Lepore UART_FDT_CLASS_AND_DEVICE(compat_data);
2883bb693afSIan Lepore
2895c263f43SRuslan Bukin static int
vf_uart_bus_attach(struct uart_softc * sc)2905c263f43SRuslan Bukin vf_uart_bus_attach(struct uart_softc *sc)
2915c263f43SRuslan Bukin {
2925c263f43SRuslan Bukin struct uart_bas *bas;
2935c263f43SRuslan Bukin int reg;
2945c263f43SRuslan Bukin
2955c263f43SRuslan Bukin bas = &sc->sc_bas;
2965c263f43SRuslan Bukin
2975c263f43SRuslan Bukin sc->sc_hwiflow = 0;
2985c263f43SRuslan Bukin sc->sc_hwoflow = 0;
2995c263f43SRuslan Bukin
3005c263f43SRuslan Bukin uart_reinit(sc, 66000000, 115200);
3015c263f43SRuslan Bukin
3025c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
3035c263f43SRuslan Bukin if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
3045c263f43SRuslan Bukin reg &= ~UART_C2_RIE;
3055c263f43SRuslan Bukin } else {
3065c263f43SRuslan Bukin reg |= UART_C2_RIE;
3075c263f43SRuslan Bukin }
3085c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg);
3095c263f43SRuslan Bukin
3105c263f43SRuslan Bukin return (0);
3115c263f43SRuslan Bukin }
3125c263f43SRuslan Bukin
3135c263f43SRuslan Bukin static int
vf_uart_bus_detach(struct uart_softc * sc)3145c263f43SRuslan Bukin vf_uart_bus_detach(struct uart_softc *sc)
3155c263f43SRuslan Bukin {
3165c263f43SRuslan Bukin
3175c263f43SRuslan Bukin /* TODO */
3185c263f43SRuslan Bukin return (0);
3195c263f43SRuslan Bukin }
3205c263f43SRuslan Bukin
3215c263f43SRuslan Bukin static int
vf_uart_bus_flush(struct uart_softc * sc,int what)3225c263f43SRuslan Bukin vf_uart_bus_flush(struct uart_softc *sc, int what)
3235c263f43SRuslan Bukin {
3245c263f43SRuslan Bukin
3255c263f43SRuslan Bukin /* TODO */
3265c263f43SRuslan Bukin return (0);
3275c263f43SRuslan Bukin }
3285c263f43SRuslan Bukin
3295c263f43SRuslan Bukin static int
vf_uart_bus_getsig(struct uart_softc * sc)3305c263f43SRuslan Bukin vf_uart_bus_getsig(struct uart_softc *sc)
3315c263f43SRuslan Bukin {
3325c263f43SRuslan Bukin
3335c263f43SRuslan Bukin /* TODO */
3345c263f43SRuslan Bukin return (0);
3355c263f43SRuslan Bukin }
3365c263f43SRuslan Bukin
3375c263f43SRuslan Bukin static int
vf_uart_bus_ioctl(struct uart_softc * sc,int request,intptr_t data)3385c263f43SRuslan Bukin vf_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
3395c263f43SRuslan Bukin {
3405c263f43SRuslan Bukin int error;
3415c263f43SRuslan Bukin
3425c263f43SRuslan Bukin error = 0;
3435c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx);
3445c263f43SRuslan Bukin switch (request) {
3455c263f43SRuslan Bukin case UART_IOCTL_BREAK:
3465c263f43SRuslan Bukin /* TODO */
3475c263f43SRuslan Bukin break;
3485c263f43SRuslan Bukin case UART_IOCTL_BAUD:
3495c263f43SRuslan Bukin /* TODO */
3505c263f43SRuslan Bukin *(int*)data = 115200;
3515c263f43SRuslan Bukin break;
3525c263f43SRuslan Bukin default:
3535c263f43SRuslan Bukin error = EINVAL;
3545c263f43SRuslan Bukin break;
3555c263f43SRuslan Bukin }
3565c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx);
3575c263f43SRuslan Bukin
3585c263f43SRuslan Bukin return (error);
3595c263f43SRuslan Bukin }
3605c263f43SRuslan Bukin
3615c263f43SRuslan Bukin static int
vf_uart_bus_ipend(struct uart_softc * sc)3625c263f43SRuslan Bukin vf_uart_bus_ipend(struct uart_softc *sc)
3635c263f43SRuslan Bukin {
3645c263f43SRuslan Bukin struct uart_bas *bas;
3655c263f43SRuslan Bukin int ipend;
3665c263f43SRuslan Bukin uint32_t usr1, usr2;
3675c263f43SRuslan Bukin int reg;
3685c263f43SRuslan Bukin
3695c263f43SRuslan Bukin bas = &sc->sc_bas;
3705c263f43SRuslan Bukin ipend = 0;
3715c263f43SRuslan Bukin
3725c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx);
3735c263f43SRuslan Bukin
3745c263f43SRuslan Bukin usr1 = uart_getreg(bas, UART_S1);
3755c263f43SRuslan Bukin usr2 = uart_getreg(bas, UART_S2);
37643629a8bSJohn Baldwin (void)uart_getreg(bas, UART_SFIFO);
3775c263f43SRuslan Bukin
3785c263f43SRuslan Bukin /* ack usr2 */
3795c263f43SRuslan Bukin uart_setreg(bas, UART_S2, usr2);
3805c263f43SRuslan Bukin
3815c263f43SRuslan Bukin if (usr1 & UART_S1_TDRE) {
3825c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
3835c263f43SRuslan Bukin reg &= ~(UART_C2_TIE);
3845c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg);
3855c263f43SRuslan Bukin
3865c263f43SRuslan Bukin if (sc->sc_txbusy != 0) {
3875c263f43SRuslan Bukin ipend |= SER_INT_TXIDLE;
3885c263f43SRuslan Bukin }
3895c263f43SRuslan Bukin }
3905c263f43SRuslan Bukin
3915c263f43SRuslan Bukin if (usr1 & UART_S1_RDRF) {
3925c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
3935c263f43SRuslan Bukin reg &= ~(UART_C2_RIE);
3945c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg);
3955c263f43SRuslan Bukin
3965c263f43SRuslan Bukin ipend |= SER_INT_RXREADY;
3975c263f43SRuslan Bukin }
3985c263f43SRuslan Bukin
3995c263f43SRuslan Bukin if (usr2 & UART_S2_LBKDIF) {
4005c263f43SRuslan Bukin ipend |= SER_INT_BREAK;
4015c263f43SRuslan Bukin }
4025c263f43SRuslan Bukin
4035c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx);
4045c263f43SRuslan Bukin
4055c263f43SRuslan Bukin return (ipend);
4065c263f43SRuslan Bukin }
4075c263f43SRuslan Bukin
4085c263f43SRuslan Bukin static int
vf_uart_bus_param(struct uart_softc * sc,int baudrate,int databits,int stopbits,int parity)4095c263f43SRuslan Bukin vf_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
4105c263f43SRuslan Bukin int stopbits, int parity)
4115c263f43SRuslan Bukin {
4125c263f43SRuslan Bukin
4135c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx);
4145c263f43SRuslan Bukin vf_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity);
4155c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx);
4165c263f43SRuslan Bukin
4175c263f43SRuslan Bukin return (0);
4185c263f43SRuslan Bukin }
4195c263f43SRuslan Bukin
4205c263f43SRuslan Bukin static int
vf_uart_bus_probe(struct uart_softc * sc)4215c263f43SRuslan Bukin vf_uart_bus_probe(struct uart_softc *sc)
4225c263f43SRuslan Bukin {
4235c263f43SRuslan Bukin int error;
4245c263f43SRuslan Bukin
4255c263f43SRuslan Bukin error = vf_uart_probe(&sc->sc_bas);
4265c263f43SRuslan Bukin if (error)
4275c263f43SRuslan Bukin return (error);
4285c263f43SRuslan Bukin
4295c263f43SRuslan Bukin sc->sc_rxfifosz = 1;
4305c263f43SRuslan Bukin sc->sc_txfifosz = 1;
4315c263f43SRuslan Bukin
4325c263f43SRuslan Bukin device_set_desc(sc->sc_dev, "Vybrid Family UART");
4335c263f43SRuslan Bukin return (0);
4345c263f43SRuslan Bukin }
4355c263f43SRuslan Bukin
4365c263f43SRuslan Bukin static int
vf_uart_bus_receive(struct uart_softc * sc)4375c263f43SRuslan Bukin vf_uart_bus_receive(struct uart_softc *sc)
4385c263f43SRuslan Bukin {
4395c263f43SRuslan Bukin struct uart_bas *bas;
4405c263f43SRuslan Bukin int reg;
4415c263f43SRuslan Bukin int c;
4425c263f43SRuslan Bukin
4435c263f43SRuslan Bukin bas = &sc->sc_bas;
4445c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx);
4455c263f43SRuslan Bukin
4465c263f43SRuslan Bukin /* Read FIFO */
4475c263f43SRuslan Bukin while (uart_getreg(bas, UART_S1) & UART_S1_RDRF) {
4485c263f43SRuslan Bukin if (uart_rx_full(sc)) {
4495c263f43SRuslan Bukin /* No space left in input buffer */
4505c263f43SRuslan Bukin sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
4515c263f43SRuslan Bukin break;
4525c263f43SRuslan Bukin }
4535c263f43SRuslan Bukin
4545c263f43SRuslan Bukin c = uart_getreg(bas, UART_D);
4555c263f43SRuslan Bukin uart_rx_put(sc, c);
4565c263f43SRuslan Bukin }
4575c263f43SRuslan Bukin
4585c263f43SRuslan Bukin /* Reenable Data Ready interrupt */
4595c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
4605c263f43SRuslan Bukin reg |= (UART_C2_RIE);
4615c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg);
4625c263f43SRuslan Bukin
4635c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx);
4645c263f43SRuslan Bukin return (0);
4655c263f43SRuslan Bukin }
4665c263f43SRuslan Bukin
4675c263f43SRuslan Bukin static int
vf_uart_bus_setsig(struct uart_softc * sc,int sig)4685c263f43SRuslan Bukin vf_uart_bus_setsig(struct uart_softc *sc, int sig)
4695c263f43SRuslan Bukin {
4705c263f43SRuslan Bukin struct uart_bas *bas;
4715c263f43SRuslan Bukin int reg;
4725c263f43SRuslan Bukin
4735c263f43SRuslan Bukin /* TODO: implement (?) */
4745c263f43SRuslan Bukin
4755c263f43SRuslan Bukin /* XXX workaround to have working console on mount prompt */
4765c263f43SRuslan Bukin /* Enable RX interrupt */
4775c263f43SRuslan Bukin bas = &sc->sc_bas;
4785c263f43SRuslan Bukin if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
4795c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
4805c263f43SRuslan Bukin reg |= (UART_C2_RIE);
4815c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg);
4825c263f43SRuslan Bukin }
4835c263f43SRuslan Bukin
4845c263f43SRuslan Bukin return (0);
4855c263f43SRuslan Bukin }
4865c263f43SRuslan Bukin
4875c263f43SRuslan Bukin static int
vf_uart_bus_transmit(struct uart_softc * sc)4885c263f43SRuslan Bukin vf_uart_bus_transmit(struct uart_softc *sc)
4895c263f43SRuslan Bukin {
4905c263f43SRuslan Bukin struct uart_bas *bas = &sc->sc_bas;
4915c263f43SRuslan Bukin int i;
4925c263f43SRuslan Bukin int reg;
4935c263f43SRuslan Bukin
4945c263f43SRuslan Bukin bas = &sc->sc_bas;
4955c263f43SRuslan Bukin uart_lock(sc->sc_hwmtx);
4965c263f43SRuslan Bukin
4975c263f43SRuslan Bukin /* Fill TX FIFO */
4985c263f43SRuslan Bukin for (i = 0; i < sc->sc_txdatasz; i++) {
4995c263f43SRuslan Bukin uart_setreg(bas, UART_D, sc->sc_txbuf[i] & 0xff);
5005c263f43SRuslan Bukin uart_barrier(&sc->sc_bas);
5015c263f43SRuslan Bukin }
5025c263f43SRuslan Bukin
5035c263f43SRuslan Bukin sc->sc_txbusy = 1;
5045c263f43SRuslan Bukin
5055c263f43SRuslan Bukin /* Call me when ready */
5065c263f43SRuslan Bukin reg = uart_getreg(bas, UART_C2);
5075c263f43SRuslan Bukin reg |= (UART_C2_TIE);
5085c263f43SRuslan Bukin uart_setreg(bas, UART_C2, reg);
5095c263f43SRuslan Bukin
5105c263f43SRuslan Bukin uart_unlock(sc->sc_hwmtx);
5115c263f43SRuslan Bukin
5125c263f43SRuslan Bukin return (0);
5135c263f43SRuslan Bukin }
514