diff options
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-qcom.c')
-rw-r--r-- | drivers/pci/controller/dwc/pcie-qcom.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 1bdac298a943..33e510393976 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c | |||
@@ -108,6 +108,7 @@ struct qcom_pcie_resources_2_1_0 { | |||
108 | struct reset_control *ahb_reset; | 108 | struct reset_control *ahb_reset; |
109 | struct reset_control *por_reset; | 109 | struct reset_control *por_reset; |
110 | struct reset_control *phy_reset; | 110 | struct reset_control *phy_reset; |
111 | struct reset_control *ext_reset; | ||
111 | struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY]; | 112 | struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY]; |
112 | }; | 113 | }; |
113 | 114 | ||
@@ -269,6 +270,10 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie) | |||
269 | if (IS_ERR(res->por_reset)) | 270 | if (IS_ERR(res->por_reset)) |
270 | return PTR_ERR(res->por_reset); | 271 | return PTR_ERR(res->por_reset); |
271 | 272 | ||
273 | res->ext_reset = devm_reset_control_get_optional_exclusive(dev, "ext"); | ||
274 | if (IS_ERR(res->ext_reset)) | ||
275 | return PTR_ERR(res->ext_reset); | ||
276 | |||
272 | res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); | 277 | res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); |
273 | return PTR_ERR_OR_ZERO(res->phy_reset); | 278 | return PTR_ERR_OR_ZERO(res->phy_reset); |
274 | } | 279 | } |
@@ -281,6 +286,7 @@ static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie) | |||
281 | reset_control_assert(res->axi_reset); | 286 | reset_control_assert(res->axi_reset); |
282 | reset_control_assert(res->ahb_reset); | 287 | reset_control_assert(res->ahb_reset); |
283 | reset_control_assert(res->por_reset); | 288 | reset_control_assert(res->por_reset); |
289 | reset_control_assert(res->ext_reset); | ||
284 | reset_control_assert(res->pci_reset); | 290 | reset_control_assert(res->pci_reset); |
285 | clk_disable_unprepare(res->iface_clk); | 291 | clk_disable_unprepare(res->iface_clk); |
286 | clk_disable_unprepare(res->core_clk); | 292 | clk_disable_unprepare(res->core_clk); |
@@ -333,6 +339,12 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) | |||
333 | goto err_deassert_ahb; | 339 | goto err_deassert_ahb; |
334 | } | 340 | } |
335 | 341 | ||
342 | ret = reset_control_deassert(res->ext_reset); | ||
343 | if (ret) { | ||
344 | dev_err(dev, "cannot deassert ext reset\n"); | ||
345 | goto err_deassert_ahb; | ||
346 | } | ||
347 | |||
336 | /* enable PCIe clocks and resets */ | 348 | /* enable PCIe clocks and resets */ |
337 | val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); | 349 | val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); |
338 | val &= ~BIT(0); | 350 | val &= ~BIT(0); |
@@ -359,7 +371,9 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) | |||
359 | 371 | ||
360 | /* enable external reference clock */ | 372 | /* enable external reference clock */ |
361 | val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); | 373 | val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); |
362 | val &= ~PHY_REFCLK_USE_PAD; | 374 | /* USE_PAD is required only for ipq806x */ |
375 | if (!of_device_is_compatible(node, "qcom,pcie-apq8064")) | ||
376 | val &= ~PHY_REFCLK_USE_PAD; | ||
363 | val |= PHY_REFCLK_SSP_EN; | 377 | val |= PHY_REFCLK_SSP_EN; |
364 | writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK); | 378 | writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK); |
365 | 379 | ||