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

Merge branch 'pci/controller/qcom'

- Use devm_clk_bulk_get_all() to get all the clocks from DT to avoid
  writing out all the clock names (Manivannan Sadhasivam)

- Add DT binding and driver support for the SA8775P SoC (Mrinmay Sarkar)

- Refactor dw_pcie_edma_find_chip() to enable adding support for Hyper DMA
  (HDMA) (Manivannan Sadhasivam)

- Enable drivers to supply the eDMA channel count since some can't auto
  detect this (Manivannan Sadhasivam)

- Add HDMA support for the SA8775P SoC (Mrinmay Sarkar)

- Override the SA8775P NO_SNOOP default to avoid possible memory corruption
  (Mrinmay Sarkar)

- Make sure resources are disabled during PERST# assertion, even if the
  link is already disabled (Manivannan Sadhasivam)

- Vote for the CPU-PCIe ICC (interconnect) path to ensure it stays active
  even if other drivers don't vote for it (Krishna chaitanya chundru)

- Add Operating Performance Points (OPP) to scale performance state based
  on aggregate link bandwidth to improve SoC power efficiency (Krishna
  chaitanya chundru)

- Return failure instead of success if dev_pm_opp_find_freq_floor() fails
  (Dan Carpenter)

- Avoid an error pointer dereference if dev_pm_opp_find_freq_exact() fails
  (Dan Carpenter)

- Prevent use of uninitialized data in qcom_pcie_suspend_noirq() (Dan
  Carpenter)

* pci/controller/qcom:
  PCI: qcom: Prevent use of uninitialized data in qcom_pcie_suspend_noirq()
  PCI: qcom: Prevent potential error pointer dereference
  PCI: qcom: Fix missing error code in qcom_pcie_probe()
  PCI: qcom: Add OPP support to scale performance
  PCI: Bring the PCIe speed to MBps logic to new pcie_dev_speed_mbps()
  PCI: qcom: Add ICC bandwidth vote for CPU to PCIe path
  PCI: qcom-ep: Disable resources unconditionally during PERST# assert
  PCI: qcom-ep: Override NO_SNOOP attribute for SA8775P EP
  PCI: qcom: Override NO_SNOOP attribute for SA8775P RC
  PCI: epf-mhi: Enable HDMA for SA8775P SoC
  PCI: qcom-ep: Add HDMA support for SA8775P SoC
  PCI: dwc: Pass the eDMA mapping format flag directly from glue drivers
  PCI: dwc: Skip finding eDMA channels count for HDMA platforms
  PCI: dwc: Refactor dw_pcie_edma_find_chip() API
  PCI: qcom-ep: Add support for SA8775P SOC
  dt-bindings: PCI: qcom-ep: Add support for SA8775P SoC
  PCI: qcom: Use devm_clk_bulk_get_all() API
parents 325b9a3e 044b45be
Loading
Loading
Loading
Loading
+62 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ properties:
  compatible:
    oneOf:
      - enum:
          - qcom,sa8775p-pcie-ep
          - qcom,sdx55-pcie-ep
          - qcom,sm8450-pcie-ep
      - items:
@@ -20,6 +21,7 @@ properties:
          - const: qcom,sdx55-pcie-ep

  reg:
    minItems: 6
    items:
      - description: Qualcomm-specific PARF configuration registers
      - description: DesignWare PCIe registers
@@ -27,8 +29,10 @@ properties:
      - description: Address Translation Unit (ATU) registers
      - description: Memory region used to map remote RC address space
      - description: BAR memory region
      - description: DMA register space

  reg-names:
    minItems: 6
    items:
      - const: parf
      - const: dbi
@@ -36,13 +40,14 @@ properties:
      - const: atu
      - const: addr_space
      - const: mmio
      - const: dma

  clocks:
    minItems: 7
    minItems: 5
    maxItems: 8

  clock-names:
    minItems: 7
    minItems: 5
    maxItems: 8

  qcom,perst-regs:
@@ -57,14 +62,18 @@ properties:
          - description: Perst separation enable offset

  interrupts:
    minItems: 2
    items:
      - description: PCIe Global interrupt
      - description: PCIe Doorbell interrupt
      - description: DMA interrupt

  interrupt-names:
    minItems: 2
    items:
      - const: global
      - const: doorbell
      - const: dma

  reset-gpios:
    description: GPIO used as PERST# input signal
@@ -125,6 +134,10 @@ allOf:
              - qcom,sdx55-pcie-ep
    then:
      properties:
        reg:
          maxItems: 6
        reg-names:
          maxItems: 6
        clocks:
          items:
            - description: PCIe Auxiliary clock
@@ -143,6 +156,10 @@ allOf:
            - const: slave_q2a
            - const: sleep
            - const: ref
        interrupts:
          maxItems: 2
        interrupt-names:
          maxItems: 2

  - if:
      properties:
@@ -152,6 +169,10 @@ allOf:
              - qcom,sm8450-pcie-ep
    then:
      properties:
        reg:
          maxItems: 6
        reg-names:
          maxItems: 6
        clocks:
          items:
            - description: PCIe Auxiliary clock
@@ -172,6 +193,45 @@ allOf:
            - const: ref
            - const: ddrss_sf_tbu
            - const: aggre_noc_axi
        interrupts:
          maxItems: 2
        interrupt-names:
          maxItems: 2

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,sa8775p-pcie-ep
    then:
      properties:
        reg:
          minItems: 7
          maxItems: 7
        reg-names:
          minItems: 7
          maxItems: 7
        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
        clock-names:
          items:
            - const: aux
            - const: cfg
            - const: bus_master
            - const: bus_slave
            - const: slave_q2a
        interrupts:
          minItems: 3
          maxItems: 3
        interrupt-names:
          minItems: 3
          maxItems: 3

unevaluatedProperties: false

+49 −16
Original line number Diff line number Diff line
@@ -870,30 +870,40 @@ static struct dw_edma_plat_ops dw_pcie_edma_ops = {
	.irq_vector = dw_pcie_edma_irq_vector,
};

static int dw_pcie_edma_find_chip(struct dw_pcie *pci)
static void dw_pcie_edma_init_data(struct dw_pcie *pci)
{
	pci->edma.dev = pci->dev;

	if (!pci->edma.ops)
		pci->edma.ops = &dw_pcie_edma_ops;

	pci->edma.flags |= DW_EDMA_CHIP_LOCAL;
}

static int dw_pcie_edma_find_mf(struct dw_pcie *pci)
{
	u32 val;

	/*
	 * Bail out finding the mapping format if it is already set by the glue
	 * driver. Also ensure that the edma.reg_base is pointing to a valid
	 * memory region.
	 */
	if (pci->edma.mf != EDMA_MF_EDMA_LEGACY)
		return pci->edma.reg_base ? 0 : -ENODEV;

	/*
	 * Indirect eDMA CSRs access has been completely removed since v5.40a
	 * thus no space is now reserved for the eDMA channels viewport and
	 * former DMA CTRL register is no longer fixed to FFs.
	 *
	 * Note that Renesas R-Car S4-8's PCIe controllers for unknown reason
	 * have zeros in the eDMA CTRL register even though the HW-manual
	 * explicitly states there must FFs if the unrolled mapping is enabled.
	 * For such cases the low-level drivers are supposed to manually
	 * activate the unrolled mapping to bypass the auto-detection procedure.
	 */
	if (dw_pcie_ver_is_ge(pci, 540A) || dw_pcie_cap_is(pci, EDMA_UNROLL))
	if (dw_pcie_ver_is_ge(pci, 540A))
		val = 0xFFFFFFFF;
	else
		val = dw_pcie_readl_dbi(pci, PCIE_DMA_VIEWPORT_BASE + PCIE_DMA_CTRL);

	if (val == 0xFFFFFFFF && pci->edma.reg_base) {
		pci->edma.mf = EDMA_MF_EDMA_UNROLL;

		val = dw_pcie_readl_dma(pci, PCIE_DMA_CTRL);
	} else if (val != 0xFFFFFFFF) {
		pci->edma.mf = EDMA_MF_EDMA_LEGACY;

@@ -902,15 +912,25 @@ static int dw_pcie_edma_find_chip(struct dw_pcie *pci)
		return -ENODEV;
	}

	pci->edma.dev = pci->dev;
	return 0;
}

	if (!pci->edma.ops)
		pci->edma.ops = &dw_pcie_edma_ops;
static int dw_pcie_edma_find_channels(struct dw_pcie *pci)
{
	u32 val;

	pci->edma.flags |= DW_EDMA_CHIP_LOCAL;
	/*
	 * Autodetect the read/write channels count only for non-HDMA platforms.
	 * HDMA platforms with native CSR mapping doesn't support autodetect,
	 * so the glue drivers should've passed the valid count already. If not,
	 * the below sanity check will catch it.
	 */
	if (pci->edma.mf != EDMA_MF_HDMA_NATIVE) {
		val = dw_pcie_readl_dma(pci, PCIE_DMA_CTRL);

		pci->edma.ll_wr_cnt = FIELD_GET(PCIE_DMA_NUM_WR_CHAN, val);
		pci->edma.ll_rd_cnt = FIELD_GET(PCIE_DMA_NUM_RD_CHAN, val);
	}

	/* Sanity check the channels count if the mapping was incorrect */
	if (!pci->edma.ll_wr_cnt || pci->edma.ll_wr_cnt > EDMA_MAX_WR_CH ||
@@ -920,6 +940,19 @@ static int dw_pcie_edma_find_chip(struct dw_pcie *pci)
	return 0;
}

static int dw_pcie_edma_find_chip(struct dw_pcie *pci)
{
	int ret;

	dw_pcie_edma_init_data(pci);

	ret = dw_pcie_edma_find_mf(pci);
	if (ret)
		return ret;

	return dw_pcie_edma_find_channels(pci);
}

static int dw_pcie_edma_irq_verify(struct dw_pcie *pci)
{
	struct platform_device *pdev = to_platform_device(pci->dev);
+2 −3
Original line number Diff line number Diff line
@@ -51,9 +51,8 @@

/* DWC PCIe controller capabilities */
#define DW_PCIE_CAP_REQ_RES		0
#define DW_PCIE_CAP_EDMA_UNROLL		1
#define DW_PCIE_CAP_IATU_UNROLL		2
#define DW_PCIE_CAP_CDM_CHECK		3
#define DW_PCIE_CAP_IATU_UNROLL		1
#define DW_PCIE_CAP_CDM_CHECK		2

#define dw_pcie_cap_is(_pci, _cap) \
	test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps)
+35 −6
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#define PARF_DBI_BASE_ADDR_HI			0x354
#define PARF_SLV_ADDR_SPACE_SIZE		0x358
#define PARF_SLV_ADDR_SPACE_SIZE_HI		0x35c
#define PARF_NO_SNOOP_OVERIDE			0x3d4
#define PARF_ATU_BASE_ADDR			0x634
#define PARF_ATU_BASE_ADDR_HI			0x638
#define PARF_SRIS_MODE				0x644
@@ -86,6 +87,10 @@
#define PARF_DEBUG_INT_CFG_BUS_MASTER_EN	BIT(2)
#define PARF_DEBUG_INT_RADM_PM_TURNOFF		BIT(3)

/* PARF_NO_SNOOP_OVERIDE register fields */
#define WR_NO_SNOOP_OVERIDE_EN                 BIT(1)
#define RD_NO_SNOOP_OVERIDE_EN                 BIT(3)

/* PARF_DEVICE_TYPE register fields */
#define PARF_DEVICE_TYPE_EP			0x0

@@ -149,6 +154,16 @@ enum qcom_pcie_ep_link_status {
	QCOM_PCIE_EP_LINK_DOWN,
};

/**
 * struct qcom_pcie_ep_cfg - Per SoC config struct
 * @hdma_support: HDMA support on this SoC
 * @override_no_snoop: Override NO_SNOOP attribute in TLP to enable cache snooping
 */
struct qcom_pcie_ep_cfg {
	bool hdma_support;
	bool override_no_snoop;
};

/**
 * struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller
 * @pci: Designware PCIe controller struct
@@ -167,6 +182,7 @@ enum qcom_pcie_ep_link_status {
 * @num_clks: PCIe clocks count
 * @perst_en: Flag for PERST enable
 * @perst_sep_en: Flag for PERST separation enable
 * @cfg: PCIe EP config struct
 * @link_status: PCIe Link status
 * @global_irq: Qualcomm PCIe specific Global IRQ
 * @perst_irq: PERST# IRQ
@@ -194,6 +210,7 @@ struct qcom_pcie_ep {
	u32 perst_en;
	u32 perst_sep_en;

	const struct qcom_pcie_ep_cfg *cfg;
	enum qcom_pcie_ep_link_status link_status;
	int global_irq;
	int perst_irq;
@@ -489,6 +506,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
	val |= BIT(8);
	writel_relaxed(val, pcie_ep->parf + PARF_LTSSM);

	if (pcie_ep->cfg && pcie_ep->cfg->override_no_snoop)
		writel_relaxed(WR_NO_SNOOP_OVERIDE_EN | RD_NO_SNOOP_OVERIDE_EN,
				pcie_ep->parf + PARF_NO_SNOOP_OVERIDE);

	return 0;

err_disable_resources:
@@ -500,12 +521,6 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
static void qcom_pcie_perst_assert(struct dw_pcie *pci)
{
	struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci);
	struct device *dev = pci->dev;

	if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED) {
		dev_dbg(dev, "Link is already disabled\n");
		return;
	}

	pci_epc_deinit_notify(pci->ep.epc);
	dw_pcie_ep_cleanup(&pci->ep);
@@ -817,6 +832,14 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
	pcie_ep->pci.ops = &pci_ops;
	pcie_ep->pci.ep.ops = &pci_ep_ops;
	pcie_ep->pci.edma.nr_irqs = 1;

	pcie_ep->cfg = of_device_get_match_data(dev);
	if (pcie_ep->cfg && pcie_ep->cfg->hdma_support) {
		pcie_ep->pci.edma.ll_wr_cnt = 8;
		pcie_ep->pci.edma.ll_rd_cnt = 8;
		pcie_ep->pci.edma.mf = EDMA_MF_HDMA_NATIVE;
	}

	platform_set_drvdata(pdev, pcie_ep);

	ret = qcom_pcie_ep_get_resources(pdev, pcie_ep);
@@ -875,7 +898,13 @@ static void qcom_pcie_ep_remove(struct platform_device *pdev)
	qcom_pcie_disable_resources(pcie_ep);
}

static const struct qcom_pcie_ep_cfg cfg_1_34_0 = {
	.hdma_support = true,
	.override_no_snoop = true,
};

static const struct of_device_id qcom_pcie_ep_match[] = {
	{ .compatible = "qcom,sa8775p-pcie-ep", .data = &cfg_1_34_0},
	{ .compatible = "qcom,sdx55-pcie-ep", },
	{ .compatible = "qcom,sm8450-pcie-ep", },
	{ }
+203 −142

File changed.

Preview size limit exceeded, changes collapsed.

Loading