Lines Matching +full:ipa +full:- +full:clock +full:- +full:enabled
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.
15 #include "ipa.h"
23 * DOC: IPA Power Management
25 * The IPA hardware is enabled when the IPA core clock and all the
26 * interconnects (buses) it depends on are enabled. Runtime power
27 * management is used to determine whether the core clock and
28 * interconnects are enabled, and if not in use to be suspended
31 * The core clock currently runs at a fixed clock rate when enabled,
38 * struct ipa_power - IPA power management information
39 * @dev: IPA device pointer
40 * @core: IPA core clock
53 /* Initialize interconnects required for IPA operation */
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()
80 /* Set the bandwidth values to be used when enabled */ 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()
91 icc_bulk_put(power->interconnect_count, power->interconnect); in ipa_interconnect_exit()
94 /* Enable IPA power, enabling interconnects and the core clock */
95 static int ipa_power_enable(struct ipa *ipa) in ipa_power_enable() argument
97 struct ipa_power *power = ipa->power; in ipa_power_enable()
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()
115 static void ipa_power_disable(struct ipa *ipa) in ipa_power_disable() argument
117 struct ipa_power *power = ipa->power; in ipa_power_disable()
119 clk_disable_unprepare(power->core); in ipa_power_disable()
121 icc_bulk_disable(power->interconnect_count, power->interconnect); in ipa_power_disable()
126 struct ipa *ipa = dev_get_drvdata(dev); in ipa_runtime_suspend() local
129 if (ipa->setup_complete) { in ipa_runtime_suspend()
130 ipa_endpoint_suspend(ipa); in ipa_runtime_suspend()
131 gsi_suspend(&ipa->gsi); in ipa_runtime_suspend()
134 ipa_power_disable(ipa); in ipa_runtime_suspend()
141 struct ipa *ipa = dev_get_drvdata(dev); in ipa_runtime_resume() local
144 ret = ipa_power_enable(ipa); in ipa_runtime_resume()
149 if (ipa->setup_complete) { in ipa_runtime_resume()
150 gsi_resume(&ipa->gsi); in ipa_runtime_resume()
151 ipa_endpoint_resume(ipa); in ipa_runtime_resume()
159 struct ipa *ipa = dev_get_drvdata(dev); in ipa_suspend() local
162 * be re-enabled until the matching _enable call in in ipa_suspend()
167 * irq wake. If wakeup is enabled for the IPA then the IRQ in ipa_suspend()
170 ipa_interrupt_irq_disable(ipa); in ipa_suspend()
177 struct ipa *ipa = dev_get_drvdata(dev); in ipa_resume() local
182 /* Now that PM runtime is enabled again it's safe in ipa_resume()
186 ipa_interrupt_irq_enable(ipa); in ipa_resume()
191 /* Return the current IPA core clock rate */
192 u32 ipa_core_clock_rate(struct ipa *ipa) in ipa_core_clock_rate() argument
194 return ipa->power ? (u32)clk_get_rate(ipa->power->core) : 0; in ipa_core_clock_rate()
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()
215 qmp_put(power->qmp); in ipa_power_retention_exit()
216 power->qmp = NULL; in ipa_power_retention_exit()
220 void ipa_power_retention(struct ipa *ipa, bool enable) in ipa_power_retention() argument
223 struct ipa_power *power = ipa->power; in ipa_power_retention()
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 */
246 return dev_err_cast_probe(dev, clk, "error getting core clock\n"); in ipa_power_init()
248 ret = clk_set_rate(clk, data->core_clock_rate); in ipa_power_init()
250 dev_err(dev, "error %d setting core clock rate to %u\n", 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()
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()
292 struct device *dev = power->dev; in ipa_power_exit()
293 struct clk *clk = power->core; in ipa_power_exit()