xref: /optee_os/core/drivers/serial8250_uart.c (revision b1d7375c01ec8bcbf3561d27425d320afed23bce)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2015, Linaro Limited
4  */
5 
6 #include <compiler.h>
7 #include <console.h>
8 #include <drivers/serial8250_uart.h>
9 #include <io.h>
10 #include <keep.h>
11 #include <util.h>
12 
13 /* uart register defines */
14 #define UART_RHR	0x0
15 #define UART_THR	0x0
16 #define UART_IER	0x4
17 #define UART_ISR	0x8
18 #define UART_FCR	0x8
19 #define UART_LCR	0xc
20 #define UART_MCR	0x10
21 #define UART_LSR	0x14
22 #define UART_MSR	0x18
23 #define UART_SPR	0x1c
24 
25 /* uart status register bits */
26 #define LSR_TEMT	0x40 /* Transmitter empty */
27 #define LSR_THRE	0x20 /* Transmit-hold-register empty */
28 #define LSR_EMPTY	(LSR_TEMT | LSR_THRE)
29 #define LSR_DR		0x01 /* DATA Ready */
30 
31 static vaddr_t chip_to_base(struct serial_chip *chip)
32 {
33 	struct serial8250_uart_data *pd =
34 		container_of(chip, struct serial8250_uart_data, chip);
35 
36 	return io_pa_or_va(&pd->base);
37 }
38 
39 static void serial8250_uart_flush(struct serial_chip *chip)
40 {
41 	vaddr_t base = chip_to_base(chip);
42 
43 	while (1) {
44 		uint32_t state = read32(base + UART_LSR);
45 
46 		/* Wait until transmit FIFO is empty */
47 		if ((state & LSR_EMPTY) == LSR_EMPTY)
48 			break;
49 	}
50 }
51 
52 static bool serial8250_uart_have_rx_data(struct serial_chip *chip)
53 {
54 	vaddr_t base = chip_to_base(chip);
55 
56 	return (read32(base + UART_LSR) & LSR_DR);
57 }
58 
59 static int serial8250_uart_getchar(struct serial_chip *chip)
60 {
61 	vaddr_t base = chip_to_base(chip);
62 
63 	while (!serial8250_uart_have_rx_data(chip)) {
64 		/* Transmit FIFO is empty, waiting again */
65 		;
66 	}
67 	return read32(base + UART_RHR) & 0xff;
68 }
69 
70 static void serial8250_uart_putc(struct serial_chip *chip, int ch)
71 {
72 	vaddr_t base = chip_to_base(chip);
73 
74 	serial8250_uart_flush(chip);
75 
76 	/* Write out character to transmit FIFO */
77 	write32(ch, base + UART_THR);
78 }
79 
80 static const struct serial_ops serial8250_uart_ops = {
81 	.flush = serial8250_uart_flush,
82 	.getchar = serial8250_uart_getchar,
83 	.have_rx_data = serial8250_uart_have_rx_data,
84 	.putc = serial8250_uart_putc,
85 };
86 KEEP_PAGER(serial8250_uart_ops);
87 
88 void serial8250_uart_init(struct serial8250_uart_data *pd, paddr_t base,
89 			  uint32_t __unused uart_clk,
90 			  uint32_t __unused baud_rate)
91 
92 {
93 	pd->base.pa = base;
94 	pd->chip.ops = &serial8250_uart_ops;
95 
96 	/*
97 	 * do nothing, debug uart(uart0) share with normal world,
98 	 * everything for uart0 is ready now.
99 	 */
100 }
101