4xx_pcie.c
来自「最新版的u-boot,2008-10-18发布」· C语言 代码 · 共 1,172 行 · 第 1/3 页
C
1,172 行
return 0x0000000c40000000ULL; case 1: return 0x0000000c80000000ULL; case 2: return 0x0000000cc0000000ULL; } }#endif#if defined(CONFIG_460EX) || defined(CONFIG_460GT) if (port == 0) return 0x0000000d00000000ULL; else return 0x0000000d20000000ULL;#endif}/* * 4xx boards as end point and root point setup * and * testing inbound and out bound windows * * 4xx boards can be plugged into another 4xx boards or you can get PCI-E * cable which can be used to setup loop back from one port to another port. * Please rememeber that unless there is a endpoint plugged in to root port it * will not initialize. It is the same in case of endpoint , unless there is * root port attached it will not initialize. * * In this release of software all the PCI-E ports are configured as either * endpoint or rootpoint.In future we will have support for selective ports * setup as endpoint and root point in single board. * * Once your board came up as root point , you can verify by reading * /proc/bus/pci/devices. Where you can see the configuration registers * of end point device attached to the port. * * Enpoint cofiguration can be verified by connecting 4xx board to any * host or another 4xx board. Then try to scan the device. In case of * linux use "lspci" or appripriate os command. * * How do I verify the inbound and out bound windows ? (4xx to 4xx) * in this configuration inbound and outbound windows are setup to access * sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address * is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000, * This is waere your POM(PLB out bound memory window) mapped. then * read the data from other 4xx board's u-boot prompt at address * 0x9000 0000(SRAM). Data should match. * In case of inbound , write data to u-boot command prompt at 0xb000 0000 * which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check * data at 0x9000 0000(SRAM).Data should match. */int ppc4xx_init_pcie_port(int port, int rootport){ static int core_init; volatile u32 val = 0; int attempts; u64 addr; u32 low, high; if (!core_init) { if (ppc4xx_init_pcie()) return -1; ++core_init; } /* * Initialize various parts of the PCI Express core for our port */ ppc4xx_init_pcie_port_hw(port, rootport); /* * Notice: the following delay has critical impact on device * initialization - if too short (<50ms) the link doesn't get up. */ mdelay(100); val = SDR_READ(SDRN_PESDR_RCSSTS(port)); if (val & (1 << 20)) { printf("PCIE%d: PGRST failed %08x\n", port, val); return -1; } /* * Verify link is up */ val = SDR_READ(SDRN_PESDR_LOOP(port)); 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()) ppc4xx_setup_utl(port); /* * We map PCI Express configuration access into the 512MB regions */ addr = ppc4xx_get_cfgaddr(port); low = U64_TO_U32_LOW(addr); high = U64_TO_U32_HIGH(addr); switch (port) { case 0: mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), high); mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), low); mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */ break; case 1: mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), high); mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), low); mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */ break;#if CFG_PCIE_NR_PORTS > 2 case 2: mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), high); mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), low); mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */ break;#endif } /* * Check for VC0 active and assert RDY. */ attempts = 10; while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 16))) { if (!(attempts--)) { printf("PCIE%d: VC0 not active\n", port); return -1; } mdelay(1000); } SDR_WRITE(SDRN_PESDR_RCSSET(port), SDR_READ(SDRN_PESDR_RCSSET(port)) | 1 << 20); mdelay(100); return 0;}int ppc4xx_init_pcie_rootport(int port){ return ppc4xx_init_pcie_port(port, 1);}int ppc4xx_init_pcie_endport(int port){ return ppc4xx_init_pcie_port(port, 0);}void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port){ volatile void *mbase = NULL; 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); switch (port) { case 0: mbase = (u32 *)CFG_PCIE0_XCFGBASE; rmbase = (u32 *)CFG_PCIE0_CFGBASE; hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE; break; case 1: mbase = (u32 *)CFG_PCIE1_XCFGBASE; rmbase = (u32 *)CFG_PCIE1_CFGBASE; hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE; break;#if CFG_PCIE_NR_PORTS > 2 case 2: mbase = (u32 *)CFG_PCIE2_XCFGBASE; rmbase = (u32 *)CFG_PCIE2_CFGBASE; hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE; break;#endif } /* * Set bus numbers on our root port */ 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 * 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); debug("PECFG_POM0LA=%08x.%08x\n", in_le32(mbase + PECFG_POM0LAH), in_le32(mbase + PECFG_POM0LAL)); switch (port) { case 0: mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CFG_PCIE_ADDR_HIGH); 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); debug("0:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n", mfdcr(DCRN_PEGPL_OMR1BAH(PCIE0)), mfdcr(DCRN_PEGPL_OMR1BAL(PCIE0)), mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE0)), mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE0))); break; case 1: mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), CFG_PCIE_ADDR_HIGH); 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); debug("1:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n", mfdcr(DCRN_PEGPL_OMR1BAH(PCIE1)), mfdcr(DCRN_PEGPL_OMR1BAL(PCIE1)), mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE1)), mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE1))); break;#if CFG_PCIE_NR_PORTS > 2 case 2: mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CFG_PCIE_ADDR_HIGH); 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); debug("2:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n", mfdcr(DCRN_PEGPL_OMR1BAH(PCIE2)), mfdcr(DCRN_PEGPL_OMR1BAL(PCIE2)), mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE2)), mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE2))); break;#endif } /* 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_PIM01SAH, 0xffff0000); out_le32(mbase + PECFG_PIM01SAL, 0x00000000); out_le32(mbase + PECFG_PIM0LAL, 0); out_le32(mbase + PECFG_PIM0LAH, 0); out_le32(mbase + PECFG_PIM1LAL, 0x00000000); out_le32(mbase + PECFG_PIM1LAH, 0x00000004); 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); /* Set Device and Vendor Id */ out_le16(mbase + 0x200, 0xaaa0 + port); out_le16(mbase + 0x202, 0xbed0 + port); /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ out_le32(mbase + 0x208, 0x06040001); printf("PCIE%d: successfully set as root-complex\n", port);}int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port){ volatile void *mbase = NULL; int attempts = 0; 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;#if defined(CFG_PCIE2_CFGBASE) case 2: mbase = (u32 *)CFG_PCIE2_XCFGBASE; hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE; break;#endif } /* * 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, 0x00001ff8); out_le32(mbase + PECFG_POM0LAL, 0x00001000); switch (port) { case 0: mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CFG_PCIE_ADDR_HIGH); 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), CFG_PCIE_ADDR_HIGH); 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;#if CFG_PCIE_NR_PORTS > 2 case 2: mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CFG_PCIE_ADDR_HIGH); 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;#endif } /* Set up 64MB 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_PIM01SAH, 0xffffffff); out_le32(mbase + PECFG_PIM01SAL, 0xfc000000); /* Setup BAR0 */ out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffff); out_le32(mbase + PECFG_BAR0LMPA, 0xfc000000 | PCI_BASE_ADDRESS_MEM_TYPE_64); /* Disable BAR1 & BAR2 */ out_le32(mbase + PECFG_BAR1MPA, 0); out_le32(mbase + PECFG_BAR2HMPA, 0); out_le32(mbase + PECFG_BAR2LMPA, 0); out_le32(mbase + PECFG_PIM0LAL, U64_TO_U32_LOW(CFG_PCIE_INBOUND_BASE)); out_le32(mbase + PECFG_PIM0LAH, U64_TO_U32_HIGH(CFG_PCIE_INBOUND_BASE)); 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); out_le16(mbase + 0x200, 0xcaad); /* Setting vendor ID */ out_le16(mbase + 0x202, 0xfeed); /* Setting device ID */ /* Set Class Code to Processor/PPC */ out_le32(mbase + 0x208, 0x0b200001); attempts = 10; while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 8))) { if (!(attempts--)) { printf("PCIE%d: BME not active\n", port); return -1; } mdelay(1000); } printf("PCIE%d: successfully set as endpoint\n", port); return 0;}#endif /* CONFIG_440SPE && CONFIG_PCI */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?