Commit e302baff authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/qcom'

- List platforms that use a single MSI host interrupt in qcom DT (Johan
  Hovold)

- Add SC8280XP, SA8540P support to qcom DT binding and driver(Johan Hovold)

- Make all optional clocks truly optional in the driver (Johan Hovold)

- Rename per-IP structs to reflect the IP version (Johan Hovold)

- Sort device ID match table by compatible string (Johan Hovold)

- Add MODULE_DEVICE_TABLE to enable module autoloading (Dmitry Baryshkov)

- Drop the unused .post_deinit() callback (Johan Hovold)

- Rely on DT for clock information instead of hard-coding it in the driver
  (Manivannan Sadhasivam)

- Disable IRQs when removing driver to avoid spurious IRQs later
  (Manivannan Sadhasivam)

- Expose link transition counts via debugfs to help debug issues with
  low-power states (Manivannan Sadhasivam)

- Gate Master AXI clock to the MHI bus while in L1 substates to save power
  (Manivannan Sadhasivam)

- Disable Master AXI clock to save power when there is no traffic on PCIe
  (Manivannan Sadhasivam)

- Make the "PERST separation" debug feature optional in the DT and the
  driver (Manivannan Sadhasivam)

- Define clocks to be per-platform in DT to prepare for future SoCs
  (Manivannan Sadhasivam)

- Add SM8450 SoC support (Manivannan Sadhasivam)

- Check for platform_get_resource_byname() to avoid a NULL pointer
  dereference (Yang Yingliang)

* pci/qcom:
  PCI: qcom-ep: Check platform_get_resource_byname() return value
  PCI: qcom-ep: Add support for SM8450 SoC
  dt-bindings: PCI: qcom-ep: Add support for SM8450 SoC
  dt-bindings: PCI: qcom-ep: Define clocks per platform
  PCI: qcom-ep: Make PERST separation optional
  dt-bindings: PCI: qcom-ep: Make PERST separation optional
  PCI: qcom-ep: Disable Master AXI Clock when there is no PCIe traffic
  PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS
  PCI: qcom-ep: Expose link transition counts via debugfs
  PCI: qcom-ep: Disable IRQs during driver remove
  PCI: qcom-ep: Make use of the cached dev pointer
  PCI: qcom-ep: Rely on the clocks supplied by devicetree
  PCI: qcom-ep: Add kernel-doc for qcom_pcie_ep structure
  PCI: qcom: Rename host-init error label
  PCI: qcom: Drop unused post_deinit callback
  PCI: qcom-ep: Add MODULE_DEVICE_TABLE
  PCI: qcom: Sort device-id table
  PCI: qcom: Clean up IP configurations
  PCI: qcom: Make all optional clocks optional
  PCI: qcom: Add support for SA8540P
  PCI: qcom: Add support for SC8280XP
  dt-bindings: PCI: qcom: Add SA8540P to binding
  dt-bindings: PCI: qcom: Add SC8280XP to binding
  dt-bindings: PCI: qcom: Enumerate platforms with single msi interrupt
parents fba236f9 94f0b955
Loading
Loading
Loading
Loading
+65 −21
Original line number Diff line number Diff line
@@ -9,12 +9,11 @@ title: Qualcomm PCIe Endpoint Controller binding
maintainers:
  - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

allOf:
  - $ref: "pci-ep.yaml#"

properties:
  compatible:
    const: qcom,sdx55-pcie-ep
    enum:
      - qcom,sdx55-pcie-ep
      - qcom,sm8450-pcie-ep

  reg:
    items:
@@ -35,24 +34,12 @@ properties:
      - const: mmio

  clocks:
    items:
      - description: PCIe Auxiliary clock
      - description: PCIe CFG AHB clock
      - description: PCIe Master AXI clock
      - description: PCIe Slave AXI clock
      - description: PCIe Slave Q2A AXI clock
      - description: PCIe Sleep clock
      - description: PCIe Reference clock
    minItems: 7
    maxItems: 8

  clock-names:
    items:
      - const: aux
      - const: cfg
      - const: bus_master
      - const: bus_slave
      - const: slave_q2a
      - const: sleep
      - const: ref
    minItems: 7
    maxItems: 8

  qcom,perst-regs:
    description: Reference to a syscon representing TCSR followed by the two
@@ -105,7 +92,6 @@ required:
  - reg-names
  - clocks
  - clock-names
  - qcom,perst-regs
  - interrupts
  - interrupt-names
  - reset-gpios
@@ -113,6 +99,64 @@ required:
  - reset-names
  - power-domains

allOf:
  - $ref: pci-ep.yaml#
  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,sdx55-pcie-ep
    then:
      properties:
        clocks:
          items:
            - description: PCIe Auxiliary clock
            - description: PCIe CFG AHB clock
            - description: PCIe Master AXI clock
            - description: PCIe Slave AXI clock
            - description: PCIe Slave Q2A AXI clock
            - description: PCIe Sleep clock
            - description: PCIe Reference clock
        clock-names:
          items:
            - const: aux
            - const: cfg
            - const: bus_master
            - const: bus_slave
            - const: slave_q2a
            - const: sleep
            - const: ref

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,sm8450-pcie-ep
    then:
      properties:
        clocks:
          items:
            - description: PCIe Auxiliary clock
            - description: PCIe CFG AHB clock
            - description: PCIe Master AXI clock
            - description: PCIe Slave AXI clock
            - description: PCIe Slave Q2A AXI clock
            - description: PCIe Reference clock
            - description: PCIe DDRSS SF TBU clock
            - description: PCIe AGGRE NOC AXI clock
        clock-names:
          items:
            - const: aux
            - const: cfg
            - const: bus_master
            - const: bus_slave
            - const: slave_q2a
            - const: ref
            - const: ddrss_sf_tbu
            - const: aggre_noc_axi

unevaluatedProperties: false

examples:
+67 −3
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@ properties:
      - qcom,pcie-ipq4019
      - qcom,pcie-ipq8074
      - qcom,pcie-qcs404
      - qcom,pcie-sa8540p
      - qcom,pcie-sc7280
      - qcom,pcie-sc8180x
      - qcom,pcie-sc8280xp
      - qcom,pcie-sdm845
      - qcom,pcie-sm8150
      - qcom,pcie-sm8250
@@ -181,6 +183,7 @@ allOf:
            enum:
              - qcom,pcie-sc7280
              - qcom,pcie-sc8180x
              - qcom,pcie-sc8280xp
              - qcom,pcie-sm8250
              - qcom,pcie-sm8450-pcie0
              - qcom,pcie-sm8450-pcie1
@@ -598,6 +601,36 @@ allOf:
          items:
            - const: pci # PCIe core reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sa8540p
              - qcom,pcie-sc8280xp
    then:
      properties:
        clocks:
          minItems: 8
          maxItems: 9
        clock-names:
          minItems: 8
          items:
            - const: aux # Auxiliary clock
            - const: cfg # Configuration clock
            - const: bus_master # Master AXI clock
            - const: bus_slave # Slave AXI clock
            - const: slave_q2a # Slave Q2A clock
            - const: ddrss_sf_tbu # PCIe SF TBU clock
            - const: noc_aggr_4 # NoC aggregate 4 clock
            - const: noc_aggr_south_sf # NoC aggregate South SF clock
            - const: cnoc_qx # Configuration NoC QX clock
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: pci # PCIe core reset

  - if:
      not:
        properties:
@@ -626,8 +659,6 @@ allOf:
        - resets
        - reset-names

    # Newer chipsets support either 1 or 8 MSI vectors
    # On older chipsets it's always 1 MSI vector
  - if:
      properties:
        compatible:
@@ -662,7 +693,40 @@ allOf:
                - const: msi5
                - const: msi6
                - const: msi7
    else:

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sc8280xp
    then:
      properties:
        interrupts:
          minItems: 4
          maxItems: 4
        interrupt-names:
          items:
            - const: msi0
            - const: msi1
            - const: msi2
            - const: msi3

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-apq8064
              - qcom,pcie-apq8084
              - qcom,pcie-ipq4019
              - qcom,pcie-ipq6018
              - qcom,pcie-ipq8064
              - qcom,pcie-ipq8064-v2
              - qcom,pcie-ipq8074
              - qcom,pcie-qcs404
              - qcom,pcie-sa8540p
    then:
      properties:
        interrupts:
          maxItems: 1
+131 −33
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
 */

#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/mfd/syscon.h>
@@ -26,6 +27,7 @@
#define PARF_SYS_CTRL				0x00
#define PARF_DB_CTRL				0x10
#define PARF_PM_CTRL				0x20
#define PARF_MHI_CLOCK_RESET_CTRL		0x174
#define PARF_MHI_BASE_ADDR_LOWER		0x178
#define PARF_MHI_BASE_ADDR_UPPER		0x17c
#define PARF_DEBUG_INT_EN			0x190
@@ -45,6 +47,11 @@
#define PARF_ATU_BASE_ADDR			0x634
#define PARF_ATU_BASE_ADDR_HI			0x638
#define PARF_SRIS_MODE				0x644
#define PARF_DEBUG_CNT_PM_LINKST_IN_L2		0xc04
#define PARF_DEBUG_CNT_PM_LINKST_IN_L1		0xc0c
#define PARF_DEBUG_CNT_PM_LINKST_IN_L0S		0xc10
#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1	0xc84
#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2	0xc88
#define PARF_DEVICE_TYPE			0x1000
#define PARF_BDF_TO_SID_CFG			0x2c00

@@ -83,6 +90,9 @@
#define PARF_PM_CTRL_READY_ENTR_L23		BIT(2)
#define PARF_PM_CTRL_REQ_NOT_ENTR_L1		BIT(5)

/* PARF_MHI_CLOCK_RESET_CTRL fields */
#define PARF_MSTR_AXI_CLK_EN			BIT(1)

/* PARF_AXI_MSTR_RD_HALT_NO_WRITES register fields */
#define PARF_AXI_MSTR_RD_HALT_NO_WRITE_EN	BIT(0)

@@ -95,6 +105,7 @@
/* PARF_SYS_CTRL register fields */
#define PARF_SYS_CTRL_AUX_PWR_DET		BIT(4)
#define PARF_SYS_CTRL_CORE_CLK_CGC_DIS		BIT(6)
#define PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS		BIT(10)
#define PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE	BIT(11)

/* PARF_DB_CTRL register fields */
@@ -130,21 +141,33 @@ enum qcom_pcie_ep_link_status {
	QCOM_PCIE_EP_LINK_DOWN,
};

static struct clk_bulk_data qcom_pcie_ep_clks[] = {
	{ .id = "cfg" },
	{ .id = "aux" },
	{ .id = "bus_master" },
	{ .id = "bus_slave" },
	{ .id = "ref" },
	{ .id = "sleep" },
	{ .id = "slave_q2a" },
};

/**
 * struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller
 * @pci: Designware PCIe controller struct
 * @parf: Qualcomm PCIe specific PARF register base
 * @elbi: Designware PCIe specific ELBI register base
 * @mmio: MMIO register base
 * @perst_map: PERST regmap
 * @mmio_res: MMIO region resource
 * @core_reset: PCIe Endpoint core reset
 * @reset: PERST# GPIO
 * @wake: WAKE# GPIO
 * @phy: PHY controller block
 * @debugfs: PCIe Endpoint Debugfs directory
 * @clks: PCIe clocks
 * @num_clks: PCIe clocks count
 * @perst_en: Flag for PERST enable
 * @perst_sep_en: Flag for PERST separation enable
 * @link_status: PCIe Link status
 * @global_irq: Qualcomm PCIe specific Global IRQ
 * @perst_irq: PERST# IRQ
 */
struct qcom_pcie_ep {
	struct dw_pcie pci;

	void __iomem *parf;
	void __iomem *elbi;
	void __iomem *mmio;
	struct regmap *perst_map;
	struct resource *mmio_res;

@@ -152,6 +175,10 @@ struct qcom_pcie_ep {
	struct gpio_desc *reset;
	struct gpio_desc *wake;
	struct phy *phy;
	struct dentry *debugfs;

	struct clk_bulk_data *clks;
	int num_clks;

	u32 perst_en;
	u32 perst_sep_en;
@@ -193,9 +220,11 @@ static int qcom_pcie_ep_core_reset(struct qcom_pcie_ep *pcie_ep)
 */
static void qcom_pcie_ep_configure_tcsr(struct qcom_pcie_ep *pcie_ep)
{
	if (pcie_ep->perst_map) {
		regmap_write(pcie_ep->perst_map, pcie_ep->perst_en, 0);
		regmap_write(pcie_ep->perst_map, pcie_ep->perst_sep_en, 0);
	}
}

static int qcom_pcie_dw_link_up(struct dw_pcie *pci)
{
@@ -227,8 +256,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
{
	int ret;

	ret = clk_bulk_prepare_enable(ARRAY_SIZE(qcom_pcie_ep_clks),
				      qcom_pcie_ep_clks);
	ret = clk_bulk_prepare_enable(pcie_ep->num_clks, pcie_ep->clks);
	if (ret)
		return ret;

@@ -249,8 +277,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
err_phy_exit:
	phy_exit(pcie_ep->phy);
err_disable_clk:
	clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks),
				   qcom_pcie_ep_clks);
	clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks);

	return ret;
}
@@ -259,8 +286,7 @@ static void qcom_pcie_disable_resources(struct qcom_pcie_ep *pcie_ep)
{
	phy_power_off(pcie_ep->phy);
	phy_exit(pcie_ep->phy);
	clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks),
				   qcom_pcie_ep_clks);
	clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks);
}

static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
@@ -318,8 +344,14 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
	val &= ~PARF_Q2A_FLUSH_EN;
	writel_relaxed(val, pcie_ep->parf + PARF_Q2A_FLUSH);

	/* Disable DBI Wakeup, core clock CGC and enable AUX power */
	/*
	 * Disable Master AXI clock during idle.  Do not allow DBI access
	 * to take the core out of L1.  Disable core clock gating that
	 * gates PIPE clock from propagating to core clock.  Report to the
	 * host that Vaux is present.
	 */
	val = readl_relaxed(pcie_ep->parf + PARF_SYS_CTRL);
	val &= ~PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS;
	val |= PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE |
	       PARF_SYS_CTRL_CORE_CLK_CGC_DIS |
	       PARF_SYS_CTRL_AUX_PWR_DET;
@@ -375,6 +407,11 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
		       pcie_ep->parf + PARF_MHI_BASE_ADDR_LOWER);
	writel_relaxed(0, pcie_ep->parf + PARF_MHI_BASE_ADDR_UPPER);

	/* Gate Master AXI clock to MHI bus during L1SS */
	val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
	val &= ~PARF_MSTR_AXI_CLK_EN;
	val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);

	dw_pcie_ep_init_notify(&pcie_ep->pci.ep);

	/* Enable LTSSM */
@@ -437,11 +474,19 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev,

	pcie_ep->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							 "mmio");
	if (!pcie_ep->mmio_res) {
		dev_err(dev, "Failed to get mmio resource\n");
		return -EINVAL;
	}

	pcie_ep->mmio = devm_pci_remap_cfg_resource(dev, pcie_ep->mmio_res);
	if (IS_ERR(pcie_ep->mmio))
		return PTR_ERR(pcie_ep->mmio);

	syscon = of_parse_phandle(dev->of_node, "qcom,perst-regs", 0);
	if (!syscon) {
		dev_err(dev, "Failed to parse qcom,perst-regs\n");
		return -EINVAL;
		dev_dbg(dev, "PERST separation not available\n");
		return 0;
	}

	pcie_ep->perst_map = syscon_node_to_regmap(syscon);
@@ -474,14 +519,15 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,

	ret = qcom_pcie_ep_get_io_resources(pdev, pcie_ep);
	if (ret) {
		dev_err(&pdev->dev, "Failed to get io resources %d\n", ret);
		dev_err(dev, "Failed to get io resources %d\n", ret);
		return ret;
	}

	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(qcom_pcie_ep_clks),
				qcom_pcie_ep_clks);
	if (ret)
		return ret;
	pcie_ep->num_clks = devm_clk_bulk_get_all(dev, &pcie_ep->clks);
	if (pcie_ep->num_clks < 0) {
		dev_err(dev, "Failed to get clocks\n");
		return pcie_ep->num_clks;
	}

	pcie_ep->core_reset = devm_reset_control_get_exclusive(dev, "core");
	if (IS_ERR(pcie_ep->core_reset))
@@ -495,7 +541,7 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
	if (IS_ERR(pcie_ep->wake))
		return PTR_ERR(pcie_ep->wake);

	pcie_ep->phy = devm_phy_optional_get(&pdev->dev, "pciephy");
	pcie_ep->phy = devm_phy_optional_get(dev, "pciephy");
	if (IS_ERR(pcie_ep->phy))
		ret = PTR_ERR(pcie_ep->phy);

@@ -571,13 +617,13 @@ static irqreturn_t qcom_pcie_ep_perst_irq_thread(int irq, void *data)
static int qcom_pcie_ep_enable_irq_resources(struct platform_device *pdev,
					     struct qcom_pcie_ep *pcie_ep)
{
	int irq, ret;
	int ret;

	irq = platform_get_irq_byname(pdev, "global");
	if (irq < 0)
		return irq;
	pcie_ep->global_irq = platform_get_irq_byname(pdev, "global");
	if (pcie_ep->global_irq < 0)
		return pcie_ep->global_irq;

	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
	ret = devm_request_threaded_irq(&pdev->dev, pcie_ep->global_irq, NULL,
					qcom_pcie_ep_global_irq_thread,
					IRQF_ONESHOT,
					"global_irq", pcie_ep);
@@ -594,7 +640,7 @@ static int qcom_pcie_ep_enable_irq_resources(struct platform_device *pdev,
					"perst_irq", pcie_ep);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request PERST IRQ\n");
		disable_irq(irq);
		disable_irq(pcie_ep->global_irq);
		return ret;
	}

@@ -617,6 +663,37 @@ static int qcom_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
	}
}

static int qcom_pcie_ep_link_transition_count(struct seq_file *s, void *data)
{
	struct qcom_pcie_ep *pcie_ep = (struct qcom_pcie_ep *)
				     dev_get_drvdata(s->private);

	seq_printf(s, "L0s transition count: %u\n",
		   readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L0S));

	seq_printf(s, "L1 transition count: %u\n",
		   readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L1));

	seq_printf(s, "L1.1 transition count: %u\n",
		   readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1));

	seq_printf(s, "L1.2 transition count: %u\n",
		   readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2));

	seq_printf(s, "L2 transition count: %u\n",
		   readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L2));

	return 0;
}

static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep)
{
	struct dw_pcie *pci = &pcie_ep->pci;

	debugfs_create_devm_seqfile(pci->dev, "link_transition_count", pcie_ep->debugfs,
				    qcom_pcie_ep_link_transition_count);
}

static const struct pci_epc_features qcom_pcie_epc_features = {
	.linkup_notifier = true,
	.core_init_notifier = true,
@@ -649,6 +726,7 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct qcom_pcie_ep *pcie_ep;
	char *name;
	int ret;

	pcie_ep = devm_kzalloc(dev, sizeof(*pcie_ep), GFP_KERNEL);
@@ -680,8 +758,21 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
	if (ret)
		goto err_disable_resources;

	name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
	if (!name) {
		ret = -ENOMEM;
		goto err_disable_irqs;
	}

	pcie_ep->debugfs = debugfs_create_dir(name, NULL);
	qcom_pcie_ep_init_debugfs(pcie_ep);

	return 0;

err_disable_irqs:
	disable_irq(pcie_ep->global_irq);
	disable_irq(pcie_ep->perst_irq);

err_disable_resources:
	qcom_pcie_disable_resources(pcie_ep);

@@ -692,6 +783,11 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)
{
	struct qcom_pcie_ep *pcie_ep = platform_get_drvdata(pdev);

	disable_irq(pcie_ep->global_irq);
	disable_irq(pcie_ep->perst_irq);

	debugfs_remove_recursive(pcie_ep->debugfs);

	if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED)
		return 0;

@@ -702,8 +798,10 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)

static const struct of_device_id qcom_pcie_ep_match[] = {
	{ .compatible = "qcom,sdx55-pcie-ep", },
	{ .compatible = "qcom,sm8450-pcie-ep", },
	{ }
};
MODULE_DEVICE_TABLE(of, qcom_pcie_ep_match);

static struct platform_driver qcom_pcie_ep_driver = {
	.probe	= qcom_pcie_ep_probe,
+49 −79
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@ struct qcom_pcie_resources_2_3_3 {

/* 6 clocks typically, 7 for sm8250 */
struct qcom_pcie_resources_2_7_0 {
	struct clk_bulk_data clks[9];
	struct clk_bulk_data clks[12];
	int num_clks;
	struct regulator_bulk_data supplies[2];
	struct reset_control *pci_reset;
@@ -208,17 +208,12 @@ struct qcom_pcie_ops {
	int (*init)(struct qcom_pcie *pcie);
	int (*post_init)(struct qcom_pcie *pcie);
	void (*deinit)(struct qcom_pcie *pcie);
	void (*post_deinit)(struct qcom_pcie *pcie);
	void (*ltssm_enable)(struct qcom_pcie *pcie);
	int (*config_sid)(struct qcom_pcie *pcie);
};

struct qcom_pcie_cfg {
	const struct qcom_pcie_ops *ops;
	unsigned int has_tbu_clk:1;
	unsigned int has_ddrss_sf_tbu_clk:1;
	unsigned int has_aggre0_clk:1;
	unsigned int has_aggre1_clk:1;
};

struct qcom_pcie {
@@ -1175,6 +1170,7 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
	struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
	struct dw_pcie *pci = pcie->pci;
	struct device *dev = pci->dev;
	unsigned int num_clks, num_opt_clks;
	unsigned int idx;
	int ret;

@@ -1195,18 +1191,25 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
	res->clks[idx++].id = "bus_master";
	res->clks[idx++].id = "bus_slave";
	res->clks[idx++].id = "slave_q2a";
	if (pcie->cfg->has_tbu_clk)

	num_clks = idx;

	ret = devm_clk_bulk_get(dev, num_clks, res->clks);
	if (ret < 0)
		return ret;

	res->clks[idx++].id = "tbu";
	if (pcie->cfg->has_ddrss_sf_tbu_clk)
	res->clks[idx++].id = "ddrss_sf_tbu";
	if (pcie->cfg->has_aggre0_clk)
	res->clks[idx++].id = "aggre0";
	if (pcie->cfg->has_aggre1_clk)
	res->clks[idx++].id = "aggre1";
	res->clks[idx++].id = "noc_aggr_4";
	res->clks[idx++].id = "noc_aggr_south_sf";
	res->clks[idx++].id = "cnoc_qx";

	num_opt_clks = idx - num_clks;
	res->num_clks = idx;

	ret = devm_clk_bulk_get(dev, res->num_clks, res->clks);
	ret = devm_clk_bulk_get_optional(dev, num_opt_clks, res->clks + num_clks);
	if (ret < 0)
		return ret;

@@ -1509,15 +1512,13 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
	if (pcie->cfg->ops->config_sid) {
		ret = pcie->cfg->ops->config_sid(pcie);
		if (ret)
			goto err;
			goto err_assert_reset;
	}

	return 0;

err:
err_assert_reset:
	qcom_ep_reset_assert(pcie);
	if (pcie->cfg->ops->post_deinit)
		pcie->cfg->ops->post_deinit(pcie);
err_disable_phy:
	phy_power_off(pcie->phy);
err_deinit:
@@ -1601,68 +1602,35 @@ static const struct qcom_pcie_ops ops_2_9_0 = {
	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
};

static const struct qcom_pcie_cfg apq8084_cfg = {
static const struct qcom_pcie_cfg cfg_1_0_0 = {
	.ops = &ops_1_0_0,
};

static const struct qcom_pcie_cfg ipq8064_cfg = {
static const struct qcom_pcie_cfg cfg_1_9_0 = {
	.ops = &ops_1_9_0,
};

static const struct qcom_pcie_cfg cfg_2_1_0 = {
	.ops = &ops_2_1_0,
};

static const struct qcom_pcie_cfg msm8996_cfg = {
static const struct qcom_pcie_cfg cfg_2_3_2 = {
	.ops = &ops_2_3_2,
};

static const struct qcom_pcie_cfg ipq8074_cfg = {
static const struct qcom_pcie_cfg cfg_2_3_3 = {
	.ops = &ops_2_3_3,
};

static const struct qcom_pcie_cfg ipq4019_cfg = {
static const struct qcom_pcie_cfg cfg_2_4_0 = {
	.ops = &ops_2_4_0,
};

static const struct qcom_pcie_cfg sdm845_cfg = {
static const struct qcom_pcie_cfg cfg_2_7_0 = {
	.ops = &ops_2_7_0,
	.has_tbu_clk = true,
};

static const struct qcom_pcie_cfg sm8150_cfg = {
	/* sm8150 has qcom IP rev 1.5.0. However 1.5.0 ops are same as
	 * 1.9.0, so reuse the same.
	 */
	.ops = &ops_1_9_0,
};

static const struct qcom_pcie_cfg sm8250_cfg = {
	.ops = &ops_1_9_0,
	.has_tbu_clk = true,
	.has_ddrss_sf_tbu_clk = true,
};

static const struct qcom_pcie_cfg sm8450_pcie0_cfg = {
	.ops = &ops_1_9_0,
	.has_ddrss_sf_tbu_clk = true,
	.has_aggre0_clk = true,
	.has_aggre1_clk = true,
};

static const struct qcom_pcie_cfg sm8450_pcie1_cfg = {
	.ops = &ops_1_9_0,
	.has_ddrss_sf_tbu_clk = true,
	.has_aggre1_clk = true,
};

static const struct qcom_pcie_cfg sc7280_cfg = {
	.ops = &ops_1_9_0,
	.has_tbu_clk = true,
};

static const struct qcom_pcie_cfg sc8180x_cfg = {
	.ops = &ops_1_9_0,
	.has_tbu_clk = true,
};

static const struct qcom_pcie_cfg ipq6018_cfg = {
static const struct qcom_pcie_cfg cfg_2_9_0 = {
	.ops = &ops_2_9_0,
};

@@ -1761,22 +1729,24 @@ static int qcom_pcie_probe(struct platform_device *pdev)
}

static const struct of_device_id qcom_pcie_match[] = {
	{ .compatible = "qcom,pcie-apq8084", .data = &apq8084_cfg },
	{ .compatible = "qcom,pcie-ipq8064", .data = &ipq8064_cfg },
	{ .compatible = "qcom,pcie-ipq8064-v2", .data = &ipq8064_cfg },
	{ .compatible = "qcom,pcie-apq8064", .data = &ipq8064_cfg },
	{ .compatible = "qcom,pcie-msm8996", .data = &msm8996_cfg },
	{ .compatible = "qcom,pcie-ipq8074", .data = &ipq8074_cfg },
	{ .compatible = "qcom,pcie-ipq4019", .data = &ipq4019_cfg },
	{ .compatible = "qcom,pcie-qcs404", .data = &ipq4019_cfg },
	{ .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg },
	{ .compatible = "qcom,pcie-sm8150", .data = &sm8150_cfg },
	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
	{ .compatible = "qcom,pcie-sc8180x", .data = &sc8180x_cfg },
	{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &sm8450_pcie0_cfg },
	{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &sm8450_pcie1_cfg },
	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
	{ .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 },
	{ .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 },
	{ .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 },
	{ .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 },
	{ .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 },
	{ .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 },
	{ .compatible = "qcom,pcie-ipq8074", .data = &cfg_2_3_3 },
	{ .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 },
	{ .compatible = "qcom,pcie-qcs404", .data = &cfg_2_4_0 },
	{ .compatible = "qcom,pcie-sa8540p", .data = &cfg_1_9_0 },
	{ .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 },
	{ .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 },
	{ .compatible = "qcom,pcie-sc8280xp", .data = &cfg_1_9_0 },
	{ .compatible = "qcom,pcie-sdm845", .data = &cfg_2_7_0 },
	{ .compatible = "qcom,pcie-sm8150", .data = &cfg_1_9_0 },
	{ .compatible = "qcom,pcie-sm8250", .data = &cfg_1_9_0 },
	{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
	{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
	{ }
};