xref: /optee_os/core/drivers/sprd_uart.c (revision 5a913ee74d3c71af2a2860ce8a4e7aeab2916f9b)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2016, Spreadtrum Communications Inc.
4  * Copyright (c) 2017, Linaro Limited
5  * All rights reserved.
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 #include <drivers/sprd_uart.h>
30 #include <io.h>
31 #include <keep.h>
32 #include <util.h>
33 
34 /* Register definitions */
35 #define UART_TXD		0x0000
36 #define UART_RXD		0x0004
37 #define UART_STS1		0x000C /* data number in TX and RX fifo */
38 
39 /* Register Bit Fields*/
40 #define STS1_RXF_CNT_MASK	0x00ff  /* Rx FIFO data counter mask */
41 #define STS1_TXF_CNT_MASK	0xff00 /* Tx FIFO data counter mask */
42 
43 static vaddr_t chip_to_base(struct serial_chip *chip)
44 {
45 	struct sprd_uart_data *pd =
46 		container_of(chip, struct sprd_uart_data, chip);
47 
48 	return io_pa_or_va(&pd->base);
49 }
50 
51 static void sprd_uart_flush(struct serial_chip *chip)
52 {
53 	vaddr_t base = chip_to_base(chip);
54 
55 	while (io_read32(base + UART_STS1) & STS1_TXF_CNT_MASK)
56 		;
57 }
58 
59 static bool sprd_uart_have_rx_data(struct serial_chip *chip)
60 {
61 	vaddr_t base = chip_to_base(chip);
62 
63 	return !!(io_read32(base + UART_STS1) & STS1_RXF_CNT_MASK);
64 }
65 
66 static void sprd_uart_putc(struct serial_chip *chip, int ch)
67 {
68 	vaddr_t base = chip_to_base(chip);
69 
70 	sprd_uart_flush(chip);
71 	io_write32(base + UART_TXD, ch);
72 }
73 
74 static int sprd_uart_getchar(struct serial_chip *chip)
75 {
76 	vaddr_t base = chip_to_base(chip);
77 
78 	while (!sprd_uart_have_rx_data(chip))
79 		;
80 
81 	return io_read32(base + UART_RXD) & 0xff;
82 }
83 
84 static const struct serial_ops sprd_uart_ops = {
85 	.flush = sprd_uart_flush,
86 	.getchar = sprd_uart_getchar,
87 	.have_rx_data = sprd_uart_have_rx_data,
88 	.putc = sprd_uart_putc,
89 };
90 KEEP_PAGER(sprd_uart_ops);
91 
92 void sprd_uart_init(struct sprd_uart_data *pd, paddr_t base)
93 {
94 	pd->base.pa = base;
95 	pd->chip.ops = &sprd_uart_ops;
96 }
97