Commit 44fa676e58e90ad9283995b544f8e1013524161f
Committed by
Daniel Schwierzeck
1 parent
99ced5331b
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
serial: serial_mtk: add non-DM version for SPL
This patch adds non-DM version for mtk hsuart driver and makes it compatible with ns16550a driver in configuration. This is needed in SPL with CONFIG_SPL_DM disabled for reducing size. Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
Showing 2 changed files with 187 additions and 17 deletions Side-by-side Diff
drivers/serial/serial.c
... | ... | @@ -124,6 +124,7 @@ |
124 | 124 | serial_initfunc(pl01x_serial_initialize); |
125 | 125 | serial_initfunc(pxa_serial_initialize); |
126 | 126 | serial_initfunc(sh_serial_initialize); |
127 | +serial_initfunc(mtk_serial_initialize); | |
127 | 128 | |
128 | 129 | /** |
129 | 130 | * serial_register() - Register serial driver with serial driver core |
... | ... | @@ -177,6 +178,7 @@ |
177 | 178 | pl01x_serial_initialize(); |
178 | 179 | pxa_serial_initialize(); |
179 | 180 | sh_serial_initialize(); |
181 | + mtk_serial_initialize(); | |
180 | 182 | |
181 | 183 | serial_assign(default_serial_console()->name); |
182 | 184 | } |
drivers/serial/serial_mtk.c
... | ... | @@ -140,6 +140,37 @@ |
140 | 140 | } |
141 | 141 | } |
142 | 142 | |
143 | +static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch) | |
144 | +{ | |
145 | + if (!(readl(&priv->regs->lsr) & UART_LSR_THRE)) | |
146 | + return -EAGAIN; | |
147 | + | |
148 | + writel(ch, &priv->regs->thr); | |
149 | + | |
150 | + if (ch == '\n') | |
151 | + WATCHDOG_RESET(); | |
152 | + | |
153 | + return 0; | |
154 | +} | |
155 | + | |
156 | +static int _mtk_serial_getc(struct mtk_serial_priv *priv) | |
157 | +{ | |
158 | + if (!(readl(&priv->regs->lsr) & UART_LSR_DR)) | |
159 | + return -EAGAIN; | |
160 | + | |
161 | + return readl(&priv->regs->rbr); | |
162 | +} | |
163 | + | |
164 | +static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input) | |
165 | +{ | |
166 | + if (input) | |
167 | + return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0; | |
168 | + else | |
169 | + return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1; | |
170 | +} | |
171 | + | |
172 | +#if defined(CONFIG_DM_SERIAL) && \ | |
173 | + (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_DM)) | |
143 | 174 | static int mtk_serial_setbrg(struct udevice *dev, int baudrate) |
144 | 175 | { |
145 | 176 | struct mtk_serial_priv *priv = dev_get_priv(dev); |
146 | 177 | |
147 | 178 | |
... | ... | @@ -153,35 +184,21 @@ |
153 | 184 | { |
154 | 185 | struct mtk_serial_priv *priv = dev_get_priv(dev); |
155 | 186 | |
156 | - if (!(readl(&priv->regs->lsr) & UART_LSR_THRE)) | |
157 | - return -EAGAIN; | |
158 | - | |
159 | - writel(ch, &priv->regs->thr); | |
160 | - | |
161 | - if (ch == '\n') | |
162 | - WATCHDOG_RESET(); | |
163 | - | |
164 | - return 0; | |
187 | + return _mtk_serial_putc(priv, ch); | |
165 | 188 | } |
166 | 189 | |
167 | 190 | static int mtk_serial_getc(struct udevice *dev) |
168 | 191 | { |
169 | 192 | struct mtk_serial_priv *priv = dev_get_priv(dev); |
170 | 193 | |
171 | - if (!(readl(&priv->regs->lsr) & UART_LSR_DR)) | |
172 | - return -EAGAIN; | |
173 | - | |
174 | - return readl(&priv->regs->rbr); | |
194 | + return _mtk_serial_getc(priv); | |
175 | 195 | } |
176 | 196 | |
177 | 197 | static int mtk_serial_pending(struct udevice *dev, bool input) |
178 | 198 | { |
179 | 199 | struct mtk_serial_priv *priv = dev_get_priv(dev); |
180 | 200 | |
181 | - if (input) | |
182 | - return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0; | |
183 | - else | |
184 | - return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1; | |
201 | + return _mtk_serial_pending(priv, input); | |
185 | 202 | } |
186 | 203 | |
187 | 204 | static int mtk_serial_probe(struct udevice *dev) |
... | ... | @@ -254,6 +271,157 @@ |
254 | 271 | .ops = &mtk_serial_ops, |
255 | 272 | .flags = DM_FLAG_PRE_RELOC, |
256 | 273 | }; |
274 | +#else | |
275 | + | |
276 | +DECLARE_GLOBAL_DATA_PTR; | |
277 | + | |
278 | +#define DECLARE_HSUART_PRIV(port) \ | |
279 | + static struct mtk_serial_priv mtk_hsuart##port = { \ | |
280 | + .regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \ | |
281 | + .clock = CONFIG_SYS_NS16550_CLK \ | |
282 | +}; | |
283 | + | |
284 | +#define DECLARE_HSUART_FUNCTIONS(port) \ | |
285 | + static int mtk_serial##port##_init(void) \ | |
286 | + { \ | |
287 | + writel(0, &mtk_hsuart##port.regs->ier); \ | |
288 | + writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \ | |
289 | + writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \ | |
290 | + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ | |
291 | + return 0 ; \ | |
292 | + } \ | |
293 | + static void mtk_serial##port##_setbrg(void) \ | |
294 | + { \ | |
295 | + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ | |
296 | + } \ | |
297 | + static int mtk_serial##port##_getc(void) \ | |
298 | + { \ | |
299 | + int err; \ | |
300 | + do { \ | |
301 | + err = _mtk_serial_getc(&mtk_hsuart##port); \ | |
302 | + if (err == -EAGAIN) \ | |
303 | + WATCHDOG_RESET(); \ | |
304 | + } while (err == -EAGAIN); \ | |
305 | + return err >= 0 ? err : 0; \ | |
306 | + } \ | |
307 | + static int mtk_serial##port##_tstc(void) \ | |
308 | + { \ | |
309 | + return _mtk_serial_pending(&mtk_hsuart##port, true); \ | |
310 | + } \ | |
311 | + static void mtk_serial##port##_putc(const char c) \ | |
312 | + { \ | |
313 | + int err; \ | |
314 | + if (c == '\n') \ | |
315 | + mtk_serial##port##_putc('\r'); \ | |
316 | + do { \ | |
317 | + err = _mtk_serial_putc(&mtk_hsuart##port, c); \ | |
318 | + } while (err == -EAGAIN); \ | |
319 | + } \ | |
320 | + static void mtk_serial##port##_puts(const char *s) \ | |
321 | + { \ | |
322 | + while (*s) { \ | |
323 | + mtk_serial##port##_putc(*s++); \ | |
324 | + } \ | |
325 | + } | |
326 | + | |
327 | +/* Serial device descriptor */ | |
328 | +#define INIT_HSUART_STRUCTURE(port, __name) { \ | |
329 | + .name = __name, \ | |
330 | + .start = mtk_serial##port##_init, \ | |
331 | + .stop = NULL, \ | |
332 | + .setbrg = mtk_serial##port##_setbrg, \ | |
333 | + .getc = mtk_serial##port##_getc, \ | |
334 | + .tstc = mtk_serial##port##_tstc, \ | |
335 | + .putc = mtk_serial##port##_putc, \ | |
336 | + .puts = mtk_serial##port##_puts, \ | |
337 | +} | |
338 | + | |
339 | +#define DECLARE_HSUART(port, __name) \ | |
340 | + DECLARE_HSUART_PRIV(port); \ | |
341 | + DECLARE_HSUART_FUNCTIONS(port); \ | |
342 | + struct serial_device mtk_hsuart##port##_device = \ | |
343 | + INIT_HSUART_STRUCTURE(port, __name); | |
344 | + | |
345 | +#if !defined(CONFIG_CONS_INDEX) | |
346 | +#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6) | |
347 | +#error "Invalid console index value." | |
348 | +#endif | |
349 | + | |
350 | +#if CONFIG_CONS_INDEX == 1 && !defined(CONFIG_SYS_NS16550_COM1) | |
351 | +#error "Console port 1 defined but not configured." | |
352 | +#elif CONFIG_CONS_INDEX == 2 && !defined(CONFIG_SYS_NS16550_COM2) | |
353 | +#error "Console port 2 defined but not configured." | |
354 | +#elif CONFIG_CONS_INDEX == 3 && !defined(CONFIG_SYS_NS16550_COM3) | |
355 | +#error "Console port 3 defined but not configured." | |
356 | +#elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4) | |
357 | +#error "Console port 4 defined but not configured." | |
358 | +#elif CONFIG_CONS_INDEX == 5 && !defined(CONFIG_SYS_NS16550_COM5) | |
359 | +#error "Console port 5 defined but not configured." | |
360 | +#elif CONFIG_CONS_INDEX == 6 && !defined(CONFIG_SYS_NS16550_COM6) | |
361 | +#error "Console port 6 defined but not configured." | |
362 | +#endif | |
363 | + | |
364 | +#if defined(CONFIG_SYS_NS16550_COM1) | |
365 | +DECLARE_HSUART(1, "mtk-hsuart0"); | |
366 | +#endif | |
367 | +#if defined(CONFIG_SYS_NS16550_COM2) | |
368 | +DECLARE_HSUART(2, "mtk-hsuart1"); | |
369 | +#endif | |
370 | +#if defined(CONFIG_SYS_NS16550_COM3) | |
371 | +DECLARE_HSUART(3, "mtk-hsuart2"); | |
372 | +#endif | |
373 | +#if defined(CONFIG_SYS_NS16550_COM4) | |
374 | +DECLARE_HSUART(4, "mtk-hsuart3"); | |
375 | +#endif | |
376 | +#if defined(CONFIG_SYS_NS16550_COM5) | |
377 | +DECLARE_HSUART(5, "mtk-hsuart4"); | |
378 | +#endif | |
379 | +#if defined(CONFIG_SYS_NS16550_COM6) | |
380 | +DECLARE_HSUART(6, "mtk-hsuart5"); | |
381 | +#endif | |
382 | + | |
383 | +__weak struct serial_device *default_serial_console(void) | |
384 | +{ | |
385 | +#if CONFIG_CONS_INDEX == 1 | |
386 | + return &mtk_hsuart1_device; | |
387 | +#elif CONFIG_CONS_INDEX == 2 | |
388 | + return &mtk_hsuart2_device; | |
389 | +#elif CONFIG_CONS_INDEX == 3 | |
390 | + return &mtk_hsuart3_device; | |
391 | +#elif CONFIG_CONS_INDEX == 4 | |
392 | + return &mtk_hsuart4_device; | |
393 | +#elif CONFIG_CONS_INDEX == 5 | |
394 | + return &mtk_hsuart5_device; | |
395 | +#elif CONFIG_CONS_INDEX == 6 | |
396 | + return &mtk_hsuart6_device; | |
397 | +#else | |
398 | +#error "Bad CONFIG_CONS_INDEX." | |
399 | +#endif | |
400 | +} | |
401 | + | |
402 | +void mtk_serial_initialize(void) | |
403 | +{ | |
404 | +#if defined(CONFIG_SYS_NS16550_COM1) | |
405 | + serial_register(&mtk_hsuart1_device); | |
406 | +#endif | |
407 | +#if defined(CONFIG_SYS_NS16550_COM2) | |
408 | + serial_register(&mtk_hsuart2_device); | |
409 | +#endif | |
410 | +#if defined(CONFIG_SYS_NS16550_COM3) | |
411 | + serial_register(&mtk_hsuart3_device); | |
412 | +#endif | |
413 | +#if defined(CONFIG_SYS_NS16550_COM4) | |
414 | + serial_register(&mtk_hsuart4_device); | |
415 | +#endif | |
416 | +#if defined(CONFIG_SYS_NS16550_COM5) | |
417 | + serial_register(&mtk_hsuart5_device); | |
418 | +#endif | |
419 | +#if defined(CONFIG_SYS_NS16550_COM6) | |
420 | + serial_register(&mtk_hsuart6_device); | |
421 | +#endif | |
422 | +} | |
423 | + | |
424 | +#endif | |
257 | 425 | |
258 | 426 | #ifdef CONFIG_DEBUG_UART_MTK |
259 | 427 |