• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
4  *
5  * (C) Copyright 2002
6  * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
7  *
8  * (C) Copyright 2002
9  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
10  * Marius Groeger <mgroeger@sysgo.de>
11  *
12  * (C) Copyright 2002
13  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
14  * Alex Zuepke <azu@sysgo.de>
15  *
16  * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
17  *
18  * Modified to add driver model (DM) support
19  * (C) Copyright 2016 Marcel Ziswiler <marcel.ziswiler@toradex.com>
20  */
21 
22 #include <common.h>
23 #include <asm/arch/pxa-regs.h>
24 #include <asm/arch/regs-uart.h>
25 #include <asm/io.h>
26 #include <dm.h>
27 #include <dm/platform_data/serial_pxa.h>
28 #include <linux/compiler.h>
29 #include <serial.h>
30 #include <watchdog.h>
31 
32 DECLARE_GLOBAL_DATA_PTR;
33 
pxa_uart_get_baud_divider(int baudrate)34 static uint32_t pxa_uart_get_baud_divider(int baudrate)
35 {
36 	return 921600 / baudrate;
37 }
38 
pxa_uart_toggle_clock(uint32_t uart_index,int enable)39 static void pxa_uart_toggle_clock(uint32_t uart_index, int enable)
40 {
41 	uint32_t clk_reg, clk_offset, reg;
42 
43 	clk_reg = UART_CLK_REG;
44 	clk_offset = UART_CLK_BASE << uart_index;
45 
46 	reg = readl(clk_reg);
47 
48 	if (enable)
49 		reg |= clk_offset;
50 	else
51 		reg &= ~clk_offset;
52 
53 	writel(reg, clk_reg);
54 }
55 
56 /*
57  * Enable clock and set baud rate, parity etc.
58  */
pxa_setbrg_common(struct pxa_uart_regs * uart_regs,int port,int baudrate)59 void pxa_setbrg_common(struct pxa_uart_regs *uart_regs, int port, int baudrate)
60 {
61 	uint32_t divider = pxa_uart_get_baud_divider(baudrate);
62 	if (!divider)
63 		hang();
64 
65 
66 	pxa_uart_toggle_clock(port, 1);
67 
68 	/* Disable interrupts and FIFOs */
69 	writel(0, &uart_regs->ier);
70 	writel(0, &uart_regs->fcr);
71 
72 	/* Set baud rate */
73 	writel(LCR_WLS0 | LCR_WLS1 | LCR_DLAB, &uart_regs->lcr);
74 	writel(divider & 0xff, &uart_regs->dll);
75 	writel(divider >> 8, &uart_regs->dlh);
76 	writel(LCR_WLS0 | LCR_WLS1, &uart_regs->lcr);
77 
78 	/* Enable UART */
79 	writel(IER_UUE, &uart_regs->ier);
80 }
81 
82 #ifndef CONFIG_DM_SERIAL
pxa_uart_index_to_regs(uint32_t uart_index)83 static struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
84 {
85 	switch (uart_index) {
86 	case FFUART_INDEX: return (struct pxa_uart_regs *)FFUART_BASE;
87 	case BTUART_INDEX: return (struct pxa_uart_regs *)BTUART_BASE;
88 	case STUART_INDEX: return (struct pxa_uart_regs *)STUART_BASE;
89 	case HWUART_INDEX: return (struct pxa_uart_regs *)HWUART_BASE;
90 	default:
91 		return NULL;
92 	}
93 }
94 
95 /*
96  * Enable clock and set baud rate, parity etc.
97  */
pxa_setbrg_dev(uint32_t uart_index)98 void pxa_setbrg_dev(uint32_t uart_index)
99 {
100 	struct pxa_uart_regs *uart_regs = pxa_uart_index_to_regs(uart_index);
101 	if (!uart_regs)
102 		panic("Failed getting UART registers\n");
103 
104 	pxa_setbrg_common(uart_regs, uart_index, gd->baudrate);
105 }
106 
107 /*
108  * Initialise the serial port with the given baudrate. The settings
109  * are always 8 data bits, no parity, 1 stop bit, no start bits.
110  */
pxa_init_dev(unsigned int uart_index)111 int pxa_init_dev(unsigned int uart_index)
112 {
113 	pxa_setbrg_dev(uart_index);
114 	return 0;
115 }
116 
117 /*
118  * Output a single byte to the serial port.
119  */
pxa_putc_dev(unsigned int uart_index,const char c)120 void pxa_putc_dev(unsigned int uart_index, const char c)
121 {
122 	struct pxa_uart_regs *uart_regs;
123 
124 	/* If \n, also do \r */
125 	if (c == '\n')
126 		pxa_putc_dev(uart_index, '\r');
127 
128 	uart_regs = pxa_uart_index_to_regs(uart_index);
129 	if (!uart_regs)
130 		hang();
131 
132 	while (!(readl(&uart_regs->lsr) & LSR_TEMT))
133 		WATCHDOG_RESET();
134 	writel(c, &uart_regs->thr);
135 }
136 
137 /*
138  * Read a single byte from the serial port. Returns 1 on success, 0
139  * otherwise. When the function is succesfull, the character read is
140  * written into its argument c.
141  */
pxa_tstc_dev(unsigned int uart_index)142 int pxa_tstc_dev(unsigned int uart_index)
143 {
144 	struct pxa_uart_regs *uart_regs;
145 
146 	uart_regs = pxa_uart_index_to_regs(uart_index);
147 	if (!uart_regs)
148 		return -1;
149 
150 	return readl(&uart_regs->lsr) & LSR_DR;
151 }
152 
153 /*
154  * Read a single byte from the serial port. Returns 1 on success, 0
155  * otherwise. When the function is succesfull, the character read is
156  * written into its argument c.
157  */
pxa_getc_dev(unsigned int uart_index)158 int pxa_getc_dev(unsigned int uart_index)
159 {
160 	struct pxa_uart_regs *uart_regs;
161 
162 	uart_regs = pxa_uart_index_to_regs(uart_index);
163 	if (!uart_regs)
164 		return -1;
165 
166 	while (!(readl(&uart_regs->lsr) & LSR_DR))
167 		WATCHDOG_RESET();
168 	return readl(&uart_regs->rbr) & 0xff;
169 }
170 
pxa_puts_dev(unsigned int uart_index,const char * s)171 void pxa_puts_dev(unsigned int uart_index, const char *s)
172 {
173 	while (*s)
174 		pxa_putc_dev(uart_index, *s++);
175 }
176 
177 #define	pxa_uart(uart, UART)						\
178 	int uart##_init(void)						\
179 	{								\
180 		return pxa_init_dev(UART##_INDEX);			\
181 	}								\
182 									\
183 	void uart##_setbrg(void)					\
184 	{								\
185 		return pxa_setbrg_dev(UART##_INDEX);			\
186 	}								\
187 									\
188 	void uart##_putc(const char c)					\
189 	{								\
190 		return pxa_putc_dev(UART##_INDEX, c);			\
191 	}								\
192 									\
193 	void uart##_puts(const char *s)					\
194 	{								\
195 		return pxa_puts_dev(UART##_INDEX, s);			\
196 	}								\
197 									\
198 	int uart##_getc(void)						\
199 	{								\
200 		return pxa_getc_dev(UART##_INDEX);			\
201 	}								\
202 									\
203 	int uart##_tstc(void)						\
204 	{								\
205 		return pxa_tstc_dev(UART##_INDEX);			\
206 	}								\
207 
208 #define	pxa_uart_desc(uart)						\
209 	struct serial_device serial_##uart##_device =			\
210 	{								\
211 		.name	= "serial_"#uart,				\
212 		.start	= uart##_init,					\
213 		.stop	= NULL,						\
214 		.setbrg	= uart##_setbrg,				\
215 		.getc	= uart##_getc,					\
216 		.tstc	= uart##_tstc,					\
217 		.putc	= uart##_putc,					\
218 		.puts	= uart##_puts,					\
219 	};
220 
221 #define	pxa_uart_multi(uart, UART)					\
222 	pxa_uart(uart, UART)						\
223 	pxa_uart_desc(uart)
224 
225 #if defined(CONFIG_HWUART)
pxa_uart_multi(hwuart,HWUART)226 	pxa_uart_multi(hwuart, HWUART)
227 #endif
228 #if defined(CONFIG_STUART)
229 	pxa_uart_multi(stuart, STUART)
230 #endif
231 #if defined(CONFIG_FFUART)
232 	pxa_uart_multi(ffuart, FFUART)
233 #endif
234 #if defined(CONFIG_BTUART)
235 	pxa_uart_multi(btuart, BTUART)
236 #endif
237 
238 __weak struct serial_device *default_serial_console(void)
239 {
240 #if CONFIG_CONS_INDEX == 1
241 	return &serial_hwuart_device;
242 #elif CONFIG_CONS_INDEX == 2
243 	return &serial_stuart_device;
244 #elif CONFIG_CONS_INDEX == 3
245 	return &serial_ffuart_device;
246 #elif CONFIG_CONS_INDEX == 4
247 	return &serial_btuart_device;
248 #else
249 #error "Bad CONFIG_CONS_INDEX."
250 #endif
251 }
252 
pxa_serial_initialize(void)253 void pxa_serial_initialize(void)
254 {
255 #if defined(CONFIG_FFUART)
256 	serial_register(&serial_ffuart_device);
257 #endif
258 #if defined(CONFIG_BTUART)
259 	serial_register(&serial_btuart_device);
260 #endif
261 #if defined(CONFIG_STUART)
262 	serial_register(&serial_stuart_device);
263 #endif
264 }
265 #endif /* CONFIG_DM_SERIAL */
266 
267 #ifdef CONFIG_DM_SERIAL
pxa_serial_probe(struct udevice * dev)268 static int pxa_serial_probe(struct udevice *dev)
269 {
270 	struct pxa_serial_platdata *plat = dev->platdata;
271 
272 	pxa_setbrg_common((struct pxa_uart_regs *)plat->base, plat->port,
273 			  plat->baudrate);
274 	return 0;
275 }
276 
pxa_serial_putc(struct udevice * dev,const char ch)277 static int pxa_serial_putc(struct udevice *dev, const char ch)
278 {
279 	struct pxa_serial_platdata *plat = dev->platdata;
280 	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;
281 
282 	/* Wait for last character to go. */
283 	if (!(readl(&uart_regs->lsr) & LSR_TEMT))
284 		return -EAGAIN;
285 
286 	writel(ch, &uart_regs->thr);
287 
288 	return 0;
289 }
290 
pxa_serial_getc(struct udevice * dev)291 static int pxa_serial_getc(struct udevice *dev)
292 {
293 	struct pxa_serial_platdata *plat = dev->platdata;
294 	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;
295 
296 	/* Wait for a character to arrive. */
297 	if (!(readl(&uart_regs->lsr) & LSR_DR))
298 		return -EAGAIN;
299 
300 	return readl(&uart_regs->rbr) & 0xff;
301 }
302 
pxa_serial_setbrg(struct udevice * dev,int baudrate)303 int pxa_serial_setbrg(struct udevice *dev, int baudrate)
304 {
305 	struct pxa_serial_platdata *plat = dev->platdata;
306 	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;
307 	int port = plat->port;
308 
309 	pxa_setbrg_common(uart_regs, port, baudrate);
310 
311 	return 0;
312 }
313 
pxa_serial_pending(struct udevice * dev,bool input)314 static int pxa_serial_pending(struct udevice *dev, bool input)
315 {
316 	struct pxa_serial_platdata *plat = dev->platdata;
317 	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;
318 
319 	if (input)
320 		return readl(&uart_regs->lsr) & LSR_DR ? 1 : 0;
321 	else
322 		return readl(&uart_regs->lsr) & LSR_TEMT ? 0 : 1;
323 
324 	return 0;
325 }
326 
327 static const struct dm_serial_ops pxa_serial_ops = {
328 	.putc		= pxa_serial_putc,
329 	.pending	= pxa_serial_pending,
330 	.getc		= pxa_serial_getc,
331 	.setbrg		= pxa_serial_setbrg,
332 };
333 
334 U_BOOT_DRIVER(serial_pxa) = {
335 	.name	= "serial_pxa",
336 	.id	= UCLASS_SERIAL,
337 	.probe	= pxa_serial_probe,
338 	.ops	= &pxa_serial_ops,
339 	.flags	= DM_FLAG_PRE_RELOC,
340 };
341 #endif /* CONFIG_DM_SERIAL */
342