1// SPDX-License-Identifier: GPL-2.0 2/* 3 * MediaTek High-speed UART driver 4 * 5 * Copyright (C) 2018 MediaTek Inc. 6 * Author: Weijie Gao <weijie.gao@mediatek.com> 7 */ 8 9#include <clk.h> 10#include <common.h> 11#include <div64.h> 12#include <dm.h> 13#include <dm/device_compat.h> 14#include <errno.h> 15#include <log.h> 16#include <serial.h> 17#include <watchdog.h> 18#include <asm/global_data.h> 19#include <asm/io.h> 20#include <asm/types.h> 21#include <linux/err.h> 22#include <linux/printk.h> 23 24struct mtk_serial_regs { 25 u32 rbr; 26 u32 ier; 27 u32 fcr; 28 u32 lcr; 29 u32 mcr; 30 u32 lsr; 31 u32 msr; 32 u32 spr; 33 u32 mdr1; 34 u32 highspeed; 35 u32 sample_count; 36 u32 sample_point; 37 u32 fracdiv_l; 38 u32 fracdiv_m; 39 u32 escape_en; 40 u32 guard; 41 u32 rx_sel; 42}; 43 44#define thr rbr 45#define iir fcr 46#define dll rbr 47#define dlm ier 48 49#define UART_LCR_WLS_8 0x03 /* 8 bit character length */ 50#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ 51 52#define UART_LSR_DR 0x01 /* Data ready */ 53#define UART_LSR_THRE 0x20 /* Xmit holding register empty */ 54#define UART_LSR_TEMT 0x40 /* Xmitter empty */ 55 56#define UART_MCR_DTR 0x01 /* DTR */ 57#define UART_MCR_RTS 0x02 /* RTS */ 58 59#define UART_FCR_FIFO_EN 0x01 /* Fifo enable */ 60#define UART_FCR_RXSR 0x02 /* Receiver soft reset */ 61#define UART_FCR_TXSR 0x04 /* Transmitter soft reset */ 62 63#define UART_MCRVAL (UART_MCR_DTR | \ 64 UART_MCR_RTS) 65 66/* Clear & enable FIFOs */ 67#define UART_FCRVAL (UART_FCR_FIFO_EN | \ 68 UART_FCR_RXSR | \ 69 UART_FCR_TXSR) 70 71/* the data is correct if the real baud is within 3%. */ 72#define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100) 73#define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100) 74 75/* struct mtk_serial_priv - Structure holding all information used by the 76 * driver 77 * @regs: Register base of the serial port 78 * @clk: The baud clock device 79 * @fixed_clk_rate: Fallback fixed baud clock rate if baud clock 80 * device is not specified 81 * @force_highspeed: Force using high-speed mode 82 */ 83struct mtk_serial_priv { 84 struct mtk_serial_regs __iomem *regs; 85 struct clk clk; 86 u32 fixed_clk_rate; 87 bool force_highspeed; 88}; 89 90static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud, 91 uint clk_rate) 92{ 93 u32 quot, realbaud, samplecount = 1; 94 95 /* Special case for low baud clock */ 96 if (baud <= 115200 && clk_rate == 12000000) { 97 writel(3, &priv->regs->highspeed); 98 99 quot = DIV_ROUND_CLOSEST(clk_rate, 256 * baud); 100 if (quot == 0) 101 quot = 1; 102 103 samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); 104 105 realbaud = clk_rate / samplecount / quot; 106 if (realbaud > BAUD_ALLOW_MAX(baud) || 107 realbaud < BAUD_ALLOW_MIX(baud)) { 108 pr_info("baud %d can't be handled\n", baud); 109 } 110 111 goto set_baud; 112 } 113 114 if (priv->force_highspeed) 115 goto use_hs3; 116 117 if (baud <= 115200) { 118 writel(0, &priv->regs->highspeed); 119 quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud); 120 } else if (baud <= 576000) { 121 writel(2, &priv->regs->highspeed); 122 123 /* Set to next lower baudrate supported */ 124 if ((baud == 500000) || (baud == 576000)) 125 baud = 460800; 126 127 quot = DIV_ROUND_UP(clk_rate, 4 * baud); 128 } else { 129use_hs3: 130 writel(3, &priv->regs->highspeed); 131 132 quot = DIV_ROUND_UP(clk_rate, 256 * baud); 133 samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); 134 } 135 136set_baud: 137 /* set divisor */ 138 writel(UART_LCR_WLS_8 | UART_LCR_DLAB, &priv->regs->lcr); 139 writel(quot & 0xff, &priv->regs->dll); 140 writel((quot >> 8) & 0xff, &priv->regs->dlm); 141 writel(UART_LCR_WLS_8, &priv->regs->lcr); 142 143 /* set highspeed mode sample count & point */ 144 writel(samplecount - 1, &priv->regs->sample_count); 145 writel((samplecount - 2) >> 1, &priv->regs->sample_point); 146} 147 148static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch) 149{ 150 if (!(readl(&priv->regs->lsr) & UART_LSR_THRE)) 151 return -EAGAIN; 152 153 writel(ch, &priv->regs->thr); 154 155 if (ch == '\n') 156 schedule(); 157 158 return 0; 159} 160 161static int _mtk_serial_getc(struct mtk_serial_priv *priv) 162{ 163 if (!(readl(&priv->regs->lsr) & UART_LSR_DR)) 164 return -EAGAIN; 165 166 return readl(&priv->regs->rbr); 167} 168 169static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input) 170{ 171 if (input) 172 return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0; 173 else 174 return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1; 175} 176 177#if CONFIG_IS_ENABLED(DM_SERIAL) 178static int mtk_serial_setbrg(struct udevice *dev, int baudrate) 179{ 180 struct mtk_serial_priv *priv = dev_get_priv(dev); 181 u32 clk_rate; 182 183 clk_rate = clk_get_rate(&priv->clk); 184 if (IS_ERR_VALUE(clk_rate) || clk_rate == 0) 185 clk_rate = priv->fixed_clk_rate; 186 187 _mtk_serial_setbrg(priv, baudrate, clk_rate); 188 189 return 0; 190} 191 192static int mtk_serial_putc(struct udevice *dev, const char ch) 193{ 194 struct mtk_serial_priv *priv = dev_get_priv(dev); 195 196 return _mtk_serial_putc(priv, ch); 197} 198 199static int mtk_serial_getc(struct udevice *dev) 200{ 201 struct mtk_serial_priv *priv = dev_get_priv(dev); 202 203 return _mtk_serial_getc(priv); 204} 205 206static int mtk_serial_pending(struct udevice *dev, bool input) 207{ 208 struct mtk_serial_priv *priv = dev_get_priv(dev); 209 210 return _mtk_serial_pending(priv, input); 211} 212 213static int mtk_serial_probe(struct udevice *dev) 214{ 215 struct mtk_serial_priv *priv = dev_get_priv(dev); 216 217 /* Disable interrupt */ 218 writel(0, &priv->regs->ier); 219 220 writel(UART_MCRVAL, &priv->regs->mcr); 221 writel(UART_FCRVAL, &priv->regs->fcr); 222 223 return 0; 224} 225 226static int mtk_serial_of_to_plat(struct udevice *dev) 227{ 228 struct mtk_serial_priv *priv = dev_get_priv(dev); 229 fdt_addr_t addr; 230 int err; 231 232 addr = dev_read_addr(dev); 233 if (addr == FDT_ADDR_T_NONE) 234 return -EINVAL; 235 236 priv->regs = map_physmem(addr, 0, MAP_NOCACHE); 237 238 err = clk_get_by_index(dev, 0, &priv->clk); 239 if (err) { 240 err = dev_read_u32(dev, "clock-frequency", &priv->fixed_clk_rate); 241 if (err) { 242 dev_err(dev, "baud clock not defined\n"); 243 return -EINVAL; 244 } 245 } else { 246 err = clk_get_rate(&priv->clk); 247 if (IS_ERR_VALUE(err)) { 248 dev_err(dev, "invalid baud clock\n"); 249 return -EINVAL; 250 } 251 } 252 253 priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed"); 254 255 return 0; 256} 257 258static const struct dm_serial_ops mtk_serial_ops = { 259 .putc = mtk_serial_putc, 260 .pending = mtk_serial_pending, 261 .getc = mtk_serial_getc, 262 .setbrg = mtk_serial_setbrg, 263}; 264 265static const struct udevice_id mtk_serial_ids[] = { 266 { .compatible = "mediatek,hsuart" }, 267 { .compatible = "mediatek,mt6577-uart" }, 268 { } 269}; 270 271U_BOOT_DRIVER(serial_mtk) = { 272 .name = "serial_mtk", 273 .id = UCLASS_SERIAL, 274 .of_match = mtk_serial_ids, 275 .of_to_plat = mtk_serial_of_to_plat, 276 .priv_auto = sizeof(struct mtk_serial_priv), 277 .probe = mtk_serial_probe, 278 .ops = &mtk_serial_ops, 279 .flags = DM_FLAG_PRE_RELOC, 280}; 281#else 282 283DECLARE_GLOBAL_DATA_PTR; 284 285#define DECLARE_HSUART_PRIV(port) \ 286 static struct mtk_serial_priv mtk_hsuart##port = { \ 287 .regs = (struct mtk_serial_regs *)CFG_SYS_NS16550_COM##port, \ 288 .fixed_clk_rate = CFG_SYS_NS16550_CLK \ 289}; 290 291#define DECLARE_HSUART_FUNCTIONS(port) \ 292 static int mtk_serial##port##_init(void) \ 293 { \ 294 writel(0, &mtk_hsuart##port.regs->ier); \ 295 writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \ 296 writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \ 297 _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ 298 mtk_hsuart##port.fixed_clk_rate); \ 299 return 0 ; \ 300 } \ 301 static void mtk_serial##port##_setbrg(void) \ 302 { \ 303 _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ 304 mtk_hsuart##port.fixed_clk_rate); \ 305 } \ 306 static int mtk_serial##port##_getc(void) \ 307 { \ 308 int err; \ 309 do { \ 310 err = _mtk_serial_getc(&mtk_hsuart##port); \ 311 if (err == -EAGAIN) \ 312 schedule(); \ 313 } while (err == -EAGAIN); \ 314 return err >= 0 ? err : 0; \ 315 } \ 316 static int mtk_serial##port##_tstc(void) \ 317 { \ 318 return _mtk_serial_pending(&mtk_hsuart##port, true); \ 319 } \ 320 static void mtk_serial##port##_putc(const char c) \ 321 { \ 322 int err; \ 323 if (c == '\n') \ 324 mtk_serial##port##_putc('\r'); \ 325 do { \ 326 err = _mtk_serial_putc(&mtk_hsuart##port, c); \ 327 } while (err == -EAGAIN); \ 328 } \ 329 static void mtk_serial##port##_puts(const char *s) \ 330 { \ 331 while (*s) { \ 332 mtk_serial##port##_putc(*s++); \ 333 } \ 334 } 335 336/* Serial device descriptor */ 337#define INIT_HSUART_STRUCTURE(port, __name) { \ 338 .name = __name, \ 339 .start = mtk_serial##port##_init, \ 340 .stop = NULL, \ 341 .setbrg = mtk_serial##port##_setbrg, \ 342 .getc = mtk_serial##port##_getc, \ 343 .tstc = mtk_serial##port##_tstc, \ 344 .putc = mtk_serial##port##_putc, \ 345 .puts = mtk_serial##port##_puts, \ 346} 347 348#define DECLARE_HSUART(port, __name) \ 349 DECLARE_HSUART_PRIV(port); \ 350 DECLARE_HSUART_FUNCTIONS(port); \ 351 struct serial_device mtk_hsuart##port##_device = \ 352 INIT_HSUART_STRUCTURE(port, __name); 353 354#if !defined(CONFIG_CONS_INDEX) 355#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6) 356#error "Invalid console index value." 357#endif 358 359#if CONFIG_CONS_INDEX == 1 && !defined(CFG_SYS_NS16550_COM1) 360#error "Console port 1 defined but not configured." 361#elif CONFIG_CONS_INDEX == 2 && !defined(CFG_SYS_NS16550_COM2) 362#error "Console port 2 defined but not configured." 363#elif CONFIG_CONS_INDEX == 3 && !defined(CFG_SYS_NS16550_COM3) 364#error "Console port 3 defined but not configured." 365#elif CONFIG_CONS_INDEX == 4 && !defined(CFG_SYS_NS16550_COM4) 366#error "Console port 4 defined but not configured." 367#elif CONFIG_CONS_INDEX == 5 && !defined(CFG_SYS_NS16550_COM5) 368#error "Console port 5 defined but not configured." 369#elif CONFIG_CONS_INDEX == 6 && !defined(CFG_SYS_NS16550_COM6) 370#error "Console port 6 defined but not configured." 371#endif 372 373#if defined(CFG_SYS_NS16550_COM1) 374DECLARE_HSUART(1, "mtk-hsuart0"); 375#endif 376#if defined(CFG_SYS_NS16550_COM2) 377DECLARE_HSUART(2, "mtk-hsuart1"); 378#endif 379#if defined(CFG_SYS_NS16550_COM3) 380DECLARE_HSUART(3, "mtk-hsuart2"); 381#endif 382#if defined(CFG_SYS_NS16550_COM4) 383DECLARE_HSUART(4, "mtk-hsuart3"); 384#endif 385#if defined(CFG_SYS_NS16550_COM5) 386DECLARE_HSUART(5, "mtk-hsuart4"); 387#endif 388#if defined(CFG_SYS_NS16550_COM6) 389DECLARE_HSUART(6, "mtk-hsuart5"); 390#endif 391 392__weak struct serial_device *default_serial_console(void) 393{ 394#if CONFIG_CONS_INDEX == 1 395 return &mtk_hsuart1_device; 396#elif CONFIG_CONS_INDEX == 2 397 return &mtk_hsuart2_device; 398#elif CONFIG_CONS_INDEX == 3 399 return &mtk_hsuart3_device; 400#elif CONFIG_CONS_INDEX == 4 401 return &mtk_hsuart4_device; 402#elif CONFIG_CONS_INDEX == 5 403 return &mtk_hsuart5_device; 404#elif CONFIG_CONS_INDEX == 6 405 return &mtk_hsuart6_device; 406#else 407#error "Bad CONFIG_CONS_INDEX." 408#endif 409} 410 411void mtk_serial_initialize(void) 412{ 413#if defined(CFG_SYS_NS16550_COM1) 414 serial_register(&mtk_hsuart1_device); 415#endif 416#if defined(CFG_SYS_NS16550_COM2) 417 serial_register(&mtk_hsuart2_device); 418#endif 419#if defined(CFG_SYS_NS16550_COM3) 420 serial_register(&mtk_hsuart3_device); 421#endif 422#if defined(CFG_SYS_NS16550_COM4) 423 serial_register(&mtk_hsuart4_device); 424#endif 425#if defined(CFG_SYS_NS16550_COM5) 426 serial_register(&mtk_hsuart5_device); 427#endif 428#if defined(CFG_SYS_NS16550_COM6) 429 serial_register(&mtk_hsuart6_device); 430#endif 431} 432 433#endif 434 435#ifdef CONFIG_DEBUG_UART_MTK 436 437#include <debug_uart.h> 438 439static inline void _debug_uart_init(void) 440{ 441 struct mtk_serial_priv priv; 442 443 memset(&priv, 0, sizeof(struct mtk_serial_priv)); 444 priv.regs = (void *) CONFIG_VAL(DEBUG_UART_BASE); 445 priv.fixed_clk_rate = CONFIG_DEBUG_UART_CLOCK; 446 447 writel(0, &priv.regs->ier); 448 writel(UART_MCRVAL, &priv.regs->mcr); 449 writel(UART_FCRVAL, &priv.regs->fcr); 450 451 _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE, priv.fixed_clk_rate); 452} 453 454static inline void _debug_uart_putc(int ch) 455{ 456 struct mtk_serial_regs __iomem *regs = 457 (void *) CONFIG_VAL(DEBUG_UART_BASE); 458 459 while (!(readl(®s->lsr) & UART_LSR_THRE)) 460 ; 461 462 writel(ch, ®s->thr); 463} 464 465DEBUG_UART_FUNCS 466 467#endif 468