From: John Jacques <[email protected]>
Signed-off-by: John Jacques <[email protected]>
---
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 <[email protected]>
-*
-* 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 <[email protected]>
+ *
+ * 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 <[email protected]>");
+MODULE_AUTHOR("John Jacques <[email protected]>");
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
[email protected]
https://lists.yoctoproject.org/listinfo/linux-yocto