xref: /freebsd-src/sys/dev/uart/uart_dev_msm.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1dc7717a8SGanbold Tsagaankhuu /*-
2dc7717a8SGanbold Tsagaankhuu  * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold@freebsd.org>
3dc7717a8SGanbold Tsagaankhuu  * All rights reserved.
4dc7717a8SGanbold Tsagaankhuu  *
5dc7717a8SGanbold Tsagaankhuu  * Redistribution and use in source and binary forms, with or without
6dc7717a8SGanbold Tsagaankhuu  * modification, are permitted provided that the following conditions
7dc7717a8SGanbold Tsagaankhuu  * are met:
8dc7717a8SGanbold Tsagaankhuu  *
9dc7717a8SGanbold Tsagaankhuu  * 1. Redistributions of source code must retain the above copyright
10dc7717a8SGanbold Tsagaankhuu  *    notice, this list of conditions and the following disclaimer.
11dc7717a8SGanbold Tsagaankhuu  * 2. Redistributions in binary form must reproduce the above copyright
12dc7717a8SGanbold Tsagaankhuu  *    notice, this list of conditions and the following disclaimer in the
13dc7717a8SGanbold Tsagaankhuu  *    documentation and/or other materials provided with the distribution.
14dc7717a8SGanbold Tsagaankhuu  *
15dc7717a8SGanbold Tsagaankhuu  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16dc7717a8SGanbold Tsagaankhuu  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17dc7717a8SGanbold Tsagaankhuu  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18dc7717a8SGanbold Tsagaankhuu  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19dc7717a8SGanbold Tsagaankhuu  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20dc7717a8SGanbold Tsagaankhuu  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21dc7717a8SGanbold Tsagaankhuu  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22dc7717a8SGanbold Tsagaankhuu  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23dc7717a8SGanbold Tsagaankhuu  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24dc7717a8SGanbold Tsagaankhuu  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25dc7717a8SGanbold Tsagaankhuu  */
26dc7717a8SGanbold Tsagaankhuu 
27dc7717a8SGanbold Tsagaankhuu /* Qualcomm MSM7K/8K uart driver */
28dc7717a8SGanbold Tsagaankhuu 
29dc7717a8SGanbold Tsagaankhuu #include <sys/cdefs.h>
30dc7717a8SGanbold Tsagaankhuu #include "opt_ddb.h"
31dc7717a8SGanbold Tsagaankhuu 
32dc7717a8SGanbold Tsagaankhuu #include <sys/param.h>
33dc7717a8SGanbold Tsagaankhuu #include <sys/systm.h>
34dc7717a8SGanbold Tsagaankhuu #include <sys/bus.h>
35dc7717a8SGanbold Tsagaankhuu #include <sys/conf.h>
36dc7717a8SGanbold Tsagaankhuu #include <sys/kdb.h>
37dc7717a8SGanbold Tsagaankhuu #include <machine/bus.h>
38dc7717a8SGanbold Tsagaankhuu 
39dc7717a8SGanbold Tsagaankhuu #include <dev/uart/uart.h>
40dc7717a8SGanbold Tsagaankhuu #include <dev/uart/uart_cpu.h>
413bb693afSIan Lepore #include <dev/uart/uart_cpu_fdt.h>
42dc7717a8SGanbold Tsagaankhuu #include <dev/uart/uart_bus.h>
43dc7717a8SGanbold Tsagaankhuu #include <dev/uart/uart_dev_msm.h>
44dc7717a8SGanbold Tsagaankhuu 
45dc7717a8SGanbold Tsagaankhuu #include "uart_if.h"
46dc7717a8SGanbold Tsagaankhuu 
47dc7717a8SGanbold Tsagaankhuu #define	DEF_CLK		7372800
48dc7717a8SGanbold Tsagaankhuu 
49dc7717a8SGanbold Tsagaankhuu #define	GETREG(bas, reg)	\
50dc7717a8SGanbold Tsagaankhuu     bus_space_read_4((bas)->bst, (bas)->bsh, (reg))
51dc7717a8SGanbold Tsagaankhuu #define	SETREG(bas, reg, value)	\
52dc7717a8SGanbold Tsagaankhuu     bus_space_write_4((bas)->bst, (bas)->bsh, (reg), (value))
53dc7717a8SGanbold Tsagaankhuu 
54dc7717a8SGanbold Tsagaankhuu static int msm_uart_param(struct uart_bas *, int, int, int, int);
55dc7717a8SGanbold Tsagaankhuu 
56dc7717a8SGanbold Tsagaankhuu /*
57dc7717a8SGanbold Tsagaankhuu  * Low-level UART interface.
58dc7717a8SGanbold Tsagaankhuu  */
59dc7717a8SGanbold Tsagaankhuu static int	msm_probe(struct uart_bas *bas);
60dc7717a8SGanbold Tsagaankhuu static void	msm_init(struct uart_bas *bas, int, int, int, int);
61dc7717a8SGanbold Tsagaankhuu static void	msm_term(struct uart_bas *bas);
62dc7717a8SGanbold Tsagaankhuu static void	msm_putc(struct uart_bas *bas, int);
63dc7717a8SGanbold Tsagaankhuu static int	msm_rxready(struct uart_bas *bas);
64dc7717a8SGanbold Tsagaankhuu static int	msm_getc(struct uart_bas *bas, struct mtx *mtx);
65dc7717a8SGanbold Tsagaankhuu 
66dc7717a8SGanbold Tsagaankhuu extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
67dc7717a8SGanbold Tsagaankhuu 
68dc7717a8SGanbold Tsagaankhuu static int
msm_uart_param(struct uart_bas * bas,int baudrate,int databits,int stopbits,int parity)69dc7717a8SGanbold Tsagaankhuu msm_uart_param(struct uart_bas *bas, int baudrate, int databits,
70dc7717a8SGanbold Tsagaankhuu     int stopbits, int parity)
71dc7717a8SGanbold Tsagaankhuu {
72dc7717a8SGanbold Tsagaankhuu 	int ulcon;
73dc7717a8SGanbold Tsagaankhuu 
74dc7717a8SGanbold Tsagaankhuu 	ulcon = 0;
75dc7717a8SGanbold Tsagaankhuu 
76dc7717a8SGanbold Tsagaankhuu 	switch (databits) {
77dc7717a8SGanbold Tsagaankhuu 	case 5:
78dc7717a8SGanbold Tsagaankhuu 		ulcon |= (UART_DM_5_BPS << 4);
79dc7717a8SGanbold Tsagaankhuu 		break;
80dc7717a8SGanbold Tsagaankhuu 	case 6:
81dc7717a8SGanbold Tsagaankhuu 		ulcon |= (UART_DM_6_BPS << 4);
82dc7717a8SGanbold Tsagaankhuu 		break;
83dc7717a8SGanbold Tsagaankhuu 	case 7:
84dc7717a8SGanbold Tsagaankhuu 		ulcon |= (UART_DM_7_BPS << 4);
85dc7717a8SGanbold Tsagaankhuu 		break;
86dc7717a8SGanbold Tsagaankhuu 	case 8:
87dc7717a8SGanbold Tsagaankhuu 		ulcon |= (UART_DM_8_BPS << 4);
88dc7717a8SGanbold Tsagaankhuu 		break;
89dc7717a8SGanbold Tsagaankhuu 	default:
90dc7717a8SGanbold Tsagaankhuu 		return (EINVAL);
91dc7717a8SGanbold Tsagaankhuu 	}
92dc7717a8SGanbold Tsagaankhuu 
93dc7717a8SGanbold Tsagaankhuu 	switch (parity) {
94dc7717a8SGanbold Tsagaankhuu 	case UART_PARITY_NONE:
95dc7717a8SGanbold Tsagaankhuu 		ulcon |= UART_DM_NO_PARITY;
96dc7717a8SGanbold Tsagaankhuu 		break;
97dc7717a8SGanbold Tsagaankhuu 	case UART_PARITY_ODD:
98dc7717a8SGanbold Tsagaankhuu 		ulcon |= UART_DM_ODD_PARITY;
99dc7717a8SGanbold Tsagaankhuu 		break;
100dc7717a8SGanbold Tsagaankhuu 	case UART_PARITY_EVEN:
101dc7717a8SGanbold Tsagaankhuu 		ulcon |= UART_DM_EVEN_PARITY;
102dc7717a8SGanbold Tsagaankhuu 		break;
103dc7717a8SGanbold Tsagaankhuu 	case UART_PARITY_SPACE:
104dc7717a8SGanbold Tsagaankhuu 		ulcon |= UART_DM_SPACE_PARITY;
105dc7717a8SGanbold Tsagaankhuu 		break;
106dc7717a8SGanbold Tsagaankhuu 	case UART_PARITY_MARK:
107dc7717a8SGanbold Tsagaankhuu 	default:
108dc7717a8SGanbold Tsagaankhuu 		return (EINVAL);
109dc7717a8SGanbold Tsagaankhuu 	}
110dc7717a8SGanbold Tsagaankhuu 
111dc7717a8SGanbold Tsagaankhuu 	switch (stopbits) {
112dc7717a8SGanbold Tsagaankhuu 	case 1:
113dc7717a8SGanbold Tsagaankhuu 		ulcon |= (UART_DM_SBL_1 << 2);
114dc7717a8SGanbold Tsagaankhuu 		break;
115dc7717a8SGanbold Tsagaankhuu 	case 2:
116dc7717a8SGanbold Tsagaankhuu 		ulcon |= (UART_DM_SBL_2 << 2);
117dc7717a8SGanbold Tsagaankhuu 		break;
118dc7717a8SGanbold Tsagaankhuu 	default:
119dc7717a8SGanbold Tsagaankhuu 		return (EINVAL);
120dc7717a8SGanbold Tsagaankhuu 	}
121dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_MR2, ulcon);
122dc7717a8SGanbold Tsagaankhuu 	uart_barrier(bas);
123dc7717a8SGanbold Tsagaankhuu 
124dc7717a8SGanbold Tsagaankhuu 	return (0);
125dc7717a8SGanbold Tsagaankhuu }
126dc7717a8SGanbold Tsagaankhuu 
127dc7717a8SGanbold Tsagaankhuu struct uart_ops uart_msm_ops = {
128dc7717a8SGanbold Tsagaankhuu 	.probe = msm_probe,
129dc7717a8SGanbold Tsagaankhuu 	.init = msm_init,
130dc7717a8SGanbold Tsagaankhuu 	.term = msm_term,
131dc7717a8SGanbold Tsagaankhuu 	.putc = msm_putc,
132dc7717a8SGanbold Tsagaankhuu 	.rxready = msm_rxready,
133dc7717a8SGanbold Tsagaankhuu 	.getc = msm_getc,
134dc7717a8SGanbold Tsagaankhuu };
135dc7717a8SGanbold Tsagaankhuu 
136dc7717a8SGanbold Tsagaankhuu static int
msm_probe(struct uart_bas * bas)137dc7717a8SGanbold Tsagaankhuu msm_probe(struct uart_bas *bas)
138dc7717a8SGanbold Tsagaankhuu {
139dc7717a8SGanbold Tsagaankhuu 
140*9f7743f2SRuslan Bukin 	bas->regiowidth = 4;
141*9f7743f2SRuslan Bukin 
142dc7717a8SGanbold Tsagaankhuu 	return (0);
143dc7717a8SGanbold Tsagaankhuu }
144dc7717a8SGanbold Tsagaankhuu 
145dc7717a8SGanbold Tsagaankhuu static void
msm_init(struct uart_bas * bas,int baudrate,int databits,int stopbits,int parity)146dc7717a8SGanbold Tsagaankhuu msm_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
147dc7717a8SGanbold Tsagaankhuu     int parity)
148dc7717a8SGanbold Tsagaankhuu {
149dc7717a8SGanbold Tsagaankhuu 
150dc7717a8SGanbold Tsagaankhuu 	if (bas->rclk == 0)
151dc7717a8SGanbold Tsagaankhuu 		bas->rclk = DEF_CLK;
152dc7717a8SGanbold Tsagaankhuu 
153dc7717a8SGanbold Tsagaankhuu 	KASSERT(bas->rclk != 0, ("msm_init: Invalid rclk"));
154dc7717a8SGanbold Tsagaankhuu 
155dc7717a8SGanbold Tsagaankhuu 	/* Set default parameters */
156dc7717a8SGanbold Tsagaankhuu 	msm_uart_param(bas, baudrate, databits, stopbits, parity);
157dc7717a8SGanbold Tsagaankhuu 
158dc7717a8SGanbold Tsagaankhuu 	/*
159dc7717a8SGanbold Tsagaankhuu 	 * Configure UART mode registers MR1 and MR2.
160dc7717a8SGanbold Tsagaankhuu 	 * Hardware flow control isn't supported.
161dc7717a8SGanbold Tsagaankhuu 	 */
162dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_MR1, 0x0);
163dc7717a8SGanbold Tsagaankhuu 
164dc7717a8SGanbold Tsagaankhuu 	/* Reset interrupt mask register. */
165dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_IMR, 0);
166dc7717a8SGanbold Tsagaankhuu 
167dc7717a8SGanbold Tsagaankhuu 	/*
168dc7717a8SGanbold Tsagaankhuu 	 * Configure Tx and Rx watermarks configuration registers.
169dc7717a8SGanbold Tsagaankhuu 	 * TX watermark value is set to 0 - interrupt is generated when
170dc7717a8SGanbold Tsagaankhuu 	 * FIFO level is less than or equal to 0.
171dc7717a8SGanbold Tsagaankhuu 	 */
172dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_TFWR, UART_DM_TFW_VALUE);
173dc7717a8SGanbold Tsagaankhuu 
174dc7717a8SGanbold Tsagaankhuu 	/* Set RX watermark value */
175dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_RFWR, UART_DM_RFW_VALUE);
176dc7717a8SGanbold Tsagaankhuu 
177dc7717a8SGanbold Tsagaankhuu 	/*
178dc7717a8SGanbold Tsagaankhuu 	 * Configure Interrupt Programming Register.
179dc7717a8SGanbold Tsagaankhuu 	 * Set initial Stale timeout value.
180dc7717a8SGanbold Tsagaankhuu 	 */
181dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_IPR, UART_DM_STALE_TIMEOUT_LSB);
182dc7717a8SGanbold Tsagaankhuu 
183dc7717a8SGanbold Tsagaankhuu 	/* Disable IRDA mode */
184dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_IRDA, 0x0);
185dc7717a8SGanbold Tsagaankhuu 
186dc7717a8SGanbold Tsagaankhuu 	/*
187dc7717a8SGanbold Tsagaankhuu 	 * Configure and enable sim interface if required.
188dc7717a8SGanbold Tsagaankhuu 	 * Configure hunt character value in HCR register.
189dc7717a8SGanbold Tsagaankhuu 	 * Keep it in reset state.
190dc7717a8SGanbold Tsagaankhuu 	 */
191dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_HCR, 0x0);
192dc7717a8SGanbold Tsagaankhuu 
193dc7717a8SGanbold Tsagaankhuu 	/* Issue soft reset command */
194dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_RESET_TX);
195dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_RESET_RX);
196dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);
197dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_RESET_BREAK_INT);
198dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
199dc7717a8SGanbold Tsagaankhuu 
200dc7717a8SGanbold Tsagaankhuu 	/* Enable/Disable Rx/Tx DM interfaces */
201*9f7743f2SRuslan Bukin 	uart_setreg(bas, UART_DM_DMEN, UART_DM_DMEN_RX_SC_ENABLE);
202dc7717a8SGanbold Tsagaankhuu 
203dc7717a8SGanbold Tsagaankhuu 	/* Enable transmitter and receiver */
204dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_CR, UART_DM_CR_RX_ENABLE);
205dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_CR, UART_DM_CR_TX_ENABLE);
206dc7717a8SGanbold Tsagaankhuu 
207dc7717a8SGanbold Tsagaankhuu 	uart_barrier(bas);
208dc7717a8SGanbold Tsagaankhuu }
209dc7717a8SGanbold Tsagaankhuu 
210dc7717a8SGanbold Tsagaankhuu static void
msm_term(struct uart_bas * bas)211dc7717a8SGanbold Tsagaankhuu msm_term(struct uart_bas *bas)
212dc7717a8SGanbold Tsagaankhuu {
213dc7717a8SGanbold Tsagaankhuu 
214dc7717a8SGanbold Tsagaankhuu 	/* XXX */
215dc7717a8SGanbold Tsagaankhuu }
216dc7717a8SGanbold Tsagaankhuu 
217dc7717a8SGanbold Tsagaankhuu static void
msm_putc(struct uart_bas * bas,int c)218dc7717a8SGanbold Tsagaankhuu msm_putc(struct uart_bas *bas, int c)
219dc7717a8SGanbold Tsagaankhuu {
220dc7717a8SGanbold Tsagaankhuu 	int limit;
221dc7717a8SGanbold Tsagaankhuu 
222dc7717a8SGanbold Tsagaankhuu 	/*
223dc7717a8SGanbold Tsagaankhuu 	 * Write to NO_CHARS_FOR_TX register the number of characters
224dc7717a8SGanbold Tsagaankhuu 	 * to be transmitted. However, before writing TX_FIFO must
225dc7717a8SGanbold Tsagaankhuu 	 * be empty as indicated by TX_READY interrupt in IMR register
226dc7717a8SGanbold Tsagaankhuu 	 */
227dc7717a8SGanbold Tsagaankhuu 
228dc7717a8SGanbold Tsagaankhuu 	/*
229dc7717a8SGanbold Tsagaankhuu 	 * Check if transmit FIFO is empty.
230dc7717a8SGanbold Tsagaankhuu 	 * If not wait for TX_READY interrupt.
231dc7717a8SGanbold Tsagaankhuu 	 */
232dc7717a8SGanbold Tsagaankhuu 	limit = 1000;
233dc7717a8SGanbold Tsagaankhuu 	if (!(uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXEMT)) {
234dc7717a8SGanbold Tsagaankhuu 		while ((uart_getreg(bas, UART_DM_ISR) & UART_DM_TX_READY) == 0
235dc7717a8SGanbold Tsagaankhuu 		    && --limit)
236dc7717a8SGanbold Tsagaankhuu 			DELAY(4);
237*9f7743f2SRuslan Bukin 		SETREG(bas, UART_DM_CR, UART_DM_CLEAR_TX_READY);
238dc7717a8SGanbold Tsagaankhuu 	}
239dc7717a8SGanbold Tsagaankhuu 	/* FIFO is ready, write number of characters to be written */
240dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_NO_CHARS_FOR_TX, 1);
241dc7717a8SGanbold Tsagaankhuu 
242dc7717a8SGanbold Tsagaankhuu 	/* Wait till TX FIFO has space */
243dc7717a8SGanbold Tsagaankhuu 	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXRDY) == 0)
244dc7717a8SGanbold Tsagaankhuu 		DELAY(4);
245dc7717a8SGanbold Tsagaankhuu 
246dc7717a8SGanbold Tsagaankhuu 	/* TX FIFO has space. Write char */
247dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_TF(0), (c & 0xff));
248dc7717a8SGanbold Tsagaankhuu }
249dc7717a8SGanbold Tsagaankhuu 
250dc7717a8SGanbold Tsagaankhuu static int
msm_rxready(struct uart_bas * bas)251dc7717a8SGanbold Tsagaankhuu msm_rxready(struct uart_bas *bas)
252dc7717a8SGanbold Tsagaankhuu {
253dc7717a8SGanbold Tsagaankhuu 
254dc7717a8SGanbold Tsagaankhuu 	/* Wait for a character to come ready */
255dc7717a8SGanbold Tsagaankhuu 	return ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) ==
256dc7717a8SGanbold Tsagaankhuu 	    UART_DM_SR_RXRDY);
257dc7717a8SGanbold Tsagaankhuu }
258dc7717a8SGanbold Tsagaankhuu 
259dc7717a8SGanbold Tsagaankhuu static int
msm_getc(struct uart_bas * bas,struct mtx * mtx)260dc7717a8SGanbold Tsagaankhuu msm_getc(struct uart_bas *bas, struct mtx *mtx)
261dc7717a8SGanbold Tsagaankhuu {
262dc7717a8SGanbold Tsagaankhuu 	int c;
263dc7717a8SGanbold Tsagaankhuu 
264dc7717a8SGanbold Tsagaankhuu 	uart_lock(mtx);
265dc7717a8SGanbold Tsagaankhuu 
266dc7717a8SGanbold Tsagaankhuu 	/* Wait for a character to come ready */
267dc7717a8SGanbold Tsagaankhuu 	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) !=
268dc7717a8SGanbold Tsagaankhuu 	    UART_DM_SR_RXRDY)
269dc7717a8SGanbold Tsagaankhuu 		DELAY(4);
270dc7717a8SGanbold Tsagaankhuu 
271dc7717a8SGanbold Tsagaankhuu 	/* Check for Overrun error. If so reset Error Status */
272dc7717a8SGanbold Tsagaankhuu 	if (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_UART_OVERRUN)
273dc7717a8SGanbold Tsagaankhuu 		uart_setreg(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);
274dc7717a8SGanbold Tsagaankhuu 
275dc7717a8SGanbold Tsagaankhuu 	/* Read char */
276dc7717a8SGanbold Tsagaankhuu 	c = uart_getreg(bas, UART_DM_RF(0));
277dc7717a8SGanbold Tsagaankhuu 
278dc7717a8SGanbold Tsagaankhuu 	uart_unlock(mtx);
279dc7717a8SGanbold Tsagaankhuu 
280dc7717a8SGanbold Tsagaankhuu 	return (c);
281dc7717a8SGanbold Tsagaankhuu }
282dc7717a8SGanbold Tsagaankhuu 
283dc7717a8SGanbold Tsagaankhuu /*
284dc7717a8SGanbold Tsagaankhuu  * High-level UART interface.
285dc7717a8SGanbold Tsagaankhuu  */
286dc7717a8SGanbold Tsagaankhuu struct msm_uart_softc {
287dc7717a8SGanbold Tsagaankhuu 	struct uart_softc base;
288dc7717a8SGanbold Tsagaankhuu 	uint32_t ier;
289dc7717a8SGanbold Tsagaankhuu };
290dc7717a8SGanbold Tsagaankhuu 
291dc7717a8SGanbold Tsagaankhuu static int	msm_bus_probe(struct uart_softc *sc);
292dc7717a8SGanbold Tsagaankhuu static int	msm_bus_attach(struct uart_softc *sc);
293dc7717a8SGanbold Tsagaankhuu static int	msm_bus_flush(struct uart_softc *, int);
294dc7717a8SGanbold Tsagaankhuu static int	msm_bus_getsig(struct uart_softc *);
295dc7717a8SGanbold Tsagaankhuu static int	msm_bus_ioctl(struct uart_softc *, int, intptr_t);
296dc7717a8SGanbold Tsagaankhuu static int	msm_bus_ipend(struct uart_softc *);
297dc7717a8SGanbold Tsagaankhuu static int	msm_bus_param(struct uart_softc *, int, int, int, int);
298dc7717a8SGanbold Tsagaankhuu static int	msm_bus_receive(struct uart_softc *);
299dc7717a8SGanbold Tsagaankhuu static int	msm_bus_setsig(struct uart_softc *, int);
300dc7717a8SGanbold Tsagaankhuu static int	msm_bus_transmit(struct uart_softc *);
301dc7717a8SGanbold Tsagaankhuu static void	msm_bus_grab(struct uart_softc *);
302dc7717a8SGanbold Tsagaankhuu static void	msm_bus_ungrab(struct uart_softc *);
303dc7717a8SGanbold Tsagaankhuu 
304dc7717a8SGanbold Tsagaankhuu static kobj_method_t msm_methods[] = {
305dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_probe,		msm_bus_probe),
306dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_attach, 	msm_bus_attach),
307dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_flush,		msm_bus_flush),
308dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_getsig,		msm_bus_getsig),
309dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_ioctl,		msm_bus_ioctl),
310dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_ipend,		msm_bus_ipend),
311dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_param,		msm_bus_param),
312dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_receive,	msm_bus_receive),
313dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_setsig,		msm_bus_setsig),
314dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_transmit,	msm_bus_transmit),
315dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_grab,		msm_bus_grab),
316dc7717a8SGanbold Tsagaankhuu 	KOBJMETHOD(uart_ungrab,		msm_bus_ungrab),
317dc7717a8SGanbold Tsagaankhuu 	{0, 0 }
318dc7717a8SGanbold Tsagaankhuu };
319dc7717a8SGanbold Tsagaankhuu 
320dc7717a8SGanbold Tsagaankhuu int
msm_bus_probe(struct uart_softc * sc)321dc7717a8SGanbold Tsagaankhuu msm_bus_probe(struct uart_softc *sc)
322dc7717a8SGanbold Tsagaankhuu {
323*9f7743f2SRuslan Bukin 	struct uart_bas *bas;
324*9f7743f2SRuslan Bukin 
325*9f7743f2SRuslan Bukin 	bas = &sc->sc_bas;
326*9f7743f2SRuslan Bukin 	bas->regiowidth = 4;
327dc7717a8SGanbold Tsagaankhuu 
328dc7717a8SGanbold Tsagaankhuu 	sc->sc_txfifosz = 64;
329dc7717a8SGanbold Tsagaankhuu 	sc->sc_rxfifosz = 64;
330dc7717a8SGanbold Tsagaankhuu 
331dc7717a8SGanbold Tsagaankhuu 	device_set_desc(sc->sc_dev, "Qualcomm HSUART");
332dc7717a8SGanbold Tsagaankhuu 
333dc7717a8SGanbold Tsagaankhuu 	return (0);
334dc7717a8SGanbold Tsagaankhuu }
335dc7717a8SGanbold Tsagaankhuu 
336dc7717a8SGanbold Tsagaankhuu static int
msm_bus_attach(struct uart_softc * sc)337dc7717a8SGanbold Tsagaankhuu msm_bus_attach(struct uart_softc *sc)
338dc7717a8SGanbold Tsagaankhuu {
339dc7717a8SGanbold Tsagaankhuu 	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
340dc7717a8SGanbold Tsagaankhuu 	struct uart_bas *bas = &sc->sc_bas;
341dc7717a8SGanbold Tsagaankhuu 
342dc7717a8SGanbold Tsagaankhuu 	sc->sc_hwiflow = 0;
343dc7717a8SGanbold Tsagaankhuu 	sc->sc_hwoflow = 0;
344dc7717a8SGanbold Tsagaankhuu 
345dc7717a8SGanbold Tsagaankhuu 	/* Set TX_READY, TXLEV, RXLEV, RXSTALE */
346dc7717a8SGanbold Tsagaankhuu 	u->ier = UART_DM_IMR_ENABLED;
347dc7717a8SGanbold Tsagaankhuu 
348dc7717a8SGanbold Tsagaankhuu 	/* Configure Interrupt Mask register IMR */
349dc7717a8SGanbold Tsagaankhuu 	uart_setreg(bas, UART_DM_IMR, u->ier);
350dc7717a8SGanbold Tsagaankhuu 
351dc7717a8SGanbold Tsagaankhuu 	return (0);
352dc7717a8SGanbold Tsagaankhuu }
353dc7717a8SGanbold Tsagaankhuu 
354dc7717a8SGanbold Tsagaankhuu /*
355dc7717a8SGanbold Tsagaankhuu  * Write the current transmit buffer to the TX FIFO.
356dc7717a8SGanbold Tsagaankhuu  */
357dc7717a8SGanbold Tsagaankhuu static int
msm_bus_transmit(struct uart_softc * sc)358dc7717a8SGanbold Tsagaankhuu msm_bus_transmit(struct uart_softc *sc)
359dc7717a8SGanbold Tsagaankhuu {
360dc7717a8SGanbold Tsagaankhuu 	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
361dc7717a8SGanbold Tsagaankhuu 	struct uart_bas *bas = &sc->sc_bas;
362dc7717a8SGanbold Tsagaankhuu 	int i;
363dc7717a8SGanbold Tsagaankhuu 
364dc7717a8SGanbold Tsagaankhuu 	uart_lock(sc->sc_hwmtx);
365dc7717a8SGanbold Tsagaankhuu 
366dc7717a8SGanbold Tsagaankhuu 	/* Write some data */
367dc7717a8SGanbold Tsagaankhuu 	for (i = 0; i < sc->sc_txdatasz; i++) {
368dc7717a8SGanbold Tsagaankhuu 		/* Write TX data */
369dc7717a8SGanbold Tsagaankhuu 		msm_putc(bas, sc->sc_txbuf[i]);
370dc7717a8SGanbold Tsagaankhuu 		uart_barrier(bas);
371dc7717a8SGanbold Tsagaankhuu 	}
372dc7717a8SGanbold Tsagaankhuu 
373dc7717a8SGanbold Tsagaankhuu 	/* TX FIFO is empty now, enable TX_READY interrupt */
374dc7717a8SGanbold Tsagaankhuu 	u->ier |= UART_DM_TX_READY;
375dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_IMR, u->ier);
376dc7717a8SGanbold Tsagaankhuu 	uart_barrier(bas);
377dc7717a8SGanbold Tsagaankhuu 
378dc7717a8SGanbold Tsagaankhuu 	/*
379dc7717a8SGanbold Tsagaankhuu 	 * Inform upper layer that it is transmitting data to hardware,
380dc7717a8SGanbold Tsagaankhuu 	 * this will be cleared when TXIDLE interrupt occurs.
381dc7717a8SGanbold Tsagaankhuu 	 */
382dc7717a8SGanbold Tsagaankhuu 	sc->sc_txbusy = 1;
383dc7717a8SGanbold Tsagaankhuu 	uart_unlock(sc->sc_hwmtx);
384dc7717a8SGanbold Tsagaankhuu 
385dc7717a8SGanbold Tsagaankhuu 	return (0);
386dc7717a8SGanbold Tsagaankhuu }
387dc7717a8SGanbold Tsagaankhuu 
388dc7717a8SGanbold Tsagaankhuu static int
msm_bus_setsig(struct uart_softc * sc,int sig)389dc7717a8SGanbold Tsagaankhuu msm_bus_setsig(struct uart_softc *sc, int sig)
390dc7717a8SGanbold Tsagaankhuu {
391dc7717a8SGanbold Tsagaankhuu 
392dc7717a8SGanbold Tsagaankhuu 	return (0);
393dc7717a8SGanbold Tsagaankhuu }
394dc7717a8SGanbold Tsagaankhuu 
395dc7717a8SGanbold Tsagaankhuu static int
msm_bus_receive(struct uart_softc * sc)396dc7717a8SGanbold Tsagaankhuu msm_bus_receive(struct uart_softc *sc)
397dc7717a8SGanbold Tsagaankhuu {
398dc7717a8SGanbold Tsagaankhuu 	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
399dc7717a8SGanbold Tsagaankhuu 	struct uart_bas *bas;
400dc7717a8SGanbold Tsagaankhuu 	int c;
401dc7717a8SGanbold Tsagaankhuu 
402dc7717a8SGanbold Tsagaankhuu 	bas = &sc->sc_bas;
403dc7717a8SGanbold Tsagaankhuu 	uart_lock(sc->sc_hwmtx);
404dc7717a8SGanbold Tsagaankhuu 
405dc7717a8SGanbold Tsagaankhuu 	/* Initialize Receive Path and interrupt */
406dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
407dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_ENABLE);
408dc7717a8SGanbold Tsagaankhuu 	u->ier |= UART_DM_RXLEV;
409dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_IMR, u->ier);
410dc7717a8SGanbold Tsagaankhuu 
411dc7717a8SGanbold Tsagaankhuu 	/* Loop over until we are full, or no data is available */
412dc7717a8SGanbold Tsagaankhuu 	while (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) {
413dc7717a8SGanbold Tsagaankhuu 		if (uart_rx_full(sc)) {
414dc7717a8SGanbold Tsagaankhuu 			/* No space left in input buffer */
415dc7717a8SGanbold Tsagaankhuu 			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
416dc7717a8SGanbold Tsagaankhuu 			break;
417dc7717a8SGanbold Tsagaankhuu 		}
418dc7717a8SGanbold Tsagaankhuu 
419dc7717a8SGanbold Tsagaankhuu 		/* Read RX FIFO */
420dc7717a8SGanbold Tsagaankhuu 		c = uart_getreg(bas, UART_DM_RF(0));
421dc7717a8SGanbold Tsagaankhuu 		uart_barrier(bas);
422dc7717a8SGanbold Tsagaankhuu 
423dc7717a8SGanbold Tsagaankhuu 		uart_rx_put(sc, c);
424dc7717a8SGanbold Tsagaankhuu 	}
425dc7717a8SGanbold Tsagaankhuu 
426dc7717a8SGanbold Tsagaankhuu 	uart_unlock(sc->sc_hwmtx);
427dc7717a8SGanbold Tsagaankhuu 
428dc7717a8SGanbold Tsagaankhuu 	return (0);
429dc7717a8SGanbold Tsagaankhuu }
430dc7717a8SGanbold Tsagaankhuu 
431dc7717a8SGanbold Tsagaankhuu static int
msm_bus_param(struct uart_softc * sc,int baudrate,int databits,int stopbits,int parity)432dc7717a8SGanbold Tsagaankhuu msm_bus_param(struct uart_softc *sc, int baudrate, int databits,
433dc7717a8SGanbold Tsagaankhuu     int stopbits, int parity)
434dc7717a8SGanbold Tsagaankhuu {
435dc7717a8SGanbold Tsagaankhuu 	int error;
436dc7717a8SGanbold Tsagaankhuu 
437dc7717a8SGanbold Tsagaankhuu 	if (sc->sc_bas.rclk == 0)
438dc7717a8SGanbold Tsagaankhuu 		sc->sc_bas.rclk = DEF_CLK;
439dc7717a8SGanbold Tsagaankhuu 
440dc7717a8SGanbold Tsagaankhuu 	KASSERT(sc->sc_bas.rclk != 0, ("msm_init: Invalid rclk"));
441dc7717a8SGanbold Tsagaankhuu 
442dc7717a8SGanbold Tsagaankhuu 	uart_lock(sc->sc_hwmtx);
443dc7717a8SGanbold Tsagaankhuu 	error = msm_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
444dc7717a8SGanbold Tsagaankhuu 	    parity);
445dc7717a8SGanbold Tsagaankhuu 	uart_unlock(sc->sc_hwmtx);
446dc7717a8SGanbold Tsagaankhuu 
447dc7717a8SGanbold Tsagaankhuu 	return (error);
448dc7717a8SGanbold Tsagaankhuu }
449dc7717a8SGanbold Tsagaankhuu 
450dc7717a8SGanbold Tsagaankhuu static int
msm_bus_ipend(struct uart_softc * sc)451dc7717a8SGanbold Tsagaankhuu msm_bus_ipend(struct uart_softc *sc)
452dc7717a8SGanbold Tsagaankhuu {
453dc7717a8SGanbold Tsagaankhuu 	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
454dc7717a8SGanbold Tsagaankhuu 	struct uart_bas *bas = &sc->sc_bas;
455dc7717a8SGanbold Tsagaankhuu 	uint32_t isr;
456dc7717a8SGanbold Tsagaankhuu 	int ipend;
457dc7717a8SGanbold Tsagaankhuu 
458dc7717a8SGanbold Tsagaankhuu 	uart_lock(sc->sc_hwmtx);
459dc7717a8SGanbold Tsagaankhuu 
460dc7717a8SGanbold Tsagaankhuu 	/* Get ISR status */
461dc7717a8SGanbold Tsagaankhuu 	isr = GETREG(bas, UART_DM_MISR);
462dc7717a8SGanbold Tsagaankhuu 
463dc7717a8SGanbold Tsagaankhuu 	ipend = 0;
464dc7717a8SGanbold Tsagaankhuu 
465dc7717a8SGanbold Tsagaankhuu 	/* Uart RX starting, notify upper layer */
466dc7717a8SGanbold Tsagaankhuu 	if (isr & UART_DM_RXLEV) {
467dc7717a8SGanbold Tsagaankhuu 		u->ier &= ~UART_DM_RXLEV;
468dc7717a8SGanbold Tsagaankhuu 		SETREG(bas, UART_DM_IMR, u->ier);
469dc7717a8SGanbold Tsagaankhuu 		uart_barrier(bas);
470dc7717a8SGanbold Tsagaankhuu 		ipend |= SER_INT_RXREADY;
471dc7717a8SGanbold Tsagaankhuu 	}
472dc7717a8SGanbold Tsagaankhuu 
473dc7717a8SGanbold Tsagaankhuu 	/* Stale RX interrupt */
474dc7717a8SGanbold Tsagaankhuu 	if (isr & UART_DM_RXSTALE) {
475dc7717a8SGanbold Tsagaankhuu 		/* Disable and reset it */
476dc7717a8SGanbold Tsagaankhuu 		SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_DISABLE);
477dc7717a8SGanbold Tsagaankhuu 		SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
478dc7717a8SGanbold Tsagaankhuu 		uart_barrier(bas);
479dc7717a8SGanbold Tsagaankhuu 		ipend |= SER_INT_RXREADY;
480dc7717a8SGanbold Tsagaankhuu 	}
481dc7717a8SGanbold Tsagaankhuu 
482dc7717a8SGanbold Tsagaankhuu 	/* TX READY interrupt */
483dc7717a8SGanbold Tsagaankhuu 	if (isr & UART_DM_TX_READY) {
484dc7717a8SGanbold Tsagaankhuu 		/* Clear  TX Ready */
485dc7717a8SGanbold Tsagaankhuu 		SETREG(bas, UART_DM_CR, UART_DM_CLEAR_TX_READY);
486dc7717a8SGanbold Tsagaankhuu 
487dc7717a8SGanbold Tsagaankhuu 		/* Disable TX_READY */
488dc7717a8SGanbold Tsagaankhuu 		u->ier &= ~UART_DM_TX_READY;
489dc7717a8SGanbold Tsagaankhuu 		SETREG(bas, UART_DM_IMR, u->ier);
490dc7717a8SGanbold Tsagaankhuu 		uart_barrier(bas);
491dc7717a8SGanbold Tsagaankhuu 
492dc7717a8SGanbold Tsagaankhuu 		if (sc->sc_txbusy != 0)
493dc7717a8SGanbold Tsagaankhuu 			ipend |= SER_INT_TXIDLE;
494dc7717a8SGanbold Tsagaankhuu 	}
495dc7717a8SGanbold Tsagaankhuu 
496dc7717a8SGanbold Tsagaankhuu 	if (isr & UART_DM_TXLEV) {
497dc7717a8SGanbold Tsagaankhuu 		/* TX FIFO is empty */
498dc7717a8SGanbold Tsagaankhuu 		u->ier &= ~UART_DM_TXLEV;
499dc7717a8SGanbold Tsagaankhuu 		SETREG(bas, UART_DM_IMR, u->ier);
500dc7717a8SGanbold Tsagaankhuu 		uart_barrier(bas);
501dc7717a8SGanbold Tsagaankhuu 
502dc7717a8SGanbold Tsagaankhuu 		if (sc->sc_txbusy != 0)
503dc7717a8SGanbold Tsagaankhuu 			ipend |= SER_INT_TXIDLE;
504dc7717a8SGanbold Tsagaankhuu 	}
505dc7717a8SGanbold Tsagaankhuu 
506dc7717a8SGanbold Tsagaankhuu 	uart_unlock(sc->sc_hwmtx);
507dc7717a8SGanbold Tsagaankhuu 	return (ipend);
508dc7717a8SGanbold Tsagaankhuu }
509dc7717a8SGanbold Tsagaankhuu 
510dc7717a8SGanbold Tsagaankhuu static int
msm_bus_flush(struct uart_softc * sc,int what)511dc7717a8SGanbold Tsagaankhuu msm_bus_flush(struct uart_softc *sc, int what)
512dc7717a8SGanbold Tsagaankhuu {
513dc7717a8SGanbold Tsagaankhuu 
514dc7717a8SGanbold Tsagaankhuu 	return (0);
515dc7717a8SGanbold Tsagaankhuu }
516dc7717a8SGanbold Tsagaankhuu 
517dc7717a8SGanbold Tsagaankhuu static int
msm_bus_getsig(struct uart_softc * sc)518dc7717a8SGanbold Tsagaankhuu msm_bus_getsig(struct uart_softc *sc)
519dc7717a8SGanbold Tsagaankhuu {
520dc7717a8SGanbold Tsagaankhuu 
521dc7717a8SGanbold Tsagaankhuu 	return (0);
522dc7717a8SGanbold Tsagaankhuu }
523dc7717a8SGanbold Tsagaankhuu 
524dc7717a8SGanbold Tsagaankhuu static int
msm_bus_ioctl(struct uart_softc * sc,int request,intptr_t data)525dc7717a8SGanbold Tsagaankhuu msm_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
526dc7717a8SGanbold Tsagaankhuu {
527dc7717a8SGanbold Tsagaankhuu 
528dc7717a8SGanbold Tsagaankhuu 	return (EINVAL);
529dc7717a8SGanbold Tsagaankhuu }
530dc7717a8SGanbold Tsagaankhuu 
531dc7717a8SGanbold Tsagaankhuu static void
msm_bus_grab(struct uart_softc * sc)532dc7717a8SGanbold Tsagaankhuu msm_bus_grab(struct uart_softc *sc)
533dc7717a8SGanbold Tsagaankhuu {
534dc7717a8SGanbold Tsagaankhuu 	struct uart_bas *bas = &sc->sc_bas;
535dc7717a8SGanbold Tsagaankhuu 
536dc7717a8SGanbold Tsagaankhuu 	/*
537dc7717a8SGanbold Tsagaankhuu 	 * XXX: Turn off all interrupts to enter polling mode. Leave the
538dc7717a8SGanbold Tsagaankhuu 	 * saved mask alone. We'll restore whatever it was in ungrab.
539dc7717a8SGanbold Tsagaankhuu 	 */
540dc7717a8SGanbold Tsagaankhuu 	uart_lock(sc->sc_hwmtx);
541dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
542dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_IMR, 0);
543dc7717a8SGanbold Tsagaankhuu 	uart_barrier(bas);
544dc7717a8SGanbold Tsagaankhuu 	uart_unlock(sc->sc_hwmtx);
545dc7717a8SGanbold Tsagaankhuu }
546dc7717a8SGanbold Tsagaankhuu 
547dc7717a8SGanbold Tsagaankhuu static void
msm_bus_ungrab(struct uart_softc * sc)548dc7717a8SGanbold Tsagaankhuu msm_bus_ungrab(struct uart_softc *sc)
549dc7717a8SGanbold Tsagaankhuu {
550dc7717a8SGanbold Tsagaankhuu 	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
551dc7717a8SGanbold Tsagaankhuu 	struct uart_bas *bas = &sc->sc_bas;
552dc7717a8SGanbold Tsagaankhuu 
553dc7717a8SGanbold Tsagaankhuu 	/*
554dc7717a8SGanbold Tsagaankhuu 	 * Restore previous interrupt mask
555dc7717a8SGanbold Tsagaankhuu 	 */
556dc7717a8SGanbold Tsagaankhuu 	uart_lock(sc->sc_hwmtx);
557dc7717a8SGanbold Tsagaankhuu 	SETREG(bas, UART_DM_IMR, u->ier);
558dc7717a8SGanbold Tsagaankhuu 	uart_barrier(bas);
559dc7717a8SGanbold Tsagaankhuu 	uart_unlock(sc->sc_hwmtx);
560dc7717a8SGanbold Tsagaankhuu }
561dc7717a8SGanbold Tsagaankhuu 
5623bb693afSIan Lepore static struct uart_class uart_msm_class = {
563dc7717a8SGanbold Tsagaankhuu 	"msm",
564dc7717a8SGanbold Tsagaankhuu 	msm_methods,
565dc7717a8SGanbold Tsagaankhuu 	sizeof(struct msm_uart_softc),
566dc7717a8SGanbold Tsagaankhuu 	.uc_ops = &uart_msm_ops,
567dc7717a8SGanbold Tsagaankhuu 	.uc_range = 8,
568dc7717a8SGanbold Tsagaankhuu 	.uc_rclk = DEF_CLK,
569405ada37SAndrew Turner 	.uc_rshift = 0
570dc7717a8SGanbold Tsagaankhuu };
5713bb693afSIan Lepore 
5723bb693afSIan Lepore static struct ofw_compat_data compat_data[] = {
573*9f7743f2SRuslan Bukin 	{"qcom,msm-uartdm-v1.4",	(uintptr_t)&uart_msm_class},
5743bb693afSIan Lepore 	{"qcom,msm-uartdm",		(uintptr_t)&uart_msm_class},
5753bb693afSIan Lepore 	{NULL,				(uintptr_t)NULL},
5763bb693afSIan Lepore };
5773bb693afSIan Lepore UART_FDT_CLASS_AND_DEVICE(compat_data);
578