1
2
3
4
5
6
7
8
9#include <common.h>
10#include <dm.h>
11#include <serial.h>
12#include <asm/io.h>
13
14DECLARE_GLOBAL_DATA_PTR;
15
16#define BAUDMODE 0x00001000
17#define RXENABLE 0x00000100
18#define RUN 0x00000080
19#define MODE 0x00000001
20#define MODE_8BIT 0x0001
21#define STOP_1BIT 0x0008
22#define PARITYODD 0x0020
23
24#define STA_TF BIT(9)
25#define STA_RBF BIT(0)
26
27struct sti_asc_uart {
28 u32 baudrate;
29 u32 txbuf;
30 u32 rxbuf;
31 u32 control;
32 u32 inten;
33 u32 status;
34 u32 guardtime;
35 u32 timeout;
36 u32 txreset;
37 u32 rxreset;
38};
39
40struct sti_asc_serial {
41
42 struct sti_asc_uart *regs;
43};
44
45
46#define PCLK (200ul * 1000000ul)
47#define BAUDRATE_VAL_M0(bps) (PCLK / (16 * (bps)))
48#define BAUDRATE_VAL_M1(bps) ((bps * (1 << 14)) + (1<<13)) / (PCLK/(1 << 6))
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67static int sti_asc_pending(struct udevice *dev, bool input)
68{
69 struct sti_asc_serial *priv = dev_get_priv(dev);
70 struct sti_asc_uart *const uart = priv->regs;
71 unsigned long status;
72
73 status = readl(&uart->status);
74 if (input)
75 return status & STA_RBF;
76 else
77 return status & STA_TF;
78}
79
80static int _sti_asc_serial_setbrg(struct sti_asc_uart *uart, int baudrate)
81{
82 unsigned long val;
83 int t, mode = 1;
84
85 switch (baudrate) {
86 case 9600:
87 t = BAUDRATE_VAL_M0(9600);
88 mode = 0;
89 break;
90 case 19200:
91 t = BAUDRATE_VAL_M1(19200);
92 break;
93 case 38400:
94 t = BAUDRATE_VAL_M1(38400);
95 break;
96 case 57600:
97 t = BAUDRATE_VAL_M1(57600);
98 break;
99 default:
100 debug("ASC: unsupported baud rate: %d, using 115200 instead.\n",
101 baudrate);
102 case 115200:
103 t = BAUDRATE_VAL_M1(115200);
104 break;
105 }
106
107
108 val = readl(&uart->control);
109 writel(val & ~RUN, &uart->control);
110
111
112 writel(t, &uart->baudrate);
113
114 writel(1, &uart->txreset);
115 writel(1, &uart->rxreset);
116
117
118 if (mode)
119 val |= BAUDMODE;
120
121
122 writel(val, &uart->control);
123
124 return 0;
125}
126
127
128static int sti_asc_serial_setbrg(struct udevice *dev, int baudrate)
129{
130 struct sti_asc_serial *priv = dev_get_priv(dev);
131 struct sti_asc_uart *const uart = priv->regs;
132
133 return _sti_asc_serial_setbrg(uart, baudrate);
134}
135
136
137static int sti_asc_serial_getc(struct udevice *dev)
138{
139 struct sti_asc_serial *priv = dev_get_priv(dev);
140 struct sti_asc_uart *const uart = priv->regs;
141
142
143 if (!sti_asc_pending(dev, true))
144 return -EAGAIN;
145
146 return readl(&uart->rxbuf);
147}
148
149
150static int sti_asc_serial_putc(struct udevice *dev, const char c)
151{
152 struct sti_asc_serial *priv = dev_get_priv(dev);
153 struct sti_asc_uart *const uart = priv->regs;
154
155
156 if (sti_asc_pending(dev, false))
157 return -EAGAIN;
158
159
160 writel(c, &uart->txbuf);
161
162 return 0;
163}
164
165
166static int sti_asc_serial_probe(struct udevice *dev)
167{
168 struct sti_asc_serial *priv = dev_get_priv(dev);
169 unsigned long val;
170 fdt_addr_t base;
171
172 base = devfdt_get_addr(dev);
173 if (base == FDT_ADDR_T_NONE)
174 return -EINVAL;
175
176 priv->regs = (struct sti_asc_uart *)base;
177 sti_asc_serial_setbrg(dev, gd->baudrate);
178
179
180
181
182
183 val = RXENABLE | RUN | MODE_8BIT | STOP_1BIT | PARITYODD;
184 writel(val, &priv->regs->control);
185
186 return 0;
187}
188
189static const struct dm_serial_ops sti_asc_serial_ops = {
190 .putc = sti_asc_serial_putc,
191 .pending = sti_asc_pending,
192 .getc = sti_asc_serial_getc,
193 .setbrg = sti_asc_serial_setbrg,
194};
195
196static const struct udevice_id sti_serial_of_match[] = {
197 { .compatible = "st,asc" },
198 { }
199};
200
201U_BOOT_DRIVER(serial_sti_asc) = {
202 .name = "serial_sti_asc",
203 .id = UCLASS_SERIAL,
204 .of_match = sti_serial_of_match,
205 .ops = &sti_asc_serial_ops,
206 .probe = sti_asc_serial_probe,
207 .priv_auto_alloc_size = sizeof(struct sti_asc_serial),
208};
209
210