Commit 530ba412 authored by Richard Zhu's avatar Richard Zhu Committed by Lorenzo Pieralisi
Browse files

PCI: imx6: Add i.MX8MQ PCIe EP support

parent 75c2f26d
Loading
Loading
Loading
Loading
+33 −5
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ enum imx6_pcie_variants {
	IMX8MQ,
	IMX8MM,
	IMX8MP,
	IMX8MQ_EP,
};

#define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
@@ -153,6 +154,7 @@ struct imx6_pcie {
static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
{
	WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ &&
		imx6_pcie->drvdata->variant != IMX8MQ_EP &&
		imx6_pcie->drvdata->variant != IMX8MM &&
		imx6_pcie->drvdata->variant != IMX8MP);
	return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
@@ -167,14 +169,23 @@ static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
	else
		mode = PCI_EXP_TYPE_ROOT_PORT;

	if (imx6_pcie->drvdata->variant == IMX8MQ &&
	    imx6_pcie->controller_id == 1) {
	switch (imx6_pcie->drvdata->variant) {
	case IMX8MQ:
	case IMX8MQ_EP:
		if (imx6_pcie->controller_id == 1) {
			mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE;
		val  = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, mode);
			val  = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
					  mode);
		} else {
			mask = IMX6Q_GPR12_DEVICE_TYPE;
			val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
		}
		break;
	default:
		mask = IMX6Q_GPR12_DEVICE_TYPE;
		val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
		break;
	}

	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val);
}
@@ -315,6 +326,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
		 */
		break;
	case IMX8MQ:
	case IMX8MQ_EP:
		/*
		 * TODO: Currently this code assumes external
		 * oscillator is being used
@@ -566,6 +578,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
		break;
	case IMX8MM:
	case IMX8MQ:
	case IMX8MQ_EP:
	case IMX8MP:
		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
		if (ret) {
@@ -611,6 +624,7 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
		break;
	case IMX8MM:
	case IMX8MQ:
	case IMX8MQ_EP:
	case IMX8MP:
		clk_disable_unprepare(imx6_pcie->pcie_aux);
		break;
@@ -676,6 +690,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
	switch (imx6_pcie->drvdata->variant) {
	case IMX7D:
	case IMX8MQ:
	case IMX8MQ_EP:
		reset_control_assert(imx6_pcie->pciephy_reset);
		fallthrough;
	case IMX8MM:
@@ -717,6 +732,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)

	switch (imx6_pcie->drvdata->variant) {
	case IMX8MQ:
	case IMX8MQ_EP:
		reset_control_deassert(imx6_pcie->pciephy_reset);
		break;
	case IMX7D:
@@ -804,6 +820,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
		break;
	case IMX7D:
	case IMX8MQ:
	case IMX8MQ_EP:
	case IMX8MM:
	case IMX8MP:
		reset_control_deassert(imx6_pcie->apps_reset);
@@ -824,6 +841,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
		break;
	case IMX7D:
	case IMX8MQ:
	case IMX8MQ_EP:
	case IMX8MM:
	case IMX8MP:
		reset_control_assert(imx6_pcie->apps_reset);
@@ -1076,6 +1094,9 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
	ep->ops = &pcie_ep_ops;

	switch (imx6_pcie->drvdata->variant) {
	case IMX8MQ_EP:
		pcie_dbi2_offset = SZ_1M;
		break;
	default:
		pcie_dbi2_offset = SZ_4K;
		break;
@@ -1261,6 +1282,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
					     "pcie_inbound_axi clock missing or invalid\n");
		break;
	case IMX8MQ:
	case IMX8MQ_EP:
		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
		if (IS_ERR(imx6_pcie->pcie_aux))
			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
@@ -1445,6 +1467,11 @@ static const struct imx6_pcie_drvdata drvdata[] = {
		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
		.gpr = "fsl,imx8mp-iomuxc-gpr",
	},
	[IMX8MQ_EP] = {
		.variant = IMX8MQ_EP,
		.mode = DW_PCIE_EP_TYPE,
		.gpr = "fsl,imx8mq-iomuxc-gpr",
	},
};

static const struct of_device_id imx6_pcie_of_match[] = {
@@ -1455,6 +1482,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
	{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
	{},
};