* Added support for initializing second PCI bus on 85xx
authorMatthew McClintock <msm@freescale.com>
Wed, 28 Jun 2006 15:45:17 +0000 (10:45 -0500)
committerMatthew McClintock <msm@freescale.com>
Wed, 28 Jun 2006 15:45:17 +0000 (10:45 -0500)
  Patch by Andy Fleming 17-Mar-2006

Signed-off-by: Andy Fleming <afleming@freescale.com>
cpu/mpc85xx/pci.c
include/asm-ppc/immap_85xx.h

index a94493e0802c9424e575b0cd94cd98ff7debf586..ca11bce22ea2b78bd7c35305bf208491df9590a7 100644 (file)
 
 #if defined(CONFIG_PCI)
 
+static struct pci_controller *pci_hose;
+
 void
-pci_mpc85xx_init(struct pci_controller *hose)
+pci_mpc85xx_init(struct pci_controller *board_hose)
 {
+       u16 reg16;
+       u32 dev;
+
        volatile immap_t    *immap = (immap_t *)CFG_CCSRBAR;
        volatile ccsr_pcix_t *pcix = &immap->im_pcix;
+       volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2;
+       volatile ccsr_gur_t *gur = &immap->im_gur;
+       struct pci_controller * hose;
 
-       u16 reg16;
+       pci_hose = board_hose;
+
+       hose = &pci_hose[0];
 
        hose->first_busno = 0;
        hose->last_busno = 0xff;
 
-       pci_set_region(hose->regions + 0,
-                      CFG_PCI1_MEM_BASE,
-                      CFG_PCI1_MEM_PHYS,
-                      CFG_PCI1_MEM_SIZE,
-                      PCI_REGION_MEM);
-
-       pci_set_region(hose->regions + 1,
-                      CFG_PCI1_IO_BASE,
-                      CFG_PCI1_IO_PHYS,
-                      CFG_PCI1_IO_SIZE,
-                      PCI_REGION_IO);
-
-       hose->region_count = 2;
-
        pci_setup_indirect(hose,
                           (CFG_IMMR+0x8000),
                           (CFG_IMMR+0x8004));
 
+       /*
+        * Hose scan.
+        */
+       dev = PCI_BDF(hose->first_busno, 0, 0);
+       pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+       reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+       /*
+        * Clear non-reserved bits in status register.
+        */
+       pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+       if (!(gur->pordevsr & PORDEVSR_PCI)) {
+               /* PCI-X init */
+               reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
+                       | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+               pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16);
+       }
+
        pcix->potar1   = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
        pcix->potear1  = 0x00000000;
-       pcix->powbar1  = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+       pcix->powbar1  = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff;
        pcix->powbear1 = 0x00000000;
-       pcix->powar1   = 0x8004401c;    /* 512M MEM space */
+       pcix->powar1 = (POWAR_EN | POWAR_MEM_READ |
+                       POWAR_MEM_WRITE | POWAR_MEM_512M);
 
-       pcix->potar2   = 0x00000000;
+       pcix->potar2  = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
        pcix->potear2  = 0x00000000;
-       pcix->powbar2  = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+       pcix->powbar2  = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff;
        pcix->powbear2 = 0x00000000;
-       pcix->powar2   = 0x80088017;    /* 16M IO space */
+       pcix->powar2 = (POWAR_EN | POWAR_IO_READ |
+                       POWAR_IO_WRITE | POWAR_IO_1M);
 
        pcix->pitar1 = 0x00000000;
        pcix->piwbar1 = 0x00000000;
-       pcix->piwar1 = 0xa0f5501e;      /* Enable, Prefetch, Local Mem,
-                                        * Snoop R/W, 2G */
+       pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+                       PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
 
-       /*
-        * Hose scan.
-        */
-       pci_register_hose(hose);
+       pcix->powar3 = 0;
+       pcix->powar4 = 0;
+       pcix->piwar2 = 0;
+       pcix->piwar3 = 0;
 
-       pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, &reg16);
-       reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-       pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16);
+       pci_set_region(hose->regions + 0,
+                      CFG_PCI1_MEM_BASE,
+                      CFG_PCI1_MEM_PHYS,
+                      CFG_PCI1_MEM_SIZE,
+                      PCI_REGION_MEM);
 
-       /*
-        * Clear non-reserved bits in status register.
-        */
-       pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff);
-       pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80);
+       pci_set_region(hose->regions + 1,
+                      CFG_PCI1_IO_BASE,
+                      CFG_PCI1_IO_PHYS,
+                      CFG_PCI1_IO_SIZE,
+                      PCI_REGION_IO);
+
+       hose->region_count = 2;
+
+       pci_register_hose(hose);
 
 #if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS)
        /*
@@ -117,6 +141,94 @@ pci_mpc85xx_init(struct pci_controller *hose)
 #endif
 
        hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC85XX_PCI2
+       hose = &pci_hose[1];
+
+       hose->first_busno = pci_hose[0].last_busno + 1;
+       hose->last_busno = 0xff;
+
+       pci_setup_indirect(hose,
+                          (CFG_IMMR+0x9000),
+                          (CFG_IMMR+0x9004));
+
+       dev = PCI_BDF(hose->first_busno, 0, 0);
+       pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+       reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+       /*
+        * Clear non-reserved bits in status register.
+        */
+       pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+       pcix2->potar1   = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff;
+       pcix2->potear1  = 0x00000000;
+       pcix2->powbar1  = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff;
+       pcix2->powbear1 = 0x00000000;
+       pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ |
+                       POWAR_MEM_WRITE | POWAR_MEM_512M);
+
+       pcix2->potar2  = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff;
+       pcix2->potear2  = 0x00000000;
+       pcix2->powbar2  = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff;
+       pcix2->powbear2 = 0x00000000;
+       pcix2->powar2 = (POWAR_EN | POWAR_IO_READ |
+                       POWAR_IO_WRITE | POWAR_IO_1M);
+
+       pcix2->pitar1 = 0x00000000;
+       pcix2->piwbar1 = 0x00000000;
+       pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+                       PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
+
+       pcix2->powar3 = 0;
+       pcix2->powar4 = 0;
+       pcix2->piwar2 = 0;
+       pcix2->piwar3 = 0;
+
+       pci_set_region(hose->regions + 0,
+                      CFG_PCI2_MEM_BASE,
+                      CFG_PCI2_MEM_PHYS,
+                      CFG_PCI2_MEM_SIZE,
+                      PCI_REGION_MEM);
+
+       pci_set_region(hose->regions + 1,
+                      CFG_PCI2_IO_BASE,
+                      CFG_PCI2_IO_PHYS,
+                      CFG_PCI2_IO_SIZE,
+                      PCI_REGION_IO);
+
+       hose->region_count = 2;
+
+       /*
+        * Hose scan.
+        */
+       pci_register_hose(hose);
+
+       hose->last_busno = pci_hose_scan(hose);
+#endif
 }
 
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+       u32 *p;
+       int len;
+
+       p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len);
+       if (p != NULL) {
+               p[0] = pci_hose[0].first_busno;
+               p[1] = pci_hose[0].last_busno;
+       }
+
+#ifdef CONFIG_MPC85XX_PCI2
+       p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len);
+       if (p != NULL) {
+               p[0] = pci_hose[1].first_busno;
+               p[1] = pci_hose[1].last_busno;
+       }
+#endif
+}
+#endif /* CONFIG_OF_FLAT_TREE */
 #endif /* CONFIG_PCI */
index 2f10e9591d21eb0ecc29f73c920e5ac386a086b2..7a4345a74085e9d0c034930c6d1873fff904aa2f 100644 (file)
@@ -246,7 +246,6 @@ typedef struct ccsr_lbc {
 
 /*
  * PCI Registers(0x8000-0x9000)
- * Omitting Reserved(0x9000-0x2_0000)
  */
 typedef struct ccsr_pcix {
        uint    cfg_addr;       /* 0x8000 - PCIX Configuration Address Register */
@@ -309,9 +308,27 @@ typedef struct ccsr_pcix {
        uint    peextaddrcr;    /* 0x8e14 - PCIX  Error Extended Address Capture Register */
        uint    pedlcr;         /* 0x8e18 - PCIX Error Data Low Capture Register */
        uint    pedhcr;         /* 0x8e1c - PCIX Error Error Data High Capture Register */
-       char    res11[94688];
+       uint    gas_timr;       /* 0x8e20 - PCIX Gasket Timer Register */
+       char    res11[476];
 } ccsr_pcix_t;
 
+#define PCIX_COMMAND   0x62
+#define POWAR_EN       0x80000000
+#define POWAR_IO_READ  0x00080000
+#define POWAR_MEM_READ 0x00040000
+#define POWAR_IO_WRITE 0x00008000
+#define POWAR_MEM_WRITE        0x00004000
+#define POWAR_MEM_512M 0x0000001c
+#define POWAR_IO_1M    0x00000013
+
+#define PIWAR_EN       0x80000000
+#define PIWAR_PF       0x20000000
+#define PIWAR_LOCAL    0x00f00000
+#define PIWAR_READ_SNOOP       0x00050000
+#define PIWAR_WRITE_SNOOP      0x00005000
+#define PIWAR_MEM_2G           0x0000001e
+
+
 /*
  * L2 Cache Registers(0x2_0000-0x2_1000)
  */
@@ -1572,6 +1589,8 @@ typedef struct ccsr_gur {
        char    res15[61651];
 } ccsr_gur_t;
 
+#define PORDEVSR_PCI   (0x00800000)    /* PCI Mode */
+
 typedef struct immap {
        ccsr_local_ecm_t        im_local_ecm;
        ccsr_ddr_t              im_ddr;
@@ -1579,6 +1598,8 @@ typedef struct immap {
        ccsr_duart_t            im_duart;
        ccsr_lbc_t              im_lbc;
        ccsr_pcix_t             im_pcix;
+       ccsr_pcix_t             im_pcix2;
+       char                    reserved[90112];
        ccsr_l2cache_t          im_l2cache;
        ccsr_dma_t              im_dma;
        ccsr_tsec_t             im_tsec1;