diff options
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-qcom-ep.c')
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-qcom-ep.c | 50 | 
1 files changed, 40 insertions, 10 deletions
| diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 2fb8c15e7a91..236229f66c80 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -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 @@ -150,6 +155,16 @@ enum qcom_pcie_ep_link_status {  };  /** + * 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   * @parf: Qualcomm PCIe specific PARF register base @@ -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; @@ -482,13 +499,17 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)  	val &= ~PARF_MSTR_AXI_CLK_EN;  	writel_relaxed(val, pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); -	dw_pcie_ep_init_notify(&pcie_ep->pci.ep); +	pci_epc_init_notify(pcie_ep->pci.ep.epc);  	/* Enable LTSSM */  	val = readl_relaxed(pcie_ep->parf + PARF_LTSSM);  	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,13 +521,8 @@ err_disable_resources:  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);  	qcom_pcie_disable_resources(pcie_ep);  	pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED; @@ -640,12 +656,12 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int irq, void *data)  	if (FIELD_GET(PARF_INT_ALL_LINK_DOWN, status)) {  		dev_dbg(dev, "Received Linkdown event\n");  		pcie_ep->link_status = QCOM_PCIE_EP_LINK_DOWN; -		pci_epc_linkdown(pci->ep.epc); +		dw_pcie_ep_linkdown(&pci->ep);  	} else if (FIELD_GET(PARF_INT_ALL_BME, status)) { -		dev_dbg(dev, "Received BME event. Link is enabled!\n"); +		dev_dbg(dev, "Received Bus Master Enable event\n");  		pcie_ep->link_status = QCOM_PCIE_EP_LINK_ENABLED;  		qcom_pcie_ep_icc_update(pcie_ep); -		pci_epc_bme_notify(pci->ep.epc); +		pci_epc_bus_master_enable_notify(pci->ep.epc);  	} else if (FIELD_GET(PARF_INT_ALL_PM_TURNOFF, status)) {  		dev_dbg(dev, "Received PM Turn-off event! Entering L23\n");  		val = readl_relaxed(pcie_ep->parf + PARF_PM_CTRL); @@ -816,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); @@ -874,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", },  	{ } |