blob: d276fd0410afaa3f05e981c728d432511791489d [file] [log] [blame]
Stefan Reinauer4885daa2011-04-26 23:47:04 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2003 Eric Biederman
5 * Copyright (C) 2006-2010 coresystems GmbH
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
Patrick Georgib890a122015-03-26 15:17:45 +010018 * Foundation, Inc.
Stefan Reinauer4885daa2011-04-26 23:47:04 +000019 */
20
21#include <arch/io.h>
Kyösti Mälkki1d7541f2014-02-17 21:34:42 +020022#include <console/uart.h>
Stefan Reinauer4885daa2011-04-26 23:47:04 +000023#include <device/device.h>
Stefan Reinauer47818002012-03-30 16:19:31 -070024#include <delay.h>
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020025#include <stdint.h>
Kyösti Mälkkibea6bf02014-01-30 15:45:16 +020026#include "uart8250reg.h"
Stefan Reinauer4885daa2011-04-26 23:47:04 +000027
28/* Should support 8250, 16450, 16550, 16550A type UARTs */
29
Stefan Reinauer47818002012-03-30 16:19:31 -070030/* Expected character delay at 1200bps is 9ms for a working UART
31 * and no flow-control. Assume UART as stuck if shift register
32 * or FIFO takes more than 50ms per character to appear empty.
33 */
34#define SINGLE_CHAR_TIMEOUT (50 * 1000)
35#define FIFO_TIMEOUT (16 * SINGLE_CHAR_TIMEOUT)
36
Naveen Krishna Chatradhia73408d2015-07-08 14:23:06 +053037#if IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM_32)
38static uint8_t uart8250_read(void *base, uint8_t reg)
39{
40 return read32(base + 4 * reg) & 0xff;
41}
42
43static void uart8250_write(void *base, uint8_t reg, uint8_t data)
44{
45 write32(base + 4 * reg, data);
46}
47#else
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020048static uint8_t uart8250_read(void *base, uint8_t reg)
Stefan Reinauer4885daa2011-04-26 23:47:04 +000049{
Kyösti Mälkki8517f942015-03-12 11:33:14 +020050 return read8(base + reg);
Stefan Reinauer4885daa2011-04-26 23:47:04 +000051}
52
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020053static void uart8250_write(void *base, uint8_t reg, uint8_t data)
54{
Kyösti Mälkki8517f942015-03-12 11:33:14 +020055 write8(base + reg, data);
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020056}
Naveen Krishna Chatradhia73408d2015-07-08 14:23:06 +053057#endif
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020058
59static int uart8250_mem_can_tx_byte(void *base)
60{
61 return uart8250_read(base, UART8250_LSR) & UART8250_LSR_THRE;
62}
63
64static void uart8250_mem_tx_byte(void *base, unsigned char data)
Stefan Reinauer4885daa2011-04-26 23:47:04 +000065{
Stefan Reinauer47818002012-03-30 16:19:31 -070066 unsigned long int i = SINGLE_CHAR_TIMEOUT;
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020067 while(i-- && !uart8250_mem_can_tx_byte(base))
Stefan Reinauer47818002012-03-30 16:19:31 -070068 udelay(1);
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020069 uart8250_write(base, UART8250_TBR, data);
Stefan Reinauer4885daa2011-04-26 23:47:04 +000070}
71
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020072static void uart8250_mem_tx_flush(void *base)
Stefan Reinauer4885daa2011-04-26 23:47:04 +000073{
Stefan Reinauer47818002012-03-30 16:19:31 -070074 unsigned long int i = FIFO_TIMEOUT;
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020075 while(i-- && !(uart8250_read(base, UART8250_LSR) & UART8250_LSR_TEMT))
Stefan Reinauer47818002012-03-30 16:19:31 -070076 udelay(1);
Stefan Reinauer4885daa2011-04-26 23:47:04 +000077}
78
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020079static int uart8250_mem_can_rx_byte(void *base)
Stefan Reinauer4885daa2011-04-26 23:47:04 +000080{
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020081 return uart8250_read(base, UART8250_LSR) & UART8250_LSR_DR;
Stefan Reinauer4885daa2011-04-26 23:47:04 +000082}
83
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020084static unsigned char uart8250_mem_rx_byte(void *base)
Stefan Reinauer4885daa2011-04-26 23:47:04 +000085{
Stefan Reinauer47818002012-03-30 16:19:31 -070086 unsigned long int i = SINGLE_CHAR_TIMEOUT;
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020087 while(i-- && !uart8250_mem_can_rx_byte(base))
Stefan Reinauer47818002012-03-30 16:19:31 -070088 udelay(1);
89 if (i)
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020090 return uart8250_read(base, UART8250_RBR);
Stefan Reinauer47818002012-03-30 16:19:31 -070091 else
92 return 0x0;
Stefan Reinauer4885daa2011-04-26 23:47:04 +000093}
94
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020095static void uart8250_mem_init(void *base, unsigned divisor)
Stefan Reinauer4885daa2011-04-26 23:47:04 +000096{
97 /* Disable interrupts */
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +020098 uart8250_write(base, UART8250_IER, 0x0);
Stefan Reinauer4885daa2011-04-26 23:47:04 +000099 /* Enable FIFOs */
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200100 uart8250_write(base, UART8250_FCR, UART8250_FCR_FIFO_EN);
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000101
102 /* Assert DTR and RTS so the other end is happy */
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200103 uart8250_write(base, UART8250_MCR, UART8250_MCR_DTR | UART8250_MCR_RTS);
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000104
105 /* DLAB on */
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200106 uart8250_write(base, UART8250_LCR, UART8250_LCR_DLAB | CONFIG_TTYS0_LCS);
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000107
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200108 uart8250_write(base, UART8250_DLL, divisor & 0xFF);
109 uart8250_write(base, UART8250_DLM, (divisor >> 8) & 0xFF);
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000110
111 /* Set to 3 for 8N1 */
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200112 uart8250_write(base, UART8250_LCR, CONFIG_TTYS0_LCS);
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000113}
114
Kyösti Mälkki70342a72014-03-14 22:28:29 +0200115void uart_init(int idx)
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000116{
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200117 void *base = uart_platform_baseptr(idx);
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200118 if (!base)
119 return;
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000120
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200121 unsigned int div;
Kyösti Mälkki3ee16682014-02-17 19:37:52 +0200122 div = uart_baudrate_divisor(default_baudrate(), uart_platform_refclk(), 16);
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200123 uart8250_mem_init(base, div);
124}
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000125
Kyösti Mälkki70342a72014-03-14 22:28:29 +0200126void uart_tx_byte(int idx, unsigned char data)
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200127{
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200128 void *base = uart_platform_baseptr(idx);
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200129 if (!base)
130 return;
131 uart8250_mem_tx_byte(base, data);
132}
133
Kyösti Mälkki70342a72014-03-14 22:28:29 +0200134unsigned char uart_rx_byte(int idx)
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200135{
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200136 void *base = uart_platform_baseptr(idx);
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200137 if (!base)
138 return 0xff;
139 return uart8250_mem_rx_byte(base);
140}
141
Kyösti Mälkki70342a72014-03-14 22:28:29 +0200142void uart_tx_flush(int idx)
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200143{
Kyösti Mälkki164ac0a2014-12-13 16:39:40 +0200144 void *base = uart_platform_baseptr(idx);
Kyösti Mälkki2b95da02014-02-15 10:19:23 +0200145 if (!base)
146 return;
147 uart8250_mem_tx_flush(base);
Stefan Reinauer4885daa2011-04-26 23:47:04 +0000148}