[PATCH 4/5] soc: imx: imx8m-blk-ctrl: support i.MX8MP media blk ctrl noc settings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Peng Fan <peng.fan@xxxxxxx>

The out of reset value of NoC is not a valid value, we need
set it to a correct value. We only need to set it after power on.

Signed-off-by: Peng Fan <peng.fan@xxxxxxx>
---
 drivers/soc/imx/imx8m-blk-ctrl.c | 109 +++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c
index 3a6abd70520c..5b382b4e6a64 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx8m-blk-ctrl.c
@@ -12,6 +12,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/clk.h>
+#include <linux/mfd/syscon.h>
 
 #include <dt-bindings/power/imx8mm-power.h>
 #include <dt-bindings/power/imx8mn-power.h>
@@ -29,10 +30,19 @@ struct imx8m_blk_ctrl {
 	struct notifier_block power_nb;
 	struct device *bus_power_dev;
 	struct regmap *regmap;
+	struct regmap *noc_regmap;
 	struct imx8m_blk_ctrl_domain *domains;
 	struct genpd_onecell_data onecell_data;
 };
 
+struct imx8m_blk_ctrl_noc_data {
+	u32 off;
+	u32 priority;
+	u32 mode;
+	u32 extctrl;
+};
+
+#define DOMAIN_MAX_NOC	4
 struct imx8m_blk_ctrl_domain_data {
 	const char *name;
 	const char * const *clk_names;
@@ -49,6 +59,7 @@ struct imx8m_blk_ctrl_domain_data {
 	 * register.
 	 */
 	u32 mipi_phy_rst_mask;
+	const struct imx8m_blk_ctrl_noc_data *noc_data[DOMAIN_MAX_NOC];
 };
 
 #define DOMAIN_MAX_CLKS 3
@@ -66,6 +77,7 @@ struct imx8m_blk_ctrl_data {
 	notifier_fn_t power_notifier_fn;
 	const struct imx8m_blk_ctrl_domain_data *domains;
 	int num_domains;
+	bool has_noc;
 };
 
 static inline struct imx8m_blk_ctrl_domain *
@@ -74,6 +86,27 @@ to_imx8m_blk_ctrl_domain(struct generic_pm_domain *genpd)
 	return container_of(genpd, struct imx8m_blk_ctrl_domain, genpd);
 }
 
+static int imx8m_blk_ctrl_noc_set(struct imx8m_blk_ctrl_domain *domain)
+{
+	const struct imx8m_blk_ctrl_domain_data *data = domain->data;
+	struct imx8m_blk_ctrl *bc = domain->bc;
+	struct regmap *regmap = bc->noc_regmap;
+	int i;
+
+	if (!data || !regmap)
+		return 0;
+
+	for (i = 0; i < DOMAIN_MAX_NOC; i++) {
+		if (!data->noc_data[i])
+			continue;
+		regmap_write(regmap, data->noc_data[i]->off + 0x8, data->noc_data[i]->priority);
+		regmap_write(regmap, data->noc_data[i]->off + 0xc, data->noc_data[i]->mode);
+		regmap_write(regmap, data->noc_data[i]->off + 0x18, data->noc_data[i]->extctrl);
+	}
+
+	return 0;
+}
+
 static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 {
 	struct imx8m_blk_ctrl_domain *domain = to_imx8m_blk_ctrl_domain(genpd);
@@ -117,6 +150,8 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 	if (data->mipi_phy_rst_mask)
 		regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
 
+	imx8m_blk_ctrl_noc_set(domain);
+
 	/* disable upstream clocks */
 	clk_bulk_disable_unprepare(data->num_clks, domain->clks);
 
@@ -172,6 +207,7 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 	const struct imx8m_blk_ctrl_data *bc_data;
 	struct device *dev = &pdev->dev;
 	struct imx8m_blk_ctrl *bc;
+	struct regmap *regmap;
 	void __iomem *base;
 	int i, ret;
 
@@ -218,6 +254,10 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev),
 				     "failed to attach power domain\n");
 
+	regmap = syscon_regmap_lookup_by_compatible("fsl,imx8m-noc");
+	if (!IS_ERR(regmap))
+		bc->noc_regmap = regmap;
+
 	for (i = 0; i < bc_data->num_domains; i++) {
 		const struct imx8m_blk_ctrl_domain_data *data = &bc_data->domains[i];
 		struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
@@ -677,6 +717,55 @@ static int imx8mp_media_power_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
+#define IMX8MP_MEDIABLK_LCDIF_RD	0
+#define IMX8MP_MEDIABLK_LCDIF_WR	1
+#define IMX8MP_MEDIABLK_ISI0		2
+#define IMX8MP_MEDIABLK_ISI1		3
+#define IMX8MP_MEDIABLK_ISI2		4
+#define IMX8MP_MEDIABLK_ISP0		5
+#define IMX8MP_MEDIABLK_ISP1		6
+#define IMX8MP_MEDIABLK_DWE		7
+
+static const struct imx8m_blk_ctrl_noc_data imx8mp_media_noc_data[] = {
+	[IMX8MP_MEDIABLK_LCDIF_RD] = {
+		.off = 0x980,
+		.priority = 0x80000202,
+		.extctrl = 1,
+	},
+	[IMX8MP_MEDIABLK_LCDIF_WR] = {
+		.off = 0xa00,
+		.priority = 0x80000202,
+		.extctrl = 1,
+	},
+	[IMX8MP_MEDIABLK_ISI0] = {
+		.off = 0xa80,
+		.priority = 0x80000202,
+		.extctrl = 1,
+	},
+	[IMX8MP_MEDIABLK_ISI1] = {
+		.off = 0xb00,
+		.priority = 0x80000202,
+		.extctrl = 1,
+	},
+	[IMX8MP_MEDIABLK_ISI2] = {
+		.off = 0xb80,
+		.priority = 0x80000202,
+		.extctrl = 1,
+	},
+	[IMX8MP_MEDIABLK_ISP0] = {
+		.off = 0xc00,
+		.priority = 0x80000707,
+	},
+	[IMX8MP_MEDIABLK_ISP1] = {
+		.off = 0xc80,
+		.priority = 0x80000707,
+	},
+	[IMX8MP_MEDIABLK_DWE] = {
+		.off = 0xd00,
+		.priority = 0x80000707,
+	},
+};
+
 /*
  * From i.MX 8M Plus Applications Processor Reference Manual, Rev. 1,
  * section 13.2.2, 13.2.3
@@ -708,6 +797,10 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
 		.gpc_name = "lcdif1",
 		.rst_mask = BIT(4) | BIT(5) | BIT(23),
 		.clk_mask = BIT(4) | BIT(5) | BIT(23),
+		.noc_data = {
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_LCDIF_RD],
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_LCDIF_WR],
+		},
 	},
 	[IMX8MP_MEDIABLK_PD_ISI] = {
 		.name = "mediablk-isi",
@@ -716,6 +809,11 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
 		.gpc_name = "isi",
 		.rst_mask = BIT(6) | BIT(7),
 		.clk_mask = BIT(6) | BIT(7),
+		.noc_data = {
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_ISI0],
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_ISI1],
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_ISI2],
+		},
 	},
 	[IMX8MP_MEDIABLK_PD_MIPI_CSI2_2] = {
 		.name = "mediablk-mipi-csi2-2",
@@ -733,6 +831,10 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
 		.gpc_name = "lcdif2",
 		.rst_mask = BIT(11) | BIT(12) | BIT(24),
 		.clk_mask = BIT(11) | BIT(12) | BIT(24),
+		.noc_data = {
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_LCDIF_RD],
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_LCDIF_WR],
+		},
 	},
 	[IMX8MP_MEDIABLK_PD_ISP2] = {
 		.name = "mediablk-isp2",
@@ -749,6 +851,10 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
 		.gpc_name = "isp1",
 		.rst_mask = BIT(16) | BIT(17) | BIT(18),
 		.clk_mask = BIT(16) | BIT(17) | BIT(18),
+		.noc_data = {
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_ISP0],
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_ISP1],
+		},
 	},
 	[IMX8MP_MEDIABLK_PD_DWE] = {
 		.name = "mediablk-dwe",
@@ -757,6 +863,9 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
 		.gpc_name = "dwe",
 		.rst_mask = BIT(19) | BIT(20) | BIT(21),
 		.clk_mask = BIT(19) | BIT(20) | BIT(21),
+		.noc_data = {
+			&imx8mp_media_noc_data[IMX8MP_MEDIABLK_DWE],
+		},
 	},
 	[IMX8MP_MEDIABLK_PD_MIPI_DSI_2] = {
 		.name = "mediablk-mipi-dsi-2",
-- 
2.25.1




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux