Skip to content

Commit d46ede3

Browse files
committed
Merge tag 'pmdomain-v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm
Pull pmdomain updates from Ulf Hansson: "pmdomain core: - Add support for HW-managed devices pmdomain providers: - amlogic: Add support for the A5 and the A4 power domains - arm: Enable system wakeups for the SCMI PM domain - qcom/clk: Add HW-mode callbacks to allow switching of GDSC mode pmdomain consumers: - qcom/media/venus: Enable support for switching GDSC HW-mode on V6" * tag 'pmdomain-v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: pmdomain: amlogic: Constify struct meson_secure_pwrc_domain_desc venus: pm_helpers: Use dev_pm_genpd_set_hwmode to switch GDSC mode on V6 clk: qcom: videocc: Use HW_CTRL_TRIGGER for SM8250, SC7280 vcodec GDSC's clk: qcom: gdsc: Add set and get hwmode callbacks to switch GDSC mode PM: domains: Add the domain HW-managed mode to the summary PM: domains: Allow devices attached to genpd to be managed by HW pmdomain: amlogic: Add support for A5 power domains controller dt-bindings: power: add Amlogic A5 power domains pmdomain: amlogic: add missing MODULE_DESCRIPTION() macros pmdomain: arm: scmi_pm_domain: set flag GENPD_FLAG_ACTIVE_WAKEUP pmdomain: renesas: rmobile-sysc: Use for_each_child_of_node_scoped() pmdomain: core: Use genpd_is_irq_safe() helper pmdomain: amlogic: Add support for A4 power domains controller dt-bindings: power: add Amlogic A4 power domains
2 parents c6e63a9 + 67ce905 commit d46ede3

File tree

15 files changed

+271
-33
lines changed

15 files changed

+271
-33
lines changed

Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ properties:
2020
enum:
2121
- amlogic,meson-a1-pwrc
2222
- amlogic,meson-s4-pwrc
23+
- amlogic,a4-pwrc
24+
- amlogic,a5-pwrc
2325
- amlogic,c3-pwrc
2426
- amlogic,t7-pwrc
2527

drivers/clk/qcom/gdsc.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,43 @@ static int gdsc_disable(struct generic_pm_domain *domain)
363363
return 0;
364364
}
365365

366+
static int gdsc_set_hwmode(struct generic_pm_domain *domain, struct device *dev, bool mode)
367+
{
368+
struct gdsc *sc = domain_to_gdsc(domain);
369+
int ret;
370+
371+
ret = gdsc_hwctrl(sc, mode);
372+
if (ret)
373+
return ret;
374+
375+
/*
376+
* Wait for the GDSC to go through a power down and
377+
* up cycle. If we poll the status register before the
378+
* power cycle is finished we might read incorrect values.
379+
*/
380+
udelay(1);
381+
382+
/*
383+
* When the GDSC is switched to HW mode, HW can disable the GDSC.
384+
* When the GDSC is switched back to SW mode, the GDSC will be enabled
385+
* again, hence we need to poll for GDSC to complete the power up.
386+
*/
387+
if (!mode)
388+
return gdsc_poll_status(sc, GDSC_ON);
389+
390+
return 0;
391+
}
392+
393+
static bool gdsc_get_hwmode(struct generic_pm_domain *domain, struct device *dev)
394+
{
395+
struct gdsc *sc = domain_to_gdsc(domain);
396+
u32 val;
397+
398+
regmap_read(sc->regmap, sc->gdscr, &val);
399+
400+
return !!(val & HW_CONTROL_MASK);
401+
}
402+
366403
static int gdsc_init(struct gdsc *sc)
367404
{
368405
u32 mask, val;
@@ -451,6 +488,10 @@ static int gdsc_init(struct gdsc *sc)
451488
sc->pd.power_off = gdsc_disable;
452489
if (!sc->pd.power_on)
453490
sc->pd.power_on = gdsc_enable;
491+
if (sc->flags & HW_CTRL_TRIGGER) {
492+
sc->pd.set_hwmode_dev = gdsc_set_hwmode;
493+
sc->pd.get_hwmode_dev = gdsc_get_hwmode;
494+
}
454495

455496
ret = pm_genpd_init(&sc->pd, NULL, !on);
456497
if (ret)

drivers/clk/qcom/gdsc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct gdsc {
6767
#define ALWAYS_ON BIT(6)
6868
#define RETAIN_FF_ENABLE BIT(7)
6969
#define NO_RET_PERIPH BIT(8)
70+
#define HW_CTRL_TRIGGER BIT(9)
7071
struct reset_controller_dev *rcdev;
7172
unsigned int *resets;
7273
unsigned int reset_count;

drivers/clk/qcom/videocc-sc7280.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ static struct gdsc mvs0_gdsc = {
236236
.name = "mvs0_gdsc",
237237
},
238238
.pwrsts = PWRSTS_OFF_ON,
239-
.flags = HW_CTRL | RETAIN_FF_ENABLE,
239+
.flags = HW_CTRL_TRIGGER | RETAIN_FF_ENABLE,
240240
};
241241

242242
static struct gdsc mvsc_gdsc = {

drivers/clk/qcom/videocc-sm8250.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ static struct gdsc mvs0_gdsc = {
293293
.pd = {
294294
.name = "mvs0_gdsc",
295295
},
296-
.flags = HW_CTRL,
296+
.flags = HW_CTRL_TRIGGER,
297297
.pwrsts = PWRSTS_OFF_ON,
298298
};
299299

@@ -302,7 +302,7 @@ static struct gdsc mvs1_gdsc = {
302302
.pd = {
303303
.name = "mvs1_gdsc",
304304
},
305-
.flags = HW_CTRL,
305+
.flags = HW_CTRL_TRIGGER,
306306
.pwrsts = PWRSTS_OFF_ON,
307307
};
308308

drivers/media/platform/qcom/venus/pm_helpers.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,9 @@ static int vcodec_control_v4(struct venus_core *core, u32 coreid, bool enable)
412412
u32 val;
413413
int ret;
414414

415-
if (IS_V6(core)) {
416-
ctrl = core->wrapper_base + WRAPPER_CORE_POWER_CONTROL_V6;
417-
stat = core->wrapper_base + WRAPPER_CORE_POWER_STATUS_V6;
418-
} else if (coreid == VIDC_CORE_ID_1) {
415+
if (IS_V6(core))
416+
return dev_pm_genpd_set_hwmode(core->pmdomains->pd_devs[coreid], !enable);
417+
else if (coreid == VIDC_CORE_ID_1) {
419418
ctrl = core->wrapper_base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
420419
stat = core->wrapper_base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
421420
} else {
@@ -451,9 +450,11 @@ static int poweroff_coreid(struct venus_core *core, unsigned int coreid_mask)
451450

452451
vcodec_clks_disable(core, core->vcodec0_clks);
453452

454-
ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
455-
if (ret)
456-
return ret;
453+
if (!IS_V6(core)) {
454+
ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
455+
if (ret)
456+
return ret;
457+
}
457458

458459
ret = pm_runtime_put_sync(core->pmdomains->pd_devs[1]);
459460
if (ret < 0)
@@ -467,9 +468,11 @@ static int poweroff_coreid(struct venus_core *core, unsigned int coreid_mask)
467468

468469
vcodec_clks_disable(core, core->vcodec1_clks);
469470

470-
ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
471-
if (ret)
472-
return ret;
471+
if (!IS_V6(core)) {
472+
ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
473+
if (ret)
474+
return ret;
475+
}
473476

474477
ret = pm_runtime_put_sync(core->pmdomains->pd_devs[2]);
475478
if (ret < 0)
@@ -488,9 +491,11 @@ static int poweron_coreid(struct venus_core *core, unsigned int coreid_mask)
488491
if (ret < 0)
489492
return ret;
490493

491-
ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
492-
if (ret)
493-
return ret;
494+
if (!IS_V6(core)) {
495+
ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
496+
if (ret)
497+
return ret;
498+
}
494499

495500
ret = vcodec_clks_enable(core, core->vcodec0_clks);
496501
if (ret)
@@ -506,9 +511,11 @@ static int poweron_coreid(struct venus_core *core, unsigned int coreid_mask)
506511
if (ret < 0)
507512
return ret;
508513

509-
ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
510-
if (ret)
511-
return ret;
514+
if (!IS_V6(core)) {
515+
ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
516+
if (ret)
517+
return ret;
518+
}
512519

513520
ret = vcodec_clks_enable(core, core->vcodec1_clks);
514521
if (ret)

drivers/pmdomain/amlogic/meson-ee-pwrc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,4 +648,5 @@ static struct platform_driver meson_ee_pwrc_driver = {
648648
},
649649
};
650650
module_platform_driver(meson_ee_pwrc_driver);
651+
MODULE_DESCRIPTION("Amlogic Meson Everything-Else Power Domains driver");
651652
MODULE_LICENSE("GPL v2");

drivers/pmdomain/amlogic/meson-gx-pwrc-vpu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,4 +376,5 @@ static struct platform_driver meson_gx_pwrc_vpu_driver = {
376376
},
377377
};
378378
module_platform_driver(meson_gx_pwrc_vpu_driver);
379+
MODULE_DESCRIPTION("Amlogic Meson GX Power Domains driver");
379380
MODULE_LICENSE("GPL v2");

drivers/pmdomain/amlogic/meson-secure-pwrc.c

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <dt-bindings/power/amlogic,c3-pwrc.h>
1515
#include <dt-bindings/power/meson-s4-power.h>
1616
#include <dt-bindings/power/amlogic,t7-pwrc.h>
17+
#include <dt-bindings/power/amlogic,a4-pwrc.h>
18+
#include <dt-bindings/power/amlogic,a5-pwrc.h>
1719
#include <linux/arm-smccc.h>
1820
#include <linux/firmware/meson/meson_sm.h>
1921
#include <linux/module.h>
@@ -45,7 +47,7 @@ struct meson_secure_pwrc_domain_desc {
4547

4648
struct meson_secure_pwrc_domain_data {
4749
unsigned int count;
48-
struct meson_secure_pwrc_domain_desc *domains;
50+
const struct meson_secure_pwrc_domain_desc *domains;
4951
};
5052

5153
static bool pwrc_secure_is_off(struct meson_secure_pwrc_domain *pwrc_domain)
@@ -109,7 +111,7 @@ static int meson_secure_pwrc_on(struct generic_pm_domain *domain)
109111
.parent = __parent, \
110112
}
111113

112-
static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
114+
static const struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
113115
SEC_PD(DSPA, 0),
114116
SEC_PD(DSPB, 0),
115117
/* UART should keep working in ATF after suspend and before resume */
@@ -136,7 +138,41 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
136138
SEC_PD(RSA, 0),
137139
};
138140

139-
static struct meson_secure_pwrc_domain_desc c3_pwrc_domains[] = {
141+
static const struct meson_secure_pwrc_domain_desc a4_pwrc_domains[] = {
142+
SEC_PD(A4_AUDIO, 0),
143+
SEC_PD(A4_SDIOA, 0),
144+
SEC_PD(A4_EMMC, 0),
145+
SEC_PD(A4_USB_COMB, 0),
146+
SEC_PD(A4_ETH, 0),
147+
SEC_PD(A4_VOUT, 0),
148+
SEC_PD(A4_AUDIO_PDM, 0),
149+
/* DMC is for DDR PHY ana/dig and DMC, and should be always on */
150+
SEC_PD(A4_DMC, GENPD_FLAG_ALWAYS_ON),
151+
/* WRAP is secure_top, a lot of modules are included, and should be always on */
152+
SEC_PD(A4_SYS_WRAP, GENPD_FLAG_ALWAYS_ON),
153+
SEC_PD(A4_AO_I2C_S, 0),
154+
SEC_PD(A4_AO_UART, 0),
155+
/* IR is wake up trigger source, and should be always on */
156+
SEC_PD(A4_AO_IR, GENPD_FLAG_ALWAYS_ON),
157+
};
158+
159+
static const struct meson_secure_pwrc_domain_desc a5_pwrc_domains[] = {
160+
SEC_PD(A5_NNA, 0),
161+
SEC_PD(A5_AUDIO, 0),
162+
SEC_PD(A5_SDIOA, 0),
163+
SEC_PD(A5_EMMC, 0),
164+
SEC_PD(A5_USB_COMB, 0),
165+
SEC_PD(A5_ETH, 0),
166+
SEC_PD(A5_RSA, 0),
167+
SEC_PD(A5_AUDIO_PDM, 0),
168+
/* DMC is for DDR PHY ana/dig and DMC, and should be always on */
169+
SEC_PD(A5_DMC, GENPD_FLAG_ALWAYS_ON),
170+
/* WRAP is secure_top, a lot of modules are included, and should be always on */
171+
SEC_PD(A5_SYS_WRAP, GENPD_FLAG_ALWAYS_ON),
172+
SEC_PD(A5_DSPA, 0),
173+
};
174+
175+
static const struct meson_secure_pwrc_domain_desc c3_pwrc_domains[] = {
140176
SEC_PD(C3_NNA, 0),
141177
SEC_PD(C3_AUDIO, 0),
142178
SEC_PD(C3_SDIOA, 0),
@@ -153,7 +189,7 @@ static struct meson_secure_pwrc_domain_desc c3_pwrc_domains[] = {
153189
SEC_PD(C3_VCODEC, 0),
154190
};
155191

156-
static struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = {
192+
static const struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = {
157193
SEC_PD(S4_DOS_HEVC, 0),
158194
SEC_PD(S4_DOS_VDEC, 0),
159195
SEC_PD(S4_VPU_HDMI, 0),
@@ -165,7 +201,7 @@ static struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = {
165201
SEC_PD(S4_AUDIO, 0),
166202
};
167203

168-
static struct meson_secure_pwrc_domain_desc t7_pwrc_domains[] = {
204+
static const struct meson_secure_pwrc_domain_desc t7_pwrc_domains[] = {
169205
SEC_PD(T7_DSPA, 0),
170206
SEC_PD(T7_DSPB, 0),
171207
TOP_PD(T7_DOS_HCODEC, 0, PWRC_T7_NIC3_ID),
@@ -311,6 +347,16 @@ static struct meson_secure_pwrc_domain_data meson_secure_a1_pwrc_data = {
311347
.count = ARRAY_SIZE(a1_pwrc_domains),
312348
};
313349

350+
static struct meson_secure_pwrc_domain_data amlogic_secure_a4_pwrc_data = {
351+
.domains = a4_pwrc_domains,
352+
.count = ARRAY_SIZE(a4_pwrc_domains),
353+
};
354+
355+
static struct meson_secure_pwrc_domain_data amlogic_secure_a5_pwrc_data = {
356+
.domains = a5_pwrc_domains,
357+
.count = ARRAY_SIZE(a5_pwrc_domains),
358+
};
359+
314360
static struct meson_secure_pwrc_domain_data amlogic_secure_c3_pwrc_data = {
315361
.domains = c3_pwrc_domains,
316362
.count = ARRAY_SIZE(c3_pwrc_domains),
@@ -331,6 +377,14 @@ static const struct of_device_id meson_secure_pwrc_match_table[] = {
331377
.compatible = "amlogic,meson-a1-pwrc",
332378
.data = &meson_secure_a1_pwrc_data,
333379
},
380+
{
381+
.compatible = "amlogic,a4-pwrc",
382+
.data = &amlogic_secure_a4_pwrc_data,
383+
},
384+
{
385+
.compatible = "amlogic,a5-pwrc",
386+
.data = &amlogic_secure_a5_pwrc_data,
387+
},
334388
{
335389
.compatible = "amlogic,c3-pwrc",
336390
.data = &amlogic_secure_c3_pwrc_data,
@@ -355,4 +409,5 @@ static struct platform_driver meson_secure_pwrc_driver = {
355409
},
356410
};
357411
module_platform_driver(meson_secure_pwrc_driver);
412+
MODULE_DESCRIPTION("Amlogic Meson Secure Power Domains driver");
358413
MODULE_LICENSE("Dual MIT/GPL");

drivers/pmdomain/arm/scmi_pm_domain.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
102102
scmi_pd->genpd.name = scmi_pd->name;
103103
scmi_pd->genpd.power_off = scmi_pd_power_off;
104104
scmi_pd->genpd.power_on = scmi_pd_power_on;
105+
scmi_pd->genpd.flags = GENPD_FLAG_ACTIVE_WAKEUP;
105106

106107
pm_genpd_init(&scmi_pd->genpd, NULL,
107108
state == SCMI_POWER_STATE_GENERIC_OFF);

0 commit comments

Comments
 (0)