1 // SPDX-License-Identifier: GPL-2.0
3 * MediaTek High-speed UART driver
5 * Copyright (C) 2018 MediaTek Inc.
13 #include <dm/device_compat.h>
18 #include <asm/global_data.h>
20 #include <asm/types.h>
21 #include <linux/err.h>
23 struct mtk_serial_regs {
48 #define UART_LCR_WLS_8 0x03 /* 8 bit character length */
49 #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
51 #define UART_LSR_DR 0x01 /* Data ready */
52 #define UART_LSR_THRE 0x20 /* Xmit holding register empty */
53 #define UART_LSR_TEMT 0x40 /* Xmitter empty */
55 #define UART_MCR_DTR 0x01 /* DTR */
56 #define UART_MCR_RTS 0x02 /* RTS */
58 #define UART_FCR_FIFO_EN 0x01 /* Fifo enable */
59 #define UART_FCR_RXSR 0x02 /* Receiver soft reset */
60 #define UART_FCR_TXSR 0x04 /* Transmitter soft reset */
62 #define UART_MCRVAL (UART_MCR_DTR | \
65 /* Clear & enable FIFOs */
66 #define UART_FCRVAL (UART_FCR_FIFO_EN | \
70 /* the data is correct if the real baud is within 3%. */
71 #define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100)
72 #define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100)
74 /* struct mtk_serial_priv - Structure holding all information used by the
76 * @regs: Register base of the serial port
77 * @clk: The baud clock device
78 * @fixed_clk_rate: Fallback fixed baud clock rate if baud clock
79 * device is not specified
80 * @force_highspeed: Force using high-speed mode
82 struct mtk_serial_priv {
83 struct mtk_serial_regs __iomem *regs;
89 static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud,
92 u32 quot, realbaud, samplecount = 1;
94 /* Special case for low baud clock */
95 if (baud <= 115200 && clk_rate == 12000000) {
96 writel(3, &priv->regs->highspeed);
98 quot = DIV_ROUND_CLOSEST(clk_rate, 256 * baud);
102 samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud);
104 realbaud = clk_rate / samplecount / quot;
105 if (realbaud > BAUD_ALLOW_MAX(baud) ||
106 realbaud < BAUD_ALLOW_MIX(baud)) {
107 pr_info("baud %d can't be handled\n", baud);
113 if (priv->force_highspeed)
116 if (baud <= 115200) {
117 writel(0, &priv->regs->highspeed);
118 quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud);
119 } else if (baud <= 576000) {
120 writel(2, &priv->regs->highspeed);
122 /* Set to next lower baudrate supported */
123 if ((baud == 500000) || (baud == 576000))
126 quot = DIV_ROUND_UP(clk_rate, 4 * baud);
129 writel(3, &priv->regs->highspeed);
131 quot = DIV_ROUND_UP(clk_rate, 256 * baud);
132 samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud);
137 writel(UART_LCR_WLS_8 | UART_LCR_DLAB, &priv->regs->lcr);
138 writel(quot & 0xff, &priv->regs->dll);
139 writel((quot >> 8) & 0xff, &priv->regs->dlm);
140 writel(UART_LCR_WLS_8, &priv->regs->lcr);
142 /* set highspeed mode sample count & point */
143 writel(samplecount - 1, &priv->regs->sample_count);
144 writel((samplecount - 2) >> 1, &priv->regs->sample_point);
147 static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch)
149 if (!(readl(&priv->regs->lsr) & UART_LSR_THRE))
152 writel(ch, &priv->regs->thr);
160 static int _mtk_serial_getc(struct mtk_serial_priv *priv)
162 if (!(readl(&priv->regs->lsr) & UART_LSR_DR))
165 return readl(&priv->regs->rbr);
168 static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input)
171 return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0;
173 return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
176 #if CONFIG_IS_ENABLED(DM_SERIAL)
177 static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
179 struct mtk_serial_priv *priv = dev_get_priv(dev);
182 clk_rate = clk_get_rate(&priv->clk);
183 if (IS_ERR_VALUE(clk_rate) || clk_rate == 0)
184 clk_rate = priv->fixed_clk_rate;
186 _mtk_serial_setbrg(priv, baudrate, clk_rate);
191 static int mtk_serial_putc(struct udevice *dev, const char ch)
193 struct mtk_serial_priv *priv = dev_get_priv(dev);
195 return _mtk_serial_putc(priv, ch);
198 static int mtk_serial_getc(struct udevice *dev)
200 struct mtk_serial_priv *priv = dev_get_priv(dev);
202 return _mtk_serial_getc(priv);
205 static int mtk_serial_pending(struct udevice *dev, bool input)
207 struct mtk_serial_priv *priv = dev_get_priv(dev);
209 return _mtk_serial_pending(priv, input);
212 static int mtk_serial_probe(struct udevice *dev)
214 struct mtk_serial_priv *priv = dev_get_priv(dev);
216 /* Disable interrupt */
217 writel(0, &priv->regs->ier);
219 writel(UART_MCRVAL, &priv->regs->mcr);
220 writel(UART_FCRVAL, &priv->regs->fcr);
225 static int mtk_serial_of_to_plat(struct udevice *dev)
227 struct mtk_serial_priv *priv = dev_get_priv(dev);
231 addr = dev_read_addr(dev);
232 if (addr == FDT_ADDR_T_NONE)
235 priv->regs = map_physmem(addr, 0, MAP_NOCACHE);
237 err = clk_get_by_index(dev, 0, &priv->clk);
239 err = dev_read_u32(dev, "clock-frequency", &priv->fixed_clk_rate);
241 dev_err(dev, "baud clock not defined\n");
245 err = clk_get_rate(&priv->clk);
246 if (IS_ERR_VALUE(err)) {
247 dev_err(dev, "invalid baud clock\n");
252 priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed");
257 static const struct dm_serial_ops mtk_serial_ops = {
258 .putc = mtk_serial_putc,
259 .pending = mtk_serial_pending,
260 .getc = mtk_serial_getc,
261 .setbrg = mtk_serial_setbrg,
264 static const struct udevice_id mtk_serial_ids[] = {
265 { .compatible = "mediatek,hsuart" },
266 { .compatible = "mediatek,mt6577-uart" },
270 U_BOOT_DRIVER(serial_mtk) = {
271 .name = "serial_mtk",
273 .of_match = mtk_serial_ids,
274 .of_to_plat = mtk_serial_of_to_plat,
275 .priv_auto = sizeof(struct mtk_serial_priv),
276 .probe = mtk_serial_probe,
277 .ops = &mtk_serial_ops,
278 .flags = DM_FLAG_PRE_RELOC,
282 DECLARE_GLOBAL_DATA_PTR;
284 #define DECLARE_HSUART_PRIV(port) \
285 static struct mtk_serial_priv mtk_hsuart##port = { \
286 .regs = (struct mtk_serial_regs *)CFG_SYS_NS16550_COM##port, \
287 .fixed_clk_rate = CFG_SYS_NS16550_CLK \
290 #define DECLARE_HSUART_FUNCTIONS(port) \
291 static int mtk_serial##port##_init(void) \
293 writel(0, &mtk_hsuart##port.regs->ier); \
294 writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \
295 writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \
296 _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \
297 mtk_hsuart##port.fixed_clk_rate); \
300 static void mtk_serial##port##_setbrg(void) \
302 _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \
303 mtk_hsuart##port.fixed_clk_rate); \
305 static int mtk_serial##port##_getc(void) \
309 err = _mtk_serial_getc(&mtk_hsuart##port); \
310 if (err == -EAGAIN) \
312 } while (err == -EAGAIN); \
313 return err >= 0 ? err : 0; \
315 static int mtk_serial##port##_tstc(void) \
317 return _mtk_serial_pending(&mtk_hsuart##port, true); \
319 static void mtk_serial##port##_putc(const char c) \
323 mtk_serial##port##_putc('\r'); \
325 err = _mtk_serial_putc(&mtk_hsuart##port, c); \
326 } while (err == -EAGAIN); \
328 static void mtk_serial##port##_puts(const char *s) \
331 mtk_serial##port##_putc(*s++); \
335 /* Serial device descriptor */
336 #define INIT_HSUART_STRUCTURE(port, __name) { \
338 .start = mtk_serial##port##_init, \
340 .setbrg = mtk_serial##port##_setbrg, \
341 .getc = mtk_serial##port##_getc, \
342 .tstc = mtk_serial##port##_tstc, \
343 .putc = mtk_serial##port##_putc, \
344 .puts = mtk_serial##port##_puts, \
347 #define DECLARE_HSUART(port, __name) \
348 DECLARE_HSUART_PRIV(port); \
349 DECLARE_HSUART_FUNCTIONS(port); \
350 struct serial_device mtk_hsuart##port##_device = \
351 INIT_HSUART_STRUCTURE(port, __name);
353 #if !defined(CONFIG_CONS_INDEX)
354 #elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6)
355 #error "Invalid console index value."
358 #if CONFIG_CONS_INDEX == 1 && !defined(CFG_SYS_NS16550_COM1)
359 #error "Console port 1 defined but not configured."
360 #elif CONFIG_CONS_INDEX == 2 && !defined(CFG_SYS_NS16550_COM2)
361 #error "Console port 2 defined but not configured."
362 #elif CONFIG_CONS_INDEX == 3 && !defined(CFG_SYS_NS16550_COM3)
363 #error "Console port 3 defined but not configured."
364 #elif CONFIG_CONS_INDEX == 4 && !defined(CFG_SYS_NS16550_COM4)
365 #error "Console port 4 defined but not configured."
366 #elif CONFIG_CONS_INDEX == 5 && !defined(CFG_SYS_NS16550_COM5)
367 #error "Console port 5 defined but not configured."
368 #elif CONFIG_CONS_INDEX == 6 && !defined(CFG_SYS_NS16550_COM6)
369 #error "Console port 6 defined but not configured."
372 #if defined(CFG_SYS_NS16550_COM1)
373 DECLARE_HSUART(1, "mtk-hsuart0");
375 #if defined(CFG_SYS_NS16550_COM2)
376 DECLARE_HSUART(2, "mtk-hsuart1");
378 #if defined(CFG_SYS_NS16550_COM3)
379 DECLARE_HSUART(3, "mtk-hsuart2");
381 #if defined(CFG_SYS_NS16550_COM4)
382 DECLARE_HSUART(4, "mtk-hsuart3");
384 #if defined(CFG_SYS_NS16550_COM5)
385 DECLARE_HSUART(5, "mtk-hsuart4");
387 #if defined(CFG_SYS_NS16550_COM6)
388 DECLARE_HSUART(6, "mtk-hsuart5");
391 __weak struct serial_device *default_serial_console(void)
393 #if CONFIG_CONS_INDEX == 1
394 return &mtk_hsuart1_device;
395 #elif CONFIG_CONS_INDEX == 2
396 return &mtk_hsuart2_device;
397 #elif CONFIG_CONS_INDEX == 3
398 return &mtk_hsuart3_device;
399 #elif CONFIG_CONS_INDEX == 4
400 return &mtk_hsuart4_device;
401 #elif CONFIG_CONS_INDEX == 5
402 return &mtk_hsuart5_device;
403 #elif CONFIG_CONS_INDEX == 6
404 return &mtk_hsuart6_device;
406 #error "Bad CONFIG_CONS_INDEX."
410 void mtk_serial_initialize(void)
412 #if defined(CFG_SYS_NS16550_COM1)
413 serial_register(&mtk_hsuart1_device);
415 #if defined(CFG_SYS_NS16550_COM2)
416 serial_register(&mtk_hsuart2_device);
418 #if defined(CFG_SYS_NS16550_COM3)
419 serial_register(&mtk_hsuart3_device);
421 #if defined(CFG_SYS_NS16550_COM4)
422 serial_register(&mtk_hsuart4_device);
424 #if defined(CFG_SYS_NS16550_COM5)
425 serial_register(&mtk_hsuart5_device);
427 #if defined(CFG_SYS_NS16550_COM6)
428 serial_register(&mtk_hsuart6_device);
434 #ifdef CONFIG_DEBUG_UART_MTK
436 #include <debug_uart.h>
438 static inline void _debug_uart_init(void)
440 struct mtk_serial_priv priv;
442 priv.regs = (void *) CONFIG_VAL(DEBUG_UART_BASE);
443 priv.fixed_clk_rate = CONFIG_DEBUG_UART_CLOCK;
445 writel(0, &priv.regs->ier);
446 writel(UART_MCRVAL, &priv.regs->mcr);
447 writel(UART_FCRVAL, &priv.regs->fcr);
449 _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE, priv.fixed_clk_rate);
452 static inline void _debug_uart_putc(int ch)
454 struct mtk_serial_regs __iomem *regs =
455 (void *) CONFIG_VAL(DEBUG_UART_BASE);
457 while (!(readl(®s->lsr) & UART_LSR_THRE))
460 writel(ch, ®s->thr);