Merge branch 'remotes/lorenzo/pci/qcom'

- Save pointer to device match data instead of copying it (Dmitry
  Baryshkov)

- Add ddrss_sf_tbu flag to device match data instead of checking OF
  compatible string (Dmitry Baryshkov)

- Add SM8450 SoC PCIe DT bindings (Dmitry Baryshkov)

- Add SM8450 PCIe support (Dmitry Baryshkov)

* remotes/lorenzo/pci/qcom:
  PCI: qcom: Add SM8450 PCIe support
  PCI: qcom: Add ddrss_sf_tbu flag
  PCI: qcom: Remove redundancy between qcom_pcie and qcom_pcie_cfg
  dt-bindings: pci: qcom: Document PCIe bindings for SM8450
This commit is contained in:
Bjorn Helgaas 2022-03-22 17:16:26 -05:00
commit 0c634fcb98
2 changed files with 83 additions and 32 deletions

View File

@ -15,6 +15,8 @@
- "qcom,pcie-sc8180x" for sc8180x
- "qcom,pcie-sdm845" for sdm845
- "qcom,pcie-sm8250" for sm8250
- "qcom,pcie-sm8450-pcie0" for PCIe0 on sm8450
- "qcom,pcie-sm8450-pcie1" for PCIe1 on sm8450
- "qcom,pcie-ipq6018" for ipq6018
- reg:
@ -169,6 +171,24 @@
- "ddrss_sf_tbu" PCIe SF TBU clock
- "pipe" PIPE clock
- clock-names:
Usage: required for sm8450-pcie0 and sm8450-pcie1
Value type: <stringlist>
Definition: Should contain the following entries
- "aux" Auxiliary clock
- "cfg" Configuration clock
- "bus_master" Master AXI clock
- "bus_slave" Slave AXI clock
- "slave_q2a" Slave Q2A clock
- "tbu" PCIe TBU clock
- "ddrss_sf_tbu" PCIe SF TBU clock
- "pipe" PIPE clock
- "pipe_mux" PIPE MUX
- "phy_pipe" PIPE output clock
- "ref" REFERENCE clock
- "aggre0" Aggre NoC PCIe0 AXI clock, only for sm8450-pcie0
- "aggre1" Aggre NoC PCIe1 AXI clock
- resets:
Usage: required
Value type: <prop-encoded-array>
@ -246,7 +266,7 @@
- "ahb" AHB reset
- reset-names:
Usage: required for sc8180x, sdm845 and sm8250
Usage: required for sc8180x, sdm845, sm8250 and sm8450
Value type: <stringlist>
Definition: Should contain the following entries
- "pci" PCIe core reset

View File

@ -161,7 +161,7 @@ struct qcom_pcie_resources_2_3_3 {
/* 6 clocks typically, 7 for sm8250 */
struct qcom_pcie_resources_2_7_0 {
struct clk_bulk_data clks[7];
struct clk_bulk_data clks[9];
int num_clks;
struct regulator_bulk_data supplies[2];
struct reset_control *pci_reset;
@ -195,6 +195,10 @@ struct qcom_pcie_ops {
struct qcom_pcie_cfg {
const struct qcom_pcie_ops *ops;
unsigned int pipe_clk_need_muxing:1;
unsigned int has_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 {
@ -204,8 +208,7 @@ struct qcom_pcie {
union qcom_pcie_resources res;
struct phy *phy;
struct gpio_desc *reset;
const struct qcom_pcie_ops *ops;
unsigned int pipe_clk_need_muxing:1;
const struct qcom_pcie_cfg *cfg;
};
#define to_qcom_pcie(x) dev_get_drvdata((x)->dev)
@ -229,8 +232,8 @@ static int qcom_pcie_start_link(struct dw_pcie *pci)
struct qcom_pcie *pcie = to_qcom_pcie(pci);
/* Enable Link Training state machine */
if (pcie->ops->ltssm_enable)
pcie->ops->ltssm_enable(pcie);
if (pcie->cfg->ops->ltssm_enable)
pcie->cfg->ops->ltssm_enable(pcie);
return 0;
}
@ -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 dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
unsigned int idx;
int ret;
res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
@ -1159,24 +1163,28 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
if (ret)
return ret;
res->clks[0].id = "aux";
res->clks[1].id = "cfg";
res->clks[2].id = "bus_master";
res->clks[3].id = "bus_slave";
res->clks[4].id = "slave_q2a";
res->clks[5].id = "tbu";
if (of_device_is_compatible(dev->of_node, "qcom,pcie-sm8250")) {
res->clks[6].id = "ddrss_sf_tbu";
res->num_clks = 7;
} else {
res->num_clks = 6;
}
idx = 0;
res->clks[idx++].id = "aux";
res->clks[idx++].id = "cfg";
res->clks[idx++].id = "bus_master";
res->clks[idx++].id = "bus_slave";
res->clks[idx++].id = "slave_q2a";
if (pcie->cfg->has_tbu_clk)
res->clks[idx++].id = "tbu";
if (pcie->cfg->has_ddrss_sf_tbu_clk)
res->clks[idx++].id = "ddrss_sf_tbu";
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);
if (ret < 0)
return ret;
if (pcie->pipe_clk_need_muxing) {
if (pcie->cfg->pipe_clk_need_muxing) {
res->pipe_clk_src = devm_clk_get(dev, "pipe_mux");
if (IS_ERR(res->pipe_clk_src))
return PTR_ERR(res->pipe_clk_src);
@ -1209,7 +1217,7 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
}
/* Set TCXO as clock source for pcie_pipe_clk_src */
if (pcie->pipe_clk_need_muxing)
if (pcie->cfg->pipe_clk_need_muxing)
clk_set_parent(res->pipe_clk_src, res->ref_clk_src);
ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
@ -1236,6 +1244,9 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
goto err_disable_clocks;
}
/* Wait for reset to complete, required on SM8450 */
usleep_range(1000, 1500);
/* configure PCIe to RC mode */
writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
@ -1284,7 +1295,7 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
/* Set pipe clock as clock source for pcie_pipe_clk_src */
if (pcie->pipe_clk_need_muxing)
if (pcie->cfg->pipe_clk_need_muxing)
clk_set_parent(res->pipe_clk_src, res->phy_pipe_clk);
return clk_prepare_enable(res->pipe_clk);
@ -1384,7 +1395,7 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
qcom_ep_reset_assert(pcie);
ret = pcie->ops->init(pcie);
ret = pcie->cfg->ops->init(pcie);
if (ret)
return ret;
@ -1392,16 +1403,16 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
if (ret)
goto err_deinit;
if (pcie->ops->post_init) {
ret = pcie->ops->post_init(pcie);
if (pcie->cfg->ops->post_init) {
ret = pcie->cfg->ops->post_init(pcie);
if (ret)
goto err_disable_phy;
}
qcom_ep_reset_deassert(pcie);
if (pcie->ops->config_sid) {
ret = pcie->ops->config_sid(pcie);
if (pcie->cfg->ops->config_sid) {
ret = pcie->cfg->ops->config_sid(pcie);
if (ret)
goto err;
}
@ -1410,12 +1421,12 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
err:
qcom_ep_reset_assert(pcie);
if (pcie->ops->post_deinit)
pcie->ops->post_deinit(pcie);
if (pcie->cfg->ops->post_deinit)
pcie->cfg->ops->post_deinit(pcie);
err_disable_phy:
phy_power_off(pcie->phy);
err_deinit:
pcie->ops->deinit(pcie);
pcie->cfg->ops->deinit(pcie);
return ret;
}
@ -1509,14 +1520,33 @@ static const struct qcom_pcie_cfg ipq4019_cfg = {
static const struct qcom_pcie_cfg sdm845_cfg = {
.ops = &ops_2_7_0,
.has_tbu_clk = true,
};
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,
.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 = {
.ops = &ops_1_9_0,
.has_tbu_clk = true,
.pipe_clk_need_muxing = true,
};
@ -1559,8 +1589,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
pcie->pci = pci;
pcie->ops = pcie_cfg->ops;
pcie->pipe_clk_need_muxing = pcie_cfg->pipe_clk_need_muxing;
pcie->cfg = pcie_cfg;
pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH);
if (IS_ERR(pcie->reset)) {
@ -1586,7 +1615,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_pm_runtime_put;
}
ret = pcie->ops->get_resources(pcie);
ret = pcie->cfg->ops->get_resources(pcie);
if (ret)
goto err_pm_runtime_put;
@ -1628,6 +1657,8 @@ static const struct of_device_id qcom_pcie_match[] = {
{ .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg },
{ .compatible = "qcom,pcie-sm8250", .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 },
{ }
};