From: Gary McGee <gary.mc...@intel.com>

Signed-off-by: Gary McGee <gary.mc...@intel.com>
---
 drivers/misc/axxia-pei.c      | 1465 +++++++++++++++++++++++------------------
 drivers/pci/host/pcie-axxia.c |  146 ++--
 include/linux/axxia-pei.h     |    6 +-
 3 files changed, 917 insertions(+), 700 deletions(-)

diff --git a/drivers/misc/axxia-pei.c b/drivers/misc/axxia-pei.c
index 7a5b255..7996e9c 100644
--- a/drivers/misc/axxia-pei.c
+++ b/drivers/misc/axxia-pei.c
@@ -31,17 +31,29 @@
 #include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/lsi-ncr.h>
+#include <linux/mutex.h>
 
 static int is_5500;
 static int is_5600;
 static int is_6700;
 
 static void __iomem *pcie_gpreg0;
+static void __iomem *pcie_gpreg1;
+static void __iomem *pcie_gpreg2;
 static void __iomem *pcie_rc;
 
+static int pcie_cc_gpreg_offset = 0x8000;
 static int is_pei_control_available;
 static int is_pei_control_v2;
 
+DEFINE_MUTEX(axxia_pei_mux);
+
+struct axxia_pei {
+       unsigned int    control;
+       int             control_set;
+       unsigned int    initialized;
+};
+
 struct pei_coefficients {
        unsigned version;
        unsigned control;
@@ -57,6 +69,7 @@ struct pei_coefficients {
        unsigned lane_1_vboost;
 };
 
+static struct axxia_pei axxia_pei;
 static struct pei_coefficients coefficients;
 
 enum SataMode {
@@ -79,6 +92,12 @@ enum SrioSpeed {
        SRIO_SPEED_5G,
        SRIO_SPEED_6_25G
 };
+
+enum PCIMode {
+       PEI0,
+       PEI1,
+       PEI2
+};
 enum PLLMode {
        PLLA,
        PLLB
@@ -94,6 +113,37 @@ enum Dir {
        RX
 };
 
+/* PEI0x8 000/010 which is valid? */
+enum port_config0 {
+       pc0_PEI0x8 = 0x0,
+       pc0_PEI0x4 = 0x1,
+       pc0_PEI0x8_alt = 0x2,
+       pc0_PEI0x2_PEI2x2 = 0x3,
+       pc0_SRIO1x2_SRIO0x2 = 0x4,
+       pc0_PEI0x2_SRIO0x2 = 0x7,
+};
+
+enum port_config1 {
+       pc1_PEI0x8 = 0x0,
+       pc1_PEI1x4 = 0x1,
+       pc1_PEI1x2_SATA0x1_SATA1x1 = 0x2,
+       pc1_PEI1x2_PEI2x2 = 0x3,
+};
+
+enum pipe_port {
+       pp_disable = 0x0,
+       pp_0 = 0x1,
+       pp_0_1 = 0x2,
+       pp_0_1_2_3 = 0x3,
+};
+
+enum pipe_nphy {
+       one_phy = 0x0,
+       two_phy = 0x1,
+       three_phy = 0x2,
+       four_phy = 0x3,
+};
+
 /******************************************************************************
  * PCIe/SRIO/SATA parameters
  * Supported configs:
@@ -185,7 +235,7 @@ enum Dir {
  * Bit 2: PEI2 enabled
  * Bit 1: PEI1 enabled
  * Bit 0: PEI0 enabled
- 
*******************************************************************************/
+ 
******************************************************************************/
 
 void setup_sata_mode(enum SataMode mode, enum SataSpeed speed)
 {
@@ -369,6 +419,7 @@ void setup_srio_mode(enum SrioMode mode, enum SrioSpeed 
speed)
        u32 regVal;
        u32 phy, lane, rate, width, pll;
        int i = 0;
+
        if (mode == SRIO0) {
                phy = 1;
                lane = 2;
@@ -566,69 +617,172 @@ void setup_srio_mode(enum SrioMode mode, enum SrioSpeed 
speed)
        }
 }
 
+void disable_ltssm(enum PCIMode mode)
+{
+       u32 val;
+
+       if (!is_5600 && !is_6700)
+               return;
+
+       switch (mode) {
+       case PEI0:
+               /* LTSSM Disable for PEI0 */
+               val = readl(pcie_gpreg0 + pcie_cc_gpreg_offset + 0x38);
+               val &= (~(0x1));
+               writel(val, pcie_gpreg0 + pcie_cc_gpreg_offset + 0x38);
+               break;
+       case PEI1:
+               /* LTSSM Disable for PEI1 */
+               if (!is_5600)
+                       break;
+               val = readl(pcie_gpreg1 + pcie_cc_gpreg_offset + 0x38);
+               val &= (~(0x1));
+               writel(val, pcie_gpreg1 + pcie_cc_gpreg_offset + 0x38);
+               break;
+       case PEI2:
+               /* LTSSM Disable for PEI2 */
+               if (!is_5600)
+                       break;
+               val = readl(pcie_gpreg2 + pcie_cc_gpreg_offset + 0x38);
+               val &= (~(0x1));
+               writel(val, pcie_gpreg2 + pcie_cc_gpreg_offset + 0x38);
+               break;
+       default:
+               pr_err("%s Unsupported PEI %d\n", __func__, mode);
+       };
+
+       mdelay(100);            /* TODO: Why is this needed? */
+}
+
+void set_sw_port_config0(enum port_config0 mode)
+{
+       u32 regVal;
+
+       ncr_read32(NCP_REGION_ID(0x115, 0), 0, &regVal);
+       regVal &= ~(0x7 << 26);
+       regVal |= ((mode & 0x7) << 26);
+       ncr_write32(NCP_REGION_ID(0x115, 0), 0, regVal);
+}
+
+void set_sw_port_config1(enum port_config1 mode)
+{
+       u32 regVal;
+
+       ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &regVal);
+       regVal &= ~(0x3 << 22);
+       regVal |= ((mode & 0x3) << 22);
+       ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
+}
+
+static void set_pipe_port_sel(enum pipe_port pp)
+{
+       u32 regVal;
+
+       ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &regVal);
+       regVal &= ~(0x3 << 24);
+       regVal |= ((pp & 0x3) << 24);
+       ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
+}
+
+static void set_pipe_nphy(enum pipe_nphy nphy)
+{
+       u32 regVal;
+
+       ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &regVal);
+       regVal &= ~(0x3 << 20);
+       regVal |= ((nphy & 0x3) << 20);
+       ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
+}
+
+static void set_srio_mode(enum SrioMode mode, unsigned int ctrl)
+{
+       u32 regVal;
+
+       ncr_read32(NCP_REGION_ID(0x115, 0), 0, &regVal);
+       if (SRIO0 == mode) {
+               regVal &= ~(0x3 << 20);
+               regVal |= ((ctrl & 0x3) << 20);
+       } else {
+               regVal &= ~(0x3 << 24);
+               regVal |= ((ctrl & 0x3) << 24);
+       }
+       ncr_write32(NCP_REGION_ID(0x115, 0), 0, regVal);
+}
+
+static void set_srio_speed(enum SrioMode mode, enum SrioSpeed speed)
+{
+       u32 regVal;
+
+       ncr_read32(NCP_REGION_ID(0x115, 0x0), 0x4, &regVal);
+       if (SRIO0 == mode) {
+               regVal &= ~(0x7 << 12);
+               regVal |= ((speed & 0x7) << 12);
+       } else {
+               regVal &= ~(0x7 << 16);
+               regVal |= ((speed & 0x7) << 16);
+       }
+       ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
+}
+
+static void set_pei0_rc_mode(u32 rc)
+{
+       u32 regVal;
+
+       ncr_read32(NCP_REGION_ID(0x115, 0x0), 0x0, &regVal);
+       if (rc)
+               regVal |= (0x1 << 22);
+       else
+               regVal &= ~(0x1 << 22);
+       ncr_write32(NCP_REGION_ID(0x115, 0x0), 0x0, regVal);
+}
+
 void enable_reset(u32 phy)
 {
        u32 regVal;
 
        if (phy == 0) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &regVal);
                regVal |= (1 << 5);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, regVal);
        } else if (phy == 1) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &regVal);
                regVal |= (1 << 14);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, regVal);
        } else if (phy == 2) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &regVal);
                regVal |= (1 << 19);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
        } else if (phy == 3) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &regVal);
                regVal |= (1 << 29);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
        }
 }
 
-void release_reset(u32 phy)
+static void release_reset(u32 phy)
 {
        u32 regVal;
 
        if (phy == 0) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &regVal);
                regVal &= (~(1 << 5));
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, regVal);
        } else if (phy == 1) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &regVal);
                regVal &= (~(1 << 14));
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, regVal);
        } else if (phy == 2) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &regVal);
                regVal &= (~(1 << 19));
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
        } else if (phy == 3) {
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4,
-                          &regVal);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &regVal);
                regVal &= (~(1 << 29));
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4,
-                           regVal);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, regVal);
        }
 }
 
-int check_pll_lock(enum PLLMode mode, u32 phy)
+static int check_pll_lock(enum PLLMode mode, u32 phy)
 {
        u32 regVal;
        int count = 0;
@@ -647,7 +801,36 @@ int check_pll_lock(enum PLLMode mode, u32 phy)
        return regVal;
 }
 
-int check_ack(u32 phy, u32 lane, enum Dir dir)
+static int release_srio_reset(enum SrioMode mode, enum SrioSpeed speed)
+{
+       u32 phy;
+       enum PLLMode pll;
+
+       switch (mode) {
+       case SRIO0:
+               phy = 1;
+               break;
+       case SRIO1:
+               phy = 0;
+               break;
+       default:
+               pr_err("Wrong SRIO%d\n", mode);
+               return 1;
+       }
+
+       release_reset(phy);
+       pll = PLLA;
+       if ((SRIO_SPEED_3_125G == speed) ||
+           (SRIO_SPEED_6_25G == speed))
+               pll = PLLB;
+       if (!check_pll_lock(pll, phy)) {
+               pr_err("%s didn't lock\n", pll == PLLA ? "PLLA" : "PLLB");
+               return 1;
+       }
+       return 0;
+}
+
+static int check_ack(u32 phy, u32 lane, enum Dir dir)
 {
        u32 regVal;
        int count = 0;
@@ -672,6 +855,33 @@ int check_ack(u32 phy, u32 lane, enum Dir dir)
        return regVal;
 }
 
+static int check_srio_ack(enum SrioMode mode)
+{
+       unsigned int phy;
+       unsigned int lane;
+
+       switch (mode) {
+       case SRIO0:
+               phy = 1;
+               break;
+       case SRIO1:
+               phy = 0;
+               break;
+       default:
+               pr_err("Wrong SRIO%d\n", mode);
+               return 1;
+       }
+
+       for (lane = 0; lane < 2; lane++) {
+               if (!check_ack(phy, lane, RX)) {
+                       pr_err("RX ACK not set for PHY%d LANE%d\n", phy, lane);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 void set_tx_clk_ready(void)
 {
        u32 regVal;
@@ -733,6 +943,40 @@ powerup_lane(u32 phy, u32 lane, enum PowerState state, 
enum Dir dir)
        return ret;
 }
 
+static int
+powerup_srio_lanes(enum SrioMode mode, enum PowerState state)
+{
+       u32 lane;
+       u32 phy;
+
+       switch (mode) {
+       case SRIO0:
+               phy = 1;
+               break;
+       case SRIO1:
+               phy = 0;
+               break;
+       default:
+               pr_err("Wrong SRIO%d\n", mode);
+               return 1;
+       }
+
+       /* Power up TX/RX lanes */
+       for (lane = 0; lane < 2; lane++) {
+               if (!powerup_lane(phy, lane, state, TX)) {
+                       pr_err("TX powerup failed for PHY%d LANE%d\n",
+                              phy, lane);
+                       return 1;
+               }
+               if (!powerup_lane(phy, lane, state, RX)) {
+                       pr_err("RX powerup failed for PHY%d LANE%d\n",
+                              phy, lane);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 /*
   
------------------------------------------------------------------------------
   enable_lane
@@ -757,8 +1001,29 @@ enable_lane(u32 phy, u32 lane, enum Dir dir)
                regVal |= (1 << 21);
 
        ncr_write32(NCP_REGION_ID(0x115, 0), offset, regVal);
+}
 
-       return;
+static void enable_srio_lanes(enum SrioMode mode)
+{
+       u32 lane;
+       u32 phy;
+
+       switch (mode) {
+       case SRIO0:
+               phy = 1;
+               break;
+       case SRIO1:
+               phy = 0;
+               break;
+       default:
+               pr_err("Wrong SRIO%d\n", mode);
+               return;
+       }
+
+       for (lane = 0; lane < 2; lane++) {
+               enable_lane(phy, lane, TX);
+               enable_lane(phy, lane, RX);
+       }
 }
 
 /*
@@ -900,7 +1165,6 @@ update_settings(void)
                ncr_write32(region, offset, value);
        }
 
-       return;
 }
 
 
@@ -909,15 +1173,11 @@ update_settings(void)
   pei_setup
 */
 
-int
-pei_setup(void)
+static int
+pei_setup(unsigned int control)
 {
-       unsigned int control;
        unsigned int pci_srio_sata_mode;
-       unsigned int val;
        unsigned int rc_mode;
-       unsigned int phyVal0;
-       unsigned int phyVal1;
        unsigned int srio0_mode;
        unsigned int srio1_mode;
        unsigned int srio0_speed;
@@ -928,19 +1188,18 @@ pei_setup(void)
        unsigned int sata1_mode;
        unsigned int srio0_ctrl;
        unsigned int srio1_ctrl;
-       unsigned int reg_val = 0;
-       enum PLLMode pll;
+       unsigned int pei0_mode;
+       unsigned int pei1_mode;
+       unsigned int pei2_mode;
+       u32 reg_val = 0;
        int phy, lane;
 
-       if (!is_pei_control_available) {
-               pr_err("Control value is NOT available!\n");
-
-               return 1;
-       }
-
-       control = coefficients.control;
-
        pci_srio_sata_mode = (control & 0x03c00000) >> 22;
+       /*
+       pr_debug("YYY: pei_setup control=0x%08x pci_srio_sata_mode=%d\n",
+               control, pci_srio_sata_mode);
+       */
+
        sata0_mode = (control & 0x20) >> 5;
        sata1_mode = (control & 0x40) >> 6;
 
@@ -953,749 +1212,578 @@ pei_setup(void)
        srio0_speed = (control & 0x7000) >> 12;
        srio1_speed = (control & 0x38000) >> 15;
 
-       /* LTSSM Disable for PEI0 */
-       val = readl(pcie_gpreg0 + 0x8038);
-       val &= (~(0x1));
-       writel(val, pcie_gpreg0 + 0x8038);
-       msleep(100);
+       srio0_ctrl = (control & 0x300) >> 8;
+       srio1_ctrl = (control & 0xc00) >> 10;
+
+       pei0_mode = (control & 0x1);
+       pei1_mode = (control & 0x2) >> 1;
+       pei2_mode = (control & 0x4) >> 2;
+
+       rc_mode = (control & 0x80) >> 7;
+
+       disable_ltssm(PEI0);
+       disable_ltssm(PEI1);
+       disable_ltssm(PEI2);
 
        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), 0, phyVal0);
+       /* Disable all interfaces */
+       ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+       reg_val &= ~(0xf | (0x1 << 10) | (0x3 << 29));
+       ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
        mdelay(100);            /* TODO: Why is this needed? */
 
        switch (pci_srio_sata_mode) {
        case 0:
-               /* PEI0x8 */
-               rc_mode = (control & 0x80)<<15;
-               /* Enable PEI0, PEI0 RC mode */
-               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));
+               set_sw_port_config0(pc0_PEI0x8);
+               set_sw_port_config1(pc1_PEI0x8);
+               set_pei0_rc_mode(rc_mode);
+               set_pipe_port_sel(pp_0);
+               set_pipe_nphy(four_phy);
+
+               if (pei0_mode)
+                       for (phy = 0; phy < 4; phy++)
+                               release_reset(phy);
+
+               /* Enable PEI0 */
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &reg_val);
+               reg_val |= (pei0_mode << 0);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, reg_val);
                break;
        case 1:
                /*
                  PEI0x4, PEI1x4
                */
-               phyVal1 = 0x0e7001ac;
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0x4, phyVal1);
-
-               phyVal0 = 0x84400040;
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0);
+               set_sw_port_config0(pc0_PEI0x4);
+               set_sw_port_config1(pc1_PEI1x4);
+               set_pei0_rc_mode(rc_mode);
+               set_pipe_port_sel(pp_0_1);
+               set_pipe_nphy(four_phy);
+
+               if (pei0_mode)
+                       for (phy = 0; phy < 2; phy++)
+                               release_reset(phy);
+               if (pei1_mode)
+                       for (phy = 2; phy < 4; phy++)
+                               release_reset(phy);
+
+               /* Enable PEI0/PEI1 */
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0x0, &reg_val);
+               reg_val |=
+                       (pei0_mode << 0) |
+                       (pei1_mode << 1);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0x0, reg_val);
                break;
        case 2:
                /* PEI0x4_PEI1x2_SATA0x1_SATA1x1 */
-               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), 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);
+               set_sw_port_config0(pc0_PEI0x4);
+               set_sw_port_config1(pc1_PEI1x2_SATA0x1_SATA1x1);
+               set_pei0_rc_mode(rc_mode);
+               set_pipe_port_sel(pp_0_1);
+
+               if (pei0_mode)
+                       for (phy = 0; phy < 2; phy++)
+                               release_reset(phy);
+               if (pei1_mode)
+                       release_reset(2);
+
+               /* Enable PEI0/PEI1 */
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (pei0_mode << 0) | (pei1_mode << 1);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+
                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;
-               }
-               for (lane = 0; lane < 2; lane++) {
-                       if (!check_ack(3, lane, TX)) {
-                               printk("TX ACK not set for PHY3 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!check_ack(3, lane, RX)) {
-                               printk("RX ACK not set for PHY3 LANE%d\n", 
lane);
-                               return 1;
+               if (sata0_mode || sata1_mode) {
+                       release_reset(3);
+                       for (lane = 0; lane < 2; lane++) {
+                               if (!check_ack(3, lane, TX)) {
+                                       pr_err("TX ACK not set for PHY3 
LANE%d\n",
+                                              lane);
+                                       return 1;
+                               }
+                               if (!check_ack(3, lane, RX)) {
+                                       pr_err("RX ACK not set for PHY3 
LANE%d\n",
+                                              lane);
+                                       return 1;
+                               }
                        }
-               }
 
-               /* Set TX clock ready */
-               set_tx_clk_ready();
+                       /* Set TX clock ready */
+                       set_tx_clk_ready();
+               }
 
                /* Enable SATA0/SATA1 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &phyVal0);
-               phyVal0 |= (control & 0x20) << 24;
-               phyVal0 |= (control & 0x40) << 24;
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (sata0_mode << 29) | (sata1_mode << 30);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
 
-               if (!check_rx_valid(3, 0)) {
-                       printk("RX clock/data recovery not asserted for PHY3 
LANE0\n");
-                       return 1;
-               }
-               if (!check_rx_valid(3, 1)) {
-                       printk("RX clock/data recovery not asserted for PHY3 
LANE1\n");
-                       return 1;
+               if (sata0_mode || sata1_mode) {
+                       if (!check_rx_valid(3, 0)) {
+                               pr_err("RX clock/data recovery not asserted for 
PHY3 LANE0\n");
+                               return 1;
+                       }
+                       if (!check_rx_valid(3, 1)) {
+                               pr_err("RX clock/data recovery not asserted for 
PHY3 LANE1\n");
+                               return 1;
+                       }
                }
                break;
        case 3:
-               /* PEI0x2_PEI2x2_PEI1x2_SATA0x1_SATA1x1 */
-               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), 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);
+               set_sw_port_config0(pc0_PEI0x2_PEI2x2);
+               set_sw_port_config1(pc1_PEI1x2_SATA0x1_SATA1x1);
+               set_pei0_rc_mode(rc_mode);
+               set_pipe_port_sel(pp_0_1_2_3);
+
+               if (pei0_mode)
+                       release_reset(0);
+               if (pei1_mode)
+                       release_reset(1);
+               if (pei2_mode)
+                       release_reset(2);
+
+               /* Enable PEI0/PEI1/PEI2 */
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (pei0_mode << 0) | (pei1_mode << 1) |
+                       (pei2_mode << 2);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+
                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;
-               }
-               for (lane = 0; lane < 2; lane++) {
-                       if (!check_ack(3, lane, TX)) {
-                               printk("TX ACK not set for PHY3 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!check_ack(3, lane, RX)) {
-                               printk("RX ACK not set for PHY3 LANE%d\n", 
lane);
-                               return 1;
+               if (sata0_mode || sata1_mode) {
+                       release_reset(3);
+                       for (lane = 0; lane < 2; lane++) {
+                               if (!check_ack(3, lane, TX)) {
+                                       pr_err("TX ACK not set for PHY3 
LANE%d\n",
+                                              lane);
+                                       return 1;
+                               }
+                               if (!check_ack(3, lane, RX)) {
+                                       pr_err("RX ACK not set for PHY3 
LANE%d\n",
+                                              lane);
+                                       return 1;
+                               }
                        }
+                       /* Set TX clock ready */
+                       set_tx_clk_ready();
                }
-               /* Set TX clock ready */
-               set_tx_clk_ready();
 
                /* Enable SATA0/SATA1 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               phyVal0 |= (control & 0x20) << 24;
-               phyVal0 |= (control & 0x40) << 24;
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (sata0_mode << 29) | (sata1_mode << 30);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
 
-               if (!check_rx_valid(3, 0)) {
-                       printk("RX clock/data recovery not asserted for PHY3 
LANE0\n");
-                       return 1;
-               }
-               if (!check_rx_valid(3, 1)) {
-                       printk("RX clock/data recovery not asserted for PHY3 
LANE1\n");
-                       return 1;
+               if (sata0_mode || sata1_mode) {
+                       if (!check_rx_valid(3, 0)) {
+                               pr_err("RX clock/data recovery not asserted for 
PHY3 LANE0\n");
+                               return 1;
+                       }
+                       if (!check_rx_valid(3, 1)) {
+                               pr_err("RX clock/data recovery not asserted for 
PHY3 LANE1\n");
+                               return 1;
+                       }
                }
                break;
        case 4:
                /* PEI0x2_SRIO0x2_PEI1x4 */
-               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_ctrl = ((control & 0x300) << 12);
+               set_sw_port_config0(pc0_PEI0x2_SRIO0x2);
+               set_sw_port_config1(pc1_PEI1x4);
+               set_pei0_rc_mode(rc_mode);
+               set_pipe_port_sel(pp_0_1);
+
+               if (pei0_mode)
+                       release_reset(0);
+               if (pei1_mode)
+                       for (phy = 2; phy < 4; phy++)
+                               release_reset(phy);
+
+               /* Enable PEI0/PEI1 */
                ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
-               reg_val &= ~(0xf | (0x1 << 22) | (0x7<<26) | (0x3 << 20));
-               reg_val |= phyVal0 | srio0_ctrl;
+               reg_val |= (pei0_mode << 0) | (pei1_mode << 1);
                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_read32(NCP_REGION_ID(0x115, 0), 0x4, &reg_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);
-               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(3, lane, RX)) {
-                               printk("RX ACK not set for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-               }
-               /* Power up TX/RX lanes */
-               for (lane = 0; lane < 2; lane++) {
-                       if (!powerup_lane(1, lane, P1, TX)) {
-                               printk("TX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!powerup_lane(1, lane, P1, RX)) {
-                               printk("RX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-               }
-
-               /* Set TX clock ready */
-               set_tx_clk_ready();
 
+               set_srio_mode(SRIO0, srio0_ctrl);
+               set_srio_speed(SRIO0, srio0_speed);
+               pr_debug("Set up sRIO0 -- %d\n", srio0_speed);
+               if (srio0_mode && release_srio_reset(SRIO0, srio0_speed))
+                       srio0_mode = 0;
+               pr_debug("Enabling sRIO .");
+               if (srio0_mode && check_srio_ack(SRIO0))
+                       srio0_mode = 0;
                /* Power up TX/RX lanes */
-               for (lane = 0; lane < 2; lane++) {
-                       if (!powerup_lane(1, lane, P0, TX)) {
-                               printk("TX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!powerup_lane(1, lane, P0, RX)) {
-                               printk("RX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-               }
-
-               for (lane = 0; lane < 2; lane++) {
-                       enable_lane(1, lane, TX);
-                       enable_lane(1, lane, RX);
-               }
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P1))
+                       srio0_mode = 0;
+               /* Set TX clock ready */
+               if (srio0_mode)
+                       set_tx_clk_ready();
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P0))
+                       srio0_mode = 0;
+               if (srio0_mode)
+                       enable_srio_lanes(SRIO0);
                /* Enable SRIO0 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           phyVal0 | 0x8);
-               printk("Done\n");
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (srio0_mode << 3);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+               pr_debug("Done\n");
                break;
        case 5:
                /* PEI0x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 */
-               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_ctrl = ((control & 0x300) << 12);
+               set_sw_port_config0(pc0_PEI0x2_SRIO0x2);
+               set_sw_port_config1(pc1_PEI1x2_SATA0x1_SATA1x1);
+               set_pei0_rc_mode(rc_mode);
+               set_pipe_port_sel(pp_0_1);
+               set_pipe_nphy(three_phy);
+
+               if (pei0_mode)
+                       release_reset(0);
+               if (pei1_mode)
+                       release_reset(2);
+
+               /* Enable PEI0/PEI1 */
                ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
-               reg_val &= ~(0xf | (0x1 << 22) | (0x7<<26) | (0x3 << 20));
-               reg_val |= phyVal0 | srio0_ctrl;
+               reg_val |= (pei0_mode << 0) | (pei1_mode << 1);
                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_read32(NCP_REGION_ID(0x115, 0), 0x4, &reg_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;
+
+               set_srio_mode(SRIO0, srio0_ctrl);
+               set_srio_speed(SRIO0, srio0_speed);
+
                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);
-               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(3, lane, TX)) {
-                               printk("TX ACK not set for PHY3 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!check_ack(3, lane, RX)) {
-                               printk("RX ACK not set for PHY3 LANE%d\n", 
lane);
-                               return 1;
-                       }
-               }
-               printk("Enabling sRIO/SATA .");
-               /* Power up TX/RX lanes */
-               for (lane = 0; lane < 2; lane++) {
-                       if (!powerup_lane(1, lane, P1, TX)) {
-                               printk("TX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!powerup_lane(1, lane, P1, RX)) {
-                               printk("RX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
+               pr_debug("Set up sRIO0 -- %d\n", srio0_speed);
+               if (srio0_mode && release_srio_reset(SRIO0, srio0_speed))
+                       srio0_mode = 0;
+               if (sata0_mode || sata1_mode)
+                       release_reset(3);
+               if (sata0_mode || sata1_mode) {
+                       for (lane = 0; lane < 2; lane++) {
+                               if (!check_ack(3, lane, TX)) {
+                                       pr_err("TX ACK not set for PHY3 
LANE%d\n",
+                                              lane);
+                                       return 1;
+                               }
+                               if (!check_ack(3, lane, RX)) {
+                                       pr_err("RX ACK not set for PHY3 
LANE%d\n",
+                                              lane);
+                                       return 1;
+                               }
                        }
                }
+               pr_debug("Enabling sRIO/SATA .");
+               if (srio0_mode && check_srio_ack(SRIO0))
+                       srio0_mode = 0;
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P1))
+                       srio0_mode = 0;
 
                /* Set TX clock ready */
-               set_tx_clk_ready();
+               if (srio0_mode || sata0_mode || sata1_mode)
+                       set_tx_clk_ready();
 
-               /* Power up TX/RX lanes */
-               for (lane = 0; lane < 2; lane++) {
-                       if (!powerup_lane(1, lane, P0, TX)) {
-                               printk("TX powerup failed for PHY1 LANE%d\n", 
lane);
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P0))
+                       srio0_mode = 0;
+               if (srio0_mode)
+                       enable_srio_lanes(SRIO0);
+
+               /* Enable SATA0/SATA1 */
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (sata0_mode << 29) | (sata1_mode << 30);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+
+               if (sata0_mode || sata1_mode) {
+                       if (!check_rx_valid(3, 0)) {
+                               pr_err("RX clock/data recovery not asserted for 
PHY3 LANE0\n");
                                return 1;
                        }
-                       if (!powerup_lane(1, lane, P0, RX)) {
-                               printk("RX powerup failed for PHY1 LANE%d\n", 
lane);
+                       if (!check_rx_valid(3, 1)) {
+                               pr_err("RX clock/data recovery not asserted for 
PHY3 LANE1\n");
                                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), 0, &phyVal0);
-               phyVal0 |= (control & 0x20) << 24;
-               phyVal0 |= (control & 0x40) << 24;
-               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");
-                       return 1;
-               }
-               if (!check_rx_valid(3, 1)) {
-                       printk("RX clock/data recovery not asserted for PHY3 
LANE1\n");
-                       return 1;
-               }
                /* Enable SRIO0 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           phyVal0 | 0x8);
-               printk("Done\n");
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (srio0_mode << 3);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+               pr_debug("Done\n");
                break;
        case 6:
                /* PEI0x2_SRIO0x2_PEI1x2_PEI2x2 */
-               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_ctrl = ((control & 0x300) << 12);
+               set_pei0_rc_mode(rc_mode);
+               set_sw_port_config0(pc0_PEI0x2_SRIO0x2);
+               set_sw_port_config1(pc1_PEI1x2_PEI2x2);
+               set_pipe_port_sel(pp_0_1_2_3);
+               set_pipe_nphy(three_phy);
+
+               if (pei0_mode)
+                       release_reset(0);
+               if (pei1_mode)
+                       release_reset(2);
+               if (pei2_mode)
+                       release_reset(3);
+
+               /* Enable PEI0/PEI1/PEI2 */
                ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
-               reg_val &= ~(0xf | (0x1 << 22) | (0x7<<26) | (0x3 << 20));
-               reg_val |= phyVal0 | srio0_ctrl;
+               reg_val |= (pei0_mode << 0) | (pei1_mode << 1) |
+                       (pei2_mode << 2);
                ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
-               /* PEI1x2_PEI2x2 */
-               phyVal1 = (0x3 << 22);
-               /* PIPE port select -- Enable PIPE0, PIPE1
-                * and PIPE2 interface */
-               phyVal1 |= (0x3 << 24);
-               /* SRIO0 speed */
-               srio0_speed = (control & 0x7000);
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &reg_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)
+
+               set_srio_mode(SRIO0, srio0_ctrl);
+               set_srio_speed(SRIO0, srio0_speed);
+               if (srio0_mode) {
+                       pr_err("Set up sRIO0 -- %d\n", srio0_speed);
                        setup_srio_mode(SRIO0, srio0_speed);
-               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;
+                       if (release_srio_reset(SRIO0, srio0_speed))
+                               srio0_mode = 0;
                }
 
-               printk("Enabling sRIO .");
-               /* Power up TX/RX lanes */
-               for (lane = 0; lane < 2; lane++) {
-                       if (!powerup_lane(1, lane, P1, TX)) {
-                               printk("TX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!powerup_lane(1, lane, P1, RX)) {
-                               printk("RX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-               }
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P1))
+                       srio0_mode = 0;
 
                /* Set TX clock ready */
-               set_tx_clk_ready();
+               if (srio0_mode) {
+                       set_tx_clk_ready();
 
-               /* Power up TX/RX lanes */
-               for (lane = 0; lane < 2; lane++) {
-                       if (!powerup_lane(1, lane, P0, TX)) {
-                               printk("TX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
-                       if (!powerup_lane(1, lane, P0, RX)) {
-                               printk("RX powerup failed for PHY1 LANE%d\n", 
lane);
-                               return 1;
-                       }
+                       if (powerup_srio_lanes(SRIO0, P0))
+                               srio0_mode = 0;
                }
+               if (srio0_mode)
+                       enable_srio_lanes(SRIO0);
 
-               for (lane = 0; lane < 2; lane++) {
-                       enable_lane(1, lane, TX);
-                       enable_lane(1, lane, RX);
-               }
                /* Enable SRIO0 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           phyVal0 | 0x8);
-               printk("Done\n");
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (srio0_mode << 3);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+               pr_debug("Done\n");
                break;
        case 7:
                /* SRIO1x2_SRIO0x2_PEI1x4 */
                /* Enable PEI1/SRIO0/SRIO1 */
-               phyVal0 = (control & 0x2);
-               /* SRIO1x2_SRIO0x2 */
-               phyVal0 |= (0x4 << 26);
-               /* SRIO0 mode */
-               srio0_ctrl = ((control & 0x300) << 12);
-               /* SRIO1 mode */
-               srio1_ctrl = ((control & 0xC00) << 14);
+               set_sw_port_config0(pc0_SRIO1x2_SRIO0x2);
+               set_sw_port_config1(pc1_PEI1x4);
+               set_pipe_port_sel(pp_0_1);
+               set_pipe_nphy(four_phy);
+
+               if (pei1_mode)
+                       for (phy = 2; phy < 4; phy++)
+                               release_reset(phy);
+               /* Enable PEI1 */
                ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
-               reg_val &= ~(0xf | (0x7<<26) | (0x3 << 20) | (0x3 << 24));
-               reg_val |= (phyVal0 | srio0_ctrl | srio1_ctrl);
+               reg_val |= (pei1_mode << 1);
                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);
-               /* SRIO1 speed */
-               srio1_speed = (control & 0x38000) << 1;
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &reg_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)
+
+               set_srio_mode(SRIO0, srio0_ctrl);
+               set_srio_mode(SRIO1, srio1_ctrl);
+               set_srio_speed(SRIO0, srio0_speed);
+               set_srio_speed(SRIO1, srio1_speed);
+               pr_debug("Set up sRIO0 -- %d\n", srio0_speed);
+               if (srio0_mode) {
                        setup_srio_mode(SRIO0, srio0_speed);
-               printk("Set up sRIO0 -- %d\n", srio0_speed);
-               if (srio1_mode)
+                       if (release_srio_reset(SRIO0, srio0_speed))
+                               srio0_mode = 0;
+               }
+               pr_debug("Set up sRIO1 -- %d\n", srio1_speed);
+               if (srio1_mode) {
                        setup_srio_mode(SRIO1, srio1_speed);
-               printk("Set up sRIO1 -- %d\n", srio1_speed);
-               for (phy = 0; phy < 4; phy++)
-                       release_reset(phy);
-
-               for (phy = 0; phy < 2; phy++) {
-                       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;
-                       }
+                       if (release_srio_reset(SRIO1, srio1_speed))
+                               srio1_mode = 0;
                }
-               printk("Enabling sRIO .");
+               pr_debug("Enabling sRIO .");
                /* Power up TX/RX lanes */
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               if (!powerup_lane(phy, lane, P1, TX)) {
-                                       printk("TX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                               if (!powerup_lane(phy, lane, P1, RX)) {
-                                       printk("RX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                       }
+               if (srio0_mode) {
+                       pr_debug("0 .");
+                       if (powerup_srio_lanes(SRIO0, P1))
+                               srio0_mode = 0;
+               }
+               if (srio1_mode) {
+                       pr_debug("1 .");
+                       if (powerup_srio_lanes(SRIO1, P1))
+                               srio1_mode = 0;
                }
-               printk(".");
+               pr_debug(".");
                /* Set TX clock ready */
-               set_tx_clk_ready();
+               if (srio0_mode || srio1_mode)
+                       set_tx_clk_ready();
+
                /* Power up TX/RX lanes */
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               if (!powerup_lane(phy, lane, P0, TX)) {
-                                       printk("TX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                               if (!powerup_lane(phy, lane, P0, RX)) {
-                                       printk("RX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                       }
-               }
-               printk(".");
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               enable_lane(phy, lane, TX);
-                               enable_lane(phy, lane, RX);
-                       }
-               }
-               printk(".");
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P0))
+                       srio0_mode = 0;
+               if (srio1_mode && powerup_srio_lanes(SRIO1, P0))
+                       srio1_mode = 0;
+               pr_debug(".");
+               if (srio0_mode)
+                       enable_srio_lanes(SRIO0);
+               if (srio1_mode)
+                       enable_srio_lanes(SRIO1);
+               pr_debug(".");
                /* Enable SRIO0/SRIO1 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           phyVal0 | 0x408);
-               printk("Done\n");
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (srio0_mode << 3) | (srio1_mode << 10);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+               pr_debug("Done\n");
                break;
        case 8:
                /* SRIO1x2_SRIO0x2_PEI1x2_SATA0x1_SATA1x1 */
                /* Enable PEI1 */
-               phyVal0 = (control & 0x2);
-               /* SRIO1x2_SRIO0x2 */
-               phyVal0 |= (0x4 << 26);
-               /* SRIO0 mode */
-               srio0_ctrl = ((control & 0x300) << 12);
-               /* SRIO1 mode */
-               srio1_ctrl = ((control & 0xC00) << 14);
+               set_sw_port_config0(pc0_SRIO1x2_SRIO0x2);
+               set_sw_port_config1(pc1_PEI1x2_SATA0x1_SATA1x1);
+               set_pipe_port_sel(pp_0_1);
+               set_pipe_nphy(two_phy);
+
+               if (pei1_mode)
+                       release_reset(2);
+
+               /* Enable PEI1 */
                ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
-               reg_val &= ~(0xf | (0x7 << 26) | (0x3 << 20) | (0x3 << 24));
-               reg_val |= (phyVal0 | srio0_ctrl | srio1_ctrl);
+               reg_val |= (pei1_mode << 1);
                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);
-               /* SRIO1 speed */
-               srio1_speed = (control & 0x38000) << 1;
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &reg_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;
+
+               set_srio_mode(SRIO0, srio0_ctrl);
+               set_srio_mode(SRIO1, srio1_ctrl);
+               set_srio_speed(SRIO0, srio0_speed);
+               set_srio_speed(SRIO1, srio1_speed);
                if (sata0_mode)
                        setup_sata_mode(SATA0, sata0_speed);
                if (sata1_mode)
                        setup_sata_mode(SATA1, sata1_speed);
-               if (srio0_mode)
+               pr_debug("Set up sRIO0 -- %d\n", srio0_speed);
+               if (srio0_mode) {
                        setup_srio_mode(SRIO0, srio0_speed);
-               printk("Set up sRIO0 -- %d\n", srio0_speed);
-               if (srio1_mode)
+                       if (release_srio_reset(SRIO0, srio0_speed))
+                               srio0_mode = 0;
+               }
+               pr_debug("Set up sRIO1 -- %d\n", srio1_speed);
+               if (srio1_mode) {
                        setup_srio_mode(SRIO1, srio1_speed);
-               printk("Set up sRIO1 -- %d\n", srio1_speed);
-               for (phy = 0; phy < 4; phy++)
-                       release_reset(phy);
-
-               for (phy = 0; phy < 2; phy++) {
-                       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;
-                       }
+                       if (release_srio_reset(SRIO1, srio1_speed))
+                               srio1_mode = 0;
                }
-               printk("Enabling sRIO/SATA .");
+               if (sata0_mode || sata1_mode)
+                       release_reset(3);
+
+               pr_debug("Enabling sRIO/SATA .");
                /* Power up TX/RX lanes */
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               if (!powerup_lane(phy, lane, P1, TX)) {
-                                       printk("TX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                               if (!powerup_lane(phy, lane, P1, RX)) {
-                                       printk("RX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                       }
-               }
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P1))
+                       srio0_mode = 0;
+               if (srio1_mode && powerup_srio_lanes(SRIO1, P1))
+                       srio1_mode = 0;
 
-               printk(".");
+               pr_debug(".");
                /* Set TX clock ready */
-               set_tx_clk_ready();
+               if (srio0_mode || srio1_mode || sata0_mode || sata1_mode)
+                       set_tx_clk_ready();
 
                /* Power up TX/RX lanes */
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               if (!powerup_lane(phy, lane, P0, TX)) {
-                                       printk("TX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                               if (!powerup_lane(phy, lane, P0, RX)) {
-                                       printk("RX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                       }
-               }
-               printk(".");
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P0))
+                       srio0_mode = 0;
+               if (srio1_mode && powerup_srio_lanes(SRIO1, P0))
+                       srio1_mode = 0;
+               pr_debug(".");
 
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               enable_lane(phy, lane, TX);
-                               enable_lane(phy, lane, RX);
-                       }
-               }
-               printk(".");
+               if (srio0_mode)
+                       enable_srio_lanes(SRIO0);
+               if (srio1_mode)
+                       enable_srio_lanes(SRIO1);
+               pr_debug(".");
 
                /* Enable SATA0/SATA1 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               phyVal0 |= (control & 0x20) << 24;
-               phyVal0 |= (control & 0x40) << 24;
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0);
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (sata0_mode << 29) | (sata1_mode << 30);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
 
-               if (!check_rx_valid(3, 0)) {
-                       printk("RX clock/data recovery not asserted for PHY3 
LANE0\n");
-                       return 1;
-               }
-               if (!check_rx_valid(3, 1)) {
-                       printk("RX clock/data recovery not asserted for PHY3 
LANE1\n");
-                       return 1;
-               }
+               if (sata0_mode && !check_rx_valid(3, 0))
+                       pr_err("RX clock/data recovery not asserted for PHY3 
LANE0\n");
+               if (sata1_mode && !check_rx_valid(3, 1))
+                       pr_err("RX clock/data recovery not asserted for PHY3 
LANE1\n");
                /* Enable SRIO0/SRIO1 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           phyVal0 | 0x408);
-               printk("Done\n");
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (srio0_mode << 3) | (srio1_mode << 10);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+               pr_debug("Done\n");
                break;
        case 9:
                /* SRIO1x2_SRIO0x2_PEI1x2_PEI2x2 */
                /* Enable PEI2/PEI1 */
-               phyVal0 = (control & 0x6);
-               /* SRIO1x2_SRIO0x2 */
-               phyVal0 |= (0x4 << 26);
-               /* SRIO0 mode */
-               srio0_ctrl = ((control & 0x300) << 12);
-               /* SRIO1 mode */
-               srio1_ctrl = ((control & 0xC00) << 14);
+               set_sw_port_config0(pc0_SRIO1x2_SRIO0x2);
+               set_sw_port_config1(pc1_PEI1x2_PEI2x2);
+               set_pipe_port_sel(pp_0_1_2_3);
+
+               if (pei1_mode)
+                       release_reset(2);
+               if (pei2_mode)
+                       release_reset(3);
+
+               /* Enable PEI1/PEI2 */
                ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
-               reg_val &= ~(0xf | (0x7 << 26) | (0x3 << 20) | (0x3 << 24));
-               reg_val |= (phyVal0 | srio0_ctrl | srio1_ctrl);
+               reg_val |= (pei1_mode << 1) | (pei2_mode << 2);
                ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
-               /* PEI1x2_PEI2x2 */
-               phyVal1 = (0x3 << 22);
-               /* PIPE port select -- Enable PIPE0, PIPE1
-                * and PIPE2 interface */
-               phyVal1 |= (0x3 << 24);
-               /* SRIO0 speed */
-               srio0_speed = (control & 0x7000);
-               /* SRIO1 speed */
-               srio1_speed = (control & 0x38000) << 1;
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0x4, &reg_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)
+
+               set_srio_mode(SRIO0, srio0_ctrl);
+               set_srio_mode(SRIO1, srio1_ctrl);
+               set_srio_speed(SRIO0, srio0_speed);
+               set_srio_speed(SRIO1, srio1_speed);
+               if (srio0_mode) {
+                       pr_debug("Set up sRIO0 -- %d\n", srio0_speed);
                        setup_srio_mode(SRIO0, srio0_speed);
-               printk("Set up sRIO0 -- %d\n", srio0_speed);
-               if (srio1_mode)
+                       if (release_srio_reset(SRIO0, srio0_speed))
+                               srio0_mode = 0;
+               }
+               if (srio1_mode) {
+                       pr_debug("Set up sRIO1 -- %d\n", srio1_speed);
                        setup_srio_mode(SRIO1, srio1_speed);
-               printk("Set up sRIO1 -- %d\n", srio1_speed);
-               for (phy = 0; phy < 4; phy++)
-                       release_reset(phy);
-
-               for (phy = 0; phy < 2; phy++) {
-                       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;
-                       }
+                       if (release_srio_reset(SRIO1, srio1_speed))
+                               srio1_mode = 0;
                }
-               printk("Enabling sRIO .");
+               pr_debug("Enabling sRIO .");
                /* Power up TX/RX lanes */
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               if (!powerup_lane(phy, lane, P1, TX)) {
-                                       printk("TX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                               if (!powerup_lane(phy, lane, P1, RX)) {
-                                       printk("RX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                       }
-               }
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P1))
+                       srio0_mode = 0;
+               if (srio1_mode && powerup_srio_lanes(SRIO1, P1))
+                       srio1_mode = 0;
 
-               printk(".");
+               pr_debug(".");
                /* Set TX clock ready */
-               set_tx_clk_ready();
+               if (srio0_mode || srio1_mode)
+                       set_tx_clk_ready();
 
                /* Power up TX/RX lanes */
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               if (!powerup_lane(phy, lane, P0, TX)) {
-                                       printk("TX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                               if (!powerup_lane(phy, lane, P0, RX)) {
-                                       printk("RX powerup failed for PHY%d 
LANE%d\n", phy, lane);
-                                       return 1;
-                               }
-                       }
-               }
-               printk(".");
+               if (srio0_mode && powerup_srio_lanes(SRIO0, P0))
+                       srio0_mode = 0;
+               if (srio1_mode && powerup_srio_lanes(SRIO1, P0))
+                       srio1_mode = 0;
+               pr_debug(".");
 
-               for (phy = 0; phy < 2; phy++) {
-                       for (lane = 0; lane < 2; lane++) {
-                               enable_lane(phy, lane, TX);
-                               enable_lane(phy, lane, RX);
-                       }
-               }
-               printk(".");
+               if (srio0_mode)
+                       enable_srio_lanes(SRIO0);
+               if (srio1_mode)
+                       enable_srio_lanes(SRIO1);
+               pr_debug(".");
                /* Enable SRIO0/SRIO1 */
-               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-               ncr_write32(NCP_REGION_ID(0x115, 0), 0,
-                           phyVal0 | 0x408);
-               printk("Done\n");
+               ncr_read32(NCP_REGION_ID(0x115, 0), 0, &reg_val);
+               reg_val |= (srio0_mode << 3) | (srio1_mode << 10);
+               ncr_write32(NCP_REGION_ID(0x115, 0), 0, reg_val);
+               pr_debug("Done\n");
                break;
        }
 
-       ncr_read32(NCP_REGION_ID(0x115, 0), 0, &phyVal0);
-       phyVal0 |= 1;
-       ncr_write32(NCP_REGION_ID(0x115, 0), 0, phyVal0);
-       msleep(100);
-
-       switch (pci_srio_sata_mode) {
-       case 1:
-               writel(0x70120, pcie_rc + 0x710);
-               writel(0x104be, pcie_rc + 0x80c);
-               writel(0x1017201, pcie_rc + 0x8a8);
-               break;
-       default:
-               break;
-       }
 
        update_settings();
 
        return 0;
 }
-
 EXPORT_SYMBOL(pei_setup);
 
 /*
@@ -1703,12 +1791,7 @@ EXPORT_SYMBOL(pei_setup);
   get_v2_coefficients
 */
 
-static int
-get_v2_coefficients(struct device_node *pei_control)
-{
-       int i;
-       unsigned *lvalue;
-       char *names[] = {
+static char *names[] = {
                "primary_input_clock",
                "input_ref_clock_range",
                "lane_0_eq_main",
@@ -1719,7 +1802,13 @@ get_v2_coefficients(struct device_node *pei_control)
                "lane_1_eq_pre",
                "lane_1_eq_post",
                "lane_1_vboost"
-       };
+};
+
+static int
+get_v2_coefficients(struct device_node *pei_control)
+{
+       int i;
+       unsigned *lvalue;
 
        lvalue = &coefficients.primary_input_clock;
 
@@ -1740,6 +1829,70 @@ get_v2_coefficients(struct device_node *pei_control)
        return 0;
 }
 
+int axxia_pei_setup(unsigned int control, unsigned int force)
+{
+       int ret = 0;
+
+       mutex_lock(&axxia_pei_mux);
+
+       pr_debug("axxia_pei_setup: control=0x%08x, force = 0x%08x\n",
+                       control, force);
+       axxia_pei.control = control;
+       axxia_pei.control_set = 1;
+
+       if (1 == force)
+               axxia_pei.initialized = 0;
+
+       if (axxia_pei.initialized)
+               goto cleanup;
+
+       /*
+         Previously, if the boot loader set 'control', it did
+         not initialized the PEI.  Start with that
+         assumption.
+       */
+       if (0 == axxia_pei.initialized) {
+               if (0 != pei_setup(control)) {
+                       pr_err("pcie-axxia: PEI setup failed!\n");
+
+                       ret = -EINVAL;
+                       goto cleanup;
+               } else {
+                       axxia_pei.initialized = 1;
+               }
+
+       msleep(100);
+       }
+
+cleanup:
+       mutex_unlock(&axxia_pei_mux);
+       return ret;
+}
+EXPORT_SYMBOL(axxia_pei_setup);
+
+unsigned int axxia_pei_get_control(void)
+{
+       unsigned int ret;
+
+       mutex_lock(&axxia_pei_mux);
+       ret = axxia_pei.control;
+       mutex_unlock(&axxia_pei_mux);
+       return ret;
+}
+EXPORT_SYMBOL(axxia_pei_get_control);
+
+int axxia_pei_is_control_set(void)
+{
+       int ret;
+
+       mutex_lock(&axxia_pei_mux);
+       ret = axxia_pei.control_set;
+       mutex_unlock(&axxia_pei_mux);
+       return ret;
+}
+EXPORT_SYMBOL(axxia_pei_is_control_set);
+
+
 /*
   
------------------------------------------------------------------------------
   pei_init
@@ -1755,9 +1908,13 @@ pei_init(void)
        } else if (of_find_compatible_node(NULL, NULL, "lsi,axm5616")) {
                is_5600 = 1;
                pcie_gpreg0 = ioremap(0xa003000000, 0x10000);
+               pcie_gpreg1 = ioremap(0xa005000000, 0x10000);
+               pcie_gpreg2 = ioremap(0xa007000000, 0x10000);
                pcie_rc = ioremap(0xa002000000, 0x1000);
        } else if (of_find_compatible_node(NULL, NULL, "lsi,axc6732")) {
                is_6700 = 1;
+               pcie_gpreg0 = ioremap(0xa003000000, 0x10000);
+               pcie_rc = ioremap(0xa002000000, 0x1000);
        } else {
                pr_err("No Valid Compatible String Found for PEI!\n");
 
diff --git a/drivers/pci/host/pcie-axxia.c b/drivers/pci/host/pcie-axxia.c
index 247838e..7bc54e0 100644
--- a/drivers/pci/host/pcie-axxia.c
+++ b/drivers/pci/host/pcie-axxia.c
@@ -43,13 +43,15 @@
 #define PORT_LINK_MODE_1_LANES          (0x1 << 16)
 #define PORT_LINK_MODE_2_LANES          (0x3 << 16)
 #define PORT_LINK_MODE_4_LANES          (0x7 << 16)
+#define PORT_LINK_MODE_8_LANES          (0xf << 16)
 
 #define PCIE_LINK_WIDTH_SPEED_CONTROL   0x80C
 #define PORT_LOGIC_SPEED_CHANGE         (0x1 << 17)
-#define PORT_LOGIC_LINK_WIDTH_MASK      (0x1ff << 8)
+#define PORT_LOGIC_LINK_WIDTH_MASK      (0x1f << 8)
 #define PORT_LOGIC_LINK_WIDTH_1_LANES   (0x1 << 8)
 #define PORT_LOGIC_LINK_WIDTH_2_LANES   (0x2 << 8)
 #define PORT_LOGIC_LINK_WIDTH_4_LANES   (0x4 << 8)
+#define PORT_LOGIC_LINK_WIDTH_8_LANES   (0x8 << 8)
 
 #define PCIE_GEN3_EQ_CONTROL_OFF        0x8a8
 
@@ -106,9 +108,6 @@
 /* SYSCON */
 #define AXXIA_SYSCON_BASE             0x8002C00000
 
-static int control_set;
-static unsigned int control_value;
-static struct pcie_port *_pp;
 
 static inline uint32_t axxia_mmio_read_32(uintptr_t addr)
 {
@@ -126,10 +125,11 @@ axxia_is_x9(void)
 
 struct axxia_pcie {
        struct pcie_port pp;
-       unsigned int     control;
-       unsigned int     initialized;
+       struct axxia_pcie *next;
 };
 
+static struct axxia_pcie *axxia_pcie_controllers;
+
 static unsigned long global_io_offset;
 
 static inline void axxia_pcie_readl_rc(struct pcie_port *pp, u32 reg, u32 *val)
@@ -457,16 +457,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++;
                        }
@@ -509,9 +509,10 @@ int axxia_pcie_link_up(struct pcie_port *pp)
 
        axxia_cc_gpreg_readl(pp, PEI_SII_PWR_MGMT_REG, &smlh_state);
        smlh_state = (smlh_state & PEI_SMLH_LINK_STATE) >> 4;
+
        if ((smlh_state != 0x11) && (smlh_state != 0x23)) {
-               pr_info("smlh_state = 0x%x\n", smlh_state);
-               pr_err("PCIe LINK IS NOT UP\n");
+               dev_err(pp->dev, "PCIe LINK IS NOT UP: smlh_state = %x\n",
+                       smlh_state);
                return 0;
        }
        return 1;
@@ -523,8 +524,26 @@ void axxia_pcie_setup_rc(struct pcie_port *pp)
        u32 membase;
        u32 memlimit;
 
+       axxia_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
+       val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
+       switch (pp->lanes) {
+       case 2:
+               val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
+               break;
+       case 4:
+               val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
+               break;
+       case 8:
+               val |= PORT_LOGIC_LINK_WIDTH_8_LANES;
+               break;
+       case 1:
+       default:
+               val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
+       }
+       axxia_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
+
        /* Set the number of lanes based on the device tree. */
-       axxia_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
+       axxia_pcie_rd_own_conf(pp, PCIE_PORT_LINK_CONTROL, 4, &val);
        val &= ~PORT_LINK_MODE_MASK;
 
        switch (pp->lanes) {
@@ -537,11 +556,13 @@ void axxia_pcie_setup_rc(struct pcie_port *pp)
        case 4:
                val |= PORT_LINK_MODE_4_LANES;
                break;
+       case 8:
+               val |= PORT_LINK_MODE_8_LANES;
+               break;
        default:
                break;
        }
-
-       axxia_pcie_writel_rc(pp, val, PCIE_PORT_LINK_CONTROL);
+       axxia_pcie_wr_own_conf(pp, PCIE_PORT_LINK_CONTROL, 4, val);
 
        /* Add Mikes tweak for GEN3_EQ_CONTROL */
        axxia_pcie_writel_rc(pp, 0x1017201, PCIE_GEN3_EQ_CONTROL_OFF);
@@ -569,10 +590,11 @@ void axxia_pcie_setup_rc(struct pcie_port *pp)
        axxia_cc_gpreg_readl(pp, PEI_GENERAL_CORE_CTL_REG, &val);
        msleep(100);
        val |= 0x1;
-       axxia_cc_gpreg_writel(pp, 0x1, PEI_GENERAL_CORE_CTL_REG);
+       axxia_cc_gpreg_writel(pp, val, PEI_GENERAL_CORE_CTL_REG);
        msleep(100);
 }
 
+
 static int axxia_pcie_establish_link(struct pcie_port *pp)
 {
        /* setup root complex */
@@ -586,6 +608,20 @@ static int axxia_pcie_establish_link(struct pcie_port *pp)
        return 0;
 }
 
+static void pci_axxia_program_rc_class(struct pcie_port *pp)
+{
+       u32 dbi_ro_wr_en;
+       /* program correct class for RC */
+       axxia_pcie_readl_rc(pp, 0x8bc, &dbi_ro_wr_en);
+       /* DBI_RO_WR_EN */
+       if (!(dbi_ro_wr_en & 0x1))
+               axxia_pcie_writel_rc(pp, (dbi_ro_wr_en | 0x1), 0x8bc);
+       axxia_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI);
+       /* DBI_RO_WR_EN */
+       if (!(dbi_ro_wr_en & 0x1))
+               axxia_pcie_writel_rc(pp, dbi_ro_wr_en, 0x8bc);
+}
+
 static irqreturn_t axxia_pcie_irq_handler(int irq, void *arg)
 {
        struct pcie_port *pp = arg;
@@ -845,6 +881,8 @@ int axxia_pcie_host_init(struct pcie_port *pp)
                return -EINVAL;
        }
 
+       /* program correct class for RC */
+       pci_axxia_program_rc_class(pp);
 
        if (axxia_pcie_establish_link(pp))
                dev_warn(pp->dev, "axxia_pcie_establish_link failed\n");
@@ -864,8 +902,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;
@@ -877,9 +915,6 @@ int axxia_pcie_host_init(struct pcie_port *pp)
 
        axxia_pcie_enable_interrupts(pp);
 
-       /* program correct class for RC */
-       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);
        if (!bus)
@@ -898,7 +933,6 @@ int axxia_pcie_host_init(struct pcie_port *pp)
        return 0;
 }
 
-
 static int axxia_pcie_probe(struct platform_device *pdev)
 {
        struct axxia_pcie *axxia_pcie;
@@ -907,15 +941,21 @@ static int axxia_pcie_probe(struct platform_device *pdev)
        int ret;
        struct device_node *pei_control;
        const unsigned int *control;
+       unsigned int control_value;
        const unsigned int *initialized;
+       unsigned int initialized_value;
+       u32 val;
 
        axxia_pcie = devm_kzalloc(&pdev->dev, sizeof(*axxia_pcie),
                                  GFP_KERNEL);
        if (!axxia_pcie)
                return -ENOMEM;
 
-       pp = &axxia_pcie->pp;
+       /* add this instance to the list */
+       axxia_pcie->next = axxia_pcie_controllers;
+       axxia_pcie_controllers = axxia_pcie;
 
+       pp = &axxia_pcie->pp;
        pp->dev = &pdev->dev;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
@@ -934,40 +974,45 @@ static int axxia_pcie_probe(struct platform_device *pdev)
                return PTR_ERR(pp->cc_gpreg_base);
 
        pp->root_bus_nr = 0;
-       _pp = pp;
        pei_control = of_find_node_by_name(NULL, "pei_control");
 
+       /* LTSSM disable */
+       axxia_cc_gpreg_readl(pp, PEI_GENERAL_CORE_CTL_REG, &val);
+       msleep(100);
+       val &= ~(0x1);
+       axxia_cc_gpreg_writel(pp, val, PEI_GENERAL_CORE_CTL_REG);
+       msleep(100);
+
        if (pei_control) {
                control = of_get_property(pei_control, "control", NULL);
 
                if (NULL == control) {
                        pr_err("pcie-axxia: 'control' NOT set!!!\n");
-
                        return -EINVAL;
                }
 
-               axxia_pcie->control = be32_to_cpu(*control);
-               control_value = axxia_pcie->control;
-               control_set = 1;
+               control_value = be32_to_cpu(*control);
+
+               initialized = of_get_property(pei_control, "initialized", NULL);
 
                /*
                  Previously, if the boot loader set 'control', it did
-                 not initialized the PEI.  Start with that
-                 assumption.
+                 not initialized the PEI.  Start with that assumption.
                */
-
-               axxia_pcie->initialized = 1;
-               initialized = of_get_property(pei_control, "initialized", NULL);
-
+               initialized_value = 1;
                if (NULL != initialized)
-                       axxia_pcie->initialized = be32_to_cpu(*initialized);
-
-               if (0 == axxia_pcie->initialized)
-                       if (0 != pei_setup()) {
-                               pr_err("pcie-axxia: PEI setup failed!\n");
+                       initialized_value = be32_to_cpu(*initialized);
 
-                               return -EINVAL;
-                       }
+               /*
+                * always call pei_setup regardless of the 'initialized' value.
+                * this is needed to save the control_value.
+                * the axxia_pei setup will only be done once
+                */
+               ret = axxia_pei_setup(control_value, 0);
+               if (0 != ret) {
+                       pr_err("pcie-axxia: PEI setup failed!\n");
+                       return ret;
+               }
        }
 
        ret = axxia_pcie_host_init(pp);
@@ -1010,15 +1055,26 @@ axxia_pcie_reset(void)
 {
        struct pci_bus *pci_bus = NULL;
        int sub_buses;
+       unsigned int control;
+       struct pcie_port *_pp = NULL;
+       struct axxia_pcie *axx_pcie = axxia_pcie_controllers;
+
 
-       if (0 == control_set || NULL == _pp)
+       if (0 == axxia_pei_is_control_set())
                return -1;
 
+
+       control = axxia_pei_get_control();
+
        /* Re-initialize the PEIs */
-       pei_setup();
+       axxia_pei_setup(control, 1);
 
        /* Re-configure the root complex */
-       axxia_pcie_setup_rc(_pp);
+       while (axx_pcie) {
+               _pp = &axx_pcie->pp;
+               axxia_pcie_setup_rc(_pp);
+               axx_pcie = axx_pcie->next;
+       }
 
        /* Re-scan the Bus */
        while (NULL != (pci_bus = pci_find_next_bus(pci_bus))) {
@@ -1029,7 +1085,6 @@ axxia_pcie_reset(void)
 
        return 0;
 }
-
 EXPORT_SYMBOL(axxia_pcie_reset);
 
 static ssize_t
@@ -1045,6 +1100,7 @@ axxia_pcie_reset_trigger(struct file *file, const char 
__user *buf,
 
 static int pcie_init(void)
 {
+       axxia_pcie_controllers = NULL;
        return platform_driver_register(&axxia_pcie_driver);
 }
 subsys_initcall(pcie_init);
diff --git a/include/linux/axxia-pei.h b/include/linux/axxia-pei.h
index abbe9d6..9744945 100644
--- a/include/linux/axxia-pei.h
+++ b/include/linux/axxia-pei.h
@@ -18,7 +18,11 @@
 #ifndef __AXXIA_PEI_H
 #define __AXXIA_PEI_H
 
-int pei_setup(void);
+int axxia_pei_setup(unsigned int, unsigned int);
 int axxia_pcie_reset(void);
 
+unsigned int axxia_pei_get_control(void);
+int axxia_pei_is_control_set(void);
+
+
 #endif /* __AXXIA_PEI_H */
-- 
2.7.4

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to