mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 17:01:14 +00:00
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:
commit
0c634fcb98
2 changed files with 83 additions and 32 deletions
|
@ -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
|
||||
|
|
|
@ -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 },
|
||||
{ }
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue