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 /* disable everything */ 84 writel(0, ®s->pl011_cr); 85 break; 86 default: 87 return -EINVAL; 88 } 89 90 return 0; 91 } 92 93 static int pl011_set_line_control(struct pl01x_regs *regs) 94 { 95 unsigned int lcr; 96 /* 97 * Internal update of baud rate register require line 98 * control register write 99 */ 100 lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN; 101 writel(lcr, ®s->pl011_lcrh); 102 return 0; 103 } 104 105 static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, 106 int clock, int baudrate) 107 { 108 switch (type) { 109 case TYPE_PL010: { 110 unsigned int divisor; 111 112 /* disable everything */ 113 writel(0, ®s->pl010_cr); 114 115 switch (baudrate) { 116 case 9600: 117 divisor = UART_PL010_BAUD_9600; 118 break; 119 case 19200: 120 divisor = UART_PL010_BAUD_9600; 121 break; 122 case 38400: 123 divisor = UART_PL010_BAUD_38400; 124 break; 125 case 57600: 126 divisor = UART_PL010_BAUD_57600; 127 break; 128 case 115200: 129 divisor = UART_PL010_BAUD_115200; 130 break; 131 default: 132 divisor = UART_PL010_BAUD_38400; 133 } 134 135 writel((divisor & 0xf00) >> 8, ®s->pl010_lcrm); 136 writel(divisor & 0xff, ®s->pl010_lcrl); 137 138 /* 139 * Set line control for the PL010 to be 8 bits, 1 stop bit, 140 * no parity, fifo enabled 141 */ 142 writel(UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN, 143 ®s->pl010_lcrh); 144 /* Finally, enable the UART */ 145 writel(UART_PL010_CR_UARTEN, ®s->pl010_cr); 146 break; 147 } 148 case TYPE_PL011: { 149 unsigned int temp; 150 unsigned int divider; 151 unsigned int remainder; 152 unsigned int fraction; 153 154 /* 155 * Set baud rate 156 * 157 * IBRD = UART_CLK / (16 * BAUD_RATE) 158 * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) 159 * / (16 * BAUD_RATE)) 160 */ 161 temp = 16 * baudrate; 162 divider = clock / temp; 163 remainder = clock % temp; 164 temp = (8 * remainder) / baudrate; 165 fraction = (temp >> 1) + (temp & 1); 166 167 writel(divider, ®s->pl011_ibrd); 168 writel(fraction, ®s->pl011_fbrd); 169 170 pl011_set_line_control(regs); 171 /* Finally, enable the UART */ 172 writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | 173 UART_PL011_CR_RXE | UART_PL011_CR_RTS, ®s->pl011_cr); 174 break; 175 } 176 default: 177 return -EINVAL; 178 } 179 180 return 0; 181 } 182 183 #ifndef CONFIG_DM_SERIAL 184 static void pl01x_serial_init_baud(int baudrate) 185 { 186 int clock = 0; 187 188 #if defined(CONFIG_PL010_SERIAL) 189 pl01x_type = TYPE_PL010; 190 #elif defined(CONFIG_PL011_SERIAL) 191 pl01x_type = TYPE_PL011; 192 clock = CONFIG_PL011_CLOCK; 193 #endif 194 base_regs = (struct pl01x_regs *)port[CONFIG_CONS_INDEX]; 195 196 pl01x_generic_serial_init(base_regs, pl01x_type); 197 pl01x_generic_setbrg(base_regs, pl01x_type, clock, baudrate); 198 } 199 200 /* 201 * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 202 * Integrator CP has two UARTs, use the first one, at 38400-8-N-1 203 * Versatile PB has four UARTs. 204 */ 205 int pl01x_serial_init(void) 206 { 207 pl01x_serial_init_baud(CONFIG_BAUDRATE); 208 209 return 0; 210 } 211 212 static void pl01x_serial_putc(const char c) 213 { 214 if (c == '\n') 215 while (pl01x_putc(base_regs, '\r') == -EAGAIN); 216 217 while (pl01x_putc(base_regs, c) == -EAGAIN); 218 } 219 220 static int pl01x_serial_getc(void) 221 { 222 while (1) { 223 int ch = pl01x_getc(base_regs); 224 225 if (ch == -EAGAIN) { 226 WATCHDOG_RESET(); 227 continue; 228 } 229 230 return ch; 231 } 232 } 233 234 static int pl01x_serial_tstc(void) 235 { 236 return pl01x_tstc(base_regs); 237 } 238 239 static void pl01x_serial_setbrg(void) 240 { 241 /* 242 * Flush FIFO and wait for non-busy before changing baudrate to avoid 243 * crap in console 244 */ 245 while (!(readl(&base_regs->fr) & UART_PL01x_FR_TXFE)) 246 WATCHDOG_RESET(); 247 while (readl(&base_regs->fr) & UART_PL01x_FR_BUSY) 248 WATCHDOG_RESET(); 249 pl01x_serial_init_baud(gd->baudrate); 250 } 251 252 static struct serial_device pl01x_serial_drv = { 253 .name = "pl01x_serial", 254 .start = pl01x_serial_init, 255 .stop = NULL, 256 .setbrg = pl01x_serial_setbrg, 257 .putc = pl01x_serial_putc, 258 .puts = default_serial_puts, 259 .getc = pl01x_serial_getc, 260 .tstc = pl01x_serial_tstc, 261 }; 262 263 void pl01x_serial_initialize(void) 264 { 265 serial_register(&pl01x_serial_drv); 266 } 267 268 __weak struct serial_device *default_serial_console(void) 269 { 270 return &pl01x_serial_drv; 271 } 272 273 #endif /* nCONFIG_DM_SERIAL */ 274 275 #ifdef CONFIG_DM_SERIAL 276 277 struct pl01x_priv { 278 struct pl01x_regs *regs; 279 enum pl01x_type type; 280 }; 281 282 static int pl01x_serial_setbrg(struct udevice *dev, int baudrate) 283 { 284 struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 285 struct pl01x_priv *priv = dev_get_priv(dev); 286 287 pl01x_generic_setbrg(priv->regs, priv->type, plat->clock, baudrate); 288 289 return 0; 290 } 291 292 static int pl01x_serial_probe(struct udevice *dev) 293 { 294 struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 295 struct pl01x_priv *priv = dev_get_priv(dev); 296 297 priv->regs = (struct pl01x_regs *)plat->base; 298 priv->type = plat->type; 299 return pl01x_generic_serial_init(priv->regs, priv->type); 300 } 301 302 static int pl01x_serial_getc(struct udevice *dev) 303 { 304 struct pl01x_priv *priv = dev_get_priv(dev); 305 306 return pl01x_getc(priv->regs); 307 } 308 309 static int pl01x_serial_putc(struct udevice *dev, const char ch) 310 { 311 struct pl01x_priv *priv = dev_get_priv(dev); 312 313 return pl01x_putc(priv->regs, ch); 314 } 315 316 static int pl01x_serial_pending(struct udevice *dev, bool input) 317 { 318 struct pl01x_priv *priv = dev_get_priv(dev); 319 unsigned int fr = readl(&priv->regs->fr); 320 321 if (input) 322 return pl01x_tstc(priv->regs); 323 else 324 return fr & UART_PL01x_FR_TXFF ? 0 : 1; 325 } 326 327 static const struct dm_serial_ops pl01x_serial_ops = { 328 .putc = pl01x_serial_putc, 329 .pending = pl01x_serial_pending, 330 .getc = pl01x_serial_getc, 331 .setbrg = pl01x_serial_setbrg, 332 }; 333 334 #if CONFIG_IS_ENABLED(OF_CONTROL) 335 static const struct udevice_id pl01x_serial_id[] ={ 336 {.compatible = "arm,pl011", .data = TYPE_PL011}, 337 {.compatible = "arm,pl010", .data = TYPE_PL010}, 338 {} 339 }; 340 341 static int pl01x_serial_ofdata_to_platdata(struct udevice *dev) 342 { 343 struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 344 fdt_addr_t addr; 345 346 addr = dev_get_addr(dev); 347 if (addr == FDT_ADDR_T_NONE) 348 return -EINVAL; 349 350 plat->base = addr; 351 plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock", 1); 352 plat->type = dev_get_driver_data(dev); 353 return 0; 354 } 355 #endif 356 357 U_BOOT_DRIVER(serial_pl01x) = { 358 .name = "serial_pl01x", 359 .id = UCLASS_SERIAL, 360 .of_match = of_match_ptr(pl01x_serial_id), 361 .ofdata_to_platdata = of_match_ptr(pl01x_serial_ofdata_to_platdata), 362 .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata), 363 .probe = pl01x_serial_probe, 364 .ops = &pl01x_serial_ops, 365 .flags = DM_FLAG_PRE_RELOC, 366 .priv_auto_alloc_size = sizeof(struct pl01x_priv), 367 }; 368 369 #endif 370