From: Stanimir Varbanov
The PCIe driver reuse the Designware common code for host
and MSI initialization, and also program the Qualcomm
application specific registers.
Signed-off-by: Stanimir Varbanov
Signed-off-by: Stanimir Varbanov
---
MAINTAINERS |7 +
drivers/pci/host/Kconfig | 10 +
drivers/pci/host/Makefile|1 +
drivers/pci/host/pcie-qcom.c | 617 ++
4 files changed, 635 insertions(+)
create mode 100644 drivers/pci/host/pcie-qcom.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 38df53f828e1..7de5d2597e2b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8247,6 +8247,13 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
F: drivers/pci/host/pcie-hisi.c
+PCIE DRIVER FOR QUALCOMM MSM
+M: Stanimir Varbanov
+L: linux-...@vger.kernel.org
+L: linux-arm-msm@vger.kernel.org
+S: Maintained
+F: drivers/pci/host/*qcom*
+
PCMCIA SUBSYSTEM
P: Linux PCMCIA Team
L: linux-pcm...@lists.infradead.org
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index f131ba947dc6..64d33ba3e336 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -172,4 +172,14 @@ config PCI_HISI
help
Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+config PCIE_QCOM
+ bool "Qualcomm PCIe controller"
+ depends on ARCH_QCOM && OF || COMPILE_TEST
+ select PCIE_DW
+ select PCIEPORTBUS
+ help
+ Say Y here to enable PCIe controller support on Qualcomm SoCs. The
+ PCIe controller use Designware core plus Qualcomm specific hardware
+ wrappers.
+
endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 9d4d3c6924a1..e523c171febf 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
+obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
new file mode 100644
index ..36c81973467d
--- /dev/null
+++ b/drivers/pci/host/pcie-qcom.c
@@ -0,0 +1,617 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright 2015 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "pcie-designware.h"
+
+#define PCIE20_PARF_PHY_CTRL 0x40
+#define PCIE20_PARF_PHY_REFCLK 0x4C
+#define PCIE20_PARF_DBI_BASE_ADDR 0x168
+#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE0x16c
+#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178
+
+#define PCIE20_ELBI_SYS_CTRL 0x04
+#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)
+
+#define PCIE20_CAP 0x70
+
+#define PERST_DELAY_US 1000
+
+struct qcom_pcie_resources_v0 {
+ struct clk *iface_clk;
+ struct clk *core_clk;
+ struct clk *phy_clk;
+ struct reset_control *pci_reset;
+ struct reset_control *axi_reset;
+ struct reset_control *ahb_reset;
+ struct reset_control *por_reset;
+ struct reset_control *phy_reset;
+ struct regulator *vdda;
+ struct regulator *vdda_phy;
+ struct regulator *vdda_refclk;
+};
+
+struct qcom_pcie_resources_v1 {
+ struct clk *iface;
+ struct clk *aux;
+ struct clk *master_bus;
+ struct clk *slave_bus;
+ struct reset_control *core;
+ struct regulator *vdda;
+};
+
+union qcom_pcie_resources {
+ struct qcom_pcie_resources_v0 v0;
+ struct qcom_pcie_resources_v1 v1;
+};
+
+struct qcom_pcie;
+
+struct qcom_pcie_ops {
+ int (*get_resources)(struct qcom_pcie *pcie);
+ int (*init)(struct qcom_pcie *pcie);
+ void (*deinit)(struct qcom_pcie *pcie);
+};
+
+struct qcom_pcie {
+ struct pcie_port pp;
+ struct device *dev;
+ union qcom_pcie_resources res;
+ void __iomem *parf;
+ void __iomem *dbi;
+ void __iomem *elbi;
+ struct phy *phy;
+ struct gpio_desc *reset;
+ struct qcom_pcie_ops *ops;
+};
+
+#define to_qcom_pcie(x)container_of(x, struct qcom_pcie, pp)
+
+static void qco