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 #include <kernel/dt.h>
13 
14 /* uart register defines */
15 #define UART_RHR	0x0
16 #define UART_THR	0x0
17 #define UART_IER	0x4
18 #define UART_ISR	0x8
19 #define UART_FCR	0x8
20 #define UART_LCR	0xc
21 #define UART_MCR	0x10
22 #define UART_LSR	0x14
23 #define UART_MSR	0x18
24 #define UART_SPR	0x1c
25 
26 /* uart status register bits */
27 #define LSR_TEMT	0x40 /* Transmitter empty */
28 #define LSR_THRE	0x20 /* Transmit-hold-register empty */
29 #define LSR_EMPTY	(LSR_TEMT | LSR_THRE)
30 #define LSR_DR		0x01 /* DATA Ready */
31 
chip_to_base(struct serial_chip * chip)32 static vaddr_t chip_to_base(struct serial_chip *chip)
33 {
34 	struct serial8250_uart_data *pd =
35 		container_of(chip, struct serial8250_uart_data, chip);
36 
37 	return io_pa_or_va(&pd->base, SERIAL8250_UART_REG_SIZE);
38 }
39 
serial8250_uart_flush(struct serial_chip * chip)40 static void serial8250_uart_flush(struct serial_chip *chip)
41 {
42 	vaddr_t base = chip_to_base(chip);
43 
44 	while (1) {
45 		uint32_t state = io_read32(base + UART_LSR);
46 
47 		/* Wait until transmit FIFO is empty */
48 		if ((state & LSR_EMPTY) == LSR_EMPTY)
49 			break;
50 	}
51 }
52 
serial8250_uart_have_rx_data(struct serial_chip * chip)53 static bool serial8250_uart_have_rx_data(struct serial_chip *chip)
54 {
55 	vaddr_t base = chip_to_base(chip);
56 
57 	return (io_read32(base + UART_LSR) & LSR_DR);
58 }
59 
serial8250_uart_getchar(struct serial_chip * chip)60 static int serial8250_uart_getchar(struct serial_chip *chip)
61 {
62 	vaddr_t base = chip_to_base(chip);
63 
64 	while (!serial8250_uart_have_rx_data(chip)) {
65 		/* Transmit FIFO is empty, waiting again */
66 		;
67 	}
68 	return io_read32(base + UART_RHR) & 0xff;
69 }
70 
serial8250_uart_putc(struct serial_chip * chip,int ch)71 static void serial8250_uart_putc(struct serial_chip *chip, int ch)
72 {
73 	vaddr_t base = chip_to_base(chip);
74 
75 	serial8250_uart_flush(chip);
76 
77 	/* Write out character to transmit FIFO */
78 	io_write32(base + UART_THR, ch);
79 }
80 
81 static const struct serial_ops serial8250_uart_ops = {
82 	.flush = serial8250_uart_flush,
83 	.getchar = serial8250_uart_getchar,
84 	.have_rx_data = serial8250_uart_have_rx_data,
85 	.putc = serial8250_uart_putc,
86 };
87 DECLARE_KEEP_PAGER(serial8250_uart_ops);
88 
serial8250_uart_init(struct serial8250_uart_data * pd,paddr_t base,uint32_t __unused uart_clk,uint32_t __unused baud_rate)89 void serial8250_uart_init(struct serial8250_uart_data *pd, paddr_t base,
90 			  uint32_t __unused uart_clk,
91 			  uint32_t __unused baud_rate)
92 
93 {
94 	pd->base.pa = base;
95 	pd->chip.ops = &serial8250_uart_ops;
96 
97 	/*
98 	 * do nothing, debug uart(uart0) share with normal world,
99 	 * everything for uart0 is ready now.
100 	 */
101 }
102 
103 #ifdef CFG_DT
104 
serial8250_uart_dev_alloc(void)105 static struct serial_chip *serial8250_uart_dev_alloc(void)
106 {
107 	struct serial8250_uart_data *pd = calloc(1, sizeof(*pd));
108 
109 	if (!pd)
110 		return NULL;
111 	return &pd->chip;
112 }
113 
serial8250_uart_dev_init(struct serial_chip * chip,const void * fdt,int offs,const char * parms)114 static int serial8250_uart_dev_init(struct serial_chip *chip,
115 			       const void *fdt,
116 			       int offs,
117 			       const char *parms)
118 {
119 	struct serial8250_uart_data *pd =
120 		container_of(chip, struct serial8250_uart_data, chip);
121 	vaddr_t vbase;
122 	paddr_t pbase;
123 	size_t size;
124 
125 	if (parms && parms[0])
126 		IMSG("serial8250_uart: device parameters ignored (%s)", parms);
127 
128 	if (dt_map_dev(fdt, offs, &vbase, &size, DT_MAP_AUTO) < 0)
129 		return -1;
130 
131 	if (size < SERIAL8250_UART_REG_SIZE) {
132 		EMSG("serial8250_uart: register size too small: %zx", size);
133 		return -1;
134 	}
135 
136 	pbase = virt_to_phys((void *)vbase);
137 	serial8250_uart_init(pd, pbase, 0, 0);
138 
139 	return 0;
140 }
141 
serial8250_uart_dev_free(struct serial_chip * chip)142 static void serial8250_uart_dev_free(struct serial_chip *chip)
143 {
144 	struct serial8250_uart_data *pd =
145 	  container_of(chip,  struct serial8250_uart_data, chip);
146 
147 	free(pd);
148 }
149 
150 static const struct serial_driver serial8250_driver = {
151 	.dev_alloc = serial8250_uart_dev_alloc,
152 	.dev_init = serial8250_uart_dev_init,
153 	.dev_free = serial8250_uart_dev_free,
154 };
155 
156 static const struct dt_device_match serial8250_match_table[] = {
157 	{ .compatible = "snps,dw-apb-uart" },
158 	{ 0 }
159 };
160 
161 DEFINE_DT_DRIVER(serial8250_dt_driver) = {
162 	.name = "serial8250_uart",
163 	.type = DT_DRIVER_UART,
164 	.match_table = serial8250_match_table,
165 	.driver = &serial8250_driver,
166 };
167 
168 #endif /* CFG_DT */
169