Hi Peng, Thank you for the patch. On Wed, Apr 06, 2022 at 04:23:29PM +0800, Peng Fan (OSS) wrote: > 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; Maybe "offset" ? > + u32 priority; > + u32 mode; > + u32 extctrl; > +}; > + > +#define DOMAIN_MAX_NOC 4 And a blank line here. We have 3 NoC entries at most below, so this could be lowered, but I wonder if it wouldn't be nicer to actually drop the macro (see below). > 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]; This would become just const struct imx8m_blk_ctrl_noc_data **noc_data; > }; > > #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; As it can never be negative, you can make i an unsigned int. > + > + if (!data || !regmap) > + return 0; > + > + for (i = 0; i < DOMAIN_MAX_NOC; i++) { > + if (!data->noc_data[i]) > + continue; With const struct imx8m_blk_ctrl_noc_data *noc_data = &data->noc_data[i]; if (!noc_data) continue; you could then write regmap_write(regmap, noc_data->off + 0x8, noc_data->priority); regmap_write(regmap, noc_data->off + 0xc, noc_data->mode); regmap_write(regmap, noc_data->off + 0x18, noc_data->extctrl); which is a bit nicer. If we drop the harcoded number of NoC entries, the loop could become const struct imx8m_blk_ctrl_noc_data *noc_data; for (i = 0; data->noc_data[i]; i++) { const struct imx8m_blk_ctrl_noc_data *noc_data = data->noc_data[i]; regmap_write(regmap, noc_data->off + 0x8, noc_data->priority); regmap_write(regmap, noc_data->off + 0xc, noc_data->mode); regmap_write(regmap, noc_data->off + 0x18, noc_data->extctrl); } You would then need a sentinel entry at the end of the noc_data array, initialized to NULL. > + 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 Would these be the two AXI write and the AXI read ports of the ISI ? Could they then be named accordingly (e.g. ISI_WR0, ISI_WR1, ISI_RD) ? I don't know which is which though. > +#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, > + }, This matches the TF-A implementation. With the above comments taken into account, Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> > +}; > + > /* > * 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", -- Regards, Laurent Pinchart