Skip to content

Commit a070a08

Browse files
committed
Merge tag 'pmdomain-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm
Pull pmdomain updates from Ulf Hansson: "Core: - Log a message when unused PM domains gets disabled - Scale down parent/child performance states in the reverse order Providers: - qcom: rpmpd: Add power domains support for MSM8974, MSM8974PRO, PMA8084 and PM8841 - renesas: rcar-gen4-sysc: Reduce atomic delays - renesas: rcar-sysc: Adjust the waiting time to cover the worst case - renesas: r8a779h0-sysc: Add support for the r8a779h0 PM domains - imx: imx8mp-blk-ctrl: Add the fdcc clock to the hdmimix domains - imx: imx8mp-blk-ctrl: Error out if domains are missing in DT Improve support for multiple PM domains: - Add two helper functions to attach/detach multiple PM domains - Convert a couple of drivers to use the new helper functions" * tag 'pmdomain-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (22 commits) pmdomain: renesas: rcar-gen4-sysc: Reduce atomic delays pmdomain: renesas: Adjust the waiting time to cover the worst case pmdomain: qcom: rpmpd: Add MSM8974PRO+PMA8084 power domains pmdomain: qcom: rpmpd: Add MSM8974+PM8841 power domains pmdomain: core: constify of_phandle_args in add device and subdomain pmdomain: core: constify of_phandle_args in xlate media: venus: Convert to dev_pm_domain_attach|detach_list() for vcodec remoteproc: qcom_q6v5_adsp: Convert to dev_pm_domain_attach|detach_list() remoteproc: imx_rproc: Convert to dev_pm_domain_attach|detach_list() remoteproc: imx_dsp_rproc: Convert to dev_pm_domain_attach|detach_list() PM: domains: Add helper functions to attach/detach multiple PM domains pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain pmdomain: mediatek: Use devm_platform_ioremap_resource() in init_scp() pmdomain: renesas: r8a779h0-sysc: Add r8a779h0 support pmdomain: imx8mp-blk-ctrl: Error out if domains are missing in DT pmdomain: ti: Add a null pointer check to the omap_prm_domain_init pmdomain: renesas: rcar-gen4-sysc: Remove unneeded includes pmdomain: core: Print a message when unused power domains are disabled pmdomain: qcom: rpmpd: Keep one RPM handle for all RPMPDs pmdomain: core: Scale down parent/child performance states in reverse order ...
2 parents 15223fd + ccabbb6 commit a070a08

File tree

30 files changed

+594
-409
lines changed

30 files changed

+594
-409
lines changed

Documentation/devicetree/bindings/power/qcom,rpmpd.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ properties:
2424
- qcom,msm8917-rpmpd
2525
- qcom,msm8939-rpmpd
2626
- qcom,msm8953-rpmpd
27+
- qcom,msm8974-rpmpd
28+
- qcom,msm8974pro-pma8084-rpmpd
2729
- qcom,msm8976-rpmpd
2830
- qcom,msm8994-rpmpd
2931
- qcom,msm8996-rpmpd

Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ properties:
2727
const: 1
2828

2929
power-domains:
30-
minItems: 8
31-
maxItems: 8
30+
minItems: 10
31+
maxItems: 10
3232

3333
power-domain-names:
3434
items:
@@ -40,17 +40,20 @@ properties:
4040
- const: trng
4141
- const: hdmi-tx
4242
- const: hdmi-tx-phy
43+
- const: hdcp
44+
- const: hrv
4345

4446
clocks:
45-
minItems: 4
46-
maxItems: 4
47+
minItems: 5
48+
maxItems: 5
4749

4850
clock-names:
4951
items:
5052
- const: apb
5153
- const: axi
5254
- const: ref_266m
5355
- const: ref_24m
56+
- const: fdcc
5457

5558
interconnects:
5659
maxItems: 3
@@ -82,12 +85,15 @@ examples:
8285
clocks = <&clk IMX8MP_CLK_HDMI_APB>,
8386
<&clk IMX8MP_CLK_HDMI_ROOT>,
8487
<&clk IMX8MP_CLK_HDMI_REF_266M>,
85-
<&clk IMX8MP_CLK_HDMI_24M>;
86-
clock-names = "apb", "axi", "ref_266m", "ref_24m";
88+
<&clk IMX8MP_CLK_HDMI_24M>,
89+
<&clk IMX8MP_CLK_HDMI_FDCC_TST>;
90+
clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
8791
power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>, <&pgc_hdmimix>,
8892
<&pgc_hdmimix>, <&pgc_hdmimix>, <&pgc_hdmimix>,
89-
<&pgc_hdmimix>, <&pgc_hdmi_phy>;
93+
<&pgc_hdmimix>, <&pgc_hdmi_phy>,
94+
<&pgc_hdmimix>, <&pgc_hdmimix>;
9095
power-domain-names = "bus", "irqsteer", "lcdif", "pai", "pvi", "trng",
91-
"hdmi-tx", "hdmi-tx-phy";
96+
"hdmi-tx", "hdmi-tx-phy",
97+
"hdcp", "hrv";
9298
#power-domain-cells = <1>;
9399
};

drivers/base/power/common.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,115 @@ struct device *dev_pm_domain_attach_by_name(struct device *dev,
167167
}
168168
EXPORT_SYMBOL_GPL(dev_pm_domain_attach_by_name);
169169

170+
/**
171+
* dev_pm_domain_attach_list - Associate a device with its PM domains.
172+
* @dev: The device used to lookup the PM domains for.
173+
* @data: The data used for attaching to the PM domains.
174+
* @list: An out-parameter with an allocated list of attached PM domains.
175+
*
176+
* This function helps to attach a device to its multiple PM domains. The
177+
* caller, which is typically a driver's probe function, may provide a list of
178+
* names for the PM domains that we should try to attach the device to, but it
179+
* may also provide an empty list, in case the attach should be done for all of
180+
* the available PM domains.
181+
*
182+
* Callers must ensure proper synchronization of this function with power
183+
* management callbacks.
184+
*
185+
* Returns the number of attached PM domains or a negative error code in case of
186+
* a failure. Note that, to detach the list of PM domains, the driver shall call
187+
* dev_pm_domain_detach_list(), typically during the remove phase.
188+
*/
189+
int dev_pm_domain_attach_list(struct device *dev,
190+
const struct dev_pm_domain_attach_data *data,
191+
struct dev_pm_domain_list **list)
192+
{
193+
struct device_node *np = dev->of_node;
194+
struct dev_pm_domain_list *pds;
195+
struct device *pd_dev = NULL;
196+
int ret, i, num_pds = 0;
197+
bool by_id = true;
198+
u32 pd_flags = data ? data->pd_flags : 0;
199+
u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 :
200+
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME;
201+
202+
if (dev->pm_domain)
203+
return -EEXIST;
204+
205+
/* For now this is limited to OF based platforms. */
206+
if (!np)
207+
return 0;
208+
209+
if (data && data->pd_names) {
210+
num_pds = data->num_pd_names;
211+
by_id = false;
212+
} else {
213+
num_pds = of_count_phandle_with_args(np, "power-domains",
214+
"#power-domain-cells");
215+
}
216+
217+
if (num_pds <= 0)
218+
return 0;
219+
220+
pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL);
221+
if (!pds)
222+
return -ENOMEM;
223+
224+
pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs),
225+
GFP_KERNEL);
226+
if (!pds->pd_devs)
227+
return -ENOMEM;
228+
229+
pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links),
230+
GFP_KERNEL);
231+
if (!pds->pd_links)
232+
return -ENOMEM;
233+
234+
if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON)
235+
link_flags |= DL_FLAG_RPM_ACTIVE;
236+
237+
for (i = 0; i < num_pds; i++) {
238+
if (by_id)
239+
pd_dev = dev_pm_domain_attach_by_id(dev, i);
240+
else
241+
pd_dev = dev_pm_domain_attach_by_name(dev,
242+
data->pd_names[i]);
243+
if (IS_ERR_OR_NULL(pd_dev)) {
244+
ret = pd_dev ? PTR_ERR(pd_dev) : -ENODEV;
245+
goto err_attach;
246+
}
247+
248+
if (link_flags) {
249+
struct device_link *link;
250+
251+
link = device_link_add(dev, pd_dev, link_flags);
252+
if (!link) {
253+
ret = -ENODEV;
254+
goto err_link;
255+
}
256+
257+
pds->pd_links[i] = link;
258+
}
259+
260+
pds->pd_devs[i] = pd_dev;
261+
}
262+
263+
pds->num_pds = num_pds;
264+
*list = pds;
265+
return num_pds;
266+
267+
err_link:
268+
dev_pm_domain_detach(pd_dev, true);
269+
err_attach:
270+
while (--i >= 0) {
271+
if (pds->pd_links[i])
272+
device_link_del(pds->pd_links[i]);
273+
dev_pm_domain_detach(pds->pd_devs[i], true);
274+
}
275+
return ret;
276+
}
277+
EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list);
278+
170279
/**
171280
* dev_pm_domain_detach - Detach a device from its PM domain.
172281
* @dev: Device to detach.
@@ -187,6 +296,31 @@ void dev_pm_domain_detach(struct device *dev, bool power_off)
187296
}
188297
EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
189298

299+
/**
300+
* dev_pm_domain_detach_list - Detach a list of PM domains.
301+
* @list: The list of PM domains to detach.
302+
*
303+
* This function reverse the actions from dev_pm_domain_attach_list().
304+
* Typically it should be invoked during the remove phase from drivers.
305+
*
306+
* Callers must ensure proper synchronization of this function with power
307+
* management callbacks.
308+
*/
309+
void dev_pm_domain_detach_list(struct dev_pm_domain_list *list)
310+
{
311+
int i;
312+
313+
if (!list)
314+
return;
315+
316+
for (i = 0; i < list->num_pds; i++) {
317+
if (list->pd_links[i])
318+
device_link_del(list->pd_links[i]);
319+
dev_pm_domain_detach(list->pd_devs[i], true);
320+
}
321+
}
322+
EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list);
323+
190324
/**
191325
* dev_pm_domain_start - Start the device through its PM domain.
192326
* @dev: Device to start.

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/platform_device.h>
1717
#include <linux/slab.h>
1818
#include <linux/types.h>
19+
#include <linux/pm_domain.h>
1920
#include <linux/pm_runtime.h>
2021
#include <media/videobuf2-v4l2.h>
2122
#include <media/v4l2-mem2mem.h>
@@ -114,7 +115,8 @@ static void venus_sys_error_handler(struct work_struct *work)
114115
pm_runtime_put_sync(core->dev);
115116

116117
for (i = 0; i < max_attempts; i++) {
117-
if (!core->pmdomains[0] || !pm_runtime_active(core->pmdomains[0]))
118+
if (!core->pmdomains ||
119+
!pm_runtime_active(core->pmdomains->pd_devs[0]))
118120
break;
119121
usleep_range(1000, 1500);
120122
}
@@ -705,7 +707,7 @@ static const struct venus_resources sdm845_res_v2 = {
705707
.vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
706708
.vcodec1_clks = { "vcodec1_core", "vcodec1_bus" },
707709
.vcodec_clks_num = 2,
708-
.vcodec_pmdomains = { "venus", "vcodec0", "vcodec1" },
710+
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0", "vcodec1" },
709711
.vcodec_pmdomains_num = 3,
710712
.opp_pmdomain = (const char *[]) { "cx", NULL },
711713
.vcodec_num = 2,
@@ -754,7 +756,7 @@ static const struct venus_resources sc7180_res = {
754756
.clks_num = 3,
755757
.vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
756758
.vcodec_clks_num = 2,
757-
.vcodec_pmdomains = { "venus", "vcodec0" },
759+
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
758760
.vcodec_pmdomains_num = 2,
759761
.opp_pmdomain = (const char *[]) { "cx", NULL },
760762
.vcodec_num = 1,
@@ -811,7 +813,7 @@ static const struct venus_resources sm8250_res = {
811813
.resets_num = 2,
812814
.vcodec0_clks = { "vcodec0_core" },
813815
.vcodec_clks_num = 1,
814-
.vcodec_pmdomains = { "venus", "vcodec0" },
816+
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
815817
.vcodec_pmdomains_num = 2,
816818
.opp_pmdomain = (const char *[]) { "mx", NULL },
817819
.vcodec_num = 1,
@@ -870,7 +872,7 @@ static const struct venus_resources sc7280_res = {
870872
.clks_num = 3,
871873
.vcodec0_clks = {"vcodec_core", "vcodec_bus"},
872874
.vcodec_clks_num = 2,
873-
.vcodec_pmdomains = { "venus", "vcodec0" },
875+
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
874876
.vcodec_pmdomains_num = 2,
875877
.opp_pmdomain = (const char *[]) { "cx", NULL },
876878
.vcodec_num = 1,

drivers/media/platform/qcom/venus/core.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
#define VIDC_CLKS_NUM_MAX 4
2727
#define VIDC_VCODEC_CLKS_NUM_MAX 2
28-
#define VIDC_PMDOMAINS_NUM_MAX 3
2928
#define VIDC_RESETS_NUM_MAX 2
3029

3130
extern int venus_fw_debug;
@@ -72,7 +71,7 @@ struct venus_resources {
7271
const char * const vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX];
7372
const char * const vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX];
7473
unsigned int vcodec_clks_num;
75-
const char * const vcodec_pmdomains[VIDC_PMDOMAINS_NUM_MAX];
74+
const char **vcodec_pmdomains;
7675
unsigned int vcodec_pmdomains_num;
7776
const char **opp_pmdomain;
7877
unsigned int vcodec_num;
@@ -134,7 +133,7 @@ struct venus_format {
134133
* @video_path: an interconnect handle to video to/from memory path
135134
* @cpucfg_path: an interconnect handle to cpu configuration path
136135
* @has_opp_table: does OPP table exist
137-
* @pmdomains: an array of pmdomains struct device pointers
136+
* @pmdomains: a pointer to a list of pmdomains
138137
* @opp_dl_venus: an device-link for device OPP
139138
* @opp_pmdomain: an OPP power-domain
140139
* @resets: an array of reset signals
@@ -187,7 +186,7 @@ struct venus_core {
187186
struct icc_path *video_path;
188187
struct icc_path *cpucfg_path;
189188
bool has_opp_table;
190-
struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX];
189+
struct dev_pm_domain_list *pmdomains;
191190
struct device_link *opp_dl_venus;
192191
struct device *opp_pmdomain;
193192
struct reset_control *resets[VIDC_RESETS_NUM_MAX];

0 commit comments

Comments
 (0)