Merge: Add support for AMCC 440SPe CPU based eval board (Yucca).
[platform/kernel/u-boot.git] / cpu / ppc4xx / 405gp_pci.c
index 4b5472b..0ccb3d8 100644 (file)
 #include <asm/processor.h>
 #include <pci.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #if defined(CONFIG_405GP) || defined(CONFIG_405EP)
 
 #ifdef CONFIG_PCI
 
+#if defined(CONFIG_PMC405)
+ushort pmc405_pci_subsys_deviceid(void);
+#endif
+
 /*#define DEBUG*/
 
 /*-----------------------------------------------------------------------------+
  *-----------------------------------------------------------------------------*/
 void pci_405gp_init(struct pci_controller *hose)
 {
-       DECLARE_GLOBAL_DATA_PTR;
-
        int i, reg_num = 0;
        bd_t *bd = gd->bd;
 
        unsigned short temp_short;
        unsigned long ptmpcila[2] = {CFG_PCI_PTM1PCI, CFG_PCI_PTM2PCI};
-#if defined(CONFIG_CPCI405)
-       unsigned long ptmla[2]    = {bd->bi_memstart, bd->bi_flashstart};
-       unsigned long ptmms[2]    = {~(bd->bi_memsize - 1) | 1, ~(bd->bi_flashsize - 1) | 1};
-#else
+#if defined(CONFIG_CPCI405) || defined(CONFIG_PMC405)
+       char *ptmla_str, *ptmms_str;
+#endif
        unsigned long ptmla[2]    = {CFG_PCI_PTM1LA, CFG_PCI_PTM2LA};
        unsigned long ptmms[2]    = {CFG_PCI_PTM1MS, CFG_PCI_PTM2MS};
-#endif
 #if defined(CONFIG_PIP405) || defined (CONFIG_MIP405)
        unsigned long pmmla[3]    = {0x80000000, 0xA0000000, 0};
        unsigned long pmmma[3]    = {0xE0000001, 0xE0000001, 0};
@@ -113,6 +115,27 @@ void pci_405gp_init(struct pci_controller *hose)
        unsigned long pmmpcila[3] = {0x80000000, 0,0};
        unsigned long pmmpciha[3] = {0x00000000, 0,0};
 #endif
+#ifdef CONFIG_PCI_PNP
+#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
+       char *s;
+#endif
+#endif
+
+#if defined(CONFIG_CPCI405) || defined(CONFIG_PMC405)
+       ptmla_str = getenv("ptm1la");
+       ptmms_str = getenv("ptm1ms");
+       if(NULL != ptmla_str && NULL != ptmms_str ) {
+               ptmla[0] = simple_strtoul (ptmla_str, NULL, 16);
+               ptmms[0] = simple_strtoul (ptmms_str, NULL, 16);
+       }
+
+       ptmla_str = getenv("ptm2la");
+       ptmms_str = getenv("ptm2ms");
+       if(NULL != ptmla_str && NULL != ptmms_str ) {
+               ptmla[1] = simple_strtoul (ptmla_str, NULL, 16);
+               ptmms[1] = simple_strtoul (ptmms_str, NULL, 16);
+       }
+#endif
 
        /*
         * Register the hose
@@ -206,11 +229,14 @@ void pci_405gp_init(struct pci_controller *hose)
         *--------------------------------------------------------------------------*/
        out32r(PTM1LA,    ptmla[0]);         /* insert address                     */
        out32r(PTM1MS,    ptmms[0]);         /* insert size, enable bit is 1       */
+       pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, ptmpcila[0]);
 
        /*--------------------------------------------------------------------------+
         * 405GP PCI Target configuration.  (PTM2)
         *--------------------------------------------------------------------------*/
        out32r(PTM2LA, ptmla[1]);            /* insert address                     */
+       pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, ptmpcila[1]);
+
        if (ptmms[1] == 0)
        {
                out32r(PTM2MS,    0x00000001);   /* set enable bit                     */
@@ -251,8 +277,9 @@ void pci_405gp_init(struct pci_controller *hose)
        }
 
 #if (CONFIG_PCI_HOST != PCI_HOST_ADAPTER)
-#if (CONFIG_PCI_HOSE == PCI_HOST_AUTO)
-       if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
+       if ((mfdcr(strap) & PSR_PCI_ARBIT_EN) ||
+           (((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0)))
 #endif
        {
                /*--------------------------------------------------------------------------+
@@ -266,6 +293,10 @@ void pci_405gp_init(struct pci_controller *hose)
        }
 #endif
 
+#if defined(CONFIG_405EP) /* on ppc405ep vendor id is not set */
+       pci_write_config_word(PCIDEVID_405GP, PCI_VENDOR_ID, 0x1014); /* IBM */
+#endif
+
        /*
         * Set HCE bit (Host Configuration Enabled)
         */
@@ -277,7 +308,8 @@ void pci_405gp_init(struct pci_controller *hose)
         * Scan the PCI bus and configure devices found.
         *--------------------------------------------------------------------------*/
 #if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
-       if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+       if ((mfdcr(strap) & PSR_PCI_ARBIT_EN) ||
+           (((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0)))
 #endif
        {
 #ifdef CONFIG_PCI_SCAN_SHOW
@@ -341,7 +373,7 @@ void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
 {
        unsigned int cmdstat = 0;
 
-       pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+       pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
 
        /* always enable io space on vga boards */
        pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
@@ -357,7 +389,7 @@ void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
  */
 static struct pci_config_table pci_405gp_config_table[] = {
 /*if VendID is 0 it terminates the table search (ie Walnut)*/
-#if CFG_PCI_SUBSYS_VENDORID
+#ifdef CFG_PCI_SUBSYS_VENDORID
        {CFG_PCI_SUBSYS_VENDORID, PCI_ANY_ID, PCI_CLASS_BRIDGE_HOST,
         PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_bridge},
 #endif
@@ -400,18 +432,32 @@ static struct pci_controller ppc440_hose = {0};
 void pci_440_init (struct pci_controller *hose)
 {
        int reg_num = 0;
-       unsigned long strap;
 
+#ifndef CONFIG_DISABLE_PISE_TEST
        /*--------------------------------------------------------------------------+
         * The PCI initialization sequence enable bit must be set ... if not abort
-     * pci setup since updating the bit requires chip reset.
+        * pci setup since updating the bit requires chip reset.
         *--------------------------------------------------------------------------*/
-    strap = mfdcr(cpc0_strp1);
-    if( (strap & 0x00040000) == 0 ){
-       printf("PCI: CPC0_STRP1[PISE] not set.\n");
-       printf("PCI: Configuration aborted.\n");
-       return;
-    }
+#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+       unsigned long strap;
+
+       mfsdr(sdr_sdstp1,strap);
+       if ((strap & SDR0_SDSTP1_PISE_MASK) == 0) {
+               printf("PCI: SDR0_STRP1[PISE] not set.\n");
+               printf("PCI: Configuration aborted.\n");
+               return;
+       }
+#elif defined(CONFIG_440GP)
+       unsigned long strap;
+
+       strap = mfdcr(cpc0_strp1);
+       if ((strap & CPC0_STRP1_PISE_MASK) == 0) {
+               printf("PCI: CPC0_STRP1[PISE] not set.\n");
+               printf("PCI: Configuration aborted.\n");
+               return;
+       }
+#endif
+#endif /* CONFIG_DISABLE_PISE_TEST */
 
        /*--------------------------------------------------------------------------+
         * PCI controller init
@@ -421,26 +467,26 @@ void pci_440_init (struct pci_controller *hose)
 
        pci_set_region(hose->regions + reg_num++,
                       0x00000000,
-                          PCIX0_IOBASE,
-                          0x10000,
-                          PCI_REGION_IO);
+                      PCIX0_IOBASE,
+                      0x10000,
+                      PCI_REGION_IO);
 
        pci_set_region(hose->regions + reg_num++,
                       CFG_PCI_TARGBASE,
-                          CFG_PCI_MEMBASE,
-                          0x10000000,
-                          PCI_REGION_MEM );
+                      CFG_PCI_MEMBASE,
+                      0x10000000,
+                      PCI_REGION_MEM );
        hose->region_count = reg_num;
 
        pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA);
 
 #if defined(CFG_PCI_PRE_INIT)
-    /* Let board change/modify hose & do initial checks */
-    if( pci_pre_init (hose) == 0 ){
-       printf("PCI: Board-specific initialization failed.\n");
-       printf("PCI: Configuration aborted.\n");
-       return;
-    }
+       /* Let board change/modify hose & do initial checks */
+       if (pci_pre_init (hose) == 0) {
+               printf("PCI: Board-specific initialization failed.\n");
+               printf("PCI: Configuration aborted.\n");
+               return;
+       }
 #endif
 
        pci_register_hose( hose );
@@ -451,13 +497,18 @@ void pci_440_init (struct pci_controller *hose)
 #if defined(CFG_PCI_TARGET_INIT)
        pci_target_init(hose);                /* Let board setup pci target */
 #else
-    out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
-    out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_ID );
-    out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */
+       out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+       out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_ID );
+       out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */
 #endif
 
-    out32r( PCIX0_BRDGOPT1, 0x10000060 );               /* PLB Rq pri highest   */
-    out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 1 ); /* Enable host config   */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+       out32r( PCIX0_BRDGOPT1, 0x04000060 );               /* PLB Rq pri highest   */
+       out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1  */
+#elif defined(PCIX0_BRDGOPT1)
+       out32r( PCIX0_BRDGOPT1, 0x10000060 );               /* PLB Rq pri highest   */
+       out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 1 ); /* Enable host config   */
+#endif
 
        /*--------------------------------------------------------------------------+
         * PCI master init: default is one 256MB region for PCI memory:
@@ -469,27 +520,34 @@ void pci_440_init (struct pci_controller *hose)
        out32r( PCIX0_POM0SA, 0 ); /* disable */
        out32r( PCIX0_POM1SA, 0 ); /* disable */
        out32r( PCIX0_POM2SA, 0 ); /* disable */
+#if defined(CONFIG_440SPE)
+       out32r( PCIX0_POM0LAL, 0x10000000 );
+       out32r( PCIX0_POM0LAH, 0x0000000c );
+#else
        out32r( PCIX0_POM0LAL, 0x00000000 );
        out32r( PCIX0_POM0LAH, 0x00000003 );
+#endif
        out32r( PCIX0_POM0PCIAL, CFG_PCI_MEMBASE );
        out32r( PCIX0_POM0PCIAH, 0x00000000 );
        out32r( PCIX0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
-    out32r( PCIX0_STS, in32r( PCIX0_STS ) & ~0x0000fff8 );
+       out32r( PCIX0_STS, in32r( PCIX0_STS ) & ~0x0000fff8 );
 #endif
 
        /*--------------------------------------------------------------------------+
         * PCI host configuration -- we don't make any assumptions here ... the
-     * _board_must_indicate_ what to do -- there's just too many runtime
-     * scenarios in environments like cPCI, PPMC, etc. to make a determination
-     * based on hard-coded values or state of arbiter enable.
+        * _board_must_indicate_ what to do -- there's just too many runtime
+        * scenarios in environments like cPCI, PPMC, etc. to make a determination
+        * based on hard-coded values or state of arbiter enable.
         *--------------------------------------------------------------------------*/
-    if( is_pci_host(hose) ){
+       if (is_pci_host(hose)) {
 #ifdef CONFIG_PCI_SCAN_SHOW
-       printf("PCI:   Bus Dev VenId DevId Class Int\n");
+               printf("PCI:   Bus Dev VenId DevId Class Int\n");
+#endif
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+               out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
 #endif
-       out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
-       hose->last_busno = pci_hose_scan(hose);
-    }
+               hose->last_busno = pci_hose_scan(hose);
+       }
 }