www.usr.com/support/gpl/USR9113_release1.0.tar.gz
[bcm963xx.git] / kernel / linux / arch / mips / brcm-boards / bcm963xx / setup.c
index 5eca144..ba10866 100755 (executable)
@@ -31,6 +31,7 @@
 #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,
@@ -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;
 }