[PATCH v4 2/2] phy: bcm-sr-pcie: Add Stingray PCIe PHY driver

2018-07-06 Thread Ray Jui
Add Stingray PCIe PHY driver for both PAXB and PAXC root complex

Signed-off-by: Ray Jui 
---
 drivers/phy/broadcom/Kconfig   |  10 ++
 drivers/phy/broadcom/Makefile  |   2 +
 drivers/phy/broadcom/phy-bcm-sr-pcie.c | 305 +
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/phy/broadcom/phy-bcm-sr-pcie.c

diff --git a/drivers/phy/broadcom/Kconfig b/drivers/phy/broadcom/Kconfig
index 97d27b0d5..8786a96 100644
--- a/drivers/phy/broadcom/Kconfig
+++ b/drivers/phy/broadcom/Kconfig
@@ -80,3 +80,13 @@ config PHY_BRCM_USB
  This driver is required by the USB XHCI, EHCI and OHCI
  drivers.
  If unsure, say N.
+
+config PHY_BCM_SR_PCIE
+   tristate "Broadcom Stingray PCIe PHY driver"
+   depends on OF && (ARCH_BCM_IPROC || COMPILE_TEST)
+   select GENERIC_PHY
+   select MFD_SYSCON
+   default ARCH_BCM_IPROC
+   help
+ Enable this to support the Broadcom Stingray PCIe PHY
+ If unsure, say N.
diff --git a/drivers/phy/broadcom/Makefile b/drivers/phy/broadcom/Makefile
index 13e000c..0f60184 100644
--- a/drivers/phy/broadcom/Makefile
+++ b/drivers/phy/broadcom/Makefile
@@ -9,3 +9,5 @@ obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
 obj-$(CONFIG_PHY_BRCM_USB) += phy-brcm-usb-dvr.o
 
 phy-brcm-usb-dvr-objs := phy-brcm-usb.o phy-brcm-usb-init.o
+
+obj-$(CONFIG_PHY_BCM_SR_PCIE)  += phy-bcm-sr-pcie.o
diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c 
b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
new file mode 100644
index 000..c10e95f
--- /dev/null
+++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Broadcom
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* we have up to 8 PAXB based RC. The 9th one is always PAXC */
+#define SR_NR_PCIE_PHYS   9
+#define SR_PAXC_PHY_IDX   (SR_NR_PCIE_PHYS - 1)
+
+#define PCIE_PIPEMUX_CFG_OFFSET   0x10c
+#define PCIE_PIPEMUX_SELECT_STRAP 0xf
+
+#define CDRU_STRAP_DATA_LSW_OFFSET0x5c
+#define PCIE_PIPEMUX_SHIFT19
+#define PCIE_PIPEMUX_MASK 0xf
+
+#define MHB_MEM_PW_PAXC_OFFSET0x1c0
+#define MHB_PWR_ARR_POWERON   0x8
+#define MHB_PWR_ARR_POWEROK   0x4
+#define MHB_PWR_POWERON   0x2
+#define MHB_PWR_POWEROK   0x1
+#define MHB_PWR_STATUS_MASK   (MHB_PWR_ARR_POWERON | \
+  MHB_PWR_ARR_POWEROK | \
+  MHB_PWR_POWERON | \
+  MHB_PWR_POWEROK)
+
+struct sr_pcie_phy_core;
+
+/**
+ * struct sr_pcie_phy - Stingray PCIe PHY
+ *
+ * @core: pointer to the Stingray PCIe PHY core control
+ * @index: PHY index
+ * @phy: pointer to the kernel PHY device
+ */
+struct sr_pcie_phy {
+   struct sr_pcie_phy_core *core;
+   unsigned int index;
+   struct phy *phy;
+};
+
+/**
+ * struct sr_pcie_phy_core - Stingray PCIe PHY core control
+ *
+ * @dev: pointer to device
+ * @base: base register of PCIe SS
+ * @cdru: regmap to the CDRU device
+ * @mhb: regmap to the MHB device
+ * @pipemux: pipemuex strap
+ * @phys: array of PCIe PHYs
+ */
+struct sr_pcie_phy_core {
+   struct device *dev;
+   void __iomem *base;
+   struct regmap *cdru;
+   struct regmap *mhb;
+   u32 pipemux;
+   struct sr_pcie_phy phys[SR_NR_PCIE_PHYS];
+};
+
+/*
+ * PCIe PIPEMUX lookup table
+ *
+ * Each array index represents a PIPEMUX strap setting
+ * The array element represents a bitmap where a set bit means the PCIe
+ * core and associated serdes has been enabled as RC and is available for use
+ */
+static const u8 pipemux_table[] = {
+   /* PIPEMUX = 0, EP 1x16 */
+   0x00,
+   /* PIPEMUX = 1, EP 2x8 */
+   0x00,
+   /* PIPEMUX = 2, EP 4x4 */
+   0x00,
+   /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
+   0x81,
+   /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
+   0xc3,
+   /* PIPEMUX = 5, RC 8x2, all 8 cores */
+   0xff,
+   /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
+   0xcd,
+   /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
+   0xfd,
+   /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
+   0xf0,
+   /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
+   0xc0,
+   /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
+   0x42,
+   /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
+   0x3c,
+   /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
+   0xfc,
+   /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
+   0x4c,
+};
+
+/*
+ * Return true if the strap setting is valid
+ */
+static bool pipemux_strap_is_valid(u32 pipemux)
+{
+   return !!(pipemux < ARRAY_SIZE(pipemux_table));
+}
+
+/*
+ * Read the PCIe PIPEMUX from strap
+ */
+static u32 

[PATCH v4 2/2] phy: bcm-sr-pcie: Add Stingray PCIe PHY driver

2018-07-06 Thread Ray Jui
Add Stingray PCIe PHY driver for both PAXB and PAXC root complex

Signed-off-by: Ray Jui 
---
 drivers/phy/broadcom/Kconfig   |  10 ++
 drivers/phy/broadcom/Makefile  |   2 +
 drivers/phy/broadcom/phy-bcm-sr-pcie.c | 305 +
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/phy/broadcom/phy-bcm-sr-pcie.c

diff --git a/drivers/phy/broadcom/Kconfig b/drivers/phy/broadcom/Kconfig
index 97d27b0d5..8786a96 100644
--- a/drivers/phy/broadcom/Kconfig
+++ b/drivers/phy/broadcom/Kconfig
@@ -80,3 +80,13 @@ config PHY_BRCM_USB
  This driver is required by the USB XHCI, EHCI and OHCI
  drivers.
  If unsure, say N.
+
+config PHY_BCM_SR_PCIE
+   tristate "Broadcom Stingray PCIe PHY driver"
+   depends on OF && (ARCH_BCM_IPROC || COMPILE_TEST)
+   select GENERIC_PHY
+   select MFD_SYSCON
+   default ARCH_BCM_IPROC
+   help
+ Enable this to support the Broadcom Stingray PCIe PHY
+ If unsure, say N.
diff --git a/drivers/phy/broadcom/Makefile b/drivers/phy/broadcom/Makefile
index 13e000c..0f60184 100644
--- a/drivers/phy/broadcom/Makefile
+++ b/drivers/phy/broadcom/Makefile
@@ -9,3 +9,5 @@ obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
 obj-$(CONFIG_PHY_BRCM_USB) += phy-brcm-usb-dvr.o
 
 phy-brcm-usb-dvr-objs := phy-brcm-usb.o phy-brcm-usb-init.o
+
+obj-$(CONFIG_PHY_BCM_SR_PCIE)  += phy-bcm-sr-pcie.o
diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c 
b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
new file mode 100644
index 000..c10e95f
--- /dev/null
+++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Broadcom
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* we have up to 8 PAXB based RC. The 9th one is always PAXC */
+#define SR_NR_PCIE_PHYS   9
+#define SR_PAXC_PHY_IDX   (SR_NR_PCIE_PHYS - 1)
+
+#define PCIE_PIPEMUX_CFG_OFFSET   0x10c
+#define PCIE_PIPEMUX_SELECT_STRAP 0xf
+
+#define CDRU_STRAP_DATA_LSW_OFFSET0x5c
+#define PCIE_PIPEMUX_SHIFT19
+#define PCIE_PIPEMUX_MASK 0xf
+
+#define MHB_MEM_PW_PAXC_OFFSET0x1c0
+#define MHB_PWR_ARR_POWERON   0x8
+#define MHB_PWR_ARR_POWEROK   0x4
+#define MHB_PWR_POWERON   0x2
+#define MHB_PWR_POWEROK   0x1
+#define MHB_PWR_STATUS_MASK   (MHB_PWR_ARR_POWERON | \
+  MHB_PWR_ARR_POWEROK | \
+  MHB_PWR_POWERON | \
+  MHB_PWR_POWEROK)
+
+struct sr_pcie_phy_core;
+
+/**
+ * struct sr_pcie_phy - Stingray PCIe PHY
+ *
+ * @core: pointer to the Stingray PCIe PHY core control
+ * @index: PHY index
+ * @phy: pointer to the kernel PHY device
+ */
+struct sr_pcie_phy {
+   struct sr_pcie_phy_core *core;
+   unsigned int index;
+   struct phy *phy;
+};
+
+/**
+ * struct sr_pcie_phy_core - Stingray PCIe PHY core control
+ *
+ * @dev: pointer to device
+ * @base: base register of PCIe SS
+ * @cdru: regmap to the CDRU device
+ * @mhb: regmap to the MHB device
+ * @pipemux: pipemuex strap
+ * @phys: array of PCIe PHYs
+ */
+struct sr_pcie_phy_core {
+   struct device *dev;
+   void __iomem *base;
+   struct regmap *cdru;
+   struct regmap *mhb;
+   u32 pipemux;
+   struct sr_pcie_phy phys[SR_NR_PCIE_PHYS];
+};
+
+/*
+ * PCIe PIPEMUX lookup table
+ *
+ * Each array index represents a PIPEMUX strap setting
+ * The array element represents a bitmap where a set bit means the PCIe
+ * core and associated serdes has been enabled as RC and is available for use
+ */
+static const u8 pipemux_table[] = {
+   /* PIPEMUX = 0, EP 1x16 */
+   0x00,
+   /* PIPEMUX = 1, EP 2x8 */
+   0x00,
+   /* PIPEMUX = 2, EP 4x4 */
+   0x00,
+   /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
+   0x81,
+   /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
+   0xc3,
+   /* PIPEMUX = 5, RC 8x2, all 8 cores */
+   0xff,
+   /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
+   0xcd,
+   /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
+   0xfd,
+   /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
+   0xf0,
+   /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
+   0xc0,
+   /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
+   0x42,
+   /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
+   0x3c,
+   /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
+   0xfc,
+   /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
+   0x4c,
+};
+
+/*
+ * Return true if the strap setting is valid
+ */
+static bool pipemux_strap_is_valid(u32 pipemux)
+{
+   return !!(pipemux < ARRAY_SIZE(pipemux_table));
+}
+
+/*
+ * Read the PCIe PIPEMUX from strap
+ */
+static u32