58472783f4fcafddc02d4f2e0e71e8ed8d253a34
[openwrt/openwrt.git] / target / linux / brcm63xx / files / arch / mips / bcm963xx / setup.c
1 /*
2 <:copyright-gpl
3 Copyright 2002 Broadcom Corp. All Rights Reserved.
4
5 This program is free software; you can distribute it and/or modify it
6 under the terms of the GNU General Public License (Version 2) as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 :>
18 */
19 /*
20 * Generic setup routines for Broadcom 963xx MIPS boards
21 */
22
23 #include <linux/autoconf.h>
24 #include <linux/init.h>
25 #include <linux/interrupt.h>
26 #include <linux/kernel.h>
27 #include <linux/kdev_t.h>
28 #include <linux/types.h>
29 #include <linux/console.h>
30 #include <linux/sched.h>
31 #include <linux/mm.h>
32 #include <linux/slab.h>
33 #include <linux/module.h>
34 #include <linux/pm.h>
35 #include <linux/bootmem.h>
36
37 #include <asm/addrspace.h>
38 #include <asm/bcache.h>
39 #include <asm/irq.h>
40 #include <asm/time.h>
41 #include <asm/reboot.h>
42 #include <asm/gdb-stub.h>
43 #include <asm/bootinfo.h>
44 #include <asm/cpu.h>
45 #include <asm/mach-bcm963xx/bootloaders.h>
46
47 extern void brcm_time_init(void);
48 extern int boot_loader_type;
49
50 #include <linux/pci.h>
51 #include <linux/delay.h>
52 #include <bcm_map_part.h>
53 #include <6348_map_part.h>
54 #include <bcmpci.h>
55
56 static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE);
57
58 /* This function should be in a board specific directory. For now,
59 * assume that all boards that include this file use a Broadcom chip
60 * with a soft reset bit in the PLL control register.
61 */
62 static void brcm_machine_restart(char *command)
63 {
64 const unsigned long ulSoftReset = 0x00000001;
65 unsigned long *pulPllCtrl = (unsigned long *) 0xfffe0008;
66 *pulPllCtrl |= ulSoftReset;
67 }
68
69 static void brcm_machine_halt(void)
70 {
71 printk("System halted\n");
72 while (1);
73 }
74
75 static void mpi_SetLocalPciConfigReg(uint32 reg, uint32 value)
76 {
77 /* write index then value */
78 mpi->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;;
79 mpi->pcicfgdata = value;
80 }
81
82 static uint32 mpi_GetLocalPciConfigReg(uint32 reg)
83 {
84 /* write index then get value */
85 mpi->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;;
86 return mpi->pcicfgdata;
87 }
88
89 /*
90 * mpi_ResetPcCard: Set/Reset the PcCard
91 */
92 static void mpi_ResetPcCard(int cardtype, BOOL bReset)
93 {
94 if (cardtype == MPI_CARDTYPE_NONE) {
95 return;
96 }
97
98 if (cardtype == MPI_CARDTYPE_CARDBUS) {
99 bReset = ! bReset;
100 }
101
102 if (bReset) {
103 mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & ~PCCARD_CARD_RESET);
104 } else {
105 mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 | PCCARD_CARD_RESET);
106 }
107 }
108
109 /*
110 * mpi_ConfigCs: Configure an MPI/EBI chip select
111 */
112 static void mpi_ConfigCs(uint32 cs, uint32 base, uint32 size, uint32 flags)
113 {
114 mpi->cs[cs].base = ((base & 0x1FFFFFFF) | size);
115 mpi->cs[cs].config = flags;
116 }
117
118 /*
119 * mpi_InitPcmciaSpace
120 */
121 static void mpi_InitPcmciaSpace(void)
122 {
123 // ChipSelect 4 controls PCMCIA Memory accesses
124 mpi_ConfigCs(PCMCIA_COMMON_BASE, pcmciaMem, EBI_SIZE_1M, (EBI_WORD_WIDE|EBI_ENABLE));
125 // ChipSelect 5 controls PCMCIA Attribute accesses
126 mpi_ConfigCs(PCMCIA_ATTRIBUTE_BASE, pcmciaAttr, EBI_SIZE_1M, (EBI_WORD_WIDE|EBI_ENABLE));
127 // ChipSelect 6 controls PCMCIA I/O accesses
128 mpi_ConfigCs(PCMCIA_IO_BASE, pcmciaIo, EBI_SIZE_64K, (EBI_WORD_WIDE|EBI_ENABLE));
129
130 mpi->pcmcia_cntl2 = ((PCMCIA_ATTR_ACTIVE << RW_ACTIVE_CNT_BIT) |
131 (PCMCIA_ATTR_INACTIVE << INACTIVE_CNT_BIT) |
132 (PCMCIA_ATTR_CE_SETUP << CE_SETUP_CNT_BIT) |
133 (PCMCIA_ATTR_CE_HOLD << CE_HOLD_CNT_BIT));
134
135 mpi->pcmcia_cntl2 |= (PCMCIA_HALFWORD_EN | PCMCIA_BYTESWAP_DIS);
136 }
137
138 /*
139 * cardtype_vcc_detect: PC Card's card detect and voltage sense connection
140 *
141 * CD1#/ CD2#/ VS1#/ VS2#/ Card Initial Vcc
142 * CCD1# CCD2# CVS1 CVS2 Type
143 *
144 * GND GND open open 16-bit 5 vdc
145 *
146 * GND GND GND open 16-bit 3.3 vdc
147 *
148 * GND GND open GND 16-bit x.x vdc
149 *
150 * GND GND GND GND 16-bit 3.3 & x.x vdc
151 *
152 *====================================================================
153 *
154 * CVS1 GND CCD1# open CardBus 3.3 vdc
155 *
156 * GND CVS2 open CCD2# CardBus x.x vdc
157 *
158 * GND CVS1 CCD2# open CardBus y.y vdc
159 *
160 * GND CVS2 GND CCD2# CardBus 3.3 & x.x vdc
161 *
162 * CVS2 GND open CCD1# CardBus x.x & y.y vdc
163 *
164 * GND CVS1 CCD2# open CardBus 3.3, x.x & y.y vdc
165 *
166 */
167 static int cardtype_vcc_detect(void)
168 {
169 uint32 data32;
170 int cardtype;
171
172 cardtype = MPI_CARDTYPE_NONE;
173 mpi->pcmcia_cntl1 = 0x0000A000; // Turn on the output enables and drive
174 // the CVS pins to 0.
175 data32 = mpi->pcmcia_cntl1;
176 switch (data32 & 0x00000003) // Test CD1# and CD2#, see if card is plugged in.
177 {
178 case 0x00000003: // No Card is in the slot.
179 printk("mpi: No Card is in the PCMCIA slot\n");
180 break;
181
182 case 0x00000002: // Partial insertion, No CD2#.
183 printk("mpi: Card in the PCMCIA slot partial insertion, no CD2 signal\n");
184 break;
185
186 case 0x00000001: // Partial insertion, No CD1#.
187 printk("mpi: Card in the PCMCIA slot partial insertion, no CD1 signal\n");
188 break;
189
190 case 0x00000000:
191 mpi->pcmcia_cntl1 = 0x0000A0C0; // Turn off the CVS output enables and
192 // float the CVS pins.
193 mdelay(1);
194 data32 = mpi->pcmcia_cntl1;
195 // Read the Register.
196 switch (data32 & 0x0000000C) // See what is on the CVS pins.
197 {
198 case 0x00000000: // CVS1 and CVS2 are tied to ground, only 1 option.
199 printk("mpi: Detected 3.3 & x.x 16-bit PCMCIA card\n");
200 cardtype = MPI_CARDTYPE_PCMCIA;
201 break;
202
203 case 0x00000004: // CVS1 is open or tied to CCD1/CCD2 and CVS2 is tied to ground.
204 // 2 valid voltage options.
205 switch (data32 & 0x00000003) // Test the values of CCD1 and CCD2.
206 {
207 case 0x00000003: // CCD1 and CCD2 are tied to 1 of the CVS pins.
208 // This is not a valid combination.
209 printk("mpi: Unknown card plugged into slot\n");
210 break;
211
212 case 0x00000002: // CCD2 is tied to either CVS1 or CVS2.
213 mpi->pcmcia_cntl1 = 0x0000A080; // Drive CVS1 to a 0.
214 mdelay(1);
215 data32 = mpi->pcmcia_cntl1;
216 if (data32 & 0x00000002) { // CCD2 is tied to CVS2, not valid.
217 printk("mpi: Unknown card plugged into slot\n");
218 } else { // CCD2 is tied to CVS1.
219 printk("mpi: Detected 3.3, x.x and y.y Cardbus card\n");
220 cardtype = MPI_CARDTYPE_CARDBUS;
221 }
222 break;
223
224 case 0x00000001: // CCD1 is tied to either CVS1 or CVS2.
225 // This is not a valid combination.
226 printk("mpi: Unknown card plugged into slot\n");
227 break;
228
229 case 0x00000000: // CCD1 and CCD2 are tied to ground.
230 printk("mpi: Detected x.x vdc 16-bit PCMCIA card\n");
231 cardtype = MPI_CARDTYPE_PCMCIA;
232 break;
233 }
234 break;
235
236 case 0x00000008: // CVS2 is open or tied to CCD1/CCD2 and CVS1 is tied to ground.
237 // 2 valid voltage options.
238 switch (data32 & 0x00000003) // Test the values of CCD1 and CCD2.
239 {
240 case 0x00000003: // CCD1 and CCD2 are tied to 1 of the CVS pins.
241 // This is not a valid combination.
242 printk("mpi: Unknown card plugged into slot\n");
243 break;
244
245 case 0x00000002: // CCD2 is tied to either CVS1 or CVS2.
246 mpi->pcmcia_cntl1 = 0x0000A040; // Drive CVS2 to a 0.
247 mdelay(1);
248 data32 = mpi->pcmcia_cntl1;
249 if (data32 & 0x00000002) { // CCD2 is tied to CVS1, not valid.
250 printk("mpi: Unknown card plugged into slot\n");
251 } else {// CCD2 is tied to CVS2.
252 printk("mpi: Detected 3.3 and x.x Cardbus card\n");
253 cardtype = MPI_CARDTYPE_CARDBUS;
254 }
255 break;
256
257 case 0x00000001: // CCD1 is tied to either CVS1 or CVS2.
258 // This is not a valid combination.
259 printk("mpi: Unknown card plugged into slot\n");
260 break;
261
262 case 0x00000000: // CCD1 and CCD2 are tied to ground.
263 cardtype = MPI_CARDTYPE_PCMCIA;
264 printk("mpi: Detected 3.3 vdc 16-bit PCMCIA card\n");
265 break;
266 }
267 break;
268
269 case 0x0000000C: // CVS1 and CVS2 are open or tied to CCD1/CCD2.
270 // 5 valid voltage options.
271
272 switch (data32 & 0x00000003) // Test the values of CCD1 and CCD2.
273 {
274 case 0x00000003: // CCD1 and CCD2 are tied to 1 of the CVS pins.
275 // This is not a valid combination.
276 printk("mpi: Unknown card plugged into slot\n");
277 break;
278
279 case 0x00000002: // CCD2 is tied to either CVS1 or CVS2.
280 // CCD1 is tied to ground.
281 mpi->pcmcia_cntl1 = 0x0000A040; // Drive CVS2 to a 0.
282 mdelay(1);
283 data32 = mpi->pcmcia_cntl1;
284 if (data32 & 0x00000002) { // CCD2 is tied to CVS1.
285 printk("mpi: Detected y.y vdc Cardbus card\n");
286 } else { // CCD2 is tied to CVS2.
287 printk("mpi: Detected x.x vdc Cardbus card\n");
288 }
289 cardtype = MPI_CARDTYPE_CARDBUS;
290 break;
291
292 case 0x00000001: // CCD1 is tied to either CVS1 or CVS2.
293 // CCD2 is tied to ground.
294
295 mpi->pcmcia_cntl1 = 0x0000A040; // Drive CVS2 to a 0.
296 mdelay(1);
297 data32 = mpi->pcmcia_cntl1;
298 if (data32 & 0x00000001) {// CCD1 is tied to CVS1.
299 printk("mpi: Detected 3.3 vdc Cardbus card\n");
300 } else { // CCD1 is tied to CVS2.
301 printk("mpi: Detected x.x and y.y Cardbus card\n");
302 }
303 cardtype = MPI_CARDTYPE_CARDBUS;
304 break;
305
306 case 0x00000000: // CCD1 and CCD2 are tied to ground.
307 cardtype = MPI_CARDTYPE_PCMCIA;
308 printk("mpi: Detected 5 vdc 16-bit PCMCIA card\n");
309 break;
310 }
311 break;
312
313 default:
314 printk("mpi: Unknown card plugged into slot\n");
315 break;
316
317 }
318 }
319 return cardtype;
320 }
321
322 /*
323 * mpi_DetectPcCard: Detect the plugged in PC-Card
324 * Return: < 0 => Unknown card detected
325 * 0 => No card detected
326 * 1 => 16-bit card detected
327 * 2 => 32-bit CardBus card detected
328 */
329 static int mpi_DetectPcCard(void)
330 {
331 int cardtype;
332
333 cardtype = cardtype_vcc_detect();
334 switch(cardtype) {
335 case MPI_CARDTYPE_PCMCIA:
336 mpi->pcmcia_cntl1 &= ~0x0000e000; // disable enable bits
337 //mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & ~PCCARD_CARD_RESET);
338 mpi->pcmcia_cntl1 |= (PCMCIA_ENABLE | PCMCIA_GPIO_ENABLE);
339 mpi_InitPcmciaSpace();
340 mpi_ResetPcCard(cardtype, FALSE);
341 // Hold card in reset for 10ms
342 mdelay(10);
343 mpi_ResetPcCard(cardtype, TRUE);
344 // Let card come out of reset
345 mdelay(100);
346 break;
347 case MPI_CARDTYPE_CARDBUS:
348 // 8 => CardBus Enable
349 // 1 => PCI Slot Number
350 // C => Float VS1 & VS2
351 mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & 0xFFFF0000) |
352 CARDBUS_ENABLE |
353 (CARDBUS_SLOT << 8)|
354 VS2_OEN |
355 VS1_OEN;
356 /* access to this memory window will be to/from CardBus */
357 mpi->l2pmremap1 |= CARDBUS_MEM;
358
359 // Need to reset the Cardbus Card. There's no CardManager to do this,
360 // and we need to be ready for PCI configuration.
361 mpi_ResetPcCard(cardtype, FALSE);
362 // Hold card in reset for 10ms
363 mdelay(10);
364 mpi_ResetPcCard(cardtype, TRUE);
365 // Let card come out of reset
366 mdelay(100);
367 break;
368 default:
369 break;
370 }
371 return cardtype;
372 }
373
374 static int mpi_init(void)
375 {
376 unsigned long data;
377 unsigned int chipid, chiprev, sdramsize;
378
379 printk("Broadcom BCM963xx MPI\n");
380 chipid = (PERF->RevID & 0xFFFF0000) >> 16;
381 chiprev = (PERF->RevID & 0xFF);
382
383 if (boot_loader_type == BOOT_LOADER_CFE)
384 sdramsize = boot_mem_map.map[0].size;
385 else
386 sdramsize = 0x01000000;
387 /*
388 * Init the pci interface
389 */
390 data = GPIO->GPIOMode; // GPIO mode register
391 data |= GROUP2_PCI | GROUP1_MII_PCCARD; // PCI internal arbiter + Cardbus
392 GPIO->GPIOMode = data; // PCI internal arbiter
393
394 /*
395 * In the BCM6348 CardBus support is defaulted to Slot 0
396 * because there is no external IDSEL for CardBus. To disable
397 * the CardBus and allow a standard PCI card in Slot 0
398 * set the cbus_idsel field to 0x1f.
399 */
400 /*
401 uData = mpi->pcmcia_cntl1;
402 uData |= CARDBUS_IDSEL;
403 mpi->pcmcia_cntl1 = uData;
404 */
405 // Setup PCI I/O Window range. Give 64K to PCI I/O
406 mpi->l2piorange = ~(BCM_PCI_IO_SIZE_64KB-1);
407 // UBUS to PCI I/O base address
408 mpi->l2piobase = BCM_PCI_IO_BASE & BCM_PCI_ADDR_MASK;
409 // UBUS to PCI I/O Window remap
410 mpi->l2pioremap = (BCM_PCI_IO_BASE | MEM_WINDOW_EN);
411
412 // enable PCI related GPIO pins and data swap between system and PCI bus
413 mpi->locbuscntrl = (EN_PCI_GPIO | DIR_U2P_NOSWAP);
414
415 /* Enable 6348 BusMaster and Memory access mode */
416 data = mpi_GetLocalPciConfigReg(PCI_COMMAND);
417 data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
418 mpi_SetLocalPciConfigReg(PCI_COMMAND, data);
419
420 /* Configure two 16 MByte PCI to System memory regions. */
421 /* These memory regions are used when PCI device is a bus master */
422 /* Accesses to the SDRAM from PCI bus will be "byte swapped" for this region */
423 mpi_SetLocalPciConfigReg(PCI_BASE_ADDRESS_3, BCM_HOST_MEM_SPACE1);
424 mpi->sp0remap = 0x0;
425
426 /* Accesses to the SDRAM from PCI bus will not be "byte swapped" for this region */
427 mpi_SetLocalPciConfigReg(PCI_BASE_ADDRESS_4, BCM_HOST_MEM_SPACE2);
428 mpi->sp1remap = 0x0;
429 mpi->pcimodesel |= (PCI_BAR2_NOSWAP | 0x40);
430
431 if ((chipid == 0x6348) && (chiprev == 0xb0)) {
432 mpi->sp0range = ~(sdramsize-1);
433 mpi->sp1range = ~(sdramsize-1);
434 }
435 /*
436 * Change 6348 PCI Cfg Reg. offset 0x40 to PCI memory read retry count infinity
437 * by set 0 in bit 8~15. This resolve read Bcm4306 srom return 0xffff in
438 * first read.
439 */
440 data = mpi_GetLocalPciConfigReg(BRCM_PCI_CONFIG_TIMER);
441 data &= ~BRCM_PCI_CONFIG_TIMER_RETRY_MASK;
442 data |= 0x00000080;
443 mpi_SetLocalPciConfigReg(BRCM_PCI_CONFIG_TIMER, data);
444
445 /* enable pci interrupt */
446 mpi->locintstat |= (EXT_PCI_INT << 16);
447
448 mpi_DetectPcCard();
449
450 ioport_resource.start = BCM_PCI_IO_BASE;
451 ioport_resource.end = BCM_PCI_IO_BASE + BCM_PCI_IO_SIZE_64KB;
452
453 #if defined(CONFIG_USB)
454 PERF->blkEnables |= USBH_CLK_EN;
455 mdelay(100);
456 *USBH_NON_OHCI = NON_OHCI_BYTE_SWAP;
457 #endif
458
459 return 0;
460 }
461
462 void __init plat_mem_setup(void)
463 {
464 _machine_restart = brcm_machine_restart;
465 _machine_halt = brcm_machine_halt;
466 pm_power_off = brcm_machine_halt;
467
468 //board_time_init = brcm_time_init;
469
470 /* mpi initialization */
471 mpi_init();
472 }