xref: /freebsd/sys/arm/freescale/vybrid/vf_uart.c (revision 5c263f43ef6296996bddf92c2ec0b5ea9ea0d3e1)
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