1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * NETLOGIC_BSD 31 * $FreeBSD$ 32 */ 33 34#ifndef __XLP_HAL_UART_H__ 35#define __XLP_HAL_UART_H__ 36 37/* UART Specific registers */ 38#define UART_RX_DATA 0x00 39#define UART_TX_DATA 0x00 40 41#define UART_INT_EN 0x01 42#define UART_INT_ID 0x02 43#define UART_FIFO_CTL 0x02 44#define UART_LINE_CTL 0x03 45#define UART_MODEM_CTL 0x04 46#define UART_LINE_STS 0x05 47#define UART_MODEM_STS 0x06 48 49#define UART_DIVISOR0 0x00 50#define UART_DIVISOR1 0x01 51 52#define BASE_BAUD (XLP_IO_CLK/16) 53#define BAUD_DIVISOR(baud) (BASE_BAUD / baud) 54 55/* LCR mask values */ 56#define LCR_5BITS 0x00 57#define LCR_6BITS 0x01 58#define LCR_7BITS 0x02 59#define LCR_8BITS 0x03 60#define LCR_STOPB 0x04 61#define LCR_PENAB 0x08 62#define LCR_PODD 0x00 63#define LCR_PEVEN 0x10 64#define LCR_PONE 0x20 65#define LCR_PZERO 0x30 66#define LCR_SBREAK 0x40 67#define LCR_EFR_ENABLE 0xbf 68#define LCR_DLAB 0x80 69 70/* MCR mask values */ 71#define MCR_DTR 0x01 72#define MCR_RTS 0x02 73#define MCR_DRS 0x04 74#define MCR_IE 0x08 75#define MCR_LOOPBACK 0x10 76 77/* FCR mask values */ 78#define FCR_RCV_RST 0x02 79#define FCR_XMT_RST 0x04 80#define FCR_RX_LOW 0x00 81#define FCR_RX_MEDL 0x40 82#define FCR_RX_MEDH 0x80 83#define FCR_RX_HIGH 0xc0 84 85/* IER mask values */ 86#define IER_ERXRDY 0x1 87#define IER_ETXRDY 0x2 88#define IER_ERLS 0x4 89#define IER_EMSC 0x8 90 91#if !defined(LOCORE) && !defined(__ASSEMBLY__) 92 93#define nlm_read_uart_reg(b, r) nlm_read_reg(b, r) 94#define nlm_write_uart_reg(b, r, v) nlm_write_reg(b, r, v) 95#define nlm_get_uart_pcibase(node, inst) \ 96 nlm_pcicfg_base(XLP_IO_UART_OFFSET(node, inst)) 97#define nlm_get_uart_regbase(node, inst) \ 98 (nlm_get_uart_pcibase(node, inst) + XLP_IO_PCI_HDRSZ) 99 100static inline void 101nlm_uart_set_baudrate(uint64_t base, int baud) 102{ 103 uint32_t lcr; 104 105 lcr = nlm_read_uart_reg(base, UART_LINE_CTL); 106 107 /* enable divisor register, and write baud values */ 108 nlm_write_uart_reg(base, UART_LINE_CTL, lcr | (1 << 7)); 109 nlm_write_uart_reg(base, UART_DIVISOR0, 110 (BAUD_DIVISOR(baud) & 0xff)); 111 nlm_write_uart_reg(base, UART_DIVISOR1, 112 ((BAUD_DIVISOR(baud) >> 8) & 0xff)); 113 114 /* restore default lcr */ 115 nlm_write_uart_reg(base, UART_LINE_CTL, lcr); 116} 117 118static inline void 119nlm_uart_outbyte(uint64_t base, char c) 120{ 121 uint32_t lsr; 122 123 for (;;) { 124 lsr = nlm_read_uart_reg(base, UART_LINE_STS); 125 if (lsr & 0x20) 126 break; 127 } 128 129 nlm_write_uart_reg(base, UART_TX_DATA, (int)c); 130} 131 132static inline char 133nlm_uart_inbyte(uint64_t base) 134{ 135 int data, lsr; 136 137 for (;;) { 138 lsr = nlm_read_uart_reg(base, UART_LINE_STS); 139 if (lsr & 0x80) { /* parity/frame/break-error - push a zero */ 140 data = 0; 141 break; 142 } 143 if (lsr & 0x01) { /* Rx data */ 144 data = nlm_read_uart_reg(base, UART_RX_DATA); 145 break; 146 } 147 } 148 149 return (char)data; 150} 151 152static inline int 153nlm_uart_init(uint64_t base, int baud, int databits, int stopbits, 154 int parity, int int_en, int loopback) 155{ 156 uint32_t lcr; 157 158 lcr = 0; 159 if (databits >= 8) 160 lcr |= LCR_8BITS; 161 else if (databits == 7) 162 lcr |= LCR_7BITS; 163 else if (databits == 6) 164 lcr |= LCR_6BITS; 165 else 166 lcr |= LCR_5BITS; 167 168 if (stopbits > 1) 169 lcr |= LCR_STOPB; 170 171 lcr |= parity << 3; 172 173 /* setup default lcr */ 174 nlm_write_uart_reg(base, UART_LINE_CTL, lcr); 175 176 /* Reset the FIFOs */ 177 nlm_write_uart_reg(base, UART_LINE_CTL, FCR_RCV_RST | FCR_XMT_RST); 178 179 nlm_uart_set_baudrate(base, baud); 180 181 if (loopback) 182 nlm_write_uart_reg(base, UART_MODEM_CTL, 0x1f); 183 184 if (int_en) 185 nlm_write_uart_reg(base, UART_INT_EN, IER_ERXRDY | IER_ETXRDY); 186 187 return 0; 188} 189#endif /* !LOCORE && !__ASSEMBLY__ */ 190#endif /* __XLP_HAL_UART_H__ */ 191