Skip to content

Commit 7605252

Browse files
committed
platform: intel: add clock switch for waiti
Platforms with cAVS version 1.8 & 2.0 have hardware requirement that DSP should use LPRO as clock source in waiti. This patch adds config for that and enables it for platforms that need it. Signed-off-by: Janusz Jankowski <janusz.jankowski@linux.intel.com>
1 parent 1b71a50 commit 7605252

File tree

5 files changed

+102
-7
lines changed

5 files changed

+102
-7
lines changed

src/platform/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ config CANNONLAKE
9595
select CAVS
9696
select CAVS_VERSION_1_8
9797
select WAITI_DELAY
98+
select CAVS_USE_LPRO_IN_WAITI
9899
help
99100
Select if your target platform is Cannonlake-compatible
100101

@@ -113,6 +114,7 @@ config SUECREEK
113114
select CAVS
114115
select CAVS_VERSION_2_0
115116
select WAITI_DELAY
117+
select CAVS_USE_LPRO_IN_WAITI
116118
help
117119
Select if your target platform is Suecreek-compatible
118120

@@ -130,6 +132,7 @@ config ICELAKE
130132
select CAVS
131133
select CAVS_VERSION_2_0
132134
select WAITI_DELAY
135+
select CAVS_USE_LPRO_IN_WAITI
133136
help
134137
Select if your target platform is Icelake-compatible
135138

@@ -219,6 +222,16 @@ config CONFIG_CHERRYTRAIL_EXTRA_DW_DMA
219222
Select if you need support for all 3 DMACs versus the default 2 used
220223
in baytrail.
221224

225+
config CAVS_USE_LPRO_IN_WAITI
226+
bool
227+
default n
228+
depends on CAVS
229+
select WAKEUP_HOOK
230+
help
231+
Select if platform requires DSP clock source to be switched to LPRO
232+
while in waiti.
233+
After waiti clock source is restored.
234+
222235
# TODO: it should just take manifest version and offsets
223236
config FIRMWARE_SHORT_NAME
224237
string "Rimage firmware name"

src/platform/intel/cavs/include/cavs/drivers/interrupt.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,20 @@
1010
#ifndef __CAVS_DRIVERS_INTERRUPT_H__
1111
#define __CAVS_DRIVERS_INTERRUPT_H__
1212

13+
#include <sof/lib/clk.h>
14+
1315
extern char irq_name_level2[];
1416
extern char irq_name_level3[];
1517
extern char irq_name_level4[];
1618
extern char irq_name_level5[];
1719

20+
#if CONFIG_CAVS_USE_LPRO_IN_WAITI
21+
static inline void platform_interrupt_on_wakeup(void)
22+
{
23+
platform_clock_on_wakeup();
24+
}
25+
#endif
26+
1827
#endif /* __CAVS_DRIVERS_INTERRUPT_H__ */
1928

2029
#else

src/platform/intel/cavs/include/cavs/lib/clk.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ extern uint32_t cpu_freq_status_mask[];
4141

4242
void platform_clock_init(void);
4343

44+
#if CONFIG_CAVS_USE_LPRO_IN_WAITI
45+
void platform_clock_on_waiti(void);
46+
void platform_clock_on_wakeup(void);
47+
#endif
48+
4449
#endif /* __CAVS_LIB_CLK_H__ */
4550

4651
#else

src/platform/intel/cavs/lib/clk.c

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,41 @@ static struct clock_info platform_clocks_info[NUM_CLOCKS];
1313

1414
struct clock_info *clocks = platform_clocks_info;
1515

16-
static int clock_platform_set_cpu_freq(int clock, int freq_idx)
16+
#if CONFIG_CAVS_USE_LPRO_IN_WAITI
17+
/* Track freq_idx value, so it can be stored before switching to LPRO. */
18+
static int cpu_current_freq_idx;
19+
20+
static inline int get_cpu_current_freq_idx(void)
1721
{
18-
uint32_t enc = cpu_freq_enc[freq_idx];
22+
return *cache_to_uncache(&cpu_current_freq_idx);
23+
}
24+
25+
static inline void set_cpu_current_freq_idx(int freq_idx)
26+
{
27+
*cache_to_uncache(&cpu_current_freq_idx) = freq_idx;
28+
}
29+
#else
30+
static inline void set_cpu_current_freq_idx(int freq_idx)
31+
{
32+
}
33+
#endif
1934

20-
/* set CPU frequency request for CCU */
2135
#if CAVS_VERSION == CAVS_VERSION_1_5
36+
static inline void select_cpu_clock(int freq_idx, bool release_unused)
37+
{
38+
uint32_t enc = cpu_freq_enc[freq_idx];
39+
2240
io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL, SHIM_CLKCTL_HDCS, 0);
2341
io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL,
2442
SHIM_CLKCTL_DPCS_MASK(cpu_get_id()),
2543
enc);
44+
45+
set_cpu_current_freq_idx(freq_idx);
46+
}
2647
#else
48+
static inline void select_cpu_clock(int freq_idx, bool release_unused)
49+
{
50+
uint32_t enc = cpu_freq_enc[freq_idx];
2751
uint32_t status_mask = cpu_freq_status_mask[freq_idx];
2852

2953
/* request clock */
@@ -39,14 +63,53 @@ static int clock_platform_set_cpu_freq(int clock, int freq_idx)
3963
io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL,
4064
SHIM_CLKCTL_OSC_SOURCE_MASK, enc);
4165

42-
/* release other clocks */
43-
io_reg_write(SHIM_BASE + SHIM_CLKCTL,
44-
(io_reg_read(SHIM_BASE + SHIM_CLKCTL) &
45-
~SHIM_CLKCTL_OSC_REQUEST_MASK) | enc);
66+
if (release_unused) {
67+
/* release other clocks */
68+
io_reg_write(SHIM_BASE + SHIM_CLKCTL,
69+
(io_reg_read(SHIM_BASE + SHIM_CLKCTL) &
70+
~SHIM_CLKCTL_OSC_REQUEST_MASK) | enc);
71+
}
72+
73+
set_cpu_current_freq_idx(freq_idx);
74+
}
4675
#endif
76+
77+
static int clock_platform_set_cpu_freq(int clock, int freq_idx)
78+
{
79+
select_cpu_clock(freq_idx, true);
4780
return 0;
4881
}
4982

83+
#if CONFIG_CAVS_USE_LPRO_IN_WAITI
84+
/* Store clock source that was active before going to waiti,
85+
* so it can be restored on wake up.
86+
*/
87+
static int active_freq_idx = CPU_DEFAULT_IDX;
88+
89+
void platform_clock_on_wakeup(void)
90+
{
91+
int freq_idx = *cache_to_uncache(&active_freq_idx);
92+
93+
if (freq_idx != get_cpu_current_freq_idx())
94+
select_cpu_clock(freq_idx, true);
95+
}
96+
97+
void platform_clock_on_waiti(void)
98+
{
99+
int freq_idx = get_cpu_current_freq_idx();
100+
101+
*cache_to_uncache(&active_freq_idx) = freq_idx;
102+
103+
if (freq_idx != CPU_LPRO_FREQ_IDX)
104+
/* LPRO requests are fast, but requests for other ROs
105+
* can take a lot of time. That's why it's better to
106+
* not release active clock just for waiti,
107+
* so they can be switched without delay on wake up.
108+
*/
109+
select_cpu_clock(CPU_LPRO_FREQ_IDX, false);
110+
}
111+
#endif
112+
50113
void platform_clock_init(void)
51114
{
52115
int i;
@@ -70,4 +133,6 @@ void platform_clock_init(void)
70133
.notification_mask = NOTIFIER_TARGET_CORE_ALL_MASK,
71134
.set_freq = NULL,
72135
};
136+
137+
set_cpu_current_freq_idx(CPU_DEFAULT_IDX);
73138
}

src/platform/intel/cavs/platform.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ int platform_init(struct sof *sof)
479479

480480
void platform_wait_for_interrupt(int level)
481481
{
482+
#if CONFIG_CAVS_USE_LPRO_IN_WAITI
483+
platform_clock_on_waiti();
484+
#endif
482485
#if (CONFIG_CAVS_LPS)
483486
if (pm_runtime_is_active(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID))
484487
arch_wait_for_interrupt(level);

0 commit comments

Comments
 (0)