]>
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 VZ |
40 | { |
41 | writel(c, &hsuart->tx); | |
42 | ||
43 | /* Wait for character to be sent */ | |
44 | while (readl(&hsuart->level) & HSUART_LEVEL_TX) | |
45 | /* NOP */; | |
46 | } | |
47 | ||
e503f90a | 48 | static int lpc32xx_serial_tstc(void) |
cc35fdbc VZ |
49 | { |
50 | if (readl(&hsuart->level) & HSUART_LEVEL_RX) | |
51 | return 1; | |
52 | ||
53 | return 0; | |
54 | } | |
55 | ||
e503f90a | 56 | static int lpc32xx_serial_init(void) |
cc35fdbc | 57 | { |
e503f90a | 58 | lpc32xx_serial_setbrg(); |
cc35fdbc VZ |
59 | |
60 | /* Disable hardware RTS and CTS flow control, set up RX and TX FIFO */ | |
61 | writel(HSUART_CTRL_TMO_16 | HSUART_CTRL_HSU_OFFSET(20) | | |
62 | HSUART_CTRL_HSU_RX_TRIG_32 | HSUART_CTRL_HSU_TX_TRIG_0, | |
63 | &hsuart->ctrl); | |
e503f90a | 64 | return 0; |
cc35fdbc VZ |
65 | } |
66 | ||
e503f90a MV |
67 | static struct serial_device lpc32xx_serial_drv = { |
68 | .name = "lpc32xx_serial", | |
69 | .start = lpc32xx_serial_init, | |
70 | .stop = NULL, | |
71 | .setbrg = lpc32xx_serial_setbrg, | |
72 | .putc = lpc32xx_serial_putc, | |
ec3fd689 | 73 | .puts = default_serial_puts, |
e503f90a MV |
74 | .getc = lpc32xx_serial_getc, |
75 | .tstc = lpc32xx_serial_tstc, | |
76 | }; | |
77 | ||
78 | void lpc32xx_serial_initialize(void) | |
cc35fdbc | 79 | { |
e503f90a MV |
80 | serial_register(&lpc32xx_serial_drv); |
81 | } | |
cc35fdbc | 82 | |
e503f90a MV |
83 | __weak struct serial_device *default_serial_console(void) |
84 | { | |
85 | return &lpc32xx_serial_drv; | |
86 | } |