mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
pmdomain: Merge branch fixes into next
Merge the pmdomain fixes for v7.2-rc[n] into the next branch, to allow them to get tested together with the pmdomain changes that are targeted for the next release. Signed-off-by: Ulf Hansson <ulfh@kernel.org>
This commit is contained in:
@@ -54,6 +54,15 @@ struct imx8m_blk_ctrl_domain_data {
|
||||
* register.
|
||||
*/
|
||||
u32 mipi_phy_rst_mask;
|
||||
|
||||
/*
|
||||
* VC8000E reset de-assertion edge and AXI clock may have a timing issue.
|
||||
* Workaround: Set bit2 (vc8000e_clk_en) of BLK_CLK_EN_CSR to 0 to gate off
|
||||
* both AXI clock and VC8000E clock sent to VC8000E and AXI clock sent to
|
||||
* VPU_NOC m_v_2 interface during VC8000E power up(VC8000E reset is
|
||||
* de-asserted by HW)
|
||||
*/
|
||||
bool is_errata_err050531;
|
||||
};
|
||||
|
||||
#define DOMAIN_MAX_CLKS 4
|
||||
@@ -108,7 +117,11 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
|
||||
dev_err(bc->dev, "failed to enable clocks\n");
|
||||
goto bus_put;
|
||||
}
|
||||
regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask);
|
||||
|
||||
if (data->is_errata_err050531)
|
||||
regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask);
|
||||
else
|
||||
regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask);
|
||||
|
||||
/* power up upstream GPC domain */
|
||||
ret = pm_runtime_get_sync(domain->power_dev);
|
||||
@@ -117,6 +130,9 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
|
||||
goto clk_disable;
|
||||
}
|
||||
|
||||
if (data->is_errata_err050531)
|
||||
regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask);
|
||||
|
||||
/* wait for reset to propagate */
|
||||
udelay(5);
|
||||
|
||||
@@ -511,12 +527,38 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_vpu_blk_ctl_domain_data[]
|
||||
.clk_mask = BIT(2),
|
||||
.path_names = (const char *[]){"vc8000e"},
|
||||
.num_paths = 1,
|
||||
.is_errata_err050531 = true,
|
||||
},
|
||||
};
|
||||
|
||||
static int imx8mp_vpu_power_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
|
||||
power_nb);
|
||||
|
||||
if (action == GENPD_NOTIFY_ON) {
|
||||
/*
|
||||
* On power up we have no software backchannel to the GPC to
|
||||
* wait for the ADB handshake to happen, so we just delay for a
|
||||
* bit. On power down the GPC driver waits for the handshake.
|
||||
*/
|
||||
|
||||
udelay(5);
|
||||
|
||||
/* set "fuse" bits to enable the VPUs */
|
||||
regmap_set_bits(bc->regmap, 0x8, 0xffffffff);
|
||||
regmap_set_bits(bc->regmap, 0xc, 0xffffffff);
|
||||
regmap_set_bits(bc->regmap, 0x10, 0xffffffff);
|
||||
regmap_set_bits(bc->regmap, 0x14, 0xffffffff);
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static const struct imx8m_blk_ctrl_data imx8mp_vpu_blk_ctl_dev_data = {
|
||||
.max_reg = 0x18,
|
||||
.power_notifier_fn = imx8mm_vpu_power_notifier,
|
||||
.power_notifier_fn = imx8mp_vpu_power_notifier,
|
||||
.domains = imx8mp_vpu_blk_ctl_domain_data,
|
||||
.num_domains = ARRAY_SIZE(imx8mp_vpu_blk_ctl_domain_data),
|
||||
};
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
|
||||
#define PRIO(X) (X)
|
||||
|
||||
#define BLK_CTRL_NO_PARENT UINT_MAX
|
||||
|
||||
struct imx93_blk_ctrl_domain;
|
||||
|
||||
struct imx93_blk_ctrl {
|
||||
@@ -68,12 +70,18 @@ struct imx93_blk_ctrl_qos {
|
||||
u32 cfg_prio;
|
||||
};
|
||||
|
||||
struct imx93_blk_ctrl_subdomain_link {
|
||||
struct generic_pm_domain *parent;
|
||||
struct generic_pm_domain *subdomain;
|
||||
};
|
||||
|
||||
struct imx93_blk_ctrl_domain_data {
|
||||
const char *name;
|
||||
const char * const *clk_names;
|
||||
int num_clks;
|
||||
u32 rst_mask;
|
||||
u32 clk_mask;
|
||||
u32 parent;
|
||||
int num_qos;
|
||||
struct imx93_blk_ctrl_qos qos[DOMAIN_MAX_QOS];
|
||||
};
|
||||
@@ -203,6 +211,13 @@ static void imx93_release_pm_genpd(void *data)
|
||||
pm_genpd_remove(genpd);
|
||||
}
|
||||
|
||||
static void imx93_release_subdomain(void *data)
|
||||
{
|
||||
struct imx93_blk_ctrl_subdomain_link *link = data;
|
||||
|
||||
pm_genpd_remove_subdomain(link->parent, link->subdomain);
|
||||
}
|
||||
|
||||
static struct lock_class_key blk_ctrl_genpd_lock_class;
|
||||
|
||||
static int imx93_blk_ctrl_probe(struct platform_device *pdev)
|
||||
@@ -302,6 +317,34 @@ static int imx93_blk_ctrl_probe(struct platform_device *pdev)
|
||||
bc->onecell_data.domains[i] = &domain->genpd;
|
||||
}
|
||||
|
||||
for (i = 0; i < bc_data->num_domains; i++) {
|
||||
struct imx93_blk_ctrl_domain *domain = &bc->domains[i];
|
||||
const struct imx93_blk_ctrl_domain_data *data = domain->data;
|
||||
struct imx93_blk_ctrl_subdomain_link *link;
|
||||
|
||||
if (bc_data->skip_mask & BIT(i) ||
|
||||
data->parent == BLK_CTRL_NO_PARENT)
|
||||
continue;
|
||||
|
||||
link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
link->parent = &bc->domains[data->parent].genpd;
|
||||
link->subdomain = &domain->genpd;
|
||||
|
||||
ret = pm_genpd_add_subdomain(&bc->domains[data->parent].genpd,
|
||||
&domain->genpd);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to add subdomain %s\n",
|
||||
domain->genpd.name);
|
||||
|
||||
ret = devm_add_action_or_reset(dev, imx93_release_subdomain, link);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to add subdomain release callback\n");
|
||||
}
|
||||
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to enable pm-runtime\n");
|
||||
@@ -326,8 +369,9 @@ static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[]
|
||||
.name = "mediablk-mipi-dsi",
|
||||
.clk_names = (const char *[]){ "dsi" },
|
||||
.num_clks = 1,
|
||||
.rst_mask = BIT(11) | BIT(12),
|
||||
.clk_mask = BIT(11) | BIT(12),
|
||||
.rst_mask = BIT(11),
|
||||
.clk_mask = BIT(11),
|
||||
.parent = IMX93_MEDIABLK_PD_MIPI_PHY,
|
||||
},
|
||||
[IMX93_MEDIABLK_PD_MIPI_CSI] = {
|
||||
.name = "mediablk-mipi-csi",
|
||||
@@ -335,6 +379,7 @@ static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[]
|
||||
.num_clks = 2,
|
||||
.rst_mask = BIT(9) | BIT(10),
|
||||
.clk_mask = BIT(9) | BIT(10),
|
||||
.parent = IMX93_MEDIABLK_PD_MIPI_PHY,
|
||||
},
|
||||
[IMX93_MEDIABLK_PD_PXP] = {
|
||||
.name = "mediablk-pxp",
|
||||
@@ -342,6 +387,7 @@ static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[]
|
||||
.num_clks = 1,
|
||||
.rst_mask = BIT(7) | BIT(8),
|
||||
.clk_mask = BIT(7) | BIT(8),
|
||||
.parent = BLK_CTRL_NO_PARENT,
|
||||
.num_qos = 2,
|
||||
.qos = {
|
||||
{
|
||||
@@ -363,6 +409,7 @@ static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[]
|
||||
.num_clks = 2,
|
||||
.rst_mask = BIT(4) | BIT(5) | BIT(6),
|
||||
.clk_mask = BIT(4) | BIT(5) | BIT(6),
|
||||
.parent = BLK_CTRL_NO_PARENT,
|
||||
.num_qos = 1,
|
||||
.qos = {
|
||||
{
|
||||
@@ -379,6 +426,7 @@ static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[]
|
||||
.num_clks = 1,
|
||||
.rst_mask = BIT(2) | BIT(3),
|
||||
.clk_mask = BIT(2) | BIT(3),
|
||||
.parent = BLK_CTRL_NO_PARENT,
|
||||
.num_qos = 4,
|
||||
.qos = {
|
||||
{
|
||||
@@ -404,6 +452,14 @@ static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[]
|
||||
}
|
||||
}
|
||||
},
|
||||
[IMX93_MEDIABLK_PD_MIPI_PHY] = {
|
||||
.name = "mediablk-mipi-phy",
|
||||
.clk_names = NULL,
|
||||
.num_clks = 0,
|
||||
.rst_mask = BIT(12),
|
||||
.clk_mask = BIT(12),
|
||||
.parent = BLK_CTRL_NO_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_range imx93_media_blk_ctl_yes_ranges[] = {
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
#define IMX93_MEDIABLK_PD_PXP 2
|
||||
#define IMX93_MEDIABLK_PD_LCDIF 3
|
||||
#define IMX93_MEDIABLK_PD_ISI 4
|
||||
#define IMX93_MEDIABLK_PD_MIPI_PHY 5
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user