@@ -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",