]>
Commit | Line | Data |
---|---|---|
0db5bca8 WD |
1 | /* |
2 | * (C) Copyright 2003 | |
3 | * Martin Winistoerfer, martinwinistoerfer@gmx.ch. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
8bde7f77 | 20 | * Foundation, |
0db5bca8 WD |
21 | */ |
22 | ||
23 | /* | |
24 | * File: serial.c | |
8bde7f77 WD |
25 | * |
26 | * Discription: Serial interface driver for SCI1 and SCI2. | |
53677ef1 WD |
27 | * Since this code will be called from ROM use |
28 | * only non-static local variables. | |
0db5bca8 WD |
29 | * |
30 | */ | |
31 | ||
32 | #include <common.h> | |
33 | #include <watchdog.h> | |
34 | #include <command.h> | |
35 | #include <mpc5xx.h> | |
b57c6528 MV |
36 | #include <serial.h> |
37 | #include <linux/compiler.h> | |
0db5bca8 | 38 | |
d87080b7 | 39 | DECLARE_GLOBAL_DATA_PTR; |
0db5bca8 WD |
40 | |
41 | /* | |
b57c6528 | 42 | * Local functions |
0db5bca8 WD |
43 | */ |
44 | ||
b57c6528 MV |
45 | static int ready_to_send(void) |
46 | { | |
47 | volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; | |
48 | volatile short status; | |
49 | ||
50 | do { | |
51 | #if defined(CONFIG_5xx_CONS_SCI1) | |
52 | status = immr->im_qsmcm.qsmcm_sc1sr; | |
53 | #else | |
54 | status = immr->im_qsmcm.qsmcm_sc2sr; | |
55 | #endif | |
56 | ||
57 | #if defined(CONFIG_WATCHDOG) | |
58 | reset_5xx_watchdog (immr); | |
59 | #endif | |
60 | } while ((status & SCI_TDRE) == 0); | |
61 | return 1; | |
62 | ||
63 | } | |
0db5bca8 WD |
64 | |
65 | /* | |
66 | * Minimal global serial functions needed to use one of the SCI modules. | |
67 | */ | |
68 | ||
b57c6528 | 69 | static int mpc5xx_serial_init(void) |
0db5bca8 | 70 | { |
6d0f6bcf | 71 | volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; |
0db5bca8 WD |
72 | |
73 | serial_setbrg(); | |
74 | ||
75 | #if defined(CONFIG_5xx_CONS_SCI1) | |
76 | /* 10-Bit, 1 start bit, 8 data bit, no parity, 1 stop bit */ | |
77 | immr->im_qsmcm.qsmcm_scc1r1 = SCI_M_10; | |
8bde7f77 | 78 | immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE; |
0db5bca8 | 79 | #else |
8bde7f77 | 80 | immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10; |
0db5bca8 WD |
81 | immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE; |
82 | #endif | |
83 | return 0; | |
84 | } | |
85 | ||
b57c6528 | 86 | static void mpc5xx_serial_putc(const char c) |
8bde7f77 | 87 | { |
6d0f6bcf | 88 | volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; |
8bde7f77 | 89 | |
0db5bca8 WD |
90 | /* Test for completition */ |
91 | if(ready_to_send()) { | |
92 | #if defined(CONFIG_5xx_CONS_SCI1) | |
8bde7f77 | 93 | immr->im_qsmcm.qsmcm_sc1dr = (short)c; |
0db5bca8 WD |
94 | #else |
95 | immr->im_qsmcm.qsmcm_sc2dr = (short)c; | |
8bde7f77 | 96 | #endif |
0db5bca8 WD |
97 | if(c == '\n') { |
98 | if(ready_to_send()); | |
99 | #if defined(CONFIG_5xx_CONS_SCI1) | |
100 | immr->im_qsmcm.qsmcm_sc1dr = (short)'\r'; | |
101 | #else | |
102 | immr->im_qsmcm.qsmcm_sc2dr = (short)'\r'; | |
103 | #endif | |
104 | } | |
105 | } | |
106 | } | |
107 | ||
b57c6528 | 108 | static int mpc5xx_serial_getc(void) |
8bde7f77 | 109 | { |
6d0f6bcf | 110 | volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; |
0db5bca8 WD |
111 | volatile short status; |
112 | unsigned char tmp; | |
8bde7f77 | 113 | |
0db5bca8 WD |
114 | /* New data ? */ |
115 | do { | |
116 | #if defined(CONFIG_5xx_CONS_SCI1) | |
8bde7f77 | 117 | status = immr->im_qsmcm.qsmcm_sc1sr; |
0db5bca8 WD |
118 | #else |
119 | status = immr->im_qsmcm.qsmcm_sc2sr; | |
120 | #endif | |
121 | ||
122 | #if defined(CONFIG_WATCHDOG) | |
8bde7f77 | 123 | reset_5xx_watchdog (immr); |
0db5bca8 | 124 | #endif |
8bde7f77 WD |
125 | } while ((status & SCI_RDRF) == 0); |
126 | ||
0db5bca8 WD |
127 | /* Read data */ |
128 | #if defined(CONFIG_5xx_CONS_SCI1) | |
8bde7f77 | 129 | tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK); |
0db5bca8 WD |
130 | #else |
131 | tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK); | |
132 | #endif | |
133 | return tmp; | |
134 | } | |
135 | ||
b57c6528 | 136 | static int mpc5xx_serial_tstc(void) |
0db5bca8 | 137 | { |
6d0f6bcf | 138 | volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; |
8bde7f77 | 139 | short status; |
0db5bca8 WD |
140 | |
141 | /* New data character ? */ | |
142 | #if defined(CONFIG_5xx_CONS_SCI1) | |
8bde7f77 | 143 | status = immr->im_qsmcm.qsmcm_sc1sr; |
0db5bca8 WD |
144 | #else |
145 | status = immr->im_qsmcm.qsmcm_sc2sr; | |
146 | #endif | |
8bde7f77 | 147 | return (status & SCI_RDRF); |
0db5bca8 WD |
148 | } |
149 | ||
b57c6528 | 150 | static void mpc5xx_serial_setbrg(void) |
0db5bca8 | 151 | { |
6d0f6bcf | 152 | volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; |
0db5bca8 WD |
153 | short scxbr; |
154 | ||
155 | /* Set baudrate */ | |
156 | scxbr = (gd->cpu_clk / (32 * gd->baudrate)); | |
157 | #if defined(CONFIG_5xx_CONS_SCI1) | |
8bde7f77 | 158 | immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK); |
0db5bca8 WD |
159 | #else |
160 | immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK); | |
161 | #endif | |
162 | } | |
163 | ||
b57c6528 | 164 | static void mpc5xx_serial_puts(const char *s) |
0db5bca8 WD |
165 | { |
166 | while (*s) { | |
167 | serial_putc(*s); | |
168 | ++s; | |
169 | } | |
170 | } | |
171 | ||
b57c6528 MV |
172 | static struct serial_device mpc5xx_serial_drv = { |
173 | .name = "mpc5xx_serial", | |
174 | .start = mpc5xx_serial_init, | |
175 | .stop = NULL, | |
176 | .setbrg = mpc5xx_serial_setbrg, | |
177 | .putc = mpc5xx_serial_putc, | |
178 | .puts = mpc5xx_serial_puts, | |
179 | .getc = mpc5xx_serial_getc, | |
180 | .tstc = mpc5xx_serial_tstc, | |
181 | }; | |
182 | ||
183 | void mpc5xx_serial_initialize(void) | |
0db5bca8 | 184 | { |
b57c6528 MV |
185 | serial_register(&mpc5xx_serial_drv); |
186 | } | |
0db5bca8 | 187 | |
b57c6528 MV |
188 | __weak struct serial_device *default_serial_console(void) |
189 | { | |
190 | return &mpc5xx_serial_drv; | |
191 | } |