1 // SPDX-License-Identifier: GPL-2.0
3 * MediaTek High-speed UART driver
5 * Copyright (C) 2018 MediaTek Inc.
6 * Author: Weijie Gao <weijie.gao@mediatek.com>
17 #include <asm/types.h>
19 struct mtk_serial_regs
{
44 #define UART_LCR_WLS_8 0x03 /* 8 bit character length */
45 #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
47 #define UART_LSR_DR 0x01 /* Data ready */
48 #define UART_LSR_THRE 0x20 /* Xmit holding register empty */
50 /* the data is correct if the real baud is within 3%. */
51 #define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100)
52 #define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100)
54 struct mtk_serial_priv
{
55 struct mtk_serial_regs __iomem
*regs
;
59 static void _mtk_serial_setbrg(struct mtk_serial_priv
*priv
, int baud
)
61 bool support_clk12m_baud115200
;
62 u32 quot
, samplecount
, realbaud
;
64 if ((baud
<= 115200) && (priv
->clock
== 12000000))
65 support_clk12m_baud115200
= true;
67 support_clk12m_baud115200
= false;
70 writel(0, &priv
->regs
->highspeed
);
71 quot
= DIV_ROUND_CLOSEST(priv
->clock
, 16 * baud
);
73 if (support_clk12m_baud115200
) {
74 writel(3, &priv
->regs
->highspeed
);
75 quot
= DIV_ROUND_CLOSEST(priv
->clock
, 256 * baud
);
79 samplecount
= DIV_ROUND_CLOSEST(priv
->clock
,
81 if (samplecount
!= 0) {
82 realbaud
= priv
->clock
/ samplecount
/ quot
;
83 if ((realbaud
> BAUD_ALLOW_MAX(baud
)) ||
84 (realbaud
< BAUD_ALLOW_MIX(baud
))) {
85 pr_info("baud %d can't be handled\n",
89 pr_info("samplecount is 0\n");
92 } else if (baud
<= 576000) {
93 writel(2, &priv
->regs
->highspeed
);
95 /* Set to next lower baudrate supported */
96 if ((baud
== 500000) || (baud
== 576000))
98 quot
= DIV_ROUND_UP(priv
->clock
, 4 * baud
);
100 writel(3, &priv
->regs
->highspeed
);
101 quot
= DIV_ROUND_UP(priv
->clock
, 256 * baud
);
105 writel(UART_LCR_WLS_8
| UART_LCR_DLAB
, &priv
->regs
->lcr
);
106 writel(quot
& 0xff, &priv
->regs
->dll
);
107 writel((quot
>> 8) & 0xff, &priv
->regs
->dlm
);
108 writel(UART_LCR_WLS_8
, &priv
->regs
->lcr
);
113 tmp
= DIV_ROUND_CLOSEST(priv
->clock
, quot
* baud
);
114 writel(tmp
- 1, &priv
->regs
->sample_count
);
115 writel((tmp
- 2) >> 1, &priv
->regs
->sample_point
);
117 writel(0, &priv
->regs
->sample_count
);
118 writel(0xff, &priv
->regs
->sample_point
);
121 if (support_clk12m_baud115200
) {
122 writel(samplecount
- 1, &priv
->regs
->sample_count
);
123 writel((samplecount
- 2) >> 1, &priv
->regs
->sample_point
);
127 static int mtk_serial_setbrg(struct udevice
*dev
, int baudrate
)
129 struct mtk_serial_priv
*priv
= dev_get_priv(dev
);
131 _mtk_serial_setbrg(priv
, baudrate
);
136 static int mtk_serial_putc(struct udevice
*dev
, const char ch
)
138 struct mtk_serial_priv
*priv
= dev_get_priv(dev
);
140 if (!(readl(&priv
->regs
->lsr
) & UART_LSR_THRE
))
143 writel(ch
, &priv
->regs
->thr
);
151 static int mtk_serial_getc(struct udevice
*dev
)
153 struct mtk_serial_priv
*priv
= dev_get_priv(dev
);
155 if (!(readl(&priv
->regs
->lsr
) & UART_LSR_DR
))
158 return readl(&priv
->regs
->rbr
);
161 static int mtk_serial_pending(struct udevice
*dev
, bool input
)
163 struct mtk_serial_priv
*priv
= dev_get_priv(dev
);
166 return (readl(&priv
->regs
->lsr
) & UART_LSR_DR
) ? 1 : 0;
168 return (readl(&priv
->regs
->lsr
) & UART_LSR_THRE
) ? 0 : 1;
171 static int mtk_serial_probe(struct udevice
*dev
)
173 struct mtk_serial_priv
*priv
= dev_get_priv(dev
);
175 /* Disable interrupt */
176 writel(0, &priv
->regs
->ier
);
181 static int mtk_serial_ofdata_to_platdata(struct udevice
*dev
)
183 struct mtk_serial_priv
*priv
= dev_get_priv(dev
);
188 addr
= dev_read_addr(dev
);
189 if (addr
== FDT_ADDR_T_NONE
)
192 priv
->regs
= map_physmem(addr
, 0, MAP_NOCACHE
);
194 err
= clk_get_by_index(dev
, 0, &clk
);
196 err
= clk_get_rate(&clk
);
197 if (!IS_ERR_VALUE(err
))
199 } else if (err
!= -ENOENT
&& err
!= -ENODEV
&& err
!= -ENOSYS
) {
200 debug("mtk_serial: failed to get clock\n");
205 priv
->clock
= dev_read_u32_default(dev
, "clock-frequency", 0);
208 debug("mtk_serial: clock not defined\n");
215 static const struct dm_serial_ops mtk_serial_ops
= {
216 .putc
= mtk_serial_putc
,
217 .pending
= mtk_serial_pending
,
218 .getc
= mtk_serial_getc
,
219 .setbrg
= mtk_serial_setbrg
,
222 static const struct udevice_id mtk_serial_ids
[] = {
223 { .compatible
= "mediatek,hsuart" },
224 { .compatible
= "mediatek,mt6577-uart" },
228 U_BOOT_DRIVER(serial_mtk
) = {
229 .name
= "serial_mtk",
231 .of_match
= mtk_serial_ids
,
232 .ofdata_to_platdata
= mtk_serial_ofdata_to_platdata
,
233 .priv_auto_alloc_size
= sizeof(struct mtk_serial_priv
),
234 .probe
= mtk_serial_probe
,
235 .ops
= &mtk_serial_ops
,
236 .flags
= DM_FLAG_PRE_RELOC
,
239 #ifdef CONFIG_DEBUG_UART_MTK
241 #include <debug_uart.h>
243 static inline void _debug_uart_init(void)
245 struct mtk_serial_priv priv
;
247 priv
.regs
= (void *) CONFIG_DEBUG_UART_BASE
;
248 priv
.clock
= CONFIG_DEBUG_UART_CLOCK
;
250 writel(0, &priv
.regs
->ier
);
252 _mtk_serial_setbrg(&priv
, CONFIG_BAUDRATE
);
255 static inline void _debug_uart_putc(int ch
)
257 struct mtk_serial_regs __iomem
*regs
=
258 (void *) CONFIG_DEBUG_UART_BASE
;
260 while (!(readl(®s
->lsr
) & UART_LSR_THRE
))
263 writel(ch
, ®s
->thr
);