提交 a0e43bb9 编写于 作者: R Robert Marko 提交者: Bjorn Helgaas

PCI: qcom: Power on PHY before IPQ8074 DBI register accesses

Currently the Gen2 port in IPQ8074 will cause the system to hang as it
accesses DBI registers in qcom_pcie_init_2_3_3(), and those are only
accesible after phy_power_on().

Move the DBI read/writes to a new qcom_pcie_post_init_2_3_3(), which is
executed after phy_power_on().

Link: https://lore.kernel.org/r/20220623155004.688090-1-robimarko@gmail.com
Fixes: a0fd361d ("PCI: dwc: Move "dbi", "dbi2", and "addr_space" resource setup into common code")
Signed-off-by: NRobert Marko <robimarko@gmail.com>
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: NDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: stable@vger.kernel.org	# v5.11+
上级 38f897ae
...@@ -1036,9 +1036,7 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) ...@@ -1036,9 +1036,7 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3; struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;
struct dw_pcie *pci = pcie->pci; struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev; struct device *dev = pci->dev;
u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
int i, ret; int i, ret;
u32 val;
for (i = 0; i < ARRAY_SIZE(res->rst); i++) { for (i = 0; i < ARRAY_SIZE(res->rst); i++) {
ret = reset_control_assert(res->rst[i]); ret = reset_control_assert(res->rst[i]);
...@@ -1095,6 +1093,33 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) ...@@ -1095,6 +1093,33 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
goto err_clk_aux; goto err_clk_aux;
} }
return 0;
err_clk_aux:
clk_disable_unprepare(res->ahb_clk);
err_clk_ahb:
clk_disable_unprepare(res->axi_s_clk);
err_clk_axi_s:
clk_disable_unprepare(res->axi_m_clk);
err_clk_axi_m:
clk_disable_unprepare(res->iface);
err_clk_iface:
/*
* Not checking for failure, will anyway return
* the original failure in 'ret'.
*/
for (i = 0; i < ARRAY_SIZE(res->rst); i++)
reset_control_assert(res->rst[i]);
return ret;
}
static int qcom_pcie_post_init_2_3_3(struct qcom_pcie *pcie)
{
struct dw_pcie *pci = pcie->pci;
u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
u32 val;
writel(SLV_ADDR_SPACE_SZ, writel(SLV_ADDR_SPACE_SZ,
pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE); pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
...@@ -1122,24 +1147,6 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) ...@@ -1122,24 +1147,6 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
PCI_EXP_DEVCTL2); PCI_EXP_DEVCTL2);
return 0; return 0;
err_clk_aux:
clk_disable_unprepare(res->ahb_clk);
err_clk_ahb:
clk_disable_unprepare(res->axi_s_clk);
err_clk_axi_s:
clk_disable_unprepare(res->axi_m_clk);
err_clk_axi_m:
clk_disable_unprepare(res->iface);
err_clk_iface:
/*
* Not checking for failure, will anyway return
* the original failure in 'ret'.
*/
for (i = 0; i < ARRAY_SIZE(res->rst); i++)
reset_control_assert(res->rst[i]);
return ret;
} }
static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
...@@ -1465,6 +1472,7 @@ static const struct qcom_pcie_ops ops_2_4_0 = { ...@@ -1465,6 +1472,7 @@ static const struct qcom_pcie_ops ops_2_4_0 = {
static const struct qcom_pcie_ops ops_2_3_3 = { static const struct qcom_pcie_ops ops_2_3_3 = {
.get_resources = qcom_pcie_get_resources_2_3_3, .get_resources = qcom_pcie_get_resources_2_3_3,
.init = qcom_pcie_init_2_3_3, .init = qcom_pcie_init_2_3_3,
.post_init = qcom_pcie_post_init_2_3_3,
.deinit = qcom_pcie_deinit_2_3_3, .deinit = qcom_pcie_deinit_2_3_3,
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册