1 /* 2 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 3 * 4 * (C) Copyright 2002 5 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> 6 * 7 * (C) Copyright 2002 8 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 9 * Marius Groeger <mgroeger@sysgo.de> 10 * 11 * (C) Copyright 2002 12 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 13 * Alex Zuepke <azu@sysgo.de> 14 * 15 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) 16 * 17 * This program is free software; you can redistribute it and/or modify 18 * it under the terms of the GNU General Public License as published by 19 * the Free Software Foundation; either version 2 of the License, or 20 * (at your option) any later version. 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 * 31 */ 32 33 #include <common.h> 34 #include <watchdog.h> 35 #include <serial.h> 36 #include <asm/arch/pxa-regs.h> 37 #include <asm/arch/regs-uart.h> 38 #include <asm/io.h> 39 40 DECLARE_GLOBAL_DATA_PTR; 41 42 /* 43 * The numbering scheme differs here for PXA25x, PXA27x and PXA3xx so we can 44 * easily handle enabling of clock. 45 */ 46 #ifdef CONFIG_CPU_MONAHANS 47 #define UART_CLK_BASE CKENA_21_BTUART 48 #define UART_CLK_REG CKENA 49 #define BTUART_INDEX 0 50 #define FFUART_INDEX 1 51 #define STUART_INDEX 2 52 #elif CONFIG_CPU_PXA25X 53 #define UART_CLK_BASE (1 << 4) /* HWUART */ 54 #define UART_CLK_REG CKEN 55 #define HWUART_INDEX 0 56 #define STUART_INDEX 1 57 #define FFUART_INDEX 2 58 #define BTUART_INDEX 3 59 #else /* PXA27x */ 60 #define UART_CLK_BASE CKEN5_STUART 61 #define UART_CLK_REG CKEN 62 #define STUART_INDEX 0 63 #define FFUART_INDEX 1 64 #define BTUART_INDEX 2 65 #endif 66 67 /* 68 * Only PXA250 has HWUART, to avoid poluting the code with more macros, 69 * artificially introduce this. 70 */ 71 #ifndef CONFIG_CPU_PXA25X 72 #define HWUART_INDEX 0xff 73 #endif 74 75 #ifndef CONFIG_SERIAL_MULTI 76 #if defined(CONFIG_FFUART) 77 #define UART_INDEX FFUART_INDEX 78 #elif defined(CONFIG_BTUART) 79 #define UART_INDEX BTUART_INDEX 80 #elif defined(CONFIG_STUART) 81 #define UART_INDEX STUART_INDEX 82 #elif defined(CONFIG_HWUART) 83 #define UART_INDEX HWUART_INDEX 84 #else 85 #error "Please select CONFIG_(FF|BT|ST|HW)UART in board config file." 86 #endif 87 #endif 88 89 uint32_t pxa_uart_get_baud_divider(void) 90 { 91 if (gd->baudrate == 1200) 92 return 768; 93 else if (gd->baudrate == 9600) 94 return 96; 95 else if (gd->baudrate == 19200) 96 return 48; 97 else if (gd->baudrate == 38400) 98 return 24; 99 else if (gd->baudrate == 57600) 100 return 16; 101 else if (gd->baudrate == 115200) 102 return 8; 103 else /* Unsupported baudrate */ 104 return 0; 105 } 106 107 struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index) 108 { 109 switch (uart_index) { 110 case FFUART_INDEX: return (struct pxa_uart_regs *)FFUART_BASE; 111 case BTUART_INDEX: return (struct pxa_uart_regs *)BTUART_BASE; 112 case STUART_INDEX: return (struct pxa_uart_regs *)STUART_BASE; 113 case HWUART_INDEX: return (struct pxa_uart_regs *)HWUART_BASE; 114 default: 115 return NULL; 116 } 117 } 118 119 void pxa_uart_toggle_clock(uint32_t uart_index, int enable) 120 { 121 uint32_t clk_reg, clk_offset, reg; 122 123 clk_reg = UART_CLK_REG; 124 clk_offset = UART_CLK_BASE << uart_index; 125 126 reg = readl(clk_reg); 127 128 if (enable) 129 reg |= clk_offset; 130 else 131 reg &= ~clk_offset; 132 133 writel(reg, clk_reg); 134 } 135 136 /* 137 * Enable clock and set baud rate, parity etc. 138 */ 139 void pxa_setbrg_dev(uint32_t uart_index) 140 { 141 uint32_t divider = 0; 142 struct pxa_uart_regs *uart_regs; 143 144 divider = pxa_uart_get_baud_divider(); 145 if (!divider) 146 hang(); 147 148 uart_regs = pxa_uart_index_to_regs(uart_index); 149 if (!uart_regs) 150 hang(); 151 152 pxa_uart_toggle_clock(uart_index, 1); 153 154 /* Disable interrupts and FIFOs */ 155 writel(0, &uart_regs->ier); 156 writel(0, &uart_regs->fcr); 157 158 /* Set baud rate */ 159 writel(LCR_WLS0 | LCR_WLS1 | LCR_DLAB, &uart_regs->lcr); 160 writel(divider & 0xff, &uart_regs->dll); 161 writel(divider >> 8, &uart_regs->dlh); 162 writel(LCR_WLS0 | LCR_WLS1, &uart_regs->lcr); 163 164 /* Enable UART */ 165 writel(IER_UUE, &uart_regs->ier); 166 } 167 168 /* 169 * Initialise the serial port with the given baudrate. The settings 170 * are always 8 data bits, no parity, 1 stop bit, no start bits. 171 */ 172 int pxa_init_dev(unsigned int uart_index) 173 { 174 pxa_setbrg_dev (uart_index); 175 return 0; 176 } 177 178 /* 179 * Output a single byte to the serial port. 180 */ 181 void pxa_putc_dev(unsigned int uart_index, const char c) 182 { 183 struct pxa_uart_regs *uart_regs; 184 185 uart_regs = pxa_uart_index_to_regs(uart_index); 186 if (!uart_regs) 187 hang(); 188 189 while (!(readl(&uart_regs->lsr) & LSR_TEMT)) 190 WATCHDOG_RESET(); 191 writel(c, &uart_regs->thr); 192 193 /* If \n, also do \r */ 194 if (c == '\n') 195 pxa_putc_dev (uart_index,'\r'); 196 } 197 198 /* 199 * Read a single byte from the serial port. Returns 1 on success, 0 200 * otherwise. When the function is succesfull, the character read is 201 * written into its argument c. 202 */ 203 int pxa_tstc_dev(unsigned int uart_index) 204 { 205 struct pxa_uart_regs *uart_regs; 206 207 uart_regs = pxa_uart_index_to_regs(uart_index); 208 if (!uart_regs) 209 return -1; 210 211 return readl(&uart_regs->lsr) & LSR_DR; 212 } 213 214 /* 215 * Read a single byte from the serial port. Returns 1 on success, 0 216 * otherwise. When the function is succesfull, the character read is 217 * written into its argument c. 218 */ 219 int pxa_getc_dev(unsigned int uart_index) 220 { 221 struct pxa_uart_regs *uart_regs; 222 223 uart_regs = pxa_uart_index_to_regs(uart_index); 224 if (!uart_regs) 225 return -1; 226 227 while (!(readl(&uart_regs->lsr) & LSR_DR)) 228 WATCHDOG_RESET(); 229 return readl(&uart_regs->rbr) & 0xff; 230 } 231 232 void pxa_puts_dev(unsigned int uart_index, const char *s) 233 { 234 while (*s) 235 pxa_putc_dev(uart_index, *s++); 236 } 237 238 #define pxa_uart(uart, UART) \ 239 int uart##_init(void) \ 240 { \ 241 return pxa_init_dev(UART##_INDEX); \ 242 } \ 243 \ 244 void uart##_setbrg(void) \ 245 { \ 246 return pxa_setbrg_dev(UART##_INDEX); \ 247 } \ 248 \ 249 void uart##_putc(const char c) \ 250 { \ 251 return pxa_putc_dev(UART##_INDEX, c); \ 252 } \ 253 \ 254 void uart##_puts(const char *s) \ 255 { \ 256 return pxa_puts_dev(UART##_INDEX, s); \ 257 } \ 258 \ 259 int uart##_getc(void) \ 260 { \ 261 return pxa_getc_dev(UART##_INDEX); \ 262 } \ 263 \ 264 int uart##_tstc(void) \ 265 { \ 266 return pxa_tstc_dev(UART##_INDEX); \ 267 } \ 268 269 #define pxa_uart_desc(uart) \ 270 struct serial_device serial_##uart##_device = \ 271 { \ 272 "serial_"#uart, \ 273 uart##_init, \ 274 NULL, \ 275 uart##_setbrg, \ 276 uart##_getc, \ 277 uart##_tstc, \ 278 uart##_putc, \ 279 uart##_puts, \ 280 }; 281 282 #define pxa_uart_multi(uart, UART) \ 283 pxa_uart(uart, UART) \ 284 pxa_uart_desc(uart) 285 286 #if defined(CONFIG_HWUART) 287 pxa_uart_multi(hwuart, HWUART) 288 #endif 289 #if defined(CONFIG_STUART) 290 pxa_uart_multi(stuart, STUART) 291 #endif 292 #if defined(CONFIG_FFUART) 293 pxa_uart_multi(ffuart, FFUART) 294 #endif 295 #if defined(CONFIG_BTUART) 296 pxa_uart_multi(btuart, BTUART) 297 #endif 298 299 #ifndef CONFIG_SERIAL_MULTI 300 pxa_uart(serial, UART) 301 #endif 302