Commit 0c634fcb authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

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
parents 9b2c25fa 1c5aa037
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -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
+62 −31
Original line number Diff line number Diff line
@@ -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 },
	{ }
};