in pci/pcie-octeon.c [1147:1433]
static int __cvmx_pcie_rc_initialize_gen2(int pcie_port)
{
int i;
union cvmx_ciu_soft_prst ciu_soft_prst;
union cvmx_mio_rst_ctlx mio_rst_ctl;
union cvmx_pemx_bar_ctl pemx_bar_ctl;
union cvmx_pemx_ctl_status pemx_ctl_status;
union cvmx_pemx_bist_status pemx_bist_status;
union cvmx_pemx_bist_status2 pemx_bist_status2;
union cvmx_pciercx_cfg032 pciercx_cfg032;
union cvmx_pciercx_cfg515 pciercx_cfg515;
union cvmx_sli_ctl_portx sli_ctl_portx;
union cvmx_sli_mem_access_ctl sli_mem_access_ctl;
union cvmx_sli_mem_access_subidx mem_access_subid;
union cvmx_sriox_status_reg sriox_status_reg;
union cvmx_pemx_bar1_indexx bar1_index;
if (octeon_has_feature(OCTEON_FEATURE_SRIO)) {
/* Make sure this interface isn't SRIO */
if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
/*
* The CN66XX requires reading the
* MIO_QLMX_CFG register to figure out the
* port type.
*/
union cvmx_mio_qlmx_cfg qlmx_cfg;
qlmx_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(pcie_port));
if (qlmx_cfg.s.qlm_spd == 15) {
pr_notice("PCIe: Port %d is disabled, skipping.\n", pcie_port);
return -1;
}
switch (qlmx_cfg.s.qlm_spd) {
case 0x1: /* SRIO 1x4 short */
case 0x3: /* SRIO 1x4 long */
case 0x4: /* SRIO 2x2 short */
case 0x6: /* SRIO 2x2 long */
pr_notice("PCIe: Port %d is SRIO, skipping.\n", pcie_port);
return -1;
case 0x9: /* SGMII */
pr_notice("PCIe: Port %d is SGMII, skipping.\n", pcie_port);
return -1;
case 0xb: /* XAUI */
pr_notice("PCIe: Port %d is XAUI, skipping.\n", pcie_port);
return -1;
case 0x0: /* PCIE gen2 */
case 0x8: /* PCIE gen2 (alias) */
case 0x2: /* PCIE gen1 */
case 0xa: /* PCIE gen1 (alias) */
break;
default:
pr_notice("PCIe: Port %d is unknown, skipping.\n", pcie_port);
return -1;
}
} else {
sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(pcie_port));
if (sriox_status_reg.s.srio) {
pr_notice("PCIe: Port %d is SRIO, skipping.\n", pcie_port);
return -1;
}
}
}
#if 0
/* This code is so that the PCIe analyzer is able to see 63XX traffic */
pr_notice("PCIE : init for pcie analyzer.\n");
cvmx_helper_qlm_jtag_init();
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
cvmx_helper_qlm_jtag_update(pcie_port);
#endif
/* Make sure we aren't trying to setup a target mode interface in host mode */
mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(pcie_port));
if (!mio_rst_ctl.s.host_mode) {
pr_notice("PCIe: Port %d in endpoint mode.\n", pcie_port);
return -1;
}
/* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be programmed */
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0)) {
if (pcie_port) {
union cvmx_ciu_qlm ciu_qlm;
ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM1);
ciu_qlm.s.txbypass = 1;
ciu_qlm.s.txdeemph = 5;
ciu_qlm.s.txmargin = 0x17;
cvmx_write_csr(CVMX_CIU_QLM1, ciu_qlm.u64);
} else {
union cvmx_ciu_qlm ciu_qlm;
ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM0);
ciu_qlm.s.txbypass = 1;
ciu_qlm.s.txdeemph = 5;
ciu_qlm.s.txmargin = 0x17;
cvmx_write_csr(CVMX_CIU_QLM0, ciu_qlm.u64);
}
}
/* Bring the PCIe out of reset */
if (pcie_port)
ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
else
ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
/*
* After a chip reset the PCIe will also be in reset. If it
* isn't, most likely someone is trying to init it again
* without a proper PCIe reset
*/
if (ciu_soft_prst.s.soft_prst == 0) {
/* Reset the port */
ciu_soft_prst.s.soft_prst = 1;
if (pcie_port)
cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
else
cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
/* Wait until pcie resets the ports. */
udelay(2000);
}
if (pcie_port) {
ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
ciu_soft_prst.s.soft_prst = 0;
cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
} else {
ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
ciu_soft_prst.s.soft_prst = 0;
cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
}
/* Wait for PCIe reset to complete */
udelay(1000);
/*
* Check and make sure PCIe came out of reset. If it doesn't
* the board probably hasn't wired the clocks up and the
* interface should be skipped.
*/
if (CVMX_WAIT_FOR_FIELD64(CVMX_MIO_RST_CTLX(pcie_port), union cvmx_mio_rst_ctlx, rst_done, ==, 1, 10000)) {
pr_notice("PCIe: Port %d stuck in reset, skipping.\n", pcie_port);
return -1;
}
/* Check BIST status */
pemx_bist_status.u64 = cvmx_read_csr(CVMX_PEMX_BIST_STATUS(pcie_port));
if (pemx_bist_status.u64)
pr_notice("PCIe: BIST FAILED for port %d (0x%016llx)\n", pcie_port, CAST64(pemx_bist_status.u64));
pemx_bist_status2.u64 = cvmx_read_csr(CVMX_PEMX_BIST_STATUS2(pcie_port));
/* Errata PCIE-14766 may cause the lower 6 bits to be randomly set on CN63XXp1 */
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
pemx_bist_status2.u64 &= ~0x3full;
if (pemx_bist_status2.u64)
pr_notice("PCIe: BIST2 FAILED for port %d (0x%016llx)\n", pcie_port, CAST64(pemx_bist_status2.u64));
/* Initialize the config space CSRs */
__cvmx_pcie_rc_initialize_config_space(pcie_port);
/* Enable gen2 speed selection */
pciercx_cfg515.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG515(pcie_port));
pciercx_cfg515.s.dsc = 1;
cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG515(pcie_port), pciercx_cfg515.u32);
/* Bring the link up */
if (__cvmx_pcie_rc_initialize_link_gen2(pcie_port)) {
/*
* Some gen1 devices don't handle the gen 2 training
* correctly. Disable gen2 and try again with only
* gen1
*/
union cvmx_pciercx_cfg031 pciercx_cfg031;
pciercx_cfg031.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG031(pcie_port));
pciercx_cfg031.s.mls = 1;
cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG031(pcie_port), pciercx_cfg031.u32);
if (__cvmx_pcie_rc_initialize_link_gen2(pcie_port)) {
pr_notice("PCIe: Link timeout on port %d, probably the slot is empty\n", pcie_port);
return -1;
}
}
/* Store merge control (SLI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
sli_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL);
sli_mem_access_ctl.s.max_word = 0; /* Allow 16 words to combine */
sli_mem_access_ctl.s.timer = 127; /* Wait up to 127 cycles for more data */
cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL, sli_mem_access_ctl.u64);
/* Setup Mem access SubDIDs */
mem_access_subid.u64 = 0;
mem_access_subid.s.port = pcie_port; /* Port the request is sent to. */
mem_access_subid.s.nmerge = 0; /* Allow merging as it works on CN6XXX. */
mem_access_subid.s.esr = 1; /* Endian-swap for Reads. */
mem_access_subid.s.esw = 1; /* Endian-swap for Writes. */
mem_access_subid.s.wtype = 0; /* "No snoop" and "Relaxed ordering" are not set */
mem_access_subid.s.rtype = 0; /* "No snoop" and "Relaxed ordering" are not set */
/* PCIe Adddress Bits <63:34>. */
if (OCTEON_IS_MODEL(OCTEON_CN68XX))
mem_access_subid.cn68xx.ba = 0;
else
mem_access_subid.s.ba = 0;
/*
* Setup mem access 12-15 for port 0, 16-19 for port 1,
* supplying 36 bits of address space.
*/
for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(i), mem_access_subid.u64);
/* Set each SUBID to extend the addressable range */
__cvmx_increment_ba(&mem_access_subid);
}
/*
* Disable the peer to peer forwarding register. This must be
* setup by the OS after it enumerates the bus and assigns
* addresses to the PCIe busses.
*/
for (i = 0; i < 4; i++) {
cvmx_write_csr(CVMX_PEMX_P2P_BARX_START(i, pcie_port), -1);
cvmx_write_csr(CVMX_PEMX_P2P_BARX_END(i, pcie_port), -1);
}
/* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
cvmx_write_csr(CVMX_PEMX_P2N_BAR0_START(pcie_port), 0);
/*
* Set Octeon's BAR2 to decode 0-2^41. Bar0 and Bar1 take
* precedence where they overlap. It also overlaps with the
* device addresses, so make sure the peer to peer forwarding
* is set right.
*/
cvmx_write_csr(CVMX_PEMX_P2N_BAR2_START(pcie_port), 0);
/*
* Setup BAR2 attributes
* Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM])
* - PTLP_RO,CTLP_RO should normally be set (except for debug).
* - WAIT_COM=0 will likely work for all applications.
* Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM])
*/
pemx_bar_ctl.u64 = cvmx_read_csr(CVMX_PEMX_BAR_CTL(pcie_port));
pemx_bar_ctl.s.bar1_siz = 3; /* 256MB BAR1*/
pemx_bar_ctl.s.bar2_enb = 1;
pemx_bar_ctl.s.bar2_esx = 1;
pemx_bar_ctl.s.bar2_cax = 0;
cvmx_write_csr(CVMX_PEMX_BAR_CTL(pcie_port), pemx_bar_ctl.u64);
sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(pcie_port));
sli_ctl_portx.s.ptlp_ro = 1;
sli_ctl_portx.s.ctlp_ro = 1;
sli_ctl_portx.s.wait_com = 0;
sli_ctl_portx.s.waitl_com = 0;
cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(pcie_port), sli_ctl_portx.u64);
/* BAR1 follows BAR2 */
cvmx_write_csr(CVMX_PEMX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
bar1_index.u64 = 0;
bar1_index.s.addr_idx = (CVMX_PCIE_BAR1_PHYS_BASE >> 22);
bar1_index.s.ca = 1; /* Not Cached */
bar1_index.s.end_swp = 1; /* Endian Swap mode */
bar1_index.s.addr_v = 1; /* Valid entry */
for (i = 0; i < 16; i++) {
cvmx_write_csr(CVMX_PEMX_BAR1_INDEXX(i, pcie_port), bar1_index.u64);
/* 256MB / 16 >> 22 == 4 */
bar1_index.s.addr_idx += (((1ull << 28) / 16ull) >> 22);
}
/*
* Allow config retries for 250ms. Count is based off the 5Ghz
* SERDES clock.
*/
pemx_ctl_status.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(pcie_port));
pemx_ctl_status.s.cfg_rtry = 250 * 5000000 / 0x10000;
cvmx_write_csr(CVMX_PEMX_CTL_STATUS(pcie_port), pemx_ctl_status.u64);
/* Display the link status */
pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
pr_notice("PCIe: Port %d link active, %d lanes, speed gen%d\n", pcie_port, pciercx_cfg032.s.nlw, pciercx_cfg032.s.ls);
return 0;
}