#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/delay.h>
#include <asm/addrspace.h>
#include <asm/bcache.h>
extern void brcm_timer_setup(struct irqaction *irq);
extern unsigned long getMemorySize(void);
-#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI)
-#include <linux/pci.h>
-#include <linux/delay.h>
#include <bcm_map_part.h>
-#include <bcmpci.h>
-static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE);
+#if defined(CONFIG_PCI)
+#include <linux/pci.h>
+#include <bcmpci.h>
#endif
/* This function should be in a board specific directory. For now,
*/
static void brcm_machine_restart(char *command)
{
- const unsigned long ulSoftReset = 0x00000001;
- unsigned long *pulPllCtrl = (unsigned long *) 0xfffe0008;
- *pulPllCtrl |= ulSoftReset;
+ PERF->pll_control |= SOFT_RESET;
}
static void brcm_machine_halt(void)
while (1);
}
-#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI)
+#if defined(CONFIG_PCI)
static void mpi_SetLocalPciConfigReg(uint32 reg, uint32 value)
{
/* write index then value */
- mpi->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;;
- mpi->pcicfgdata = value;
+ MPI->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;;
+ MPI->pcicfgdata = value;
}
static uint32 mpi_GetLocalPciConfigReg(uint32 reg)
{
/* write index then get value */
- mpi->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;;
- return mpi->pcicfgdata;
+ MPI->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;;
+ return MPI->pcicfgdata;
}
/*
}
if (bReset) {
- mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & ~PCCARD_CARD_RESET);
+ MPI->pcmcia_cntl1 = (MPI->pcmcia_cntl1 & ~PCCARD_CARD_RESET);
} else {
- mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 | PCCARD_CARD_RESET);
+ MPI->pcmcia_cntl1 = (MPI->pcmcia_cntl1 | PCCARD_CARD_RESET);
}
}
*/
static void mpi_ConfigCs(uint32 cs, uint32 base, uint32 size, uint32 flags)
{
- mpi->cs[cs].base = ((base & 0x1FFFFFFF) | size);
- mpi->cs[cs].config = flags;
+ MPI->cs[cs].base = ((base & 0x1FFFFFFF) | size);
+ MPI->cs[cs].config = flags;
}
/*
// ChipSelect 6 controls PCMCIA I/O accesses
mpi_ConfigCs(PCMCIA_IO_BASE, pcmciaIo, EBI_SIZE_64K, (EBI_WORD_WIDE|EBI_ENABLE));
- mpi->pcmcia_cntl2 = ((PCMCIA_ATTR_ACTIVE << RW_ACTIVE_CNT_BIT) |
+ MPI->pcmcia_cntl2 = ((PCMCIA_ATTR_ACTIVE << RW_ACTIVE_CNT_BIT) |
(PCMCIA_ATTR_INACTIVE << INACTIVE_CNT_BIT) |
(PCMCIA_ATTR_CE_SETUP << CE_SETUP_CNT_BIT) |
(PCMCIA_ATTR_CE_HOLD << CE_HOLD_CNT_BIT));
- mpi->pcmcia_cntl2 |= (PCMCIA_HALFWORD_EN | PCMCIA_BYTESWAP_DIS);
+ MPI->pcmcia_cntl2 |= (PCMCIA_HALFWORD_EN | PCMCIA_BYTESWAP_DIS);
}
/*
int cardtype;
cardtype = MPI_CARDTYPE_NONE;
- mpi->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE); // Turn on the output enables and drive
+ MPI->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE); // Turn on the output enables and drive
// the CVS pins to 0.
- data32 = mpi->pcmcia_cntl1;
+ data32 = MPI->pcmcia_cntl1;
switch (data32 & (CD2_IN|CD1_IN)) // Test CD1# and CD2#, see if card is plugged in.
{
case (CD2_IN|CD1_IN): // No Card is in the slot.
- printk("mpi: No Card is in the PCMCIA slot\n");
+ printk("MPI: No Card is in the PCMCIA slot\n");
break;
case CD2_IN: // Partial insertion, No CD2#.
- printk("mpi: Card in the PCMCIA slot partial insertion, no CD2 signal\n");
+ printk("MPI: Card in the PCMCIA slot partial insertion, no CD2 signal\n");
break;
case CD1_IN: // Partial insertion, No CD1#.
- printk("mpi: Card in the PCMCIA slot partial insertion, no CD1 signal\n");
+ printk("MPI: Card in the PCMCIA slot partial insertion, no CD1 signal\n");
break;
case 0x00000000:
- mpi->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS2_OEN|VS1_OEN);
+ MPI->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS2_OEN|VS1_OEN);
// Turn off the CVS output enables and
// float the CVS pins.
mdelay(1);
- data32 = mpi->pcmcia_cntl1;
+ data32 = MPI->pcmcia_cntl1;
// Read the Register.
switch (data32 & (VS2_IN|VS1_IN)) // See what is on the CVS pins.
{
case 0x00000000: // CVS1 and CVS2 are tied to ground, only 1 option.
- printk("mpi: Detected 3.3 & x.x 16-bit PCMCIA card\n");
+ printk("MPI: Detected 3.3 & x.x 16-bit PCMCIA card\n");
cardtype = MPI_CARDTYPE_PCMCIA;
break;
{
case (CD2_IN|CD1_IN): // CCD1 and CCD2 are tied to 1 of the CVS pins.
// This is not a valid combination.
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
break;
case CD2_IN: // CCD2 is tied to either CVS1 or CVS2.
- mpi->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS2_OEN); // Drive CVS1 to a 0.
+ MPI->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS2_OEN); // Drive CVS1 to a 0.
mdelay(1);
- data32 = mpi->pcmcia_cntl1;
+ data32 = MPI->pcmcia_cntl1;
if (data32 & CD2_IN) { // CCD2 is tied to CVS2, not valid.
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
} else { // CCD2 is tied to CVS1.
- printk("mpi: Detected 3.3, x.x and y.y Cardbus card\n");
+ printk("MPI: Detected 3.3, x.x and y.y Cardbus card\n");
cardtype = MPI_CARDTYPE_CARDBUS;
}
break;
case CD1_IN: // CCD1 is tied to either CVS1 or CVS2.
// This is not a valid combination.
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
break;
case 0x00000000: // CCD1 and CCD2 are tied to ground.
- printk("mpi: Detected x.x vdc 16-bit PCMCIA card\n");
+ printk("MPI: Detected x.x vdc 16-bit PCMCIA card\n");
cardtype = MPI_CARDTYPE_PCMCIA;
break;
}
{
case (CD2_IN|CD1_IN): // CCD1 and CCD2 are tied to 1 of the CVS pins.
// This is not a valid combination.
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
break;
case CD2_IN: // CCD2 is tied to either CVS1 or CVS2.
- mpi->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS1_OEN);// Drive CVS2 to a 0.
+ MPI->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS1_OEN);// Drive CVS2 to a 0.
mdelay(1);
- data32 = mpi->pcmcia_cntl1;
+ data32 = MPI->pcmcia_cntl1;
if (data32 & CD2_IN) { // CCD2 is tied to CVS1, not valid.
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
} else {// CCD2 is tied to CVS2.
- printk("mpi: Detected 3.3 and x.x Cardbus card\n");
+ printk("MPI: Detected 3.3 and x.x Cardbus card\n");
cardtype = MPI_CARDTYPE_CARDBUS;
}
break;
case CD1_IN: // CCD1 is tied to either CVS1 or CVS2.
// This is not a valid combination.
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
break;
case 0x00000000: // CCD1 and CCD2 are tied to ground.
cardtype = MPI_CARDTYPE_PCMCIA;
- printk("mpi: Detected 3.3 vdc 16-bit PCMCIA card\n");
+ printk("MPI: Detected 3.3 vdc 16-bit PCMCIA card\n");
break;
}
break;
{
case (CD2_IN|CD1_IN): // CCD1 and CCD2 are tied to 1 of the CVS pins.
// This is not a valid combination.
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
break;
case CD2_IN: // CCD2 is tied to either CVS1 or CVS2.
// CCD1 is tied to ground.
- mpi->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS1_OEN);// Drive CVS2 to a 0.
+ MPI->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS1_OEN);// Drive CVS2 to a 0.
mdelay(1);
- data32 = mpi->pcmcia_cntl1;
+ data32 = MPI->pcmcia_cntl1;
if (data32 & CD2_IN) { // CCD2 is tied to CVS1.
- printk("mpi: Detected y.y vdc Cardbus card\n");
+ printk("MPI: Detected y.y vdc Cardbus card\n");
} else { // CCD2 is tied to CVS2.
- printk("mpi: Detected x.x vdc Cardbus card\n");
+ printk("MPI: Detected x.x vdc Cardbus card\n");
}
cardtype = MPI_CARDTYPE_CARDBUS;
break;
case CD1_IN: // CCD1 is tied to either CVS1 or CVS2.
// CCD2 is tied to ground.
- mpi->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS1_OEN);// Drive CVS2 to a 0.
+ MPI->pcmcia_cntl1 = (CARDBUS_ENABLE|PCMCIA_GPIO_ENABLE|VS1_OEN);// Drive CVS2 to a 0.
mdelay(1);
- data32 = mpi->pcmcia_cntl1;
+ data32 = MPI->pcmcia_cntl1;
if (data32 & CD1_IN) {// CCD1 is tied to CVS1.
- printk("mpi: Detected 3.3 vdc Cardbus card\n");
+ printk("MPI: Detected 3.3 vdc Cardbus card\n");
} else { // CCD1 is tied to CVS2.
- printk("mpi: Detected x.x and y.y Cardbus card\n");
+ printk("MPI: Detected x.x and y.y Cardbus card\n");
}
cardtype = MPI_CARDTYPE_CARDBUS;
break;
case 0x00000000: // CCD1 and CCD2 are tied to ground.
cardtype = MPI_CARDTYPE_PCMCIA;
- printk("mpi: Detected 5 vdc 16-bit PCMCIA card\n");
+ printk("MPI: Detected 5 vdc 16-bit PCMCIA card\n");
break;
}
break;
default:
- printk("mpi: Unknown card plugged into slot\n");
+ printk("MPI: Unknown card plugged into slot\n");
break;
}
cardtype = cardtype_vcc_detect();
switch(cardtype) {
case MPI_CARDTYPE_PCMCIA:
- mpi->pcmcia_cntl1 &= ~(CARDBUS_ENABLE|PCMCIA_ENABLE|PCMCIA_GPIO_ENABLE); // disable enable bits
- mpi->pcmcia_cntl1 |= (PCMCIA_ENABLE | PCMCIA_GPIO_ENABLE);
+ MPI->pcmcia_cntl1 &= ~(CARDBUS_ENABLE|PCMCIA_ENABLE|PCMCIA_GPIO_ENABLE); // disable enable bits
+ MPI->pcmcia_cntl1 |= (PCMCIA_ENABLE | PCMCIA_GPIO_ENABLE);
mpi_InitPcmciaSpace();
mpi_ResetPcCard(cardtype, FALSE);
// Hold card in reset for 10ms
// 8 => CardBus Enable
// 1 => PCI Slot Number
// C => Float VS1 & VS2
- mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & 0xFFFF0000) |
+ MPI->pcmcia_cntl1 = (MPI->pcmcia_cntl1 & 0xFFFF0000) |
CARDBUS_ENABLE |
(CARDBUS_SLOT << 8)|
VS2_OEN |
- VS1_OEN;
+ VS1_OEN | PCMCIA_GPIO_ENABLE;
/* access to this memory window will be to/from CardBus */
- mpi->l2pmremap1 |= CARDBUS_MEM;
+ MPI->l2pmremap1 |= CARDBUS_MEM;
// Need to reset the Cardbus Card. There's no CardManager to do this,
// and we need to be ready for PCI configuration.
unsigned int chipid;
unsigned int chiprev;
unsigned int sdramsize;
+ unsigned int modesel;
chipid = (PERF->RevID & 0xFFFF0000) >> 16;
chiprev = (PERF->RevID & 0xFF);
sdramsize = getMemorySize();
+
+#if defined(CONFIG_BCM96348)
/*
* Init the pci interface
*/
data = GPIO->GPIOMode; // GPIO mode register
data |= GROUP2_PCI | GROUP1_MII_PCCARD; // PCI internal arbiter + Cardbus
GPIO->GPIOMode = data; // PCI internal arbiter
-
+#endif
/*
- * In the BCM6348 CardBus support is defaulted to Slot 0
+ * CardBus support is defaulted to Slot 0
* because there is no external IDSEL for CardBus. To disable
* the CardBus and allow a standard PCI card in Slot 0
* set the cbus_idsel field to 0x1f.
*/
/*
- uData = mpi->pcmcia_cntl1;
+ uData = MPI->pcmcia_cntl1;
uData |= CARDBUS_IDSEL;
- mpi->pcmcia_cntl1 = uData;
+ MPI->pcmcia_cntl1 = uData;
*/
+
+ // UBUS to PCI address range
+ // Memory Window 1. Used for devices in slot 0. Potentially can be CardBus
+ MPI->l2pmrange1 = ~(BCM_PCI_MEM_SIZE_16MB-1);
+ // UBUS to PCI Memory base address. This is akin to the ChipSelect base
+ // register.
+ MPI->l2pmbase1 = BCM_CB_MEM_BASE & BCM_PCI_ADDR_MASK;
+ // UBUS to PCI Remap Address. Replaces the masked address bits in the
+ // range register with this setting.
+ // Also, enable direct I/O and direct Memory accesses
+ MPI->l2pmremap1 = (BCM_PCI_MEM_BASE | MEM_WINDOW_EN);
+
+ // Memory Window 2. Used for devices in other slots
+ MPI->l2pmrange2 = ~(BCM_PCI_MEM_SIZE_16MB-1);
+ // UBUS to PCI Memory base address.
+ MPI->l2pmbase2 = BCM_PCI_MEM_BASE & BCM_PCI_ADDR_MASK;
+ // UBUS to PCI Remap Address
+ MPI->l2pmremap2 = (BCM_PCI_MEM_BASE | MEM_WINDOW_EN);
+
// Setup PCI I/O Window range. Give 64K to PCI I/O
- mpi->l2piorange = ~(BCM_PCI_IO_SIZE_64KB-1);
+ MPI->l2piorange = ~(BCM_PCI_IO_SIZE_64KB-1);
// UBUS to PCI I/O base address
- mpi->l2piobase = BCM_PCI_IO_BASE & BCM_PCI_ADDR_MASK;
+ MPI->l2piobase = BCM_PCI_IO_BASE & BCM_PCI_ADDR_MASK;
// UBUS to PCI I/O Window remap
- mpi->l2pioremap = (BCM_PCI_IO_BASE | MEM_WINDOW_EN);
+ MPI->l2pioremap = (BCM_PCI_IO_BASE | MEM_WINDOW_EN);
// enable PCI related GPIO pins and data swap between system and PCI bus
- mpi->locbuscntrl = (EN_PCI_GPIO | DIR_U2P_NOSWAP);
+ MPI->locbuscntrl = (EN_PCI_GPIO | DIR_U2P_NOSWAP);
- /* Enable 6348 BusMaster and Memory access mode */
+ /* Enable BusMaster and Memory access mode */
data = mpi_GetLocalPciConfigReg(PCI_COMMAND);
data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
mpi_SetLocalPciConfigReg(PCI_COMMAND, data);
/* These memory regions are used when PCI device is a bus master */
/* Accesses to the SDRAM from PCI bus will be "byte swapped" for this region */
mpi_SetLocalPciConfigReg(PCI_BASE_ADDRESS_3, BCM_HOST_MEM_SPACE1);
- mpi->sp0remap = 0x0;
+
+#if defined(CONFIG_BCM96348)
+ MPI->sp0remap = 0x0;
+#else
+ MPI->sp0remap = MEM_WINDOW_EN;
+#endif
/* Accesses to the SDRAM from PCI bus will be "byte swapped" for this region */
mpi_SetLocalPciConfigReg(PCI_BASE_ADDRESS_4, BCM_HOST_MEM_SPACE2);
- mpi->sp1remap = 0x0;
- mpi->pcimodesel |= 0x40;
+
+#if defined(CONFIG_BCM96348)
+ MPI->sp1remap = 0x0;
+#else
+ MPI->sp1remap = MEM_WINDOW_EN;
+#endif
+
+ modesel = MPI->pcimodesel;
+ modesel &= ~PCI_INT_BUS_RD_PREFETCH;
+#if defined(CONFIG_BCM96348)
+ modesel |= 0x80;
+#else
+ modesel |= 0x100;
+#endif
+ MPI->pcimodesel = modesel;
- if ((chipid == 0x6348) && ((chiprev & 0xF0) != 0xa0)) {
- mpi->sp0range = ~(sdramsize-1);
- mpi->sp1range = ~(sdramsize-1);
+ if (!((chipid == 0x6348) && ((chiprev & 0xF0) == 0xa0))) {
+ MPI->sp0range = ~(sdramsize-1);
+ MPI->sp1range = ~(sdramsize-1);
}
/*
- * Change 6348 PCI Cfg Reg. offset 0x40 to PCI memory read retry count infinity
+ * Change PCI Cfg Reg. offset 0x40 to PCI memory read retry count infinity
* by set 0 in bit 8~15. This resolve read Bcm4306 srom return 0xffff in
* first read.
*/
mpi_SetLocalPciConfigReg(BRCM_PCI_CONFIG_TIMER, data);
/* enable pci interrupt */
- mpi->locintstat |= (EXT_PCI_INT << 16);
+ MPI->locintstat |= (EXT_PCI_INT << 16);
+#if !defined(CONFIG_BCM_VDSL)
mpi_DetectPcCard();
+#endif
ioport_resource.start = BCM_PCI_IO_BASE;
ioport_resource.end = BCM_PCI_IO_BASE + BCM_PCI_IO_SIZE_64KB;
+ return 0;
+}
+#endif
+
+static int __init bcm63xx_hw_init(void)
+{
+#if defined(CONFIG_BCM96338)
+ /*
+ * atm and sdioh share the same reset bit
+ * issue reset needed such that sdioh can work properly after power cycle
+ */
+ PERF->BlockSoftReset &= ~BSR_SAR;
+ mdelay(10);
+ PERF->BlockSoftReset |= BSR_SAR;
+ mdelay(10);
+#endif
+
+#if defined(CONFIG_PCI)
+ /* MPI initialization */
+ mpi_init();
+#endif
+
#if defined(CONFIG_USB)
+#if defined(CONFIG_BCM96348)
PERF->blkEnables |= USBH_CLK_EN;
mdelay(100);
- *USBH_NON_OHCI = NON_OHCI_BYTE_SWAP;
+ *USBH = USBH_BYTE_SWAP;
+#else
+ USBH->SwapControl = EHCI_ENDIAN_SWAP | OHCI_ENDIAN_SWAP;
+ USBH->TestPortControl = 0x001c0020;
+#endif
#endif
return 0;
}
-#endif
+
+arch_initcall(bcm63xx_hw_init);
static int __init brcm63xx_setup(void)
{
panic_timeout = 1;
-#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI)
- /* mpi initialization */
- mpi_init();
-#endif
return 0;
}