]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Add support for PCI-Express on PPC440SPe (Yucca board).
authorRafal Jaworowski <raj@semihalf.com>
Thu, 10 Aug 2006 10:43:17 +0000 (12:43 +0200)
committerRafal Jaworowski <raj@pollux.denx.de>
Thu, 10 Aug 2006 10:43:17 +0000 (12:43 +0200)
CHANGELOG
board/amcc/yucca/init.S
board/amcc/yucca/yucca.c
cpu/ppc4xx/405gp_pci.c
cpu/ppc4xx/440spe_pcie.c [new file with mode: 0644]
cpu/ppc4xx/440spe_pcie.h [new file with mode: 0644]
cpu/ppc4xx/Makefile
cpu/ppc4xx/cpu.c
cpu/ppc4xx/start.S
include/common.h
include/configs/yucca.h

index de02125bd63dc6f01180fc29e968a2e26572862d..0c70d3cfcdbcd80de0086b0093f691f63839b29b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,8 @@
 Changes since U-Boot 1.1.4:
 ======================================================================
 
+* Add initial support for PCI-Express on PPC440SPe (Yucca board).
+
 * Fix timer problems on AMCC yucca board.
   Set Timer Clock Select to use CPU clock as a timer input source.
 
index 8cf2636228b4188460a9361135a54a9062b90f88..a950eac44f984ed1be962e0e2d0ae00943fad151 100644 (file)
  *************************************************************************/
 
        .section .bootpg,"ax"
-       .globl tlbtab
 
-tlbtab:
+/**************************************************************************
+ * TLB table for revA
+ *************************************************************************/
+       .globl tlbtabA
+tlbtabA:
        tlbtab_start
        tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
 
@@ -94,12 +97,63 @@ tlbtab:
        tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
 
        tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
-       tlbentry(CFG_FPGA_BASE,SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
+       tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
 
-       tlbentry(CFG_OPER_FLASH,SZ_16M,0xE7000000, 4,AC_R|AC_W|AC_X|SA_G|SA_I)
+       tlbentry(CFG_OPER_FLASH, SZ_16M, 0xE7000000, 4,AC_R|AC_W|AC_X|SA_G|SA_I)
        tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I)
 
        tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+
+       tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE0_XCFGBASE, SZ_4K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_XCFGBASE, SZ_4K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_XCFGBASE, SZ_4K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+
+       tlbentry(CFG_PCIE1_REGBASE, SZ_1K, 0x60000400, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE3_REGBASE, SZ_1K, 0x60001400, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE5_REGBASE, SZ_1K, 0x60002400, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbtab_end
 
+/**************************************************************************
+ * TLB table for revB
+ *
+ * Notice: revB of the 440SPe chip is very strict about PLB real addressess
+ * and ranges to be mapped for config space: it seems to only work with
+ * d_nnnn_nnnn range (hangs the core upon config transaction attempts when
+ * set otherwise) while revA uses c_nnnn_nnnn.
+ *************************************************************************/
+       .globl tlbtabB
+tlbtabB:
+       tlbtab_start
+       tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
+
+       tlbentry(CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+       tlbentry(CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+       tlbentry(CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+       tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+
+       tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
+       tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
+
+       tlbentry(CFG_OPER_FLASH, SZ_16M, 0xE7000000, 4,AC_R|AC_W|AC_X|SA_G|SA_I)
+       tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I)
+
+       tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+
+       tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+
+       tlbentry(CFG_PCIE1_REGBASE, SZ_1K, 0x60000400, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE3_REGBASE, SZ_1K, 0x60001400, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE5_REGBASE, SZ_1K, 0x60002400, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbtab_end
index 1ae3a549b9b45e133220957d0bf9e3289543904e..a6589ec262a93e7cdb14816840a1e160ab029044 100644 (file)
  * MA 02111-1307 USA
  *
  * Port to AMCC-440SPE Evaluation Board SOP - April 2005
+ *
+ * PCIe supporting routines derived from Linux 440SPe PCIe driver.
  */
 
 #include <common.h>
 #include <ppc4xx.h>
 #include <asm/processor.h>
 #include <i2c.h>
+#include <asm-ppc/io.h>
+
 #include "yucca.h"
 
 void fpga_init (void);
@@ -39,6 +43,9 @@ int get_console_port(void);
 unsigned long ppcMfcpr(unsigned long cpr_reg);
 unsigned long ppcMfsdr(unsigned long sdr_reg);
 
+int ppc440spe_init_pcie_rootport(int port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+
 #define DEBUG_ENV
 #ifdef DEBUG_ENV
 #define DEBUGF(fmt,args...) printf(fmt ,##args)
@@ -908,6 +915,7 @@ void pci_target_init(struct pci_controller * hose )
 }
 #endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
 
+#if defined(CONFIG_PCI)
 /*************************************************************************
  *  is_pci_host
  *
@@ -923,12 +931,131 @@ void pci_target_init(struct pci_controller * hose )
  *
  *
  ************************************************************************/
-#if defined(CONFIG_PCI)
 int is_pci_host(struct pci_controller *hose)
 {
        /* The yucca board is always configured as host. */
        return 1;
 }
+
+
+int yucca_pcie_card_present(int port)
+{
+       u16 reg;
+
+       reg = in_be16((u16 *)FPGA_REG1C);
+       switch(port) {
+       case 0:
+               return !(reg & FPGA_REG1C_PE0_PRSNT);
+       case 1:
+               return !(reg & FPGA_REG1C_PE1_PRSNT);
+       case 2:
+               return !(reg & FPGA_REG1C_PE2_PRSNT);
+       default:
+               return 0;
+       }
+}
+
+/*
+ * For the given slot, set rootpoint mode, send power to the slot,
+ * turn on the green LED and turn off the yellow LED, enable the clock
+ * and turn off reset.
+ */
+void yucca_setup_pcie_fpga_rootpoint(int port)
+{
+       u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
+
+       switch(port) {
+       case 0:
+               rootpoint   = FPGA_REG1C_PE0_ROOTPOINT;
+               endpoint    = 0;
+               power       = FPGA_REG1A_PE0_PWRON;
+               green_led   = FPGA_REG1A_PE0_GLED;
+               clock       = FPGA_REG1A_PE0_REFCLK_ENABLE;
+               yellow_led  = FPGA_REG1A_PE0_YLED;
+               reset_off   = FPGA_REG1C_PE0_PERST;
+               break;
+       case 1:
+               rootpoint   = 0;
+               endpoint    = FPGA_REG1C_PE1_ENDPOINT;
+               power       = FPGA_REG1A_PE1_PWRON;
+               green_led   = FPGA_REG1A_PE1_GLED;
+               clock       = FPGA_REG1A_PE1_REFCLK_ENABLE;
+               yellow_led  = FPGA_REG1A_PE1_YLED;
+               reset_off   = FPGA_REG1C_PE1_PERST;
+               break;
+       case 2:
+               rootpoint   = 0;
+               endpoint    = FPGA_REG1C_PE2_ENDPOINT;
+               power       = FPGA_REG1A_PE2_PWRON;
+               green_led   = FPGA_REG1A_PE2_GLED;
+               clock       = FPGA_REG1A_PE2_REFCLK_ENABLE;
+               yellow_led  = FPGA_REG1A_PE2_YLED;
+               reset_off   = FPGA_REG1C_PE2_PERST;
+               break;
+
+       default:
+               return;
+       }
+
+       out_be16((u16 *)FPGA_REG1A,
+                ~(power | clock | green_led) &
+                (yellow_led | in_be16((u16 *)FPGA_REG1A)));
+
+       out_be16((u16 *)FPGA_REG1C,
+                ~(endpoint | reset_off) &
+                (rootpoint | in_be16((u16 *)FPGA_REG1C)));
+       /*
+        * Leave device in reset for a while after powering on the
+        * slot to give it a chance to initialize.
+        */
+       udelay(250 * 1000);
+
+       out_be16((u16 *)FPGA_REG1C, reset_off | in_be16((u16 *)FPGA_REG1C));
+}
+
+
+static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
+
+void pcie_setup_hoses(void)
+{
+       struct pci_controller *hose;
+       int i, bus;
+
+       /*
+        * assume we're called after the PCIX hose is initialized, which takes
+        * bus ID 0 and therefore start numbering PCIe's from 1.
+        */
+       bus = 1;
+       for (i = 0; i <= 2; i++) {
+               /* Check for yucca card presence */
+               if (!yucca_pcie_card_present(i))
+                       continue;
+
+               yucca_setup_pcie_fpga_rootpoint(i);
+               if (ppc440spe_init_pcie_rootport(i)) {
+                       printf("PCIE%d: initialization failed\n", i);
+                       continue;
+               }
+
+               hose = &pcie_hose[i];
+               hose->first_busno = bus;
+               hose->last_busno  = bus;
+               bus++;
+
+               /* setup mem resource */
+               pci_set_region(hose->regions + 0,
+                       CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE,
+                       CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE,
+                       CFG_PCIE_MEMSIZE,
+                       PCI_REGION_MEM
+                       );
+               hose->region_count = 1;
+               pci_register_hose(hose);
+
+               ppc440spe_setup_pcie(hose, i);
+               hose->last_busno = pci_hose_scan(hose);
+       }
+}
 #endif /* defined(CONFIG_PCI) */
 
 int misc_init_f (void)
@@ -1094,4 +1221,3 @@ unsigned long ppcMfsdr(unsigned long sdr_reg)
 
        return (sdr_value);
 }
-
index cf5eccb01fdf5532d0ec22c742c29e92aee34712..0b0686bcf716e8eb2136e52489dab41dc02d22fd 100644 (file)
@@ -315,7 +315,6 @@ void pci_405gp_init(struct pci_controller *hose)
 #ifdef CONFIG_PCI_SCAN_SHOW
                printf("PCI:   Bus Dev VenId DevId Class Int\n");
 #endif
-
                hose->last_busno = pci_hose_scan(hose);
        }
 #endif  /* CONFIG_PCI_PNP */
@@ -563,10 +562,12 @@ void pci_440_init (struct pci_controller *hose)
        }
 }
 
-
 void pci_init_board(void)
 {
        pci_440_init (&ppc440_hose);
+#if defined(CONFIG_440SPE)
+       pcie_setup_hoses();
+#endif
 }
 
 #endif /* CONFIG_440 & CONFIG_PCI */
diff --git a/cpu/ppc4xx/440spe_pcie.c b/cpu/ppc4xx/440spe_pcie.c
new file mode 100644 (file)
index 0000000..cbc93dd
--- /dev/null
@@ -0,0 +1,593 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm-ppc/io.h>
+#include <ppc4xx.h>
+#include <common.h>
+#include <pci.h>
+
+#include "440spe_pcie.h"
+
+#if defined(CONFIG_440SPE)
+#if defined(CONFIG_PCI)
+
+enum {
+       PTYPE_ENDPOINT          = 0x0,
+       PTYPE_LEGACY_ENDPOINT   = 0x1,
+       PTYPE_ROOT_PORT         = 0x4,
+
+       LNKW_X1                 = 0x1,
+       LNKW_X4                 = 0x4,
+       LNKW_X8                 = 0x8
+};
+
+static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
+       int offset, int len, u32 *val) {
+
+       *val = 0;
+       /*
+        * 440SPE implements only one function per port
+        */
+       if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+               return 0;
+
+       devfn = PCI_BDF(0,0,0);
+       offset += devfn << 4;
+
+       switch (len) {
+       case 1:
+               *val = in_8(hose->cfg_data + offset);
+               break;
+       case 2:
+               *val = in_le16((u16 *)(hose->cfg_data + offset));
+               break;
+       default:
+               *val = in_le32((u32 *)(hose->cfg_data + offset));
+               break;
+       }
+       return 0;
+}
+
+static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
+       int offset, int len, u32 val) {
+
+       /*
+        * 440SPE implements only one function per port
+        */
+       if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+               return 0;
+
+       devfn = PCI_BDF(0,0,0);
+       offset += devfn << 4;
+
+       switch (len) {
+       case 1:
+               out_8(hose->cfg_data + offset, val);
+               break;
+       case 2:
+               out_le16((u16 *)(hose->cfg_data + offset), val);
+               break;
+       default:
+               out_le32((u32 *)(hose->cfg_data + offset), val);
+               break;
+       }
+       return 0;
+}
+
+int pcie_read_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 *val)
+{
+       u32 v;
+       int rv;
+
+       rv =  pcie_read_config(hose, dev, offset, 1, &v);
+       *val = (u8)v;
+       return rv;
+}
+
+int pcie_read_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 *val)
+{
+       u32 v;
+       int rv;
+
+       rv = pcie_read_config(hose, dev, offset, 2, &v);
+       *val = (u16)v;
+       return rv;
+}
+
+int pcie_read_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 *val)
+{
+       u32 v;
+       int rv;
+
+       rv = pcie_read_config(hose, dev, offset, 3, &v);
+       *val = (u32)v;
+       return rv;
+}
+
+int pcie_write_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 val)
+{
+       return pcie_write_config(hose,(u32)dev,offset,1,val);
+}
+
+int pcie_write_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 val)
+{
+       return pcie_write_config(hose,(u32)dev,offset,2,(u32 )val);
+}
+
+int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 val)
+{
+       return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
+}
+
+static void ppc440spe_setup_utl(u32 port) {
+
+       volatile void *utl_base = NULL;
+
+       /*
+        * Map UTL registers
+        */
+       switch (port) {
+       case 0:
+               mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000d);
+               mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x60000400);
+               mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0xFFFFFC01);
+               mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
+               utl_base = (unsigned int *)(CFG_PCIE1_REGBASE);
+               break;
+
+       case 1:
+               mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000d);
+               mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x60001400);
+               mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0xFFFFFC01);
+               mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
+               utl_base = (unsigned int *)(CFG_PCIE3_REGBASE);
+               break;
+
+       case 2:
+               mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000d);
+               mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x60002400);
+               mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0xFFFFFC01);
+               mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
+               utl_base = (unsigned int *)(CFG_PCIE5_REGBASE);
+               break;
+       }
+
+       /*
+        * Set buffer allocations and then assert VRB and TXE.
+        */
+       out_be32(utl_base + PEUTL_OUTTR,   0x08000000);
+       out_be32(utl_base + PEUTL_INTR,    0x02000000);
+       out_be32(utl_base + PEUTL_OPDBSZ,  0x10000000);
+       out_be32(utl_base + PEUTL_PBBSZ,   0x53000000);
+       out_be32(utl_base + PEUTL_IPHBSZ,  0x08000000);
+       out_be32(utl_base + PEUTL_IPDBSZ,  0x10000000);
+       out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
+       out_be32(utl_base + PEUTL_PCTL,    0x8080007d);
+}
+
+static int check_error(void)
+{
+       u32 valPE0, valPE1, valPE2;
+       int err = 0;
+
+       /* SDR0_PEGPLLLCT1 reset */
+       if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
+               printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0);
+       }
+
+       valPE0 = SDR_READ(PESDR0_RCSSET);
+       valPE1 = SDR_READ(PESDR1_RCSSET);
+       valPE2 = SDR_READ(PESDR2_RCSSET);
+
+       /* SDR0_PExRCSSET rstgu */
+       if (!(valPE0 & 0x01000000) ||
+           !(valPE1 & 0x01000000) ||
+           !(valPE2 & 0x01000000)) {
+               printf("PCIE:  SDR0_PExRCSSET rstgu error\n");
+               err = -1;
+       }
+
+       /* SDR0_PExRCSSET rstdl */
+       if (!(valPE0 & 0x00010000) ||
+           !(valPE1 & 0x00010000) ||
+           !(valPE2 & 0x00010000)) {
+               printf("PCIE:  SDR0_PExRCSSET rstdl error\n");
+               err = -1;
+       }
+
+       /* SDR0_PExRCSSET rstpyn */
+       if ((valPE0 & 0x00001000) ||
+           (valPE1 & 0x00001000) ||
+           (valPE2 & 0x00001000)) {
+               printf("PCIE:  SDR0_PExRCSSET rstpyn error\n");
+               err = -1;
+       }
+
+       /* SDR0_PExRCSSET hldplb */
+       if ((valPE0 & 0x10000000) ||
+           (valPE1 & 0x10000000) ||
+           (valPE2 & 0x10000000)) {
+               printf("PCIE:  SDR0_PExRCSSET hldplb error\n");
+               err = -1;
+       }
+
+       /* SDR0_PExRCSSET rdy */
+       if ((valPE0 & 0x00100000) ||
+           (valPE1 & 0x00100000) ||
+           (valPE2 & 0x00100000)) {
+               printf("PCIE:  SDR0_PExRCSSET rdy error\n");
+               err = -1;
+       }
+
+       /* SDR0_PExRCSSET shutdown */
+       if ((valPE0 & 0x00000100) ||
+           (valPE1 & 0x00000100) ||
+           (valPE2 & 0x00000100)) {
+               printf("PCIE:  SDR0_PExRCSSET shutdown error\n");
+               err = -1;
+       }
+       return err;
+}
+
+/*
+ * Initialize PCI Express core
+ */
+int ppc440spe_init_pcie(void)
+{
+       int time_out = 20;
+
+       /* Set PLL clock receiver to LVPECL */
+       SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
+
+       if (check_error())
+               return -1;
+
+       if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
+       {
+               printf("PCIE: PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+                      SDR_READ(PESDR0_PLLLCT2));
+               return -1;
+       }
+       /* De-assert reset of PCIe PLL, wait for lock */
+       SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
+       udelay(3);
+
+       while(time_out) {
+               if (!(SDR_READ(PESDR0_PLLLCT3) & 0x10000000)) {
+                       time_out--;
+                       udelay(1);
+               } else
+                       break;
+       }
+       if (!time_out) {
+               printf("PCIE: VCO output not locked\n");
+               return -1;
+       }
+       return 0;
+}
+
+int ppc440spe_init_pcie_rootport(int port)
+{
+       static int core_init;
+       volatile u32 val = 0;
+       int attempts;
+
+       if (!core_init) {
+               ++core_init;
+               if (ppc440spe_init_pcie())
+                       return -1;
+       }
+
+       /*
+        * Initialize various parts of the PCI Express core for our port:
+        *
+        * - Set as a root port and enable max width
+        *   (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+        * - Set up UTL configuration.
+        * - Increase SERDES drive strength to levels suggested by AMCC.
+        * - De-assert RSTPYN, RSTDL and RSTGU.
+        *
+        * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
+        * default setting 0x11310000. The register has new fields,
+        * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+        * hang.
+        */
+       switch (port) {
+       case 0:
+               SDR_WRITE(PESDR0_DLPSET,  1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
+
+               SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
+               if (!ppc440spe_revB())
+                       SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+               SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+               SDR_WRITE(PESDR0_RCSSET,
+                       (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+               break;
+
+       case 1:
+               SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+               SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
+               if (!ppc440spe_revB())
+                       SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+               SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+               SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+               SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+               SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+               SDR_WRITE(PESDR1_RCSSET,
+                       (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+               break;
+
+       case 2:
+               SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+               SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
+               if (!ppc440spe_revB())
+                       SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+               SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+               SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+               SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+               SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+               SDR_WRITE(PESDR2_RCSSET,
+                       (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+               break;
+       }
+       /*
+        * Notice: the following delay has critical impact on device
+        * initialization - if too short (<50ms) the link doesn't get up.
+        */
+       mdelay(100);
+
+       switch (port) {
+       case 0: val = SDR_READ(PESDR0_RCSSTS); break;
+       case 1: val = SDR_READ(PESDR1_RCSSTS); break;
+       case 2: val = SDR_READ(PESDR2_RCSSTS); break;
+       }
+
+       if (val & (1 << 20)) {
+               printf("PCIE%d: PGRST failed %08x\n", port, val);
+               return -1;
+       }
+
+       /*
+        * Verify link is up
+        */
+       val = 0;
+       switch (port)
+       {
+               case 0:
+                       val = SDR_READ(PESDR0_LOOP);
+                       break;
+               case 1:
+                       val = SDR_READ(PESDR1_LOOP);
+                       break;
+               case 2:
+                       val = SDR_READ(PESDR2_LOOP);
+                       break;
+       }
+       if (!(val & 0x00001000)) {
+               printf("PCIE%d: link is not up.\n", port);
+               return -1;
+       }
+
+       /*
+        * Setup UTL registers - but only on revA!
+        * We use default settings for revB chip.
+        */
+       if (!ppc440spe_revB())
+               ppc440spe_setup_utl(port);
+
+       /*
+        * We map PCI Express configuration access into the 512MB regions
+        *
+        * NOTICE: revB is very strict about PLB real addressess and ranges to
+        * be mapped for config space; it seems to only work with d_nnnn_nnnn
+        * range (hangs the core upon config transaction attempts when set
+        * otherwise) while revA uses c_nnnn_nnnn.
+        *
+        * For revA:
+        *     PCIE0: 0xc_4000_0000
+        *     PCIE1: 0xc_8000_0000
+        *     PCIE2: 0xc_c000_0000
+        *
+        * For revB:
+        *     PCIE0: 0xd_0000_0000
+        *     PCIE1: 0xd_2000_0000
+        *     PCIE2: 0xd_4000_0000
+        */
+       switch (port) {
+       case 0:
+               if (ppc440spe_revB()) {
+                       mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
+                       mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
+               } else {
+                       /* revA */
+                       mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+                       mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+               }
+               mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+               break;
+
+       case 1:
+               if (ppc440spe_revB()) {
+                       mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
+                       mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
+               } else {
+                       mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+                       mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+               }
+               mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+               break;
+
+       case 2:
+               if (ppc440spe_revB()) {
+                       mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
+                       mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
+               } else {
+                       mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+                       mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+               }
+               mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+               break;
+       }
+
+       /*
+        * Check for VC0 active and assert RDY.
+        */
+       attempts = 10;
+       switch (port) {
+       case 0:
+               while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+                       if (!(attempts--)) {
+                               printf("PCIE0: VC0 not active\n");
+                               return -1;
+                       }
+                       mdelay(1000);
+               }
+               SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+               break;
+       case 1:
+               while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+                       if (!(attempts--)) {
+                               printf("PCIE1: VC0 not active\n");
+                               return -1;
+                       }
+                       mdelay(1000);
+               }
+
+               SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+               break;
+       case 2:
+               while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+                       if (!(attempts--)) {
+                               printf("PCIE2: VC0 not active\n");
+                               return -1;
+                       }
+                       mdelay(1000);
+               }
+
+               SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+               break;
+       }
+       mdelay(100);
+
+       return 0;
+}
+
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
+{
+       volatile void *mbase = NULL;
+
+       pci_set_ops(hose,
+                       pcie_read_config_byte,
+                       pcie_read_config_word,
+                       pcie_read_config_dword,
+                       pcie_write_config_byte,
+                       pcie_write_config_word,
+                       pcie_write_config_dword);
+
+       switch(port) {
+       case 0:
+               mbase = (u32 *)CFG_PCIE0_XCFGBASE;
+               hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
+               break;
+       case 1:
+               mbase = (u32 *)CFG_PCIE1_XCFGBASE;
+               hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
+               break;
+       case 2:
+               mbase = (u32 *)CFG_PCIE2_XCFGBASE;
+               hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
+               break;
+       }
+
+       /*
+        * Set bus numbers on our root port
+        */
+       if (ppc440spe_revB()) {
+               out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
+               out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
+               out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
+       } else {
+               out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
+               out_8((u8 *)mbase + PCI_SECONDARY_BUS, 0);
+       }
+
+       /*
+        * Set up outbound translation to hose->mem_space from PLB
+        * addresses at an offset of 0xd_0000_0000.  We set the low
+        * bits of the mask to 11 to turn off splitting into 8
+        * subregions and to enable the outbound translation.
+        */
+       out_le32(mbase + PECFG_POM0LAH, 0x00000000);
+       out_le32(mbase + PECFG_POM0LAL, (CFG_PCIE_MEMBASE +
+                       port * CFG_PCIE_MEMSIZE));
+
+       switch (port) {
+       case 0:
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0),  0x0000000d);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0),  CFG_PCIE_MEMBASE +
+                       port * CFG_PCIE_MEMSIZE);
+               mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+               mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+                       ~(CFG_PCIE_MEMSIZE - 1) | 3);
+               break;
+       case 1:
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1),  0x0000000d);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1),  (CFG_PCIE_MEMBASE +
+                       port * CFG_PCIE_MEMSIZE));
+               mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+               mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+                       ~(CFG_PCIE_MEMSIZE - 1) | 3);
+               break;
+       case 2:
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2),  0x0000000d);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2),  (CFG_PCIE_MEMBASE +
+                       port * CFG_PCIE_MEMSIZE));
+               mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+               mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+                       ~(CFG_PCIE_MEMSIZE - 1) | 3);
+               break;
+       }
+
+       /* Set up 16GB inbound memory window at 0 */
+       out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+       out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+       out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+       out_le32(mbase + PECFG_BAR0LMPA, 0);
+       out_le32(mbase + PECFG_PIM0LAL, 0);
+       out_le32(mbase + PECFG_PIM0LAH, 0);
+       out_le32(mbase + PECFG_PIMEN, 0x1);
+
+       /* Enable I/O, Mem, and Busmaster cycles */
+       out_le16((u16 *)(mbase + PCI_COMMAND),
+                in_le16((u16 *)(mbase + PCI_COMMAND)) |
+                PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+}
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_440SPE */
diff --git a/cpu/ppc4xx/440spe_pcie.h b/cpu/ppc4xx/440spe_pcie.h
new file mode 100644 (file)
index 0000000..47df762
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <ppc4xx.h>
+#ifndef __440SPE_PCIE_H
+#define __440SPE_PCIE_H
+
+#define mdelay(n) ({unsigned long __ms=(n); while (__ms--) udelay(1000);})
+
+#define DCRN_SDR0_CFGADDR      0x00e
+#define DCRN_SDR0_CFGDATA      0x00f
+
+#define DCRN_PCIE0_BASE                0x100
+#define DCRN_PCIE1_BASE                0x120
+#define DCRN_PCIE2_BASE                0x140
+#define PCIE0                  DCRN_PCIE0_BASE
+#define PCIE1                  DCRN_PCIE1_BASE
+#define PCIE2                  DCRN_PCIE2_BASE
+
+#define DCRN_PEGPL_CFGBAH(base)                (base + 0x00)
+#define DCRN_PEGPL_CFGBAL(base)                (base + 0x01)
+#define DCRN_PEGPL_CFGMSK(base)                (base + 0x02)
+#define DCRN_PEGPL_MSGBAH(base)                (base + 0x03)
+#define DCRN_PEGPL_MSGBAL(base)                (base + 0x04)
+#define DCRN_PEGPL_MSGMSK(base)                (base + 0x05)
+#define DCRN_PEGPL_OMR1BAH(base)       (base + 0x06)
+#define DCRN_PEGPL_OMR1BAL(base)       (base + 0x07)
+#define DCRN_PEGPL_OMR1MSKH(base)      (base + 0x08)
+#define DCRN_PEGPL_OMR1MSKL(base)      (base + 0x09)
+#define DCRN_PEGPL_REGBAH(base)                (base + 0x12)
+#define DCRN_PEGPL_REGBAL(base)                (base + 0x13)
+#define DCRN_PEGPL_REGMSK(base)                (base + 0x14)
+#define DCRN_PEGPL_SPECIAL(base)       (base + 0x15)
+
+/*
+ * System DCRs (SDRs)
+ */
+#define PESDR0_PLLLCT1         0x03a0
+#define PESDR0_PLLLCT2         0x03a1
+#define PESDR0_PLLLCT3         0x03a2
+
+#define PESDR0_UTLSET1         0x0300
+#define PESDR0_UTLSET2         0x0301
+#define PESDR0_DLPSET          0x0302
+#define PESDR0_LOOP            0x0303
+#define PESDR0_RCSSET          0x0304
+#define PESDR0_RCSSTS          0x0305
+#define PESDR0_HSSL0SET1       0x0306
+#define PESDR0_HSSL0SET2       0x0307
+#define PESDR0_HSSL0STS                0x0308
+#define PESDR0_HSSL1SET1       0x0309
+#define PESDR0_HSSL1SET2       0x030a
+#define PESDR0_HSSL1STS                0x030b
+#define PESDR0_HSSL2SET1       0x030c
+#define PESDR0_HSSL2SET2       0x030d
+#define PESDR0_HSSL2STS                0x030e
+#define PESDR0_HSSL3SET1       0x030f
+#define PESDR0_HSSL3SET2       0x0310
+#define PESDR0_HSSL3STS                0x0311
+#define PESDR0_HSSL4SET1       0x0312
+#define PESDR0_HSSL4SET2       0x0313
+#define PESDR0_HSSL4STS                0x0314
+#define PESDR0_HSSL5SET1       0x0315
+#define PESDR0_HSSL5SET2       0x0316
+#define PESDR0_HSSL5STS                0x0317
+#define PESDR0_HSSL6SET1       0x0318
+#define PESDR0_HSSL6SET2       0x0319
+#define PESDR0_HSSL6STS                0x031a
+#define PESDR0_HSSL7SET1       0x031b
+#define PESDR0_HSSL7SET2       0x031c
+#define PESDR0_HSSL7STS                0x031d
+#define PESDR0_HSSCTLSET       0x031e
+#define PESDR0_LANE_ABCD       0x031f
+#define PESDR0_LANE_EFGH       0x0320
+
+#define PESDR1_UTLSET1         0x0340
+#define PESDR1_UTLSET2         0x0341
+#define PESDR1_DLPSET          0x0342
+#define PESDR1_LOOP            0x0343
+#define PESDR1_RCSSET          0x0344
+#define PESDR1_RCSSTS          0x0345
+#define PESDR1_HSSL0SET1       0x0346
+#define PESDR1_HSSL0SET2       0x0347
+#define PESDR1_HSSL0STS                0x0348
+#define PESDR1_HSSL1SET1       0x0349
+#define PESDR1_HSSL1SET2       0x034a
+#define PESDR1_HSSL1STS                0x034b
+#define PESDR1_HSSL2SET1       0x034c
+#define PESDR1_HSSL2SET2       0x034d
+#define PESDR1_HSSL2STS                0x034e
+#define PESDR1_HSSL3SET1       0x034f
+#define PESDR1_HSSL3SET2       0x0350
+#define PESDR1_HSSL3STS                0x0351
+#define PESDR1_HSSCTLSET       0x0352
+#define PESDR1_LANE_ABCD       0x0353
+
+#define PESDR2_UTLSET1         0x0370
+#define PESDR2_UTLSET2         0x0371
+#define PESDR2_DLPSET          0x0372
+#define PESDR2_LOOP            0x0373
+#define PESDR2_RCSSET          0x0374
+#define PESDR2_RCSSTS          0x0375
+#define PESDR2_HSSL0SET1       0x0376
+#define PESDR2_HSSL0SET2       0x0377
+#define PESDR2_HSSL0STS                0x0378
+#define PESDR2_HSSL1SET1       0x0379
+#define PESDR2_HSSL1SET2       0x037a
+#define PESDR2_HSSL1STS                0x037b
+#define PESDR2_HSSL2SET1       0x037c
+#define PESDR2_HSSL2SET2       0x037d
+#define PESDR2_HSSL2STS                0x037e
+#define PESDR2_HSSL3SET1       0x037f
+#define PESDR2_HSSL3SET2       0x0380
+#define PESDR2_HSSL3STS                0x0381
+#define PESDR2_HSSCTLSET       0x0382
+#define PESDR2_LANE_ABCD       0x0383
+
+/*
+ * UTL register offsets
+ */
+#define PEUTL_PBBSZ            0x20
+#define PEUTL_OPDBSZ           0x68
+#define PEUTL_IPHBSZ           0x70
+#define PEUTL_IPDBSZ           0x78
+#define PEUTL_OUTTR            0x90
+#define PEUTL_INTR             0x98
+#define PEUTL_PCTL             0xa0
+#define PEUTL_RCIRQEN          0xb8
+
+/*
+ * Config space register offsets
+ */
+#define PECFG_BAR0LMPA         0x210
+#define PECFG_BAR0HMPA         0x214
+#define PECFG_PIMEN            0x33c
+#define PECFG_PIM0LAL          0x340
+#define PECFG_PIM0LAH          0x344
+#define PECFG_POM0LAL          0x380
+#define PECFG_POM0LAH          0x384
+
+#define SDR_READ(offset) ({\
+       mtdcr(DCRN_SDR0_CFGADDR, offset); \
+       mfdcr(DCRN_SDR0_CFGDATA);})
+
+#define SDR_WRITE(offset, data) ({\
+       mtdcr(DCRN_SDR0_CFGADDR, offset); \
+       mtdcr(DCRN_SDR0_CFGDATA,data);})
+
+int ppc440spe_init_pcie(void);
+int ppc440spe_init_pcie_rootport(int port);
+void yucca_setup_pcie_fpga_rootpoint(int port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+int yucca_pcie_card_present(int port);
+int pcie_hose_scan(struct pci_controller *hose, int bus);
+#endif /* __440SPE_PCIE_H */
index c5634570054b92169442cb040b56b3f11c70cffc..7d6990f9a876e05fbffc0b7dbe7edb759bdef436 100644 (file)
@@ -31,7 +31,8 @@ COBJS = 405gp_pci.o 4xx_enet.o \
          bedbug_405.o commproc.o \
          cpu.o cpu_init.o i2c.o interrupts.o \
          miiphy.o sdram.o serial.o \
-         spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o
+         spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o \
+         440spe_pcie.o
 
 OBJS   = $(AOBJS) $(COBJS)
 
index 71303bcc49fb493da5d1e5a0acee815492ccb2d2..bc51fbfdbedcf20c9455c910a1631487f7d8eb87 100644 (file)
@@ -315,6 +315,17 @@ int checkcpu (void)
        return 0;
 }
 
+#if defined (CONFIG_440SPE)
+int ppc440spe_revB() {
+       unsigned int pvr;
+
+       pvr = get_pvr();
+       if (pvr == PVR_440SPe_RB)
+               return 1;
+       else
+               return 0;
+}
+#endif
 
 /* ------------------------------------------------------------------------- */
 
index 0a6f81de44952966ed87ea9ac08d651a0132befe..6d6d75fd30f017bdebd374c3fdea0111fef84ced 100644 (file)
@@ -315,7 +315,23 @@ rsttlb:    tlbwe   r0,r1,0x0000    /* Invalidate all entries (V=0)*/
        /*----------------------------------------------------------------*/
        /* TLB entry setup -- step thru tlbtab */
        /*----------------------------------------------------------------*/
+#if defined(CONFIG_440SPE)
+       /*----------------------------------------------------------------*/
+       /* We have different TLB tables for revA and rev B of 440SPe */
+       /*----------------------------------------------------------------*/
+       mfspr   r1, PVR
+       lis     r0,0x5342
+       ori     r0,r0,0x1891
+       cmpw    r7,r1,r0
+       bne     r7,..revA
+       bl      tlbtabB
+       b       ..goon
+..revA:
+       bl      tlbtabA
+..goon:
+#else
        bl      tlbtab          /* Get tlbtab pointer */
+#endif
        mr      r5,r0
        li      r1,0x003f       /* 64 TLB entries max */
        mtctr   r1
index 6d7c41ad2b62129f70b54ca6210efbd32e5cf10e..5f00f91f3fb687bc16794d73ea2c65b30ee4bf91 100644 (file)
@@ -244,6 +244,9 @@ void        pciinfo       (int, int);
        void    pci_master_init      (struct pci_controller *);
 #   endif
     int            is_pci_host         (struct pci_controller *);
+#if defined(CONFIG_440SPE)
+   void pcie_setup_hoses(void);
+#endif
 #endif
 
 int    misc_init_f   (void);
@@ -461,6 +464,7 @@ void        get_sys_info  ( sys_info_t * );
 #      if defined(CONFIG_440SPE)
         unsigned long determine_sysper(void);
         unsigned long determine_pci_clock_per(void);
+        int ppc440spe_revB(void);
 #      endif
 #  else
     typedef PPC405_SYS_INFO sys_info_t;
index 0e58e7e102442877504614ebff5397e74a0012fe..9dd9e5eae48e8d7c9139da55ae1e5da248ee38af 100644 (file)
 #define CFG_PERIPHERAL_BASE    0xa0000000      /* internal peripherals */
 #define CFG_ISRAM_BASE         0x90000000      /* internal SRAM        */
 
-#define CFG_PCI_MEMBASE                0x80000000      /* mapped pci memory    */
-#define CFG_PCI_MEMBASE1       0x90000000      /* mapped pci memory    */
-#define CFG_PCI_MEMBASE2       0xa0000000      /* mapped pci memory    */
-#define CFG_PCI_MEMBASE3       0xb0000000      /* mapped pci memory    */
-
+#define CFG_PCI_MEMBASE                0x80000000      /* mapped PCI memory    */
 #define CFG_PCI_BASE           0xd0000000      /* internal PCI regs    */
-#define CFG_PCI_TARGBASE       0x80000000      /*PCIaddr mapped to CFG_PCI_MEMBASE*/
+#define CFG_PCI_TARGBASE       CFG_PCI_MEMBASE
+
+#define CFG_PCIE_MEMBASE       0xB0000000      /* mapped PCIe memory   */
+#define CFG_PCIE_MEMSIZE       0x01000000
 
-/* #define CFG_PCI_BASE_IO     0xB8000000 */   /* internal PCI I-O     */
-/* #define CFG_PCI_BASE_REGS   0xBEC00000 */   /* internal PCI regs    */
-/* #define CFG_PCI_BASE_CYCLE  0xBED00000 */   /* internal PCI regs    */
+#define CFG_PCIE0_CFGBASE      0xc0000000
+#define CFG_PCIE0_XCFGBASE     0xc0000400
+#define CFG_PCIE1_CFGBASE      0xc0001000
+#define CFG_PCIE1_XCFGBASE     0xc0001400
+#define CFG_PCIE2_CFGBASE      0xc0002000
+#define CFG_PCIE2_XCFGBASE     0xc0002400
+
+#define CFG_PCIE0_REGBASE      0xc0003000
+#define CFG_PCIE1_REGBASE      0xc0003400
+#define CFG_PCIE2_REGBASE      0xc0004000
+#define CFG_PCIE3_REGBASE      0xc0004400
+#define CFG_PCIE4_REGBASE      0xc0005000
+#define CFG_PCIE5_REGBASE      0xc0005400
 
 /* System RAM mapped to PCI space */
 #define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
  */
 /* Support for Intel 82557/82559/82559ER chips. */
 #define CONFIG_EEPRO100
+
 /*
  * For booting Linux, the board info and command line data
  * have to be in the first 8 MB of memory, since this is
 #define FPGA_REG1C_PE1_WAKE            0x0040
 #define FPGA_REG1C_PE2_WAKE            0x0020
 #define FPGA_REG1C_PE0_PERST           0x0010
-#define FPGA_REG1C_PE1_PERST           0x0080
-#define FPGA_REG1C_PE2_PERST           0x0040
+#define FPGA_REG1C_PE1_PERST           0x0008
+#define FPGA_REG1C_PE2_PERST           0x0004
 
 /*----------------------------------------------------------------------------+
 | Defines