xref: /optee_os/core/drivers/atmel_uart.c (revision e20d1bce8d23bb5994c08fadbce85a5c5712f247)
1*e20d1bceSAkshay Bhat /*
2*e20d1bceSAkshay Bhat  * Copyright (C) 2017 Timesys Corporation
3*e20d1bceSAkshay Bhat  * All rights reserved.
4*e20d1bceSAkshay Bhat  *
5*e20d1bceSAkshay Bhat  * Redistribution and use in source and binary forms, with or without
6*e20d1bceSAkshay Bhat  * modification, are permitted provided that the following conditions are met:
7*e20d1bceSAkshay Bhat  *
8*e20d1bceSAkshay Bhat  * 1. Redistributions of source code must retain the above copyright notice,
9*e20d1bceSAkshay Bhat  * this list of conditions and the following disclaimer.
10*e20d1bceSAkshay Bhat  *
11*e20d1bceSAkshay Bhat  * 2. Redistributions in binary form must reproduce the above copyright notice,
12*e20d1bceSAkshay Bhat  * this list of conditions and the following disclaimer in the documentation
13*e20d1bceSAkshay Bhat  * and/or other materials provided with the distribution.
14*e20d1bceSAkshay Bhat  *
15*e20d1bceSAkshay Bhat  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16*e20d1bceSAkshay Bhat  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*e20d1bceSAkshay Bhat  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*e20d1bceSAkshay Bhat  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19*e20d1bceSAkshay Bhat  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20*e20d1bceSAkshay Bhat  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21*e20d1bceSAkshay Bhat  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22*e20d1bceSAkshay Bhat  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*e20d1bceSAkshay Bhat  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24*e20d1bceSAkshay Bhat  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25*e20d1bceSAkshay Bhat  * POSSIBILITY OF SUCH DAMAGE.
26*e20d1bceSAkshay Bhat  */
27*e20d1bceSAkshay Bhat 
28*e20d1bceSAkshay Bhat #include <assert.h>
29*e20d1bceSAkshay Bhat #include <drivers/atmel_uart.h>
30*e20d1bceSAkshay Bhat #include <io.h>
31*e20d1bceSAkshay Bhat #include <keep.h>
32*e20d1bceSAkshay Bhat #include <util.h>
33*e20d1bceSAkshay Bhat 
34*e20d1bceSAkshay Bhat /* Register definitions */
35*e20d1bceSAkshay Bhat #define ATMEL_UART_CR		0x0000 /* Control Register */
36*e20d1bceSAkshay Bhat #define ATMEL_UART_MR		0x0004 /* Mode Register */
37*e20d1bceSAkshay Bhat #define ATMEL_UART_IER		0x0008 /* Interrupt Enable Register */
38*e20d1bceSAkshay Bhat #define ATMEL_UART_IDR		0x000c /* Interrupt Disable Register */
39*e20d1bceSAkshay Bhat #define ATMEL_UART_IMR		0x0010 /* Interrupt Mask Register */
40*e20d1bceSAkshay Bhat #define ATMEL_UART_SR		0x0014 /* Status Register */
41*e20d1bceSAkshay Bhat 	#define	ATMEL_SR_RXRDY		BIT(0)	/* Receiver Ready */
42*e20d1bceSAkshay Bhat 	#define	ATMEL_SR_TXRDY		BIT(1)	/* Transmitter Ready */
43*e20d1bceSAkshay Bhat 	#define	ATMEL_SR_TXEMPTY	BIT(1)	/* Transmitter Ready */
44*e20d1bceSAkshay Bhat #define ATMEL_UART_RHR		0x0018 /* Receive Holding Register */
45*e20d1bceSAkshay Bhat #define ATMEL_UART_THR		0x001c /* Transmit Holding Register */
46*e20d1bceSAkshay Bhat #define ATMEL_UART_BRGR		0x0020 /* Baud Rate Generator Register */
47*e20d1bceSAkshay Bhat #define ATMEL_UART_CMPR		0x0024 /* Comparison Register */
48*e20d1bceSAkshay Bhat #define ATMEL_UART_RTOR		0x0028 /* Receiver Time-out Register */
49*e20d1bceSAkshay Bhat #define ATMEL_UART_WPMR		0x00e4 /* Write Protect Mode Register */
50*e20d1bceSAkshay Bhat 
51*e20d1bceSAkshay Bhat static vaddr_t chip_to_base(struct serial_chip *chip)
52*e20d1bceSAkshay Bhat {
53*e20d1bceSAkshay Bhat 	struct atmel_uart_data *pd =
54*e20d1bceSAkshay Bhat 		container_of(chip, struct atmel_uart_data, chip);
55*e20d1bceSAkshay Bhat 
56*e20d1bceSAkshay Bhat 	return io_pa_or_va(&pd->base);
57*e20d1bceSAkshay Bhat }
58*e20d1bceSAkshay Bhat 
59*e20d1bceSAkshay Bhat static void atmel_uart_flush(struct serial_chip *chip)
60*e20d1bceSAkshay Bhat {
61*e20d1bceSAkshay Bhat 	vaddr_t base = chip_to_base(chip);
62*e20d1bceSAkshay Bhat 
63*e20d1bceSAkshay Bhat 	while (!(read32(base + ATMEL_UART_SR) & ATMEL_SR_TXEMPTY))
64*e20d1bceSAkshay Bhat 		;
65*e20d1bceSAkshay Bhat }
66*e20d1bceSAkshay Bhat 
67*e20d1bceSAkshay Bhat static int atmel_uart_getchar(struct serial_chip *chip)
68*e20d1bceSAkshay Bhat {
69*e20d1bceSAkshay Bhat 	vaddr_t base = chip_to_base(chip);
70*e20d1bceSAkshay Bhat 
71*e20d1bceSAkshay Bhat 	while (read32(base + ATMEL_UART_SR) & ATMEL_SR_RXRDY)
72*e20d1bceSAkshay Bhat 		;
73*e20d1bceSAkshay Bhat 
74*e20d1bceSAkshay Bhat 	return read32(base + ATMEL_UART_RHR);
75*e20d1bceSAkshay Bhat }
76*e20d1bceSAkshay Bhat 
77*e20d1bceSAkshay Bhat static void atmel_uart_putc(struct serial_chip *chip, int ch)
78*e20d1bceSAkshay Bhat {
79*e20d1bceSAkshay Bhat 	vaddr_t base = chip_to_base(chip);
80*e20d1bceSAkshay Bhat 
81*e20d1bceSAkshay Bhat 	while (!(read32(base + ATMEL_UART_SR) & ATMEL_SR_TXRDY))
82*e20d1bceSAkshay Bhat 		;
83*e20d1bceSAkshay Bhat 
84*e20d1bceSAkshay Bhat 	write32(ch, base + ATMEL_UART_THR);
85*e20d1bceSAkshay Bhat }
86*e20d1bceSAkshay Bhat 
87*e20d1bceSAkshay Bhat static const struct serial_ops atmel_uart_ops = {
88*e20d1bceSAkshay Bhat 	.flush = atmel_uart_flush,
89*e20d1bceSAkshay Bhat 	.getchar = atmel_uart_getchar,
90*e20d1bceSAkshay Bhat 	.putc = atmel_uart_putc,
91*e20d1bceSAkshay Bhat };
92*e20d1bceSAkshay Bhat 
93*e20d1bceSAkshay Bhat void atmel_uart_init(struct atmel_uart_data *pd, paddr_t base)
94*e20d1bceSAkshay Bhat {
95*e20d1bceSAkshay Bhat 	pd->base.pa = base;
96*e20d1bceSAkshay Bhat 	pd->chip.ops = &atmel_uart_ops;
97*e20d1bceSAkshay Bhat 
98*e20d1bceSAkshay Bhat 	/*
99*e20d1bceSAkshay Bhat 	 * Do nothing, debug uart share with normal world,
100*e20d1bceSAkshay Bhat 	 * everything for uart initialization is done in bootloader.
101*e20d1bceSAkshay Bhat 	 */
102*e20d1bceSAkshay Bhat }
103