@@ -13,17 +13,41 @@ static struct clock_info platform_clocks_info[NUM_CLOCKS];
1313
1414struct 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+
50113void 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}
0 commit comments