Repository navigation
lib: MCPS budget manager #6649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
lib: MCPS budget manager #6649
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| /* SPDX-License-Identifier: BSD-3-Clause | ||
| * | ||
| * Copyright(c) 2022 Intel Corporation. All rights reserved. | ||
| * | ||
| * Author: Krzysztof Frydryk <frydryk.krzysztof@intel.com> | ||
| */ | ||
|
|
||
| /** | ||
| * \file include/sof/lib/cpu-clk-manager.h | ||
| * \brief CPU clk manager definition | ||
| * \author Krzysztof Frydryk <krzysztofx.frydryk@intel.com> | ||
| */ | ||
|
|
||
| #ifndef __SOF_LIB_CPU_CLK_MANAGER_H__ | ||
| #define __SOF_LIB_CPU_CLK_MANAGER_H__ | ||
|
|
||
| #include <rtos/spinlock.h> | ||
| #include <sof/sof.h> | ||
| #include <stdint.h> | ||
|
|
||
| /** | ||
| * \brief CPS budget data. | ||
| */ | ||
| struct kcps_budget_data { | ||
| /* uncache only */ | ||
| int kcps_consumption[CONFIG_CORE_COUNT]; /* Sum of declared consumptions on core */ | ||
| struct k_spinlock lock; | ||
| }; | ||
|
|
||
| /** | ||
| * \brief Declare KCPS usage on core | ||
| * | ||
| * Declare KCPS (kilo cycles per second) CPU usage on core and adjust | ||
| * CPU clock according to sum of declared consumptions. | ||
| * | ||
| * Declared consumption can be negative in case of freeing CPS. | ||
| * | ||
| * @param core The core to which consumption should be pinned | ||
| * @param kcps_delta declared usage. Can be negative. | ||
| */ | ||
| int core_kcps_adjust(int core, int kcps_delta); | ||
|
|
||
| /** | ||
| * \brief Get KCPS usage on core | ||
| * | ||
| * Get declared KCPS usage on core | ||
| * | ||
| * @param core The core which consumption should be returned | ||
| */ | ||
| int core_kcps_get(int core); | ||
|
|
||
| /** | ||
| * \brief Init KCPS budget mechanism | ||
| */ | ||
| int kcps_budget_init(void); | ||
|
|
||
| #endif /*__SOF_LIB_CPU_CLK_MANAGER_H__ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,4 +23,5 @@ add_local_sources(sof | |
| dma.c | ||
| dai.c | ||
| wait.c | ||
| cpu-clk-manager.c | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
| // | ||
| // Copyright(c) 2022 Intel Corporation. All rights reserved. | ||
| // | ||
| // Author: Krzysztof Frydryk <frydryk.krzysztof@intel.com> | ||
|
|
||
| #include <rtos/spinlock.h> | ||
| #include <sof/sof.h> | ||
| #include <stdint.h> | ||
| #include <sof/lib/cpu-clk-manager.h> | ||
| #include <rtos/clk.h> | ||
| #include <sof/sof.h> | ||
| #include <sof/math/numbers.h> | ||
| #include <errno.h> | ||
| #ifdef __ZEPHYR__ | ||
| #include <zephyr/sys/util.h> | ||
| #endif /* __ZEPHYR__ */ | ||
|
|
||
| static struct kcps_budget_data kcps_data; | ||
|
|
||
| static int request_freq_change(unsigned int core, int freq) | ||
| { | ||
| int current_freq; | ||
| int selected_freq_id; | ||
| struct clock_info *clk; | ||
|
|
||
| clk = clocks_get() + core; | ||
|
|
||
| for (selected_freq_id = 0; selected_freq_id < clk->freqs_num; selected_freq_id++) { | ||
| if (freq < clk->freqs[selected_freq_id].freq) | ||
| break; | ||
| } | ||
|
|
||
| /* don't change clock frequency if already using proper clock */ | ||
| current_freq = clock_get_freq(core); | ||
| if (clk->freqs[selected_freq_id].freq != current_freq) | ||
| clock_set_freq(core, freq); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int max_core_consumption(void) | ||
| { | ||
| int result = 0; | ||
| unsigned int core; | ||
|
|
||
| for (core = 0; core < CONFIG_CORE_COUNT; core++) | ||
| result = MAX(result, kcps_data.kcps_consumption[core]); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| int core_kcps_adjust(int adjusted_core_id, int kcps_delta) | ||
| { | ||
| k_spinlock_key_t key; | ||
| int freq; | ||
| unsigned int core_id; | ||
| int ret = 0; | ||
|
|
||
| key = k_spin_lock(&kcps_data.lock); | ||
| kcps_data.kcps_consumption[adjusted_core_id] += kcps_delta; | ||
|
|
||
| /* set clock according to maximum requested mcps budget */ | ||
| freq = max_core_consumption(); | ||
|
|
||
| for (core_id = 0; core_id < CONFIG_CORE_COUNT; core_id++) { | ||
| /* Convert kcps to cps */ | ||
| ret = request_freq_change(core_id, freq * 1000); | ||
| if (ret < 0) | ||
| goto out; | ||
| } | ||
|
|
||
| out: | ||
| k_spin_unlock(&kcps_data.lock, key); | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| int core_kcps_get(int core) | ||
| { | ||
| k_spinlock_key_t key; | ||
| int ret; | ||
|
|
||
| key = k_spin_lock(&kcps_data.lock); | ||
| ret = kcps_data.kcps_consumption[core]; | ||
| k_spin_unlock(&kcps_data.lock, key); | ||
| return ret; | ||
| } | ||
|
|
||
| int kcps_budget_init(void) | ||
| { | ||
| k_spinlock_init(&kcps_data.lock); | ||
|
|
||
| return 0; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kfrydryx did you try to clarify with ACE FW/Windows SW why do we have two IPC's doing actually the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not. register_kcps is not used in internal testing, though the call is implemented. Both are handled by closed source fw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is 1 mcps == 1000 kcps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, exactly. Just like in metric system. 1 MCPS = 1000 KCPS = 1000 000 CPS.