From 68c84c7b346bd8ee0055c6142142579b8947957f Mon Sep 17 00:00:00 2001 From: Paul Olaru Date: Fri, 22 Nov 2019 13:19:09 +0200 Subject: [PATCH 01/37] sof: lib: notifier: Do not break build on platforms without CLK_SSP Some platforms do not have a SSP clock, so a dummy define for CLK_SSP and related macros shouldn't be required to exist in order for the firmware to build. Signed-off-by: Paul Olaru --- src/include/sof/lib/notifier.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/include/sof/lib/notifier.h b/src/include/sof/lib/notifier.h index 8301b1ddd46e..45fc5efdab06 100644 --- a/src/include/sof/lib/notifier.h +++ b/src/include/sof/lib/notifier.h @@ -45,8 +45,12 @@ struct notifier { void (*cb)(int message, void *cb_data, void *event_data); }; +#if defined(CLK_SSP) && defined(NOTIFIER_ID_SSP_FREQ) #define NOTIFIER_CLK_CHANGE_ID(clk) \ ((clk) == CLK_SSP ? NOTIFIER_ID_SSP_FREQ : NOTIFIER_ID_CPU_FREQ) +#else +#define NOTIFIER_CLK_CHANGE_ID(clk) NOTIFIER_ID_CPU_FREQ +#endif struct notify **arch_notify_get(void); From 551fa115499a58a38467134c3d505e918f01761b Mon Sep 17 00:00:00 2001 From: Marcin Maka Date: Fri, 22 Nov 2019 19:59:48 +0100 Subject: [PATCH 02/37] pm: cavs: fix literal dcache lock in power down Compiler options has to be changed in order to compute the literal block address correctly. Some literals must be declared explicitly and loaded indirectly to make sure that compiler does not optimize the out to another shared region. Signed-off-by: Marcin Maka --- .../include/cavs/lib/asm_memory_management.h | 5 +++-- src/platform/intel/cavs/lib/CMakeLists.txt | 8 +++++++- src/platform/intel/cavs/lib/power_down.S | 17 ++++++++++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/platform/intel/cavs/include/cavs/lib/asm_memory_management.h b/src/platform/intel/cavs/include/cavs/lib/asm_memory_management.h index 4d1929b2926e..05a32a88fa06 100644 --- a/src/platform/intel/cavs/include/cavs/lib/asm_memory_management.h +++ b/src/platform/intel/cavs/include/cavs/lib/asm_memory_management.h @@ -63,14 +63,15 @@ bne \ax, \mask, 1b .endm -.macro m_cavs_lpsram_power_down_entire ax, ay, az +.macro m_cavs_lpsram_power_down_entire ax, ay, az, loop_cnt_addr movi \az, LSPGISTS movi \ax, LSPGCTL movi \ay, LPSRAM_MASK() s32i \ay, \ax, 0 memw // assumed that HDA shared dma buffer will be in LPSRAM - movi \ax, 4096 + movi \ax, \loop_cnt_addr + l32i \ax, \ax, 0 1 : addi \ax, \ax, -1 bnez \ax, 1b diff --git a/src/platform/intel/cavs/lib/CMakeLists.txt b/src/platform/intel/cavs/lib/CMakeLists.txt index b57285b54573..1ed93d8bf39a 100644 --- a/src/platform/intel/cavs/lib/CMakeLists.txt +++ b/src/platform/intel/cavs/lib/CMakeLists.txt @@ -1,5 +1,12 @@ # SPDX-License-Identifier: BSD-3-Clause +add_library(pdown STATIC "") +target_link_libraries(pdown sof_options) +target_compile_options(pdown PRIVATE -mtext-section-literals) + +add_local_sources(pdown power_down.S) +target_link_libraries(sof_static_libraries INTERFACE pdown) + add_local_sources(sof clk.c dai.c @@ -7,7 +14,6 @@ add_local_sources(sof memory.c pm_runtime.c pm_memory.c - power_down.S ) if(CONFIG_MEM_WND) diff --git a/src/platform/intel/cavs/lib/power_down.S b/src/platform/intel/cavs/lib/power_down.S index c23724c91c54..35c03da4d1a2 100644 --- a/src/platform/intel/cavs/lib/power_down.S +++ b/src/platform/intel/cavs/lib/power_down.S @@ -23,10 +23,16 @@ .section .text, "ax" .align 64 -literals: +power_down_literals: .literal_position +ipc_flag: + .word IPC_DIPCTDR_BUSY +sram_dis_loop_cnt: + .word 4096 + .global power_down .type power_down, @function + /** * Perform power down. * @@ -52,7 +58,7 @@ power_down: // xthal_dcache_region_lock(&literals, 128); // xthal_dcache_region_lock(&powerdown, 256); // xthal_dcache_region_lock(&pu32_hpsram_mask, 64); - movi pfl_reg, literals + movi pfl_reg, power_down_literals dpfl pfl_reg, 0 dpfl pfl_reg, 64 @@ -72,7 +78,8 @@ _PD_DISABLE_LPSRAM: * } */ beqz b_enable_lpsram, _PD_DISABLE_HPSRAM - m_cavs_lpsram_power_down_entire temp_reg0, temp_reg1, temp_reg2 + m_cavs_lpsram_power_down_entire temp_reg0, temp_reg1, temp_reg2,\ + sram_dis_loop_cnt j _PD_DISABLE_HPSRAM _PD_DISABLE_HPSRAM: @@ -132,12 +139,12 @@ _PD_SEND_IPC: */ movi temp_reg0, IPC_HOST_BASE l32i temp_reg1, temp_reg0, IPC_DIPCTDR - movi temp_reg2, IPC_DIPCTDR_BUSY + movi temp_reg2, ipc_flag + l32i temp_reg2, temp_reg2, 0 or temp_reg1, temp_reg1, temp_reg2 s32i temp_reg1, temp_reg0, IPC_DIPCTDR l32i temp_reg1, temp_reg0, IPC_DIPCTDA - movi temp_reg2, IPC_DIPCTDA_DONE or temp_reg1, temp_reg1, temp_reg2 s32i temp_reg1, temp_reg0, IPC_DIPCTDA From 66c3784e164873a273256d9c1b4a07295dad7865 Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Fri, 15 Nov 2019 07:57:54 +0200 Subject: [PATCH 03/37] topology: intel-generic-dmic.m4: fix dai parameters Fix errorneous parameters in DAI_ADD. Signed-off-by: Jaska Uimonen --- tools/topology/platform/intel/intel-generic-dmic.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/topology/platform/intel/intel-generic-dmic.m4 b/tools/topology/platform/intel/intel-generic-dmic.m4 index 31dd7fa61b30..125300b070f5 100644 --- a/tools/topology/platform/intel/intel-generic-dmic.m4 +++ b/tools/topology/platform/intel/intel-generic-dmic.m4 @@ -46,14 +46,14 @@ dnl deadline, priority, core, time_domain) DAI_ADD(sof/pipe-dai-capture.m4, DMIC_PIPELINE_48k_ID, DMIC, 0, dmic01, concat(`PIPELINE_SINK_', DMIC_PIPELINE_48k_ID), 2, s32le, - 1000, 0, 0, 48000, 48000, 48000) + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) # capture DAI is DMIC 1 using 2 periods # Buffers use s32le format, with 16 frame per 1000us on core 0 with priority 0 DAI_ADD(sof/pipe-dai-capture.m4, DMIC_PIPELINE_16k_ID, DMIC, 1, dmic16k, concat(`PIPELINE_SINK_', DMIC_PIPELINE_16k_ID), 2, s32le, - 1000, 0, 0, 16000, 16000, 16000) + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) dnl PCM_CAPTURE_ADD(name, pipeline, capture) From ccd09c1e949638c4d67597c19a5a0a0c2c213300 Mon Sep 17 00:00:00 2001 From: Guido Roncarolo Date: Mon, 25 Nov 2019 16:37:02 +0100 Subject: [PATCH 04/37] drivers: imx: sai: fix minor log issue Correct log verbosity in SAI driver Signed-off-by: Guido Roncarolo Signed-off-by: Jerome Laclavere --- src/drivers/imx/sai.c | 2 +- src/include/sof/drivers/sai.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/imx/sai.c b/src/drivers/imx/sai.c index d4f3413133a2..dd7a55e37e4c 100644 --- a/src/drivers/imx/sai.c +++ b/src/drivers/imx/sai.c @@ -21,7 +21,7 @@ static void sai_start(struct dai *dai, int direction) { - tracev_sai("SAI: sai_start"); + trace_sai("SAI: sai_start"); dai_update_bits(dai, REG_SAI_XCSR(direction), REG_SAI_CSR_FRDE, REG_SAI_CSR_FRDE); diff --git a/src/include/sof/drivers/sai.h b/src/include/sof/drivers/sai.h index 66954462cd04..18f8a06d67f0 100644 --- a/src/include/sof/drivers/sai.h +++ b/src/include/sof/drivers/sai.h @@ -233,7 +233,7 @@ #define SAI_TDM_SLOTS 2 extern const struct dai_driver sai_driver; -#define trace_sai(format, ...) tracev_event(TRACE_CLASS_DAI, format, \ +#define trace_sai(format, ...) trace_event(TRACE_CLASS_DAI, format, \ ##__VA_ARGS__) #define tracev_sai(format, ...) tracev_event(TRACE_CLASS_DAI, format, \ ##__VA_ARGS__) From 6d53f054f56bbfbd332fd0fad03d97ad32fc81fc Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Thu, 31 Oct 2019 16:39:31 +0800 Subject: [PATCH 05/37] arch: string: enable vec_memcpy only with HIFI3 xcc HIFI2 do not vec_memcpy, we can only use vec_memcpy on HIFI3 supported platforms. Signed-off-by: Pan Xiuli --- src/arch/xtensa/include/arch/string.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arch/xtensa/include/arch/string.h b/src/arch/xtensa/include/arch/string.h index 8474245fbfc7..11c55452b643 100644 --- a/src/arch/xtensa/include/arch/string.h +++ b/src/arch/xtensa/include/arch/string.h @@ -36,7 +36,7 @@ int memset_s(void *dest, size_t dest_size, int memcpy_s(void *dest, size_t dest_size, const void *src, size_t src_size); -#if __XCC__ && !CONFIG_LIBRARY +#if __XCC__ && XCHAL_HAVE_HIFI3 && !CONFIG_LIBRARY void *__vec_memcpy(void *dst, const void *src, size_t len); void *__vec_memset(void *dest, int data, size_t src_size); #endif @@ -54,7 +54,7 @@ static inline int arch_memcpy_s(void *dest, size_t dest_size, if (src_size > dest_size) return -EINVAL; -#if __XCC__ && !CONFIG_LIBRARY +#if __XCC__ && XCHAL_HAVE_HIFI3 && !CONFIG_LIBRARY __vec_memcpy(dest, src, src_size); #else memcpy(dest, src, src_size); @@ -72,7 +72,7 @@ static inline int arch_memset_s(void *dest, size_t dest_size, if (count > dest_size) return -EINVAL; -#if __XCC__ && !CONFIG_LIBRARY +#if __XCC__ && XCHAL_HAVE_HIFI3 && !CONFIG_LIBRARY if (!__vec_memset(dest, data, count)) return -ENOMEM; #else From d7581cbf3c7b348684efc7262da359e31cfc0a7d Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Thu, 31 Oct 2019 16:41:22 +0800 Subject: [PATCH 06/37] haswell: fix _memmap_vecbase_reset address Use SOF_MEM_VECBASE_TEXT_BASE to repalce unset variable. Signed-off-by: Pan Xiuli --- src/platform/haswell/haswell.x.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/haswell/haswell.x.in b/src/platform/haswell/haswell.x.in index 2d8d7530d9f7..8ff8618d5bb2 100644 --- a/src/platform/haswell/haswell.x.in +++ b/src/platform/haswell/haswell.x.in @@ -156,7 +156,7 @@ ENTRY(_ResetVector) _rom_store_table = 0; /* ABI0 does not use Window base */ -PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR); +PROVIDE(_memmap_vecbase_reset = SOF_MEM_VECBASE_TEXT_BASE); /* Various memory-map dependent cache attribute settings: */ _memmap_cacheattr_wb_base = 0x44024000; From c821f9ea39745a7286ca480e08aeb9905f2072ba Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Thu, 31 Oct 2019 17:41:49 +0800 Subject: [PATCH 07/37] memory: modify bootloader for xcc build xcc build will have bigger TEXT. Need to keep the total block size unchange as the block need to be 4k align. Signed-off-by: Pan Xiuli --- src/platform/suecreek/include/platform/lib/memory.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platform/suecreek/include/platform/lib/memory.h b/src/platform/suecreek/include/platform/lib/memory.h index 523d7c79ca20..6b50977ade97 100644 --- a/src/platform/suecreek/include/platform/lib/memory.h +++ b/src/platform/suecreek/include/platform/lib/memory.h @@ -382,12 +382,12 @@ /* code loader */ #define BOOT_LDR_TEXT_ENTRY_BASE (BOOT_LDR_MANIFEST_BASE + \ BOOT_LDR_MANIFEST_SIZE) -#define BOOT_LDR_TEXT_ENTRY_SIZE 0x400 +#define BOOT_LDR_TEXT_ENTRY_SIZE 0x200 #define BOOT_LDR_LIT_BASE (BOOT_LDR_TEXT_ENTRY_BASE + \ BOOT_LDR_TEXT_ENTRY_SIZE) -#define BOOT_LDR_LIT_SIZE 0x400 +#define BOOT_LDR_LIT_SIZE 0x200 #define BOOT_LDR_TEXT_BASE (BOOT_LDR_LIT_BASE + BOOT_LDR_LIT_SIZE) -#define BOOT_LDR_TEXT_SIZE 0x800 +#define BOOT_LDR_TEXT_SIZE 0xC00 #define BOOT_LDR_DATA_BASE (BOOT_LDR_TEXT_BASE + \ BOOT_LDR_TEXT_SIZE) #define BOOT_LDR_DATA_SIZE 0x1000 From 9c90af86cd800817f6814e065d551c44c557f6c1 Mon Sep 17 00:00:00 2001 From: Paul Olaru Date: Tue, 26 Nov 2019 15:07:02 +0200 Subject: [PATCH 08/37] sof: clk: Remove specificity on clock notifier change ID The previous version changes behavior on the BYT platform. Fixes: ee9283c159 ("sof: lib: notifier: Do not break build on platforms without CLK_SSP"). Signed-off-by: Paul Olaru --- src/include/sof/lib/notifier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/sof/lib/notifier.h b/src/include/sof/lib/notifier.h index 45fc5efdab06..4514ded49695 100644 --- a/src/include/sof/lib/notifier.h +++ b/src/include/sof/lib/notifier.h @@ -45,7 +45,7 @@ struct notifier { void (*cb)(int message, void *cb_data, void *event_data); }; -#if defined(CLK_SSP) && defined(NOTIFIER_ID_SSP_FREQ) +#ifdef CLK_SSP #define NOTIFIER_CLK_CHANGE_ID(clk) \ ((clk) == CLK_SSP ? NOTIFIER_ID_SSP_FREQ : NOTIFIER_ID_CPU_FREQ) #else From 39de2721c3ddd79f9ef07d898ac68aa62e492eac Mon Sep 17 00:00:00 2001 From: WojciechX Wittbrodt Date: Thu, 28 Nov 2019 10:25:37 +0100 Subject: [PATCH 09/37] Topology: Fix DAI_ADD function call in sof-cml-rt1011-rt5682 topology This patch fixes DAI_ADD function call for speaker pipeline. The function call had incorrect number of agruments passed which was causing issues with playback. Signed-off-by: WojciechX Wittbrodt --- tools/topology/sof-cml-rt1011-rt5682.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/topology/sof-cml-rt1011-rt5682.m4 b/tools/topology/sof-cml-rt1011-rt5682.m4 index d9be8532a129..0201829ef179 100644 --- a/tools/topology/sof-cml-rt1011-rt5682.m4 +++ b/tools/topology/sof-cml-rt1011-rt5682.m4 @@ -40,7 +40,7 @@ dnl deadline, priority, core, time_domain) DAI_ADD(sof/pipe-dai-playback.m4, 7, SSP, 1, SSP1-Codec, PIPELINE_SOURCE_7, 2, s24le, - 48, 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) # PCM Low Latency, id 0 dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) From 93b84ec16c9c228741cd3d605713b539def367ce Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Fri, 6 Dec 2019 11:38:31 +0100 Subject: [PATCH 10/37] alloc: invalidate uncached memory Invalidates memory regions, which are requested to be uncached. This way we can make sure we won't overwrite data by accident. Signed-off-by: Tomasz Lauda --- src/lib/alloc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 47cc2f449a33..8bd7b9d8af36 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -195,8 +195,10 @@ static void *rmalloc_sys(int zone, int caps, int core, size_t bytes) dcache_writeback_invalidate_region(cpu_heap, sizeof(*cpu_heap)); - if ((zone & RZONE_FLAG_MASK) == RZONE_FLAG_UNCACHED) + if ((zone & RZONE_FLAG_MASK) == RZONE_FLAG_UNCACHED) { + dcache_invalidate_region(ptr, bytes); ptr = cache_to_uncache(ptr); + } return ptr; } @@ -427,8 +429,10 @@ static void *get_ptr_from_heap(struct mm_heap *heap, int zone, uint32_t caps, break; } - if (ptr && (zone & RZONE_FLAG_MASK) == RZONE_FLAG_UNCACHED) + if (ptr && (zone & RZONE_FLAG_MASK) == RZONE_FLAG_UNCACHED) { + dcache_invalidate_region(ptr, bytes); ptr = cache_to_uncache(ptr); + } return ptr; } @@ -777,8 +781,10 @@ static void *alloc_heap_buffer(struct mm_heap *heap, int zone, uint32_t caps, } } - if (ptr && ((zone & RZONE_FLAG_MASK) == RZONE_FLAG_UNCACHED)) + if (ptr && ((zone & RZONE_FLAG_MASK) == RZONE_FLAG_UNCACHED)) { + dcache_invalidate_region(ptr, bytes); ptr = cache_to_uncache(ptr); + } #if CONFIG_DEBUG_BLOCK_FREE if (ptr) From 4243192a29a03cdc66ae2687c4a8bb046b0d3eda Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Wed, 11 Dec 2019 16:52:06 +0100 Subject: [PATCH 11/37] alloc: fix modulo zero bug Fixes modulo bug in get_ptr_from_heap function, where alignment can potentially be 0. Modulo zero is undefined operation. Signed-off-by: Tomasz Lauda --- src/lib/alloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 8bd7b9d8af36..eea1cef4be92 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -407,8 +407,9 @@ static void *get_ptr_from_heap(struct mm_heap *heap, int zone, uint32_t caps, * we check if first free block is already aligned if not * we need to allocate bigger size for alignment */ - if ((map->base + (map->block_size * map->first_free)) - % alignment) + if (alignment && + ((map->base + (map->block_size * map->first_free)) % + alignment)) temp_bytes += alignment; /* is block big enough */ From 0f24dd2604ecc58f653a969cae44165f1fe6817f Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Wed, 11 Dec 2019 16:42:11 +0200 Subject: [PATCH 12/37] Volume: Fix handling of mute and unmute control This patch fixes the issue of audio left muted after a cycle of mute and unmute commands. The additional improvements are applying of gain ramp for mute that helps to avoid annoying click sounds. Also since the driver issues both volume and switch commands back to back the duplicate scheduling of ramp update is prevented if there is already a ramp happening. The old ramp will operate based on new step and direction if it was changed. Some variable names were changed in function volume_set_chan() for better readability. The impacted trace print commands were also updated to not split strings unnecessarily. Signed-off-by: Seppo Ingalsuo --- src/audio/volume/volume.c | 106 +++++++++++++++++++-------------- src/include/sof/audio/volume.h | 2 + 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index 3816b4de8cc7..b1a39426acec 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -81,6 +81,8 @@ static enum task_state vol_work(void *data) int again = 0; int i; + cd->vol_ramp_active = true; + /* inc/dec each volume if it's not at target */ for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) { /* skip if target reached */ @@ -96,6 +98,7 @@ static enum task_state vol_work(void *data) /* ramp up, check if ramp completed */ if (vol >= cd->tvolume[i] || vol >= cd->vol_max) { vol_update(cd, i); + cd->ramp_increment[i] = 0; } else { cd->volume[i] = vol; again = 1; @@ -105,11 +108,13 @@ static enum task_state vol_work(void *data) if (vol <= 0) { /* cannot ramp down below 0 */ vol_update(cd, i); + cd->ramp_increment[i] = 0; } else { /* ramp completed ? */ if (vol <= cd->tvolume[i] || vol <= cd->vol_min) { vol_update(cd, i); + cd->ramp_increment[i] = 0; } else { cd->volume[i] = vol; again = 1; @@ -122,7 +127,11 @@ static enum task_state vol_work(void *data) } /* do we need to continue ramping */ - return again ? SOF_TASK_STATE_RESCHEDULE : SOF_TASK_STATE_COMPLETED; + if (again) + return SOF_TASK_STATE_RESCHEDULE; + + cd->vol_ramp_active = 0; + return SOF_TASK_STATE_COMPLETED; } /** @@ -212,9 +221,12 @@ static struct comp_dev *volume_new(struct sof_ipc_comp *comp) for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) { cd->volume[i] = MAX(MIN(cd->vol_max, VOL_ZERO_DB), cd->vol_min); - cd->tvolume[i] = cd->volume[i]; + cd->tvolume[i] = cd->volume[i]; + cd->mvolume[i] = cd->volume[i]; + cd->muted[i] = false; } + cd->vol_ramp_active = false; trace_volume_with_ids(dev, "vol->initial_ramp = %d, vol->ramp = %d, " "vol->min_value = %d, vol->max_value = %d", @@ -359,10 +371,11 @@ static inline void volume_set_chan_mute(struct comp_dev *dev, int chan) { struct comp_data *cd = comp_get_drvdata(dev); - /* Check if not muted already */ - if (cd->volume[chan] != 0) - cd->mvolume[chan] = cd->volume[chan]; - cd->tvolume[chan] = 0; + if (!cd->muted[chan]) { + cd->mvolume[chan] = cd->tvolume[chan]; + volume_set_chan(dev, chan, 0); + cd->muted[chan] = true; + } } /** @@ -374,9 +387,10 @@ static inline void volume_set_chan_unmute(struct comp_dev *dev, int chan) { struct comp_data *cd = comp_get_drvdata(dev); - /* Check if muted */ - if (cd->volume[chan] == 0) - cd->tvolume[chan] = cd->mvolume[chan]; + if (cd->muted[chan]) { + cd->muted[chan] = false; + volume_set_chan(dev, chan, cd->mvolume[chan]); + } } /** @@ -389,7 +403,8 @@ static int volume_ctrl_set_cmd(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata) { struct comp_data *cd = comp_get_drvdata(dev); - int i; + uint32_t val; + int ch; int j; int ret = 0; @@ -407,29 +422,29 @@ static int volume_ctrl_set_cmd(struct comp_dev *dev, "cdata->comp_id = %u", cdata->comp_id); for (j = 0; j < cdata->num_elems; j++) { - trace_volume_with_ids(dev, "volume_ctrl_set_cmd(), " - "SOF_CTRL_CMD_VOLUME, " - "channel = %u, value = %u", - cdata->chanv[j].channel, - cdata->chanv[j].value); - i = cdata->chanv[j].channel; - if (i >= 0 && i < SOF_IPC_MAX_CHANNELS) { - ret = volume_set_chan(dev, i, - cdata->chanv[j].value); - } else { + ch = cdata->chanv[j].channel; + val = cdata->chanv[j].value; + trace_volume_with_ids(dev, "volume_ctrl_set_cmd(), channel = %d" + ", value = %u", ch, val); + if (ch < 0 || ch >= SOF_IPC_MAX_CHANNELS) { trace_volume_error_with_ids(dev, - "volume_ctrl_set_cmd() " - "error: " - "SOF_CTRL_CMD_VOLUME, " - "invalid i = %u", - i); + "volume_ctrl_set_cmd(), illegal channel = %d", + ch); + return -EINVAL; + } + + if (cd->muted[ch]) { + cd->mvolume[ch] = val; + } else { + ret = volume_set_chan(dev, ch, val); + if (ret) + return ret; } - if (ret) - return ret; } - schedule_task(&cd->volwork, VOL_RAMP_UPDATE_US, - VOL_RAMP_UPDATE_US); + if (!cd->vol_ramp_active) + schedule_task(&cd->volwork, VOL_RAMP_UPDATE_US, + VOL_RAMP_UPDATE_US); break; case SOF_CTRL_CMD_SWITCH: @@ -437,27 +452,26 @@ static int volume_ctrl_set_cmd(struct comp_dev *dev, "SOF_CTRL_CMD_SWITCH, " "cdata->comp_id = %u", cdata->comp_id); for (j = 0; j < cdata->num_elems; j++) { - trace_volume_with_ids(dev, "volume_ctrl_set_cmd(), " - "SOF_CTRL_CMD_SWITCH, " - "channel = %u, value = %u", - cdata->chanv[j].channel, - cdata->chanv[j].value); - i = cdata->chanv[j].channel; - if (i >= 0 && i < SOF_IPC_MAX_CHANNELS) { - if (cdata->chanv[j].value) - volume_set_chan_unmute(dev, i); - else - volume_set_chan_mute(dev, i); - } else { + ch = cdata->chanv[j].channel; + val = cdata->chanv[j].value; + trace_volume_with_ids(dev, "volume_ctrl_set_cmd(), channel = %d" + ", value = %u", ch, val); + if (ch < 0 || ch >= SOF_IPC_MAX_CHANNELS) { trace_volume_error_with_ids(dev, - "volume_ctrl_set_cmd() error: " - "SOF_CTRL_CMD_SWITCH, invalid i = %u", - i); + "volume_ctrl_set_cmd(), illegal channel = %d", + ch); + return -EINVAL; } + + if (val) + volume_set_chan_unmute(dev, ch); + else + volume_set_chan_mute(dev, ch); } - schedule_task(&cd->volwork, VOL_RAMP_UPDATE_US, - VOL_RAMP_UPDATE_US); + if (!cd->vol_ramp_active) + schedule_task(&cd->volwork, VOL_RAMP_UPDATE_US, + VOL_RAMP_UPDATE_US); break; default: diff --git a/src/include/sof/audio/volume.h b/src/include/sof/audio/volume.h index 819bb46f28a6..50f3102b6e21 100644 --- a/src/include/sof/audio/volume.h +++ b/src/include/sof/audio/volume.h @@ -112,6 +112,8 @@ struct comp_data { int32_t vol_ramp_range; /**< max ramp transition */ enum sof_ipc_frame source_format; /**< source frame format */ enum sof_ipc_frame sink_format; /**< sink frame format */ + bool muted[SOF_IPC_MAX_CHANNELS]; /**< set if channel is muted */ + bool vol_ramp_active; /**< set if volume is ramped */ /**< volume processing function */ void (*scale_vol)(struct comp_dev *dev, struct comp_buffer *sink, struct comp_buffer *source, uint32_t frames); From 7013662a267936914bff3f5701c94d3be22a0d0c Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Wed, 27 Nov 2019 12:41:50 -0800 Subject: [PATCH 13/37] platform: cht: reset ssp clk M/N dividers on boot The firmware may have modified these values to execute features such as a boot beep. Therefore we cannot assume they are set to their defaults. Lets write the defaults just to be safe. Fixes #1847 Signed-off-by: Curtis Malainey --- src/platform/baytrail/platform.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index d14072bd79c0..bc6ef5ae468e 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -241,6 +241,22 @@ int platform_init(struct sof *sof) shim_write(SHIM_PIMRH, shim_read(SHIM_PIMRH) | 0x00000700); #endif + /* Reset M/N SSP clock dividers */ + shim_write(SHIM_SSP0_DIVL, 1); + shim_write(SHIM_SSP0_DIVH, 0x80000001); + shim_write(SHIM_SSP1_DIVL, 1); + shim_write(SHIM_SSP1_DIVH, 0x80000001); + shim_write(SHIM_SSP2_DIVL, 1); + shim_write(SHIM_SSP2_DIVH, 0x80000001); +#if defined CONFIG_CHERRYTRAIL + shim_write(SHIM_SSP3_DIVL, 1); + shim_write(SHIM_SSP3_DIVH, 0x80000001); + shim_write(SHIM_SSP4_DIVL, 1); + shim_write(SHIM_SSP4_DIVH, 0x80000001); + shim_write(SHIM_SSP5_DIVL, 1); + shim_write(SHIM_SSP5_DIVH, 0x80000001); +#endif + /* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP); ssp0 = dai_get(SOF_DAI_INTEL_SSP, 0, DAI_CREAT); From 1b5398e171ad5a4fb67b659b82551d21c2faaff1 Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Tue, 10 Dec 2019 17:24:23 +0800 Subject: [PATCH 14/37] platform: bdw: fix bdw DMA timer BDW DMAC0 can not be used with scheduler and no-one used it. The DMA chan is not initiated and may cause DSP hang when read null point. Skip the DMAC0 to avoid such issue. Signed-off-by: Tomasz Lauda Signed-off-by: Pan Xiuli --- src/platform/haswell/include/platform/drivers/dw-dma.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/haswell/include/platform/drivers/dw-dma.h b/src/platform/haswell/include/platform/drivers/dw-dma.h index 1af7b880ce77..c42ce8ecc645 100644 --- a/src/platform/haswell/include/platform/drivers/dw-dma.h +++ b/src/platform/haswell/include/platform/drivers/dw-dma.h @@ -16,11 +16,11 @@ struct dma; struct dma_chan_data; -/* number of supported DW-DMACs */ -#define PLATFORM_NUM_DW_DMACS 2 +/* number of supported DW-DMACs (DMAC0 is not related with SSP)*/ +#define PLATFORM_NUM_DW_DMACS 1 -/* index of the first DW-DMAC in the array */ -#define PLATFORM_DW_DMA_INDEX 0 +/* index of the first DW-DMAC in the array (DMAC0 is not related with SSP)*/ +#define PLATFORM_DW_DMA_INDEX 1 /* DMA treats PHY addresses as host address unless within DSP region */ #define PLATFORM_DW_DMA_HOST_MASK 0xFFF00000 From e305697a487ea23527d12d779eb0d59141b43edc Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Tue, 10 Dec 2019 17:31:56 +0800 Subject: [PATCH 15/37] platform: bdw: fix SSP clock setting SSP clock on BDW is 24MHz. Signed-off-by: Pan Xiuli --- src/platform/haswell/platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c index 0fcf3d08fc55..e3fefde20587 100644 --- a/src/platform/haswell/platform.c +++ b/src/platform/haswell/platform.c @@ -202,9 +202,9 @@ int platform_init(struct sof *sof) trace_point(TRACE_BOOT_PLATFORM_CPU_FREQ); clock_set_freq(CLK_CPU(cpu_get_id()), CLK_MAX_CPU_HZ); - /* set SSP clock to 25M */ + /* set SSP clock to 24M */ trace_point(TRACE_BOOT_PLATFORM_SSP_FREQ); - clock_set_freq(CLK_SSP, 25000000); + clock_set_freq(CLK_SSP, 24000000); /* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); From 9f57fb14f39ecbcccc5176fe94b2fff6dccc6797 Mon Sep 17 00:00:00 2001 From: Dragos Tarcatu Date: Mon, 16 Dec 2019 18:33:06 +0200 Subject: [PATCH 16/37] gdb: ringbuffer: Fix void pointer arithmetic If CONFIG_GDB_DEBUG is set, the build is currently failing because of these void pointer arithmentic operations. This patch fixes that. Signed-off-by: Dragos Tarcatu --- src/debug/gdb/ringbuffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debug/gdb/ringbuffer.c b/src/debug/gdb/ringbuffer.c index 1f03ba1f25c7..b0ab91414d99 100644 --- a/src/debug/gdb/ringbuffer.c +++ b/src/debug/gdb/ringbuffer.c @@ -10,9 +10,9 @@ #define BUFFER_OFFSET 0x120 volatile struct ring * const rx = (void *) SRAM_DEBUG_BASE; -volatile struct ring * const tx = (void *) SRAM_DEBUG_BASE + BUFFER_OFFSET; -volatile struct ring * const debug = (void *) SRAM_DEBUG_BASE + - (2*BUFFER_OFFSET); +volatile struct ring * const tx = (void *)(SRAM_DEBUG_BASE + BUFFER_OFFSET); +volatile struct ring * const debug = (void *)(SRAM_DEBUG_BASE + + (2 * BUFFER_OFFSET)); void init_buffers(void) { From 9eda078ae8647dd148ac19d53ecfca4cb5061012 Mon Sep 17 00:00:00 2001 From: Dragos Tarcatu Date: Mon, 16 Dec 2019 19:36:24 +0200 Subject: [PATCH 17/37] cmake: Use correct config option for GDB_DEBUG If CONFIG_GDB_DEBUG is set, the build fails at link time because of undefined references to arch_gdb_memory_load_and_store, arch_gdb_load_from_memory, gdb_debug_info, and several others. Fix that by replacing CONFIG_GDB with CONFIG_GDB_DEBUG. Signed-off-by: Dragos Tarcatu --- src/arch/xtensa/debug/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/xtensa/debug/CMakeLists.txt b/src/arch/xtensa/debug/CMakeLists.txt index 919d344b5fe4..2148cd3bd201 100644 --- a/src/arch/xtensa/debug/CMakeLists.txt +++ b/src/arch/xtensa/debug/CMakeLists.txt @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -if (CONFIG_GDB) +if (CONFIG_GDB_DEBUG) add_subdirectory(gdb) endif() From 9ddadf6e8a11dc83b1364bc10c03b01eb5207589 Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Tue, 17 Dec 2019 16:33:30 +0100 Subject: [PATCH 18/37] eq_iir: set iir_delay pointer to NULL when freed Sets iir_delay pointer to NULL when freed to prevent attempts to free the buffer multiple times. Signed-off-by: Tomasz Lauda --- src/audio/eq_iir/eq_iir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 904b094d1268..0557540a2961 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -379,6 +379,7 @@ static void eq_iir_free_delaylines(struct comp_data *cd) * each IIR channel delay line to NULL. */ rfree(cd->iir_delay); + cd->iir_delay = NULL; cd->iir_delay_size = 0; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) iir[i].delay = NULL; From dca78870097f2205e5d16893e5dbce3595add0ab Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Tue, 17 Dec 2019 16:35:50 +0100 Subject: [PATCH 19/37] eq_fir: set fir_delay pointer to NULL when freed Sets fir_delay pointer to NULL when freed to prevent attempts to free the buffer multiple times. Signed-off-by: Tomasz Lauda --- src/audio/eq_fir/eq_fir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index 4069f728d05a..6b9f8fdcfc71 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -273,6 +273,7 @@ static void eq_fir_free_delaylines(struct comp_data *cd) * each FIR channel delay line to NULL. */ rfree(cd->fir_delay); + cd->fir_delay = NULL; cd->fir_delay_size = 0; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) fir[i].delay = NULL; From 96a6b0760ca349428ece10dfb54eda83f476edd3 Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Tue, 17 Dec 2019 13:29:14 +0100 Subject: [PATCH 20/37] ll_schedule: fix task insertion Fixes low latency task insertion into the priority list. Tasks should be inserted into the list from the highest to the lowest priority. Tasks with the same priority should be served on a first-come-first-serve basis. Note that the list_item_append method, which is used to insert task into the list is a bit misleading, since it normally should work on list's head instead of any element from the list. This piece of code should be revisited in the future and proper list_item_insert method should be implemented and used. Signed-off-by: Tomasz Lauda --- src/schedule/ll_schedule.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index 743d567aa870..d35c5994e2ab 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -221,10 +221,13 @@ static void schedule_ll_task_insert(struct task *task, struct list_item *tasks) struct list_item *tlist; struct task *curr_task; - /* tasks are added into the list in order */ + /* tasks are added into the list from highest to lowest priority + * and tasks with the same priority should be served on + * a first-come-first-serve basis + */ list_for_item(tlist, tasks) { curr_task = container_of(tlist, struct task, list); - if (task->priority <= curr_task->priority) { + if (task->priority < curr_task->priority) { list_item_append(&task->list, &curr_task->list); return; } From 5023ab4233c0a4435f06cfb866e91f7cf4f046cb Mon Sep 17 00:00:00 2001 From: Paul Olaru Date: Fri, 20 Dec 2019 16:27:46 +0200 Subject: [PATCH 21/37] alloc: Fix bug in handling first_free member of the block map That field is intended to point to the first free block of this particular block map (part of heap). As long as the heap doesn't fill up the old code manages it correctly. However once the block map becomes full (all blocks are occupied) this member will no longer point to a free block. Without this fix rfree may fail to update this pointer to point to the correct block when freeing a block from a full heap. Not updating this will cause subsequent memory allocations to hand out used blocks as if they were free. This fix ensures that will not happen in this edge case. Signed-off-by: Paul Olaru --- src/lib/alloc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index eea1cef4be92..78acd12e9366 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -447,6 +448,7 @@ static void free_block(void *ptr) int i; int block; int used_blocks; + bool heap_is_full; heap = get_heap_from_ptr(ptr); if (!heap) { @@ -499,6 +501,8 @@ static void free_block(void *ptr) if (block_map->base + block_map->block_size * block != (uint32_t)ptr) panic(SOF_IPC_PANIC_MEM); + heap_is_full = !block_map->free_count; + /* free block header and continuous blocks */ used_blocks = block + hdr->size; @@ -513,7 +517,7 @@ static void free_block(void *ptr) } /* set first free block */ - if (block < block_map->first_free) + if (block < block_map->first_free || heap_is_full) block_map->first_free = block; writeback_block_map(block_map); From 917d75e9b27b29201517aa3efaf072149741510a Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Tue, 7 Jan 2020 14:25:00 +0100 Subject: [PATCH 22/37] cmake: version: consider unannotated tags Command git describe looks only for annotated tags, but we should get any tag reachable from master, that's why --tags flag is needed. Signed-off-by: Janusz Jankowski --- scripts/cmake/version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cmake/version.cmake b/scripts/cmake/version.cmake index bb57986073b5..719cfd9852e1 100644 --- a/scripts/cmake/version.cmake +++ b/scripts/cmake/version.cmake @@ -21,7 +21,7 @@ if(EXISTS ${TARBALL_VERSION_SOURCE_PATH}) message(STATUS "Found ${TARBALL_VERSION_FILE_NAME}") message(STATUS "Version: ${GIT_TAG} / ${GIT_LOG_HASH}") else() - execute_process(COMMAND git describe --abbrev=4 + execute_process(COMMAND git describe --tags --abbrev=4 OUTPUT_VARIABLE GIT_TAG OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET From 1c6009703454a2a27109a9f7d7eb7532436abf19 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 9 Jan 2020 03:22:29 +0100 Subject: [PATCH 23/37] github: fix link to bug tracking docs Update bug form to point to new location of the document. Signed-off-by: Janusz Jankowski --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 884f8eea61b3..2ae70e8e78bb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,7 +10,7 @@ assignees: '' **Describe the bug** A clear and concise description of what the bug is. What have you tried to diagnose or workaround this issue? -Please also read https://thesofproject.github.io/latest/howtos/process/bug-tracking.html for further information on submitting bugs. +Please also read https://thesofproject.github.io/latest/contribute/process/bug-tracking.html for further information on submitting bugs. **To Reproduce** Steps to reproduce the behavior: (e.g. list commands or actions used to reproduce the bug) From 66a5ae978df83195ee1c82bdec5bb5180dbdbb69 Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Thu, 19 Dec 2019 14:13:06 +0100 Subject: [PATCH 24/37] sof: align sof structure to cache line size Aligns sof structure to cache line size. It is needed in order to assure that no data will be randomly overwritten by cache eviction with multicore access. Signed-off-by: Tomasz Lauda --- src/include/sof/sof.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/include/sof/sof.h b/src/include/sof/sof.h index f7438d612f59..dcb3a4c4395c 100644 --- a/src/include/sof/sof.h +++ b/src/include/sof/sof.h @@ -9,12 +9,20 @@ #define __SOF_SOF_H__ #include +#include +#include struct dma_trace_data; struct ipc; struct sa; -/* general firmware context */ +/** + * \brief General firmware context. + * This structure holds all the global pointers, which can potentially + * be accessed by SMP code, hence it should be aligned to platform's + * data cache line size. Alignments in the both beginning and end are needed + * to avoid potential before and after data evictions. + */ struct sof { /* init data */ int argc; @@ -28,6 +36,8 @@ struct sof { /* DMA for Trace*/ struct dma_trace_data *dmat; -}; + + __aligned(PLATFORM_DCACHE_ALIGN) int alignment[0]; +} __aligned(PLATFORM_DCACHE_ALIGN); #endif /* __SOF_SOF_H__ */ From 61577dc16b6e40e9ec9dfd46e37f196487931a69 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:33:05 +0200 Subject: [PATCH 25/37] cannonlake: shim: clock status registers Add registers for checking clock status. Signed-off-by: Janusz Jankowski --- .../cannonlake/include/platform/lib/shim.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/platform/cannonlake/include/platform/lib/shim.h b/src/platform/cannonlake/include/platform/lib/shim.h index 7e56d594c0a5..815fe6b1af2b 100644 --- a/src/platform/cannonlake/include/platform/lib/shim.h +++ b/src/platform/cannonlake/include/platform/lib/shim.h @@ -113,9 +113,6 @@ /** \brief Clock control */ #define SHIM_CLKCTL 0x78 -/** \brief Clock status */ -#define SHIM_CLKSTS 0x7C - /** \brief Request HP RING Oscillator Clock */ #define SHIM_CLKCTL_RHROSCC BIT(31) @@ -147,6 +144,18 @@ #define SHIM_CLKCTL_HMCS_DIV2 0 #define SHIM_CLKCTL_HMCS_DIV4 BIT(0) +/** \brief Clock status */ +#define SHIM_CLKSTS 0x7C + +/** \brief HP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_HROSCCS BIT(31) + +/** \brief XTAL Oscillator Clock Status */ +#define SHIM_CLKSTS_XOSCCS BIT(30) + +/** \brief LP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_LROSCCS BIT(29) + #define SHIM_PWRCTL 0x90 #define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) #define SHIM_PWRCTL_TCPCTLPG BIT(4) From 47f3601860a793cd5026b1b7e6e0b71b93f31332 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:35:24 +0200 Subject: [PATCH 26/37] cannonlake: shim: clock control registers Add missing registers for requesting clock changes. Signed-off-by: Janusz Jankowski --- src/platform/cannonlake/include/platform/lib/shim.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/platform/cannonlake/include/platform/lib/shim.h b/src/platform/cannonlake/include/platform/lib/shim.h index 815fe6b1af2b..2423c0304b03 100644 --- a/src/platform/cannonlake/include/platform/lib/shim.h +++ b/src/platform/cannonlake/include/platform/lib/shim.h @@ -144,6 +144,18 @@ #define SHIM_CLKCTL_HMCS_DIV2 0 #define SHIM_CLKCTL_HMCS_DIV4 BIT(0) +/** \brief Mask for requesting clock + */ +#define SHIM_CLKCTL_OSC_REQUEST_MASK \ + (SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_RXOSCC | \ + SHIM_CLKCTL_RLROSCC) + +/** \brief Mask for setting previously requested clock + */ +#define SHIM_CLKCTL_OSC_SOURCE_MASK \ + (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_LMCS_DIV4 | \ + SHIM_CLKCTL_HMCS_DIV4) + /** \brief Clock status */ #define SHIM_CLKSTS 0x7C From ec4cb78134e3da7000a7bf217d2bf1b3abf62050 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:47:26 +0200 Subject: [PATCH 27/37] suecreek: shim: clock control registers Add registers for requesting clocks. Signed-off-by: Janusz Jankowski --- .../suecreek/include/platform/lib/shim.h | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/platform/suecreek/include/platform/lib/shim.h b/src/platform/suecreek/include/platform/lib/shim.h index 9fe736592526..4c0b3f5fcb80 100644 --- a/src/platform/suecreek/include/platform/lib/shim.h +++ b/src/platform/suecreek/include/platform/lib/shim.h @@ -110,19 +110,29 @@ #define SHIM_DSPWCTCS_T1A (0x1 << 1) /* Timer 1 armed */ #define SHIM_DSPWCTCS_T0A (0x1 << 0) /* Timer 0 armed */ +/** \brief Clock control */ #define SHIM_CLKCTL 0x78 -#define SHIM_CLKSTS 0x7C -#define SHIM_PWRCTL 0x90 -#define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) -#define SHIM_PWRCTL_TCPCTLPG BIT(4) +/** \brief Request HP RING Oscillator Clock */ +#define SHIM_CLKCTL_RHROSCC BIT(31) -#define SHIM_PWRSTS 0x92 +/** \brief Request XTAL Oscillator Clock */ +#define SHIM_CLKCTL_RXOSCC BIT(30) -#define SHIM_LPSCTL 0x94 -#define SHIM_LPSCTL_BID BIT(7) -#define SHIM_LPSCTL_FDSPRUN BIT(9) -#define SHIM_LPSCTL_BATTR_0 BIT(12) +/** \brief Request LP RING Oscillator Clock */ +#define SHIM_CLKCTL_RLROSCC BIT(29) + +/** \brief Oscillator Clock Select*/ +#define SHIM_CLKCTL_OCS_HP_RING BIT(2) +#define SHIM_CLKCTL_OCS_LP_RING 0 + +/** \brief LP Memory Clock Select */ +#define SHIM_CLKCTL_LMCS_DIV2 0 +#define SHIM_CLKCTL_LMCS_DIV4 BIT(1) + +/** \brief HP Memory Clock Select */ +#define SHIM_CLKCTL_HMCS_DIV2 0 +#define SHIM_CLKCTL_HMCS_DIV4 BIT(0) /* LP GPDMA Force Dynamic Clock Gating bits, 0--enable */ #define SHIM_CLKCTL_TCPLCG(x) (0x1 << (16 + x)) @@ -142,6 +152,31 @@ /* HP memory clock PLL divisor */ #define SHIM_CLKCTL_HPMPCS (0x1 << 0) +/** \brief Mask for requesting clock + */ +#define SHIM_CLKCTL_OSC_REQUEST_MASK \ + (SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_RXOSCC | \ + SHIM_CLKCTL_RLROSCC) + +/** \brief Mask for setting previously requested clock + */ +#define SHIM_CLKCTL_OSC_SOURCE_MASK \ + (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_LMCS_DIV4 | \ + SHIM_CLKCTL_HMCS_DIV4) + +#define SHIM_CLKSTS 0x7C + +#define SHIM_PWRCTL 0x90 +#define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) +#define SHIM_PWRCTL_TCPCTLPG BIT(4) + +#define SHIM_PWRSTS 0x92 + +#define SHIM_LPSCTL 0x94 +#define SHIM_LPSCTL_BID BIT(7) +#define SHIM_LPSCTL_FDSPRUN BIT(9) +#define SHIM_LPSCTL_BATTR_0 BIT(12) + /** \brief GPDMA shim registers Control */ #define SHIM_GPDMA_BASE_OFFSET 0x6500 #define SHIM_GPDMA_BASE(x) (SHIM_GPDMA_BASE_OFFSET + (x) * 0x100) From e802a7ca95db0253ec6bf0c99997d7b936255dbe Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:48:51 +0200 Subject: [PATCH 28/37] suecreek: shim: clock status registers Add registers for checking clock status. Signed-off-by: Janusz Jankowski --- src/platform/suecreek/include/platform/lib/shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/platform/suecreek/include/platform/lib/shim.h b/src/platform/suecreek/include/platform/lib/shim.h index 4c0b3f5fcb80..67a078e9f6bc 100644 --- a/src/platform/suecreek/include/platform/lib/shim.h +++ b/src/platform/suecreek/include/platform/lib/shim.h @@ -164,8 +164,18 @@ (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_LMCS_DIV4 | \ SHIM_CLKCTL_HMCS_DIV4) +/** \brief Clock status */ #define SHIM_CLKSTS 0x7C +/** \brief HP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_HROSCCS BIT(31) + +/** \brief XTAL Oscillator Clock Status */ +#define SHIM_CLKSTS_XOSCCS BIT(30) + +/** \brief LP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_LROSCCS BIT(29) + #define SHIM_PWRCTL 0x90 #define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) #define SHIM_PWRCTL_TCPCTLPG BIT(4) From e7ea4aefa0ed2c563dc11c797c2abf91c660add9 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:51:33 +0200 Subject: [PATCH 29/37] icelake: shim: clock control registers Add registers for requesting clocks. Signed-off-by: Janusz Jankowski --- .../icelake/include/platform/lib/shim.h | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/platform/icelake/include/platform/lib/shim.h b/src/platform/icelake/include/platform/lib/shim.h index 3137c61dbb8a..9c401c2ff720 100644 --- a/src/platform/icelake/include/platform/lib/shim.h +++ b/src/platform/icelake/include/platform/lib/shim.h @@ -110,19 +110,29 @@ #define SHIM_DSPWCTCS_T1A (0x1 << 1) /* Timer 1 armed */ #define SHIM_DSPWCTCS_T0A (0x1 << 0) /* Timer 0 armed */ +/** \brief Clock control */ #define SHIM_CLKCTL 0x78 -#define SHIM_CLKSTS 0x7C -#define SHIM_PWRCTL 0x90 -#define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) -#define SHIM_PWRCTL_TCPCTLPG BIT(4) +/** \brief Request HP RING Oscillator Clock */ +#define SHIM_CLKCTL_RHROSCC BIT(31) -#define SHIM_PWRSTS 0x92 +/** \brief Request XTAL Oscillator Clock */ +#define SHIM_CLKCTL_RXOSCC BIT(30) -#define SHIM_LPSCTL 0x94 -#define SHIM_LPSCTL_BID BIT(7) -#define SHIM_LPSCTL_FDSPRUN BIT(9) -#define SHIM_LPSCTL_BATTR_0 BIT(12) +/** \brief Request LP RING Oscillator Clock */ +#define SHIM_CLKCTL_RLROSCC BIT(29) + +/** \brief Oscillator Clock Select*/ +#define SHIM_CLKCTL_OCS_HP_RING BIT(2) +#define SHIM_CLKCTL_OCS_LP_RING 0 + +/** \brief LP Memory Clock Select */ +#define SHIM_CLKCTL_LMCS_DIV2 0 +#define SHIM_CLKCTL_LMCS_DIV4 BIT(1) + +/** \brief HP Memory Clock Select */ +#define SHIM_CLKCTL_HMCS_DIV2 0 +#define SHIM_CLKCTL_HMCS_DIV4 BIT(0) /* LP GPDMA Force Dynamic Clock Gating bits, 0--enable */ #define SHIM_CLKCTL_TCPLCG(x) (0x1 << (16 + x)) @@ -142,6 +152,31 @@ /* HP memory clock PLL divisor */ #define SHIM_CLKCTL_HPMPCS (0x1 << 0) +/** \brief Mask for requesting clock + */ +#define SHIM_CLKCTL_OSC_REQUEST_MASK \ + (SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_RXOSCC | \ + SHIM_CLKCTL_RLROSCC) + +/** \brief Mask for setting previously requested clock + */ +#define SHIM_CLKCTL_OSC_SOURCE_MASK \ + (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_LMCS_DIV4 | \ + SHIM_CLKCTL_HMCS_DIV4) + +#define SHIM_CLKSTS 0x7C + +#define SHIM_PWRCTL 0x90 +#define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) +#define SHIM_PWRCTL_TCPCTLPG BIT(4) + +#define SHIM_PWRSTS 0x92 + +#define SHIM_LPSCTL 0x94 +#define SHIM_LPSCTL_BID BIT(7) +#define SHIM_LPSCTL_FDSPRUN BIT(9) +#define SHIM_LPSCTL_BATTR_0 BIT(12) + /** \brief GPDMA shim registers Control */ #define SHIM_GPDMA_BASE_OFFSET 0x6500 #define SHIM_GPDMA_BASE(x) (SHIM_GPDMA_BASE_OFFSET + (x) * 0x100) From a8c280def34dfb04db1c64c680be921302e275b5 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:52:48 +0200 Subject: [PATCH 30/37] icelake: shim: clock status registers Add registers for checking clock status. Signed-off-by: Janusz Jankowski --- src/platform/icelake/include/platform/lib/shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/platform/icelake/include/platform/lib/shim.h b/src/platform/icelake/include/platform/lib/shim.h index 9c401c2ff720..6b92c20fbf4f 100644 --- a/src/platform/icelake/include/platform/lib/shim.h +++ b/src/platform/icelake/include/platform/lib/shim.h @@ -164,8 +164,18 @@ (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_LMCS_DIV4 | \ SHIM_CLKCTL_HMCS_DIV4) +/** \brief Clock status */ #define SHIM_CLKSTS 0x7C +/** \brief HP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_HROSCCS BIT(31) + +/** \brief XTAL Oscillator Clock Status */ +#define SHIM_CLKSTS_XOSCCS BIT(30) + +/** \brief LP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_LROSCCS BIT(29) + #define SHIM_PWRCTL 0x90 #define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) #define SHIM_PWRCTL_TCPCTLPG BIT(4) From 7c6780064efaa83e5ae087c450f1951f708be587 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:58:05 +0200 Subject: [PATCH 31/37] tigerlake: shim: clock control registers Add registers for requesting clocks. Signed-off-by: Janusz Jankowski --- .../tigerlake/include/platform/lib/shim.h | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/platform/tigerlake/include/platform/lib/shim.h b/src/platform/tigerlake/include/platform/lib/shim.h index 69a0720dca49..10e27bcbe1c9 100644 --- a/src/platform/tigerlake/include/platform/lib/shim.h +++ b/src/platform/tigerlake/include/platform/lib/shim.h @@ -110,19 +110,29 @@ #define SHIM_DSPWCTCS_T1A (0x1 << 1) /* Timer 1 armed */ #define SHIM_DSPWCTCS_T0A (0x1 << 0) /* Timer 0 armed */ +/** \brief Clock control */ #define SHIM_CLKCTL 0x78 -#define SHIM_CLKSTS 0x7C -#define SHIM_PWRCTL 0x90 -#define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) -#define SHIM_PWRCTL_TCPCTLPG BIT(4) +/** \brief Request HP RING Oscillator Clock */ +#define SHIM_CLKCTL_RHROSCC BIT(31) -#define SHIM_PWRSTS 0x92 +/** \brief Request XTAL Oscillator Clock */ +#define SHIM_CLKCTL_RXOSCC BIT(30) -#define SHIM_LPSCTL 0x94 -#define SHIM_LPSCTL_BID BIT(7) -#define SHIM_LPSCTL_FDSPRUN BIT(9) -#define SHIM_LPSCTL_BATTR_0 BIT(12) +/** \brief Request LP RING Oscillator Clock */ +#define SHIM_CLKCTL_RLROSCC BIT(29) + +/** \brief Oscillator Clock Select*/ +#define SHIM_CLKCTL_OCS_HP_RING BIT(2) +#define SHIM_CLKCTL_OCS_LP_RING 0 + +/** \brief LP Memory Clock Select */ +#define SHIM_CLKCTL_LMCS_DIV2 0 +#define SHIM_CLKCTL_LMCS_DIV4 BIT(1) + +/** \brief HP Memory Clock Select */ +#define SHIM_CLKCTL_HMCS_DIV2 0 +#define SHIM_CLKCTL_HMCS_DIV4 BIT(0) /* LP GPDMA Force Dynamic Clock Gating bits, 0--enable */ #define SHIM_CLKCTL_TCPLCG(x) (0x1 << (16 + x)) @@ -142,6 +152,31 @@ /* HP memory clock PLL divisor */ #define SHIM_CLKCTL_HPMPCS (0x1 << 0) +/** \brief Mask for requesting clock + */ +#define SHIM_CLKCTL_OSC_REQUEST_MASK \ + (SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_RXOSCC | \ + SHIM_CLKCTL_RLROSCC) + +/** \brief Mask for setting previously requested clock + */ +#define SHIM_CLKCTL_OSC_SOURCE_MASK \ + (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_LMCS_DIV4 | \ + SHIM_CLKCTL_HMCS_DIV4) + +#define SHIM_CLKSTS 0x7C + +#define SHIM_PWRCTL 0x90 +#define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) +#define SHIM_PWRCTL_TCPCTLPG BIT(4) + +#define SHIM_PWRSTS 0x92 + +#define SHIM_LPSCTL 0x94 +#define SHIM_LPSCTL_BID BIT(7) +#define SHIM_LPSCTL_FDSPRUN BIT(9) +#define SHIM_LPSCTL_BATTR_0 BIT(12) + /** \brief GPDMA shim registers Control */ #define SHIM_GPDMA_BASE_OFFSET 0x6500 #define SHIM_GPDMA_BASE(x) (SHIM_GPDMA_BASE_OFFSET + (x) * 0x100) From 658a079fc597de921f0ee58289e6a6753484743b Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Thu, 10 Oct 2019 13:59:37 +0200 Subject: [PATCH 32/37] tigerlake: shim: clock status registers Add registers for checking clock status. Signed-off-by: Janusz Jankowski --- src/platform/tigerlake/include/platform/lib/shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/platform/tigerlake/include/platform/lib/shim.h b/src/platform/tigerlake/include/platform/lib/shim.h index 10e27bcbe1c9..c91ad703737d 100644 --- a/src/platform/tigerlake/include/platform/lib/shim.h +++ b/src/platform/tigerlake/include/platform/lib/shim.h @@ -164,8 +164,18 @@ (SHIM_CLKCTL_OCS_HP_RING | SHIM_CLKCTL_LMCS_DIV4 | \ SHIM_CLKCTL_HMCS_DIV4) +/** \brief Clock status */ #define SHIM_CLKSTS 0x7C +/** \brief HP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_HROSCCS BIT(31) + +/** \brief XTAL Oscillator Clock Status */ +#define SHIM_CLKSTS_XOSCCS BIT(30) + +/** \brief LP RING Oscillator Clock Status */ +#define SHIM_CLKSTS_LROSCCS BIT(29) + #define SHIM_PWRCTL 0x90 #define SHIM_PWRCTL_TCPDSPPG(x) BIT(x) #define SHIM_PWRCTL_TCPCTLPG BIT(4) From 8311e0c6af3d4259306cae162c9685c8b81150fa Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Tue, 3 Dec 2019 12:38:11 +0100 Subject: [PATCH 33/37] cavs: lib: check status mask in cpu clock set On some platforms clocks may not be switched instantly and f.e. there may be need to wait for clock availability before switching to it. That's why there is need for mask that is used for checking status. Signed-off-by: Janusz Jankowski --- src/platform/cannonlake/lib/clk.c | 11 ++++++++-- src/platform/icelake/lib/clk.c | 11 ++++++++-- .../intel/cavs/include/cavs/lib/clk.h | 1 + src/platform/intel/cavs/lib/clk.c | 21 ++++++++++++++++++- src/platform/suecreek/lib/clk.c | 11 ++++++++-- src/platform/tigerlake/lib/clk.c | 11 ++++++++-- 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/platform/cannonlake/lib/clk.c b/src/platform/cannonlake/lib/clk.c index 33d87f625463..648d8c92d6ea 100644 --- a/src/platform/cannonlake/lib/clk.c +++ b/src/platform/cannonlake/lib/clk.c @@ -15,8 +15,15 @@ static struct freq_table platform_cpu_freq[] = { }; uint32_t cpu_freq_enc[] = { - 0x0, - 0x4, + SHIM_CLKCTL_RLROSCC | SHIM_CLKCTL_OCS_LP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, + SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_OCS_HP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, +}; + +uint32_t cpu_freq_status_mask[] = { + SHIM_CLKSTS_LROSCCS, + SHIM_CLKSTS_HROSCCS, }; STATIC_ASSERT(NUM_CPU_FREQ == ARRAY_SIZE(platform_cpu_freq), diff --git a/src/platform/icelake/lib/clk.c b/src/platform/icelake/lib/clk.c index 3bf59ccf0508..cdd7db6334b7 100644 --- a/src/platform/icelake/lib/clk.c +++ b/src/platform/icelake/lib/clk.c @@ -15,8 +15,15 @@ static struct freq_table platform_cpu_freq[] = { }; uint32_t cpu_freq_enc[] = { - 0x0, - 0x4, + SHIM_CLKCTL_RLROSCC | SHIM_CLKCTL_OCS_LP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, + SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_OCS_HP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, +}; + +uint32_t cpu_freq_status_mask[] = { + SHIM_CLKSTS_LROSCCS, + SHIM_CLKSTS_HROSCCS, }; STATIC_ASSERT(NUM_CPU_FREQ == ARRAY_SIZE(platform_cpu_freq), diff --git a/src/platform/intel/cavs/include/cavs/lib/clk.h b/src/platform/intel/cavs/include/cavs/lib/clk.h index 542ddd92176b..031975368ef0 100644 --- a/src/platform/intel/cavs/include/cavs/lib/clk.h +++ b/src/platform/intel/cavs/include/cavs/lib/clk.h @@ -37,6 +37,7 @@ extern struct freq_table *cpu_freq; extern uint32_t cpu_freq_enc[]; +extern uint32_t cpu_freq_status_mask[]; void platform_clock_init(void); diff --git a/src/platform/intel/cavs/lib/clk.c b/src/platform/intel/cavs/lib/clk.c index 3685d98f62ad..d355e2f5ec6f 100644 --- a/src/platform/intel/cavs/lib/clk.c +++ b/src/platform/intel/cavs/lib/clk.c @@ -20,11 +20,30 @@ static int clock_platform_set_cpu_freq(int clock, int freq_idx) /* set CPU frequency request for CCU */ #if CAVS_VERSION == CAVS_VERSION_1_5 io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL, SHIM_CLKCTL_HDCS, 0); -#endif io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL, SHIM_CLKCTL_DPCS_MASK(cpu_get_id()), enc); +#else + uint32_t status_mask = cpu_freq_status_mask[freq_idx]; + + /* request clock */ + io_reg_write(SHIM_BASE + SHIM_CLKCTL, + io_reg_read(SHIM_BASE + SHIM_CLKCTL) | enc); + + /* wait for requested clock to be on */ + while ((io_reg_read(SHIM_BASE + SHIM_CLKSTS) & + status_mask) != status_mask) + idelay(PLATFORM_DEFAULT_DELAY); + /* switch to requested clock */ + io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL, + SHIM_CLKCTL_OSC_SOURCE_MASK, enc); + + /* release other clocks */ + io_reg_write(SHIM_BASE + SHIM_CLKCTL, + (io_reg_read(SHIM_BASE + SHIM_CLKCTL) & + ~SHIM_CLKCTL_OSC_REQUEST_MASK) | enc); +#endif return 0; } diff --git a/src/platform/suecreek/lib/clk.c b/src/platform/suecreek/lib/clk.c index a1dcea613d7b..a4611aaa9db9 100644 --- a/src/platform/suecreek/lib/clk.c +++ b/src/platform/suecreek/lib/clk.c @@ -15,8 +15,15 @@ static struct freq_table platform_cpu_freq[] = { }; uint32_t cpu_freq_enc[] = { - 0x0, - 0x4, + SHIM_CLKCTL_RLROSCC | SHIM_CLKCTL_OCS_LP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, + SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_OCS_HP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, +}; + +uint32_t cpu_freq_status_mask[] = { + SHIM_CLKSTS_LROSCCS, + SHIM_CLKSTS_HROSCCS, }; STATIC_ASSERT(NUM_CPU_FREQ == ARRAY_SIZE(platform_cpu_freq), diff --git a/src/platform/tigerlake/lib/clk.c b/src/platform/tigerlake/lib/clk.c index 3bf59ccf0508..cdd7db6334b7 100644 --- a/src/platform/tigerlake/lib/clk.c +++ b/src/platform/tigerlake/lib/clk.c @@ -15,8 +15,15 @@ static struct freq_table platform_cpu_freq[] = { }; uint32_t cpu_freq_enc[] = { - 0x0, - 0x4, + SHIM_CLKCTL_RLROSCC | SHIM_CLKCTL_OCS_LP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, + SHIM_CLKCTL_RHROSCC | SHIM_CLKCTL_OCS_HP_RING | + SHIM_CLKCTL_HMCS_DIV2 | SHIM_CLKCTL_LMCS_DIV4, +}; + +uint32_t cpu_freq_status_mask[] = { + SHIM_CLKSTS_LROSCCS, + SHIM_CLKSTS_HROSCCS, }; STATIC_ASSERT(NUM_CPU_FREQ == ARRAY_SIZE(platform_cpu_freq), From 5a7ef9cbb43f76c59427e440d75e1d3573ef9099 Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Thu, 19 Dec 2019 13:42:03 +0100 Subject: [PATCH 34/37] cavs: interrupt: move irq names to cavs header Moves interrupt controller names to cavs platform header. They are only used by cAVS platforms and shouldn't be generic to xtensa architecture. Signed-off-by: Tomasz Lauda --- .../xtensa/include/arch/drivers/interrupt.h | 5 ---- .../include/platform/drivers/interrupt.h | 1 + .../include/platform/drivers/interrupt.h | 1 + .../include/platform/drivers/interrupt.h | 1 + .../cavs/include/cavs/drivers/interrupt.h | 24 +++++++++++++++++++ .../include/platform/drivers/interrupt.h | 1 + .../include/platform/drivers/interrupt.h | 1 + 7 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 src/platform/intel/cavs/include/cavs/drivers/interrupt.h diff --git a/src/arch/xtensa/include/arch/drivers/interrupt.h b/src/arch/xtensa/include/arch/drivers/interrupt.h index 21d950dbcde6..10ea72103ce9 100644 --- a/src/arch/xtensa/include/arch/drivers/interrupt.h +++ b/src/arch/xtensa/include/arch/drivers/interrupt.h @@ -15,11 +15,6 @@ #include #include -extern char irq_name_level2[]; -extern char irq_name_level3[]; -extern char irq_name_level4[]; -extern char irq_name_level5[]; - static inline int arch_interrupt_register(int irq, void (*handler)(void *arg), void *arg) { diff --git a/src/platform/apollolake/include/platform/drivers/interrupt.h b/src/platform/apollolake/include/platform/drivers/interrupt.h index 3435a6988099..b7f65bb0a7c4 100644 --- a/src/platform/apollolake/include/platform/drivers/interrupt.h +++ b/src/platform/apollolake/include/platform/drivers/interrupt.h @@ -11,6 +11,7 @@ #ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ #define __PLATFORM_DRIVERS_INTERRUPT_H__ +#include #include #include diff --git a/src/platform/cannonlake/include/platform/drivers/interrupt.h b/src/platform/cannonlake/include/platform/drivers/interrupt.h index 034c24fd93ed..057b13be1679 100644 --- a/src/platform/cannonlake/include/platform/drivers/interrupt.h +++ b/src/platform/cannonlake/include/platform/drivers/interrupt.h @@ -12,6 +12,7 @@ #ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ #define __PLATFORM_DRIVERS_INTERRUPT_H__ +#include #include #include diff --git a/src/platform/icelake/include/platform/drivers/interrupt.h b/src/platform/icelake/include/platform/drivers/interrupt.h index 034c24fd93ed..057b13be1679 100644 --- a/src/platform/icelake/include/platform/drivers/interrupt.h +++ b/src/platform/icelake/include/platform/drivers/interrupt.h @@ -12,6 +12,7 @@ #ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ #define __PLATFORM_DRIVERS_INTERRUPT_H__ +#include #include #include diff --git a/src/platform/intel/cavs/include/cavs/drivers/interrupt.h b/src/platform/intel/cavs/include/cavs/drivers/interrupt.h new file mode 100644 index 000000000000..84c4d589727a --- /dev/null +++ b/src/platform/intel/cavs/include/cavs/drivers/interrupt.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +#ifdef __PLATFORM_DRIVERS_INTERRUPT_H__ + +#ifndef __CAVS_DRIVERS_INTERRUPT_H__ +#define __CAVS_DRIVERS_INTERRUPT_H__ + +extern char irq_name_level2[]; +extern char irq_name_level3[]; +extern char irq_name_level4[]; +extern char irq_name_level5[]; + +#endif /* __CAVS_DRIVERS_INTERRUPT_H__ */ + +#else + +#error "This file shouldn't be included from outside of platform/drivers/interrupt.h" + +#endif /* __PLATFORM_DRIVERS_INTERRUPT_H__ */ diff --git a/src/platform/suecreek/include/platform/drivers/interrupt.h b/src/platform/suecreek/include/platform/drivers/interrupt.h index c5f139ef413d..9acca789f2d8 100644 --- a/src/platform/suecreek/include/platform/drivers/interrupt.h +++ b/src/platform/suecreek/include/platform/drivers/interrupt.h @@ -12,6 +12,7 @@ #ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ #define __PLATFORM_DRIVERS_INTERRUPT_H__ +#include #include #include #include diff --git a/src/platform/tigerlake/include/platform/drivers/interrupt.h b/src/platform/tigerlake/include/platform/drivers/interrupt.h index 034c24fd93ed..057b13be1679 100644 --- a/src/platform/tigerlake/include/platform/drivers/interrupt.h +++ b/src/platform/tigerlake/include/platform/drivers/interrupt.h @@ -12,6 +12,7 @@ #ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ #define __PLATFORM_DRIVERS_INTERRUPT_H__ +#include #include #include From 0ca4545f9e7399c79f750e1942c674cc6eafc403 Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Fri, 24 Jan 2020 14:24:52 +0100 Subject: [PATCH 35/37] platform: intel: LP HP freq indexes Add freq indexes for LPRO and HPRO, to be able to request clock source by providing specific frequency index instead of frequency in Hz. Signed-off-by: Janusz Jankowski --- src/platform/cannonlake/include/platform/lib/clk.h | 6 +++++- src/platform/icelake/include/platform/lib/clk.h | 6 +++++- src/platform/suecreek/include/platform/lib/clk.h | 6 +++++- src/platform/tigerlake/include/platform/lib/clk.h | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/platform/cannonlake/include/platform/lib/clk.h b/src/platform/cannonlake/include/platform/lib/clk.h index e251a319aa85..eb39bb31f549 100644 --- a/src/platform/cannonlake/include/platform/lib/clk.h +++ b/src/platform/cannonlake/include/platform/lib/clk.h @@ -16,7 +16,11 @@ #define CLK_MAX_CPU_HZ 400000000 -#define CPU_DEFAULT_IDX 1 +#define CPU_LPRO_FREQ_IDX 0 + +#define CPU_HPRO_FREQ_IDX 1 + +#define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX #define SSP_DEFAULT_IDX 0 diff --git a/src/platform/icelake/include/platform/lib/clk.h b/src/platform/icelake/include/platform/lib/clk.h index ed4ad42d09f3..dc13be94b6c1 100644 --- a/src/platform/icelake/include/platform/lib/clk.h +++ b/src/platform/icelake/include/platform/lib/clk.h @@ -16,7 +16,11 @@ #define CLK_MAX_CPU_HZ 400000000 -#define CPU_DEFAULT_IDX 1 +#define CPU_LPRO_FREQ_IDX 0 + +#define CPU_HPRO_FREQ_IDX 1 + +#define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX #define SSP_DEFAULT_IDX 1 diff --git a/src/platform/suecreek/include/platform/lib/clk.h b/src/platform/suecreek/include/platform/lib/clk.h index e251a319aa85..eb39bb31f549 100644 --- a/src/platform/suecreek/include/platform/lib/clk.h +++ b/src/platform/suecreek/include/platform/lib/clk.h @@ -16,7 +16,11 @@ #define CLK_MAX_CPU_HZ 400000000 -#define CPU_DEFAULT_IDX 1 +#define CPU_LPRO_FREQ_IDX 0 + +#define CPU_HPRO_FREQ_IDX 1 + +#define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX #define SSP_DEFAULT_IDX 0 diff --git a/src/platform/tigerlake/include/platform/lib/clk.h b/src/platform/tigerlake/include/platform/lib/clk.h index ed4ad42d09f3..dc13be94b6c1 100644 --- a/src/platform/tigerlake/include/platform/lib/clk.h +++ b/src/platform/tigerlake/include/platform/lib/clk.h @@ -16,7 +16,11 @@ #define CLK_MAX_CPU_HZ 400000000 -#define CPU_DEFAULT_IDX 1 +#define CPU_LPRO_FREQ_IDX 0 + +#define CPU_HPRO_FREQ_IDX 1 + +#define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX #define SSP_DEFAULT_IDX 1 From 1b71a50283d6ba26930236d57e5fd6ee4a83438d Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Fri, 24 Jan 2020 14:35:31 +0100 Subject: [PATCH 36/37] arch: xtensa: add waiti wakeup hook On some platforms there is a need to perform tasks after coming back from waiti. There is no central interrupts processing function in SOF. Every interrupt is registered separaterly, so we need to execute 'wake up' functions in xtos interrupts handlers. Signed-off-by: Janusz Jankowski --- src/arch/xtensa/Kconfig | 9 +++++++++ src/arch/xtensa/drivers/CMakeLists.txt | 2 +- src/arch/xtensa/drivers/interrupt.c | 14 ++++++++++++++ src/arch/xtensa/include/arch/drivers/interrupt.h | 5 +++++ src/arch/xtensa/include/arch/lib/wait.h | 1 + src/arch/xtensa/xtos/int-medpri-dispatcher.S | 4 ++++ src/arch/xtensa/xtos/xea1/int-lowpri-dispatcher.S | 2 ++ src/arch/xtensa/xtos/xea2/int-lowpri-dispatcher.S | 2 ++ src/arch/xtensa/xtos/xtos-internal.h | 7 +++++++ 9 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/arch/xtensa/drivers/interrupt.c diff --git a/src/arch/xtensa/Kconfig b/src/arch/xtensa/Kconfig index 57b12d54ccc0..becf840ae9b8 100644 --- a/src/arch/xtensa/Kconfig +++ b/src/arch/xtensa/Kconfig @@ -17,4 +17,13 @@ config SMP help Indicates that architecture uses multiple cores +config WAKEUP_HOOK + bool + default n + help + Enables hook that is called and after coming back from WAITI. + This config should be selected by other platform-level configs. + Platforms that use it, have to implement hook function + platform_interrupt_on_wakeup. + endmenu diff --git a/src/arch/xtensa/drivers/CMakeLists.txt b/src/arch/xtensa/drivers/CMakeLists.txt index 73e16b5d5f26..90376763c3ee 100644 --- a/src/arch/xtensa/drivers/CMakeLists.txt +++ b/src/arch/xtensa/drivers/CMakeLists.txt @@ -1,3 +1,3 @@ # SPDX-License-Identifier: BSD-3-Clause -add_local_sources(sof timer.c) +add_local_sources(sof interrupt.c timer.c) diff --git a/src/arch/xtensa/drivers/interrupt.c b/src/arch/xtensa/drivers/interrupt.c new file mode 100644 index 000000000000..16269fd09d2f --- /dev/null +++ b/src/arch/xtensa/drivers/interrupt.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Janusz Jankowski + +#include + +#if CONFIG_WAKEUP_HOOK +void arch_interrupt_on_wakeup(void) +{ + platform_interrupt_on_wakeup(); +} +#endif diff --git a/src/arch/xtensa/include/arch/drivers/interrupt.h b/src/arch/xtensa/include/arch/drivers/interrupt.h index 10ea72103ce9..afb4921141a8 100644 --- a/src/arch/xtensa/include/arch/drivers/interrupt.h +++ b/src/arch/xtensa/include/arch/drivers/interrupt.h @@ -14,6 +14,7 @@ #include #include #include +#include static inline int arch_interrupt_register(int irq, void (*handler)(void *arg), void *arg) @@ -83,6 +84,10 @@ static inline void arch_interrupt_global_enable(uint32_t flags) :: "a" (flags) : "memory"); } +#if CONFIG_WAKEUP_HOOK +void arch_interrupt_on_wakeup(void); +#endif + #endif /* __ARCH_DRIVERS_INTERRUPT_H__ */ #else diff --git a/src/arch/xtensa/include/arch/lib/wait.h b/src/arch/xtensa/include/arch/lib/wait.h index abecf0ce86d5..29c9317c49f3 100644 --- a/src/arch/xtensa/include/arch/lib/wait.h +++ b/src/arch/xtensa/include/arch/lib/wait.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/src/arch/xtensa/xtos/int-medpri-dispatcher.S b/src/arch/xtensa/xtos/int-medpri-dispatcher.S index 1dc1276e1537..d2f998a725ff 100644 --- a/src/arch/xtensa/xtos/int-medpri-dispatcher.S +++ b/src/arch/xtensa/xtos/int-medpri-dispatcher.S @@ -169,6 +169,8 @@ no_context: * number and exception stack frame), then call the interrupt handler. * Note: The callx12 preserves the original user task's a4..a15.*/ + xtos_on_wakeup + #if CONFIG_SMP xtos_addr_percore_add a12, xtos_interrupt_table, MAPINT(SINGLE_INT_NUM)*XIE_SIZE #else @@ -228,6 +230,8 @@ no_context: /* set interrupt task context */ xtos_task_ctx_store_percore a11, a14 + xtos_on_wakeup + /* Loop to handle all pending interrupts. */ LABEL(.L1,_loop0): diff --git a/src/arch/xtensa/xtos/xea1/int-lowpri-dispatcher.S b/src/arch/xtensa/xtos/xea1/int-lowpri-dispatcher.S index 09f95b8b5d1e..681010b49965 100644 --- a/src/arch/xtensa/xtos/xea1/int-lowpri-dispatcher.S +++ b/src/arch/xtensa/xtos/xea1/int-lowpri-dispatcher.S @@ -159,6 +159,8 @@ no_context: /* set interrupt task context */ xtos_task_ctx_store_percore a11, a14 + xtos_on_wakeup + /* Loop to handle all pending interrupts. */ LABEL(.L1,_loop0): diff --git a/src/arch/xtensa/xtos/xea2/int-lowpri-dispatcher.S b/src/arch/xtensa/xtos/xea2/int-lowpri-dispatcher.S index 5471cb8a0186..c70c7044c142 100644 --- a/src/arch/xtensa/xtos/xea2/int-lowpri-dispatcher.S +++ b/src/arch/xtensa/xtos/xea2/int-lowpri-dispatcher.S @@ -159,6 +159,8 @@ no_context: /* set interrupt task context */ xtos_task_ctx_store_percore a11, a14 + xtos_on_wakeup + /* Loop to handle all pending interrupts. */ LABEL(.L1,_loop0): diff --git a/src/arch/xtensa/xtos/xtos-internal.h b/src/arch/xtensa/xtos/xtos-internal.h index 12329d24f8bc..8a9c7ae361e1 100644 --- a/src/arch/xtensa/xtos/xtos-internal.h +++ b/src/arch/xtensa/xtos/xtos-internal.h @@ -494,6 +494,13 @@ XTOS_PENDING_OFS: .space 4 /* _xtos_pending variable */ s32i \ax, \ay, XTOS_TASK_CONTEXT_OFFSET .endm + // Executes optional callback on wake up + .macro xtos_on_wakeup +#if CONFIG_WAKEUP_HOOK + call12 arch_interrupt_on_wakeup +#endif + .endm + #else /* !_ASMLANGUAGE && !__ASSEMBLER__ */ /* From 7605252851ca9dfb56b30792eba714cf9f07d58d Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Fri, 24 Jan 2020 14:57:45 +0100 Subject: [PATCH 37/37] 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 --- src/platform/Kconfig | 13 +++ .../cavs/include/cavs/drivers/interrupt.h | 9 +++ .../intel/cavs/include/cavs/lib/clk.h | 5 ++ src/platform/intel/cavs/lib/clk.c | 79 +++++++++++++++++-- src/platform/intel/cavs/platform.c | 3 + 5 files changed, 102 insertions(+), 7 deletions(-) diff --git a/src/platform/Kconfig b/src/platform/Kconfig index a0cec1a055a4..20133624557f 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -95,6 +95,7 @@ config CANNONLAKE select CAVS select CAVS_VERSION_1_8 select WAITI_DELAY + select CAVS_USE_LPRO_IN_WAITI help Select if your target platform is Cannonlake-compatible @@ -113,6 +114,7 @@ config SUECREEK select CAVS select CAVS_VERSION_2_0 select WAITI_DELAY + select CAVS_USE_LPRO_IN_WAITI help Select if your target platform is Suecreek-compatible @@ -130,6 +132,7 @@ config ICELAKE select CAVS select CAVS_VERSION_2_0 select WAITI_DELAY + select CAVS_USE_LPRO_IN_WAITI help Select if your target platform is Icelake-compatible @@ -219,6 +222,16 @@ config CONFIG_CHERRYTRAIL_EXTRA_DW_DMA Select if you need support for all 3 DMACs versus the default 2 used in baytrail. +config CAVS_USE_LPRO_IN_WAITI + bool + default n + depends on CAVS + select WAKEUP_HOOK + help + Select if platform requires DSP clock source to be switched to LPRO + while in waiti. + After waiti clock source is restored. + # TODO: it should just take manifest version and offsets config FIRMWARE_SHORT_NAME string "Rimage firmware name" diff --git a/src/platform/intel/cavs/include/cavs/drivers/interrupt.h b/src/platform/intel/cavs/include/cavs/drivers/interrupt.h index 84c4d589727a..79dc465aeed5 100644 --- a/src/platform/intel/cavs/include/cavs/drivers/interrupt.h +++ b/src/platform/intel/cavs/include/cavs/drivers/interrupt.h @@ -10,11 +10,20 @@ #ifndef __CAVS_DRIVERS_INTERRUPT_H__ #define __CAVS_DRIVERS_INTERRUPT_H__ +#include + extern char irq_name_level2[]; extern char irq_name_level3[]; extern char irq_name_level4[]; extern char irq_name_level5[]; +#if CONFIG_CAVS_USE_LPRO_IN_WAITI +static inline void platform_interrupt_on_wakeup(void) +{ + platform_clock_on_wakeup(); +} +#endif + #endif /* __CAVS_DRIVERS_INTERRUPT_H__ */ #else diff --git a/src/platform/intel/cavs/include/cavs/lib/clk.h b/src/platform/intel/cavs/include/cavs/lib/clk.h index 031975368ef0..edde92c9fd85 100644 --- a/src/platform/intel/cavs/include/cavs/lib/clk.h +++ b/src/platform/intel/cavs/include/cavs/lib/clk.h @@ -41,6 +41,11 @@ extern uint32_t cpu_freq_status_mask[]; void platform_clock_init(void); +#if CONFIG_CAVS_USE_LPRO_IN_WAITI +void platform_clock_on_waiti(void); +void platform_clock_on_wakeup(void); +#endif + #endif /* __CAVS_LIB_CLK_H__ */ #else diff --git a/src/platform/intel/cavs/lib/clk.c b/src/platform/intel/cavs/lib/clk.c index d355e2f5ec6f..0df9a3ada8dd 100644 --- a/src/platform/intel/cavs/lib/clk.c +++ b/src/platform/intel/cavs/lib/clk.c @@ -13,17 +13,41 @@ static struct clock_info platform_clocks_info[NUM_CLOCKS]; struct clock_info *clocks = platform_clocks_info; -static int clock_platform_set_cpu_freq(int clock, int freq_idx) +#if CONFIG_CAVS_USE_LPRO_IN_WAITI +/* Track freq_idx value, so it can be stored before switching to LPRO. */ +static int cpu_current_freq_idx; + +static inline int get_cpu_current_freq_idx(void) { - uint32_t enc = cpu_freq_enc[freq_idx]; + return *cache_to_uncache(&cpu_current_freq_idx); +} + +static inline void set_cpu_current_freq_idx(int freq_idx) +{ + *cache_to_uncache(&cpu_current_freq_idx) = freq_idx; +} +#else +static inline void set_cpu_current_freq_idx(int freq_idx) +{ +} +#endif - /* set CPU frequency request for CCU */ #if CAVS_VERSION == CAVS_VERSION_1_5 +static inline void select_cpu_clock(int freq_idx, bool release_unused) +{ + uint32_t enc = cpu_freq_enc[freq_idx]; + io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL, SHIM_CLKCTL_HDCS, 0); io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL, SHIM_CLKCTL_DPCS_MASK(cpu_get_id()), enc); + + set_cpu_current_freq_idx(freq_idx); +} #else +static inline void select_cpu_clock(int freq_idx, bool release_unused) +{ + uint32_t enc = cpu_freq_enc[freq_idx]; uint32_t status_mask = cpu_freq_status_mask[freq_idx]; /* request clock */ @@ -39,14 +63,53 @@ static int clock_platform_set_cpu_freq(int clock, int freq_idx) io_reg_update_bits(SHIM_BASE + SHIM_CLKCTL, SHIM_CLKCTL_OSC_SOURCE_MASK, enc); - /* release other clocks */ - io_reg_write(SHIM_BASE + SHIM_CLKCTL, - (io_reg_read(SHIM_BASE + SHIM_CLKCTL) & - ~SHIM_CLKCTL_OSC_REQUEST_MASK) | enc); + if (release_unused) { + /* release other clocks */ + io_reg_write(SHIM_BASE + SHIM_CLKCTL, + (io_reg_read(SHIM_BASE + SHIM_CLKCTL) & + ~SHIM_CLKCTL_OSC_REQUEST_MASK) | enc); + } + + set_cpu_current_freq_idx(freq_idx); +} #endif + +static int clock_platform_set_cpu_freq(int clock, int freq_idx) +{ + select_cpu_clock(freq_idx, true); 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. + */ +static int active_freq_idx = CPU_DEFAULT_IDX; + +void platform_clock_on_wakeup(void) +{ + int freq_idx = *cache_to_uncache(&active_freq_idx); + + if (freq_idx != get_cpu_current_freq_idx()) + select_cpu_clock(freq_idx, true); +} + +void platform_clock_on_waiti(void) +{ + int freq_idx = get_cpu_current_freq_idx(); + + *cache_to_uncache(&active_freq_idx) = freq_idx; + + if (freq_idx != CPU_LPRO_FREQ_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); +} +#endif + void platform_clock_init(void) { int i; @@ -70,4 +133,6 @@ void platform_clock_init(void) .notification_mask = NOTIFIER_TARGET_CORE_ALL_MASK, .set_freq = NULL, }; + + set_cpu_current_freq_idx(CPU_DEFAULT_IDX); } diff --git a/src/platform/intel/cavs/platform.c b/src/platform/intel/cavs/platform.c index f5444218b572..f938e1975e0f 100644 --- a/src/platform/intel/cavs/platform.c +++ b/src/platform/intel/cavs/platform.c @@ -479,6 +479,9 @@ 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 #if (CONFIG_CAVS_LPS) if (pm_runtime_is_active(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID)) arch_wait_for_interrupt(level);