Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2008, Google Inc. |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * * Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * * Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in |
| 12 | * the documentation and/or other materials provided with the |
| 13 | * distribution. |
| 14 | * * Neither the name of Google, Inc. nor the names of its contributors |
| 15 | * may be used to endorse or promote products derived from this |
| 16 | * software without specific prior written permission. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 22 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| 25 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| 26 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| 28 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 29 | * SUCH DAMAGE. |
| 30 | */ |
| 31 | |
Brian Swetland | c82fda9 | 2009-01-02 01:53:42 -0800 | [diff] [blame] | 32 | #include <debug.h> |
| 33 | |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 34 | #include <platform/iomap.h> |
| 35 | #include <dev/uart.h> |
| 36 | #include <reg.h> |
| 37 | |
| 38 | #define UART_MR1 0x0000 |
| 39 | |
| 40 | #define UART_MR1_AUTO_RFR_LEVEL0(n) (((n) & 0x3f) << 8) |
| 41 | #define UART_MR1_RX_RDY_CTL (1 << 7) |
| 42 | #define UART_MR1_CTS_CTL (1 << 6) |
| 43 | #define UART_MR1_AUTO_RFR_LEVEL1(n) ((n) & 0x3f) |
| 44 | |
| 45 | #define UART_MR2 0x0004 |
| 46 | #define UART_MR2_ERROR_MODE (1 << 6) |
| 47 | #define UART_MR2_BITS_PER_CHAR_5 (0 << 4) |
| 48 | #define UART_MR2_BITS_PER_CHAR_6 (1 << 4) |
| 49 | #define UART_MR2_BITS_PER_CHAR_7 (2 << 4) |
| 50 | #define UART_MR2_BITS_PER_CHAR_8 (3 << 4) |
| 51 | #define UART_MR2_STOP_BIT_LEN_0563 (0 << 2) |
| 52 | #define UART_MR2_STOP_BIT_LEN_1000 (1 << 2) |
| 53 | #define UART_MR2_STOP_BIT_LEN_1563 (2 << 2) |
| 54 | #define UART_MR2_STOP_BIT_LEN_2000 (3 << 2) |
| 55 | #define UART_MR2_PARITY_MODE_NONE (0) |
| 56 | #define UART_MR2_PARITY_MODE_ODD (1) |
| 57 | #define UART_MR2_PARITY_MODE_EVEN (2) |
| 58 | #define UART_MR2_PARITY_MODE_SPACE (3) |
| 59 | |
| 60 | #define UART_CSR 0x0008 |
| 61 | #define UART_CSR_115200 0xFF |
| 62 | #define UART_CSR_57600 0xEE |
| 63 | #define UART_CSR_38400 0xDD |
| 64 | #define UART_CSR_19200 0xBB |
| 65 | |
| 66 | #define UART_TF 0x000C |
| 67 | |
| 68 | #define UART_CR 0x0010 |
| 69 | #define UART_CR_CMD_NULL (0 << 4) |
| 70 | #define UART_CR_CMD_RESET_RX (1 << 4) |
| 71 | #define UART_CR_CMD_RESET_TX (2 << 4) |
| 72 | #define UART_CR_CMD_RESET_ERR (3 << 4) |
| 73 | #define UART_CR_CMD_RESET_BCI (4 << 4) |
| 74 | #define UART_CR_CMD_START_BREAK (5 << 4) |
| 75 | #define UART_CR_CMD_STOP_BREAK (6 << 4) |
| 76 | #define UART_CR_CMD_RESET_CTS_N (7 << 4) |
| 77 | #define UART_CR_CMD_PACKET_MODE (9 << 4) |
| 78 | #define UART_CR_CMD_MODE_RESET (12<< 4) |
| 79 | #define UART_CR_CMD_SET_RFR_N (13<< 4) |
| 80 | #define UART_CR_CMD_RESET_RFR_ND (14<< 4) |
| 81 | #define UART_CR_TX_DISABLE (1 << 3) |
| 82 | #define UART_CR_TX_ENABLE (1 << 3) |
| 83 | #define UART_CR_RX_DISABLE (1 << 3) |
| 84 | #define UART_CR_RX_ENABLE (1 << 3) |
| 85 | |
| 86 | #define UART_IMR 0x0014 |
| 87 | #define UART_IMR_RXLEV (1 << 4) |
| 88 | #define UART_IMR_TXLEV (1 << 0) |
| 89 | |
| 90 | #define UART_IPR 0x0018 |
| 91 | #define UART_TFWR 0x001C |
| 92 | #define UART_RFWR 0x0020 |
| 93 | #define UART_HCR 0x0024 |
| 94 | |
| 95 | #define UART_MREG 0x0028 |
| 96 | #define UART_NREG 0x002C |
| 97 | #define UART_DREG 0x0030 |
| 98 | #define UART_MNDREG 0x0034 |
| 99 | #define UART_IRDA 0x0038 |
| 100 | #define UART_MISR_MODE 0x0040 |
| 101 | #define UART_MISR_RESET 0x0044 |
| 102 | #define UART_MISR_EXPORT 0x0048 |
| 103 | #define UART_MISR_VAL 0x004C |
| 104 | #define UART_TEST_CTRL 0x0050 |
| 105 | |
| 106 | #define UART_SR 0x0008 |
| 107 | #define UART_SR_HUNT_CHAR (1 << 7) |
| 108 | #define UART_SR_RX_BREAK (1 << 6) |
| 109 | #define UART_SR_PAR_FRAME_ERR (1 << 5) |
| 110 | #define UART_SR_OVERRUN (1 << 4) |
| 111 | #define UART_SR_TX_EMPTY (1 << 3) |
| 112 | #define UART_SR_TX_READY (1 << 2) |
| 113 | #define UART_SR_RX_FULL (1 << 1) |
| 114 | #define UART_SR_RX_READY (1 << 0) |
| 115 | |
| 116 | #define UART_RF 0x000C |
| 117 | #define UART_MISR 0x0010 |
| 118 | #define UART_ISR 0x0014 |
| 119 | |
Brian Swetland | bfeab36 | 2009-01-29 17:28:40 -0800 | [diff] [blame] | 120 | static unsigned uart_ready = 0; |
Shashank Mittal | 1ddc04c | 2010-12-21 14:39:07 -0800 | [diff] [blame] | 121 | #if PLATFORM_MSM7X30 |
| 122 | static unsigned uart_base = MSM_UART2_BASE; |
Shashank Mittal | 2fad67f | 2011-04-08 19:45:10 -0700 | [diff] [blame] | 123 | #elif PLATFORM_MSM7X27A |
| 124 | static unsigned uart_base = MSM_UART1_BASE; |
Shashank Mittal | 1ddc04c | 2010-12-21 14:39:07 -0800 | [diff] [blame] | 125 | #else |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 126 | static unsigned uart_base = MSM_UART3_BASE; |
Shashank Mittal | 1ddc04c | 2010-12-21 14:39:07 -0800 | [diff] [blame] | 127 | #endif |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 128 | |
| 129 | #define uwr(v,a) writel(v, uart_base + (a)) |
| 130 | #define urd(a) readl(uart_base + (a)) |
| 131 | |
| 132 | void uart_init(void) |
| 133 | { |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 134 | uwr(0x0A, UART_CR); /* disable TX and RX */ |
| 135 | |
| 136 | uwr(0x30, UART_CR); /* reset error status */ |
| 137 | uwr(0x10, UART_CR); /* reset receiver */ |
| 138 | uwr(0x20, UART_CR); /* reset transmitter */ |
| 139 | |
Shashank Mittal | 2fad67f | 2011-04-08 19:45:10 -0700 | [diff] [blame] | 140 | #if PLATFORM_QSD8K || PLATFORM_MSM7X30 || PLATFORM_MSM7X27A |
Brian Swetland | d0da856 | 2009-01-25 02:38:19 -0800 | [diff] [blame] | 141 | /* TCXO */ |
| 142 | uwr(0x06, UART_MREG); |
| 143 | uwr(0xF1, UART_NREG); |
| 144 | uwr(0x0F, UART_DREG); |
| 145 | uwr(0x1A, UART_MNDREG); |
| 146 | #else |
| 147 | /* TCXO/4 */ |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 148 | uwr(0xC0, UART_MREG); |
| 149 | uwr(0xAF, UART_NREG); |
| 150 | uwr(0x80, UART_DREG); |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 151 | uwr(0x19, UART_MNDREG); |
Brian Swetland | d0da856 | 2009-01-25 02:38:19 -0800 | [diff] [blame] | 152 | #endif |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 153 | |
| 154 | uwr(0x10, UART_CR); /* reset RX */ |
| 155 | uwr(0x20, UART_CR); /* reset TX */ |
| 156 | uwr(0x30, UART_CR); /* reset error status */ |
| 157 | uwr(0x40, UART_CR); /* reset RX break */ |
| 158 | uwr(0x70, UART_CR); /* rest? */ |
| 159 | uwr(0xD0, UART_CR); /* reset */ |
| 160 | |
| 161 | uwr(0x7BF, UART_IPR); /* stale timeout = 630 * bitrate */ |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 162 | uwr(0, UART_IMR); |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 163 | uwr(115, UART_RFWR); /* RX watermark = 58 * 2 - 1 */ |
| 164 | uwr(10, UART_TFWR); /* TX watermark */ |
| 165 | |
| 166 | uwr(0, UART_RFWR); |
| 167 | |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 168 | uwr(UART_CSR_115200, UART_CSR); |
| 169 | uwr(0, UART_IRDA); |
| 170 | uwr(0x1E, UART_HCR); |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 171 | // uwr(0x7F4, UART_MR1); /* RFS/ CTS/ 500chr RFR */ |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 172 | uwr(16, UART_MR1); |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 173 | uwr(0x34, UART_MR2); /* 8N1 */ |
| 174 | |
| 175 | uwr(0x05, UART_CR); /* enable TX & RX */ |
Brian Swetland | bfeab36 | 2009-01-29 17:28:40 -0800 | [diff] [blame] | 176 | |
| 177 | uart_ready = 1; |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 178 | } |
| 179 | |
Shashank Mittal | 1ddc04c | 2010-12-21 14:39:07 -0800 | [diff] [blame] | 180 | static int _uart_putc(int port, char c) |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 181 | { |
Brian Swetland | bfeab36 | 2009-01-29 17:28:40 -0800 | [diff] [blame] | 182 | if (!uart_ready) |
| 183 | return -1; |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 184 | while (!(urd(UART_SR) & UART_SR_TX_READY)) ; |
| 185 | uwr(c, UART_TF); |
| 186 | return 0; |
| 187 | } |
| 188 | |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 189 | int uart_putc(int port, char c) |
Shashank Mittal | 1ddc04c | 2010-12-21 14:39:07 -0800 | [diff] [blame] | 190 | { |
Ajay Dudani | b01e506 | 2011-12-03 23:23:42 -0800 | [diff] [blame] | 191 | if (c == '\n') { |
Shashank Mittal | 1ddc04c | 2010-12-21 14:39:07 -0800 | [diff] [blame] | 192 | _uart_putc(0, '\r'); |
| 193 | } |
| 194 | _uart_putc(0, c); |
| 195 | } |
| 196 | |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 197 | int uart_getc(int port, bool wait) |
| 198 | { |
Brian Swetland | bfeab36 | 2009-01-29 17:28:40 -0800 | [diff] [blame] | 199 | if (!uart_ready) |
| 200 | return -1; |
Brian Swetland | c82fda9 | 2009-01-02 01:53:42 -0800 | [diff] [blame] | 201 | while (!(urd(UART_SR) & UART_SR_RX_READY)) |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 202 | if (!wait) |
| 203 | return -1; |
Brian Swetland | 2500aa1 | 2009-01-01 04:33:55 -0800 | [diff] [blame] | 204 | |
| 205 | return urd(UART_RF); |
| 206 | } |