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