Skip to content

Commit 4f6c983

Browse files
MrVanstorulf
authored andcommitted
genpd: imx: scu-pd: initialize is_off according to HW state
The current code default set is_off to true except console resource, this implies bootloader should power off all the resources it uses. But this is not always true, let's check the HW state and set is_off. Signed-off-by: Peng Fan <peng.fan@nxp.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent ec8b561 commit 4f6c983

File tree

1 file changed

+55
-4
lines changed

1 file changed

+55
-4
lines changed

drivers/genpd/imx/scu-pd.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,22 @@ struct imx_sc_msg_req_set_resource_power_mode {
7272
u8 mode;
7373
} __packed __aligned(4);
7474

75+
struct req_get_resource_mode {
76+
u16 resource;
77+
};
78+
79+
struct resp_get_resource_mode {
80+
u8 mode;
81+
};
82+
83+
struct imx_sc_msg_req_get_resource_power_mode {
84+
struct imx_sc_rpc_msg hdr;
85+
union {
86+
struct req_get_resource_mode req;
87+
struct resp_get_resource_mode resp;
88+
} data;
89+
} __packed __aligned(4);
90+
7591
#define IMX_SCU_PD_NAME_SIZE 20
7692
struct imx_sc_pm_domain {
7793
struct generic_pm_domain pd;
@@ -96,6 +112,14 @@ struct imx_sc_pd_soc {
96112

97113
static int imx_con_rsrc;
98114

115+
/* Align with the IMX_SC_PM_PW_MODE_[OFF,STBY,LP,ON] macros */
116+
static const char * const imx_sc_pm_mode[] = {
117+
"IMX_SC_PM_PW_MODE_OFF",
118+
"IMX_SC_PM_PW_MODE_STBY",
119+
"IMX_SC_PM_PW_MODE_LP",
120+
"IMX_SC_PM_PW_MODE_ON"
121+
};
122+
99123
static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
100124
/* LSIO SS */
101125
{ "pwm", IMX_SC_R_PWM_0, 8, true, 0 },
@@ -308,6 +332,27 @@ static void imx_sc_pd_get_console_rsrc(void)
308332
imx_con_rsrc = specs.args[0];
309333
}
310334

335+
static int imx_sc_get_pd_power(struct device *dev, u32 rsrc)
336+
{
337+
struct imx_sc_msg_req_get_resource_power_mode msg;
338+
struct imx_sc_rpc_msg *hdr = &msg.hdr;
339+
int ret;
340+
341+
hdr->ver = IMX_SC_RPC_VERSION;
342+
hdr->svc = IMX_SC_RPC_SVC_PM;
343+
hdr->func = IMX_SC_PM_FUNC_GET_RESOURCE_POWER_MODE;
344+
hdr->size = 2;
345+
346+
msg.data.req.resource = rsrc;
347+
348+
ret = imx_scu_call_rpc(pm_ipc_handle, &msg, true);
349+
if (ret)
350+
dev_err(dev, "failed to get power resource %d mode, ret %d\n",
351+
rsrc, ret);
352+
353+
return msg.data.resp.mode;
354+
}
355+
311356
static int imx_sc_pd_power(struct generic_pm_domain *domain, bool power_on)
312357
{
313358
struct imx_sc_msg_req_set_resource_power_mode msg;
@@ -372,8 +417,8 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
372417
const struct imx_sc_pd_range *pd_ranges)
373418
{
374419
struct imx_sc_pm_domain *sc_pd;
375-
bool is_off = true;
376-
int ret;
420+
bool is_off;
421+
int mode, ret;
377422

378423
if (!imx_sc_rm_is_resource_owned(pm_ipc_handle, pd_ranges->rsrc + idx))
379424
return NULL;
@@ -394,10 +439,16 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
394439
"%s", pd_ranges->name);
395440

396441
sc_pd->pd.name = sc_pd->name;
397-
if (imx_con_rsrc == sc_pd->rsrc) {
442+
if (imx_con_rsrc == sc_pd->rsrc)
398443
sc_pd->pd.flags = GENPD_FLAG_RPM_ALWAYS_ON;
444+
445+
mode = imx_sc_get_pd_power(dev, pd_ranges->rsrc + idx);
446+
if (mode == IMX_SC_PM_PW_MODE_ON)
399447
is_off = false;
400-
}
448+
else
449+
is_off = true;
450+
451+
dev_dbg(dev, "%s : %s\n", sc_pd->name, imx_sc_pm_mode[mode]);
401452

402453
if (sc_pd->rsrc >= IMX_SC_R_LAST) {
403454
dev_warn(dev, "invalid pd %s rsrc id %d found",

0 commit comments

Comments
 (0)