Commit 36d9018d authored by Robert Marko's avatar Robert Marko Committed by Bjorn Helgaas

PCI: qcom: Power on PHY before DBI register accesses

IPQ8074 requires the PHY to be powered on before accessing DBI registers.
It's not clear whether other variants have the same dependency, but there
seems to be no reason for them to be different, so move all the DBI
accesses from .init() to .post_init() so they are all after phy_power_on().

[bhelgaas: commit log]
Link: https://lore.kernel.org/r/20220623155004.688090-2-robimarko@gmail.comSigned-off-by: default avatarRobert Marko <robimarko@gmail.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent a0e43bb9
...@@ -325,8 +325,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) ...@@ -325,8 +325,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
struct dw_pcie *pci = pcie->pci; struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev; struct device *dev = pci->dev;
struct device_node *node = dev->of_node;
u32 val;
int ret; int ret;
/* reset the PCIe interface as uboot can leave it undefined state */ /* reset the PCIe interface as uboot can leave it undefined state */
...@@ -379,6 +377,33 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) ...@@ -379,6 +377,33 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
goto err_deassert_axi; goto err_deassert_axi;
} }
return 0;
err_deassert_axi:
reset_control_assert(res->por_reset);
err_deassert_por:
reset_control_assert(res->pci_reset);
err_deassert_pci:
reset_control_assert(res->phy_reset);
err_deassert_phy:
reset_control_assert(res->ext_reset);
err_deassert_ext:
reset_control_assert(res->ahb_reset);
err_deassert_ahb:
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
return ret;
}
static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
{
struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
struct device_node *node = dev->of_node;
u32 val;
int ret;
/* enable PCIe clocks and resets */ /* enable PCIe clocks and resets */
val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
val &= ~BIT(0); val &= ~BIT(0);
...@@ -386,7 +411,7 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) ...@@ -386,7 +411,7 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks); ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
if (ret) if (ret)
goto err_clks; return ret;
if (of_device_is_compatible(node, "qcom,pcie-ipq8064") || if (of_device_is_compatible(node, "qcom,pcie-ipq8064") ||
of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) { of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) {
...@@ -426,23 +451,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) ...@@ -426,23 +451,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1); pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
return 0; return 0;
err_clks:
reset_control_assert(res->axi_reset);
err_deassert_axi:
reset_control_assert(res->por_reset);
err_deassert_por:
reset_control_assert(res->pci_reset);
err_deassert_pci:
reset_control_assert(res->phy_reset);
err_deassert_phy:
reset_control_assert(res->ext_reset);
err_deassert_ext:
reset_control_assert(res->ahb_reset);
err_deassert_ahb:
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
return ret;
} }
static int qcom_pcie_get_resources_1_0_0(struct qcom_pcie *pcie) static int qcom_pcie_get_resources_1_0_0(struct qcom_pcie *pcie)
...@@ -530,16 +538,6 @@ static int qcom_pcie_init_1_0_0(struct qcom_pcie *pcie) ...@@ -530,16 +538,6 @@ static int qcom_pcie_init_1_0_0(struct qcom_pcie *pcie)
goto err_slave; goto err_slave;
} }
/* change DBI base address */
writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
if (IS_ENABLED(CONFIG_PCI_MSI)) {
u32 val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
val |= BIT(31);
writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
}
return 0; return 0;
err_slave: err_slave:
clk_disable_unprepare(res->slave_bus); clk_disable_unprepare(res->slave_bus);
...@@ -555,6 +553,21 @@ static int qcom_pcie_init_1_0_0(struct qcom_pcie *pcie) ...@@ -555,6 +553,21 @@ static int qcom_pcie_init_1_0_0(struct qcom_pcie *pcie)
return ret; return ret;
} }
static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
{
/* change DBI base address */
writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
if (IS_ENABLED(CONFIG_PCI_MSI)) {
u32 val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
val |= BIT(31);
writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
}
return 0;
}
static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie) static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie)
{ {
u32 val; u32 val;
...@@ -623,7 +636,6 @@ static int qcom_pcie_init_2_3_2(struct qcom_pcie *pcie) ...@@ -623,7 +636,6 @@ static int qcom_pcie_init_2_3_2(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2; struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2;
struct dw_pcie *pci = pcie->pci; struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev; struct device *dev = pci->dev;
u32 val;
int ret; int ret;
ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies); ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
...@@ -656,27 +668,6 @@ static int qcom_pcie_init_2_3_2(struct qcom_pcie *pcie) ...@@ -656,27 +668,6 @@ static int qcom_pcie_init_2_3_2(struct qcom_pcie *pcie)
goto err_slave_clk; goto err_slave_clk;
} }
/* enable PCIe clocks and resets */
val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
val &= ~BIT(0);
writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
/* change DBI base address */
writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
/* MAC PHY_POWERDOWN MUX DISABLE */
val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
val &= ~BIT(29);
writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
val |= BIT(4);
writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
val |= BIT(31);
writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
return 0; return 0;
err_slave_clk: err_slave_clk:
...@@ -697,8 +688,30 @@ static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie) ...@@ -697,8 +688,30 @@ static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2; struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2;
struct dw_pcie *pci = pcie->pci; struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev; struct device *dev = pci->dev;
u32 val;
int ret; int ret;
/* enable PCIe clocks and resets */
val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
val &= ~BIT(0);
writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
/* change DBI base address */
writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
/* MAC PHY_POWERDOWN MUX DISABLE */
val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
val &= ~BIT(29);
writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
val |= BIT(4);
writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
val |= BIT(31);
writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
ret = clk_prepare_enable(res->pipe_clk); ret = clk_prepare_enable(res->pipe_clk);
if (ret) { if (ret) {
dev_err(dev, "cannot prepare/enable pipe clock\n"); dev_err(dev, "cannot prepare/enable pipe clock\n");
...@@ -812,7 +825,6 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie) ...@@ -812,7 +825,6 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_4_0 *res = &pcie->res.v2_4_0; struct qcom_pcie_resources_2_4_0 *res = &pcie->res.v2_4_0;
struct dw_pcie *pci = pcie->pci; struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev; struct device *dev = pci->dev;
u32 val;
int ret; int ret;
ret = reset_control_assert(res->axi_m_reset); ret = reset_control_assert(res->axi_m_reset);
...@@ -937,6 +949,33 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie) ...@@ -937,6 +949,33 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie)
if (ret) if (ret)
goto err_clks; goto err_clks;
return 0;
err_clks:
reset_control_assert(res->ahb_reset);
err_rst_ahb:
reset_control_assert(res->pwr_reset);
err_rst_pwr:
reset_control_assert(res->axi_s_reset);
err_rst_axi_s:
reset_control_assert(res->axi_m_sticky_reset);
err_rst_axi_m_sticky:
reset_control_assert(res->axi_m_reset);
err_rst_axi_m:
reset_control_assert(res->pipe_sticky_reset);
err_rst_pipe_sticky:
reset_control_assert(res->pipe_reset);
err_rst_pipe:
reset_control_assert(res->phy_reset);
err_rst_phy:
reset_control_assert(res->phy_ahb_reset);
return ret;
}
static int qcom_pcie_post_init_2_4_0(struct qcom_pcie *pcie)
{
u32 val;
/* enable PCIe clocks and resets */ /* enable PCIe clocks and resets */
val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
val &= ~BIT(0); val &= ~BIT(0);
...@@ -959,26 +998,6 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie) ...@@ -959,26 +998,6 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie)
writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2); writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
return 0; return 0;
err_clks:
reset_control_assert(res->ahb_reset);
err_rst_ahb:
reset_control_assert(res->pwr_reset);
err_rst_pwr:
reset_control_assert(res->axi_s_reset);
err_rst_axi_s:
reset_control_assert(res->axi_m_sticky_reset);
err_rst_axi_m_sticky:
reset_control_assert(res->axi_m_reset);
err_rst_axi_m:
reset_control_assert(res->pipe_sticky_reset);
err_rst_pipe_sticky:
reset_control_assert(res->pipe_reset);
err_rst_pipe:
reset_control_assert(res->phy_reset);
err_rst_phy:
reset_control_assert(res->phy_ahb_reset);
return ret;
} }
static int qcom_pcie_get_resources_2_3_3(struct qcom_pcie *pcie) static int qcom_pcie_get_resources_2_3_3(struct qcom_pcie *pcie)
...@@ -1438,6 +1457,7 @@ static const struct dw_pcie_host_ops qcom_pcie_dw_ops = { ...@@ -1438,6 +1457,7 @@ static const struct dw_pcie_host_ops qcom_pcie_dw_ops = {
static const struct qcom_pcie_ops ops_2_1_0 = { static const struct qcom_pcie_ops ops_2_1_0 = {
.get_resources = qcom_pcie_get_resources_2_1_0, .get_resources = qcom_pcie_get_resources_2_1_0,
.init = qcom_pcie_init_2_1_0, .init = qcom_pcie_init_2_1_0,
.post_init = qcom_pcie_post_init_2_1_0,
.deinit = qcom_pcie_deinit_2_1_0, .deinit = qcom_pcie_deinit_2_1_0,
.ltssm_enable = qcom_pcie_2_1_0_ltssm_enable, .ltssm_enable = qcom_pcie_2_1_0_ltssm_enable,
}; };
...@@ -1446,6 +1466,7 @@ static const struct qcom_pcie_ops ops_2_1_0 = { ...@@ -1446,6 +1466,7 @@ static const struct qcom_pcie_ops ops_2_1_0 = {
static const struct qcom_pcie_ops ops_1_0_0 = { static const struct qcom_pcie_ops ops_1_0_0 = {
.get_resources = qcom_pcie_get_resources_1_0_0, .get_resources = qcom_pcie_get_resources_1_0_0,
.init = qcom_pcie_init_1_0_0, .init = qcom_pcie_init_1_0_0,
.post_init = qcom_pcie_post_init_1_0_0,
.deinit = qcom_pcie_deinit_1_0_0, .deinit = qcom_pcie_deinit_1_0_0,
.ltssm_enable = qcom_pcie_2_1_0_ltssm_enable, .ltssm_enable = qcom_pcie_2_1_0_ltssm_enable,
}; };
...@@ -1464,6 +1485,7 @@ static const struct qcom_pcie_ops ops_2_3_2 = { ...@@ -1464,6 +1485,7 @@ static const struct qcom_pcie_ops ops_2_3_2 = {
static const struct qcom_pcie_ops ops_2_4_0 = { static const struct qcom_pcie_ops ops_2_4_0 = {
.get_resources = qcom_pcie_get_resources_2_4_0, .get_resources = qcom_pcie_get_resources_2_4_0,
.init = qcom_pcie_init_2_4_0, .init = qcom_pcie_init_2_4_0,
.post_init = qcom_pcie_post_init_2_4_0,
.deinit = qcom_pcie_deinit_2_4_0, .deinit = qcom_pcie_deinit_2_4_0,
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment