Commit 09865465821fd35eabedcd9f102f1d576c626ad8
Committed by
Daniel Hellstrom
1 parent
891655ebc1
Exists in
v2017.01-smarct4x
and in
40 other branches
serial: zynq: Fix typo in suffix function name
's/zynq_serial_initalize/zynq_serial_initialize/g' serial_initialize is used by all serial drivers. Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Showing 2 changed files with 3 additions and 3 deletions Inline Diff
drivers/serial/serial.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2004 | 2 | * (C) Copyright 2004 |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | 3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | * | 4 | * |
5 | * SPDX-License-Identifier: GPL-2.0+ | 5 | * SPDX-License-Identifier: GPL-2.0+ |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <common.h> | 8 | #include <common.h> |
9 | #include <environment.h> | 9 | #include <environment.h> |
10 | #include <serial.h> | 10 | #include <serial.h> |
11 | #include <stdio_dev.h> | 11 | #include <stdio_dev.h> |
12 | #include <post.h> | 12 | #include <post.h> |
13 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
14 | #include <errno.h> | 14 | #include <errno.h> |
15 | 15 | ||
16 | DECLARE_GLOBAL_DATA_PTR; | 16 | DECLARE_GLOBAL_DATA_PTR; |
17 | 17 | ||
18 | static struct serial_device *serial_devices; | 18 | static struct serial_device *serial_devices; |
19 | static struct serial_device *serial_current; | 19 | static struct serial_device *serial_current; |
20 | /* | 20 | /* |
21 | * Table with supported baudrates (defined in config_xyz.h) | 21 | * Table with supported baudrates (defined in config_xyz.h) |
22 | */ | 22 | */ |
23 | static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; | 23 | static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * serial_null() - Void registration routine of a serial driver | 26 | * serial_null() - Void registration routine of a serial driver |
27 | * | 27 | * |
28 | * This routine implements a void registration routine of a serial | 28 | * This routine implements a void registration routine of a serial |
29 | * driver. The registration routine of a particular driver is aliased | 29 | * driver. The registration routine of a particular driver is aliased |
30 | * to this empty function in case the driver is not compiled into | 30 | * to this empty function in case the driver is not compiled into |
31 | * U-Boot. | 31 | * U-Boot. |
32 | */ | 32 | */ |
33 | static void serial_null(void) | 33 | static void serial_null(void) |
34 | { | 34 | { |
35 | } | 35 | } |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * on_baudrate() - Update the actual baudrate when the env var changes | 38 | * on_baudrate() - Update the actual baudrate when the env var changes |
39 | * | 39 | * |
40 | * This will check for a valid baudrate and only apply it if valid. | 40 | * This will check for a valid baudrate and only apply it if valid. |
41 | */ | 41 | */ |
42 | static int on_baudrate(const char *name, const char *value, enum env_op op, | 42 | static int on_baudrate(const char *name, const char *value, enum env_op op, |
43 | int flags) | 43 | int flags) |
44 | { | 44 | { |
45 | int i; | 45 | int i; |
46 | int baudrate; | 46 | int baudrate; |
47 | 47 | ||
48 | switch (op) { | 48 | switch (op) { |
49 | case env_op_create: | 49 | case env_op_create: |
50 | case env_op_overwrite: | 50 | case env_op_overwrite: |
51 | /* | 51 | /* |
52 | * Switch to new baudrate if new baudrate is supported | 52 | * Switch to new baudrate if new baudrate is supported |
53 | */ | 53 | */ |
54 | baudrate = simple_strtoul(value, NULL, 10); | 54 | baudrate = simple_strtoul(value, NULL, 10); |
55 | 55 | ||
56 | /* Not actually changing */ | 56 | /* Not actually changing */ |
57 | if (gd->baudrate == baudrate) | 57 | if (gd->baudrate == baudrate) |
58 | return 0; | 58 | return 0; |
59 | 59 | ||
60 | for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) { | 60 | for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) { |
61 | if (baudrate == baudrate_table[i]) | 61 | if (baudrate == baudrate_table[i]) |
62 | break; | 62 | break; |
63 | } | 63 | } |
64 | if (i == ARRAY_SIZE(baudrate_table)) { | 64 | if (i == ARRAY_SIZE(baudrate_table)) { |
65 | if ((flags & H_FORCE) == 0) | 65 | if ((flags & H_FORCE) == 0) |
66 | printf("## Baudrate %d bps not supported\n", | 66 | printf("## Baudrate %d bps not supported\n", |
67 | baudrate); | 67 | baudrate); |
68 | return 1; | 68 | return 1; |
69 | } | 69 | } |
70 | if ((flags & H_INTERACTIVE) != 0) { | 70 | if ((flags & H_INTERACTIVE) != 0) { |
71 | printf("## Switch baudrate to %d" | 71 | printf("## Switch baudrate to %d" |
72 | " bps and press ENTER ...\n", baudrate); | 72 | " bps and press ENTER ...\n", baudrate); |
73 | udelay(50000); | 73 | udelay(50000); |
74 | } | 74 | } |
75 | 75 | ||
76 | gd->baudrate = baudrate; | 76 | gd->baudrate = baudrate; |
77 | #if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) | 77 | #if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) |
78 | gd->bd->bi_baudrate = baudrate; | 78 | gd->bd->bi_baudrate = baudrate; |
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | serial_setbrg(); | 81 | serial_setbrg(); |
82 | 82 | ||
83 | udelay(50000); | 83 | udelay(50000); |
84 | 84 | ||
85 | if ((flags & H_INTERACTIVE) != 0) | 85 | if ((flags & H_INTERACTIVE) != 0) |
86 | while (1) { | 86 | while (1) { |
87 | if (getc() == '\r') | 87 | if (getc() == '\r') |
88 | break; | 88 | break; |
89 | } | 89 | } |
90 | 90 | ||
91 | return 0; | 91 | return 0; |
92 | case env_op_delete: | 92 | case env_op_delete: |
93 | printf("## Baudrate may not be deleted\n"); | 93 | printf("## Baudrate may not be deleted\n"); |
94 | return 1; | 94 | return 1; |
95 | default: | 95 | default: |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | } | 98 | } |
99 | U_BOOT_ENV_CALLBACK(baudrate, on_baudrate); | 99 | U_BOOT_ENV_CALLBACK(baudrate, on_baudrate); |
100 | 100 | ||
101 | /** | 101 | /** |
102 | * serial_initfunc() - Forward declare of driver registration routine | 102 | * serial_initfunc() - Forward declare of driver registration routine |
103 | * @name: Name of the real driver registration routine. | 103 | * @name: Name of the real driver registration routine. |
104 | * | 104 | * |
105 | * This macro expands onto forward declaration of a driver registration | 105 | * This macro expands onto forward declaration of a driver registration |
106 | * routine, which is then used below in serial_initialize() function. | 106 | * routine, which is then used below in serial_initialize() function. |
107 | * The declaration is made weak and aliases to serial_null() so in case | 107 | * The declaration is made weak and aliases to serial_null() so in case |
108 | * the driver is not compiled in, the function is still declared and can | 108 | * the driver is not compiled in, the function is still declared and can |
109 | * be used, but aliases to serial_null() and thus is optimized away. | 109 | * be used, but aliases to serial_null() and thus is optimized away. |
110 | */ | 110 | */ |
111 | #define serial_initfunc(name) \ | 111 | #define serial_initfunc(name) \ |
112 | void name(void) \ | 112 | void name(void) \ |
113 | __attribute__((weak, alias("serial_null"))); | 113 | __attribute__((weak, alias("serial_null"))); |
114 | 114 | ||
115 | serial_initfunc(mpc8xx_serial_initialize); | 115 | serial_initfunc(mpc8xx_serial_initialize); |
116 | serial_initfunc(ns16550_serial_initialize); | 116 | serial_initfunc(ns16550_serial_initialize); |
117 | serial_initfunc(pxa_serial_initialize); | 117 | serial_initfunc(pxa_serial_initialize); |
118 | serial_initfunc(s3c24xx_serial_initialize); | 118 | serial_initfunc(s3c24xx_serial_initialize); |
119 | serial_initfunc(s5p_serial_initialize); | 119 | serial_initfunc(s5p_serial_initialize); |
120 | serial_initfunc(zynq_serial_initalize); | 120 | serial_initfunc(zynq_serial_initialize); |
121 | serial_initfunc(bfin_serial_initialize); | 121 | serial_initfunc(bfin_serial_initialize); |
122 | serial_initfunc(bfin_jtag_initialize); | 122 | serial_initfunc(bfin_jtag_initialize); |
123 | serial_initfunc(mpc512x_serial_initialize); | 123 | serial_initfunc(mpc512x_serial_initialize); |
124 | serial_initfunc(uartlite_serial_initialize); | 124 | serial_initfunc(uartlite_serial_initialize); |
125 | serial_initfunc(au1x00_serial_initialize); | 125 | serial_initfunc(au1x00_serial_initialize); |
126 | serial_initfunc(asc_serial_initialize); | 126 | serial_initfunc(asc_serial_initialize); |
127 | serial_initfunc(jz_serial_initialize); | 127 | serial_initfunc(jz_serial_initialize); |
128 | serial_initfunc(mpc5xx_serial_initialize); | 128 | serial_initfunc(mpc5xx_serial_initialize); |
129 | serial_initfunc(mpc8260_scc_serial_initialize); | 129 | serial_initfunc(mpc8260_scc_serial_initialize); |
130 | serial_initfunc(mpc8260_smc_serial_initialize); | 130 | serial_initfunc(mpc8260_smc_serial_initialize); |
131 | serial_initfunc(mpc85xx_serial_initialize); | 131 | serial_initfunc(mpc85xx_serial_initialize); |
132 | serial_initfunc(iop480_serial_initialize); | 132 | serial_initfunc(iop480_serial_initialize); |
133 | serial_initfunc(leon2_serial_initialize); | 133 | serial_initfunc(leon2_serial_initialize); |
134 | serial_initfunc(leon3_serial_initialize); | 134 | serial_initfunc(leon3_serial_initialize); |
135 | serial_initfunc(marvell_serial_initialize); | 135 | serial_initfunc(marvell_serial_initialize); |
136 | serial_initfunc(amirix_serial_initialize); | 136 | serial_initfunc(amirix_serial_initialize); |
137 | serial_initfunc(bmw_serial_initialize); | 137 | serial_initfunc(bmw_serial_initialize); |
138 | serial_initfunc(cogent_serial_initialize); | 138 | serial_initfunc(cogent_serial_initialize); |
139 | serial_initfunc(cpci750_serial_initialize); | 139 | serial_initfunc(cpci750_serial_initialize); |
140 | serial_initfunc(evb64260_serial_initialize); | 140 | serial_initfunc(evb64260_serial_initialize); |
141 | serial_initfunc(ml2_serial_initialize); | 141 | serial_initfunc(ml2_serial_initialize); |
142 | serial_initfunc(sconsole_serial_initialize); | 142 | serial_initfunc(sconsole_serial_initialize); |
143 | serial_initfunc(p3mx_serial_initialize); | 143 | serial_initfunc(p3mx_serial_initialize); |
144 | serial_initfunc(altera_jtag_serial_initialize); | 144 | serial_initfunc(altera_jtag_serial_initialize); |
145 | serial_initfunc(altera_serial_initialize); | 145 | serial_initfunc(altera_serial_initialize); |
146 | serial_initfunc(atmel_serial_initialize); | 146 | serial_initfunc(atmel_serial_initialize); |
147 | serial_initfunc(lpc32xx_serial_initialize); | 147 | serial_initfunc(lpc32xx_serial_initialize); |
148 | serial_initfunc(mcf_serial_initialize); | 148 | serial_initfunc(mcf_serial_initialize); |
149 | serial_initfunc(oc_serial_initialize); | 149 | serial_initfunc(oc_serial_initialize); |
150 | serial_initfunc(sandbox_serial_initialize); | 150 | serial_initfunc(sandbox_serial_initialize); |
151 | serial_initfunc(clps7111_serial_initialize); | 151 | serial_initfunc(clps7111_serial_initialize); |
152 | serial_initfunc(imx_serial_initialize); | 152 | serial_initfunc(imx_serial_initialize); |
153 | serial_initfunc(ks8695_serial_initialize); | 153 | serial_initfunc(ks8695_serial_initialize); |
154 | serial_initfunc(lh7a40x_serial_initialize); | 154 | serial_initfunc(lh7a40x_serial_initialize); |
155 | serial_initfunc(max3100_serial_initialize); | 155 | serial_initfunc(max3100_serial_initialize); |
156 | serial_initfunc(mxc_serial_initialize); | 156 | serial_initfunc(mxc_serial_initialize); |
157 | serial_initfunc(pl01x_serial_initialize); | 157 | serial_initfunc(pl01x_serial_initialize); |
158 | serial_initfunc(sa1100_serial_initialize); | 158 | serial_initfunc(sa1100_serial_initialize); |
159 | serial_initfunc(sh_serial_initialize); | 159 | serial_initfunc(sh_serial_initialize); |
160 | serial_initfunc(arm_dcc_initialize); | 160 | serial_initfunc(arm_dcc_initialize); |
161 | serial_initfunc(mxs_auart_initialize); | 161 | serial_initfunc(mxs_auart_initialize); |
162 | serial_initfunc(arc_serial_initialize); | 162 | serial_initfunc(arc_serial_initialize); |
163 | 163 | ||
164 | /** | 164 | /** |
165 | * serial_register() - Register serial driver with serial driver core | 165 | * serial_register() - Register serial driver with serial driver core |
166 | * @dev: Pointer to the serial driver structure | 166 | * @dev: Pointer to the serial driver structure |
167 | * | 167 | * |
168 | * This function registers the serial driver supplied via @dev with | 168 | * This function registers the serial driver supplied via @dev with |
169 | * serial driver core, thus making U-Boot aware of it and making it | 169 | * serial driver core, thus making U-Boot aware of it and making it |
170 | * available for U-Boot to use. On platforms that still require manual | 170 | * available for U-Boot to use. On platforms that still require manual |
171 | * relocation of constant variables, relocation of the supplied structure | 171 | * relocation of constant variables, relocation of the supplied structure |
172 | * is performed. | 172 | * is performed. |
173 | */ | 173 | */ |
174 | void serial_register(struct serial_device *dev) | 174 | void serial_register(struct serial_device *dev) |
175 | { | 175 | { |
176 | #ifdef CONFIG_NEEDS_MANUAL_RELOC | 176 | #ifdef CONFIG_NEEDS_MANUAL_RELOC |
177 | if (dev->start) | 177 | if (dev->start) |
178 | dev->start += gd->reloc_off; | 178 | dev->start += gd->reloc_off; |
179 | if (dev->stop) | 179 | if (dev->stop) |
180 | dev->stop += gd->reloc_off; | 180 | dev->stop += gd->reloc_off; |
181 | if (dev->setbrg) | 181 | if (dev->setbrg) |
182 | dev->setbrg += gd->reloc_off; | 182 | dev->setbrg += gd->reloc_off; |
183 | if (dev->getc) | 183 | if (dev->getc) |
184 | dev->getc += gd->reloc_off; | 184 | dev->getc += gd->reloc_off; |
185 | if (dev->tstc) | 185 | if (dev->tstc) |
186 | dev->tstc += gd->reloc_off; | 186 | dev->tstc += gd->reloc_off; |
187 | if (dev->putc) | 187 | if (dev->putc) |
188 | dev->putc += gd->reloc_off; | 188 | dev->putc += gd->reloc_off; |
189 | if (dev->puts) | 189 | if (dev->puts) |
190 | dev->puts += gd->reloc_off; | 190 | dev->puts += gd->reloc_off; |
191 | #endif | 191 | #endif |
192 | 192 | ||
193 | dev->next = serial_devices; | 193 | dev->next = serial_devices; |
194 | serial_devices = dev; | 194 | serial_devices = dev; |
195 | } | 195 | } |
196 | 196 | ||
197 | /** | 197 | /** |
198 | * serial_initialize() - Register all compiled-in serial port drivers | 198 | * serial_initialize() - Register all compiled-in serial port drivers |
199 | * | 199 | * |
200 | * This function registers all serial port drivers that are compiled | 200 | * This function registers all serial port drivers that are compiled |
201 | * into the U-Boot binary with the serial core, thus making them | 201 | * into the U-Boot binary with the serial core, thus making them |
202 | * available to U-Boot to use. Lastly, this function assigns a default | 202 | * available to U-Boot to use. Lastly, this function assigns a default |
203 | * serial port to the serial core. That serial port is then used as a | 203 | * serial port to the serial core. That serial port is then used as a |
204 | * default output. | 204 | * default output. |
205 | */ | 205 | */ |
206 | void serial_initialize(void) | 206 | void serial_initialize(void) |
207 | { | 207 | { |
208 | mpc8xx_serial_initialize(); | 208 | mpc8xx_serial_initialize(); |
209 | ns16550_serial_initialize(); | 209 | ns16550_serial_initialize(); |
210 | pxa_serial_initialize(); | 210 | pxa_serial_initialize(); |
211 | s3c24xx_serial_initialize(); | 211 | s3c24xx_serial_initialize(); |
212 | s5p_serial_initialize(); | 212 | s5p_serial_initialize(); |
213 | mpc512x_serial_initialize(); | 213 | mpc512x_serial_initialize(); |
214 | bfin_serial_initialize(); | 214 | bfin_serial_initialize(); |
215 | bfin_jtag_initialize(); | 215 | bfin_jtag_initialize(); |
216 | uartlite_serial_initialize(); | 216 | uartlite_serial_initialize(); |
217 | zynq_serial_initalize(); | 217 | zynq_serial_initialize(); |
218 | au1x00_serial_initialize(); | 218 | au1x00_serial_initialize(); |
219 | asc_serial_initialize(); | 219 | asc_serial_initialize(); |
220 | jz_serial_initialize(); | 220 | jz_serial_initialize(); |
221 | mpc5xx_serial_initialize(); | 221 | mpc5xx_serial_initialize(); |
222 | mpc8260_scc_serial_initialize(); | 222 | mpc8260_scc_serial_initialize(); |
223 | mpc8260_smc_serial_initialize(); | 223 | mpc8260_smc_serial_initialize(); |
224 | mpc85xx_serial_initialize(); | 224 | mpc85xx_serial_initialize(); |
225 | iop480_serial_initialize(); | 225 | iop480_serial_initialize(); |
226 | leon2_serial_initialize(); | 226 | leon2_serial_initialize(); |
227 | leon3_serial_initialize(); | 227 | leon3_serial_initialize(); |
228 | marvell_serial_initialize(); | 228 | marvell_serial_initialize(); |
229 | amirix_serial_initialize(); | 229 | amirix_serial_initialize(); |
230 | bmw_serial_initialize(); | 230 | bmw_serial_initialize(); |
231 | cogent_serial_initialize(); | 231 | cogent_serial_initialize(); |
232 | cpci750_serial_initialize(); | 232 | cpci750_serial_initialize(); |
233 | evb64260_serial_initialize(); | 233 | evb64260_serial_initialize(); |
234 | ml2_serial_initialize(); | 234 | ml2_serial_initialize(); |
235 | sconsole_serial_initialize(); | 235 | sconsole_serial_initialize(); |
236 | p3mx_serial_initialize(); | 236 | p3mx_serial_initialize(); |
237 | altera_jtag_serial_initialize(); | 237 | altera_jtag_serial_initialize(); |
238 | altera_serial_initialize(); | 238 | altera_serial_initialize(); |
239 | atmel_serial_initialize(); | 239 | atmel_serial_initialize(); |
240 | lpc32xx_serial_initialize(); | 240 | lpc32xx_serial_initialize(); |
241 | mcf_serial_initialize(); | 241 | mcf_serial_initialize(); |
242 | oc_serial_initialize(); | 242 | oc_serial_initialize(); |
243 | sandbox_serial_initialize(); | 243 | sandbox_serial_initialize(); |
244 | clps7111_serial_initialize(); | 244 | clps7111_serial_initialize(); |
245 | imx_serial_initialize(); | 245 | imx_serial_initialize(); |
246 | ks8695_serial_initialize(); | 246 | ks8695_serial_initialize(); |
247 | lh7a40x_serial_initialize(); | 247 | lh7a40x_serial_initialize(); |
248 | max3100_serial_initialize(); | 248 | max3100_serial_initialize(); |
249 | mxc_serial_initialize(); | 249 | mxc_serial_initialize(); |
250 | pl01x_serial_initialize(); | 250 | pl01x_serial_initialize(); |
251 | sa1100_serial_initialize(); | 251 | sa1100_serial_initialize(); |
252 | sh_serial_initialize(); | 252 | sh_serial_initialize(); |
253 | arm_dcc_initialize(); | 253 | arm_dcc_initialize(); |
254 | mxs_auart_initialize(); | 254 | mxs_auart_initialize(); |
255 | arc_serial_initialize(); | 255 | arc_serial_initialize(); |
256 | 256 | ||
257 | serial_assign(default_serial_console()->name); | 257 | serial_assign(default_serial_console()->name); |
258 | } | 258 | } |
259 | 259 | ||
260 | /** | 260 | /** |
261 | * serial_stdio_init() - Register serial ports with STDIO core | 261 | * serial_stdio_init() - Register serial ports with STDIO core |
262 | * | 262 | * |
263 | * This function generates a proxy driver for each serial port driver. | 263 | * This function generates a proxy driver for each serial port driver. |
264 | * These proxy drivers then register with the STDIO core, making the | 264 | * These proxy drivers then register with the STDIO core, making the |
265 | * serial drivers available as STDIO devices. | 265 | * serial drivers available as STDIO devices. |
266 | */ | 266 | */ |
267 | void serial_stdio_init(void) | 267 | void serial_stdio_init(void) |
268 | { | 268 | { |
269 | struct stdio_dev dev; | 269 | struct stdio_dev dev; |
270 | struct serial_device *s = serial_devices; | 270 | struct serial_device *s = serial_devices; |
271 | 271 | ||
272 | while (s) { | 272 | while (s) { |
273 | memset(&dev, 0, sizeof(dev)); | 273 | memset(&dev, 0, sizeof(dev)); |
274 | 274 | ||
275 | strcpy(dev.name, s->name); | 275 | strcpy(dev.name, s->name); |
276 | dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; | 276 | dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; |
277 | 277 | ||
278 | dev.start = s->start; | 278 | dev.start = s->start; |
279 | dev.stop = s->stop; | 279 | dev.stop = s->stop; |
280 | dev.putc = s->putc; | 280 | dev.putc = s->putc; |
281 | dev.puts = s->puts; | 281 | dev.puts = s->puts; |
282 | dev.getc = s->getc; | 282 | dev.getc = s->getc; |
283 | dev.tstc = s->tstc; | 283 | dev.tstc = s->tstc; |
284 | 284 | ||
285 | stdio_register(&dev); | 285 | stdio_register(&dev); |
286 | 286 | ||
287 | s = s->next; | 287 | s = s->next; |
288 | } | 288 | } |
289 | } | 289 | } |
290 | 290 | ||
291 | /** | 291 | /** |
292 | * serial_assign() - Select the serial output device by name | 292 | * serial_assign() - Select the serial output device by name |
293 | * @name: Name of the serial driver to be used as default output | 293 | * @name: Name of the serial driver to be used as default output |
294 | * | 294 | * |
295 | * This function configures the serial output multiplexing by | 295 | * This function configures the serial output multiplexing by |
296 | * selecting which serial device will be used as default. In case | 296 | * selecting which serial device will be used as default. In case |
297 | * the STDIO "serial" device is selected as stdin/stdout/stderr, | 297 | * the STDIO "serial" device is selected as stdin/stdout/stderr, |
298 | * the serial device previously configured by this function will be | 298 | * the serial device previously configured by this function will be |
299 | * used for the particular operation. | 299 | * used for the particular operation. |
300 | * | 300 | * |
301 | * Returns 0 on success, negative on error. | 301 | * Returns 0 on success, negative on error. |
302 | */ | 302 | */ |
303 | int serial_assign(const char *name) | 303 | int serial_assign(const char *name) |
304 | { | 304 | { |
305 | struct serial_device *s; | 305 | struct serial_device *s; |
306 | 306 | ||
307 | for (s = serial_devices; s; s = s->next) { | 307 | for (s = serial_devices; s; s = s->next) { |
308 | if (strcmp(s->name, name)) | 308 | if (strcmp(s->name, name)) |
309 | continue; | 309 | continue; |
310 | serial_current = s; | 310 | serial_current = s; |
311 | return 0; | 311 | return 0; |
312 | } | 312 | } |
313 | 313 | ||
314 | return -EINVAL; | 314 | return -EINVAL; |
315 | } | 315 | } |
316 | 316 | ||
317 | /** | 317 | /** |
318 | * serial_reinit_all() - Reinitialize all compiled-in serial ports | 318 | * serial_reinit_all() - Reinitialize all compiled-in serial ports |
319 | * | 319 | * |
320 | * This function reinitializes all serial ports that are compiled | 320 | * This function reinitializes all serial ports that are compiled |
321 | * into U-Boot by calling their serial_start() functions. | 321 | * into U-Boot by calling their serial_start() functions. |
322 | */ | 322 | */ |
323 | void serial_reinit_all(void) | 323 | void serial_reinit_all(void) |
324 | { | 324 | { |
325 | struct serial_device *s; | 325 | struct serial_device *s; |
326 | 326 | ||
327 | for (s = serial_devices; s; s = s->next) | 327 | for (s = serial_devices; s; s = s->next) |
328 | s->start(); | 328 | s->start(); |
329 | } | 329 | } |
330 | 330 | ||
331 | /** | 331 | /** |
332 | * get_current() - Return pointer to currently selected serial port | 332 | * get_current() - Return pointer to currently selected serial port |
333 | * | 333 | * |
334 | * This function returns a pointer to currently selected serial port. | 334 | * This function returns a pointer to currently selected serial port. |
335 | * The currently selected serial port is altered by serial_assign() | 335 | * The currently selected serial port is altered by serial_assign() |
336 | * function. | 336 | * function. |
337 | * | 337 | * |
338 | * In case this function is called before relocation or before any serial | 338 | * In case this function is called before relocation or before any serial |
339 | * port is configured, this function calls default_serial_console() to | 339 | * port is configured, this function calls default_serial_console() to |
340 | * determine the serial port. Otherwise, the configured serial port is | 340 | * determine the serial port. Otherwise, the configured serial port is |
341 | * returned. | 341 | * returned. |
342 | * | 342 | * |
343 | * Returns pointer to the currently selected serial port on success, | 343 | * Returns pointer to the currently selected serial port on success, |
344 | * NULL on error. | 344 | * NULL on error. |
345 | */ | 345 | */ |
346 | static struct serial_device *get_current(void) | 346 | static struct serial_device *get_current(void) |
347 | { | 347 | { |
348 | struct serial_device *dev; | 348 | struct serial_device *dev; |
349 | 349 | ||
350 | if (!(gd->flags & GD_FLG_RELOC)) | 350 | if (!(gd->flags & GD_FLG_RELOC)) |
351 | dev = default_serial_console(); | 351 | dev = default_serial_console(); |
352 | else if (!serial_current) | 352 | else if (!serial_current) |
353 | dev = default_serial_console(); | 353 | dev = default_serial_console(); |
354 | else | 354 | else |
355 | dev = serial_current; | 355 | dev = serial_current; |
356 | 356 | ||
357 | /* We must have a console device */ | 357 | /* We must have a console device */ |
358 | if (!dev) { | 358 | if (!dev) { |
359 | #ifdef CONFIG_SPL_BUILD | 359 | #ifdef CONFIG_SPL_BUILD |
360 | puts("Cannot find console\n"); | 360 | puts("Cannot find console\n"); |
361 | hang(); | 361 | hang(); |
362 | #else | 362 | #else |
363 | panic("Cannot find console\n"); | 363 | panic("Cannot find console\n"); |
364 | #endif | 364 | #endif |
365 | } | 365 | } |
366 | 366 | ||
367 | return dev; | 367 | return dev; |
368 | } | 368 | } |
369 | 369 | ||
370 | /** | 370 | /** |
371 | * serial_init() - Initialize currently selected serial port | 371 | * serial_init() - Initialize currently selected serial port |
372 | * | 372 | * |
373 | * This function initializes the currently selected serial port. This | 373 | * This function initializes the currently selected serial port. This |
374 | * usually involves setting up the registers of that particular port, | 374 | * usually involves setting up the registers of that particular port, |
375 | * enabling clock and such. This function uses the get_current() call | 375 | * enabling clock and such. This function uses the get_current() call |
376 | * to determine which port is selected. | 376 | * to determine which port is selected. |
377 | * | 377 | * |
378 | * Returns 0 on success, negative on error. | 378 | * Returns 0 on success, negative on error. |
379 | */ | 379 | */ |
380 | int serial_init(void) | 380 | int serial_init(void) |
381 | { | 381 | { |
382 | return get_current()->start(); | 382 | return get_current()->start(); |
383 | } | 383 | } |
384 | 384 | ||
385 | /** | 385 | /** |
386 | * serial_setbrg() - Configure baud-rate of currently selected serial port | 386 | * serial_setbrg() - Configure baud-rate of currently selected serial port |
387 | * | 387 | * |
388 | * This function configures the baud-rate of the currently selected | 388 | * This function configures the baud-rate of the currently selected |
389 | * serial port. The baud-rate is retrieved from global data within | 389 | * serial port. The baud-rate is retrieved from global data within |
390 | * the serial port driver. This function uses the get_current() call | 390 | * the serial port driver. This function uses the get_current() call |
391 | * to determine which port is selected. | 391 | * to determine which port is selected. |
392 | * | 392 | * |
393 | * Returns 0 on success, negative on error. | 393 | * Returns 0 on success, negative on error. |
394 | */ | 394 | */ |
395 | void serial_setbrg(void) | 395 | void serial_setbrg(void) |
396 | { | 396 | { |
397 | get_current()->setbrg(); | 397 | get_current()->setbrg(); |
398 | } | 398 | } |
399 | 399 | ||
400 | /** | 400 | /** |
401 | * serial_getc() - Read character from currently selected serial port | 401 | * serial_getc() - Read character from currently selected serial port |
402 | * | 402 | * |
403 | * This function retrieves a character from currently selected serial | 403 | * This function retrieves a character from currently selected serial |
404 | * port. In case there is no character waiting on the serial port, | 404 | * port. In case there is no character waiting on the serial port, |
405 | * this function will block and wait for the character to appear. This | 405 | * this function will block and wait for the character to appear. This |
406 | * function uses the get_current() call to determine which port is | 406 | * function uses the get_current() call to determine which port is |
407 | * selected. | 407 | * selected. |
408 | * | 408 | * |
409 | * Returns the character on success, negative on error. | 409 | * Returns the character on success, negative on error. |
410 | */ | 410 | */ |
411 | int serial_getc(void) | 411 | int serial_getc(void) |
412 | { | 412 | { |
413 | return get_current()->getc(); | 413 | return get_current()->getc(); |
414 | } | 414 | } |
415 | 415 | ||
416 | /** | 416 | /** |
417 | * serial_tstc() - Test if data is available on currently selected serial port | 417 | * serial_tstc() - Test if data is available on currently selected serial port |
418 | * | 418 | * |
419 | * This function tests if one or more characters are available on | 419 | * This function tests if one or more characters are available on |
420 | * currently selected serial port. This function never blocks. This | 420 | * currently selected serial port. This function never blocks. This |
421 | * function uses the get_current() call to determine which port is | 421 | * function uses the get_current() call to determine which port is |
422 | * selected. | 422 | * selected. |
423 | * | 423 | * |
424 | * Returns positive if character is available, zero otherwise. | 424 | * Returns positive if character is available, zero otherwise. |
425 | */ | 425 | */ |
426 | int serial_tstc(void) | 426 | int serial_tstc(void) |
427 | { | 427 | { |
428 | return get_current()->tstc(); | 428 | return get_current()->tstc(); |
429 | } | 429 | } |
430 | 430 | ||
431 | /** | 431 | /** |
432 | * serial_putc() - Output character via currently selected serial port | 432 | * serial_putc() - Output character via currently selected serial port |
433 | * @c: Single character to be output from the serial port. | 433 | * @c: Single character to be output from the serial port. |
434 | * | 434 | * |
435 | * This function outputs a character via currently selected serial | 435 | * This function outputs a character via currently selected serial |
436 | * port. This character is passed to the serial port driver responsible | 436 | * port. This character is passed to the serial port driver responsible |
437 | * for controlling the hardware. The hardware may still be in process | 437 | * for controlling the hardware. The hardware may still be in process |
438 | * of transmitting another character, therefore this function may block | 438 | * of transmitting another character, therefore this function may block |
439 | * for a short amount of time. This function uses the get_current() | 439 | * for a short amount of time. This function uses the get_current() |
440 | * call to determine which port is selected. | 440 | * call to determine which port is selected. |
441 | */ | 441 | */ |
442 | void serial_putc(const char c) | 442 | void serial_putc(const char c) |
443 | { | 443 | { |
444 | get_current()->putc(c); | 444 | get_current()->putc(c); |
445 | } | 445 | } |
446 | 446 | ||
447 | /** | 447 | /** |
448 | * serial_puts() - Output string via currently selected serial port | 448 | * serial_puts() - Output string via currently selected serial port |
449 | * @s: Zero-terminated string to be output from the serial port. | 449 | * @s: Zero-terminated string to be output from the serial port. |
450 | * | 450 | * |
451 | * This function outputs a zero-terminated string via currently | 451 | * This function outputs a zero-terminated string via currently |
452 | * selected serial port. This function behaves as an accelerator | 452 | * selected serial port. This function behaves as an accelerator |
453 | * in case the hardware can queue multiple characters for transfer. | 453 | * in case the hardware can queue multiple characters for transfer. |
454 | * The whole string that is to be output is available to the function | 454 | * The whole string that is to be output is available to the function |
455 | * implementing the hardware manipulation. Transmitting the whole | 455 | * implementing the hardware manipulation. Transmitting the whole |
456 | * string may take some time, thus this function may block for some | 456 | * string may take some time, thus this function may block for some |
457 | * amount of time. This function uses the get_current() call to | 457 | * amount of time. This function uses the get_current() call to |
458 | * determine which port is selected. | 458 | * determine which port is selected. |
459 | */ | 459 | */ |
460 | void serial_puts(const char *s) | 460 | void serial_puts(const char *s) |
461 | { | 461 | { |
462 | get_current()->puts(s); | 462 | get_current()->puts(s); |
463 | } | 463 | } |
464 | 464 | ||
465 | /** | 465 | /** |
466 | * default_serial_puts() - Output string by calling serial_putc() in loop | 466 | * default_serial_puts() - Output string by calling serial_putc() in loop |
467 | * @s: Zero-terminated string to be output from the serial port. | 467 | * @s: Zero-terminated string to be output from the serial port. |
468 | * | 468 | * |
469 | * This function outputs a zero-terminated string by calling serial_putc() | 469 | * This function outputs a zero-terminated string by calling serial_putc() |
470 | * in a loop. Most drivers do not support queueing more than one byte for | 470 | * in a loop. Most drivers do not support queueing more than one byte for |
471 | * transfer, thus this function precisely implements their serial_puts(). | 471 | * transfer, thus this function precisely implements their serial_puts(). |
472 | * | 472 | * |
473 | * To optimize the number of get_current() calls, this function only | 473 | * To optimize the number of get_current() calls, this function only |
474 | * calls get_current() once and then directly accesses the putc() call | 474 | * calls get_current() once and then directly accesses the putc() call |
475 | * of the &struct serial_device . | 475 | * of the &struct serial_device . |
476 | */ | 476 | */ |
477 | void default_serial_puts(const char *s) | 477 | void default_serial_puts(const char *s) |
478 | { | 478 | { |
479 | struct serial_device *dev = get_current(); | 479 | struct serial_device *dev = get_current(); |
480 | while (*s) | 480 | while (*s) |
481 | dev->putc(*s++); | 481 | dev->putc(*s++); |
482 | } | 482 | } |
483 | 483 | ||
484 | #if CONFIG_POST & CONFIG_SYS_POST_UART | 484 | #if CONFIG_POST & CONFIG_SYS_POST_UART |
485 | static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE; | 485 | static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE; |
486 | 486 | ||
487 | /** | 487 | /** |
488 | * uart_post_test() - Test the currently selected serial port using POST | 488 | * uart_post_test() - Test the currently selected serial port using POST |
489 | * @flags: POST framework flags | 489 | * @flags: POST framework flags |
490 | * | 490 | * |
491 | * Do a loopback test of the currently selected serial port. This | 491 | * Do a loopback test of the currently selected serial port. This |
492 | * function is only useful in the context of the POST testing framwork. | 492 | * function is only useful in the context of the POST testing framwork. |
493 | * The serial port is firstly configured into loopback mode and then | 493 | * The serial port is firstly configured into loopback mode and then |
494 | * characters are sent through it. | 494 | * characters are sent through it. |
495 | * | 495 | * |
496 | * Returns 0 on success, value otherwise. | 496 | * Returns 0 on success, value otherwise. |
497 | */ | 497 | */ |
498 | /* Mark weak until post/cpu/.../uart.c migrate over */ | 498 | /* Mark weak until post/cpu/.../uart.c migrate over */ |
499 | __weak | 499 | __weak |
500 | int uart_post_test(int flags) | 500 | int uart_post_test(int flags) |
501 | { | 501 | { |
502 | unsigned char c; | 502 | unsigned char c; |
503 | int ret, saved_baud, b; | 503 | int ret, saved_baud, b; |
504 | struct serial_device *saved_dev, *s; | 504 | struct serial_device *saved_dev, *s; |
505 | bd_t *bd = gd->bd; | 505 | bd_t *bd = gd->bd; |
506 | 506 | ||
507 | /* Save current serial state */ | 507 | /* Save current serial state */ |
508 | ret = 0; | 508 | ret = 0; |
509 | saved_dev = serial_current; | 509 | saved_dev = serial_current; |
510 | saved_baud = bd->bi_baudrate; | 510 | saved_baud = bd->bi_baudrate; |
511 | 511 | ||
512 | for (s = serial_devices; s; s = s->next) { | 512 | for (s = serial_devices; s; s = s->next) { |
513 | /* If this driver doesn't support loop back, skip it */ | 513 | /* If this driver doesn't support loop back, skip it */ |
514 | if (!s->loop) | 514 | if (!s->loop) |
515 | continue; | 515 | continue; |
516 | 516 | ||
517 | /* Test the next device */ | 517 | /* Test the next device */ |
518 | serial_current = s; | 518 | serial_current = s; |
519 | 519 | ||
520 | ret = serial_init(); | 520 | ret = serial_init(); |
521 | if (ret) | 521 | if (ret) |
522 | goto done; | 522 | goto done; |
523 | 523 | ||
524 | /* Consume anything that happens to be queued */ | 524 | /* Consume anything that happens to be queued */ |
525 | while (serial_tstc()) | 525 | while (serial_tstc()) |
526 | serial_getc(); | 526 | serial_getc(); |
527 | 527 | ||
528 | /* Enable loop back */ | 528 | /* Enable loop back */ |
529 | s->loop(1); | 529 | s->loop(1); |
530 | 530 | ||
531 | /* Test every available baud rate */ | 531 | /* Test every available baud rate */ |
532 | for (b = 0; b < ARRAY_SIZE(bauds); ++b) { | 532 | for (b = 0; b < ARRAY_SIZE(bauds); ++b) { |
533 | bd->bi_baudrate = bauds[b]; | 533 | bd->bi_baudrate = bauds[b]; |
534 | serial_setbrg(); | 534 | serial_setbrg(); |
535 | 535 | ||
536 | /* | 536 | /* |
537 | * Stick to printable chars to avoid issues: | 537 | * Stick to printable chars to avoid issues: |
538 | * - terminal corruption | 538 | * - terminal corruption |
539 | * - serial program reacting to sequences and sending | 539 | * - serial program reacting to sequences and sending |
540 | * back random extra data | 540 | * back random extra data |
541 | * - most serial drivers add in extra chars (like \r\n) | 541 | * - most serial drivers add in extra chars (like \r\n) |
542 | */ | 542 | */ |
543 | for (c = 0x20; c < 0x7f; ++c) { | 543 | for (c = 0x20; c < 0x7f; ++c) { |
544 | /* Send it out */ | 544 | /* Send it out */ |
545 | serial_putc(c); | 545 | serial_putc(c); |
546 | 546 | ||
547 | /* Make sure it's the same one */ | 547 | /* Make sure it's the same one */ |
548 | ret = (c != serial_getc()); | 548 | ret = (c != serial_getc()); |
549 | if (ret) { | 549 | if (ret) { |
550 | s->loop(0); | 550 | s->loop(0); |
551 | goto done; | 551 | goto done; |
552 | } | 552 | } |
553 | 553 | ||
554 | /* Clean up the output in case it was sent */ | 554 | /* Clean up the output in case it was sent */ |
555 | serial_putc('\b'); | 555 | serial_putc('\b'); |
556 | ret = ('\b' != serial_getc()); | 556 | ret = ('\b' != serial_getc()); |
557 | if (ret) { | 557 | if (ret) { |
558 | s->loop(0); | 558 | s->loop(0); |
559 | goto done; | 559 | goto done; |
560 | } | 560 | } |
561 | } | 561 | } |
562 | } | 562 | } |
563 | 563 | ||
564 | /* Disable loop back */ | 564 | /* Disable loop back */ |
565 | s->loop(0); | 565 | s->loop(0); |
566 | 566 | ||
567 | /* XXX: There is no serial_stop() !? */ | 567 | /* XXX: There is no serial_stop() !? */ |
568 | if (s->stop) | 568 | if (s->stop) |
569 | s->stop(); | 569 | s->stop(); |
570 | } | 570 | } |
571 | 571 | ||
572 | done: | 572 | done: |
573 | /* Restore previous serial state */ | 573 | /* Restore previous serial state */ |
574 | serial_current = saved_dev; | 574 | serial_current = saved_dev; |
575 | bd->bi_baudrate = saved_baud; | 575 | bd->bi_baudrate = saved_baud; |
576 | serial_reinit_all(); | 576 | serial_reinit_all(); |
577 | serial_setbrg(); | 577 | serial_setbrg(); |
578 | 578 | ||
579 | return ret; | 579 | return ret; |
580 | } | 580 | } |
581 | #endif | 581 | #endif |
582 | 582 |
drivers/serial/serial_zynq.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2012 Michal Simek <monstr@monstr.eu> | 2 | * Copyright (C) 2012 Michal Simek <monstr@monstr.eu> |
3 | * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved. | 3 | * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * SPDX-License-Identifier: GPL-2.0+ | 5 | * SPDX-License-Identifier: GPL-2.0+ |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <common.h> | 8 | #include <common.h> |
9 | #include <fdtdec.h> | 9 | #include <fdtdec.h> |
10 | #include <watchdog.h> | 10 | #include <watchdog.h> |
11 | #include <asm/io.h> | 11 | #include <asm/io.h> |
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | #include <serial.h> | 13 | #include <serial.h> |
14 | #include <asm/arch/clk.h> | 14 | #include <asm/arch/clk.h> |
15 | #include <asm/arch/hardware.h> | 15 | #include <asm/arch/hardware.h> |
16 | 16 | ||
17 | DECLARE_GLOBAL_DATA_PTR; | 17 | DECLARE_GLOBAL_DATA_PTR; |
18 | 18 | ||
19 | #define ZYNQ_UART_SR_TXFULL 0x00000010 /* TX FIFO full */ | 19 | #define ZYNQ_UART_SR_TXFULL 0x00000010 /* TX FIFO full */ |
20 | #define ZYNQ_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */ | 20 | #define ZYNQ_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */ |
21 | 21 | ||
22 | #define ZYNQ_UART_CR_TX_EN 0x00000010 /* TX enabled */ | 22 | #define ZYNQ_UART_CR_TX_EN 0x00000010 /* TX enabled */ |
23 | #define ZYNQ_UART_CR_RX_EN 0x00000004 /* RX enabled */ | 23 | #define ZYNQ_UART_CR_RX_EN 0x00000004 /* RX enabled */ |
24 | #define ZYNQ_UART_CR_TXRST 0x00000002 /* TX logic reset */ | 24 | #define ZYNQ_UART_CR_TXRST 0x00000002 /* TX logic reset */ |
25 | #define ZYNQ_UART_CR_RXRST 0x00000001 /* RX logic reset */ | 25 | #define ZYNQ_UART_CR_RXRST 0x00000001 /* RX logic reset */ |
26 | 26 | ||
27 | #define ZYNQ_UART_MR_PARITY_NONE 0x00000020 /* No parity mode */ | 27 | #define ZYNQ_UART_MR_PARITY_NONE 0x00000020 /* No parity mode */ |
28 | 28 | ||
29 | struct uart_zynq { | 29 | struct uart_zynq { |
30 | u32 control; /* Control Register [8:0] */ | 30 | u32 control; /* Control Register [8:0] */ |
31 | u32 mode; /* Mode Register [10:0] */ | 31 | u32 mode; /* Mode Register [10:0] */ |
32 | u32 reserved1[4]; | 32 | u32 reserved1[4]; |
33 | u32 baud_rate_gen; /* Baud Rate Generator [15:0] */ | 33 | u32 baud_rate_gen; /* Baud Rate Generator [15:0] */ |
34 | u32 reserved2[4]; | 34 | u32 reserved2[4]; |
35 | u32 channel_sts; /* Channel Status [11:0] */ | 35 | u32 channel_sts; /* Channel Status [11:0] */ |
36 | u32 tx_rx_fifo; /* FIFO [15:0] or [7:0] */ | 36 | u32 tx_rx_fifo; /* FIFO [15:0] or [7:0] */ |
37 | u32 baud_rate_divider; /* Baud Rate Divider [7:0] */ | 37 | u32 baud_rate_divider; /* Baud Rate Divider [7:0] */ |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct uart_zynq *uart_zynq_ports[2] = { | 40 | static struct uart_zynq *uart_zynq_ports[2] = { |
41 | [0] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR0, | 41 | [0] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR0, |
42 | [1] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR1, | 42 | [1] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR1, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #if !defined(CONFIG_ZYNQ_SERIAL_BAUDRATE0) | 45 | #if !defined(CONFIG_ZYNQ_SERIAL_BAUDRATE0) |
46 | # define CONFIG_ZYNQ_SERIAL_BAUDRATE0 CONFIG_BAUDRATE | 46 | # define CONFIG_ZYNQ_SERIAL_BAUDRATE0 CONFIG_BAUDRATE |
47 | #endif | 47 | #endif |
48 | #if !defined(CONFIG_ZYNQ_SERIAL_BAUDRATE1) | 48 | #if !defined(CONFIG_ZYNQ_SERIAL_BAUDRATE1) |
49 | # define CONFIG_ZYNQ_SERIAL_BAUDRATE1 CONFIG_BAUDRATE | 49 | # define CONFIG_ZYNQ_SERIAL_BAUDRATE1 CONFIG_BAUDRATE |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | struct uart_zynq_params { | 52 | struct uart_zynq_params { |
53 | u32 baudrate; | 53 | u32 baudrate; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct uart_zynq_params uart_zynq_ports_param[2] = { | 56 | static struct uart_zynq_params uart_zynq_ports_param[2] = { |
57 | [0].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE0, | 57 | [0].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE0, |
58 | [1].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE1, | 58 | [1].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE1, |
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* Set up the baud rate in gd struct */ | 61 | /* Set up the baud rate in gd struct */ |
62 | static void uart_zynq_serial_setbrg(const int port) | 62 | static void uart_zynq_serial_setbrg(const int port) |
63 | { | 63 | { |
64 | /* Calculation results. */ | 64 | /* Calculation results. */ |
65 | unsigned int calc_bauderror, bdiv, bgen; | 65 | unsigned int calc_bauderror, bdiv, bgen; |
66 | unsigned long calc_baud = 0; | 66 | unsigned long calc_baud = 0; |
67 | unsigned long baud = uart_zynq_ports_param[port].baudrate; | 67 | unsigned long baud = uart_zynq_ports_param[port].baudrate; |
68 | unsigned long clock = get_uart_clk(port); | 68 | unsigned long clock = get_uart_clk(port); |
69 | struct uart_zynq *regs = uart_zynq_ports[port]; | 69 | struct uart_zynq *regs = uart_zynq_ports[port]; |
70 | 70 | ||
71 | /* master clock | 71 | /* master clock |
72 | * Baud rate = ------------------ | 72 | * Baud rate = ------------------ |
73 | * bgen * (bdiv + 1) | 73 | * bgen * (bdiv + 1) |
74 | * | 74 | * |
75 | * Find acceptable values for baud generation. | 75 | * Find acceptable values for baud generation. |
76 | */ | 76 | */ |
77 | for (bdiv = 4; bdiv < 255; bdiv++) { | 77 | for (bdiv = 4; bdiv < 255; bdiv++) { |
78 | bgen = clock / (baud * (bdiv + 1)); | 78 | bgen = clock / (baud * (bdiv + 1)); |
79 | if (bgen < 2 || bgen > 65535) | 79 | if (bgen < 2 || bgen > 65535) |
80 | continue; | 80 | continue; |
81 | 81 | ||
82 | calc_baud = clock / (bgen * (bdiv + 1)); | 82 | calc_baud = clock / (bgen * (bdiv + 1)); |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Use first calculated baudrate with | 85 | * Use first calculated baudrate with |
86 | * an acceptable (<3%) error | 86 | * an acceptable (<3%) error |
87 | */ | 87 | */ |
88 | if (baud > calc_baud) | 88 | if (baud > calc_baud) |
89 | calc_bauderror = baud - calc_baud; | 89 | calc_bauderror = baud - calc_baud; |
90 | else | 90 | else |
91 | calc_bauderror = calc_baud - baud; | 91 | calc_bauderror = calc_baud - baud; |
92 | if (((calc_bauderror * 100) / baud) < 3) | 92 | if (((calc_bauderror * 100) / baud) < 3) |
93 | break; | 93 | break; |
94 | } | 94 | } |
95 | 95 | ||
96 | writel(bdiv, ®s->baud_rate_divider); | 96 | writel(bdiv, ®s->baud_rate_divider); |
97 | writel(bgen, ®s->baud_rate_gen); | 97 | writel(bgen, ®s->baud_rate_gen); |
98 | } | 98 | } |
99 | 99 | ||
100 | /* Initialize the UART, with...some settings. */ | 100 | /* Initialize the UART, with...some settings. */ |
101 | static int uart_zynq_serial_init(const int port) | 101 | static int uart_zynq_serial_init(const int port) |
102 | { | 102 | { |
103 | struct uart_zynq *regs = uart_zynq_ports[port]; | 103 | struct uart_zynq *regs = uart_zynq_ports[port]; |
104 | 104 | ||
105 | if (!regs) | 105 | if (!regs) |
106 | return -1; | 106 | return -1; |
107 | 107 | ||
108 | /* RX/TX enabled & reset */ | 108 | /* RX/TX enabled & reset */ |
109 | writel(ZYNQ_UART_CR_TX_EN | ZYNQ_UART_CR_RX_EN | ZYNQ_UART_CR_TXRST | \ | 109 | writel(ZYNQ_UART_CR_TX_EN | ZYNQ_UART_CR_RX_EN | ZYNQ_UART_CR_TXRST | \ |
110 | ZYNQ_UART_CR_RXRST, ®s->control); | 110 | ZYNQ_UART_CR_RXRST, ®s->control); |
111 | writel(ZYNQ_UART_MR_PARITY_NONE, ®s->mode); /* 8 bit, no parity */ | 111 | writel(ZYNQ_UART_MR_PARITY_NONE, ®s->mode); /* 8 bit, no parity */ |
112 | uart_zynq_serial_setbrg(port); | 112 | uart_zynq_serial_setbrg(port); |
113 | 113 | ||
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | static void uart_zynq_serial_putc(const char c, const int port) | 117 | static void uart_zynq_serial_putc(const char c, const int port) |
118 | { | 118 | { |
119 | struct uart_zynq *regs = uart_zynq_ports[port]; | 119 | struct uart_zynq *regs = uart_zynq_ports[port]; |
120 | 120 | ||
121 | while ((readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0) | 121 | while ((readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0) |
122 | WATCHDOG_RESET(); | 122 | WATCHDOG_RESET(); |
123 | 123 | ||
124 | if (c == '\n') { | 124 | if (c == '\n') { |
125 | writel('\r', ®s->tx_rx_fifo); | 125 | writel('\r', ®s->tx_rx_fifo); |
126 | while ((readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0) | 126 | while ((readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0) |
127 | WATCHDOG_RESET(); | 127 | WATCHDOG_RESET(); |
128 | } | 128 | } |
129 | writel(c, ®s->tx_rx_fifo); | 129 | writel(c, ®s->tx_rx_fifo); |
130 | } | 130 | } |
131 | 131 | ||
132 | static void uart_zynq_serial_puts(const char *s, const int port) | 132 | static void uart_zynq_serial_puts(const char *s, const int port) |
133 | { | 133 | { |
134 | while (*s) | 134 | while (*s) |
135 | uart_zynq_serial_putc(*s++, port); | 135 | uart_zynq_serial_putc(*s++, port); |
136 | } | 136 | } |
137 | 137 | ||
138 | static int uart_zynq_serial_tstc(const int port) | 138 | static int uart_zynq_serial_tstc(const int port) |
139 | { | 139 | { |
140 | struct uart_zynq *regs = uart_zynq_ports[port]; | 140 | struct uart_zynq *regs = uart_zynq_ports[port]; |
141 | 141 | ||
142 | return (readl(®s->channel_sts) & ZYNQ_UART_SR_RXEMPTY) == 0; | 142 | return (readl(®s->channel_sts) & ZYNQ_UART_SR_RXEMPTY) == 0; |
143 | } | 143 | } |
144 | 144 | ||
145 | static int uart_zynq_serial_getc(const int port) | 145 | static int uart_zynq_serial_getc(const int port) |
146 | { | 146 | { |
147 | struct uart_zynq *regs = uart_zynq_ports[port]; | 147 | struct uart_zynq *regs = uart_zynq_ports[port]; |
148 | 148 | ||
149 | while (!uart_zynq_serial_tstc(port)) | 149 | while (!uart_zynq_serial_tstc(port)) |
150 | WATCHDOG_RESET(); | 150 | WATCHDOG_RESET(); |
151 | return readl(®s->tx_rx_fifo); | 151 | return readl(®s->tx_rx_fifo); |
152 | } | 152 | } |
153 | 153 | ||
154 | /* Multi serial device functions */ | 154 | /* Multi serial device functions */ |
155 | #define DECLARE_PSSERIAL_FUNCTIONS(port) \ | 155 | #define DECLARE_PSSERIAL_FUNCTIONS(port) \ |
156 | static int uart_zynq##port##_init(void) \ | 156 | static int uart_zynq##port##_init(void) \ |
157 | { return uart_zynq_serial_init(port); } \ | 157 | { return uart_zynq_serial_init(port); } \ |
158 | static void uart_zynq##port##_setbrg(void) \ | 158 | static void uart_zynq##port##_setbrg(void) \ |
159 | { return uart_zynq_serial_setbrg(port); } \ | 159 | { return uart_zynq_serial_setbrg(port); } \ |
160 | static int uart_zynq##port##_getc(void) \ | 160 | static int uart_zynq##port##_getc(void) \ |
161 | { return uart_zynq_serial_getc(port); } \ | 161 | { return uart_zynq_serial_getc(port); } \ |
162 | static int uart_zynq##port##_tstc(void) \ | 162 | static int uart_zynq##port##_tstc(void) \ |
163 | { return uart_zynq_serial_tstc(port); } \ | 163 | { return uart_zynq_serial_tstc(port); } \ |
164 | static void uart_zynq##port##_putc(const char c) \ | 164 | static void uart_zynq##port##_putc(const char c) \ |
165 | { uart_zynq_serial_putc(c, port); } \ | 165 | { uart_zynq_serial_putc(c, port); } \ |
166 | static void uart_zynq##port##_puts(const char *s) \ | 166 | static void uart_zynq##port##_puts(const char *s) \ |
167 | { uart_zynq_serial_puts(s, port); } | 167 | { uart_zynq_serial_puts(s, port); } |
168 | 168 | ||
169 | /* Serial device descriptor */ | 169 | /* Serial device descriptor */ |
170 | #define INIT_PSSERIAL_STRUCTURE(port, __name) { \ | 170 | #define INIT_PSSERIAL_STRUCTURE(port, __name) { \ |
171 | .name = __name, \ | 171 | .name = __name, \ |
172 | .start = uart_zynq##port##_init, \ | 172 | .start = uart_zynq##port##_init, \ |
173 | .stop = NULL, \ | 173 | .stop = NULL, \ |
174 | .setbrg = uart_zynq##port##_setbrg, \ | 174 | .setbrg = uart_zynq##port##_setbrg, \ |
175 | .getc = uart_zynq##port##_getc, \ | 175 | .getc = uart_zynq##port##_getc, \ |
176 | .tstc = uart_zynq##port##_tstc, \ | 176 | .tstc = uart_zynq##port##_tstc, \ |
177 | .putc = uart_zynq##port##_putc, \ | 177 | .putc = uart_zynq##port##_putc, \ |
178 | .puts = uart_zynq##port##_puts, \ | 178 | .puts = uart_zynq##port##_puts, \ |
179 | } | 179 | } |
180 | 180 | ||
181 | DECLARE_PSSERIAL_FUNCTIONS(0); | 181 | DECLARE_PSSERIAL_FUNCTIONS(0); |
182 | static struct serial_device uart_zynq_serial0_device = | 182 | static struct serial_device uart_zynq_serial0_device = |
183 | INIT_PSSERIAL_STRUCTURE(0, "ttyPS0"); | 183 | INIT_PSSERIAL_STRUCTURE(0, "ttyPS0"); |
184 | DECLARE_PSSERIAL_FUNCTIONS(1); | 184 | DECLARE_PSSERIAL_FUNCTIONS(1); |
185 | static struct serial_device uart_zynq_serial1_device = | 185 | static struct serial_device uart_zynq_serial1_device = |
186 | INIT_PSSERIAL_STRUCTURE(1, "ttyPS1"); | 186 | INIT_PSSERIAL_STRUCTURE(1, "ttyPS1"); |
187 | 187 | ||
188 | #ifdef CONFIG_OF_CONTROL | 188 | #ifdef CONFIG_OF_CONTROL |
189 | __weak struct serial_device *default_serial_console(void) | 189 | __weak struct serial_device *default_serial_console(void) |
190 | { | 190 | { |
191 | const void *blob = gd->fdt_blob; | 191 | const void *blob = gd->fdt_blob; |
192 | int node; | 192 | int node; |
193 | unsigned int base_addr; | 193 | unsigned int base_addr; |
194 | 194 | ||
195 | node = fdt_path_offset(blob, "serial0"); | 195 | node = fdt_path_offset(blob, "serial0"); |
196 | if (node < 0) | 196 | if (node < 0) |
197 | return NULL; | 197 | return NULL; |
198 | 198 | ||
199 | base_addr = fdtdec_get_addr(blob, node, "reg"); | 199 | base_addr = fdtdec_get_addr(blob, node, "reg"); |
200 | if (base_addr == FDT_ADDR_T_NONE) | 200 | if (base_addr == FDT_ADDR_T_NONE) |
201 | return NULL; | 201 | return NULL; |
202 | 202 | ||
203 | if (base_addr == ZYNQ_SERIAL_BASEADDR0) | 203 | if (base_addr == ZYNQ_SERIAL_BASEADDR0) |
204 | return &uart_zynq_serial0_device; | 204 | return &uart_zynq_serial0_device; |
205 | 205 | ||
206 | if (base_addr == ZYNQ_SERIAL_BASEADDR1) | 206 | if (base_addr == ZYNQ_SERIAL_BASEADDR1) |
207 | return &uart_zynq_serial1_device; | 207 | return &uart_zynq_serial1_device; |
208 | 208 | ||
209 | return NULL; | 209 | return NULL; |
210 | } | 210 | } |
211 | #else | 211 | #else |
212 | __weak struct serial_device *default_serial_console(void) | 212 | __weak struct serial_device *default_serial_console(void) |
213 | { | 213 | { |
214 | #if defined(CONFIG_ZYNQ_SERIAL_UART0) | 214 | #if defined(CONFIG_ZYNQ_SERIAL_UART0) |
215 | if (uart_zynq_ports[0]) | 215 | if (uart_zynq_ports[0]) |
216 | return &uart_zynq_serial0_device; | 216 | return &uart_zynq_serial0_device; |
217 | #endif | 217 | #endif |
218 | #if defined(CONFIG_ZYNQ_SERIAL_UART1) | 218 | #if defined(CONFIG_ZYNQ_SERIAL_UART1) |
219 | if (uart_zynq_ports[1]) | 219 | if (uart_zynq_ports[1]) |
220 | return &uart_zynq_serial1_device; | 220 | return &uart_zynq_serial1_device; |
221 | #endif | 221 | #endif |
222 | return NULL; | 222 | return NULL; |
223 | } | 223 | } |
224 | #endif | 224 | #endif |
225 | 225 | ||
226 | void zynq_serial_initalize(void) | 226 | void zynq_serial_initialize(void) |
227 | { | 227 | { |
228 | serial_register(&uart_zynq_serial0_device); | 228 | serial_register(&uart_zynq_serial0_device); |
229 | serial_register(&uart_zynq_serial1_device); | 229 | serial_register(&uart_zynq_serial1_device); |
230 | } | 230 | } |
231 | 231 |