blob: 5d6524dbd3804e965f120d9f0eb28c626f3b53ef [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <common.h>
25#include <mpc8xx.h>
26#include <asm/8xx_immap.h>
27#include "ioport.h"
28
29#if 0
30#define IOPORT_DEBUG
31#endif
32
33#ifdef IOPORT_DEBUG
34#define PRINTF(fmt,args...) printf (fmt ,##args)
35#else
36#define PRINTF(fmt,args...)
37#endif
38
39/*
40 * The ioport configuration table.
41 */
42const mpc8xx_iop_conf_t iop_conf_tab[NUM_PORTS][PORT_BITS] = {
43 /*
44 * Port A configuration
45 * Pin Signal Type Active Initial state
46 * PA7 fpgaProgramLowOut Out Low High
47 */
48 { /* conf ppar psor pdir podr pdat pint function */
49 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* No pin */
50 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* No pin */
51 /* PA15 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
52 /* PA14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
53 /* PA13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
54 /* PA12 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
55 /* PA11 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
56 /* PA10 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
57 /* PA9 */ { 1, 0, 0, 1, 0, 0, 0 }, /* grn bicolor LED 1*/
58 /* PA8 */ { 1, 0, 0, 1, 0, 0, 0 }, /* red bicolor LED 1*/
59 /* PA7 */ { 1, 0, 0, 1, 0, 1, 0 }, /* fpgaProgramLow */
60 /* PA6 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
61 /* PA5 */ { 1, 0, 0, 1, 0, 0, 0 }, /* grn bicolor LED 0*/
62 /* PA4 */ { 1, 0, 0, 1, 0, 0, 0 }, /* red bicolor LED 0*/
63 /* PA3 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
64 /* PA2 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
65 /* PA1 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
66 /* PA0 */ { 0, 0, 0, 0, 0, 0, 0 } /* */
67 },
68
69 /*
70 * Pin Signal Type Active Initial state
71 * PB14 docBusyLowIn In Low X
72 * PB15 gpio1Sig Out High Low
73 * PB16 fpgaDoneBi In High X
74 * PB17 swBitOkLowOut Out Low Low
75 * PB19 speakerVolSig Out/Hi-Z High/Low High (Hi-Z)
76 * PB22 fpgaInitLowBi In Low X
77 * PB23 batteryOkSig In High X
78 */
79 { /* conf ppar psor pdir podr pdat pint function */
80 /* PB31 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
81 /* PB30 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
82 /* PB29 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
83 /* PB28 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
84 /* PB27 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
85 /* PB26 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
86 /* PB25 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
87 /* PB24 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
88 /* PB23 */ { 1, 0, 0, 0, 0, 0, 0 }, /* batteryOk */
89 /* PB22 */ { 1, 0, 0, 0, 0, 0, 0 }, /* fpgaInitLowBi */
90 /* PB21 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
91 /* PB20 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
92 /* PB19 */ { 1, 0, 0, 1, 1, 1, 0 }, /* speakerVol */
93 /* PB18 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
94 /* PB17 */ { 1, 0, 0, 1, 0, 0, 0 }, /* swBitOkLow */
95 /* PB16 */ { 1, 0, 0, 0, 0, 0, 0 }, /* fpgaDone */
96 /* PB15 */ { 1, 0, 0, 1, 0, 0, 0 }, /* gpio1 */
97 /* PB14 */ { 1, 0, 0, 0, 0, 0, 0 } /* docBusyLow */
98 },
99
100 /*
101 * Pin Signal Type Active Initial state
102 * PC4 i2cBus1EnSig Out High High
103 * PC5 i2cBus2EnSig Out High High
104 * PC6 gpio0Sig Out High Low
105 * PC8 i2cBus3EnSig Out High High
106 * PC10 i2cBus4EnSig Out High High
107 * PC11 fpgaResetLowOut Out Low High
108 * PC12 systemBitOkIn In High X
109 * PC15 selfDreqLow In Low X
110 */
111 { /* conf ppar psor pdir podr pdat pint function */
112 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
113 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
114 /* PC15 */ { 1, 0, 0, 0, 0, 0, 0 }, /* selfDreqLowIn */
115 /* PC14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
116 /* PC13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
117 /* PC12 */ { 1, 0, 0, 0, 0, 0, 0 }, /* systemBitOkIn */
118 /* PC11 */ { 1, 0, 0, 1, 0, 1, 0 }, /* fpgaResetLowOut */
119 /* PC10 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus4EnSig */
120 /* PC9 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
121 /* PC8 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus3EnSig */
122 /* PC7 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
123 /* PC6 */ { 1, 0, 0, 1, 0, 1, 0 }, /* gpio0 */
124 /* PC5 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus2EnSig */
125 /* PC4 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus1EnSig */
126 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
127 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
128 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
129 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 } /* */
130 },
131
132 /* Port D configuration */
133 { /* conf ppar psor pdir podr pdat pint function */
134 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
135 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
136 /* PD15 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
137 /* PD14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
138 /* PD13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
139 /* PD12 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
140 /* PD11 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
141 /* PD10 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
142 /* PD9 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
143 /* PD8 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
144 /* PD7 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
145 /* PD6 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
146 /* PD5 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
147 /* PD4 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
148 /* PD3 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
149 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
150 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
151 /* N/A */ { 0, 0, 0, 0, 0, 0, 0 } /* */
152 }
153};
154
155/*
156 * Configure the MPC8XX I/O ports per the ioport configuration table
157 * (taken from ./cpu/mpc8260/cpu_init.c)
158 */
159void
160config_mpc8xx_ioports(volatile immap_t *immr)
161{
162 int portnum;
163
164 for (portnum = 0; portnum < NUM_PORTS; portnum++) {
165 uint pmsk = 0, ppar = 0, psor = 0, pdir = 0;
166 uint podr = 0, pdat = 0, pint = 0;
167 uint msk = 1;
168 mpc8xx_iop_conf_t *iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][0];
169 mpc8xx_iop_conf_t *eiopc = iopc + PORT_BITS;
170
171 /*
172 * For all ports except port B, ignore the two don't care entries
173 * in the configuration tables.
174 */
175 if (portnum != 1) {
176 iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][2];
177 }
178
179 /*
180 * NOTE: index 0 refers to pin 17, index 17 refers to pin 0
181 */
182 while (iopc < eiopc) {
183 if (iopc->conf) {
184 pmsk |= msk;
185 if (iopc->ppar) ppar |= msk;
186 if (iopc->psor) psor |= msk;
187 if (iopc->pdir) pdir |= msk;
188 if (iopc->podr) podr |= msk;
189 if (iopc->pdat) pdat |= msk;
190 if (iopc->pint) pint |= msk;
191 }
192 msk <<= 1;
193 iopc++;
194 }
195
196 PRINTF("%s:%d:\n portnum=%d ", __FUNCTION__, __LINE__, portnum);
197#ifdef IOPORT_DEBUG
198 switch(portnum) {
199 case 0: printf("(A)\n"); break;
200 case 1: printf("(B)\n"); break;
201 case 2: printf("(C)\n"); break;
202 case 3: printf("(D)\n"); break;
203 default: printf("(?)\n"); break;
204 }
205#endif
206 PRINTF(" ppar=0x%.8x pdir=0x%.8x podr=0x%.8x\n"
207 " pdat=0x%.8x psor=0x%.8x pint=0x%.8x pmsk=0x%.8x\n",
208 ppar, pdir, podr, pdat, psor, pint, pmsk);
209
210 /*
211 * Have to handle the ioports on a port-by-port basis since there
212 * are three different flavors.
213 */
214 if (pmsk != 0) {
215 uint tpmsk = ~pmsk;
216
217 if (0 == portnum) { /* port A */
218 immr->im_ioport.iop_papar &= tpmsk;
219 immr->im_ioport.iop_padat =
220 (immr->im_ioport.iop_padat & tpmsk) | pdat;
221 immr->im_ioport.iop_padir =
222 (immr->im_ioport.iop_padir & tpmsk) | pdir;
223 immr->im_ioport.iop_paodr =
224 (immr->im_ioport.iop_paodr & tpmsk) | podr;
225 immr->im_ioport.iop_papar |= ppar;
226 }
227 else if (1 == portnum) { /* port B */
228 immr->im_cpm.cp_pbpar &= tpmsk;
229 immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & tpmsk) | pdat;
230 immr->im_cpm.cp_pbdir = (immr->im_cpm.cp_pbdir & tpmsk) | pdir;
231 immr->im_cpm.cp_pbodr = (immr->im_cpm.cp_pbodr & tpmsk) | podr;
232 immr->im_cpm.cp_pbpar |= ppar;
233 }
234 else if (2 == portnum) { /* port C */
235 immr->im_ioport.iop_pcpar &= tpmsk;
236 immr->im_ioport.iop_pcdat =
237 (immr->im_ioport.iop_pcdat & tpmsk) | pdat;
238 immr->im_ioport.iop_pcdir =
239 (immr->im_ioport.iop_pcdir & tpmsk) | pdir;
240 immr->im_ioport.iop_pcint =
241 (immr->im_ioport.iop_pcint & tpmsk) | pint;
242 immr->im_ioport.iop_pcso =
243 (immr->im_ioport.iop_pcso & tpmsk) | psor;
244 immr->im_ioport.iop_pcpar |= ppar;
245 }
246 else if (3 == portnum) { /* port D */
247 immr->im_ioport.iop_pdpar &= tpmsk;
248 immr->im_ioport.iop_pddat =
249 (immr->im_ioport.iop_pddat & tpmsk) | pdat;
250 immr->im_ioport.iop_pddir =
251 (immr->im_ioport.iop_pddir & tpmsk) | pdir;
252 immr->im_ioport.iop_pdpar |= ppar;
253 }
254 }
255 }
256
257 PRINTF("%s:%d: Port A:\n papar=0x%.4x padir=0x%.4x"
258 " paodr=0x%.4x\n padat=0x%.4x\n", __FUNCTION__, __LINE__,
259 immr->im_ioport.iop_papar, immr->im_ioport.iop_padir,
260 immr->im_ioport.iop_paodr, immr->im_ioport.iop_padat);
261 PRINTF("%s:%d: Port B:\n pbpar=0x%.8x pbdir=0x%.8x"
262 " pbodr=0x%.8x\n pbdat=0x%.8x\n", __FUNCTION__, __LINE__,
263 immr->im_cpm.cp_pbpar, immr->im_cpm.cp_pbdir,
264 immr->im_cpm.cp_pbodr, immr->im_cpm.cp_pbdat);
265 PRINTF("%s:%d: Port C:\n pcpar=0x%.4x pcdir=0x%.4x"
266 " pcdat=0x%.4x\n pcso=0x%.4x pcint=0x%.4x\n ",
267 __FUNCTION__, __LINE__, immr->im_ioport.iop_pcpar,
268 immr->im_ioport.iop_pcdir, immr->im_ioport.iop_pcdat,
269 immr->im_ioport.iop_pcso, immr->im_ioport.iop_pcint);
270 PRINTF("%s:%d: Port D:\n pdpar=0x%.4x pddir=0x%.4x"
271 " pddat=0x%.4x\n", __FUNCTION__, __LINE__,
272 immr->im_ioport.iop_pdpar, immr->im_ioport.iop_pddir,
273 immr->im_ioport.iop_pddat);
274}
275
276/* vim: set ts=4 sw=4 tw=78: */