diff --git a/src/arch/xtensa/configs/override/cannonlake_chrome.config b/src/arch/xtensa/configs/override/cannonlake_chrome.config index 3ac57df516da..039ec36fdcc2 100644 --- a/src/arch/xtensa/configs/override/cannonlake_chrome.config +++ b/src/arch/xtensa/configs/override/cannonlake_chrome.config @@ -1,2 +1,2 @@ CONFIG_CAVS_LPS=y -CONFIG_CAVS_LPRO=y +CONFIG_CAVS_USE_LPRO_IN_WAITI=y diff --git a/src/arch/xtensa/configs/override/jasperlake_chrome.config b/src/arch/xtensa/configs/override/jasperlake_chrome.config index 3ac57df516da..039ec36fdcc2 100644 --- a/src/arch/xtensa/configs/override/jasperlake_chrome.config +++ b/src/arch/xtensa/configs/override/jasperlake_chrome.config @@ -1,2 +1,2 @@ CONFIG_CAVS_LPS=y -CONFIG_CAVS_LPRO=y +CONFIG_CAVS_USE_LPRO_IN_WAITI=y diff --git a/src/arch/xtensa/configs/override/tigerlake_chrome.config b/src/arch/xtensa/configs/override/tigerlake_chrome.config index fedf5820299d..d8eec7d1433d 100644 --- a/src/arch/xtensa/configs/override/tigerlake_chrome.config +++ b/src/arch/xtensa/configs/override/tigerlake_chrome.config @@ -1,3 +1,3 @@ CONFIG_CAVS_LPS=y -CONFIG_CAVS_LPRO=y CONFIG_PROBE=y +CONFIG_HAVE_AGENT=n diff --git a/src/arch/xtensa/lib/cpu.c b/src/arch/xtensa/lib/cpu.c index d6e0cfc65782..7f8e5e721361 100644 --- a/src/arch/xtensa/lib/cpu.c +++ b/src/arch/xtensa/lib/cpu.c @@ -32,7 +32,6 @@ extern struct core_context *core_ctx_ptr[PLATFORM_CORE_COUNT]; extern struct xtos_core_data *core_data_ptr[PLATFORM_CORE_COUNT]; static uint32_t active_cores_mask; -static int dsp_sref[PLATFORM_CORE_COUNT]; /**< simple ref counter */ #if CONFIG_NO_SLAVE_CORE_ROM extern void *shared_vecbase_ptr; @@ -82,7 +81,7 @@ int arch_cpu_enable_core(int id) pm_runtime_get(CORE_MEMORY_POW, id); /* Power up slave core */ - pm_runtime_get(PM_RUNTIME_DSP, id); + pm_runtime_get(PM_RUNTIME_DSP, PWRD_BY_TPLG | id); /* allocate resources for core */ cpu_alloc_core_context(id); @@ -104,7 +103,6 @@ int arch_cpu_enable_core(int id) active_cores_mask |= (1 << id); } - ++dsp_sref[id]; return 0; } @@ -114,8 +112,7 @@ void arch_cpu_disable_core(int id) struct idc_msg power_down = { IDC_MSG_POWER_DOWN, IDC_MSG_POWER_DOWN_EXT, id }; - --dsp_sref[id]; - if (arch_cpu_is_core_enabled(id) && dsp_sref[id] == 0) { + if (arch_cpu_is_core_enabled(id)) { idc_send_msg(&power_down, IDC_NON_BLOCKING); active_cores_mask ^= (1 << id); @@ -177,7 +174,7 @@ void cpu_power_down_core(void) /* Turn off stack memory for core */ pm_runtime_put(CORE_MEMORY_POW, cpu_get_id()); - pm_runtime_put(PM_RUNTIME_DSP, cpu_get_id()); + pm_runtime_put(PM_RUNTIME_DSP, PWRD_BY_TPLG | cpu_get_id()); /* arch_wait_for_interrupt() not used, because it will cause panic. * This code is executed on irq lvl > 0, which is expected. diff --git a/src/audio/dai.c b/src/audio/dai.c index b2a7e9419704..108b40368844 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -689,12 +689,6 @@ static int dai_copy(struct comp_dev *dev) src_samples = avail_bytes / get_sample_bytes(dd->frame_fmt); sink_samples = audio_stream_get_free_samples(&buf->stream); samples = MIN(src_samples, sink_samples); - - /* limit bytes per copy to one period for the whole pipeline - * in order to avoid high load spike - */ - samples = MIN(samples, dd->period_bytes / - get_sample_bytes(dd->frame_fmt)); } copy_bytes = samples * get_sample_bytes(dd->frame_fmt); diff --git a/src/audio/detect_test.c b/src/audio/detect_test.c index 6dd9684a5b68..9e2031988e23 100644 --- a/src/audio/detect_test.c +++ b/src/audio/detect_test.c @@ -33,15 +33,14 @@ #include #define ACTIVATION_DEFAULT_SHIFT 3 -#define ACTIVATION_DEFAULT_DIVIDER_S16 0.5 -#define ACTIVATION_DEFAULT_DIVIDER_S24 0.05 +#define ACTIVATION_DEFAULT_COEF 0.05 #define ACTIVATION_DEFAULT_THRESHOLD_S16 \ - ((int16_t)((INT16_MAX) * (ACTIVATION_DEFAULT_DIVIDER_S16))) + Q_CONVERT_FLOAT(ACTIVATION_DEFAULT_COEF, 15) /* Q1.15 */ #define ACTIVATION_DEFAULT_THRESHOLD_S24 \ - ((int32_t)((INT24_MAXVALUE) * (ACTIVATION_DEFAULT_DIVIDER_S24))) + Q_CONVERT_FLOAT(ACTIVATION_DEFAULT_COEF, 23) /* Q1.23 */ #define ACTIVATION_DEFAULT_THRESHOLD_S32 \ - ACTIVATION_DEFAULT_THRESHOLD_S24 + Q_CONVERT_FLOAT(ACTIVATION_DEFAULT_COEF, 31) /* Q1.31 */ #define INITIAL_MODEL_DATA_SIZE 64 @@ -384,6 +383,9 @@ static int test_keyword_params(struct comp_dev *dev, cd->keyphrase_samples = KEYPHRASE_DEFAULT_PREAMBLE_LENGTH; } + cd->config.activation_threshold = + test_keyword_get_threshold(dev, params->sample_valid_bytes * 8); + return 0; } diff --git a/src/drivers/intel/hda/hda-dma.c b/src/drivers/intel/hda/hda-dma.c index 0a3ad0797dea..a35fc8e27fb3 100644 --- a/src/drivers/intel/hda/hda-dma.c +++ b/src/drivers/intel/hda/hda-dma.c @@ -221,18 +221,6 @@ static void hda_dma_get_dbg_vals(struct dma_chan_data *chan, #define hda_dma_ptr_trace(...) #endif -static void hda_dma_l1_entry_notify(void *arg, enum notify_id type, void *data) -{ - /* Notify about Host DMA usage */ - pm_runtime_get(PM_RUNTIME_HOST_DMA_L1, 0); -} - -static void hda_dma_l1_exit_notify(void *arg, enum notify_id type, void *data) -{ - /* Force Host DMA to exit L1 */ - pm_runtime_put(PM_RUNTIME_HOST_DMA_L1, 0); -} - static inline int hda_dma_is_buffer_full(struct dma_chan_data *chan) { return dma_chan_reg_read(chan, DGCS) & DGCS_BF; @@ -293,7 +281,6 @@ static int hda_dma_wait_for_buffer_empty(struct dma_chan_data *chan) static void hda_dma_post_copy(struct dma_chan_data *chan, int bytes) { - struct hda_chan_data *hda_chan = dma_chan_get_data(chan); struct dma_cb_data next = { .channel = chan, .elem = { .size = bytes }, @@ -309,9 +296,8 @@ static void hda_dma_post_copy(struct dma_chan_data *chan, int bytes) */ hda_dma_inc_fp(chan, bytes); - /* Force Host DMA to exit L1 if scheduled on DMA */ - if (!hda_chan->irq_disabled) - pm_runtime_put(PM_RUNTIME_HOST_DMA_L1, 0); + /* Force Host DMA to exit L1 */ + pm_runtime_put(PM_RUNTIME_HOST_DMA_L1, 0); } else { /* * set BFPI to let link gateway know we have read size, @@ -336,60 +322,10 @@ static int hda_dma_link_copy_ch(struct dma_chan_data *chan, int bytes) return 0; } -static int hda_dma_host_start(struct dma_chan_data *channel) -{ - struct hda_chan_data *hda_chan = dma_chan_get_data(channel); - int ret = 0; - - /* Force Host DMA to exit L1 only on start*/ - if (!(hda_chan->state & HDA_STATE_RELEASE)) - pm_runtime_put(PM_RUNTIME_HOST_DMA_L1, 0); - - if (!hda_chan->irq_disabled) - return ret; - - /* Inform about Host DMA usage */ - ret = notifier_register(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER), - NOTIFIER_ID_LL_PRE_RUN, hda_dma_l1_entry_notify, - NOTIFIER_FLAG_AGGREGATE); - if (ret < 0) - tr_err(&hdma_tr, "hda-dmac: %d channel %d, cannot register notification %d", - channel->dma->plat_data.id, channel->index, - ret); - - /* Register common L1 exit for all channels */ - ret = notifier_register(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER), - NOTIFIER_ID_LL_POST_RUN, hda_dma_l1_exit_notify, - NOTIFIER_FLAG_AGGREGATE); - if (ret < 0) - tr_err(&hdma_tr, "hda-dmac: %d channel %d, cannot register notification %d", - channel->dma->plat_data.id, channel->index, - ret); - - return ret; -} - -static void hda_dma_host_stop(struct dma_chan_data *channel) -{ - struct hda_chan_data *hda_chan = dma_chan_get_data(channel); - - if (!hda_chan->irq_disabled) - return; - - /* Unregister L1 entry */ - notifier_unregister(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER), - NOTIFIER_ID_LL_PRE_RUN); - - /* Unregister L1 exit */ - notifier_unregister(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER), - NOTIFIER_ID_LL_POST_RUN); -} - /* lock should be held by caller */ static int hda_dma_enable_unlock(struct dma_chan_data *channel) { struct hda_chan_data *hda_chan; - int ret; tr_info(&hdma_tr, "hda-dmac: %d channel %d -> enable", channel->dma->plat_data.id, channel->index); @@ -404,14 +340,6 @@ static int hda_dma_enable_unlock(struct dma_chan_data *channel) hda_chan = dma_chan_get_data(channel); hda_chan->desc_avail = channel->desc_count; - if (channel->direction == DMA_DIR_HMEM_TO_LMEM || - channel->direction == DMA_DIR_LMEM_TO_HMEM) { - pm_runtime_get(PM_RUNTIME_HOST_DMA_L1, 0); - ret = hda_dma_host_start(channel); - if (ret < 0) - return ret; - } - /* start link output transfer now */ if (channel->direction == DMA_DIR_MEM_TO_DEV && !(hda_chan->state & HDA_STATE_RELEASE)) @@ -436,7 +364,6 @@ static int hda_dma_link_copy(struct dma_chan_data *channel, int bytes, static int hda_dma_host_copy(struct dma_chan_data *channel, int bytes, uint32_t flags) { - struct hda_chan_data *hda_chan = dma_chan_get_data(channel); int ret; tr_dbg(&hdma_tr, "hda-dmac: %d channel %d -> copy 0x%x bytes", @@ -445,8 +372,7 @@ static int hda_dma_host_copy(struct dma_chan_data *channel, int bytes, hda_dma_get_dbg_vals(channel, HDA_DBG_PRE, HDA_DBG_HOST); /* Register Host DMA usage */ - if (!hda_chan->irq_disabled) - pm_runtime_get(PM_RUNTIME_HOST_DMA_L1, 0); + pm_runtime_get(PM_RUNTIME_HOST_DMA_L1, 0); /* blocking mode copy */ if (flags & DMA_COPY_BLOCKING) { @@ -580,10 +506,6 @@ static int hda_dma_release(struct dma_chan_data *channel) */ hda_chan->state |= HDA_STATE_RELEASE; - if (channel->direction == DMA_DIR_HMEM_TO_LMEM || - channel->direction == DMA_DIR_LMEM_TO_HMEM) - ret = hda_dma_host_start(channel); - irq_local_enable(flags); return ret; } @@ -622,10 +544,6 @@ static int hda_dma_stop(struct dma_chan_data *channel) tr_info(&hdma_tr, "hda-dmac: %d channel %d -> stop", channel->dma->plat_data.id, channel->index); - if (channel->direction == DMA_DIR_HMEM_TO_LMEM || - channel->direction == DMA_DIR_LMEM_TO_HMEM) - hda_dma_host_stop(channel); - /* disable the channel */ dma_chan_reg_update_bits(channel, DGCS, DGCS_GEN | DGCS_FIFORDY, 0); channel->status = COMP_STATE_PREPARE; diff --git a/src/lib/agent.c b/src/lib/agent.c index e13eae2e396d..2c1125c4f03e 100644 --- a/src/lib/agent.c +++ b/src/lib/agent.c @@ -66,7 +66,7 @@ static enum task_state validate(void *data) /* warning timeout */ if (delta > sa->warn_timeout) tr_warn(&sa_tr, "validate(), ll drift detected, delta = %u", - delta); + (uint32_t)delta); /* update last_check to current */ sa->last_check = current; diff --git a/src/platform/Kconfig b/src/platform/Kconfig index 940610717c2d..c27506ac5ffa 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -296,17 +296,9 @@ config CAVS_LPS This option is required to support S0ix/D0ix mode on cAVS platforms. -config CAVS_LPRO - bool "Enable low power ring oscillator as the default clock" - default n - depends on CAVS && !CAVS_VERSION_1_5 - help - Select if you want to use 120MHz LPRO as the DSP clock source. - This option is required to support S0ix/D0ix mode. - config CAVS_USE_LPRO_IN_WAITI bool - default n + default y depends on CAVS select WAKEUP_HOOK help diff --git a/src/platform/cannonlake/include/platform/lib/clk.h b/src/platform/cannonlake/include/platform/lib/clk.h index 61fbbd53fa55..eb39bb31f549 100644 --- a/src/platform/cannonlake/include/platform/lib/clk.h +++ b/src/platform/cannonlake/include/platform/lib/clk.h @@ -20,11 +20,7 @@ #define CPU_HPRO_FREQ_IDX 1 -#if CONFIG_CAVS_LPRO -#define CPU_DEFAULT_IDX CPU_LPRO_FREQ_IDX -#else #define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX -#endif #define SSP_DEFAULT_IDX 0 diff --git a/src/platform/intel/cavs/include/cavs/lib/clk.h b/src/platform/intel/cavs/include/cavs/lib/clk.h index 459d84847b11..ec83f09fc221 100644 --- a/src/platform/intel/cavs/include/cavs/lib/clk.h +++ b/src/platform/intel/cavs/include/cavs/lib/clk.h @@ -43,11 +43,15 @@ extern const uint32_t cpu_freq_status_mask[]; void platform_clock_init(struct sof *sof); +void platform_clock_waiti_entry(void); +void platform_clock_waiti_exit(void); + #if CONFIG_CAVS_USE_LPRO_IN_WAITI -void platform_clock_on_waiti(void); void platform_clock_on_wakeup(void); #endif +void platform_set_active_clock(int index); + #endif /* __CAVS_LIB_CLK_H__ */ #else diff --git a/src/platform/intel/cavs/include/cavs/lib/pm_runtime.h b/src/platform/intel/cavs/include/cavs/lib/pm_runtime.h index 94e590c83271..d9db3743907e 100644 --- a/src/platform/intel/cavs/include/cavs/lib/pm_runtime.h +++ b/src/platform/intel/cavs/include/cavs/lib/pm_runtime.h @@ -16,12 +16,21 @@ #ifndef __CAVS_LIB_PM_RUNTIME_H__ #define __CAVS_LIB_PM_RUNTIME_H__ +/** + * \brief extra pwr flag to power up a core with a specific reason + * it can be powered down only with the same reason (flag) + */ +#define PWRD_MASK MASK(31, 30) +#define PWRD_BY_HPRO BIT(31) /**< requested by HPRO */ +#define PWRD_BY_TPLG BIT(30) /**< typical power up */ + struct pm_runtime_data; /** \brief cAVS specific runtime power management data. */ struct cavs_pm_runtime_data { int dsp_d0_sref; /**< simple ref counter, accessed by core 0 only */ int host_dma_l1_sref; /**< ref counter for Host DMA accesses */ + int dsp_client_bitmap[PLATFORM_CORE_COUNT]; /**< simple pwr override */ }; #endif diff --git a/src/platform/intel/cavs/lib/clk.c b/src/platform/intel/cavs/lib/clk.c index f2e4433b0348..6fc07ed98d8b 100644 --- a/src/platform/intel/cavs/lib/clk.c +++ b/src/platform/intel/cavs/lib/clk.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -32,7 +33,7 @@ static inline void select_cpu_clock(int freq_idx, bool release_unused) #if CONFIG_TIGERLAKE if (freq_idx == CPU_HPRO_FREQ_IDX) - cpu_enable_core(PLATFORM_CORE_COUNT - 1); + pm_runtime_get(PM_RUNTIME_DSP, PWRD_BY_HPRO | (PLATFORM_CORE_COUNT - 1)); #endif /* request clock */ @@ -55,7 +56,7 @@ static inline void select_cpu_clock(int freq_idx, bool release_unused) ~SHIM_CLKCTL_OSC_REQUEST_MASK) | enc); #if CONFIG_TIGERLAKE if (freq_idx != CPU_HPRO_FREQ_IDX) - cpu_disable_core(PLATFORM_CORE_COUNT - 1); + pm_runtime_put(PM_RUNTIME_DSP, PWRD_BY_HPRO | (PLATFORM_CORE_COUNT - 1)); #endif } } @@ -67,10 +68,7 @@ static int clock_platform_set_cpu_freq(int clock, int freq_idx) return 0; } -#if CONFIG_CAVS_USE_LPRO_IN_WAITI -/* Store clock source that was active before going to waiti, - * so it can be restored on wake up. - */ +/* Clock source to be used when not waiting for an interrupt. */ static SHARED_DATA int active_freq_idx = CPU_DEFAULT_IDX; static inline int get_cpu_current_freq_idx(void) @@ -92,6 +90,7 @@ static inline void set_cpu_current_freq_idx(int freq_idx) sizeof(*clk_info) * PLATFORM_CORE_COUNT); } +#if CONFIG_CAVS_USE_LPRO_IN_WAITI void platform_clock_on_wakeup(void) { int freq_idx = *cache_to_uncache(&active_freq_idx); @@ -101,24 +100,70 @@ void platform_clock_on_wakeup(void) set_cpu_current_freq_idx(freq_idx); } } +#endif -void platform_clock_on_waiti(void) +void platform_clock_waiti_entry(void) { - int freq_idx = get_cpu_current_freq_idx(); + int freq_idx; + int target_idx; + + /* update the active clock according to the pm runtime state */ + if (*cache_to_uncache(&active_freq_idx) != CPU_LPRO_FREQ_IDX && + !pm_runtime_is_active(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID)) + platform_set_active_clock(CPU_LPRO_FREQ_IDX); + else if (*cache_to_uncache(&active_freq_idx) != CPU_HPRO_FREQ_IDX && + pm_runtime_is_active(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID)) + platform_set_active_clock(CPU_HPRO_FREQ_IDX); + + freq_idx = get_cpu_current_freq_idx(); + +#if CONFIG_CAVS_USE_LPRO_IN_WAITI + target_idx = CPU_LPRO_FREQ_IDX; + /* store the cpu freq_idx */ *cache_to_uncache(&active_freq_idx) = freq_idx; +#else + target_idx = *cache_to_uncache(&active_freq_idx); +#endif - if (freq_idx != CPU_LPRO_FREQ_IDX) { + if (freq_idx != target_idx) { /* LPRO requests are fast, but requests for other ROs * can take a lot of time. That's why it's better to * not release active clock just for waiti, * so they can be switched without delay on wake up. */ - select_cpu_clock(CPU_LPRO_FREQ_IDX, false); - set_cpu_current_freq_idx(CPU_LPRO_FREQ_IDX); + select_cpu_clock(target_idx, false); + set_cpu_current_freq_idx(target_idx); } } -#endif + +void platform_clock_waiti_exit(void) +{ + int current_idx = get_cpu_current_freq_idx(); + int target_idx = *cache_to_uncache(&active_freq_idx); + + /* restore the active cpu freq_idx */ + if (current_idx != target_idx) { + /* LPRO requests are fast, but requests for other ROs + * can take a lot of time. That's why it's better to + * not release active clock just for waiti, + * so they can be switched without delay on wake up. + */ + select_cpu_clock(target_idx, false); + set_cpu_current_freq_idx(target_idx); + } +} + +void platform_set_active_clock(int index) +{ + if (*cache_to_uncache(&active_freq_idx) == index) + return; + + select_cpu_clock(index, true); + set_cpu_current_freq_idx(index); + + *cache_to_uncache(&active_freq_idx) = index; +} void platform_clock_init(struct sof *sof) { diff --git a/src/platform/intel/cavs/lib/pm_runtime.c b/src/platform/intel/cavs/lib/pm_runtime.c index ea56e4722ff9..165595135d51 100644 --- a/src/platform/intel/cavs/lib/pm_runtime.c +++ b/src/platform/intel/cavs/lib/pm_runtime.c @@ -340,7 +340,12 @@ static inline void cavs_pm_runtime_core_en_memory(uint32_t index) static inline void cavs_pm_runtime_dis_dsp_pg(uint32_t index) { #if CAVS_VERSION >= CAVS_VERSION_1_8 + struct pm_runtime_data *prd = pm_runtime_data_get(); + struct cavs_pm_runtime_data *pprd = prd->platform_data; uint32_t lps_ctl, tries = PLATFORM_PM_RUNTIME_DSP_TRIES; + uint32_t flag = PWRD_MASK & index; + + index &= ~(PWRD_MASK); if (index == PLATFORM_MASTER_CORE_ID) { lps_ctl = shim_read(SHIM_LPSCTL); @@ -368,6 +373,7 @@ static inline void cavs_pm_runtime_dis_dsp_pg(uint32_t index) if (tries == 0) tr_err(&power_tr, "cavs_pm_runtime_dis_dsp_pg(): failed to power up core %d", index); + pprd->dsp_client_bitmap[index] |= flag; } #endif } @@ -375,7 +381,12 @@ static inline void cavs_pm_runtime_dis_dsp_pg(uint32_t index) static inline void cavs_pm_runtime_en_dsp_pg(uint32_t index) { #if CAVS_VERSION >= CAVS_VERSION_1_8 + struct pm_runtime_data *prd = pm_runtime_data_get(); + struct cavs_pm_runtime_data *pprd = prd->platform_data; uint32_t lps_ctl; + uint32_t flag = PWRD_MASK & index; + + index &= ~(PWRD_MASK); if (index == PLATFORM_MASTER_CORE_ID) { lps_ctl = shim_read(SHIM_LPSCTL); @@ -389,8 +400,11 @@ static inline void cavs_pm_runtime_en_dsp_pg(uint32_t index) lps_ctl &= ~SHIM_LPSCTL_FDSPRUN; shim_write(SHIM_LPSCTL, lps_ctl); } else { - shim_write16(SHIM_PWRCTL, shim_read16(SHIM_PWRCTL) & - ~SHIM_PWRCTL_TCPDSPPG(index)); + pprd->dsp_client_bitmap[index] &= ~(flag); + + if (pprd->dsp_client_bitmap[index] == 0) + shim_write16(SHIM_PWRCTL, shim_read16(SHIM_PWRCTL) & + ~SHIM_PWRCTL_TCPDSPPG(index)); } #endif } diff --git a/src/platform/intel/cavs/platform.c b/src/platform/intel/cavs/platform.c index 14afc8b3ff51..08cc0693f3fd 100644 --- a/src/platform/intel/cavs/platform.c +++ b/src/platform/intel/cavs/platform.c @@ -146,13 +146,8 @@ EXT_MAN_PORT( #endif #if CONFIG_CANNONLAKE || CONFIG_ICELAKE || CONFIG_TIGERLAKE -#if CONFIG_CAVS_LPRO -#define CAVS_DEFAULT_RO SHIM_CLKCTL_RLROSCC -#define CAVS_DEFAULT_RO_FOR_MEM SHIM_CLKCTL_OCS_LP_RING -#else -#define CAVS_DEFAULT_RO SHIM_CLKCTL_RHROSCC -#define CAVS_DEFAULT_RO_FOR_MEM SHIM_CLKCTL_OCS_HP_RING -#endif +#define CAVS_ROS (SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_RLROSCC) +#define CAVS_ROS_FOR_MEM (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_OCS_LP_RING) #endif #if CONFIG_DW_GPIO @@ -296,10 +291,6 @@ int platform_boot_complete(uint32_t boot_message) { uint32_t mb_offset = 0; -#if CONFIG_TIGERLAKE && !CONFIG_CAVS_LPRO - cpu_enable_core(PLATFORM_CORE_COUNT - 1); -#endif - mailbox_dspbox_write(mb_offset, &ready, sizeof(ready)); mb_offset = mb_offset + sizeof(ready); @@ -432,17 +423,19 @@ int platform_init(struct sof *sof) #elif CONFIG_CANNONLAKE || CONFIG_ICELAKE || CONFIG_TIGERLAKE /* initialize PM for boot */ - +#if CONFIG_TIGERLAKE + pm_runtime_get(PM_RUNTIME_DSP, PWRD_BY_HPRO | (PLATFORM_CORE_COUNT - 1)); +#endif /* request configured ring oscillator and wait for status ready */ - shim_write(SHIM_CLKCTL, shim_read(SHIM_CLKCTL) | CAVS_DEFAULT_RO); - while (!(shim_read(SHIM_CLKSTS) & CAVS_DEFAULT_RO)) + shim_write(SHIM_CLKCTL, shim_read(SHIM_CLKCTL) | CAVS_ROS); + while (!((shim_read(SHIM_CLKSTS) & CAVS_ROS) == CAVS_ROS)) idelay(16); shim_write(SHIM_CLKCTL, - CAVS_DEFAULT_RO | /* Request configured RING Osc */ - CAVS_DEFAULT_RO_FOR_MEM | /* Select configured - * RING Oscillator Clk for memory - */ + CAVS_ROS | /* Request configured RING Osc */ + CAVS_ROS_FOR_MEM | /* Select configured + * RING Oscillator Clk for memory + */ SHIM_CLKCTL_HMCS_DIV2 | /* HP mem clock div by 2 */ SHIM_CLKCTL_LMCS_DIV4 | /* LP mem clock div by 4 */ SHIM_CLKCTL_TCPLCG_DIS_ALL); /* Allow Local Clk Gating */ @@ -453,7 +446,9 @@ int platform_init(struct sof *sof) /* prevent DSP Common power gating */ pm_runtime_get(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID); - +#if CONFIG_TIGERLAKE && CONFIG_CAVS_LPRO + pm_runtime_put(PM_RUNTIME_DSP, PWRD_BY_HPRO | (PLATFORM_CORE_COUNT - 1)); +#endif #elif CONFIG_SUECREEK /* TODO: need to merge as for APL */ clock_set_freq(CLK_CPU(cpu_get_id()), CLK_MAX_CPU_HZ); @@ -530,9 +525,8 @@ int platform_init(struct sof *sof) void platform_wait_for_interrupt(int level) { -#if CONFIG_CAVS_USE_LPRO_IN_WAITI - platform_clock_on_waiti(); -#endif + platform_clock_waiti_entry(); + #if (CONFIG_CAVS_LPS) if (pm_runtime_is_active(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID)) arch_wait_for_interrupt(level); @@ -541,4 +535,6 @@ void platform_wait_for_interrupt(int level) #else arch_wait_for_interrupt(level); #endif + + platform_clock_waiti_exit(); } diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index 6d2db4219d66..e46dac371ff3 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -172,9 +172,11 @@ static void schedule_ll_tasks_run(void *data) /* TODO: no need for atomic operations, * already protected by spin_lock */ - num_clients = atomic_sub(&sch->domain->num_clients, 1); - if (!num_clients) - domain_clear(sch->domain); + if (atomic_read(&sch->domain->num_clients)) { + num_clients = atomic_sub(&sch->domain->num_clients, 1); + if (!num_clients) + domain_clear(sch->domain); + } platform_shared_commit(sch->domain, sizeof(*sch->domain)); diff --git a/src/schedule/timer_domain.c b/src/schedule/timer_domain.c index fe74fa2d9e04..edb71d388134 100644 --- a/src/schedule/timer_domain.c +++ b/src/schedule/timer_domain.c @@ -31,8 +31,8 @@ static inline void timer_report_delay(int id, uint64_t delay) uint32_t ll_delay_us = (delay * 1000) / clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1); - tr_err(&ll_tr, "timer_report_delay(): timer %d delayed by %d uS %d ticks", - id, ll_delay_us, delay); + tr_err(&ll_tr, "timer_report_delay(): timer %d delayed by %d uS %u ticks", + id, ll_delay_us, (uint32_t)delay); /* Fix compile error when traces are disabled */ (void)ll_delay_us; diff --git a/tools/topology/sof-smart-amplifier.m4 b/tools/topology/sof-smart-amplifier.m4 index 593b5afa2a37..07aa8b56837c 100644 --- a/tools/topology/sof-smart-amplifier.m4 +++ b/tools/topology/sof-smart-amplifier.m4 @@ -222,7 +222,7 @@ DAI_CONFIG(ALH, eval(SMART_ALH_INDEX + 1), eval(SMART_BE_ID + 1), SMART_ALH_CAPT #SSP SSP_INDEX (ID: SMART_BE_ID) DAI_CONFIG(SSP, SMART_SSP_INDEX, SMART_BE_ID, SMART_SSP_NAME, SSP_CONFIG(DSP_B, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 9600000, codec_slave), + SSP_CLOCK(bclk, 12288000, codec_slave), SSP_CLOCK(fsync, 48000, codec_slave), SSP_TDM(8, 25, 15, 255), SSP_CONFIG_DATA(SSP, SMART_SSP_INDEX, 24, 0, SMART_SSP_QUIRK))) diff --git a/tools/topology/sof-tgl-max98357a-rt5682.m4 b/tools/topology/sof-tgl-max98357a-rt5682.m4 index 77b48288c576..4f7036e350c0 100644 --- a/tools/topology/sof-tgl-max98357a-rt5682.m4 +++ b/tools/topology/sof-tgl-max98357a-rt5682.m4 @@ -192,14 +192,14 @@ SectionGraph."PIPE_CAP_VIRT" { DAI_ADD(sof/pipe-dai-playback.m4, 2, SSP, 0, SSP0-Codec, PIPELINE_SOURCE_2, 2, s24le, - 1000, 0, 0) + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) # capture DAI is SSP0 using 2 periods # Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 DAI_ADD(sof/pipe-dai-capture.m4, 3, SSP, 0, SSP0-Codec, PIPELINE_SINK_3, 2, s24le, - 1000, 0, 0) + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) # playback DAI is iDisp1 using 2 periods # Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0