]>
Commit | Line | Data |
---|---|---|
cc35fdbc VZ |
1 | /* |
2 | * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com> | |
3 | * | |
1a459660 | 4 | * SPDX-License-Identifier: GPL-2.0+ |
cc35fdbc VZ |
5 | */ |
6 | ||
7 | #include <common.h> | |
8 | #include <asm/arch/cpu.h> | |
9 | #include <asm/arch/clk.h> | |
10 | #include <asm/arch/uart.h> | |
11 | #include <asm/io.h> | |
e503f90a MV |
12 | #include <serial.h> |
13 | #include <linux/compiler.h> | |
cc35fdbc VZ |
14 | |
15 | DECLARE_GLOBAL_DATA_PTR; | |
16 | ||
17 | static struct hsuart_regs *hsuart = (struct hsuart_regs *)HS_UART_BASE; | |
18 | ||
e503f90a | 19 | static void lpc32xx_serial_setbrg(void) |
cc35fdbc VZ |
20 | { |
21 | u32 div; | |
22 | ||
23 | /* UART rate = PERIPH_CLK / ((HSU_RATE + 1) x 14) */ | |
24 | div = (get_serial_clock() / 14 + gd->baudrate / 2) / gd->baudrate - 1; | |
25 | if (div > 255) | |
26 | div = 255; | |
27 | ||
28 | writel(div, &hsuart->rate); | |
29 | } | |
30 | ||
e503f90a | 31 | static int lpc32xx_serial_getc(void) |
cc35fdbc VZ |
32 | { |
33 | while (!(readl(&hsuart->level) & HSUART_LEVEL_RX)) | |
34 | /* NOP */; | |
35 | ||
36 | return readl(&hsuart->rx) & HSUART_RX_DATA; | |
37 | } | |
38 | ||
e503f90a | 39 | static void lpc32xx_serial_putc(const char c) |
cc35fdbc | 40 | { |
5deccafa VZ |
41 | if (c == '\n') |
42 | serial_putc('\r'); | |
43 | ||
cc35fdbc VZ |
44 | writel(c, &hsuart->tx); |
45 | ||
46 | /* Wait for character to be sent */ | |
47 | while (readl(&hsuart->level) & HSUART_LEVEL_TX) | |
48 | /* NOP */; | |
49 | } | |
50 | ||
e503f90a | 51 | static int lpc32xx_serial_tstc(void) |
cc35fdbc VZ |
52 | { |
53 | if (readl(&hsuart->level) & HSUART_LEVEL_RX) | |
54 | return 1; | |
55 | ||
56 | return 0; | |
57 | } | |
58 | ||
e503f90a | 59 | static int lpc32xx_serial_init(void) |
cc35fdbc | 60 | { |
e503f90a | 61 | lpc32xx_serial_setbrg(); |
cc35fdbc VZ |
62 | |
63 | /* Disable hardware RTS and CTS flow control, set up RX and TX FIFO */ | |
64 | writel(HSUART_CTRL_TMO_16 | HSUART_CTRL_HSU_OFFSET(20) | | |
65 | HSUART_CTRL_HSU_RX_TRIG_32 | HSUART_CTRL_HSU_TX_TRIG_0, | |
66 | &hsuart->ctrl); | |
e503f90a | 67 | return 0; |
cc35fdbc VZ |
68 | } |
69 | ||
e503f90a MV |
70 | static struct serial_device lpc32xx_serial_drv = { |
71 | .name = "lpc32xx_serial", | |
72 | .start = lpc32xx_serial_init, | |
73 | .stop = NULL, | |
74 | .setbrg = lpc32xx_serial_setbrg, | |
75 | .putc = lpc32xx_serial_putc, | |
ec3fd689 | 76 | .puts = default_serial_puts, |
e503f90a MV |
77 | .getc = lpc32xx_serial_getc, |
78 | .tstc = lpc32xx_serial_tstc, | |
79 | }; | |
80 | ||
81 | void lpc32xx_serial_initialize(void) | |
cc35fdbc | 82 | { |
e503f90a MV |
83 | serial_register(&lpc32xx_serial_drv); |
84 | } | |
cc35fdbc | 85 | |
e503f90a MV |
86 | __weak struct serial_device *default_serial_console(void) |
87 | { | |
88 | return &lpc32xx_serial_drv; | |
89 | } |