Lines Matching +full:power +full:-
1 // SPDX-License-Identifier: GPL-2.0
3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2018-2024 Linaro Ltd.
23 * DOC: IPA Power Management
26 * interconnects (buses) it depends on are enabled. Runtime power
38 * struct ipa_power - IPA power management information
54 static int ipa_interconnect_init(struct ipa_power *power, in ipa_interconnect_init() argument
62 interconnect = &power->interconnect[0]; in ipa_interconnect_init()
63 for (i = 0; i < power->interconnect_count; i++) { in ipa_interconnect_init()
64 /* interconnect->path is filled in by of_icc_bulk_get() */ in ipa_interconnect_init()
65 interconnect->name = data->name; in ipa_interconnect_init()
66 interconnect->avg_bw = data->average_bandwidth; in ipa_interconnect_init()
67 interconnect->peak_bw = data->peak_bandwidth; in ipa_interconnect_init()
72 ret = of_icc_bulk_get(power->dev, power->interconnect_count, in ipa_interconnect_init()
73 power->interconnect); in ipa_interconnect_init()
78 icc_bulk_disable(power->interconnect_count, power->interconnect); in ipa_interconnect_init()
81 ret = icc_bulk_set_bw(power->interconnect_count, power->interconnect); in ipa_interconnect_init()
83 icc_bulk_put(power->interconnect_count, power->interconnect); in ipa_interconnect_init()
89 static void ipa_interconnect_exit(struct ipa_power *power) in ipa_interconnect_exit() argument
91 icc_bulk_put(power->interconnect_count, power->interconnect); in ipa_interconnect_exit()
94 /* Enable IPA power, enabling interconnects and the core clock */
97 struct ipa_power *power = ipa->power; in ipa_power_enable() local
100 ret = icc_bulk_enable(power->interconnect_count, power->interconnect); in ipa_power_enable()
104 ret = clk_prepare_enable(power->core); in ipa_power_enable()
106 dev_err(power->dev, "error %d enabling core clock\n", ret); in ipa_power_enable()
107 icc_bulk_disable(power->interconnect_count, in ipa_power_enable()
108 power->interconnect); in ipa_power_enable()
117 struct ipa_power *power = ipa->power; in ipa_power_disable() local
119 clk_disable_unprepare(power->core); in ipa_power_disable()
121 icc_bulk_disable(power->interconnect_count, power->interconnect); in ipa_power_disable()
129 if (ipa->setup_complete) { in ipa_runtime_suspend()
131 gsi_suspend(&ipa->gsi); in ipa_runtime_suspend()
149 if (ipa->setup_complete) { in ipa_runtime_resume()
150 gsi_resume(&ipa->gsi); in ipa_runtime_resume()
162 * be re-enabled until the matching _enable call in in ipa_suspend()
194 return ipa->power ? (u32)clk_get_rate(ipa->power->core) : 0; in ipa_core_clock_rate()
197 static int ipa_power_retention_init(struct ipa_power *power) in ipa_power_retention_init() argument
199 struct qmp *qmp = qmp_get(power->dev); in ipa_power_retention_init()
202 if (PTR_ERR(qmp) == -EPROBE_DEFER) in ipa_power_retention_init()
203 return -EPROBE_DEFER; in ipa_power_retention_init()
208 power->qmp = qmp; in ipa_power_retention_init()
213 static void ipa_power_retention_exit(struct ipa_power *power) in ipa_power_retention_exit() argument
215 qmp_put(power->qmp); in ipa_power_retention_exit()
216 power->qmp = NULL; in ipa_power_retention_exit()
219 /* Control register retention on power collapse */
223 struct ipa_power *power = ipa->power; in ipa_power_retention() local
226 if (!power->qmp) in ipa_power_retention()
229 ret = qmp_send(power->qmp, fmt, enable ? '1' : '0'); in ipa_power_retention()
231 dev_err(power->dev, "error %d sending QMP %sable request\n", in ipa_power_retention()
235 /* Initialize IPA power management */
239 struct ipa_power *power; in ipa_power_init() local
248 ret = clk_set_rate(clk, data->core_clock_rate); in ipa_power_init()
251 ret, data->core_clock_rate); in ipa_power_init()
255 size = struct_size(power, interconnect, data->interconnect_count); in ipa_power_init()
256 power = kzalloc(size, GFP_KERNEL); in ipa_power_init()
257 if (!power) { in ipa_power_init()
258 ret = -ENOMEM; in ipa_power_init()
261 power->dev = dev; in ipa_power_init()
262 power->core = clk; in ipa_power_init()
263 power->interconnect_count = data->interconnect_count; in ipa_power_init()
265 ret = ipa_interconnect_init(power, data->interconnect_data); in ipa_power_init()
269 ret = ipa_power_retention_init(power); in ipa_power_init()
277 return power; in ipa_power_init()
280 ipa_interconnect_exit(power); in ipa_power_init()
282 kfree(power); in ipa_power_init()
290 void ipa_power_exit(struct ipa_power *power) in ipa_power_exit() argument
292 struct device *dev = power->dev; in ipa_power_exit()
293 struct clk *clk = power->core; in ipa_power_exit()
297 ipa_power_retention_exit(power); in ipa_power_exit()
298 ipa_interconnect_exit(power); in ipa_power_exit()
299 kfree(power); in ipa_power_exit()