int pci_init_board (void) { #ifdef CONFIG_ATH_EMULATION printf("--- Skipping %s for emulation\n", __func__); #else uint32_t cmd; // common for rc1 and rc2 ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MAX_ADDRESS, PCIE_PLL_DITHER_DIV_MAX_EN_DITHER_SET(1) | PCIE_PLL_DITHER_DIV_MAX_USE_MAX_SET(1) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_INT_SET(0x14) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_FRAC_SET(0x3ff)); ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MIN_ADDRESS, PCIE_PLL_DITHER_DIV_MIN_DIV_MIN_INT_SET(0x14)); ath_reg_wr_nf(PCIE_PLL_CONFIG_ADDRESS, PCIE_PLL_CONFIG_REFDIV_SET(1) | PCIE_PLL_CONFIG_BYPASS_SET(1) | PCIE_PLL_CONFIG_PLLPWD_SET(1)); udelay(10000); ath_reg_rmw_clear(PCIE_PLL_CONFIG_ADDRESS, PCIE_PLL_CONFIG_PLLPWD_SET(1)); udelay(1000); ath_reg_rmw_clear(PCIE_PLL_CONFIG_ADDRESS, PCIE_PLL_CONFIG_BYPASS_SET(1)); udelay(1000); if (!(ath_reg_rd(RST_BOOTSTRAP_ADDRESS) & RST_BOOTSTRAP_PCIE_RC_EP_SELECT_MASK)) { pci_rc2_init_board(); return 0; } ath_reg_rmw_set(RST_RESET_ADDRESS, RST_RESET_PCIE_PHY_RESET_SET(1)); udelay(10000); ath_reg_rmw_set(RST_RESET_ADDRESS, RST_RESET_PCIE_RESET_SET(1)); udelay(10000); ath_reg_rmw_clear(RST_MISC2_ADDRESS, RST_MISC2_PERSTN_RCPHY_SET(1)); udelay(10000); ath_reg_wr_nf(PCIE_RESET_ADDRESS, 0); // Put endpoint in reset udelay(100000); ath_reg_rmw_set(RST_MISC2_ADDRESS, RST_MISC2_PERSTN_RCPHY_SET(1)); udelay(10000); ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_PCIE_PHY_RESET_SET(1)); udelay(10000); ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_PCIE_RESET_SET(1)); udelay(10000); ath_reg_wr_nf(PCIE_APP_ADDRESS, PCIE_APP_PCIE_BAR_MSN_SET(1) | PCIE_APP_CFG_BE_SET(0xf) | PCIE_APP_SLV_RESP_ERR_MAP_SET(0x3f) | PCIE_APP_LTSSM_ENABLE_SET(1)); cmd = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; ath_local_write_config(PCI_COMMAND, 4, cmd); ath_local_write_config(0x20, 4, 0x1ff01000); ath_local_write_config(0x24, 4, 0x1ff01000); ath_reg_wr_nf(PCIE_RESET_ADDRESS, 4); // Pull endpoint out of reset udelay(100000); /* training reset */ ath_reg_rmw_set(PCIE_APP_ADDRESS, PCIE_APP_INIT_RST_SET(1)); udelay(1000); /* * Check if the WLAN PCI-E H/W is present, If the * WLAN H/W is not present, skip the PCI platform * initialization code and return */ if (((ath_reg_rd(PCIE_RESET_ADDRESS)) & 0x1) == 0x0) { printf("*** Warning *** : PCIe WLAN Module not found !!!\n"); } pci_rc2_init_board(); #endif /* CONFIG_ATH_EMULATION */ return 0; }
PCI_INIT_RET_TYPE pci_init_board (void) { #ifdef CONFIG_ATH_EMULATION prmsg("--- Skipping %s for emulation\n", __func__); #else uint32_t cmd; if (is_drqfn() && !is_qca953x()) { /* * Dont enable PCIe in DRQFN package as it has some issues * related to PCIe */ PCI_INIT_RETURN; } #if defined(CONFIG_MACH_QCA953x) if (ath_reg_rd(RST_BOOTSTRAP_ADDRESS) & RST_BOOTSTRAP_TESTROM_ENABLE_MASK) { ath_reg_rmw_clear(RST_MISC2_ADDRESS, RST_MISC2_PERSTN_RCPHY_SET(1)); ath_reg_wr(PCIE_PHY_REG_1_ADDRESS, PCIE_PHY_REG_1_RESET_1); ath_reg_wr(PCIE_PHY_REG_3_ADDRESS, PCIE_PHY_REG_3_RESET_1); ath_reg_rmw_set(PCIE_PWR_MGMT_ADDRESS, PCIE_PWR_MGMT_ASSERT_CLKREQN_SET(1)); ath_reg_rmw_set(PCIE_PLL_CONFIG_ADDRESS, PCIE_PLL_CONFIG_PLLPWD_SET(1)); ath_reg_rmw_set(RST_RESET_ADDRESS, RST_RESET_PCIE_RESET_SET(1)); ath_reg_rmw_set(RST_RESET_ADDRESS, RST_RESET_PCIE_PHY_RESET_SET(1)); ath_reg_rmw_clear(RST_CLKGAT_EN_ADDRESS, RST_CLKGAT_EN_PCIE_RC_SET(1)); PCI_INIT_RETURN; } else { /* Honeybee -The PCIe reference clock frequency is being changed to vary from 99.968MHz to 99.999MHz using SS modulation */ ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MAX_ADDRESS, PCIE_PLL_DITHER_DIV_MAX_EN_DITHER_SET(0x1) | PCIE_PLL_DITHER_DIV_MAX_USE_MAX_SET(0x1) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_INT_SET(0x17) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_FRAC_SET(0x3fff)); ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MIN_ADDRESS, PCIE_PLL_DITHER_DIV_MIN_DIV_MIN_FRAC_SET(0x3f84)| PCIE_PLL_DITHER_DIV_MIN_DIV_MIN_INT_SET(0x17)); } #else #if defined(CONFIG_MACH_QCA956x) ath_reg_rmw_set(PCIE_PHY_REG_1_ADDRESS, PCIE_PHY_REG_1_S_SET(PCIE_PHY_REG_1_S_RESET)); ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MAX_ADDRESS, PCIE_PLL_DITHER_DIV_MAX_USE_MAX_SET(0x1) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_INT_SET(0x17) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_FRAC_SET(0x3fff)); ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MIN_ADDRESS, PCIE_PLL_DITHER_DIV_MIN_DIV_MIN_FRAC_SET(0x3f84) | PCIE_PLL_DITHER_DIV_MIN_DIV_MIN_INT_SET(0x17)); #else // common for rc1 and rc2 ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MAX_ADDRESS, PCIE_PLL_DITHER_DIV_MAX_EN_DITHER_SET(0x1) | PCIE_PLL_DITHER_DIV_MAX_USE_MAX_SET(0x1) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_INT_SET(0x14) | PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_FRAC_SET(0x3ff)); ath_reg_wr_nf(PCIE_PLL_DITHER_DIV_MIN_ADDRESS, PCIE_PLL_DITHER_DIV_MIN_DIV_MIN_INT_SET(0x14)); #endif #endif ath_reg_wr_nf(PCIE_PLL_CONFIG_ADDRESS, PCIE_PLL_CONFIG_REFDIV_SET(1) | PCIE_PLL_CONFIG_BYPASS_SET(1) | PCIE_PLL_CONFIG_PLLPWD_SET(1)); udelay(10000); ath_reg_rmw_clear(PCIE_PLL_CONFIG_ADDRESS, PCIE_PLL_CONFIG_PLLPWD_SET(1)); udelay(1000); ath_reg_rmw_clear(PCIE_PLL_CONFIG_ADDRESS, PCIE_PLL_CONFIG_BYPASS_SET(1)); udelay(1000); #if !defined(CONFIG_MACH_QCA956x) #ifdef PCIE2_APP_ADDRESS if (!(ath_reg_rd(RST_BOOTSTRAP_ADDRESS) & RST_BOOTSTRAP_PCIE_RC_EP_SELECT_MASK)) { pci_rc2_init_board(); return; } #endif ath_reg_rmw_set(RST_RESET_ADDRESS, RST_RESET_PCIE_PHY_RESET_SET(1)); udelay(10000); ath_reg_rmw_set(RST_RESET_ADDRESS, RST_RESET_PCIE_RESET_SET(1)); udelay(10000); #ifdef PCIE2_APP_ADDRESS ath_reg_rmw_clear(RST_MISC2_ADDRESS, RST_MISC2_PERSTN_RCPHY_SET(1)); udelay(10000); #endif ath_reg_wr_nf(PCIE_RESET_ADDRESS, 0); // Put endpoint in reset udelay(100000); #ifdef PCIE2_APP_ADDRESS ath_reg_rmw_set(RST_MISC2_ADDRESS, RST_MISC2_PERSTN_RCPHY_SET(1)); udelay(10000); #endif ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_PCIE_PHY_RESET_SET(1)); udelay(10000); ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_PCIE_RESET_SET(1)); udelay(10000); ath_reg_wr_nf(PCIE_APP_ADDRESS, PCIE_APP_PCIE_BAR_MSN_SET(1) | PCIE_APP_CFG_BE_SET(0xf) | PCIE_APP_SLV_RESP_ERR_MAP_SET(0x3f) | PCIE_APP_LTSSM_ENABLE_SET(1)); cmd = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; ath_local_write_config(PCI_COMMAND, 4, cmd); ath_local_write_config(0x20, 4, 0x1ff01000); ath_local_write_config(0x24, 4, 0x1ff01000); ath_reg_wr_nf(PCIE_RESET_ADDRESS, 4); // Pull endpoint out of reset udelay(100000); /* * Check if the WLAN PCI-E H/W is present, If the * WLAN H/W is not present, skip the PCI platform * initialization code and return */ if (((ath_reg_rd(PCIE_RESET_ADDRESS)) & 0x1) == 0x0) { prmsg("*** Warning *** : PCIe WLAN Module not found !!!\n"); } #endif #ifdef PCIE2_APP_ADDRESS pci_rc2_init_board(); #endif #ifndef COMPRESSED_UBOOT /* * Now, configure for u-boot tools */ hose.first_busno = 0; hose.last_busno = 0xff; /* System space */ pci_set_region( &hose.regions[0], 0x80000000, 0x00000000, 32 * 1024 * 1024, PCI_REGION_MEM | PCI_REGION_MEMORY); /* PCI memory space */ pci_set_region( &hose.regions[1], 0x10000000, 0x10000000, 128 * 1024 * 1024, PCI_REGION_MEM); hose.region_count = 2; pci_register_hose(&hose); pci_set_ops( &hose, pci_hose_read_config_byte_via_dword, pci_hose_read_config_word_via_dword, ath_pci_read_config, pci_hose_write_config_byte_via_dword, pci_hose_write_config_word_via_dword, ath_pci_write_config); #endif plat_dev_init(); #endif /* CONFIG_ATH_EMULATION */ PCI_INIT_RETURN; }
/* * We want a 1:1 mapping between PCI and DDR for inbound and outbound. * The PCI<---AHB decoding works as follows: * * 8 registers in the DDR unit provide software configurable 32 bit offsets * for each of the eight 16MB PCI windows in the 128MB. The offsets will be * added to any address in the 16MB segment before being sent to the PCI unit. * * Essentially for any AHB address generated by the CPU, * 1. the MSB four bits are stripped off, [31:28], * 2. Bit 27 is used to decide between the lower 128Mb (PCI) or the rest of * the AHB space * 3. Bits 26:24 are used to access one of the 8 window registers and are * masked off. * 4. If it is a PCI address, then the WINDOW offset in the WINDOW register * corresponding to the next 3 bits (bit 26:24) is ADDED to the address, * to generate the address to PCI unit. * * eg. CPU address = 0x100000ff * window 0 offset = 0x10000000 * This points to lowermost 16MB window in PCI space. * So the resulting address would be 0x000000ff+0x10000000 * = 0x100000ff * * eg2. CPU address = 0x120000ff * WINDOW 2 offset = 0x12000000 * resulting address would be 0x000000ff+0x12000000 * = 0x120000ff * * There is no translation for inbound access (PCI device as a master) */ static int __init ath_pcibios_init(void) { uint32_t cmd; #ifdef CONFIG_MACH_AR934x if (is_ar9341()) { return 0; } #endif /* * Check if the WLAN PCI-E H/W is present, If the * WLAN H/W is not present, skip the PCI * initialization code and just return. */ if (((ath_reg_rd(ATH_PCI_LCL_RESET)) & 0x1) == 0x0) { printk("***** Warning *****: PCIe WLAN H/W not found !!!\n"); return 0; } if ((is_ar7241() || is_ar7242())) ath_reg_wr(ATH_PCI_LCL_APP, (ath_reg_rd(ATH_PCI_LCL_APP) | (0x1 << 16))); #ifdef CONFIG_PERICOM ath_reg_wr(0xb80f0000, 0x0ffc1); // Address Translation disabled ath_reg_wr(0x180f0040, 0); // Enable Type 0 ath_reg_rd(0x14000000); // Reading the Config space of Upstream port of Switch ath_reg_wr(0x1400003c, 0x400000); // Assert Reset to the Downstream ports ath_reg_wr(0x1400003c, 0x0); // Deassert Reset ath_reg_wr(0x14000004, 0x106); ath_reg_wr(0x14000018, 0x070504); // Program the Primary Bus, Sec Bus and Subordinate Bus ath_reg_wr(0x14000020, 0x1ff01000); // Memory Base and Limit ath_reg_wr(0x14000024, 0x1ff01000); // Prefetch Memory Base and Limit ath_reg_wr(0x140000b4, 0x0200010a); // Enable Round robin priority on the ports ath_reg_wr(0x180f0040, 1); // Enable Type 1 // Configure the Pericom Switch's Downstream Port0 using Type1 Configuration ath_reg_rd(0x15080000); // Reading the Config space of Downstream port0 of Switch ath_reg_wr(0x15080004, 0x106); // Command register ath_reg_wr(0x15080018, 0x060605); // Program the pri bus, sec bus and subordinate bus ath_reg_wr(0x15080020, 0x11f01000); // Memory base and limit ath_reg_wr(0x15080024, 0x11f01000); // Configure the Pericom Switch's Downstream Port1 using Type1 Configuration ath_reg_rd(0x15100000); // Reading the Config space of Downstream port1 of Switch ath_reg_wr(0x15100004, 0x106); ath_reg_wr(0x15100018, 0x070705); ath_reg_wr(0x15100020, 0x13f01200); ath_reg_wr(0x15100024, 0x13f01200); ath_reg_wr(0xb80f0000, 0x1ffc1); // Address Translation enabled #endif /* CONFIG_PERICOM */ printk("PCI init:%s\n", __func__); #ifndef CONFIG_PCI_INIT_IN_MONITOR cmd = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; printk("%s(%d): PCI CMD write: 0x%x\n", __func__, __LINE__, cmd); ath_local_write_config(PCI_COMMAND, 4, cmd); /* * clear any lingering errors and register core error IRQ */ #if 0 ath_check_error(0); #endif # if !defined(CONFIG_PERICOM) ath_pci_ops.write(NULL, 0, PCI_COMMAND, 4, cmd); # endif /* CONFIG_PERICOM */ #endif #ifdef CONFIG_PERICOM #define ath_udelay(us) do { \ extern uint32_t ath_cpu_freq; \ volatile register int N = (ath_cpu_freq / 1000000) * (us); \ while (--N > 0); \ } while(0) /* For Pericom -> Merlin link availability */ ath_udelay(600); cmd = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; printk("%s: cmd = 0x%x\n", __func__, cmd); ath_pci_ops.write(2, 0, PCI_COMMAND, 4, cmd); ath_pci_ops.write(1, 0, PCI_COMMAND, 4, cmd); register_pci_controller(&ath_pci_controller1); register_pci_controller(&ath_pci_controller2); #else #if ATH_LOW_POWER_ENABLE // Enable L0 & L1 ASPM Support ath_reg_rmw_set(ATH_PCIE_RC_ASPM_SUPPORT, ATH_PCIE_RC_SUPP_L0 | ATH_PCIE_RC_SUPP_L1); // Enable L0 & L1 ath_reg_rmw_set(ATH_PCIE_RC_ASPM_ENABLE, ATH_PCIE_RC_EN_L0 | ATH_PCIE_RC_EN_L1); #endif register_pci_controller(&ath_pci_controller); #endif /* CONFIG_PERICOM */ return 0; }