[PATCH v6 12/23] PCI: dwc: dra7xx: Add EP mode support

2017-04-05 Thread Kishon Vijay Abraham I
The PCIe controller integrated in dra7xx SoCs is capable of operating in
endpoint mode. Add endpoint mode support to dra7xx driver.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Bjorn Helgaas 
---
 drivers/pci/dwc/Kconfig   |  31 +-
 drivers/pci/dwc/Makefile  |   4 +-
 drivers/pci/dwc/pci-dra7xx.c  | 197 +++---
 drivers/pci/dwc/pcie-designware.h |   7 ++
 4 files changed, 221 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index d37ea72a846a..b7e15526d676 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -16,14 +16,37 @@ config PCIE_DW_EP
 
 config PCI_DRA7XX
bool "TI DRA7xx PCIe controller"
-   depends on PCI
+   depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT
depends on OF && HAS_IOMEM && TI_PIPE3
+   help
+Enables support for the PCIe controller in the DRA7xx SoC. There
+are two instances of PCIe controller in DRA7xx. This controller can
+work either as EP or RC. In order to enable host-specific features
+PCI_DRA7XX_HOST must be selected and in order to enable device-
+specific features PCI_DRA7XX_EP must be selected. This uses
+the Designware core.
+
+if PCI_DRA7XX
+
+config PCI_DRA7XX_HOST
+   bool "PCI DRA7xx Host Mode"
+   depends on PCI
depends on PCI_MSI_IRQ_DOMAIN
select PCIE_DW_HOST
+   default y
help
-Enables support for the PCIe controller in the DRA7xx SoC.  There
-are two instances of PCIe controller in DRA7xx.  This controller can
-act both as EP and RC.  This reuses the Designware core.
+Enables support for the PCIe controller in the DRA7xx SoC to work in
+host mode.
+
+config PCI_DRA7XX_EP
+   bool "PCI DRA7xx Endpoint Mode"
+   depends on PCI_ENDPOINT
+   select PCIE_DW_EP
+   help
+Enables support for the PCIe controller in the DRA7xx SoC to work in
+endpoint mode.
+
+endif
 
 config PCIE_DW_PLAT
bool "Platform bus based DesignWare PCIe Controller"
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
index b38425d36200..f31a8596442a 100644
--- a/drivers/pci/dwc/Makefile
+++ b/drivers/pci/dwc/Makefile
@@ -2,7 +2,9 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
 obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
-obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
+ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
+obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
+endif
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index d78974d20360..35c18534469c 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -10,12 +10,14 @@
  * published by the Free Software Foundation.
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -57,6 +59,11 @@
 #defineMSI BIT(4)
 #defineLEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD)
 
+#definePCIECTRL_TI_CONF_DEVICE_TYPE0x0100
+#defineDEVICE_TYPE_EP  0x0
+#defineDEVICE_TYPE_LEG_EP  0x1
+#defineDEVICE_TYPE_RC  0x4
+
 #definePCIECTRL_DRA7XX_CONF_DEVICE_CMD 0x0104
 #defineLTSSM_EN0x1
 
@@ -66,6 +73,13 @@
 
 #define EXP_CAP_ID_OFFSET  0x70
 
+#definePCIECTRL_TI_CONF_INTX_ASSERT0x0124
+#definePCIECTRL_TI_CONF_INTX_DEASSERT  0x0128
+
+#definePCIECTRL_TI_CONF_MSI_XMT0x012c
+#define MSI_REQ_GRANT  BIT(0)
+#define MSI_VECTOR_SHIFT   7
+
 struct dra7xx_pcie {
struct dw_pcie  *pci;
void __iomem*base;  /* DT ti_conf */
@@ -73,6 +87,11 @@ struct dra7xx_pcie {
struct phy  **phy;
int link_gen;
struct irq_domain   *irq_domain;
+   enum dw_pcie_device_mode mode;
+};
+
+struct dra7xx_pcie_of_data {
+   enum dw_pcie_device_mode mode;
 };
 
 #define to_dra7xx_pcie(x)  dev_get_drvdata((x)->dev)
@@ -101,9 +120,19 @@ static int dra7xx_pcie_link_up(struct dw_pcie *pci)
return !!(reg & LINK_UP);
 }
 
-static int dra7xx_pcie_establish_link(struct dra7xx_pcie *dra7xx)
+static void dra7xx_pcie_stop_link(struct dw_pcie *pci)
 {
-   struct dw_pcie *pci = dra7xx->pci;
+   struct 

[PATCH v6 12/23] PCI: dwc: dra7xx: Add EP mode support

2017-04-05 Thread Kishon Vijay Abraham I
The PCIe controller integrated in dra7xx SoCs is capable of operating in
endpoint mode. Add endpoint mode support to dra7xx driver.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Bjorn Helgaas 
---
 drivers/pci/dwc/Kconfig   |  31 +-
 drivers/pci/dwc/Makefile  |   4 +-
 drivers/pci/dwc/pci-dra7xx.c  | 197 +++---
 drivers/pci/dwc/pcie-designware.h |   7 ++
 4 files changed, 221 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index d37ea72a846a..b7e15526d676 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -16,14 +16,37 @@ config PCIE_DW_EP
 
 config PCI_DRA7XX
bool "TI DRA7xx PCIe controller"
-   depends on PCI
+   depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT
depends on OF && HAS_IOMEM && TI_PIPE3
+   help
+Enables support for the PCIe controller in the DRA7xx SoC. There
+are two instances of PCIe controller in DRA7xx. This controller can
+work either as EP or RC. In order to enable host-specific features
+PCI_DRA7XX_HOST must be selected and in order to enable device-
+specific features PCI_DRA7XX_EP must be selected. This uses
+the Designware core.
+
+if PCI_DRA7XX
+
+config PCI_DRA7XX_HOST
+   bool "PCI DRA7xx Host Mode"
+   depends on PCI
depends on PCI_MSI_IRQ_DOMAIN
select PCIE_DW_HOST
+   default y
help
-Enables support for the PCIe controller in the DRA7xx SoC.  There
-are two instances of PCIe controller in DRA7xx.  This controller can
-act both as EP and RC.  This reuses the Designware core.
+Enables support for the PCIe controller in the DRA7xx SoC to work in
+host mode.
+
+config PCI_DRA7XX_EP
+   bool "PCI DRA7xx Endpoint Mode"
+   depends on PCI_ENDPOINT
+   select PCIE_DW_EP
+   help
+Enables support for the PCIe controller in the DRA7xx SoC to work in
+endpoint mode.
+
+endif
 
 config PCIE_DW_PLAT
bool "Platform bus based DesignWare PCIe Controller"
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
index b38425d36200..f31a8596442a 100644
--- a/drivers/pci/dwc/Makefile
+++ b/drivers/pci/dwc/Makefile
@@ -2,7 +2,9 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
 obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
-obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
+ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
+obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
+endif
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index d78974d20360..35c18534469c 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -10,12 +10,14 @@
  * published by the Free Software Foundation.
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -57,6 +59,11 @@
 #defineMSI BIT(4)
 #defineLEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD)
 
+#definePCIECTRL_TI_CONF_DEVICE_TYPE0x0100
+#defineDEVICE_TYPE_EP  0x0
+#defineDEVICE_TYPE_LEG_EP  0x1
+#defineDEVICE_TYPE_RC  0x4
+
 #definePCIECTRL_DRA7XX_CONF_DEVICE_CMD 0x0104
 #defineLTSSM_EN0x1
 
@@ -66,6 +73,13 @@
 
 #define EXP_CAP_ID_OFFSET  0x70
 
+#definePCIECTRL_TI_CONF_INTX_ASSERT0x0124
+#definePCIECTRL_TI_CONF_INTX_DEASSERT  0x0128
+
+#definePCIECTRL_TI_CONF_MSI_XMT0x012c
+#define MSI_REQ_GRANT  BIT(0)
+#define MSI_VECTOR_SHIFT   7
+
 struct dra7xx_pcie {
struct dw_pcie  *pci;
void __iomem*base;  /* DT ti_conf */
@@ -73,6 +87,11 @@ struct dra7xx_pcie {
struct phy  **phy;
int link_gen;
struct irq_domain   *irq_domain;
+   enum dw_pcie_device_mode mode;
+};
+
+struct dra7xx_pcie_of_data {
+   enum dw_pcie_device_mode mode;
 };
 
 #define to_dra7xx_pcie(x)  dev_get_drvdata((x)->dev)
@@ -101,9 +120,19 @@ static int dra7xx_pcie_link_up(struct dw_pcie *pci)
return !!(reg & LINK_UP);
 }
 
-static int dra7xx_pcie_establish_link(struct dra7xx_pcie *dra7xx)
+static void dra7xx_pcie_stop_link(struct dw_pcie *pci)
 {
-   struct dw_pcie *pci = dra7xx->pci;
+   struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
+