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