mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
pmdomain providers:
- imx: Assign child domains for imx93 to prevent power off when in use - imx: Fix i.MX8MP power up sequences - mediatek: Fix possible nullptr in HWV cleanup/on-check -----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmpY0fEQHHVsZmhAa2Vy bmVsLm9yZwAKCRD+JoQlc1iMKZtVD/9E1rSTcAK/tHKIt2Ng8hLPZgWib8z8JjDj OU8i5kmMJHnymEcnWYllMFkAjJicVauo3kbNyMZqtU+TxDTqrZgUjWzO9Pu7OGMy ZA4YBBGnDQP7faRrfTDB31EVuwxziTq9kcctpqkYEiSWnN1+ZOpAF2vqfHvOEek0 v82Wu6fSorZXeXYjH49sEEAW8qiel8u3gA6ctHv2MFXD7fqK6POTTWpHdvnBI0rp CRP4imWH6tTKC2FVMw5rLel+JzHU6y658Qg/gd2AVtG+8nQH/LX7gu0M2tg0E/Sq TTMbRSnS93+rlTyWSkJgIyQnlSGkYddHJEGDFxaUxfln2LiLCNeXgbPcJvAQIEji GH5AeJEoz6XtkVBsv4Aga+EG1O154YKQ8/jnGGM2q+cFrBItfeiNcSwhexHoNMnw hIcKW7lvmEUM/N/GS3wsBBJBftAz8bmeSITEqrVzscIZRVjWlElYrtAuG+cmKagc jamfwQDJ2WfzJz9lolSMbKobo6bJEzmxqvP6cN1iVgHkdm22BxE29q2/XACilzH4 ASMHbkxd3gAR2P4HrzhxX6jn0SI7YxJCfrI1aYD6yKKp7MA2sdWBm3IVTREHZhP2 5FiArPQced3tjdtlDfbXLan1AmEiZ49o31fEUssylA4D7Z1G8qKB7RXXphDayRM/ ATNSav1EzQ== =tWH8 -----END PGP SIGNATURE----- Merge tag 'pmdomain-v7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm Pull pmdomain fixes from Ulf Hansson: "imx: - Assign child domains for imx93 to prevent power off when in use - Fix i.MX8MP power up sequences mediatek: - Fix possible nullptr in HWV cleanup/on-check" * tag 'pmdomain-v7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: pmdomain: mediatek: Fix possible nullptr KP in HWV cleanup/on-check pmdomain: imx: Fix i.MX8MP VC8000E power up sequence pmdomain: imx: Fix i.MX8MP power notifier pmdomain: imx93-blk-ctrl: Extract PHY as shared domain for DSI/CSI dt-bindings: power: imx93: Add MIPI PHY power domain
This commit is contained in:
commit
4302c3503c
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -393,9 +393,8 @@ static int scpsys_hwv_power_on(struct generic_pm_domain *genpd)
|
|||
return ret;
|
||||
};
|
||||
|
||||
static int scpsys_hwv_power_off(struct generic_pm_domain *genpd)
|
||||
static int scpsys_hwv_power_off_internal(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
const struct scpsys_hwv_domain_data *hwv = pd->hwv_data;
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
u32 val;
|
||||
|
|
@ -464,6 +463,13 @@ static int scpsys_hwv_power_off(struct generic_pm_domain *genpd)
|
|||
return ret;
|
||||
};
|
||||
|
||||
static int scpsys_hwv_power_off(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
|
||||
return scpsys_hwv_power_off_internal(pd);
|
||||
}
|
||||
|
||||
static int scpsys_ctl_pwrseq_on(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
|
|
@ -694,9 +700,8 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int scpsys_power_off(struct generic_pm_domain *genpd)
|
||||
static int scpsys_power_off_internal(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
bool tmp;
|
||||
int ret;
|
||||
|
|
@ -737,6 +742,13 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_power_off(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
|
||||
return scpsys_power_off_internal(pd);
|
||||
}
|
||||
|
||||
static struct
|
||||
generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node)
|
||||
{
|
||||
|
|
@ -884,7 +896,14 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
* late_init time.
|
||||
*/
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF)) {
|
||||
if (scpsys_domain_is_on(pd))
|
||||
bool domain_is_on;
|
||||
|
||||
if (scpsys->soc_data->type == SCPSYS_MTCMOS_TYPE_HW_VOTER)
|
||||
domain_is_on = scpsys_hwv_domain_is_enable_done(pd);
|
||||
else
|
||||
domain_is_on = scpsys_domain_is_on(pd);
|
||||
|
||||
if (domain_is_on)
|
||||
dev_warn(scpsys->dev,
|
||||
"%pOF: A default off power domain has been ON\n", node);
|
||||
} else {
|
||||
|
|
@ -973,6 +992,7 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren
|
|||
|
||||
static void scpsys_remove_one_domain(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
|
@ -984,8 +1004,14 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd)
|
|||
dev_err(pd->scpsys->dev,
|
||||
"failed to remove domain '%s' : %d - state may be inconsistent\n",
|
||||
pd->genpd.name, ret);
|
||||
if (scpsys_domain_is_on(pd))
|
||||
scpsys_power_off(&pd->genpd);
|
||||
|
||||
if (scpsys->soc_data->type == SCPSYS_MTCMOS_TYPE_HW_VOTER) {
|
||||
if (scpsys_hwv_domain_is_enable_done(pd))
|
||||
scpsys_hwv_power_off_internal(pd);
|
||||
} else {
|
||||
if (scpsys_domain_is_on(pd))
|
||||
scpsys_power_off_internal(pd);
|
||||
}
|
||||
|
||||
clk_bulk_put(pd->num_clks, pd->clks);
|
||||
clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user