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) 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 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/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() 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 21d950dbcde6..afb4921141a8 100644 --- a/src/arch/xtensa/include/arch/drivers/interrupt.h +++ b/src/arch/xtensa/include/arch/drivers/interrupt.h @@ -14,11 +14,7 @@ #include #include #include - -extern char irq_name_level2[]; -extern char irq_name_level3[]; -extern char irq_name_level4[]; -extern char irq_name_level5[]; +#include static inline int arch_interrupt_register(int irq, void (*handler)(void *arg), void *arg) @@ -88,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/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 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__ */ /* 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; 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; 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/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) { 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/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); 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__) diff --git a/src/include/sof/lib/notifier.h b/src/include/sof/lib/notifier.h index 8301b1ddd46e..4514ded49695 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); }; +#ifdef CLK_SSP #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); 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__ */ diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 47cc2f449a33..78acd12e9366 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -195,8 +196,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; } @@ -405,8 +408,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 */ @@ -427,8 +431,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; } @@ -442,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) { @@ -494,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; @@ -508,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); @@ -777,8 +786,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) 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/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/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); 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/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/cannonlake/include/platform/lib/shim.h b/src/platform/cannonlake/include/platform/lib/shim.h index 7e56d594c0a5..2423c0304b03 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,30 @@ #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 + +/** \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) 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/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; 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 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); 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/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/icelake/include/platform/lib/shim.h b/src/platform/icelake/include/platform/lib/shim.h index 3137c61dbb8a..6b92c20fbf4f 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,41 @@ /* 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) + +/** \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) + +#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) 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/drivers/interrupt.h b/src/platform/intel/cavs/include/cavs/drivers/interrupt.h new file mode 100644 index 000000000000..79dc465aeed5 --- /dev/null +++ b/src/platform/intel/cavs/include/cavs/drivers/interrupt.h @@ -0,0 +1,33 @@ +/* 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__ + +#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 + +#error "This file shouldn't be included from outside of platform/drivers/interrupt.h" + +#endif /* __PLATFORM_DRIVERS_INTERRUPT_H__ */ 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/include/cavs/lib/clk.h b/src/platform/intel/cavs/include/cavs/lib/clk.h index 542ddd92176b..edde92c9fd85 100644 --- a/src/platform/intel/cavs/include/cavs/lib/clk.h +++ b/src/platform/intel/cavs/include/cavs/lib/clk.h @@ -37,9 +37,15 @@ extern struct freq_table *cpu_freq; extern uint32_t cpu_freq_enc[]; +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/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/clk.c b/src/platform/intel/cavs/lib/clk.c index 3685d98f62ad..0df9a3ada8dd 100644 --- a/src/platform/intel/cavs/lib/clk.c +++ b/src/platform/intel/cavs/lib/clk.c @@ -13,21 +13,103 @@ 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); -#endif 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 */ + 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); + + 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; @@ -51,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/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 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); 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/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/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 diff --git a/src/platform/suecreek/include/platform/lib/shim.h b/src/platform/suecreek/include/platform/lib/shim.h index 9fe736592526..67a078e9f6bc 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,41 @@ /* 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) + +/** \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) + +#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) 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/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 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 diff --git a/src/platform/tigerlake/include/platform/lib/shim.h b/src/platform/tigerlake/include/platform/lib/shim.h index 69a0720dca49..c91ad703737d 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,41 @@ /* 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) + +/** \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) + +#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) 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), 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; } 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) 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)