Commit 383215dd authored by Manivannan Sadhasivam's avatar Manivannan Sadhasivam Committed by Lorenzo Pieralisi

PCI: qcom: Use bulk reset APIs for handling resets for IP rev 2.1.0

All the resets are asserted and deasserted at the same time. So the bulk
reset APIs can be used to handle them together. This simplifies the code
a lot.

While at it, let's also move the qcom_pcie_resources_2_1_0 struct below
qcom_pcie_resources_1_0_0 to keep it sorted.

Link: https://lore.kernel.org/r/20230316081117.14288-8-manivannan.sadhasivam@linaro.orgSigned-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarLorenzo Pieralisi <lpieralisi@kernel.org>
parent 94ebd232
...@@ -143,22 +143,8 @@ ...@@ -143,22 +143,8 @@
#define PERST_DELAY_US 1000 #define PERST_DELAY_US 1000
#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0)) #define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
struct qcom_pcie_resources_2_1_0 {
struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
struct reset_control *pci_reset;
struct reset_control *axi_reset;
struct reset_control *ahb_reset;
struct reset_control *por_reset;
struct reset_control *phy_reset;
struct reset_control *ext_reset;
struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY];
};
struct qcom_pcie_resources_1_0_0 { struct qcom_pcie_resources_1_0_0 {
struct clk *iface; struct clk *iface;
struct clk *aux; struct clk *aux;
...@@ -168,6 +154,16 @@ struct qcom_pcie_resources_1_0_0 { ...@@ -168,6 +154,16 @@ struct qcom_pcie_resources_1_0_0 {
struct regulator *vdda; struct regulator *vdda;
}; };
#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
#define QCOM_PCIE_2_1_0_MAX_RESETS 6
#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
struct qcom_pcie_resources_2_1_0 {
struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
struct reset_control_bulk_data resets[QCOM_PCIE_2_1_0_MAX_RESETS];
int num_resets;
struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY];
};
#define QCOM_PCIE_2_3_2_MAX_SUPPLY 2 #define QCOM_PCIE_2_3_2_MAX_SUPPLY 2
struct qcom_pcie_resources_2_3_2 { struct qcom_pcie_resources_2_3_2 {
struct clk *aux_clk; struct clk *aux_clk;
...@@ -295,6 +291,7 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie) ...@@ -295,6 +291,7 @@ static int qcom_pcie_get_resources_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;
bool is_apq = of_device_is_compatible(dev->of_node, "qcom,pcie-apq8064");
int ret; int ret;
res->supplies[0].supply = "vdda"; res->supplies[0].supply = "vdda";
...@@ -321,28 +318,20 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie) ...@@ -321,28 +318,20 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
if (ret < 0) if (ret < 0)
return ret; return ret;
res->pci_reset = devm_reset_control_get_exclusive(dev, "pci"); res->resets[0].id = "pci";
if (IS_ERR(res->pci_reset)) res->resets[1].id = "axi";
return PTR_ERR(res->pci_reset); res->resets[2].id = "ahb";
res->resets[3].id = "por";
res->axi_reset = devm_reset_control_get_exclusive(dev, "axi"); res->resets[4].id = "phy";
if (IS_ERR(res->axi_reset)) res->resets[5].id = "ext";
return PTR_ERR(res->axi_reset);
res->ahb_reset = devm_reset_control_get_exclusive(dev, "ahb");
if (IS_ERR(res->ahb_reset))
return PTR_ERR(res->ahb_reset);
res->por_reset = devm_reset_control_get_exclusive(dev, "por");
if (IS_ERR(res->por_reset))
return PTR_ERR(res->por_reset);
res->ext_reset = devm_reset_control_get_optional_exclusive(dev, "ext"); /* ext is optional on APQ8016 */
if (IS_ERR(res->ext_reset)) res->num_resets = is_apq ? 5 : 6;
return PTR_ERR(res->ext_reset); ret = devm_reset_control_bulk_get_exclusive(dev, res->num_resets, res->resets);
if (ret < 0)
return ret;
res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); return 0;
return PTR_ERR_OR_ZERO(res->phy_reset);
} }
static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie) static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie)
...@@ -350,12 +339,7 @@ static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie) ...@@ -350,12 +339,7 @@ static void qcom_pcie_deinit_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;
clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks); clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
reset_control_assert(res->pci_reset); reset_control_bulk_assert(res->num_resets, res->resets);
reset_control_assert(res->axi_reset);
reset_control_assert(res->ahb_reset);
reset_control_assert(res->por_reset);
reset_control_assert(res->ext_reset);
reset_control_assert(res->phy_reset);
writel(1, pcie->parf + PARF_PHY_CTRL); writel(1, pcie->parf + PARF_PHY_CTRL);
...@@ -370,12 +354,11 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) ...@@ -370,12 +354,11 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
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 */
reset_control_assert(res->pci_reset); ret = reset_control_bulk_assert(res->num_resets, res->resets);
reset_control_assert(res->axi_reset); if (ret < 0) {
reset_control_assert(res->ahb_reset); dev_err(dev, "cannot assert resets\n");
reset_control_assert(res->por_reset); return ret;
reset_control_assert(res->ext_reset); }
reset_control_assert(res->phy_reset);
ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies); ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
if (ret < 0) { if (ret < 0) {
...@@ -383,58 +366,14 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) ...@@ -383,58 +366,14 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
return ret; return ret;
} }
ret = reset_control_deassert(res->ahb_reset); ret = reset_control_bulk_deassert(res->num_resets, res->resets);
if (ret) { if (ret < 0) {
dev_err(dev, "cannot deassert ahb reset\n"); dev_err(dev, "cannot deassert resets\n");
goto err_deassert_ahb; regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
} return ret;
ret = reset_control_deassert(res->ext_reset);
if (ret) {
dev_err(dev, "cannot deassert ext reset\n");
goto err_deassert_ext;
}
ret = reset_control_deassert(res->phy_reset);
if (ret) {
dev_err(dev, "cannot deassert phy reset\n");
goto err_deassert_phy;
}
ret = reset_control_deassert(res->pci_reset);
if (ret) {
dev_err(dev, "cannot deassert pci reset\n");
goto err_deassert_pci;
}
ret = reset_control_deassert(res->por_reset);
if (ret) {
dev_err(dev, "cannot deassert por reset\n");
goto err_deassert_por;
}
ret = reset_control_deassert(res->axi_reset);
if (ret) {
dev_err(dev, "cannot deassert axi reset\n");
goto err_deassert_axi;
} }
return 0; 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) static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
......
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