1 /* 2 * (C) Copyright 2000 3 * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. 4 * 5 * (C) Copyright 2004 6 * ARM Ltd. 7 * Philippe Robin, <philippe.robin@arm.com> 8 * 9 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 12 /* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */ 13 14 #include <common.h> 15 #include <dm.h> 16 #include <errno.h> 17 #include <watchdog.h> 18 #include <asm/io.h> 19 #include <serial.h> 20 #include <dm/platform_data/serial_pl01x.h> 21 #include <linux/compiler.h> 22 #include "serial_pl01x_internal.h" 23 #include <fdtdec.h> 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 #ifndef CONFIG_DM_SERIAL 28 29 static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS; 30 static enum pl01x_type pl01x_type __attribute__ ((section(".data"))); 31 static struct pl01x_regs *base_regs __attribute__ ((section(".data"))); 32 #define NUM_PORTS (sizeof(port)/sizeof(port[0])) 33 34 #endif 35 36 static int pl01x_putc(struct pl01x_regs *regs, char c) 37 { 38 /* Wait until there is space in the FIFO */ 39 if (readl(®s->fr) & UART_PL01x_FR_TXFF) 40 return -EAGAIN; 41 42 /* Send the character */ 43 writel(c, ®s->dr); 44 45 return 0; 46 } 47 48 static int pl01x_getc(struct pl01x_regs *regs) 49 { 50 unsigned int data; 51 52 /* Wait until there is data in the FIFO */ 53 if (readl(®s->fr) & UART_PL01x_FR_RXFE) 54 return -EAGAIN; 55 56 data = readl(®s->dr); 57 58 /* Check for an error flag */ 59 if (data & 0xFFFFFF00) { 60 /* Clear the error */ 61 writel(0xFFFFFFFF, ®s->ecr); 62 return -1; 63 } 64 65 return (int) data; 66 } 67 68 static int pl01x_tstc(struct pl01x_regs *regs) 69 { 70 WATCHDOG_RESET(); 71 return !(readl(®s->fr) & UART_PL01x_FR_RXFE); 72 } 73 74 static int pl01x_generic_serial_init(struct pl01x_regs *regs, 75 enum pl01x_type type) 76 { 77 switch (type) { 78 case TYPE_PL010: 79 /* disable everything */ 80 writel(0, ®s->pl010_cr); 81 break; 82 case TYPE_PL011: 83 #ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT 84 /* Empty RX fifo if necessary */ 85 if (readl(®s->pl011_cr) & UART_PL011_CR_UARTEN) { 86 while (!(readl(®s->fr) & UART_PL01x_FR_RXFE)) 87 readl(®s->dr); 88 } 89 #endif 90 /* disable everything */ 91 writel(0, ®s->pl011_cr); 92 break; 93 default: 94 return -EINVAL; 95 } 96 97 return 0; 98 } 99 100 static int pl011_set_line_control(struct pl01x_regs *regs) 101 { 102 unsigned int lcr; 103 /* 104 * Internal update of baud rate register require line 105 * control register write 106 */ 107 lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN; 108 #ifdef CONFIG_PL011_SERIAL_RLCR 109 { 110 int i; 111 112 /* 113 * Program receive line control register after waiting 114 * 10 bus cycles. Delay be writing to readonly register 115 * 10 times 116 */ 117 for (i = 0; i < 10; i++) 118 writel(lcr, ®s->fr); 119 120 writel(lcr, ®s->pl011_rlcr); 121 } 122 #endif 123 writel(lcr, ®s->pl011_lcrh); 124 return 0; 125 } 126 127 static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, 128 int clock, int baudrate) 129 { 130 switch (type) { 131 case TYPE_PL010: { 132 unsigned int divisor; 133 134 /* disable everything */ 135 writel(0, ®s->pl010_cr); 136 137 switch (baudrate) { 138 case 9600: 139 divisor = UART_PL010_BAUD_9600; 140 break; 141 case 19200: 142 divisor = UART_PL010_BAUD_9600; 143 break; 144 case 38400: 145 divisor = UART_PL010_BAUD_38400; 146 break; 147 case 57600: 148 divisor = UART_PL010_BAUD_57600; 149 break; 150 case 115200: 151 divisor = UART_PL010_BAUD_115200; 152 break; 153 default: 154 divisor = UART_PL010_BAUD_38400; 155 } 156 157 writel((divisor & 0xf00) >> 8, ®s->pl010_lcrm); 158 writel(divisor & 0xff, ®s->pl010_lcrl); 159 160 /* 161 * Set line control for the PL010 to be 8 bits, 1 stop bit, 162 * no parity, fifo enabled 163 */ 164 writel(UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN, 165 ®s->pl010_lcrh); 166 /* Finally, enable the UART */ 167 writel(UART_PL010_CR_UARTEN, ®s->pl010_cr); 168 break; 169 } 170 case TYPE_PL011: { 171 unsigned int temp; 172 unsigned int divider; 173 unsigned int remainder; 174 unsigned int fraction; 175 176 /* 177 * Set baud rate 178 * 179 * IBRD = UART_CLK / (16 * BAUD_RATE) 180 * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) 181 * / (16 * BAUD_RATE)) 182 */ 183 temp = 16 * baudrate; 184 divider = clock / temp; 185 remainder = clock % temp; 186 temp = (8 * remainder) / baudrate; 187 fraction = (temp >> 1) + (temp & 1); 188 189 writel(divider, ®s->pl011_ibrd); 190 writel(fraction, ®s->pl011_fbrd); 191 192 pl011_set_line_control(regs); 193 /* Finally, enable the UART */ 194 writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | 195 UART_PL011_CR_RXE | UART_PL011_CR_RTS, ®s->pl011_cr); 196 break; 197 } 198 default: 199 return -EINVAL; 200 } 201 202 return 0; 203 } 204 205 #ifndef CONFIG_DM_SERIAL 206 static void pl01x_serial_init_baud(int baudrate) 207 { 208 int clock = 0; 209 210 #if defined(CONFIG_PL010_SERIAL) 211 pl01x_type = TYPE_PL010; 212 #elif defined(CONFIG_PL011_SERIAL) 213 pl01x_type = TYPE_PL011; 214 clock = CONFIG_PL011_CLOCK; 215 #endif 216 base_regs = (struct pl01x_regs *)port[CONFIG_CONS_INDEX]; 217 218 pl01x_generic_serial_init(base_regs, pl01x_type); 219 pl01x_generic_setbrg(base_regs, pl01x_type, clock, baudrate); 220 } 221 222 /* 223 * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 224 * Integrator CP has two UARTs, use the first one, at 38400-8-N-1 225 * Versatile PB has four UARTs. 226 */ 227 int pl01x_serial_init(void) 228 { 229 pl01x_serial_init_baud(CONFIG_BAUDRATE); 230 231 return 0; 232 } 233 234 static void pl01x_serial_putc(const char c) 235 { 236 if (c == '\n') 237 while (pl01x_putc(base_regs, '\r') == -EAGAIN); 238 239 while (pl01x_putc(base_regs, c) == -EAGAIN); 240 } 241 242 static int pl01x_serial_getc(void) 243 { 244 while (1) { 245 int ch = pl01x_getc(base_regs); 246 247 if (ch == -EAGAIN) { 248 WATCHDOG_RESET(); 249 continue; 250 } 251 252 return ch; 253 } 254 } 255 256 static int pl01x_serial_tstc(void) 257 { 258 return pl01x_tstc(base_regs); 259 } 260 261 static void pl01x_serial_setbrg(void) 262 { 263 /* 264 * Flush FIFO and wait for non-busy before changing baudrate to avoid 265 * crap in console 266 */ 267 while (!(readl(&base_regs->fr) & UART_PL01x_FR_TXFE)) 268 WATCHDOG_RESET(); 269 while (readl(&base_regs->fr) & UART_PL01x_FR_BUSY) 270 WATCHDOG_RESET(); 271 pl01x_serial_init_baud(gd->baudrate); 272 } 273 274 static struct serial_device pl01x_serial_drv = { 275 .name = "pl01x_serial", 276 .start = pl01x_serial_init, 277 .stop = NULL, 278 .setbrg = pl01x_serial_setbrg, 279 .putc = pl01x_serial_putc, 280 .puts = default_serial_puts, 281 .getc = pl01x_serial_getc, 282 .tstc = pl01x_serial_tstc, 283 }; 284 285 void pl01x_serial_initialize(void) 286 { 287 serial_register(&pl01x_serial_drv); 288 } 289 290 __weak struct serial_device *default_serial_console(void) 291 { 292 return &pl01x_serial_drv; 293 } 294 295 #endif /* nCONFIG_DM_SERIAL */ 296 297 #ifdef CONFIG_DM_SERIAL 298 299 struct pl01x_priv { 300 struct pl01x_regs *regs; 301 enum pl01x_type type; 302 }; 303 304 static int pl01x_serial_setbrg(struct udevice *dev, int baudrate) 305 { 306 struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 307 struct pl01x_priv *priv = dev_get_priv(dev); 308 309 pl01x_generic_setbrg(priv->regs, priv->type, plat->clock, baudrate); 310 311 return 0; 312 } 313 314 static int pl01x_serial_probe(struct udevice *dev) 315 { 316 struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 317 struct pl01x_priv *priv = dev_get_priv(dev); 318 319 priv->regs = (struct pl01x_regs *)plat->base; 320 priv->type = plat->type; 321 return pl01x_generic_serial_init(priv->regs, priv->type); 322 } 323 324 static int pl01x_serial_getc(struct udevice *dev) 325 { 326 struct pl01x_priv *priv = dev_get_priv(dev); 327 328 return pl01x_getc(priv->regs); 329 } 330 331 static int pl01x_serial_putc(struct udevice *dev, const char ch) 332 { 333 struct pl01x_priv *priv = dev_get_priv(dev); 334 335 return pl01x_putc(priv->regs, ch); 336 } 337 338 static int pl01x_serial_pending(struct udevice *dev, bool input) 339 { 340 struct pl01x_priv *priv = dev_get_priv(dev); 341 unsigned int fr = readl(&priv->regs->fr); 342 343 if (input) 344 return pl01x_tstc(priv->regs); 345 else 346 return fr & UART_PL01x_FR_TXFF ? 0 : 1; 347 } 348 349 static const struct dm_serial_ops pl01x_serial_ops = { 350 .putc = pl01x_serial_putc, 351 .pending = pl01x_serial_pending, 352 .getc = pl01x_serial_getc, 353 .setbrg = pl01x_serial_setbrg, 354 }; 355 356 #if CONFIG_IS_ENABLED(OF_CONTROL) 357 static const struct udevice_id pl01x_serial_id[] ={ 358 {.compatible = "arm,pl011", .data = TYPE_PL011}, 359 {.compatible = "arm,pl010", .data = TYPE_PL010}, 360 {} 361 }; 362 363 static int pl01x_serial_ofdata_to_platdata(struct udevice *dev) 364 { 365 struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 366 fdt_addr_t addr; 367 368 addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); 369 if (addr == FDT_ADDR_T_NONE) 370 return -EINVAL; 371 372 plat->base = addr; 373 plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock", 1); 374 plat->type = dev_get_driver_data(dev); 375 return 0; 376 } 377 #endif 378 379 U_BOOT_DRIVER(serial_pl01x) = { 380 .name = "serial_pl01x", 381 .id = UCLASS_SERIAL, 382 .of_match = of_match_ptr(pl01x_serial_id), 383 .ofdata_to_platdata = of_match_ptr(pl01x_serial_ofdata_to_platdata), 384 .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata), 385 .probe = pl01x_serial_probe, 386 .ops = &pl01x_serial_ops, 387 .flags = DM_FLAG_PRE_RELOC, 388 .priv_auto_alloc_size = sizeof(struct pl01x_priv), 389 }; 390 391 #endif 392