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