tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I)
- tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
- tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
- tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, 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_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I)
tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I)
tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 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_CFGBASE, SZ_16M, 0x00000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x20000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0x40000000, 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)
static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
-void pcie_setup_hoses(void)
+void pcie_setup_hoses(int busno)
{
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;
+ bus = busno;
for (i = 0; i <= 2; i++) {
/* Check for katmai card presence */
if (!katmai_pcie_card_present(i))
hose = &pcie_hose[i];
hose->first_busno = bus;
- hose->last_busno = bus;
- bus++;
+ hose->last_busno = bus;
+ hose->current_busno = bus;
/* setup mem resource */
pci_set_region(hose->regions + 0,
* Config access can only go down stream
*/
hose->last_busno = pci_hose_scan(hose);
+ bus = hose->last_busno + 1;
#endif
}
}
tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I)
- tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
- tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
- tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, 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_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I)
tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I)
tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 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_CFGBASE, SZ_16M, 0x00000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x20000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0x40000000, 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)
static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
-void pcie_setup_hoses(void)
+void pcie_setup_hoses(int busno)
{
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;
+ bus = busno;
for (i = 0; i <= 2; i++) {
/* Check for yucca card presence */
if (!yucca_pcie_card_present(i))
hose = &pcie_hose[i];
hose->first_busno = bus;
- hose->last_busno = bus;
- bus++;
+ hose->last_busno = bus;
+ hose->current_busno = bus;
/* setup mem resource */
pci_set_region(hose->regions + 0,
* Config access can only go down stream
*/
hose->last_busno = pci_hose_scan(hose);
+ bus = hose->last_busno + 1;
#endif
}
}
static struct pci_controller ppc440_hose = {0};
-void pci_440_init (struct pci_controller *hose)
+int pci_440_init (struct pci_controller *hose)
{
int reg_num = 0;
if ((strap & SDR0_SDSTP1_PISE_MASK) == 0) {
printf("PCI: SDR0_STRP1[PISE] not set.\n");
printf("PCI: Configuration aborted.\n");
- return;
+ return -1;
}
#elif defined(CONFIG_440GP)
unsigned long strap;
if ((strap & CPC0_STRP1_PISE_MASK) == 0) {
printf("PCI: CPC0_STRP1[PISE] not set.\n");
printf("PCI: Configuration aborted.\n");
- return;
+ return -1;
}
#endif
#endif /* CONFIG_DISABLE_PISE_TEST */
* PCI controller init
*--------------------------------------------------------------------------*/
hose->first_busno = 0;
- hose->last_busno = 0xff;
+ hose->last_busno = 0;
/* PCI I/O space */
pci_set_region(hose->regions + reg_num++,
if (pci_pre_init (hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
- return;
+ return -1;
}
pci_register_hose( hose );
#endif
hose->last_busno = pci_hose_scan(hose);
}
+ return hose->last_busno;
}
void pci_init_board(void)
{
- pci_440_init (&ppc440_hose);
+ int busno;
+
+ busno = pci_440_init (&ppc440_hose);
#if defined(CONFIG_440SPE)
- pcie_setup_hoses();
+ pcie_setup_hoses(busno + 1);
#endif
}
LNKW_X8 = 0x8
};
+static u8* pcie_get_base(struct pci_controller *hose, unsigned int devfn)
+{
+ u8 *base = (u8*)hose->cfg_data;
+
+ /* use local configuration space for the first bus */
+ if (PCI_BUS(devfn) == 0) {
+ if (hose->cfg_data == (u8*)CFG_PCIE0_CFGBASE)
+ base = (u8*)CFG_PCIE0_XCFGBASE;
+ if (hose->cfg_data == (u8*)CFG_PCIE1_CFGBASE)
+ base = (u8*)CFG_PCIE1_XCFGBASE;
+ if (hose->cfg_data == (u8*)CFG_PCIE2_CFGBASE)
+ base = (u8*)CFG_PCIE2_XCFGBASE;
+ }
+
+ return base;
+}
+
static void pcie_dmer_disable(void)
{
mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE),
mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) & ~GPL_DMER_MASK_DISA);
}
-
static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
int offset, int len, u32 *val) {
+ u8 *address;
*val = 0;
+
+ /*
+ * Bus numbers are relative to hose->first_busno
+ */
+ devfn -= PCI_BDF(hose->first_busno, 0, 0);
+
/*
- * 440SPE implements only one function per port
+ * NOTICE: configuration space ranges are currenlty mapped only for
+ * the first 16 buses, so such limit must be imposed. In case more
+ * buses are required the TLB settings in board/amcc/<board>/init.S
+ * need to be altered accordingly (one bus takes 1 MB of memory space).
*/
- if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+ if (PCI_BUS(devfn) >= 16)
return 0;
- devfn = PCI_BDF(0,0,0);
+ /*
+ * Only single device/single function is supported for the primary and
+ * secondary buses of the 440SPe host bridge.
+ */
+ if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
+ ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
+ return 0;
+
+ address = pcie_get_base(hose, devfn);
offset += devfn << 4;
/*
static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
int offset, int len, u32 val) {
+ u8 *address;
+
/*
- * 440SPE implements only one function per port
+ * Bus numbers are relative to hose->first_busno
*/
- if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+ devfn -= PCI_BDF(hose->first_busno, 0, 0);
+
+ /*
+ * Same constraints as in pcie_read_config().
+ */
+ if (PCI_BUS(devfn) >= 16)
return 0;
- devfn = PCI_BDF(0,0,0);
+ if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
+ ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
+ return 0;
+
+ address = pcie_get_base(hose, devfn);
offset += devfn << 4;
/*
u32 v;
int rv;
- rv = pcie_read_config(hose, dev, offset, 1, &v);
+ rv = pcie_read_config(hose, dev, offset, 1, &v);
*val = (u8)v;
return rv;
}
volatile void *rmbase = 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);
+ 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:
/*
* 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);
- }
+ out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
+ out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
+ out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
/*
* Set up outbound translation to hose->mem_space from PLB
in_le16((u16 *)(mbase + PCI_COMMAND)) |
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
printf("PCIE:%d successfully set as rootpoint\n",port);
+
+ /* Set Device and Vendor Id */
+ switch (port) {
+ case 0:
+ out_le16(mbase + 0x200, 0xaaa0);
+ out_le16(mbase + 0x202, 0xbed0);
+ break;
+ case 1:
+ out_le16(mbase + 0x200, 0xaaa1);
+ out_le16(mbase + 0x202, 0xbed1);
+ break;
+ case 2:
+ out_le16(mbase + 0x200, 0xaaa2);
+ out_le16(mbase + 0x202, 0xbed2);
+ break;
+ default:
+ out_le16(mbase + 0x200, 0xaaa3);
+ out_le16(mbase + 0x202, 0xbed3);
+ }
+
+ /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
+ out_le32(mbase + 0x208, 0x06040001);
+
}
int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
/* 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);
+ in_le16((u16 *)(mbase + PCI_COMMAND)) |
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
attempts = 10;
# endif
int is_pci_host (struct pci_controller *);
#if defined(CONFIG_440SPE)
- void pcie_setup_hoses(void);
+ void pcie_setup_hoses(int busno);
#endif
#endif
#define CFG_PCIE_BASE 0xe0000000 /* PCIe UTL 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_PCIE1_CFGBASE 0xc1000000
+#define CFG_PCIE2_CFGBASE 0xc2000000
+#define CFG_PCIE0_XCFGBASE 0xc3000000
+#define CFG_PCIE1_XCFGBASE 0xc3001000
+#define CFG_PCIE2_XCFGBASE 0xc3002000
/* System RAM mapped to PCI space */
#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
#define CFG_PCIE_BASE 0xe0000000 /* PCIe UTL 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_PCIE1_CFGBASE 0xc1000000
+#define CFG_PCIE2_CFGBASE 0xc2000000
+#define CFG_PCIE0_XCFGBASE 0xc3000000
+#define CFG_PCIE1_XCFGBASE 0xc3001000
+#define CFG_PCIE2_XCFGBASE 0xc3002000
/* System RAM mapped to PCI space */
#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE