X-Git-Url: http://git.rot13.org/?p=bcm963xx.git;a=blobdiff_plain;f=kernel%2Flinux%2Farch%2Fmips%2Fbrcm-boards%2Fbcm963xx%2Fsetup.c;h=ba10866ee8f93a250d42fb9329f86bfa5bb480a5;hp=5eca1442647616ca675a557414027d18d7579d32;hb=6adeba4d92a546ebbadde2562283ee6b984b22c1;hpb=dacd86d83a9fb430cca42cb78a67f9d46e289f5c diff --git a/kernel/linux/arch/mips/brcm-boards/bcm963xx/setup.c b/kernel/linux/arch/mips/brcm-boards/bcm963xx/setup.c index 5eca1442..ba10866e 100755 --- a/kernel/linux/arch/mips/brcm-boards/bcm963xx/setup.c +++ b/kernel/linux/arch/mips/brcm-boards/bcm963xx/setup.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -42,13 +43,11 @@ extern void brcm_timer_setup(struct irqaction *irq); extern unsigned long getMemorySize(void); -#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) -#include -#include #include -#include -static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE); +#if defined(CONFIG_PCI) +#include +#include #endif /* This function should be in a board specific directory. For now, @@ -57,9 +56,7 @@ static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE); */ 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) @@ -68,20 +65,20 @@ 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; } /* @@ -98,9 +95,9 @@ static void mpi_ResetPcCard(int cardtype, BOOL bReset) } 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); } } @@ -109,8 +106,8 @@ static void mpi_ResetPcCard(int cardtype, BOOL bReset) */ 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; } /* @@ -125,12 +122,12 @@ static void mpi_InitPcmciaSpace(void) // 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); } /* @@ -168,34 +165,34 @@ static int cardtype_vcc_detect(void) 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; @@ -205,28 +202,28 @@ static int cardtype_vcc_detect(void) { 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; } @@ -238,29 +235,29 @@ static int cardtype_vcc_detect(void) { 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; @@ -272,18 +269,18 @@ static int cardtype_vcc_detect(void) { 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; @@ -291,26 +288,26 @@ static int cardtype_vcc_detect(void) 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; } @@ -332,8 +329,8 @@ static int mpi_DetectPcCard(void) 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 @@ -346,13 +343,13 @@ static int mpi_DetectPcCard(void) // 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. @@ -375,39 +372,61 @@ static int mpi_init(void) 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); @@ -416,19 +435,37 @@ static int mpi_init(void) /* 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. */ @@ -438,22 +475,52 @@ static int mpi_init(void) 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) { @@ -467,10 +534,6 @@ static int __init brcm63xx_setup(void) panic_timeout = 1; -#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) - /* mpi initialization */ - mpi_init(); -#endif return 0; }