提交 1c5aa037 编写于 作者: D Dmitry Baryshkov 提交者: Lorenzo Pieralisi

PCI: qcom: Add SM8450 PCIe support

On SM8450 platform PCIe hosts do not use all the clocks (and add several
additional clocks), so expand the driver to handle these requirements.

PCIe0 and PCIe1 hosts use different sets of clocks, so separate entries
are required.

Link: https://lore.kernel.org/r/20220223101435.447839-5-dmitry.baryshkov@linaro.orgSigned-off-by: NDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: NBjorn Andersson <bjorn.andersson@linaro.org>
Acked-by: NStanimir Varbanov <svarbanov@mm-sol.com>
上级 0614f98b
...@@ -161,7 +161,7 @@ struct qcom_pcie_resources_2_3_3 { ...@@ -161,7 +161,7 @@ struct qcom_pcie_resources_2_3_3 {
/* 6 clocks typically, 7 for sm8250 */ /* 6 clocks typically, 7 for sm8250 */
struct qcom_pcie_resources_2_7_0 { struct qcom_pcie_resources_2_7_0 {
struct clk_bulk_data clks[7]; struct clk_bulk_data clks[9];
int num_clks; int num_clks;
struct regulator_bulk_data supplies[2]; struct regulator_bulk_data supplies[2];
struct reset_control *pci_reset; struct reset_control *pci_reset;
...@@ -195,7 +195,10 @@ struct qcom_pcie_ops { ...@@ -195,7 +195,10 @@ struct qcom_pcie_ops {
struct qcom_pcie_cfg { struct qcom_pcie_cfg {
const struct qcom_pcie_ops *ops; const struct qcom_pcie_ops *ops;
unsigned int pipe_clk_need_muxing:1; unsigned int pipe_clk_need_muxing:1;
unsigned int has_tbu_clk:1;
unsigned int has_ddrss_sf_tbu_clk:1; unsigned int has_ddrss_sf_tbu_clk:1;
unsigned int has_aggre0_clk:1;
unsigned int has_aggre1_clk:1;
}; };
struct qcom_pcie { struct qcom_pcie {
...@@ -1146,6 +1149,7 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) ...@@ -1146,6 +1149,7 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0; struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
struct dw_pcie *pci = pcie->pci; struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev; struct device *dev = pci->dev;
unsigned int idx;
int ret; int ret;
res->pci_reset = devm_reset_control_get_exclusive(dev, "pci"); res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
...@@ -1159,18 +1163,22 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) ...@@ -1159,18 +1163,22 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
if (ret) if (ret)
return ret; return ret;
res->clks[0].id = "aux"; idx = 0;
res->clks[1].id = "cfg"; res->clks[idx++].id = "aux";
res->clks[2].id = "bus_master"; res->clks[idx++].id = "cfg";
res->clks[3].id = "bus_slave"; res->clks[idx++].id = "bus_master";
res->clks[4].id = "slave_q2a"; res->clks[idx++].id = "bus_slave";
res->clks[5].id = "tbu"; res->clks[idx++].id = "slave_q2a";
if (pcie->cfg->has_ddrss_sf_tbu_clk) { if (pcie->cfg->has_tbu_clk)
res->clks[6].id = "ddrss_sf_tbu"; res->clks[idx++].id = "tbu";
res->num_clks = 7; if (pcie->cfg->has_ddrss_sf_tbu_clk)
} else { res->clks[idx++].id = "ddrss_sf_tbu";
res->num_clks = 6; if (pcie->cfg->has_aggre0_clk)
} res->clks[idx++].id = "aggre0";
if (pcie->cfg->has_aggre1_clk)
res->clks[idx++].id = "aggre1";
res->num_clks = idx;
ret = devm_clk_bulk_get(dev, res->num_clks, res->clks); ret = devm_clk_bulk_get(dev, res->num_clks, res->clks);
if (ret < 0) if (ret < 0)
...@@ -1236,6 +1244,9 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie) ...@@ -1236,6 +1244,9 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
goto err_disable_clocks; goto err_disable_clocks;
} }
/* Wait for reset to complete, required on SM8450 */
usleep_range(1000, 1500);
/* configure PCIe to RC mode */ /* configure PCIe to RC mode */
writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE); writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
...@@ -1509,15 +1520,33 @@ static const struct qcom_pcie_cfg ipq4019_cfg = { ...@@ -1509,15 +1520,33 @@ static const struct qcom_pcie_cfg ipq4019_cfg = {
static const struct qcom_pcie_cfg sdm845_cfg = { static const struct qcom_pcie_cfg sdm845_cfg = {
.ops = &ops_2_7_0, .ops = &ops_2_7_0,
.has_tbu_clk = true,
}; };
static const struct qcom_pcie_cfg sm8250_cfg = { static const struct qcom_pcie_cfg sm8250_cfg = {
.ops = &ops_1_9_0,
.has_tbu_clk = true,
.has_ddrss_sf_tbu_clk = true,
};
static const struct qcom_pcie_cfg sm8450_pcie0_cfg = {
.ops = &ops_1_9_0, .ops = &ops_1_9_0,
.has_ddrss_sf_tbu_clk = true, .has_ddrss_sf_tbu_clk = true,
.pipe_clk_need_muxing = true,
.has_aggre0_clk = true,
.has_aggre1_clk = true,
};
static const struct qcom_pcie_cfg sm8450_pcie1_cfg = {
.ops = &ops_1_9_0,
.has_ddrss_sf_tbu_clk = true,
.pipe_clk_need_muxing = true,
.has_aggre1_clk = true,
}; };
static const struct qcom_pcie_cfg sc7280_cfg = { static const struct qcom_pcie_cfg sc7280_cfg = {
.ops = &ops_1_9_0, .ops = &ops_1_9_0,
.has_tbu_clk = true,
.pipe_clk_need_muxing = true, .pipe_clk_need_muxing = true,
}; };
...@@ -1628,6 +1657,8 @@ static const struct of_device_id qcom_pcie_match[] = { ...@@ -1628,6 +1657,8 @@ static const struct of_device_id qcom_pcie_match[] = {
{ .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg }, { .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg },
{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg }, { .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg }, { .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &sm8450_pcie0_cfg },
{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &sm8450_pcie1_cfg },
{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg }, { .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
{ } { }
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册