From: John Jacques <john.jacq...@intel.com> Signed-off-by: John Jacques <john.jacq...@intel.com> --- drivers/misc/axxia-pei.c | 830 ++++++++++++++++++++++++++---------------- drivers/pci/host/pcie-axxia.c | 221 ++++++----- include/linux/axxia-pei.h | 1 + 3 files changed, 638 insertions(+), 414 deletions(-)
diff --git a/drivers/misc/axxia-pei.c b/drivers/misc/axxia-pei.c index e78cf60..bb40dd0 100644 --- a/drivers/misc/axxia-pei.c +++ b/drivers/misc/axxia-pei.c @@ -77,97 +77,97 @@ enum Dir { }; /****************************************************************************** -* PCIe/SRIO/SATA parameters -* Supported configs: -* PEI0x8 -* PEI0x4_PEI1x4 -* PEI0x4_PEI1x2_SATA0x1_SATA1x1 -* PEI0x2_PEI2x2_PEI1x2_SATA0x1_SATA1x1 -* PEI0x2_SRIO0x2_PEI1x4 -* PEI0x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 -* PEI0x2_SRIO0x2_PEI1x2_PEI2x2 -* SRIO1x2_SRIO0x2_PEI1x4 -* SRIO1x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 -* SRIO1x2_SRIO0x2_PEI1x2_PEI2x2 -* -* Bits 25:22 :Supported configs: -* 0x0 - PEI0x8 (HSS10-ch0,1;HSS11-ch0,1;HSS12-ch0,1;HSS13-ch0,1) -* 0x1 - PEI0x4 (HSS10-ch0,1; HSS11-ch0,1) -* PEI1x4 (HSS12-ch0,1; HSS12-ch0,1) -* 0x2 - PEI0x4 (HSS10-ch0,1; HSS11-ch0,1) -* PEI1x2 (HSS12-ch0,1) -* SATA0x1 (HSS13-ch0) -* SATA1x1 (HSS13-ch1) -* 0x3 - PEI0x2 (HSS10-ch0,1) -* PEI2x2 (HSS11-ch0,1) -* PEI1x2 (HSS12-ch0,1) -* SATA0x1 (HSS13-ch0) -* SATA1x1 (HSS13-ch1) -* 0x4 - PEI0x2 (HSS10-ch0,1) -* SRIO0x2 (HSS11-ch0,1) -* PEI1x4 (HSS12-ch0,1; HSS13-ch0,1) -* 0x5 - PEI0x2 (HSS10-ch0,1) -* SRIO0x2 (HSS11-ch0,1) -* PEI1x2 (HSS12-ch0,1) -* SATA0x1 (HSS13-ch0) -* SATA1x1 (HSS13-ch1) -* 0x6 - PEI0x2 (HSS10-ch0,1) -* SRIO0x2 (HSS11-ch0,1) -* PEI1x2 (HSS12-ch0,1) -* PEI2x2 (HSS13-ch0,1) -* 0x7 - SRIO1x2 (HSS10-ch0,1) -* SRIO0x2 (HSS11-ch0,1) -* PEI1x4 (HSS12-ch0,1; HSS13-ch0,1) -* 0x8 - SRIO1x2 (HSS10-ch0,1) -* SRIO0x2 (HSS11-ch0,1) -* PEI1x2 (HSS12-ch0,1) -* SATA0x1 (HSS13-ch0) -* SATA1x1 (HSS13-ch1) -* 0x9 - SRIO1x2 (HSS10-ch0,1) -* SRIO0x2 (HSS11-ch0,1) -* PEI1x2 (HSS12-ch0,1) -* PEI2x2 (HSS13-ch0,1) -* Bits 21:20: SATA1 speed selection -* 0x0 - indicates 1.5 Gbps -* 0x1 - indicates 3 Gbps -* 0x2 - indicates 6 Gbps -* Bits 19:18: SATA0 speed selection -* 0x0 - indicates 1.5 Gbps -* 0x1 - indicates 3 Gbps -* 0x2 - indicates 6 Gbps -* Bits 17:15 : SRIO1 speed selection -* 0x0 - indicates 1.25 Gbps -* 0x1 - indicates 2.5 Gbps -* 0x2 - indicates 3.125 Gbps -* 0x3 - indicates 5 Gbps -* 0x4 - indicates 6.25 Gbps -* Bits 14:12 : SRIO0 speed selection -* 0x0 - indicates 1.25 Gbps -* 0x1 - indicates 2.5 Gbps -* 0x2 - indicates 3.125 Gbps -* 0x3 - indicates 5 Gbps -* 0x4 - indicates 6.25 Gbps -* Bits 11:10 : If SRIO1 is configured, -* 0x0 - indicates Host with ID 0, -* 0x1 - indicates Host with ID 1, -* 0x2 - indicates not a host (agent) -* 0x3 - RESERVED -* Bits 9:8 : If SRIO0 is configured, -* 0x0 - indicates Host with ID 0, -* 0x1 - indicates Host with ID 1, -* 0x2 - indicates not a host (agent) -* 0x3 - RESERVED -* Bit 7: If PEI0 is configured, -* 0x0 - indicates END_POINT -* 0x1 - indicates ROOT_COMPLEX -* Bit 6: SATA1 enabled -* Bit 5: SATA0 enabled -* Bit 4: SRIO1 enabled -* Bit 3: SRIO0 enabled -* Bit 2: PEI2 enabled -* Bit 1: PEI1 enabled -* Bit 0: PEI0 enabled -*******************************************************************************/ + * PCIe/SRIO/SATA parameters + * Supported configs: + * PEI0x8 + * PEI0x4_PEI1x4 + * PEI0x4_PEI1x2_SATA0x1_SATA1x1 + * PEI0x2_PEI2x2_PEI1x2_SATA0x1_SATA1x1 + * PEI0x2_SRIO0x2_PEI1x4 + * PEI0x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 + * PEI0x2_SRIO0x2_PEI1x2_PEI2x2 + * SRIO1x2_SRIO0x2_PEI1x4 + * SRIO1x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 + * SRIO1x2_SRIO0x2_PEI1x2_PEI2x2 + * + * Bits 25:22 :Supported configs: + * 0x0 - PEI0x8 (HSS10-ch0,1;HSS11-ch0,1;HSS12-ch0,1;HSS13-ch0,1) + * 0x1 - PEI0x4 (HSS10-ch0,1; HSS11-ch0,1) + * PEI1x4 (HSS12-ch0,1; HSS12-ch0,1) + * 0x2 - PEI0x4 (HSS10-ch0,1; HSS11-ch0,1) + * PEI1x2 (HSS12-ch0,1) + * SATA0x1 (HSS13-ch0) + * SATA1x1 (HSS13-ch1) + * 0x3 - PEI0x2 (HSS10-ch0,1) + * PEI2x2 (HSS11-ch0,1) + * PEI1x2 (HSS12-ch0,1) + * SATA0x1 (HSS13-ch0) + * SATA1x1 (HSS13-ch1) + * 0x4 - PEI0x2 (HSS10-ch0,1) + * SRIO0x2 (HSS11-ch0,1) + * PEI1x4 (HSS12-ch0,1; HSS13-ch0,1) + * 0x5 - PEI0x2 (HSS10-ch0,1) + * SRIO0x2 (HSS11-ch0,1) + * PEI1x2 (HSS12-ch0,1) + * SATA0x1 (HSS13-ch0) + * SATA1x1 (HSS13-ch1) + * 0x6 - PEI0x2 (HSS10-ch0,1) + * SRIO0x2 (HSS11-ch0,1) + * PEI1x2 (HSS12-ch0,1) + * PEI2x2 (HSS13-ch0,1) + * 0x7 - SRIO1x2 (HSS10-ch0,1) + * SRIO0x2 (HSS11-ch0,1) + * PEI1x4 (HSS12-ch0,1; HSS13-ch0,1) + * 0x8 - SRIO1x2 (HSS10-ch0,1) + * SRIO0x2 (HSS11-ch0,1) + * PEI1x2 (HSS12-ch0,1) + * SATA0x1 (HSS13-ch0) + * SATA1x1 (HSS13-ch1) + * 0x9 - SRIO1x2 (HSS10-ch0,1) + * SRIO0x2 (HSS11-ch0,1) + * PEI1x2 (HSS12-ch0,1) + * PEI2x2 (HSS13-ch0,1) + * Bits 21:20: SATA1 speed selection + * 0x0 - indicates 1.5 Gbps + * 0x1 - indicates 3 Gbps + * 0x2 - indicates 6 Gbps + * Bits 19:18: SATA0 speed selection + * 0x0 - indicates 1.5 Gbps + * 0x1 - indicates 3 Gbps + * 0x2 - indicates 6 Gbps + * Bits 17:15 : SRIO1 speed selection + * 0x0 - indicates 1.25 Gbps + * 0x1 - indicates 2.5 Gbps + * 0x2 - indicates 3.125 Gbps + * 0x3 - indicates 5 Gbps + * 0x4 - indicates 6.25 Gbps + * Bits 14:12 : SRIO0 speed selection + * 0x0 - indicates 1.25 Gbps + * 0x1 - indicates 2.5 Gbps + * 0x2 - indicates 3.125 Gbps + * 0x3 - indicates 5 Gbps + * 0x4 - indicates 6.25 Gbps + * Bits 11:10 : If SRIO1 is configured, + * 0x0 - indicates Host with ID 0, + * 0x1 - indicates Host with ID 1, + * 0x2 - indicates not a host (agent) + * 0x3 - RESERVED + * Bits 9:8 : If SRIO0 is configured, + * 0x0 - indicates Host with ID 0, + * 0x1 - indicates Host with ID 1, + * 0x2 - indicates not a host (agent) + * 0x3 - RESERVED + * Bit 7: If PEI0 is configured, + * 0x0 - indicates END_POINT + * 0x1 - indicates ROOT_COMPLEX + * Bit 6: SATA1 enabled + * Bit 5: SATA0 enabled + * Bit 4: SRIO1 enabled + * Bit 3: SRIO0 enabled + * Bit 2: PEI2 enabled + * Bit 1: PEI1 enabled + * Bit 0: PEI0 enabled + *******************************************************************************/ void setup_sata_mode(enum SataMode mode, enum SataSpeed speed) { @@ -252,7 +252,7 @@ void setup_sata_mode(enum SataMode mode, enum SataSpeed speed) /* Set AFE attenuation level to -2dB * Set the AFE first and second stage varialble Gain Amplifier gain - * Set the continuous time linear equalizer CTLE boost pole location + * Set the continous time linear equalizer CTLE boost pole location * Set the CTLE boost level * Set the value of DFE data tap 1 */ @@ -349,9 +349,8 @@ void setup_sata_mode(enum SataMode mode, enum SataSpeed speed) void setup_srio_mode(enum SrioMode mode, enum SrioSpeed speed) { u32 regVal; - u32 phy, lane, rate, width; + u32 phy, lane, rate, width, pll; int i = 0; - if (mode == SRIO0) { phy = 1; lane = 2; @@ -363,59 +362,84 @@ void setup_srio_mode(enum SrioMode mode, enum SrioSpeed speed) /* set wordmode to bypass for lane 0 and lane 1*/ for (i = lane; i <= (lane + 1); i++) { /* set Tx word mode */ - ncr_read32(NCP_REGION_ID(0x115, 0), (0x18 + (lane * 0x1c)), + ncr_read32(NCP_REGION_ID(0x115, 0), (0x18 + (i * 0x1c)), ®Val); regVal &= (~(3 << 4)); - regVal |= (0x0 << 4); + regVal |= (0 << 4); /* TX iboost level */ regVal |= (15 << 12); - ncr_write32(NCP_REGION_ID(0x115, 0), (0x18 + (lane * 0x1c)), + ncr_write32(NCP_REGION_ID(0x115, 0), (0x18 + (i * 0x1c)), regVal); /* control for setting the transmitter driver * output pre-emphasis/post-emphasis and amplitude */ - regVal = ((0x0 << 8) | (0x0 << 16) | (40 << 0)); + regVal = ((0 << 8) | (0 << 16) | (40 << 0) | (1 << 28)); ncr_write32(NCP_REGION_ID(0x115, 0), - (0x18 + (lane * 0x1c) + 0x8), + (0x18 + (i * 0x1c) + 0x8), regVal); /* Tx width */ ncr_read32(NCP_REGION_ID(0x115, 0), - (0x18 + (lane * 0x1c) + 0x4), ®Val); - regVal &= 0xffec8fcf; + (0x18 + (i * 0x1c) + 0x4), ®Val); + regVal &= 0xffac8fcf; /* SEt the power state of the transmitter * TX rate/width */ rate = (speed == SRIO_SPEED_1_25G) ? 3 : - (speed == SRIO_SPEED_2_5G) ? 2 : 1; + ((speed == SRIO_SPEED_2_5G) || + (speed == SRIO_SPEED_3_125G)) ? 2 : 1; width = 1; + pll = 0; + pll = ((speed == SRIO_SPEED_3_125G) || + (speed == SRIO_SPEED_6_25G)) ? 1 : 0; regVal |= ((0x3 << 4) | (rate << 12) | (width << 16) - | (0 << 20) | (1 << 22)); + | (pll << 20) | (1 << 22)); + ncr_write32(NCP_REGION_ID(0x115, 0), + (0x18 + (i * 0x1c) + 0x4), regVal); + + if ((speed == SRIO_SPEED_3_125G) || (speed == SRIO_SPEED_6_25G)) + regVal = (0x550 << 8) | 0x22; + else + regVal = (0x540 << 8) | 0x2a; ncr_write32(NCP_REGION_ID(0x115, 0), - (0x18 + (lane * 0x1c) + 0x4), regVal); + (0x18 + (i * 0x1c) + 0x10), regVal); + ncr_read32(NCP_REGION_ID(0x115, 0), + (0x18 + (i * 0x1c) + 0x14), ®Val); + regVal &= 0xff3c8fcf; + regVal |= ((0x3 << 4) | (rate << 12) | (width << 16)); + if ((speed == SRIO_SPEED_5G) || (speed == SRIO_SPEED_6_25G)) + regVal |= ((1 << 22) | (1 << 23)); + ncr_write32(NCP_REGION_ID(0x115, 0), + (0x18 + (i * 0x1c) + 0x14), regVal); + } /* set gearbox word clk sel for phy 1 lane 0/lane 1 */ ncr_read32(NCP_REGION_ID(0x115, 0), (0xf8 + (phy * 0x18) + 0x14), ®Val); regVal &= (~(0x7 << 20)); - regVal |= (0x2) << 20; + if (speed == SRIO_SPEED_1_25G) + regVal |= (0x2) << 20; + else if ((speed == SRIO_SPEED_2_5G) || (speed == SRIO_SPEED_3_125G)) + regVal |= (0x1) << 20; ncr_write32(NCP_REGION_ID(0x115, 0), (0xf8 + (phy * 0x18) + 0x14), regVal); ncr_read32(NCP_REGION_ID(0x115, 0), (0xf8 + (phy * 0x18) + 0x14), ®Val); regVal &= (~(0x7 << 24)); - regVal |= (0x2) << 24; + if (speed == SRIO_SPEED_1_25G) + regVal |= (0x2) << 24; + else if ((speed == SRIO_SPEED_2_5G) || (speed == SRIO_SPEED_3_125G)) + regVal |= (0x1) << 24; ncr_write32(NCP_REGION_ID(0x115, 0), (0xf8 + (phy * 0x18) + 0x14), regVal); - /* PLLA Settings */ /* Enable ref clk, ref use_pad, ref_clk_div2_en */ - regVal = ((0x1) | ((0x1) << 1) | (0x0 << 2)); + regVal = ((0x1) | ((0x1) << 1) | (0 << 2)); /* Select ref range 78.1-104 MHz */ regVal |= (0x6 << 4); /* Enable ref_clk_mplla_div2_en, ref_clk_mpllb_div2_en * and ref_repeat_clk_en */ - regVal |= ((0x1 << 8) | (0x1 << 9) | (0x0 << 10)); + regVal |= ((0x1 << 8) | (0x1 << 9) | (0 << 10)); /* Set tx_vboost_lvl and vref_ctrl */ regVal |= ((0x5 << 16) | (17 << 20)); ncr_write32(NCP_REGION_ID(0x115, 0), (0xf8 + (phy * 0x18)), @@ -430,7 +454,7 @@ void setup_srio_mode(enum SrioMode mode, enum SrioSpeed speed) */ /* MPLLA spread-spectrum clock (SSC) and * div_clk enable */ - regVal = (0x0 | (0x0 << 2)); + regVal = (0 | (0 << 2)); /* SSC range and SSC clk select */ regVal |= (0 << 20); /* mplla_div_multiplier */ @@ -470,28 +494,29 @@ void setup_srio_mode(enum SrioMode mode, enum SrioSpeed speed) regVal &= 0xffff0000; regVal |= (0x3a << 9); ncr_write32(NCP_REGION_ID(0x115, 0), - (0xf8 + (1 * 0x18) + 0x10), + (0xf8 + (phy * 0x18) + 0x10), regVal); break; case SRIO_SPEED_3_125G: case SRIO_SPEED_6_25G: - /* 625 MHz PLLA */ - /* MPLLA settings - * mplla_force_en = 1'b0; - * mplla_div8_clk_en = 1'b0; - * mplla_div10_clk_en = 1'b1; - * mplla_div16p5_clk_en = 1'b0; - * mplla_multiplier = 7'h28; + /* 625 MHz PLLB */ + /* MPLLB settings + * mpllb_force_en = 1'b0; + * mpllb_div8_clk_en = 1'b0; + * mpllb_div10_clk_en = 1'b1; + * mpllb_div16p5_clk_en = 1'b0; + * mpllb_multiplier = 7'h28; */ - ncr_read32(NCP_REGION_ID(0x115, 0), (0xf8 + (3 * 0x18) + 0x4), + ncr_read32(NCP_REGION_ID(0x115, 0), (0xf8 + (phy * 0x18) + 0x4), ®Val); - /* Disable MPLLA force, mplla_div8_clk_en - * Enable mplla_div10_clk_en - * and Disable mplla_div16p5_clk_en */ - /* MPLLA multiplier is 40 */ - regVal |= ((0x1 << 2) | (0x28 << 4)); - ncr_write32(NCP_REGION_ID(0x115, 0), (0xf8 + (3 * 0x18) + 0x4), - regVal); + /* Disable MPLLB force, mpllb_div8_clk_en + * Enable mpllb_div10_clk_en + * and Disable mpllb_div16p5_clk_en */ + /* MPLLB multiplier is 40 */ + regVal |= (((0x1 << 2) | (0x28 << 4))<<16); + regVal |= ((0x1 << 2) | (0x20 << 4)); /* Is this needed*/ + ncr_write32(NCP_REGION_ID(0x115, 0), + (0xf8 + (phy * 0x18) + 0x4), regVal); /* * mplla_fracn_ctrl = 9'h0; * mplla_bandwidth = 7'h5b; @@ -499,15 +524,92 @@ void setup_srio_mode(enum SrioMode mode, enum SrioSpeed speed) ncr_read32(NCP_REGION_ID(0x115, 0), (0xf8 + (phy * 0x18) + 0x10), ®Val); - regVal &= 0xffff0000; - regVal |= (0x5b << 9); + regVal &= 0xffff; + regVal |= ((0x5b << 9)<<16); + regVal |= (0x3a << 9); /* Is this needed*/ ncr_write32(NCP_REGION_ID(0x115, 0), - (0xf8 + (1 * 0x18) + 0x10), + (0xf8 + (phy * 0x18) + 0x10), regVal); + if (speed == SRIO_SPEED_6_25G) { + ncr_write32(NCP_REGION_ID(0x115, (phy + 1)), + 0x16, 0x0010); + ncr_write32(NCP_REGION_ID(0x115, (phy + 1)), + 0x24, 0x001E); + ncr_write32(NCP_REGION_ID(0x115, (phy + 1)), + 0x26, 0x0000); + ncr_write32(NCP_REGION_ID(0x115, (phy + 1)), + 0x18, 0x0010); + ncr_write32(NCP_REGION_ID(0x115, (phy + 1)), + 0x44, 0x001E); + ncr_write32(NCP_REGION_ID(0x115, (phy + 1)), + 0x46, 0x0000); + } break; } } +void enable_reset(u32 phy) +{ + u32 regVal; + + if (phy == 0) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0, + ®Val); + regVal |= (1 << 5); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, + regVal); + } else if (phy == 1) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0, + ®Val); + regVal |= (1 << 14); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, + regVal); + } else if (phy == 2) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, + ®Val); + regVal |= (1 << 19); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, + regVal); + } else if (phy == 3) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, + ®Val); + regVal |= (1 << 29); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, + regVal); + } +} + +void release_reset(u32 phy) +{ + u32 regVal; + + if (phy == 0) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0, + ®Val); + regVal &= (~(1 << 5)); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, + regVal); + } else if (phy == 1) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0, + ®Val); + regVal &= (~(1 << 14)); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, + regVal); + } else if (phy == 2) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, + ®Val); + regVal &= (~(1 << 19)); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, + regVal); + } else if (phy == 3) { + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, + ®Val); + regVal &= (~(1 << 29)); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, + regVal); + } +} + int check_pll_lock(enum PLLMode mode, u32 phy) { u32 regVal; @@ -522,7 +624,7 @@ int check_pll_lock(enum PLLMode mode, u32 phy) ncr_read32(NCP_REGION_ID(0x115, 0), 0x184 + (phy * 8), ®Val); regVal &= (1 << (20 + mode)); - } while ((!regVal) || (count++ < 5)); + } while ((!regVal) && (count++ < 5)); return regVal; } @@ -547,7 +649,7 @@ int check_ack(u32 phy, u32 lane, enum Dir dir) regVal &= (1 << (0 + lane)); else regVal &= (1 << (16 + lane)); - } while ((!regVal) || (count++ < 5)); + } while ((!regVal) && (count++ < 5)); return regVal; } @@ -575,7 +677,7 @@ int check_rx_valid(u32 phy, u32 lane) mdelay(100); ncr_read32(NCP_REGION_ID(0x115, 0), 0x184 + (phy * 8), ®Val); regVal &= (1 << (24 + (4 * lane))); - } while ((!regVal) || (count++ < 5)); + } while ((!regVal) && (count++ < 5)); return regVal; } @@ -590,11 +692,12 @@ powerup_lane(u32 phy, u32 lane, enum PowerState state, enum Dir dir) { u32 regVal, powerVal; u32 offset; + int ret; if (dir == TX) - offset = 0x18 + (lane * 0x1c) + 0x4; + offset = 0x18 + (((phy * 2) + lane) * 0x1c) + 0x4; else - offset = 0x18 + (lane * 0x1c) + 0x14; + offset = 0x18 + (((phy * 2) + lane) * 0x1c) + 0x14; ncr_read32(NCP_REGION_ID(0x115, 0), offset, ®Val); regVal &= 0xffffffce; @@ -604,7 +707,12 @@ powerup_lane(u32 phy, u32 lane, enum PowerState state, enum Dir dir) ncr_write32(NCP_REGION_ID(0x115, 0), offset, regVal); /* Check if ack is set */ - return check_ack(phy, lane, dir); + ret = check_ack(phy, lane, dir); + ncr_read32(NCP_REGION_ID(0x115, 0), offset, ®Val); + regVal &= ~(1 << 0); + ncr_write32(NCP_REGION_ID(0x115, 0), offset, regVal); + + return ret; } /* @@ -619,13 +727,13 @@ enable_lane(u32 phy, u32 lane, enum Dir dir) u32 offset; if (TX == dir) - offset = 0x18 + (lane * 0x1c); + offset = 0x18 + (((phy * 2) + lane) * 0x1c); else - offset = 0x18 + (lane * 0x1c) + 0x14; + offset = 0x18 + (((phy * 2) + lane) * 0x1c) + 0x14; ncr_read32(NCP_REGION_ID(0x115, 0), offset, ®Val); - if (TX == dir) + if (TX ==dir) regVal |= (1 << 25); else regVal |= (1 << 21); @@ -651,6 +759,7 @@ enable_lane(u32 phy, u32 lane, enum Dir dir) int pei_setup(unsigned int control) { + unsigned int pci_srio_sata_mode; unsigned int val; unsigned int rc_mode; unsigned int phyVal0; @@ -659,8 +768,23 @@ pei_setup(unsigned int control) unsigned int srio1_mode; unsigned int srio0_speed; unsigned int srio1_speed; + unsigned int sata0_speed; + unsigned int sata1_speed; + unsigned int sata0_mode; + unsigned int sata1_mode; + unsigned int srio0_ctrl; + unsigned int srio1_ctrl; + unsigned int reg_val = 0; + enum PLLMode pll; int phy, lane; + pci_srio_sata_mode = (control & 0x03c00000) >> 22; + sata0_mode = (control & 0x20) >> 5; + sata1_mode = (control & 0x40) >> 6; + + sata0_speed = (control & 0xc0000) >> 18; + sata1_speed = (control & 0x30000) >> 20; + srio0_mode = (control & 0x8) >> 3; srio1_mode = (control & 0x10) >> 4; @@ -673,18 +797,21 @@ pei_setup(unsigned int control) writel(val, pcie_gpreg0 + 0x8038); msleep(100); - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); + for (phy = 0; phy < 4; phy++) + enable_reset(phy); + + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); phyVal0 &= ~1; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); mdelay(100); /* TODO: Why is this needed? */ - switch ((control & 0x03c00000) >> 22) { /* bits 25:22 */ + switch (pci_srio_sata_mode) { case 0: /* PEI0x8 */ - rc_mode = (control & 0x80)<<15; /* jl */ + rc_mode = (control & 0x80)<<15; /* Enable PEI0, PEI0 RC mode */ - phyVal0 = (control & 0x1) | rc_mode; /* jl */ - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + phyVal0 = (control & 0x1) | rc_mode; + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); /* PIPE port select -- Enable PIPE0 interface */ ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, (0x1<<24)); break; @@ -692,31 +819,29 @@ pei_setup(unsigned int control) /* PEI0x4, PEI1x4 */ - - printk("%s:%d -\n", __FILE__, __LINE__); phyVal1 = 0x0e7001ac; ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, phyVal1); phyVal0 = 0x84400040; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); break; case 2: /* PEI0x4_PEI1x2_SATA0x1_SATA1x1 */ - rc_mode = (control & 0x80)<<15; /* jl */ + rc_mode = (control & 0x80)<<15; /* Enable PEI0/PEI1, PEI0 RC mode */ phyVal0 = (control & 0x3) | rc_mode; /* PEI0x4 */ phyVal0 |= (0x1 << 26); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); /* PEI1x2_SATA0_SATA1 */ phyVal1 = (0x1 << 23); /* PIPE port select -- Enable PIPE0/PIPE1 interface */ phyVal1 |= (0x2 << 24); ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, phyVal1); - if (((control & 0x20) >> 5)) - setup_sata_mode(SATA0, ((control & 0xc0000) >> 18)); - if (((control & 0x40) >> 6)) - setup_sata_mode(SATA1, ((control & 0x30000) >> 20)); + if (sata0_mode) + setup_sata_mode(SATA0, sata0_speed); + if (sata1_mode) + setup_sata_mode(SATA1, sata1_speed); if (!check_pll_lock(PLLA, 1)) { printk("PLLA didn't lock\n"); return 1; @@ -739,7 +864,7 @@ pei_setup(unsigned int control) ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &phyVal0); phyVal0 |= (control & 0x20) << 24; phyVal0 |= (control & 0x40) << 24; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); if (!check_rx_valid(3, 0)) { printk("RX clock/data recovery not asserted for PHY3 LANE0\n"); @@ -752,22 +877,22 @@ pei_setup(unsigned int control) break; case 3: /* PEI0x2_PEI2x2_PEI1x2_SATA0x1_SATA1x1 */ - rc_mode = (control & 0x80)<<15; /* jl */ + rc_mode = (control & 0x80)<<15; /* Enable PEI0/PEI1/PEI2, PEI0 RC mode */ phyVal0 = (control & 0x7) | rc_mode; /* PEI0x2_PEI2x2 */ phyVal0 |= (0x3 << 26); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); /* PEI1x2_SATA0_SATA1 */ phyVal1 = (0x1 << 23); /* PIPE port select -- Enable PIPE0, PIPE1 * and PIPE2 interface */ phyVal1 |= (0x3 << 24); ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, phyVal1); - if (((control & 0x20) >> 5)) - setup_sata_mode(SATA0, ((control & 0xc0000) >> 18)); - if (((control & 0x40) >> 6)) - setup_sata_mode(SATA1, ((control & 0x30000) >> 20)); + if (sata0_mode) + setup_sata_mode(SATA0, sata0_speed); + if (sata1_mode) + setup_sata_mode(SATA1, sata1_speed); if (!check_pll_lock(PLLA, 1)) { printk("PLLA didn't lock\n"); @@ -787,10 +912,10 @@ pei_setup(unsigned int control) set_tx_clk_ready(); /* Enable SATA0/SATA1 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); phyVal0 |= (control & 0x20) << 24; phyVal0 |= (control & 0x40) << 24; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); if (!check_rx_valid(3, 0)) { printk("RX clock/data recovery not asserted for PHY3 LANE0\n"); @@ -803,34 +928,45 @@ pei_setup(unsigned int control) break; case 4: /* PEI0x2_SRIO0x2_PEI1x4 */ - rc_mode = (control & 0x80)<<15; /* jl */ + rc_mode = (control & 0x80)<<15; /* Enable PEI0/PEI1/SRIO0, PEI0 RC mode */ phyVal0 = (control & 0x3) | rc_mode; /* PEI0x2_SRI0x2 */ phyVal0 |= (0x7 << 26); /* SRIO0 mode */ - srio0_mode = ((control & 0x300) << 12); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | srio0_mode); + srio0_ctrl = ((control & 0x300) << 12); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, ®_val); + reg_val &= ~(0xf | (0x1 << 22) | (0x7<<26) | (0x3 << 20)); + reg_val |= phyVal0 | srio0_ctrl; + ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val); /* PEI1x4 */ phyVal1 = (0x1 << 22); /* PIPE port select -- Enable PIPE0/PIPE1 interface */ phyVal1 |= (0x2 << 24); /* SRIO0 speed */ srio0_speed = (control & 0x7000); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, - phyVal1 | srio0_speed); + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, ®_val); + reg_val &= ~((0x3<<24) | (0x3 << 22) | (0x7 << 12)); + reg_val |= (phyVal1 | srio0_speed); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, reg_val); + srio0_speed = srio0_speed >> 12; if (srio0_mode) setup_srio_mode(SRIO0, srio0_speed); - if (!check_pll_lock(PLLA, 1)) { - printk("PLLA didn't lock\n"); + printk("Set up sRIO0 -- %d\n", srio0_speed); + for (phy = 0; phy < 4; phy++) + release_reset(phy); + + pll = PLLA; + if ((srio0_speed == SRIO_SPEED_3_125G) + || (srio0_speed == SRIO_SPEED_6_25G)) + pll = PLLB; + if (!check_pll_lock(pll, 1)) { + printk("%s didn't lock\n", + pll == PLLA ? "PLLA" : "PLLB"); return 1; } + printk("Enabling sRIO ."); for (lane = 0; lane < 2; lane++) { - if (!check_ack(1, lane, TX)) { - printk("TX ACK not set for PHY1 LANE%d\n", lane); - return 1; - } if (!check_ack(3, lane, RX)) { printk("RX ACK not set for PHY1 LANE%d\n", lane); return 1; @@ -868,49 +1004,54 @@ pei_setup(unsigned int control) enable_lane(1, lane, RX); } /* Enable SRIO0 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0 | 0x8); - + printk("Done\n"); break; case 5: /* PEI0x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 */ - rc_mode = (control & 0x80)<<15; /* jl */ + rc_mode = (control & 0x80)<<15; /* Enable PEI0/PEI1/SRIO0, PEI0 RC mode */ phyVal0 = (control & 0x3) | rc_mode; /* PEI0x2_SRI0x2 */ phyVal0 |= (0x7 << 26); /* SRIO0 mode */ - srio0_mode = ((control & 0x300) << 12); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | srio0_mode); + srio0_ctrl = ((control & 0x300) << 12); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, ®_val); + reg_val &= ~(0xf | (0x1 << 22) | (0x7<<26) | (0x3 << 20)); + reg_val |= phyVal0 | srio0_ctrl; + ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val); /* PEI1x2_SATA0x1_SATA1x1 */ phyVal1 = (0x1 << 23); /* PIPE port select -- Enable PIPE0/PIPE1 interface */ phyVal1 |= (0x2 << 24); /* SRIO0 speed */ srio0_speed = (control & 0x7000); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, - phyVal1 | srio0_speed); - if (((control & 0x20) >> 5)) - setup_sata_mode(SATA0, ((control & 0xc0000) >> 18)); - if (((control & 0x40) >> 6)) - setup_sata_mode(SATA1, ((control & 0x30000) >> 20)); + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, ®_val); + reg_val &= ~((0x3<<24) | (0x3 << 22) | (0x7 << 12)); + reg_val |= (phyVal1 | srio0_speed); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, reg_val); + srio0_speed = srio0_speed >> 12; + if (sata0_mode) + setup_sata_mode(SATA0, sata0_speed); + if (sata1_mode) + setup_sata_mode(SATA1, sata1_speed); if (srio0_mode) setup_srio_mode(SRIO0, srio0_speed); - if (!check_pll_lock(PLLA, 1)) { - printk("PLLA didn't lock\n"); + printk("Set up sRIO0 -- %d\n", srio0_speed); + for (phy = 0; phy < 4; phy++) + release_reset(phy); + pll = PLLA; + if ((srio0_speed == SRIO_SPEED_3_125G) + || (srio0_speed == SRIO_SPEED_6_25G)) + pll = PLLB; + if (!check_pll_lock(pll, 1)) { + printk("%s didn't lock\n", + pll == PLLA ? "PLLA" : "PLLB"); return 1; } for (lane = 0; lane < 2; lane++) { - if (!check_ack(1, lane, TX)) { - printk("TX ACK not set for PHY1 LANE%d\n", lane); - return 1; - } - if (!check_ack(1, lane, RX)) { - printk("RX ACK not set for PHY1 LANE%d\n", lane); - return 1; - } if (!check_ack(3, lane, TX)) { printk("TX ACK not set for PHY3 LANE%d\n", lane); return 1; @@ -920,6 +1061,7 @@ pei_setup(unsigned int control) return 1; } } + printk("Enabling sRIO/SATA ."); /* Power up TX/RX lanes */ for (lane = 0; lane < 2; lane++) { if (!powerup_lane(1, lane, P1, TX)) { @@ -946,17 +1088,17 @@ pei_setup(unsigned int control) return 1; } } - + printk("."); for (lane = 0; lane < 2; lane++) { enable_lane(1, lane, TX); enable_lane(1, lane, RX); } /* Enable SATA0/SATA1 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); phyVal0 |= (control & 0x20) << 24; phyVal0 |= (control & 0x40) << 24; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); if (!check_rx_valid(3, 0)) { printk("RX clock/data recovery not asserted for PHY3 LANE0\n"); @@ -967,21 +1109,24 @@ pei_setup(unsigned int control) return 1; } /* Enable SRIO0 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0 | 0x8); + printk("Done\n"); break; case 6: /* PEI0x2_SRIO0x2_PEI1x2_PEI2x2 */ - rc_mode = (control & 0x80)<<15; /* jl */ + rc_mode = (control & 0x80)<<15; /* Enable PEI0/PEI1/PEI2/SRIO0, PEI0 RC mode */ phyVal0 = (control & 0x7) | rc_mode; /* PEI0x2_SRIO0x2 */ phyVal0 |= (0x7 << 26); /* SRIO0 mode */ - srio0_mode = ((control & 0x300) << 12); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | srio0_mode); + srio0_ctrl = ((control & 0x300) << 12); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, ®_val); + reg_val &= ~(0xf | (0x1 << 22) | (0x7<<26) | (0x3 << 20)); + reg_val |= phyVal0 | srio0_ctrl; + ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val); /* PEI1x2_PEI2x2 */ phyVal1 = (0x3 << 22); /* PIPE port select -- Enable PIPE0, PIPE1 @@ -989,24 +1134,28 @@ pei_setup(unsigned int control) phyVal1 |= (0x3 << 24); /* SRIO0 speed */ srio0_speed = (control & 0x7000); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, - phyVal1 | srio0_speed); + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, ®_val); + reg_val &= ~((0x3<<24) | (0x3 << 22) | (0x7 << 12)); + reg_val |= (phyVal1 | srio0_speed); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, reg_val); + srio0_speed = srio0_speed >> 12; if (srio0_mode) setup_srio_mode(SRIO0, srio0_speed); - if (!check_pll_lock(PLLA, 1)) { - printk("PLLA didn't lock\n"); + printk("Set up sRIO0 -- %d\n", srio0_speed); + for (phy = 0; phy < 4; phy++) + release_reset(phy); + + pll = PLLA; + if ((srio0_speed == SRIO_SPEED_3_125G) + || (srio0_speed == SRIO_SPEED_6_25G)) + pll = PLLB; + if (!check_pll_lock(pll, 1)) { + printk("%s didn't lock\n", + pll == PLLA ? "PLLA" : "PLLB"); return 1; } - for (lane = 0; lane < 2; lane++) { - if (!check_ack(1, lane, TX)) { - printk("TX ACK not set for PHY1 LANE%d\n", lane); - return 1; - } - if (!check_ack(1, lane, RX)) { - printk("RX ACK not set for PHY1 LANE%d\n", lane); - return 1; - } - } + + printk("Enabling sRIO ."); /* Power up TX/RX lanes */ for (lane = 0; lane < 2; lane++) { if (!powerup_lane(1, lane, P1, TX)) { @@ -1039,9 +1188,10 @@ pei_setup(unsigned int control) enable_lane(1, lane, RX); } /* Enable SRIO0 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0 | 0x8); + printk("Done\n"); break; case 7: /* SRIO1x2_SRIO0x2_PEI1x4 */ @@ -1050,12 +1200,13 @@ pei_setup(unsigned int control) /* SRIO1x2_SRIO0x2 */ phyVal0 |= (0x4 << 26); /* SRIO0 mode */ - srio0_mode = ((control & 0x300) << 12); + srio0_ctrl = ((control & 0x300) << 12); /* SRIO1 mode */ - srio1_mode = ((control & 0xC00) << 14); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | srio0_mode - | srio1_mode); + srio1_ctrl = ((control & 0xC00) << 14); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, ®_val); + reg_val &= ~(0xf | (0x7<<26) | (0x3 << 20) | (0x3 << 24)); + reg_val |= (phyVal0 | srio0_ctrl | srio1_ctrl); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val); /* PEI1x4 */ phyVal1 = (0x1 << 22); /* PIPE port select -- Enable PIPE0/PIPE1 interface */ @@ -1064,28 +1215,39 @@ pei_setup(unsigned int control) srio0_speed = (control & 0x7000); /* SRIO1 speed */ srio1_speed = (control & 0x38000) << 1; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, - phyVal1 | srio0_speed | srio1_speed); + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, ®_val); + reg_val &= ~((0x3 << 24) | (0x3 << 22) | (0x7 << 12) | + (0x7 << 16)); + reg_val |= (phyVal1 | srio0_speed | srio1_speed); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, reg_val); + srio0_speed = srio0_speed >> 12; + srio1_speed = srio1_speed >> 16; if (srio0_mode) setup_srio_mode(SRIO0, srio0_speed); + printk("Set up sRIO0 -- %d\n", srio0_speed); if (srio1_mode) setup_srio_mode(SRIO1, srio1_speed); - if (!check_pll_lock(PLLA, 1)) { - printk("PLLA didn't lock\n"); - return 1; - } + printk("Set up sRIO1 -- %d\n", srio1_speed); + for (phy = 0; phy < 4; phy++) + release_reset(phy); + for (phy = 0; phy < 2; phy++) { - for (lane = 0; lane < 2; lane++) { - if (!check_ack(phy, lane, TX)) { - printk("TX ACK not set for PHY%d LANE%d\n", phy, lane); - return 1; - } - if (!check_ack(phy, lane, RX)) { - printk("RX ACK not set for PHY%d LANE%d\n", phy, lane); - return 1; - } + pll = PLLA; + if ((phy == 0) && + ((srio1_speed == SRIO_SPEED_3_125G) || + (srio1_speed == SRIO_SPEED_6_25G))) + pll = PLLB; + else if ((phy == 1) && + ((srio0_speed == SRIO_SPEED_3_125G) || + (srio0_speed == SRIO_SPEED_6_25G))) + pll = PLLB; + if (!check_pll_lock(pll, phy)) { + printk("%s didn't lock\n", + pll == PLLA ? "PLLA" : "PLLB"); + return 1; } } + printk("Enabling sRIO ."); /* Power up TX/RX lanes */ for (phy = 0; phy < 2; phy++) { for (lane = 0; lane < 2; lane++) { @@ -1099,10 +1261,9 @@ pei_setup(unsigned int control) } } } - + printk("."); /* Set TX clock ready */ set_tx_clk_ready(); - /* Power up TX/RX lanes */ for (phy = 0; phy < 2; phy++) { for (lane = 0; lane < 2; lane++) { @@ -1116,15 +1277,19 @@ pei_setup(unsigned int control) } } } - - for (lane = 0; lane < 2; lane++) { - enable_lane(1, lane, TX); - enable_lane(1, lane, RX); + printk("."); + for (phy = 0; phy < 2; phy++) { + for (lane = 0; lane < 2; lane++) { + enable_lane(phy, lane, TX); + enable_lane(phy, lane, RX); + } } + printk("."); /* Enable SRIO0/SRIO1 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | 0x18); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, + phyVal0 | 0x408); + printk("Done\n"); break; case 8: /* SRIO1x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 */ @@ -1133,11 +1298,13 @@ pei_setup(unsigned int control) /* SRIO1x2_SRIO0x2 */ phyVal0 |= (0x4 << 26); /* SRIO0 mode */ - srio0_mode = ((control & 0x300) << 12); + srio0_ctrl = ((control & 0x300) << 12); /* SRIO1 mode */ - srio1_mode = ((control & 0xC00) << 14); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | srio0_mode | srio1_mode); + srio1_ctrl = ((control & 0xC00) << 14); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, ®_val); + reg_val &= ~(0xf | (0x7 << 26) | (0x3 << 20) | (0x3 << 24)); + reg_val |= (phyVal0 | srio0_ctrl | srio1_ctrl); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val); /* PEI1x2_SATA0x1_SATA1x1 */ phyVal1 = (0x1 << 23); /* PIPE port select -- Enable PIPE0/PIPE1 interface */ @@ -1146,42 +1313,42 @@ pei_setup(unsigned int control) srio0_speed = (control & 0x7000); /* SRIO1 speed */ srio1_speed = (control & 0x38000) << 1; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, - phyVal1 | srio0_speed | srio1_speed); - if (((control & 0x20) >> 5)) - setup_sata_mode(SATA0, ((control & 0xc0000) >> 18)); - if (((control & 0x40) >> 6)) - setup_sata_mode(SATA1, ((control & 0x30000) >> 20)); + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, ®_val); + reg_val &= ~((0x3 << 24) | (0x3 << 22) | (0x7 << 12) | + (0x7 << 16)); + reg_val |= (phyVal1 | srio0_speed | srio1_speed); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, reg_val); + srio0_speed = srio0_speed >> 12; + srio1_speed = srio1_speed >> 16; + if (sata0_mode) + setup_sata_mode(SATA0, sata0_speed); + if (sata1_mode) + setup_sata_mode(SATA1, sata1_speed); if (srio0_mode) setup_srio_mode(SRIO0, srio0_speed); + printk("Set up sRIO0 -- %d\n", srio0_speed); if (srio1_mode) setup_srio_mode(SRIO1, srio1_speed); - if (!check_pll_lock(PLLA, 1)) { - printk("PLLA didn't lock\n"); - return 1; - } + printk("Set up sRIO1 -- %d\n", srio1_speed); + for (phy = 0; phy < 4; phy++) + release_reset(phy); + for (phy = 0; phy < 2; phy++) { - for (lane = 0; lane < 2; lane++) { - if (!check_ack(phy, lane, TX)) { - printk("TX ACK not set for PHY%d LANE%d\n", phy, lane); - return 1; - } - if (!check_ack(phy, lane, RX)) { - printk("RX ACK not set for PHY%d LANE%d\n", phy, lane); - return 1; - } - } - } - for (lane = 0; lane < 2; lane++) { - if (!check_ack(phy, lane, TX)) { - printk("TX ACK not set for PHY3 LANE%d\n", lane); - return 1; - } - if (!check_ack(phy, lane, RX)) { - printk("RX ACK not set for PHY3 LANE%d\n", lane); + pll = PLLA; + if ((phy == 0) && ((srio1_speed == SRIO_SPEED_3_125G) + || (srio1_speed == SRIO_SPEED_6_25G))) + pll = PLLB; + else if ((phy == 1) && + ((srio0_speed == SRIO_SPEED_3_125G) + || (srio0_speed == SRIO_SPEED_6_25G))) + pll = PLLB; + if (!check_pll_lock(pll, phy)) { + printk("%s didn't lock\n", + pll == PLLA ? "PLLA" : "PLLB"); return 1; } } + printk("Enabling sRIO/SATA ."); /* Power up TX/RX lanes */ for (phy = 0; phy < 2; phy++) { for (lane = 0; lane < 2; lane++) { @@ -1196,6 +1363,7 @@ pei_setup(unsigned int control) } } + printk("."); /* Set TX clock ready */ set_tx_clk_ready(); @@ -1212,17 +1380,21 @@ pei_setup(unsigned int control) } } } + printk("."); - for (lane = 0; lane < 2; lane++) { - enable_lane(1, lane, TX); - enable_lane(1, lane, RX); + for (phy = 0; phy < 2; phy++) { + for (lane = 0; lane < 2; lane++) { + enable_lane(phy, lane, TX); + enable_lane(phy, lane, RX); + } } + printk("."); /* Enable SATA0/SATA1 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); phyVal0 |= (control & 0x20) << 24; phyVal0 |= (control & 0x40) << 24; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); if (!check_rx_valid(3, 0)) { printk("RX clock/data recovery not asserted for PHY3 LANE0\n"); @@ -1233,9 +1405,10 @@ pei_setup(unsigned int control) return 1; } /* Enable SRIO0/SRIO1 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | 0x18); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, + phyVal0 | 0x408); + printk("Done\n"); break; case 9: /* SRIO1x2_SRIO0x2_PEI1x2_PEI2x2 */ @@ -1244,11 +1417,13 @@ pei_setup(unsigned int control) /* SRIO1x2_SRIO0x2 */ phyVal0 |= (0x4 << 26); /* SRIO0 mode */ - srio0_mode = ((control & 0x300) << 12); + srio0_ctrl = ((control & 0x300) << 12); /* SRIO1 mode */ - srio1_mode = ((control & 0xC00) << 14); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | srio0_mode | srio1_mode); + srio1_ctrl = ((control & 0xC00) << 14); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, ®_val); + reg_val &= ~(0xf | (0x7 << 26) | (0x3 << 20) | (0x3 << 24)); + reg_val |= (phyVal0 | srio0_ctrl | srio1_ctrl); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val); /* PEI1x2_PEI2x2 */ phyVal1 = (0x3 << 22); /* PIPE port select -- Enable PIPE0, PIPE1 @@ -1258,28 +1433,39 @@ pei_setup(unsigned int control) srio0_speed = (control & 0x7000); /* SRIO1 speed */ srio1_speed = (control & 0x38000) << 1; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, - phyVal1 | srio0_speed | srio1_speed); + ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, ®_val); + reg_val &= ~((0x3 << 24) | (0x3 << 22) | (0x7 << 12) | + (0x7 << 16)); + reg_val |= (phyVal1 | srio0_speed | srio1_speed); + ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, reg_val); + srio0_speed = srio0_speed >> 12; + srio1_speed = srio1_speed >> 16; if (srio0_mode) setup_srio_mode(SRIO0, srio0_speed); + printk("Set up sRIO0 -- %d\n", srio0_speed); if (srio1_mode) setup_srio_mode(SRIO1, srio1_speed); - if (!check_pll_lock(PLLA, 1)) { - printk("PLLA didn't lock\n"); - return 1; - } + printk("Set up sRIO1 -- %d\n", srio1_speed); + for (phy = 0; phy < 4; phy++) + release_reset(phy); + for (phy = 0; phy < 2; phy++) { - for (lane = 0; lane < 2; lane++) { - if (!check_ack(phy, lane, TX)) { - printk("TX ACK not set for PHY%d LANE%d\n", phy, lane); - return 1; - } - if (!check_ack(phy, lane, RX)) { - printk("RX ACK not set for PHY%d LANE%d\n", phy, lane); - return 1; - } + pll = PLLA; + if ((phy == 0) && + ((srio1_speed == SRIO_SPEED_3_125G) || + (srio1_speed == SRIO_SPEED_6_25G))) + pll = PLLB; + else if ((phy == 1) && + ((srio0_speed == SRIO_SPEED_3_125G) || + (srio0_speed == SRIO_SPEED_6_25G))) + pll = PLLB; + if (!check_pll_lock(pll, phy)) { + printk("%s didn't lock\n", + pll == PLLA ? "PLLA" : "PLLB"); + return 1; } } + printk("Enabling sRIO ."); /* Power up TX/RX lanes */ for (phy = 0; phy < 2; phy++) { for (lane = 0; lane < 2; lane++) { @@ -1294,6 +1480,7 @@ pei_setup(unsigned int control) } } + printk("."); /* Set TX clock ready */ set_tx_clk_ready(); @@ -1310,24 +1497,29 @@ pei_setup(unsigned int control) } } } + printk("."); - for (lane = 0; lane < 2; lane++) { - enable_lane(1, lane, TX); - enable_lane(1, lane, RX); + for (phy = 0; phy < 2; phy++) { + for (lane = 0; lane < 2; lane++) { + enable_lane(phy, lane, TX); + enable_lane(phy, lane, RX); + } } + printk("."); /* Enable SRIO0/SRIO1 */ - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, - phyVal0 | 0x18); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, + phyVal0 | 0x408); + printk("Done\n"); break; } - ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &phyVal0); + ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0); phyVal0 |= 1; - ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, phyVal0); + ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0); msleep(100); - switch ((control & 0x03c00000) >> 22) { /* bits 25:22 */ + switch (pci_srio_sata_mode) { case 1: writel(0x70120, pcie_rc + 0x710); writel(0x104be, pcie_rc + 0x80c); diff --git a/drivers/pci/host/pcie-axxia.c b/drivers/pci/host/pcie-axxia.c index 9c7ef5f..ac53246 100644 --- a/drivers/pci/host/pcie-axxia.c +++ b/drivers/pci/host/pcie-axxia.c @@ -1,15 +1,15 @@ /* -* PCIe host controller driver for Intel's AXXIA X9/LF devices -* -* Copyright (C) 2015 Intel Electronics Co., Ltd. -* http://www.intel.com -* -* Author: Sangeetha Rao <sangeetha....@intel.com> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -*/ + * PCIe host controller driver for Intel's AXXIA X9/LF devices + * + * Copyright (C) 2015 Intel Electronics Co., Ltd. + * http://www.intel.com + * + * Author: Sangeetha Rao <sangeetha....@intel.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #include <linux/clk.h> #include <linux/delay.h> @@ -104,9 +104,9 @@ /* SYSCON */ #define AXXIA_SYSCON_BASE 0x8002C00000 -static int control_set; -static unsigned int control_value; -static struct pcie_port *_ppL; +static int control_set = 0; +static unsigned int control_value = 0; +static struct pcie_port *_pp = NULL; static inline uint32_t axxia_mmio_read_32(uintptr_t addr) { @@ -123,8 +123,9 @@ axxia_is_x9(void) } struct axxia_pcie { - struct pcie_port pp; - unsigned int control; + struct pcie_port pp; + unsigned int control; + unsigned int initialized; }; static unsigned long global_io_offset; @@ -150,13 +151,13 @@ static inline void axxia_cc_gpreg_readl(struct pcie_port *pp, u32 reg, u32 *val) } static inline void axxia_axi_gpreg_writel(struct pcie_port *pp, u32 val, - u32 reg) + u32 reg) { writel(val, pp->axi_gpreg_base + reg); } static inline void axxia_axi_gpreg_readl(struct pcie_port *pp, u32 reg, - u32 *val) + u32 *val) { *val = readl(pp->axi_gpreg_base + reg); } @@ -190,22 +191,22 @@ int axxia_pcie_cfg_write(void __iomem *addr, int where, int size, u32 val) } static int axxia_pcie_rd_own_conf(struct pcie_port *pp, int where, - int size, u32 *val) + int size, u32 *val) { int ret; ret = axxia_pcie_cfg_read(pp->dbi_base + (where & ~0x3), - where, size, val); + where, size, val); return ret; } static int axxia_pcie_wr_own_conf(struct pcie_port *pp, int where, - int size, u32 val) + int size, u32 val) { int ret; ret = axxia_pcie_cfg_write(pp->dbi_base + (where & ~0x3), where, - size, val); + size, val); return ret; } @@ -215,15 +216,15 @@ static void axxia_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev) /* Program viewport 0 : OUTBOUND : CFG0 */ axxia_pcie_writel_rc(pp, - PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, - PCIE_ATU_VIEWPORT); + PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, + PCIE_ATU_VIEWPORT); axxia_pcie_writel_rc(pp, pp->cfg0_base, PCIE_ATU_LOWER_BASE); /* set upper base bits [1:0] for X9, bits[7:0] for XLF */ upper_base = (pp->cfg0_base >> 32); upper_base &= (axxia_is_x9()) ? 0x3 : 0xff; axxia_pcie_writel_rc(pp, upper_base, PCIE_ATU_UPPER_BASE); axxia_pcie_writel_rc(pp, pp->cfg0_base + pp->cfg0_size - 1, - PCIE_ATU_LIMIT); + PCIE_ATU_LIMIT); axxia_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); axxia_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); axxia_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG0, PCIE_ATU_CR1); @@ -237,8 +238,8 @@ static void axxia_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev) /* Program viewport 1 : OUTBOUND : CFG1 */ axxia_pcie_writel_rc(pp, - PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, - PCIE_ATU_VIEWPORT); + PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, + PCIE_ATU_VIEWPORT); axxia_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); axxia_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE); upper_base = (pp->cfg1_base >> 32); @@ -246,7 +247,7 @@ static void axxia_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev) axxia_pcie_writel_rc(pp, upper_base, PCIE_ATU_UPPER_BASE); axxia_pcie_writel_rc(pp, pp->cfg1_base + pp->cfg1_size - 1, - PCIE_ATU_LIMIT); + PCIE_ATU_LIMIT); axxia_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); axxia_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); axxia_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); @@ -258,18 +259,18 @@ static void axxia_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) /* Program viewport 0 : OUTBOUND : MEM */ axxia_pcie_writel_rc(pp, - PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX2, - PCIE_ATU_VIEWPORT); + PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX2, + PCIE_ATU_VIEWPORT); axxia_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); axxia_pcie_writel_rc(pp, pp->mem_mod_base, PCIE_ATU_LOWER_BASE); upper_base = (pp->mem_mod_base >> 32); upper_base &= (axxia_is_x9()) ? 0x3 : 0xff; axxia_pcie_writel_rc(pp, upper_base, PCIE_ATU_UPPER_BASE); axxia_pcie_writel_rc(pp, pp->mem_mod_base + pp->mem_size - 1, - PCIE_ATU_LIMIT); + PCIE_ATU_LIMIT); axxia_pcie_writel_rc(pp, pp->mem_bus_addr, PCIE_ATU_LOWER_TARGET); axxia_pcie_writel_rc(pp, upper_32_bits(pp->mem_bus_addr), - PCIE_ATU_UPPER_TARGET); + PCIE_ATU_UPPER_TARGET); axxia_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); } @@ -278,21 +279,21 @@ static void axxia_pcie_prog_viewport_io_outbound(struct pcie_port *pp) { /* Program viewport 1 : OUTBOUND : IO */ axxia_pcie_writel_rc(pp, - PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX3, - PCIE_ATU_VIEWPORT); + PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX3, + PCIE_ATU_VIEWPORT); axxia_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); axxia_pcie_writel_rc(pp, pp->io_mod_base, PCIE_ATU_LOWER_BASE); axxia_pcie_writel_rc(pp, pp->io_mod_base + pp->io_size - 1, - PCIE_ATU_LIMIT); + PCIE_ATU_LIMIT); axxia_pcie_writel_rc(pp, pp->io_bus_addr, PCIE_ATU_LOWER_TARGET); axxia_pcie_writel_rc(pp, upper_32_bits(pp->io_bus_addr), - PCIE_ATU_UPPER_TARGET); + PCIE_ATU_UPPER_TARGET); axxia_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); } static int axxia_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, - u32 devfn, int where, int size, u32 *val) + u32 devfn, int where, int size, u32 *val) { int ret = PCIBIOS_SUCCESSFUL; u32 address, busdev; @@ -304,43 +305,43 @@ static int axxia_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, if (bus->parent->number == pp->root_bus_nr) { axxia_pcie_prog_viewport_cfg0(pp, busdev); ret = axxia_pcie_cfg_read(pp->va_cfg0_base + address, where, - size, val); + size, val); axxia_pcie_prog_viewport_mem_outbound(pp); } else { axxia_pcie_prog_viewport_cfg1(pp, busdev); ret = axxia_pcie_cfg_read(pp->va_cfg1_base + address, where, - size, val); + size, val); axxia_pcie_prog_viewport_io_outbound(pp); } return ret; } static int axxia_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, - u32 devfn, int where, int size, u32 val) + u32 devfn, int where, int size, u32 val) { int ret = PCIBIOS_SUCCESSFUL; u32 address, busdev; busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | - PCIE_ATU_FUNC(PCI_FUNC(devfn)); + PCIE_ATU_FUNC(PCI_FUNC(devfn)); address = where & ~0x3; if (bus->parent->number == pp->root_bus_nr) { axxia_pcie_prog_viewport_cfg0(pp, busdev); ret = axxia_pcie_cfg_write(pp->va_cfg0_base + address, - where, size, val); + where, size, val); axxia_pcie_prog_viewport_mem_outbound(pp); } else { axxia_pcie_prog_viewport_cfg1(pp, busdev); ret = axxia_pcie_cfg_write(pp->va_cfg1_base + address, - where, size, val); + where, size, val); axxia_pcie_prog_viewport_io_outbound(pp); } return ret; } static int axxia_pcie_valid_config(struct pcie_port *pp, - struct pci_bus *bus, int dev) + struct pci_bus *bus, int dev) { /* If there is no link, then there is no device */ if (bus->number != pp->root_bus_nr) { @@ -364,11 +365,11 @@ static int axxia_pcie_valid_config(struct pcie_port *pp, /* -* Read PCI config space -*/ + * Read PCI config space + */ static int axxia_pciex_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) { + int offset, int len, u32 *val) { struct pcie_port *pp = bus->sysdata; int ret; @@ -379,7 +380,7 @@ axxia_pciex_read_config(struct pci_bus *bus, unsigned int devfn, if (bus->number != pp->root_bus_nr) ret = axxia_pcie_rd_other_conf(pp, bus, devfn, - offset, len, val); + offset, len, val); else ret = axxia_pcie_rd_own_conf(pp, offset, len, val); @@ -387,11 +388,11 @@ axxia_pciex_read_config(struct pci_bus *bus, unsigned int devfn, } /* -* Write PCI config space. -*/ + * Write PCI config space. + */ static int axxia_pciex_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) + int offset, int len, u32 val) { struct pcie_port *pp = bus->sysdata; int ret; @@ -401,7 +402,7 @@ axxia_pciex_write_config(struct pci_bus *bus, unsigned int devfn, if (bus->number != pp->root_bus_nr) ret = axxia_pcie_wr_other_conf(pp, bus, devfn, - offset, len, val); + offset, len, val); else ret = axxia_pcie_wr_own_conf(pp, offset, len, val); @@ -421,14 +422,14 @@ static struct irq_chip axxia_dw_msi_irq_chip = { }; static int axxia_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hwirq) + irq_hw_number_t hwirq) { irq_set_chip_and_handler(irq, &axxia_dw_msi_irq_chip, - handle_simple_irq); + handle_simple_irq); irq_set_chip_data(irq, domain->host_data); set_irq_flags(irq, IRQF_VALID); -return 0; + return 0; } static const struct irq_domain_ops axxia_msi_domain_ops = { @@ -442,7 +443,7 @@ void axxia_dw_pcie_msi_init(struct pcie_port *pp) /* program the msi_data */ axxia_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4, - virt_to_phys((void *)pp->msi_data)); + virt_to_phys((void *)pp->msi_data)); axxia_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0); } @@ -455,16 +456,16 @@ irqreturn_t axxia_dw_handle_msi_irq(struct pcie_port *pp) for (i = 0; i < MAX_MSI_CTRLS; i++) { axxia_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, - (u32 *)&val); + (u32 *)&val); if (val) { ret = IRQ_HANDLED; pos = 0; while ((pos = find_next_bit(&val, 32, pos)) != 32) { irq = irq_find_mapping(pp->irq_domain, - i * 32 + pos); + i * 32 + pos); axxia_pcie_wr_own_conf(pp, - PCIE_MSI_INTR0_STATUS + i * 12, - 4, 1 << pos); + PCIE_MSI_INTR0_STATUS + i * 12, + 4, 1 << pos); generic_handle_irq(irq); pos++; } @@ -586,14 +587,14 @@ static irqreturn_t axxia_pcie_irq_handler(int irq, void *arg) pr_info("RADM_INTA_ASSERTED\n"); /* Clear the legacy interrupts */ axxia_cc_gpreg_writel(pp, val, - CC_GPREG_EDG_IRQ_STAT); + CC_GPREG_EDG_IRQ_STAT); if (IS_ENABLED(CONFIG_PCI_MSI)) { axxia_cc_gpreg_readl(pp, CC_GPREG_EDG_IRQ_STAT_HI, &val); if (val & MSI_ASSERTED) { ret = axxia_dw_handle_msi_irq(pp); axxia_cc_gpreg_writel(pp, MSI_ASSERTED, - CC_GPREG_EDG_IRQ_STAT_HI); + CC_GPREG_EDG_IRQ_STAT_HI); return ret; } } @@ -613,7 +614,7 @@ static void axxia_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, - unsigned int nvec, unsigned int pos) + unsigned int nvec, unsigned int pos) { unsigned int i; @@ -646,7 +647,7 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) struct pcie_port *pp = desc->dev->bus->sysdata; pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, - order_base_2(no_irqs)); + order_base_2(no_irqs)); if (pos0 < 0) goto no_valid_irq; @@ -678,8 +679,8 @@ no_valid_irq: } static int axxia_dw_msi_setup_irq(struct msi_controller *chip, - struct pci_dev *pdev, - struct msi_desc *desc) + struct pci_dev *pdev, + struct msi_desc *desc) { int irq, pos; struct msi_msg msg; @@ -699,7 +700,7 @@ static int axxia_dw_msi_setup_irq(struct msi_controller *chip, } static void axxia_dw_msi_teardown_irq(struct msi_controller *chip, - unsigned int irq) + unsigned int irq) { struct irq_data *data = irq_get_irq_data(irq); struct msi_desc *msi = irq_data_get_msi(data); @@ -745,19 +746,19 @@ int axxia_pcie_host_init(struct pcie_port *pp) of_pci_range_to_resource(&range, np, &pp->io); pp->io.name = "I/O"; pp->io.start = max_t(resource_size_t, - PCIBIOS_MIN_IO, - range.pci_addr + global_io_offset); + PCIBIOS_MIN_IO, + range.pci_addr + global_io_offset); pp->io.end = min_t(resource_size_t, - IO_SPACE_LIMIT, - range.pci_addr + range.size - + global_io_offset - 1); + IO_SPACE_LIMIT, + range.pci_addr + range.size + + global_io_offset - 1); pp->io_size = resource_size(&pp->io); pp->io_bus_addr = range.pci_addr; pp->io_base = range.cpu_addr; /* Find the untranslated IO space address */ pp->io_mod_base = of_read_number(parser.range - - parser.np + na, ns); + parser.np + na, ns); } if (restype == IORESOURCE_MEM) { of_pci_range_to_resource(&range, np, &pp->mem); @@ -767,7 +768,7 @@ int axxia_pcie_host_init(struct pcie_port *pp) /* Find the untranslated MEM space address */ pp->mem_mod_base = of_read_number(parser.range - - parser.np + na, ns); + parser.np + na, ns); pp->mem_mod_base = pp->mem.start; } if (restype == 0) { @@ -786,7 +787,7 @@ int axxia_pcie_host_init(struct pcie_port *pp) pp->busn.end = 0xff; pp->busn.flags = IORESOURCE_BUS; dev_dbg(pp->dev, - "failed to parse bus-range property: %d, using default %pR\n", + "failed to parse bus-range property: %d, using default %pR\n", ret, &pp->busn); } @@ -797,7 +798,7 @@ int axxia_pcie_host_init(struct pcie_port *pp) if (!pp->va_cfg0_base) { pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, - pp->cfg0_size); + pp->cfg0_size); if (!pp->va_cfg0_base) { dev_err(pp->dev, "error with ioremap in function\n"); return -ENOMEM; @@ -806,7 +807,7 @@ int axxia_pcie_host_init(struct pcie_port *pp) if (!pp->va_cfg1_base) { pp->va_cfg1_base = devm_ioremap(pp->dev, pp->cfg1_base, - pp->cfg1_size); + pp->cfg1_size); if (!pp->va_cfg1_base) { dev_err(pp->dev, "error with ioremap\n"); return -ENOMEM; @@ -829,7 +830,7 @@ int axxia_pcie_host_init(struct pcie_port *pp) return -ENODEV; } ret = devm_request_irq(pp->dev, pp->irq[0], axxia_pcie_irq_handler, - IRQF_SHARED, "axxia-pcie", pp); + IRQF_SHARED, "axxia-pcie", pp); if (ret) { dev_err(pp->dev, "failed to request irq\n"); return ret; @@ -837,8 +838,8 @@ int axxia_pcie_host_init(struct pcie_port *pp) if (IS_ENABLED(CONFIG_PCI_MSI)) { pp->irq_domain = irq_domain_add_linear(pp->dev->of_node, - MAX_MSI_IRQS, &axxia_msi_domain_ops, - &axxia_dw_pcie_msi_chip); + MAX_MSI_IRQS, &axxia_msi_domain_ops, + &axxia_dw_pcie_msi_chip); if (!pp->irq_domain) { dev_err(pp->dev, "irq domain init failed\n"); return -ENXIO; @@ -854,7 +855,7 @@ int axxia_pcie_host_init(struct pcie_port *pp) axxia_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); bus = pci_create_root_bus(&pdev->dev, pp->root_bus_nr, - &axxia_pciex_pci_ops, pp, &res); + &axxia_pciex_pci_ops, pp, &res); if (!bus) return 1; #ifdef CONFIG_PCI_MSI @@ -880,9 +881,10 @@ static int axxia_pcie_probe(struct platform_device *pdev) int ret; struct device_node *pei_control; const unsigned int *control; + const unsigned int *initialized; axxia_pcie = devm_kzalloc(&pdev->dev, sizeof(*axxia_pcie), - GFP_KERNEL); + GFP_KERNEL); if (!axxia_pcie) return -ENOMEM; @@ -919,14 +921,27 @@ static int axxia_pcie_probe(struct platform_device *pdev) } axxia_pcie->control = be32_to_cpu(*control); - control_set = 1; control_value = axxia_pcie->control; + control_set = 1; - if (0 != pei_setup(axxia_pcie->control)) { - pr_err("pcie-axxia: PEI setup failed!\n"); + /* + Previously, if the boot loader set 'control', it did + not initialized the PEI. Start with that + assumption. + */ - return -EINVAL; - } + axxia_pcie->initialized = 1; + initialized = of_get_property(pei_control, "initialized", NULL); + + if (NULL != initialized) + axxia_pcie->initialized = be32_to_cpu(*initialized); + + if (0 == axxia_pcie->initialized) + if (0 != pei_setup(axxia_pcie->control)) { + pr_err("pcie-axxia: PEI setup failed!\n"); + + return -EINVAL; + } } ret = axxia_pcie_host_init(pp); @@ -959,16 +974,18 @@ static struct platform_driver axxia_pcie_driver = { }, }; -/* Axxia PCIe driver does not allow module unload */ +/* + ------------------------------------------------------------------------------ + axxia_pcie_reset +*/ -static ssize_t -axxia_pcie_reset_trigger(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) +int +axxia_pcie_reset(void) { unsigned int val; - if (0 == control_set) - return count; + if (0 == control_set || NULL == _pp) + return -1; pei_setup(control_value); @@ -978,9 +995,22 @@ axxia_pcie_reset_trigger(struct file *file, const char __user *buf, axxia_cc_gpreg_writel(_pp, 0x1, PEI_GENERAL_CORE_CTL_REG); msleep(100); + return 0; +} + +EXPORT_SYMBOL(axxia_pcie_reset); + +static ssize_t +axxia_pcie_reset_trigger(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + axxia_pcie_reset(); + return count; } +/* Axxia PCIe driver does not allow module unload */ + static int pcie_init(void) { return platform_driver_register(&axxia_pcie_driver); @@ -995,7 +1025,7 @@ static const struct file_operations axxia_pcie_reset_proc_ops = { static int pcie2_init(void) { if (0 != proc_create("driver/axxia_pcie_reset", S_IWUSR, NULL, - &axxia_pcie_reset_proc_ops)) { + &axxia_pcie_reset_proc_ops)) { pr_err("Could not create /proc/driver/axxia_pcie_reset!\n"); return -1; @@ -1003,8 +1033,9 @@ static int pcie2_init(void) return 0; } + device_initcall(pcie2_init); -MODULE_AUTHOR("Sangeetha Rao <sangeetha....@intel.com>"); +MODULE_AUTHOR("John Jacques <john.jacq...@intel.com>"); MODULE_DESCRIPTION("Axxia PCIe host controller driver"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/axxia-pei.h b/include/linux/axxia-pei.h index e38c331..4f2ed1c 100644 --- a/include/linux/axxia-pei.h +++ b/include/linux/axxia-pei.h @@ -20,5 +20,6 @@ #define __AXXIA_PEI_H int pei_setup(unsigned int); +int axxia_pcie_reset(void); #endif /* __AXXIA_PEI_H */ -- 2.7.4 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto