📄 yucca.c
字号:
* Different boards may wish to customize the pci controller structure * (add regions, override default access routines, etc) or perform * certain pre-initialization actions. * ************************************************************************/#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)int pci_pre_init(struct pci_controller * hose ){ unsigned long strap; /*-------------------------------------------------------------------+ * The yucca board is always configured as the host & requires the * PCI arbiter to be enabled. *-------------------------------------------------------------------*/ mfsdr(sdr_sdstp1, strap); if( (strap & SDR0_SDSTP1_PAE_MASK) == 0 ) { printf("PCI: SDR0_STRP1[%08lX] - PCI Arbiter disabled.\n",strap); return 0; } return 1;}#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) *//************************************************************************* * pci_target_init * * The bootstrap configuration provides default settings for the pci * inbound map (PIM). But the bootstrap config choices are limited and * may not be sufficient for a given board. * ************************************************************************/#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)void pci_target_init(struct pci_controller * hose ){ DECLARE_GLOBAL_DATA_PTR; /*-------------------------------------------------------------------+ * Disable everything *-------------------------------------------------------------------*/ out32r( PCIX0_PIM0SA, 0 ); /* disable */ out32r( PCIX0_PIM1SA, 0 ); /* disable */ out32r( PCIX0_PIM2SA, 0 ); /* disable */ out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */ /*-------------------------------------------------------------------+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 * strapping options to not support sizes such as 128/256 MB. *-------------------------------------------------------------------*/ out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE ); out32r( PCIX0_PIM0LAH, 0 ); out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 ); out32r( PCIX0_BAR0, 0 ); /*-------------------------------------------------------------------+ * Program the board's subsystem id/vendor id *-------------------------------------------------------------------*/ out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID ); out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID ); out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY );}#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */#if defined(CONFIG_PCI)/************************************************************************* * is_pci_host * * This routine is called to determine if a pci scan should be * performed. With various hardware environments (especially cPCI and * PPMC) it's insufficient to depend on the state of the arbiter enable * bit in the strap register, or generic host/adapter assumptions. * * Rather than hard-code a bad assumption in the general 440 code, the * 440 pci code requires the board to decide at runtime. * * Return 0 for adapter mode, non-zero for host (monarch) mode. * * ************************************************************************/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));}/* * For the given slot, set endpoint mode, send power to the slot, * turn on the green LED and turn off the yellow LED, enable the clock * .In end point mode reset bit is read only. */void yucca_setup_pcie_fpga_endpoint(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, ~(rootpoint | reset_off) & (endpoint | 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;#ifdef PCIE_ENDPOINT yucca_setup_pcie_fpga_endpoint(i); if (ppc440spe_init_pcie_endport(i)) {#else yucca_setup_pcie_fpga_rootpoint(i); if (ppc440spe_init_pcie_rootport(i)) {#endif 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);#ifdef PCIE_ENDPOINT ppc440spe_setup_pcie_endpoint(hose, i); /* * Reson for no scanning is endpoint can not generate * upstream configuration accesses. */#else ppc440spe_setup_pcie_rootpoint(hose, i); /* * Config access can only go down stream */ hose->last_busno = pci_hose_scan(hose);#endif }}#endif /* defined(CONFIG_PCI) */int misc_init_f (void){ uint reg;#if defined(CONFIG_STRESS) uint i ; uint disp;#endif out16(FPGA_REG10, (in16(FPGA_REG10) & ~(FPGA_REG10_AUTO_NEG_DIS|FPGA_REG10_RESET_ETH)) | FPGA_REG10_10MHZ_ENABLE | FPGA_REG10_100MHZ_ENABLE | FPGA_REG10_GIGABIT_ENABLE | FPGA_REG10_FULL_DUPLEX ); udelay(10000); /* wait 10ms */ out16(FPGA_REG10, (in16(FPGA_REG10) | FPGA_REG10_RESET_ETH)); /* minimal init for PCIe */ /* pci express 0 Endpoint Mode */ mfsdr(SDR0_PE0DLPSET, reg); reg &= (~0x00400000); mtsdr(SDR0_PE0DLPSET, reg); /* pci express 1 Rootpoint Mode */ mfsdr(SDR0_PE1DLPSET, reg); reg |= 0x00400000; mtsdr(SDR0_PE1DLPSET, reg); /* pci express 2 Rootpoint Mode */ mfsdr(SDR0_PE2DLPSET, reg); reg |= 0x00400000; mtsdr(SDR0_PE2DLPSET, reg); out16(FPGA_REG1C,(in16 (FPGA_REG1C) & ~FPGA_REG1C_PE0_ROOTPOINT & ~FPGA_REG1C_PE1_ENDPOINT & ~FPGA_REG1C_PE2_ENDPOINT));#if defined(CONFIG_STRESS) /* * all this setting done by linux only needed by stress an charac. test * procedure * PCIe 1 Rootpoint PCIe2 Endpoint * PCIe 0 FIR Pre-emphasis Filter Coefficients & Transmit Driver * Power Level */ for (i = 0, disp = 0; i < 8; i++, disp += 3) { mfsdr(SDR0_PE0HSSSET1L0 + disp, reg); reg |= 0x33000000; mtsdr(SDR0_PE0HSSSET1L0 + disp, reg); } /* * PCIe 1 FIR Pre-emphasis Filter Coefficients & Transmit Driver * Power Level */ for (i = 0, disp = 0; i < 4; i++, disp += 3) { mfsdr(SDR0_PE1HSSSET1L0 + disp, reg); reg |= 0x33000000; mtsdr(SDR0_PE1HSSSET1L0 + disp, reg); } /* * PCIE 2 FIR Pre-emphasis Filter Coefficients & Transmit Driver * Power Level */ for (i = 0, disp = 0; i < 4; i++, disp += 3) { mfsdr(SDR0_PE2HSSSET1L0 + disp, reg); reg |= 0x33000000; mtsdr(SDR0_PE2HSSSET1L0 + disp, reg); } reg = 0x21242222; mtsdr(SDR0_PE2UTLSET1, reg); reg = 0x11000000; mtsdr(SDR0_PE2UTLSET2, reg); /* pci express 1 Endpoint Mode */ reg = 0x00004000; mtsdr(SDR0_PE2DLPSET, reg); mtsdr(SDR0_UART1, 0x2080005a); /* patch for TG */#endif return 0;}void fpga_init(void){ /* * by default sdram access is disabled by fpga */ out16(FPGA_REG10, (in16 (FPGA_REG10) | FPGA_REG10_SDRAM_ENABLE | FPGA_REG10_ENABLE_DISPLAY )); return;}#ifdef CONFIG_POST/* * Returns 1 if keys pressed to start the power-on long-running tests * Called from board_init_f(). */int post_hotkeys_pressed(void){ return (ctrlc());}#endif/*---------------------------------------------------------------------------+ | onboard_pci_arbiter_selected => from EPLD +---------------------------------------------------------------------------*/int onboard_pci_arbiter_selected(int core_pci){#if 0 unsigned long onboard_pci_arbiter_sel; onboard_pci_arbiter_sel = in16(FPGA_REG0) & FPGA_REG0_EXT_ARB_SEL_MASK; if (onboard_pci_arbiter_sel == FPGA_REG0_EXT_ARB_SEL_EXTERNAL) return (BOARD_OPTION_SELECTED); else#endif return (BOARD_OPTION_NOT_SELECTED);}/*---------------------------------------------------------------------------+ | ppcMfcpr. +---------------------------------------------------------------------------*/unsigned long ppcMfcpr(unsigned long cpr_reg){ unsigned long msr; unsigned long cpr_cfgaddr_temp; unsigned long cpr_value; msr = (mfmsr () & ~(MSR_EE)); cpr_cfgaddr_temp = mfdcr(CPR0_CFGADDR); mtdcr(CPR0_CFGADDR, cpr_reg); cpr_value = mfdcr(CPR0_CFGDATA); mtdcr(CPR0_CFGADDR, cpr_cfgaddr_temp); mtmsr(msr); return (cpr_value);}/*----------------------------------------------------------------------------+| Indirect Access of the System DCR's (SDR)| ppcMfsdr+----------------------------------------------------------------------------*/unsigned long ppcMfsdr(unsigned long sdr_reg){ unsigned long msr; unsigned long sdr_cfgaddr_temp; unsigned long sdr_value; msr = (mfmsr () & ~(MSR_EE)); sdr_cfgaddr_temp = mfdcr(SDR0_CFGADDR); mtdcr(SDR0_CFGADDR, sdr_reg); sdr_value = mfdcr(SDR0_CFGDATA); mtdcr(SDR0_CFGADDR, sdr_cfgaddr_temp); mtmsr(msr); return (sdr_value);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -