1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2015 Freescale Semiconductor, Inc.
4  * All rights reserved.
5  * Copyright 2018-2019 NXP.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <assert.h>
31 #include <drivers/imx_uart.h>
32 #include <io.h>
33 #include <keep.h>
34 #include <kernel/dt.h>
35 #include <util.h>
36 
37 /* Register definitions */
38 #define URXD  0x0  /* Receiver Register */
39 #define UTXD  0x40 /* Transmitter Register */
40 #define UCR1  0x80 /* Control Register 1 */
41 #define UCR2  0x84 /* Control Register 2 */
42 #define UCR3  0x88 /* Control Register 3 */
43 #define UCR4  0x8c /* Control Register 4 */
44 #define UFCR  0x90 /* FIFO Control Register */
45 #define USR1  0x94 /* Status Register 1 */
46 #define USR2  0x98 /* Status Register 2 */
47 #define UESC  0x9c /* Escape Character Register */
48 #define UTIM  0xa0 /* Escape Timer Register */
49 #define UBIR  0xa4 /* BRM Incremental Register */
50 #define UBMR  0xa8 /* BRM Modulator Register */
51 #define UBRC  0xac /* Baud Rate Count Register */
52 #define UTS   0xb4 /* UART Test Register (mx31) */
53 #define USIZE 0xb8 /* UTS + sizeof(uint32_t) */
54 
55 /* UART Control Register Bit Fields.*/
56 #define  URXD_CHARRDY    (1<<15)
57 #define  URXD_ERR        (1<<14)
58 #define  URXD_OVRRUN     (1<<13)
59 #define  URXD_FRMERR     (1<<12)
60 #define  URXD_BRK        (1<<11)
61 #define  URXD_PRERR      (1<<10)
62 #define  URXD_RX_DATA    (0xFF)
63 #define  UCR1_ADEN       (1<<15) /* Auto dectect interrupt */
64 #define  UCR1_ADBR       (1<<14) /* Auto detect baud rate */
65 #define  UCR1_TRDYEN     (1<<13) /* Transmitter ready interrupt enable */
66 #define  UCR1_IDEN       (1<<12) /* Idle condition interrupt */
67 #define  UCR1_RRDYEN     (1<<9)	 /* Recv ready interrupt enable */
68 #define  UCR1_RDMAEN     (1<<8)	 /* Recv ready DMA enable */
69 #define  UCR1_IREN       (1<<7)	 /* Infrared interface enable */
70 #define  UCR1_TXMPTYEN   (1<<6)	 /* Transimitter empty interrupt enable */
71 #define  UCR1_RTSDEN     (1<<5)	 /* RTS delta interrupt enable */
72 #define  UCR1_SNDBRK     (1<<4)	 /* Send break */
73 #define  UCR1_TDMAEN     (1<<3)	 /* Transmitter ready DMA enable */
74 #define  UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled */
75 #define  UCR1_DOZE       (1<<1)	 /* Doze */
76 #define  UCR1_UARTEN     (1<<0)	 /* UART enabled */
77 
78 #define  UTS_FRCPERR	 (1<<13) /* Force parity error */
79 #define  UTS_LOOP        (1<<12) /* Loop tx and rx */
80 #define  UTS_TXEMPTY	 (1<<6)	 /* TxFIFO empty */
81 #define  UTS_RXEMPTY	 (1<<5)	 /* RxFIFO empty */
82 #define  UTS_TXFULL	 (1<<4)	 /* TxFIFO full */
83 #define  UTS_RXFULL	 (1<<3)	 /* RxFIFO full */
84 #define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
85 
chip_to_base(struct serial_chip * chip)86 static vaddr_t chip_to_base(struct serial_chip *chip)
87 {
88 	struct imx_uart_data *pd =
89 		container_of(chip, struct imx_uart_data, chip);
90 
91 	return io_pa_or_va(&pd->base, USIZE);
92 }
93 
imx_uart_flush(struct serial_chip * chip)94 static void imx_uart_flush(struct serial_chip *chip)
95 {
96 	vaddr_t base = chip_to_base(chip);
97 
98 
99 	while (!(io_read32(base + UTS) & UTS_TXEMPTY))
100 		if (!(io_read32(base + UCR1) & UCR1_UARTEN))
101 			return;
102 }
103 
imx_uart_getchar(struct serial_chip * chip)104 static int imx_uart_getchar(struct serial_chip *chip)
105 {
106 	vaddr_t base = chip_to_base(chip);
107 
108 	while (io_read32(base + UTS) & UTS_RXEMPTY)
109 		;
110 
111 	return (io_read32(base + URXD) & URXD_RX_DATA);
112 }
113 
imx_uart_putc(struct serial_chip * chip,int ch)114 static void imx_uart_putc(struct serial_chip *chip, int ch)
115 {
116 	vaddr_t base = chip_to_base(chip);
117 
118 	/* Wait until there's space in the TX FIFO */
119 	while (io_read32(base + UTS) & UTS_TXFULL)
120 		if (!(io_read32(base + UCR1) & UCR1_UARTEN))
121 			return;
122 
123 	io_write32(base + UTXD, ch);
124 }
125 
126 static const struct serial_ops imx_uart_ops = {
127 	.flush = imx_uart_flush,
128 	.getchar = imx_uart_getchar,
129 	.putc = imx_uart_putc,
130 };
131 DECLARE_KEEP_PAGER(imx_uart_ops);
132 
imx_uart_init(struct imx_uart_data * pd,paddr_t base)133 void imx_uart_init(struct imx_uart_data *pd, paddr_t base)
134 {
135 	pd->base.pa = base;
136 	pd->chip.ops = &imx_uart_ops;
137 
138 	/*
139 	 * Do nothing, debug uart(uart0) share with normal world,
140 	 * everything for uart0 initialization is done in bootloader.
141 	 */
142 }
143 
144 #ifdef CFG_DT
imx_uart_dev_alloc(void)145 static struct serial_chip *imx_uart_dev_alloc(void)
146 {
147 	struct imx_uart_data *pd = calloc(1, sizeof(*pd));
148 
149 	if (!pd)
150 		return NULL;
151 
152 	return &pd->chip;
153 }
154 
imx_uart_dev_init(struct serial_chip * chip,const void * fdt,int offs,const char * parms)155 static int imx_uart_dev_init(struct serial_chip *chip, const void *fdt,
156 			     int offs, const char *parms)
157 {
158 	struct imx_uart_data *pd =
159 		container_of(chip, struct imx_uart_data, chip);
160 	vaddr_t vbase = 0;
161 	paddr_t pbase = 0;
162 	size_t size = 0;
163 
164 	if (parms && parms[0])
165 		IMSG("imx_uart: device parameters ignored (%s)", parms);
166 
167 	if (dt_map_dev(fdt, offs, &vbase, &size, DT_MAP_AUTO) < 0)
168 		return -1;
169 
170 	pbase = virt_to_phys((void *)vbase);
171 	imx_uart_init(pd, pbase);
172 
173 	return 0;
174 }
175 
imx_uart_dev_free(struct serial_chip * chip)176 static void imx_uart_dev_free(struct serial_chip *chip)
177 {
178 	struct imx_uart_data *pd =
179 		container_of(chip, struct imx_uart_data, chip);
180 
181 	free(pd);
182 }
183 
184 static const struct serial_driver imx_uart_driver = {
185 	.dev_alloc = imx_uart_dev_alloc,
186 	.dev_init = imx_uart_dev_init,
187 	.dev_free = imx_uart_dev_free,
188 };
189 
190 static const struct dt_device_match imx_match_table[] = {
191 	{ .compatible = "fsl,imx6q-uart" },
192 	{ 0 }
193 };
194 
195 DEFINE_DT_DRIVER(imx_dt_driver) = {
196 	.name = "imx_uart",
197 	.type = DT_DRIVER_UART,
198 	.match_table = imx_match_table,
199 	.driver = &imx_uart_driver,
200 };
201 
202 #endif /* CFG_DT */
203