diff --git a/boards/intel/adsp/Kconfig.intel_adsp b/boards/intel/adsp/Kconfig.intel_adsp index 2e4c98447203b2..f5a81c6dfcc633 100644 --- a/boards/intel/adsp/Kconfig.intel_adsp +++ b/boards/intel/adsp/Kconfig.intel_adsp @@ -6,3 +6,4 @@ config BOARD_INTEL_ADSP select SOC_INTEL_CAVS_V25 if BOARD_INTEL_ADSP_CAVS25_TGPH select SOC_INTEL_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM select SOC_INTEL_ACE20_LNL if BOARD_INTEL_ADSP_ACE20_LNL + select SOC_INTEL_ACE30_PTL if BOARD_INTEL_ADSP_ACE30_PTL diff --git a/boards/intel/adsp/board.cmake b/boards/intel/adsp/board.cmake index bcdfc3286467c8..584474544bf2d7 100644 --- a/boards/intel/adsp/board.cmake +++ b/boards/intel/adsp/board.cmake @@ -39,4 +39,12 @@ elseif(CONFIG_BOARD_INTEL_ADSP_ACE20_LNL) set(RIMAGE_SIGN_KEY "otc_private_key_3k.pem" CACHE STRING "default in ace20_lnl/board.cmake") +elseif(CONFIG_BOARD_INTEL_ADSP_ACE30_PTL) + + board_set_rimage_target(ptl) + + set(RIMAGE_SIGN_KEY "otc_private_key.pem" CACHE STRING "default rimage key") + + board_finalize_runner_args(intel_adsp) + endif() diff --git a/boards/intel/adsp/board.yml b/boards/intel/adsp/board.yml index 9295ae0c3eb2fd..8e35014dd66f96 100644 --- a/boards/intel/adsp/board.yml +++ b/boards/intel/adsp/board.yml @@ -7,3 +7,4 @@ boards: - name: 'tgph' - name: ace15_mtpm - name: ace20_lnl + - name: ace30_ptl diff --git a/boards/intel/adsp/intel_adsp_ace30_ptl.dts b/boards/intel/adsp/intel_adsp_ace30_ptl.dts new file mode 100644 index 00000000000000..9e25712bc2c3e2 --- /dev/null +++ b/boards/intel/adsp/intel_adsp_ace30_ptl.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "intel_adsp_ace30_ptl"; + compatible = "intel"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &mem_window3; + }; +}; diff --git a/boards/intel/adsp/intel_adsp_ace30_ptl.yaml b/boards/intel/adsp/intel_adsp_ace30_ptl.yaml new file mode 100644 index 00000000000000..4e9c71a9d2f566 --- /dev/null +++ b/boards/intel/adsp/intel_adsp_ace30_ptl.yaml @@ -0,0 +1,10 @@ +identifier: intel_adsp/ace30_ptl +name: ACE 3.0 Panther Lake Audio DSP +type: mcu +arch: xtensa +toolchain: + - xcc-clang +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/intel/adsp/intel_adsp_ace30_ptl_defconfig b/boards/intel/adsp/intel_adsp_ace30_ptl_defconfig new file mode 100644 index 00000000000000..913d2a8c3e3a90 --- /dev/null +++ b/boards/intel/adsp/intel_adsp_ace30_ptl_defconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n + +CONFIG_BUILD_OUTPUT_BIN=n + +CONFIG_DAI_SSP_HAS_POWER_CONTROL=y + +CONFIG_DCACHE_LINE_SIZE=64 diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index f65c554cf989ac..81a404a51208c5 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -159,7 +159,7 @@ static inline void dai_dmic_release_ownership(const struct dai_intel_dmic *dmic) static inline uint32_t dai_dmic_base(const struct dai_intel_dmic *dmic) { -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) return dmic->hdamldmic_base; #else return dmic->shim_base; @@ -172,7 +172,7 @@ static inline void dai_dmic_set_sync_period(uint32_t period, const struct dai_in uint32_t val = CONFIG_DAI_DMIC_HW_IOCLK / period - 1; uint32_t base = dai_dmic_base(dmic); /* DMIC Change sync period */ -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) sys_write32(sys_read32(base + DMICSYNC_OFFSET) | FIELD_PREP(DMICSYNC_SYNCPRD, val), base + DMICSYNC_OFFSET); sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPU, @@ -286,7 +286,7 @@ static void dai_dmic_irq_handler(const void *data) static inline void dai_dmic_dis_clk_gating(const struct dai_intel_dmic *dmic) { /* Disable DMIC clock gating */ -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if (CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL) sys_write32((sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET) | DMICLVSCTL_DCGD), dmic->vshim_base + DMICLVSCTL_OFFSET); #else @@ -298,10 +298,10 @@ static inline void dai_dmic_dis_clk_gating(const struct dai_intel_dmic *dmic) static inline void dai_dmic_en_clk_gating(const struct dai_intel_dmic *dmic) { /* Enable DMIC clock gating */ -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if (CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL) sys_write32((sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET) & ~DMICLVSCTL_DCGD), dmic->vshim_base + DMICLVSCTL_OFFSET); -#else +#else /* All other CAVS and ACE platforms */ sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) & ~DMICLCTL_DCGD), dmic->shim_base + DMICLCTL_OFFSET); #endif @@ -312,7 +312,7 @@ static inline void dai_dmic_program_channel_map(const struct dai_intel_dmic *dmi const struct dai_config *cfg, uint32_t index) { -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint16_t pcmsycm = cfg->link_config; uint32_t reg_add = dmic->shim_base + DMICXPCMSyCM_OFFSET + 0x0004*index; @@ -321,7 +321,7 @@ static inline void dai_dmic_program_channel_map(const struct dai_intel_dmic *dmi ARG_UNUSED(dmic); ARG_UNUSED(cfg); ARG_UNUSED(index); -#endif /* defined(CONFIG_SOC_INTEL_ACE20_LNL) */ +#endif /* defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) */ } static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic) @@ -331,7 +331,7 @@ static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic) sys_write32((sys_read32(base + DMICLCTL_OFFSET) | DMICLCTL_SPA), base + DMICLCTL_OFFSET); -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) while (!(sys_read32(base + DMICLCTL_OFFSET) & DMICLCTL_CPA)) { k_sleep(K_USEC(100)); } diff --git a/drivers/dai/intel/dmic/dmic.h b/drivers/dai/intel/dmic/dmic.h index e06ed80daed75f..d690c0cd21a1ca 100644 --- a/drivers/dai/intel/dmic/dmic.h +++ b/drivers/dai/intel/dmic/dmic.h @@ -173,7 +173,7 @@ struct dai_intel_dmic { /* hardware parameters */ uint32_t reg_base; uint32_t shim_base; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint32_t hdamldmic_base; uint32_t vshim_base; #endif diff --git a/drivers/dai/intel/dmic/dmic_nhlt.c b/drivers/dai/intel/dmic/dmic_nhlt.c index c7fe48e1432da7..5f150e6d0375c5 100644 --- a/drivers/dai/intel/dmic/dmic_nhlt.c +++ b/drivers/dai/intel/dmic/dmic_nhlt.c @@ -279,7 +279,7 @@ static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic, const int c static inline void dai_dmic_clock_select_set(const struct dai_intel_dmic *dmic, uint32_t source) { uint32_t val; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) /* ACE 2.0,3.0 */ val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET); val &= ~DMICLVSCTL_MLCS; val |= FIELD_PREP(DMICLVSCTL_MLCS, source); @@ -300,7 +300,7 @@ static inline void dai_dmic_clock_select_set(const struct dai_intel_dmic *dmic, static inline uint32_t dai_dmic_clock_select_get(const struct dai_intel_dmic *dmic) { uint32_t val; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) /* ACE 2.0,3.0 */ val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET); return FIELD_GET(DMICLVSCTL_MLCS, val); #else @@ -322,7 +322,7 @@ static int dai_dmic_set_clock(const struct dai_intel_dmic *dmic, const uint8_t c return -ENOTSUP; } -#ifndef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE15_MTPM) if (clock_source && !(sys_read32(dmic->shim_base + DMICLCAP_OFFSET) & DMICLCAP_MLCS)) { return -ENOTSUP; } diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index 215f9912d57740..a7e83f7a07f9eb 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -74,11 +74,11 @@ static struct dai_intel_ssp_mn ssp_mn_divider = { .irq = DT_NUM_IRQS(node_id), \ .irq_name = irq_name_level5_z, \ .fifo[DAI_DIR_PLAYBACK].offset = \ - DT_REG_ADDR_BY_IDX(node_id, 0) + SSDR, \ + DT_REG_ADDR_BY_IDX(node_id, 0) + OUT_FIFO, \ .fifo[DAI_DIR_PLAYBACK].handshake = \ DT_DMAS_CELL_BY_NAME(node_id, tx, channel), \ .fifo[DAI_DIR_CAPTURE].offset = \ - DT_REG_ADDR_BY_IDX(node_id, 0) + SSDR, \ + DT_REG_ADDR_BY_IDX(node_id, 0) + IN_FIFO, \ .fifo[DAI_DIR_CAPTURE].handshake = \ DT_DMAS_CELL_BY_NAME(node_id, rx, channel), \ .mn_inst = &ssp_mn_divider, \ @@ -817,7 +817,7 @@ static void dai_ssp_pm_runtime_en_ssp_power(struct dai_intel_ssp *dp, uint32_t s ret = dai_ssp_poll_for_register_delay(dai_ip_base(dp) + I2SLCTL_OFFSET, I2SLCTL_CPA(ssp_index), I2SLCTL_CPA(ssp_index), DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); -#elif CONFIG_SOC_INTEL_ACE20_LNL +#elif CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL sys_write32(sys_read32(dai_hdamlssp_base(dp) + I2SLCTL_OFFSET) | I2SLCTL_SPA(ssp_index), dai_hdamlssp_base(dp) + I2SLCTL_OFFSET); @@ -851,7 +851,8 @@ static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t ret = dai_ssp_poll_for_register_delay(dai_ip_base(dp) + I2SLCTL_OFFSET, I2SLCTL_CPA(ssp_index), 0, DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); -#elif CONFIG_SOC_INTEL_ACE20_LNL + +#elif CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL sys_write32(sys_read32(dai_hdamlssp_base(dp) + I2SLCTL_OFFSET) & (~I2SLCTL_SPA(ssp_index)), dai_hdamlssp_base(dp) + I2SLCTL_OFFSET); @@ -874,7 +875,7 @@ static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t static void dai_ssp_program_channel_map(struct dai_intel_ssp *dp, const struct dai_config *cfg, uint32_t ssp_index) { -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint16_t pcmsycm = cfg->link_config; /* Set upper slot number from configuration */ pcmsycm = pcmsycm | (dp->ssp_plat_data->params.tdm_slots - 1) << 4; @@ -905,11 +906,21 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp) * SSSR_TNF is cleared when TX FIFO is empty or full, * so wait for set TNF then for TFL zero - order matter. */ +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + ret = dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(0), + SSMODyCS_TNF, SSMODyCS_TNF, + DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); + + ret |= dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(0), SSMODyCS_TFL, 0, + DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE * + (DAI_INTEL_SSP_FIFO_DEPTH - 1) / 2); +#else ret = dai_ssp_poll_for_register_delay(dai_base(dp) + SSSR, SSSR_TNF, SSSR_TNF, DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); ret |= dai_ssp_poll_for_register_delay(dai_base(dp) + SSCR3, SSCR3_TFL_MASK, 0, DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE * (DAI_INTEL_SSP_FIFO_DEPTH - 1) / 2); +#endif if (ret) { LOG_WRN("timeout"); @@ -923,6 +934,81 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp) } } +#ifdef CONFIG_SOC_INTEL_ACE30_PTL +static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp) +{ + uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; + uint32_t i, sssr; + + sssr = sys_read32(dai_base(dp) + SSSR); + + if (sssr & SSSR_ROR) { + /* The RX FIFO is in overflow condition, empty it */ + for (i = 0; i < DAI_INTEL_SSP_FIFO_DEPTH; i++) + sys_read32(dai_base(dp) + SSMIDyD(0)); + + /* Clear the overflow status */ + dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); + /* Re-read the SSSR register */ + sssr = sys_read32(dai_base(dp) + SSSR); + } + + while ((sys_read32(dai_base(dp) + SSMIDyCS(0)) & SSMIDyCS_RNE) && retry--) { + uint32_t entries = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0))); + + /* Empty the RX FIFO (the DMA is not running at this point) */ + for (i = 0; i < entries + 1; i++) + sys_read32(dai_base(dp) + SSMIDyD(0)); + + sssr = sys_read32(dai_base(dp) + SSSR); + } +} + +static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp) +{ + struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp); + uint64_t sample_ticks = ssp_plat_data->params.fsync_rate ? + 1000000 / ssp_plat_data->params.fsync_rate : 0; + + uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; + uint32_t i, sssr, ssmidycs; + uint32_t entries[2]; + + sssr = sys_read32(dai_base(dp) + SSSR); + entries[0] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0))); + + while ((sys_read32(dai_base(dp) + SSMIDyCS(0)) & SSMIDyCS_RNE) && retry--) { + /* Wait one sample time */ + k_busy_wait(sample_ticks); + + entries[1] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0))); + sssr = sys_read32(dai_base(dp) + SSSR); + ssmidycs = sys_read32(dai_base(dp) + SSMIDyCS(0)); + + if (entries[0] > entries[1]) { + /* + * The DMA is reading the FIFO, check the status in the + * next loop + */ + entries[0] = entries[1]; + } else if (!(ssmidycs & SSMIDyCS_RFS)) { + /* + * The DMA request is not asserted, read the FIFO + * directly, otherwise let the next loop iteration to + * check the status + */ + for (i = 0; i < entries[1] + 1; i++) + sys_read32(dai_base(dp) + SSMIDyD(0)); + } + + sssr = sys_read32(dai_base(dp) + SSSR); + } + + /* Just in case clear the overflow status */ + dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); +} + +#else static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp) { uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; @@ -994,21 +1080,20 @@ static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp) dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); } +#endif + static int dai_ssp_mclk_prepare_enable(struct dai_intel_ssp *dp) { struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp); - int ret = 0; + int ret; if (ssp_plat_data->clk_active & SSP_CLK_MCLK_ACTIVE) { return 0; } /* MCLK config */ - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - ret = dai_ssp_mn_set_mclk(dp, ssp_plat_data->params.mclk_id, - ssp_plat_data->params.mclk_rate); - } - + ret = dai_ssp_mn_set_mclk(dp, ssp_plat_data->params.mclk_id, + ssp_plat_data->params.mclk_rate); if (ret < 0) { LOG_ERR("invalid mclk_rate = %d for mclk_id = %d", ssp_plat_data->params.mclk_rate, ssp_plat_data->params.mclk_id); @@ -1027,9 +1112,7 @@ static void dai_ssp_mclk_disable_unprepare(struct dai_intel_ssp *dp) return; } - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - dai_ssp_mn_release_mclk(dp, ssp_plat_data->params.mclk_id); - } + dai_ssp_mn_release_mclk(dp, ssp_plat_data->params.mclk_id); ssp_plat_data->clk_active &= ~SSP_CLK_MCLK_ACTIVE; } @@ -1049,10 +1132,6 @@ static int dai_ssp_bclk_prepare_enable(struct dai_intel_ssp *dp) return 0; } - if (!(ssp_plat_data->clk_active & SSP_CLK_BCLK_IS_NEEDED)) { - goto out; - } - sscr0 = sys_read32(dai_base(dp) + SSCR0); #if CONFIG_INTEL_MN @@ -1075,9 +1154,11 @@ static int dai_ssp_bclk_prepare_enable(struct dai_intel_ssp *dp) mdiv = ft[DAI_INTEL_SSP_DEFAULT_IDX].freq / ssp_plat_data->params.bclk_rate; #endif +#ifndef CONFIG_SOC_INTEL_ACE30_PTL if (need_ecs) { sscr0 |= SSCR0_ECS; } +#endif /* clock divisor is SCR + 1 */ mdiv -= 1; @@ -1112,9 +1193,7 @@ static void dai_ssp_bclk_disable_unprepare(struct dai_intel_ssp *dp) return; } #if CONFIG_INTEL_MN - if (ssp_plat_data->clk_active & SSP_CLK_BCLK_IS_NEEDED) { - dai_ssp_mn_release_bclk(dp, ssp_plat_data->ssp_index); - } + dai_ssp_mn_release_bclk(dp, ssp_plat_data->ssp_index); #endif ssp_plat_data->clk_active &= ~SSP_CLK_BCLK_ACTIVE; } @@ -1237,19 +1316,16 @@ static int dai_ssp_set_config_tplg(struct dai_intel_ssp *dp, const struct dai_co sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR; break; case DAI_INTEL_IPC3_SSP_FMT_CBC_CFC: - ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED | SSP_CLK_BCLK_IS_NEEDED; sscr1 |= SSCR1_SCFR; cfs = true; break; case DAI_INTEL_IPC3_SSP_FMT_CBP_CFC: - ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED; sscr1 |= SSCR1_SCLKDIR; /* FIXME: this mode has not been tested */ cfs = true; break; case DAI_INTEL_IPC3_SSP_FMT_CBC_CFP: - ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED | SSP_CLK_BCLK_IS_NEEDED; sscr1 |= SSCR1_SCFR | SSCR1_SFRMDIR; /* FIXME: this mode has not been tested */ break; @@ -1611,8 +1687,13 @@ static int dai_ssp_set_config_tplg(struct dai_intel_ssp *dp, const struct dai_co sys_write32(sspsp2, dai_base(dp) + SSPSP2); sys_write32(ssioc, dai_base(dp) + SSIOC); sys_write32(ssto, dai_base(dp) + SSTO); +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + sys_write64((uint64_t)sstsa, dai_base(dp) + SSMODyTSA(0)); + sys_write64((uint64_t)ssrsa, dai_base(dp) + SSMIDyTSA(0)); +#else sys_write32(sstsa, dai_base(dp) + SSTSA); sys_write32(ssrsa, dai_base(dp) + SSRSA); +#endif LOG_INF("sscr0 = 0x%08x, sscr1 = 0x%08x, ssto = 0x%08x, sspsp = 0x%0x", sscr0, sscr1, ssto, sspsp); @@ -1825,7 +1906,7 @@ static int dai_ssp_parse_aux_data(struct dai_intel_ssp *dp, const void *spec_con sys_write32(sys_read32(dai_ip_base(dp) + I2SLCTL_OFFSET) | I2CLCTL_MLCS(link->clock_source), dai_ip_base(dp) + I2SLCTL_OFFSET); -#elif CONFIG_SOC_INTEL_ACE20_LNL +#elif CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL sys_write32(sys_read32(dai_i2svss_base(dp) + I2SLCTL_OFFSET) | I2CLCTL_MLCS(link->clock_source), dai_i2svss_base(dp) + I2SLCTL_OFFSET); @@ -1876,14 +1957,20 @@ static int dai_ssp_set_clock_control_ver_1(struct dai_intel_ssp *dp, static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_config *cfg, const struct dai_intel_ipc4_ssp_config *regs) { - uint32_t ssc0, sstsa, ssrsa, sscr1; + uint32_t ssc0, sstsa, ssrsa; + uint32_t sscr1 = regs->ssc1; +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + sscr1 = regs->ssc1 & ~(SSCR1_RSVD21); +#else + sscr1 = regs->ssc1 & ~(SSCR1_RSRE | SSCR1_TSRE); +#endif ssc0 = regs->ssc0; sstsa = SSTSA_GET(regs->sstsa); ssrsa = SSRSA_GET(regs->ssrsa); - sscr1 = regs->ssc1 & ~(SSCR1_RSRE | SSCR1_TSRE); LOG_INF("SSP%d configuration:", dp->dai_index); +#ifndef CONFIG_SOC_INTEL_ACE30_PTL if (regs->sstsa & SSTSA_TXEN || regs->ssrsa & SSRSA_RXEN || regs->ssc1 & (SSCR1_RSRE | SSCR1_TSRE)) { LOG_INF(" Ignoring %s%s%s%sfrom blob", @@ -1892,6 +1979,7 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co regs->ssc1 & SSCR1_TSRE ? "SSCR1:TSRE " : "", regs->ssc1 & SSCR1_RSRE ? "SSCR1:RSRE " : ""); } +#endif sys_write32(ssc0, dai_base(dp) + SSCR0); sys_write32(regs->ssc2 & ~SSCR2_SFRMEN, dai_base(dp) + SSCR2); /* hardware specific flow */ @@ -1903,8 +1991,13 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co sys_write32(regs->sspsp2, dai_base(dp) + SSPSP2); sys_write32(regs->ssioc, dai_base(dp) + SSIOC); sys_write32(regs->sscto, dai_base(dp) + SSTO); +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + sys_write64((uint64_t)sstsa, dai_base(dp) + SSMODyTSA(0)); + sys_write64((uint64_t)ssrsa, dai_base(dp) + SSMIDyTSA(0)); +#else sys_write32(sstsa, dai_base(dp) + SSTSA); sys_write32(ssrsa, dai_base(dp) + SSRSA); +#endif LOG_INF(" sscr0 = 0x%08x, sscr1 = 0x%08x, ssto = 0x%08x, sspsp = 0x%0x", ssc0, sscr1, regs->sscto, regs->sspsp); @@ -1923,15 +2016,6 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co dp->ssp_plat_data->params.rx_slots = SSRSA_GET(ssrsa); dp->ssp_plat_data->params.fsync_rate = cfg->rate; - /* MCLK is needed if SSP is FS and/or BCLK provider */ - if (!(regs->ssc1 & (SSCR1_SCLKDIR | SSCR1_SFRMDIR))) { - dp->ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED; - /* BCLK is only needed if SSP is BCLK provider */ - if (!(regs->ssc1 & SSCR1_SCLKDIR)) { - dp->ssp_plat_data->clk_active |= SSP_CLK_BCLK_IS_NEEDED; - } - } - dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; } @@ -1956,19 +2040,14 @@ static int dai_ssp_set_config_blob(struct dai_intel_ssp *dp, const struct dai_co if (err) return err; dai_ssp_set_reg_config(dp, cfg, &blob15->i2s_ssp_config); - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - err = dai_ssp_set_clock_control_ver_1_5(dp, &blob15->i2s_mclk_control); - if (err) - return err; - } + err = dai_ssp_set_clock_control_ver_1_5(dp, &blob15->i2s_mclk_control); + if (err) + return err; } else { dai_ssp_set_reg_config(dp, cfg, &blob->i2s_driver_config.i2s_config); - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - err = dai_ssp_set_clock_control_ver_1(dp, - &blob->i2s_driver_config.mclk_config); - if (err) - return err; - } + err = dai_ssp_set_clock_control_ver_1(dp, &blob->i2s_driver_config.mclk_config); + if (err) + return err; } ssp_plat_data->clk_active |= SSP_CLK_MCLK_ES_REQ; @@ -2070,6 +2149,15 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction) /* enable DMA */ +#if CONFIG_SOC_INTEL_ACE30_PTL + if (direction == DAI_DIR_PLAYBACK) { + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TSRE, SSMODyCS_TSRE); + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TXEN, SSMODyCS_TXEN); + } else { + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RSRE, SSMIDyCS_RSRE); + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RXEN, SSMIDyCS_RXEN); + } +#else if (direction == DAI_DIR_PLAYBACK) { LOG_INF("SSP%d TX", dp->dai_index); dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE, SSCR1_TSRE); @@ -2079,6 +2167,7 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction) dai_ssp_update_bits(dp, SSCR1, SSCR1_RSRE, SSCR1_RSRE); dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, SSRSA_RXEN); } +#endif dp->state[direction] = DAI_STATE_RUNNING; ssp_acquire_port(dp->ssp_plat_data); @@ -2128,8 +2217,13 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction) if (direction == DAI_DIR_CAPTURE && dp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) { LOG_INF("SSP%d RX", dp->dai_index); +#if CONFIG_SOC_INTEL_ACE30_PTL + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RXEN, 0); + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RSRE, 0); +#else dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, 0); dai_ssp_update_bits(dp, SSCR1, SSCR1_RSRE, 0); +#endif ssp_empty_rx_fifo_on_stop(dp); dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; ssp_release_port(ssp_plat_data); @@ -2139,9 +2233,15 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction) if (direction == DAI_DIR_PLAYBACK && dp->state[DAI_DIR_PLAYBACK] != DAI_STATE_PRE_RUNNING) { LOG_INF("SSP%d TX", dp->dai_index); +#if CONFIG_SOC_INTEL_ACE30_PTL + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TSRE, 0); + dai_ssp_empty_tx_fifo(dp); + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TXEN, 0); +#else dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE, 0); dai_ssp_empty_tx_fifo(dp); dai_ssp_update_bits(dp, SSTSA, SSTSA_TXEN, 0); +#endif dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; ssp_release_port(ssp_plat_data); } diff --git a/drivers/dai/intel/ssp/ssp.h b/drivers/dai/intel/ssp/ssp.h index 8c3e248a0d9b7a..877ff75e532400 100644 --- a/drivers/dai/intel/ssp/ssp.h +++ b/drivers/dai/intel/ssp/ssp.h @@ -48,234 +48,16 @@ #define DAI_INTEL_SSP_CLOCK_AUDIO_CARDINAL 0x1 #define DAI_INTEL_SSP_CLOCK_PLL_FIXED 0x2 -/* SSP register offsets */ -#define SSCR0 0x00 -#define SSCR1 0x04 -#define SSSR 0x08 -#define SSITR 0x0C -#define SSDR 0x10 -#define SSTO 0x28 -#define SSPSP 0x2C -#define SSTSA 0x30 -#define SSRSA 0x34 -#define SSTSS 0x38 -#define SSCR2 0x40 - -/* SSCR0 bits */ -#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) -#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) -#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) -#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) -#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) -#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) -#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) -#define SSCR0_ECS BIT(6) -#define SSCR0_SSE BIT(7) -#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) -#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) -#define SSCR0_EDSS BIT(20) -#define SSCR0_NCS BIT(21) -#define SSCR0_RIM BIT(22) -#define SSCR0_TIM BIT(23) -#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) -#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) -#define SSCR0_ACS BIT(30) -#define SSCR0_MOD BIT(31) - -/* SSCR1 bits */ -#define SSCR1_RIE BIT(0) -#define SSCR1_TIE BIT(1) -#define SSCR1_LBM BIT(2) -#define SSCR1_SPO BIT(3) -#define SSCR1_SPH BIT(4) -#define SSCR1_MWDS BIT(5) -#define SSCR1_TFT_MASK DAI_INTEL_SSP_MASK(9, 6) -#define SSCR1_TFT(x) DAI_INTEL_SSP_SET_BITS(9, 6, (x) - 1) -#define SSCR1_RFT_MASK DAI_INTEL_SSP_MASK(13, 10) -#define SSCR1_RFT(x) DAI_INTEL_SSP_SET_BITS(13, 10, (x) - 1) -#define SSCR1_EFWR BIT(14) -#define SSCR1_STRF BIT(15) -#define SSCR1_IFS BIT(16) -#define SSCR1_PINTE BIT(18) -#define SSCR1_TINTE BIT(19) -#define SSCR1_RSRE BIT(20) -#define SSCR1_TSRE BIT(21) -#define SSCR1_TRAIL BIT(22) -#define SSCR1_RWOT BIT(23) -#define SSCR1_SFRMDIR BIT(24) -#define SSCR1_SCLKDIR BIT(25) -#define SSCR1_ECRB BIT(26) -#define SSCR1_ECRA BIT(27) -#define SSCR1_SCFR BIT(28) -#define SSCR1_EBCEI BIT(29) -#define SSCR1_TTE BIT(30) -#define SSCR1_TTELP BIT(31) - -#define SSCR2_TURM1 BIT(1) -#define SSCR2_PSPSRWFDFD BIT(3) -#define SSCR2_PSPSTWFDFD BIT(4) -#define SSCR2_SDFD BIT(14) -#define SSCR2_SDPM BIT(16) -#define SSCR2_LJDFD BIT(17) -#define SSCR2_MMRATF BIT(18) -#define SSCR2_SMTATF BIT(19) -#define SSCR2_SFRMEN BIT(20) -#define SSCR2_ACIOLBS BIT(21) - -/* SSR bits */ -#define SSSR_TNF BIT(2) -#define SSSR_RNE BIT(3) -#define SSSR_BSY BIT(4) -#define SSSR_TFS BIT(5) -#define SSSR_RFS BIT(6) -#define SSSR_ROR BIT(7) -#define SSSR_TUR BIT(21) - -/* SSPSP bits */ -#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) -#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) -#define SSPSP_ETDS BIT(3) -#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) -#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) -#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) -#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) -#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) -#define SSPSP_DMYSTOP_BITS 2 -#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) -#define SSPSP_FSRT BIT(25) -#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) - -#define SSPSP2 0x44 -#define SSPSP2_FEP_MASK 0xff - -#define SSCR3 0x48 -#define SSIOC 0x4C -#define SSP_REG_MAX SSIOC - -/* SSTSA bits */ -#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) -#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) -#define SSTSA_TXEN BIT(8) - -/* SSRSA bits */ -#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) -#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) -#define SSRSA_RXEN BIT(8) - -/* SSCR3 bits */ -#define SSCR3_FRM_MST_EN BIT(0) -#define SSCR3_I2S_MODE_EN BIT(1) -#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) -#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) -#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) -#define SSCR3_I2S_TX_EN BIT(9) -#define SSCR3_I2S_RX_EN BIT(10) -#define SSCR3_CLK_EDGE_SEL BIT(12) -#define SSCR3_STRETCH_TX BIT(14) -#define SSCR3_STRETCH_RX BIT(15) -#define SSCR3_MST_CLK_EN BIT(16) -#define SSCR3_SYN_FIX_EN BIT(17) - -/* SSCR4 bits */ -#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) - -/* SSCR5 bits */ -#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) -#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) - -/* SFIFOTT bits */ -#define SFIFOTT_TX(x) ((x) - 1) -#define SFIFOTT_RX(x) (((x) - 1) << 16) - -/* SFIFOL bits */ -#define SFIFOL_TFL(x) ((x) & 0xFFFF) -#define SFIFOL_RFL(x) ((x) >> 16) - -#define SSTSA_TSEN BIT(8) -#define SSRSA_RSEN BIT(8) - -#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) -#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) -#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) -#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) -#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) -#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) - -#define SSIOC_TXDPDEB BIT(1) -#define SSIOC_SFCR BIT(4) -#define SSIOC_SCOE BIT(5) - -/* For 8000 Hz rate one sample is transmitted within 125us */ -#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 - -/* SSP flush retry counts maximum */ -#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 - -#define SSP_CLK_MCLK_IS_NEEDED BIT(0) -#define SSP_CLK_MCLK_ES_REQ BIT(1) -#define SSP_CLK_MCLK_ACTIVE BIT(2) -#define SSP_CLK_BCLK_IS_NEEDED BIT(3) -#define SSP_CLK_BCLK_ES_REQ BIT(4) -#define SSP_CLK_BCLK_ACTIVE BIT(5) - -#define I2SLCTL_OFFSET 0x04 - #if defined(CONFIG_SOC_INTEL_ACE15_MTPM) || defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS) -#define I2SLCTL_SPA(x) BIT(0 + x) -#define I2SLCTL_CPA(x) BIT(8 + x) +#include "ssp_regs_v1.h" #elif defined(CONFIG_SOC_INTEL_ACE20_LNL) -#define I2SLCTL_OFLEN BIT(4) -#define I2SLCTL_SPA(x) BIT(16 + x) -#define I2SLCTL_CPA(x) BIT(23 + x) -#define PCMS0CM_OFFSET 0x16 -#define PCMS1CM_OFFSET 0x1A +#include "ssp_regs_v2.h" +#elif defined(CONFIG_SOC_INTEL_ACE30_PTL) +#include "ssp_regs_v3.h" #else #error "Missing ssp definitions" #endif -#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) -#define SHIM_CLKCTL 0x78 -#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) -#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) - -#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE -/** \brief Offset of MCLK Divider Control Register. */ -#define MN_MDIVCTRL 0x100 - -/** \brief Offset of MCLK Divider x Ratio Register. */ -#define MN_MDIVR(x) (0x180 + (x) * 0x4) - -/** \brief Enables the output of MCLK Divider. - * On ACE+ there is a single divider for all MCLKs - */ -#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(0) - -#else -#define MN_MDIVCTRL 0x0 -#define MN_MDIVR(x) (0x80 + (x) * 0x4) - -/** \brief Enables the output of MCLK Divider. - * Each MCLK divider can be enabled separately. - */ -#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) - -#endif - -/** \brief Bits for setting MCLK source clock. */ -#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) - -/** \brief Offset of BCLK x M/N Divider M Value Register. */ -#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) - -/** \brief Offset of BCLK x M/N Divider N Value Register. */ -#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) - -/** \brief Bits for setting M/N source clock. */ -#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) - -/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ -#define MN_SOURCE_CLKS_MASK 0x3 - #if CONFIG_INTEL_MN /** \brief BCLKs can be driven by multiple sources - M/N or XTAL directly. * Even in the case of M/N, the actual clock source can be XTAL, @@ -334,7 +116,7 @@ struct dai_intel_ssp_plat_data { uint32_t base; uint32_t ip_base; uint32_t shim_base; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint32_t hdamlssp_base; uint32_t i2svss_base; #endif diff --git a/drivers/dai/intel/ssp/ssp_regs_v1.h b/drivers/dai/intel/ssp/ssp_regs_v1.h new file mode 100644 index 00000000000000..a821ab8733a63e --- /dev/null +++ b/drivers/dai/intel/ssp/ssp_regs_v1.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2022 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DAI_DRIVER_SSP_REGSV1_H__ +#define __INTEL_DAI_DRIVER_SSP_REGSV1_H__ + +/* SSP register offsets */ +#define SSCR0 0x00 +#define SSCR1 0x04 +#define SSSR 0x08 +#define SSITR 0x0C +#define SSTO 0x28 +#define SSPSP 0x2C +#define SSTSS 0x38 +#define SSCR2 0x40 +#define SSPSP2 0x44 +#define SSIOC 0x4C +#define SSGFS 0x50 +#define SSDR 0x10 /* Not PTL */ +#define SSTSA 0x30 /* Not PTL */ +#define SSRSA 0x34 /* Not PTL */ + +#define OUT_FIFO SSDR +#define IN_FIFO SSDR + +/* SSCR0 bits */ +#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) +#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) +#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) +#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) +#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) +#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) +#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) +#define SSCR0_ECS BIT(6) +#define SSCR0_SSE BIT(7) +#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) +#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) +#define SSCR0_EDSS BIT(20) +#define SSCR0_NCS BIT(21) +#define SSCR0_RIM BIT(22) +#define SSCR0_TIM BIT(23) +#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) +#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) +#define SSCR0_ACS BIT(30) +#define SSCR0_MOD BIT(31) + +/* SSCR1 bits */ +#define SSCR1_RIE BIT(0) +#define SSCR1_TIE BIT(1) +#define SSCR1_LBM BIT(2) +#define SSCR1_SPO BIT(3) +#define SSCR1_SPH BIT(4) +#define SSCR1_MWDS BIT(5) +#define SSCR1_TFT_MASK DAI_INTEL_SSP_MASK(9, 6) +#define SSCR1_TFT(x) DAI_INTEL_SSP_SET_BITS(9, 6, (x) - 1) +#define SSCR1_RFT_MASK DAI_INTEL_SSP_MASK(13, 10) +#define SSCR1_RFT(x) DAI_INTEL_SSP_SET_BITS(13, 10, (x) - 1) +#define SSCR1_EFWR BIT(14) +#define SSCR1_STRF BIT(15) +#define SSCR1_IFS BIT(16) +#define SSCR1_PINTE BIT(18) +#define SSCR1_TINTE BIT(19) +#define SSCR1_RSRE BIT(20) +#define SSCR1_TSRE BIT(21) +#define SSCR1_TRAIL BIT(22) +#define SSCR1_RWOT BIT(23) +#define SSCR1_SFRMDIR BIT(24) +#define SSCR1_SCLKDIR BIT(25) +#define SSCR1_ECRB BIT(26) +#define SSCR1_ECRA BIT(27) +#define SSCR1_SCFR BIT(28) +#define SSCR1_EBCEI BIT(29) +#define SSCR1_TTE BIT(30) +#define SSCR1_TTELP BIT(31) + +#define SSCR2_TURM1 BIT(1) +#define SSCR2_PSPSRWFDFD BIT(3) +#define SSCR2_PSPSTWFDFD BIT(4) +#define SSCR2_SDFD BIT(14) +#define SSCR2_SDPM BIT(16) +#define SSCR2_LJDFD BIT(17) +#define SSCR2_MMRATF BIT(18) +#define SSCR2_SMTATF BIT(19) +#define SSCR2_SFRMEN BIT(20) +#define SSCR2_ACIOLBS BIT(21) + +/* SSR bits */ +#define SSSR_TNF BIT(2) +#define SSSR_RNE BIT(3) +#define SSSR_BSY BIT(4) +#define SSSR_TFS BIT(5) +#define SSSR_RFS BIT(6) +#define SSSR_ROR BIT(7) +#define SSSR_TUR BIT(21) + +/* SSPSP bits */ +#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) +#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSPSP_ETDS BIT(3) +#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) +#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) +#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) +#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) +#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) +#define SSPSP_DMYSTOP_BITS 2 +#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) +#define SSPSP_FSRT BIT(25) +#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) + +#define SSPSP2 0x44 +#define SSPSP2_FEP_MASK 0xff + +#define SSCR3 0x48 +#define SSIOC 0x4C +#define SSP_REG_MAX SSIOC + +/* SSTSA bits */ +#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSTSA_TXEN BIT(8) + +/* SSRSA bits */ +#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSRSA_RXEN BIT(8) + +/* SSCR3 bits */ +#define SSCR3_FRM_MST_EN BIT(0) +#define SSCR3_I2S_MODE_EN BIT(1) +#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) +#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) +#define SSCR3_I2S_TX_EN BIT(9) +#define SSCR3_I2S_RX_EN BIT(10) +#define SSCR3_CLK_EDGE_SEL BIT(12) +#define SSCR3_STRETCH_TX BIT(14) +#define SSCR3_STRETCH_RX BIT(15) +#define SSCR3_MST_CLK_EN BIT(16) +#define SSCR3_SYN_FIX_EN BIT(17) + +/* SSCR4 bits */ +#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) + +/* SSCR5 bits */ +#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) +#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) + +/* SFIFOTT bits */ +#define SFIFOTT_TX(x) ((x) - 1) +#define SFIFOTT_RX(x) (((x) - 1) << 16) + +/* SFIFOL bits */ +#define SFIFOL_TFL(x) ((x) & 0xFFFF) +#define SFIFOL_RFL(x) ((x) >> 16) + +#define SSTSA_TSEN BIT(8) +#define SSRSA_RSEN BIT(8) + +#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) +#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) +#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) +#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) + +#define SSIOC_TXDPDEB BIT(1) +#define SSIOC_SFCR BIT(4) +#define SSIOC_SCOE BIT(5) + +/* SSMIDyCS */ +#define SSMIDyCS_RXEN BIT(0) +#define SSMIDyCS_RSRE BIT(1) +#define SSMIDyCS_RFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_RFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMIDyCS_RNE BIT(26) +#define SSMIDyCS_RFS BIT(27) +#define SSMIDyCS_ROR BIT(28) +#define SSMIDyCS_PINT BIT(29) +#define SSMIDyCS_TINT BIT(30) +#define SSMIDyCS_EOC BIT(31) + +/* SSMIDyTSA */ +#define SSMIDyTSA_RTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMIDyTSA_SRTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* SSMODyCS */ +#define SSMODyCS_TXEN BIT(0) +#define SSMODyCS_TSRE BIT(1) +#define SSMODyCS_TFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_TFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMODyCS_TNF BIT(26) +#define SSMODyCS_TFS BIT(27) +#define SSMODyCS_TUR BIT(28) + +/* SSMODyTSA */ +#define SSMODyTSA_TTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMODyTSA_STTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* For 8000 Hz rate one sample is transmitted within 125us */ +#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 + +/* SSP flush retry counts maximum */ +#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 + +#define SSP_CLK_MCLK_ES_REQ BIT(0) +#define SSP_CLK_MCLK_ACTIVE BIT(1) +#define SSP_CLK_BCLK_ES_REQ BIT(2) +#define SSP_CLK_BCLK_ACTIVE BIT(3) + +#define I2SLCTL_OFFSET 0x04 + +#define I2SLCTL_SPA(x) BIT(0 + x) +#define I2SLCTL_CPA(x) BIT(8 + x) + +#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) +#define SHIM_CLKCTL 0x78 +#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) +#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) + +#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE +/** \brief Offset of MCLK Divider Control Register. */ +#define MN_MDIVCTRL 0x100 + +/** \brief Offset of MCLK Divider x Ratio Register. */ +#define MN_MDIVR(x) (0x180 + (x) * 0x4) +#else +#define MN_MDIVCTRL 0x0 +#define MN_MDIVR(x) (0x80 + (x) * 0x4) +#endif + +/** \brief Enables the output of MCLK Divider. */ +#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) + +/** \brief Bits for setting MCLK source clock. */ +#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) + +/** \brief Offset of BCLK x M/N Divider M Value Register. */ +#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) + +/** \brief Offset of BCLK x M/N Divider N Value Register. */ +#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) + +/** \brief Bits for setting M/N source clock. */ +#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) + +/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ +#define MN_SOURCE_CLKS_MASK 0x3 + +#endif /* __INTEL_DAI_DRIVER_SSP_REGSV1_H__ */ diff --git a/drivers/dai/intel/ssp/ssp_regs_v2.h b/drivers/dai/intel/ssp/ssp_regs_v2.h new file mode 100644 index 00000000000000..e2d1c826d075c3 --- /dev/null +++ b/drivers/dai/intel/ssp/ssp_regs_v2.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2022 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DAI_DRIVER_SSP_REGSV2_H__ +#define __INTEL_DAI_DRIVER_SSP_REGSV2_H__ + +/* SSP register offsets */ +#define SSCR0 0x00 +#define SSCR1 0x04 +#define SSSR 0x08 +#define SSITR 0x0C +#define SSTO 0x28 +#define SSPSP 0x2C +#define SSTSS 0x38 +#define SSCR2 0x40 +#define SSPSP2 0x44 + +#define SSIOC 0x4C +#define SSGFS 0x50 +#define SSDR 0x10 /* Not PTL */ +#define SSTSA 0x30 /* Not PTL */ +#define SSRSA 0x34 /* Not PTL */ + +#define OUT_FIFO SSDR +#define IN_FIFO SSDR + +/* SSCR0 bits */ +#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) +#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) +#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) +#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) +#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) +#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) +#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) +#define SSCR0_ECS BIT(6) +#define SSCR0_SSE BIT(7) +#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) +#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) +#define SSCR0_EDSS BIT(20) +#define SSCR0_NCS BIT(21) +#define SSCR0_RIM BIT(22) +#define SSCR0_TIM BIT(23) +#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) +#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) +#define SSCR0_ACS BIT(30) +#define SSCR0_MOD BIT(31) + +/* SSCR1 bits */ +#define SSCR1_RIE BIT(0) +#define SSCR1_TIE BIT(1) +#define SSCR1_LBM BIT(2) +#define SSCR1_SPO BIT(3) +#define SSCR1_SPH BIT(4) +#define SSCR1_MWDS BIT(5) +#define SSCR1_TFT_MASK DAI_INTEL_SSP_MASK(9, 6) +#define SSCR1_TFT(x) DAI_INTEL_SSP_SET_BITS(9, 6, (x) - 1) +#define SSCR1_RFT_MASK DAI_INTEL_SSP_MASK(13, 10) +#define SSCR1_RFT(x) DAI_INTEL_SSP_SET_BITS(13, 10, (x) - 1) +#define SSCR1_EFWR BIT(14) +#define SSCR1_STRF BIT(15) +#define SSCR1_IFS BIT(16) +#define SSCR1_PINTE BIT(18) +#define SSCR1_TINTE BIT(19) +#define SSCR1_RSRE BIT(20) +#define SSCR1_TSRE BIT(21) +#define SSCR1_TRAIL BIT(22) +#define SSCR1_RWOT BIT(23) +#define SSCR1_SFRMDIR BIT(24) +#define SSCR1_SCLKDIR BIT(25) +#define SSCR1_ECRB BIT(26) +#define SSCR1_ECRA BIT(27) +#define SSCR1_SCFR BIT(28) +#define SSCR1_EBCEI BIT(29) +#define SSCR1_TTE BIT(30) +#define SSCR1_TTELP BIT(31) + +#define SSCR2_TURM1 BIT(1) +#define SSCR2_PSPSRWFDFD BIT(3) +#define SSCR2_PSPSTWFDFD BIT(4) +#define SSCR2_SDFD BIT(14) +#define SSCR2_SDPM BIT(16) +#define SSCR2_LJDFD BIT(17) +#define SSCR2_MMRATF BIT(18) +#define SSCR2_SMTATF BIT(19) +#define SSCR2_SFRMEN BIT(20) +#define SSCR2_ACIOLBS BIT(21) + +/* SSR bits */ +#define SSSR_TNF BIT(2) +#define SSSR_RNE BIT(3) +#define SSSR_BSY BIT(4) +#define SSSR_TFS BIT(5) +#define SSSR_RFS BIT(6) +#define SSSR_ROR BIT(7) +#define SSSR_TUR BIT(21) + +/* SSPSP bits */ +#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) +#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSPSP_ETDS BIT(3) +#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) +#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) +#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) +#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) +#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) +#define SSPSP_DMYSTOP_BITS 2 +#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) +#define SSPSP_FSRT BIT(25) +#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) + +#define SSPSP2 0x44 +#define SSPSP2_FEP_MASK 0xff + +#define SSCR3 0x48 +#define SSIOC 0x4C +#define SSP_REG_MAX SSIOC + +/* SSTSA bits */ +#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSTSA_TXEN BIT(8) + +/* SSRSA bits */ +#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSRSA_RXEN BIT(8) + +/* SSCR3 bits */ +#define SSCR3_FRM_MST_EN BIT(0) +#define SSCR3_I2S_MODE_EN BIT(1) +#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) +#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) +#define SSCR3_I2S_TX_EN BIT(9) +#define SSCR3_I2S_RX_EN BIT(10) +#define SSCR3_CLK_EDGE_SEL BIT(12) +#define SSCR3_STRETCH_TX BIT(14) +#define SSCR3_STRETCH_RX BIT(15) +#define SSCR3_MST_CLK_EN BIT(16) +#define SSCR3_SYN_FIX_EN BIT(17) + +/* SSCR4 bits */ +#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) + +/* SSCR5 bits */ +#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) +#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) + +/* SFIFOTT bits */ +#define SFIFOTT_TX(x) ((x) - 1) +#define SFIFOTT_RX(x) (((x) - 1) << 16) + +/* SFIFOL bits */ +#define SFIFOL_TFL(x) ((x) & 0xFFFF) +#define SFIFOL_RFL(x) ((x) >> 16) + +#define SSTSA_TSEN BIT(8) +#define SSRSA_RSEN BIT(8) + +#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) +#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) +#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) +#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) + +#define SSIOC_TXDPDEB BIT(1) +#define SSIOC_SFCR BIT(4) +#define SSIOC_SCOE BIT(5) + +/* SSMIDyCS */ +#define SSMIDyCS_RXEN BIT(0) +#define SSMIDyCS_RSRE BIT(1) +#define SSMIDyCS_RFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_RFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMIDyCS_RNE BIT(26) +#define SSMIDyCS_RFS BIT(27) +#define SSMIDyCS_ROR BIT(28) +#define SSMIDyCS_PINT BIT(29) +#define SSMIDyCS_TINT BIT(30) +#define SSMIDyCS_EOC BIT(31) + +/* SSMIDyTSA */ +#define SSMIDyTSA_RTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMIDyTSA_SRTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* SSMODyCS */ +#define SSMODyCS_TXEN BIT(0) +#define SSMODyCS_TSRE BIT(1) +#define SSMODyCS_TFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_TFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMODyCS_TNF BIT(26) +#define SSMODyCS_TFS BIT(27) +#define SSMODyCS_TUR BIT(28) + +/* SSMODyTSA */ +#define SSMODyTSA_TTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMODyTSA_STTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* For 8000 Hz rate one sample is transmitted within 125us */ +#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 + +/* SSP flush retry counts maximum */ +#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 + +#define SSP_CLK_MCLK_ES_REQ BIT(0) +#define SSP_CLK_MCLK_ACTIVE BIT(1) +#define SSP_CLK_BCLK_ES_REQ BIT(2) +#define SSP_CLK_BCLK_ACTIVE BIT(3) + +#define I2SLCTL_OFFSET 0x04 +#define I2SLCTL_OFLEN BIT(4) +#define I2SLCTL_SPA(x) BIT(16 + x) +#define I2SLCTL_CPA(x) BIT(23 + x) +#define PCMS0CM_OFFSET 0x16 +#define PCMS1CM_OFFSET 0x1A + +#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) +#define SHIM_CLKCTL 0x78 +#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) +#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) + +/** \brief Offset of MCLK Divider Control Register. */ +#define MN_MDIVCTRL 0x100 + +/** \brief Offset of MCLK Divider x Ratio Register. */ +#define MN_MDIVR(x) (0x180 + (x) * 0x4) + +/** \brief Enables the output of MCLK Divider. */ +#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) + +/** \brief Bits for setting MCLK source clock. */ +#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) + +/** \brief Offset of BCLK x M/N Divider M Value Register. */ +#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) + +/** \brief Offset of BCLK x M/N Divider N Value Register. */ +#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) + +/** \brief Bits for setting M/N source clock. */ +#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) + +/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ +#define MN_SOURCE_CLKS_MASK 0x3 + +#endif /* __INTEL_DAI_DRIVER_SSP_REGSV2_H__ */ diff --git a/drivers/dai/intel/ssp/ssp_regs_v3.h b/drivers/dai/intel/ssp/ssp_regs_v3.h new file mode 100644 index 00000000000000..958c3919c6051b --- /dev/null +++ b/drivers/dai/intel/ssp/ssp_regs_v3.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2022 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DAI_DRIVER_SSP_REGSV3_H__ +#define __INTEL_DAI_DRIVER_SSP_REGSV3_H__ + +/* SSP register offsets */ +#define SSCR0 0x00 +#define SSCR1 0x04 +#define SSSR 0x08 +#define SSITR 0x0C +#define SSTO 0x28 +#define SSPSP 0x2C +#define SSTSS 0x38 +#define SSCR2 0x40 +#define SSPSP2 0x44 + +#define SSIOC 0x4C +#define SSGFS 0x50 + +#define I2SIPCMC 8 +#define SSMIDyCS(y) 0x60 + 0x10*y +#define SSMIDyD(y) 0x64 + 0x10*y +#define SSMIDyTSA(y) 0x68 + 0x10*y +#define SSMODyCS(y) 0x60 + 0x10*I2SIPCMC + 0x10*y +#define SSMODyD(y) 0x64 + 0x10*I2SIPCMC + 0x10*y +#define SSMODyTSA(y) 0x68 + 0x10*I2SIPCMC + 0x10*y + +#define OUT_FIFO SSMODyD(0) +#define IN_FIFO SSMIDyD(0) + +/* SSCR0 bits */ +#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) +#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) +#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) +#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) +#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) +#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) +#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) +#define SSCR0_RSVD1 BIT(6) +#define SSCR0_SSE BIT(7) +#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) +#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) +#define SSCR0_EDSS BIT(20) +#define SSCR0_RSVD2 BIT(21) +#define SSCR0_RIM BIT(22) +#define SSCR0_TIM BIT(23) +#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) +#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) +#define SSCR0_EFRDC BIT(27) +#define SSCR0_EFRDC2 BIT(28) +#define SSCR0_DLE DAI_INTEL_SSP_SET_BITS(30, 29, 0) +#define SSCR0_MOD BIT(31) + +/* SSCR1 bits */ +#define SSCR1_RIE BIT(0) +#define SSCR1_TIE BIT(1) +#define SSCR1_LBM BIT(2) +#define SSCR1_RSVD1 DAI_INTEL_SSP_MASK(15, 3) +#define SSCR1_IFS BIT(16) +#define SSCR1_PINTE BIT(18) +#define SSCR1_TINTE BIT(19) +#define SSCR1_RSVD21 DAI_INTEL_SSP_MASK(21, 20) +#define SSCR1_TRAIL BIT(22) +#define SSCR1_RWOT BIT(23) +#define SSCR1_SFRMDIR BIT(24) +#define SSCR1_SCLKDIR BIT(25) +#define SSCR1_SCFR BIT(28) +#define SSCR1_EBCEI BIT(29) +#define SSCR1_TTE BIT(30) +#define SSCR1_TTELP BIT(31) + +#define SSCR2_TURM1 BIT(1) +#define SSCR2_PSPSRWFDFD BIT(3) +#define SSCR2_PSPSTWFDFD BIT(4) +#define SSCR2_SDFD BIT(14) +#define SSCR2_SDPM BIT(16) +#define SSCR2_LJDFD BIT(17) +#define SSCR2_MMRATF BIT(18) +#define SSCR2_SMTATF BIT(19) +#define SSCR2_SFRMEN BIT(20) +#define SSCR2_ACIOLBS BIT(21) + +/* SSR bits */ +#define SSSR_BSY BIT(4) +#define SSSR_ROR BIT(7) +#define SSSR_TUR BIT(21) + +/* SSPSP bits */ +#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) +#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) +#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) +#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) +#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) +#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) +#define SSPSP_DMYSTOP_BITS 2 +#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) +#define SSPSP_FSRT BIT(25) +#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) + +#define SSPSP2 0x44 +#define SSPSP2_FEP_MASK 0xff + +#define SSPSP2_RFAC DAI_INTEL_SSP_MASK(9, 8) +#define SSPSP2_TFAC DAI_INTEL_SSP_MASK(11, 10) +#define SSPSP2_EFEP DAI_INTEL_SSP_MASK(13, 12) +#define SSPSP2_ESFRMDW DAI_INTEL_SSP_MASK(15, 14) + + +#define SSCR3 0x48 +#define SSIOC 0x4C +#define SSP_REG_MAX SSIOC + +/* SSTSA bits */ +#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) + +/* SSRSA bits */ +#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) + +/* SSCR3 bits */ +#define SSCR3_FRM_MST_EN BIT(0) +#define SSCR3_I2S_MODE_EN BIT(1) +#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) +#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) +#define SSCR3_I2S_TX_EN BIT(9) +#define SSCR3_I2S_RX_EN BIT(10) +#define SSCR3_CLK_EDGE_SEL BIT(12) +#define SSCR3_STRETCH_TX BIT(14) +#define SSCR3_STRETCH_RX BIT(15) +#define SSCR3_MST_CLK_EN BIT(16) +#define SSCR3_SYN_FIX_EN BIT(17) + +/* SSCR4 bits */ +#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) + +/* SSCR5 bits */ +#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) +#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) + +/* SFIFOTT bits */ +#define SFIFOTT_TX(x) ((x) - 1) +#define SFIFOTT_RX(x) (((x) - 1) << 16) + +/* SFIFOL bits */ +#define SFIFOL_TFL(x) ((x) & 0xFFFF) +#define SFIFOL_RFL(x) ((x) >> 16) + +#define SSTSA_TSEN BIT(8) +#define SSRSA_RSEN BIT(8) + +#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) +#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) +#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) +#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) + +#define SSIOC_TXDPDEB BIT(1) +#define SSIOC_SFCR BIT(4) +#define SSIOC_SCOE BIT(5) + +/* SSMIDyCS */ +#define SSMIDyCS_RXEN BIT(0) +#define SSMIDyCS_RSRE BIT(1) +#define SSMIDyCS_RFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_RFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMIDyCS_RNE BIT(26) +#define SSMIDyCS_RFS BIT(27) +#define SSMIDyCS_ROR BIT(28) +#define SSMIDyCS_PINT BIT(29) +#define SSMIDyCS_TINT BIT(30) +#define SSMIDyCS_EOC BIT(31) + +/* SSMIDyTSA */ +#define SSMIDyTSA_RTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMIDyTSA_SRTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* SSMODyCS */ +#define SSMODyCS_TXEN BIT(0) +#define SSMODyCS_TSRE BIT(1) +#define SSMODyCS_TFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_TFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMODyCS_TNF BIT(26) +#define SSMODyCS_TFS BIT(27) +#define SSMODyCS_TUR BIT(28) + +/* SSMODyTSA */ +#define SSMODyTSA_TTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMODyTSA_STTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* For 8000 Hz rate one sample is transmitted within 125us */ +#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 + +/* SSP flush retry counts maximum */ +#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 + +#define SSP_CLK_MCLK_ES_REQ BIT(0) +#define SSP_CLK_MCLK_ACTIVE BIT(1) +#define SSP_CLK_BCLK_ES_REQ BIT(2) +#define SSP_CLK_BCLK_ACTIVE BIT(3) + +#define I2SLCTL_OFFSET 0x04 + +#define I2SLCTL_OFLEN BIT(4) +#define I2SLCTL_SPA(x) BIT(16 + x) +#define I2SLCTL_CPA(x) BIT(23 + x) +#define PCMS0CM_OFFSET 0x16 +#define PCMS1CM_OFFSET PCMS0CM_OFFSET + 4 * I2SIPCMC + +#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) +#define SHIM_CLKCTL 0x78 +#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) +#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) + +/** \brief Offset of MCLK Divider Control Register. */ +#define MN_MDIVCTRL 0x100 + +/** \brief Offset of MCLK Divider x Ratio Register. */ +#define MN_MDIVR(x) (0x180 + (x) * 0x4) + +/** \brief Enables the output of MCLK Divider. */ +#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) + +/** \brief Bits for setting MCLK source clock. */ +#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) + +/** \brief Offset of BCLK x M/N Divider M Value Register. */ +#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) + +/** \brief Offset of BCLK x M/N Divider N Value Register. */ +#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) + +/** \brief Bits for setting M/N source clock. */ +#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) + +/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ +#define MN_SOURCE_CLKS_MASK 0x3 + +#endif /* __INTEL_DAI_DRIVER_SSP_REGSV1_H__ */ diff --git a/drivers/mm/mm_drv_intel_adsp.h b/drivers/mm/mm_drv_intel_adsp.h index 8de9ccc42cab62..861621a510f44d 100644 --- a/drivers/mm/mm_drv_intel_adsp.h +++ b/drivers/mm/mm_drv_intel_adsp.h @@ -30,10 +30,7 @@ #include "mm_drv_common.h" -DEVICE_MMIO_TOPLEVEL_STATIC(tlb_regs, DT_DRV_INST(0)); - -#define TLB_BASE \ - ((mm_reg_t)DEVICE_MMIO_TOPLEVEL_GET(tlb_regs)) +#define TLB_BASE (mm_reg_t)DT_REG_ADDR(DT_NODELABEL(tlb)) /* * Number of significant bits in the page index (defines the size of diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index b78a247ae0122c..5b0bc5e576be05 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -26,6 +26,7 @@ #include #include #include +#include #define SRAM_BANK_PAGE_NUM (SRAM_BANK_SIZE / CONFIG_MM_DRV_PAGE_SIZE) @@ -268,6 +269,9 @@ int sys_mm_drv_map_page(void *virt, uintptr_t phys, uint32_t flags) tlb_entries[entry_idx] = entry; +#ifdef CONFIG_MMU + arch_mem_map(virt, va, CONFIG_MM_DRV_PAGE_SIZE, flags); +#endif /* * Invalid the cache of the newly mapped virtual page to * avoid stale data. @@ -329,7 +333,7 @@ int sys_mm_drv_map_array(void *virt, uintptr_t *phys, return sys_mm_drv_simple_map_array(va, phys, cnt, flags); } -int sys_mm_drv_unmap_page(void *virt) +static int sys_mm_drv_unmap_page_wflush(void *virt, bool flush_data) { k_spinlock_key_t key; uint32_t entry_idx, bank_idx; @@ -358,8 +362,14 @@ int sys_mm_drv_unmap_page(void *virt) /* * Flush the cache to make sure the backing physical page * has the latest data. + * No flush when called from sys_mm_drv_mm_init(). */ - sys_cache_data_flush_range(virt, CONFIG_MM_DRV_PAGE_SIZE); + if (flush_data) { + sys_cache_data_flush_range(virt, CONFIG_MM_DRV_PAGE_SIZE); +#ifdef CONFIG_MMU + arch_mem_unmap(virt, CONFIG_MM_DRV_PAGE_SIZE); +#endif + } entry_idx = get_tlb_entry_idx(va); pa = tlb_entry_to_pa(tlb_entries[entry_idx]); @@ -391,6 +401,11 @@ int sys_mm_drv_unmap_page(void *virt) return ret; } +int sys_mm_drv_unmap_page(void *virt) +{ + return sys_mm_drv_unmap_page_wflush(virt, true); +} + int sys_mm_drv_unmap_region(void *virt, size_t size) { void *va = (__sparse_force void *)sys_cache_cached_ptr_get(virt); @@ -441,6 +456,42 @@ int sys_mm_drv_update_page_flags(void *virt, uint32_t flags) return ret; } +#ifdef CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM +static int sys_mm_drv_unmap_region_initial(void *virt_in, size_t size) +{ + void *virt = (__sparse_force void *)sys_cache_cached_ptr_get(virt_in); + + k_spinlock_key_t key; + int ret = 0; + size_t offset; + + CHECKIF(!sys_mm_drv_is_virt_addr_aligned(virt) || + !sys_mm_drv_is_size_aligned(size)) { + ret = -EINVAL; + goto out; + } + + key = k_spin_lock(&sys_mm_drv_common_lock); + + for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) { + uint8_t *va = (uint8_t *)virt + offset; + + int ret2 = sys_mm_drv_unmap_page_wflush(va, false); + + if (ret2 != 0) { + __ASSERT(false, "cannot unmap %p\n", va); + + ret = ret2; + } + } + + k_spin_unlock(&sys_mm_drv_common_lock, key); + +out: + return ret; +} +#endif + int sys_mm_drv_page_phys_get(void *virt, uintptr_t *phys) { uint16_t *tlb_entries = UINT_TO_POINTER(TLB_BASE); @@ -721,8 +772,9 @@ static int sys_mm_drv_mm_init(const struct device *dev) size_t unused_size = CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE - UNUSED_L2_START_ALIGNED; - ret = sys_mm_drv_unmap_region(UINT_TO_POINTER(UNUSED_L2_START_ALIGNED), - unused_size); + ret = sys_mm_drv_unmap_region_initial(UINT_TO_POINTER(UNUSED_L2_START_ALIGNED), + unused_size); + /* Need to reset max pages statistics after unmap */ for (int i = 0; i < L2_SRAM_BANK_NUM; i++) { diff --git a/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi b/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi new file mode 100644 index 00000000000000..35825e6ea6a71b --- /dev/null +++ b/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi @@ -0,0 +1,569 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <0>; + cpu-power-states = <&d0i3 &d3>; + i-cache-line-size = <64>; + d-cache-line-size = <64>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <1>; + cpu-power-states = <&d0i3 &d3>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <2>; + cpu-power-states = <&d0i3 &d3>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <3>; + cpu-power-states = <&d0i3 &d3>; + }; + + cpu4: cpu@4 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <4>; + cpu-power-states = <&d0i3 &d3>; + }; + }; + + power-states { + d0i3: idle { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + min-residency-us = <200>; + exit-latency-us = <100>; + }; + /* PM_STATE_SOFT_OFF can be entered only by calling pm_state_force. + * The procedure is triggered by IPC from the HOST (SET_DX). + */ + d3: off { + compatible = "zephyr,power-state"; + power-state-name = "soft-off"; + min-residency-us = <0>; + exit-latency-us = <0>; + status = "disabled"; + }; + }; + + sram0: memory@a0020000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0xa0020000 DT_SIZE_K(4608)>; + }; + + sram0virtual: virtualmemory@a0020000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0xa0020000 DT_SIZE_K(8192)>; + }; + + sram1: memory@a0000000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0xa0000000 DT_SIZE_K(64)>; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + clkctl: clkctl { + compatible = "intel,adsp-shim-clkctl"; + adsp-clkctl-clk-wovcro = <0>; + adsp-clkctl-clk-ipll = <1>; + adsp-clkctl-freq-enc = <0xc 0x4>; + adsp-clkctl-freq-mask = <0x0 0x0>; + adsp-clkctl-freq-default = <1>; + adsp-clkctl-freq-lowest = <0>; + wovcro-supported; + }; + + audioclk: audio-clock { + compatible = "fixed-clock"; + clock-frequency = <24576000>; + #clock-cells = <0>; + }; + + pllclk: pll-clock { + compatible = "fixed-clock"; + clock-frequency = <96000000>; + #clock-cells = <0>; + }; + + IMR1: memory@A1000000 { + compatible = "intel,adsp-imr"; + reg = <0xA1000000 DT_SIZE_M(16)>; + block-size = <0x1000>; + zephyr,memory-region = "IMR1"; + }; + + soc { + lsbpm: lsbpm@71d80 { + compatible = "intel,adsp-lsbpm"; + reg = <0x71d80 0x0008>; + }; + + hsbpm: hsbpm@17a800 { + compatible = "intel,adsp-hsbpm"; + reg = <0x17a800 0x0008>; + }; + + core_intc: core_intc@0 { + compatible = "cdns,xtensa-core-intc"; + reg = <0x00 0x400>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + hdamlddmic: hdamlddmic@cc0 { + compatible = "intel,adsp-hda-dmic-cap"; + reg = <0xcc0 0x40>; + status = "okay"; + }; + + dmic0: dai-dmic0@10100 { + compatible = "intel,dai-dmic"; + reg = <0x10100 0x8000>; + shim = <0x10000>; + fifo = <0x0008>; + interrupts = <0x08 0 0>; + interrupt-parent = <&ace_intc>; + power-domain = <&hub_ulp_domain>; + }; + + dmic1: dai-dmic1@10100 { + compatible = "intel,dai-dmic"; + reg = <0x10100 0x8000>; + shim = <0x10000>; + fifo = <0x0108>; + interrupts = <0x08 0 0>; + interrupt-parent = <&ace_intc>; + power-domain = <&hub_ulp_domain>; + }; + + dmicvss: dmicvss@16000 { + compatible = "intel,adsp-dmic-vss"; + reg = <0x16000 0x2000>; + status = "okay"; + }; + + /* + * FIXME this is modeling individual alh channels/instances + * with node labels, which has problems. A better representation + * is discussed here: + * + * https://github.com/zephyrproject-rtos/zephyr/pull/50287#discussion_r974591009 + */ + alh0: alh0@24400 { + compatible = "intel,alh-dai"; + reg = <0x00024400 0x00024600>; + status = "okay"; + }; + + alh1: alh1@24400 { + compatible = "intel,alh-dai"; + reg = <0x00024400 0x00024600>; + status = "okay"; + }; + + sspbase: ssp_base@28000 { + compatible = "intel,ssp-sspbase"; + reg = <0x28000 0x1000>; + }; + + hdamlssp: hdamlssp@d00 { + compatible = "intel,adsp-hda-ssp-cap"; + reg = <0xD00 0x40>; + status = "okay"; + }; + + ssp0: ssp@28100 { + compatible = "intel,ssp"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x00028100 0x1000 + 0x00079C00 0x200>; + interrupts = <0x00 0 0>; + interrupt-parent = <&ace_intc>; + dmas = <&hda_link_out 1 + &hda_link_in 1>; + dma-names = "tx", "rx"; + ssp-index = <0>; + power-domain = <&io0_domain>; + status = "okay"; + + ssp00: ssp@0 { + compatible = "intel,ssp-dai"; + reg = <0x0>; + status = "okay"; + }; + }; + + ssp1: ssp@29100 { + compatible = "intel,ssp"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x00029100 0x1000 + 0x00079C00 0x200>; + interrupts = <0x01 0 0>; + interrupt-parent = <&ace_intc>; + dmas = <&hda_link_out 2 + &hda_link_in 2>; + dma-names = "tx", "rx"; + ssp-index = <1>; + power-domain = <&io0_domain>; + status = "okay"; + + ssp10: ssp@10 { + compatible = "intel,ssp-dai"; + reg = <0x10>; + status = "okay"; + }; + }; + + ssp2: ssp@2a100 { + compatible = "intel,ssp"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0002a100 0x1000 + 0x00079C00 0x200>; + interrupts = <0x02 0 0>; + interrupt-parent = <&ace_intc>; + dmas = <&hda_link_out 3 + &hda_link_in 3>; + dma-names = "tx", "rx"; + ssp-index = <2>; + power-domain = <&io0_domain>; + status = "okay"; + + ssp20: ssp@20 { + compatible = "intel,ssp-dai"; + reg = <0x20>; + status = "okay"; + }; + }; + + mem_window0: mem_window@70200 { + compatible = "intel,adsp-mem-window"; + reg = <0x70200 0x8>; + offset = <0x4000>; + memory = <&sram0>; + initialize; + read-only; + }; + + mem_window1: mem_window@70208 { + compatible = "intel,adsp-mem-window"; + reg = <0x70208 0x8>; + memory = <&sram0>; + }; + + mem_window2: mem_window@70210 { + compatible = "intel,adsp-mem-window"; + reg = <0x70210 0x8>; + memory = <&sram0>; + }; + + mem_window3: mem_window@70218 { + compatible = "intel,adsp-mem-window"; + reg = <0x70218 0x8>; + memory = <&sram0>; + read-only; + }; + + adsp_idc: ace_idc@92000 { + compatible = "intel,adsp-idc"; + reg = <0x92000 0x0400>; + interrupts = <24 0 0>; + interrupt-parent = <&ace_intc>; + }; + + dfpmcch: dfpmcch@71ac0 { + compatible = "intel,adsp-dfpmcch"; + reg = <0x00071ac0 0x40>; + }; + + dfpmccu: dfpmccu@71b00 { + compatible = "intel,adsp-dfpmccu"; + reg = <0x71b00 0x100>; + + hub_ulp_domain: hub_ulp_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <15>; + }; + hub_hp_domain: hub_hpp_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <6>; + }; + io0_domain: io0_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <8>; + }; + io1_domain: io1_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <9>; + }; + io2_domain: io2_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <10>; + }; + io3_domain: io3_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <11>; + }; + hst_domain: hst_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <5>; + }; + ml0_domain: ml0_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <12>; + }; + ml1_domain: ml1_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <13>; + }; + }; + + shim: shim@71f00 { + compatible = "intel,cavs-shim"; + reg = <0x71f00 0x100>; + }; + + tts: tts@72000 { + compatible = "intel,adsp-tts"; + reg = <0x72000 0x70>; + status = "okay"; + }; + + ace_rtc_counter: ace_rtc_counter@72008 { + compatible = "intel,ace-rtc-counter"; + reg = <0x72008 0x0064>; + }; + + ace_timestamp: ace_timestamp@72040 { + compatible = "intel,ace-timestamp"; + reg = <0x72040 0x0032>; + }; + + ace_art_counter: ace_art_counter@72058 { + compatible = "intel,ace-art-counter"; + reg = <0x72058 0x0064>; + }; + + hda_host_out: dma@72800 { + compatible = "intel,adsp-hda-host-out"; + #dma-cells = <1>; + reg = <0x00072800 0x40>; + dma-channels = <9>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&hst_domain>; + interrupts = <13 0 0>; + interrupt-parent = <&ace_intc>; + status = "okay"; + }; + + hda_host_in: dma@72c00 { + compatible = "intel,adsp-hda-host-in"; + #dma-cells = <1>; + reg = <0x00072c00 0x40>; + dma-channels = <11>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&hst_domain>; + interrupts = <12 0 0>; + interrupt-parent = <&ace_intc>; + status = "okay"; + }; + + adsp_host_ipc: ace_host_ipc@73000 { + compatible = "intel,adsp-host-ipc"; + status = "okay"; + reg = <0x73000 0x30>; + interrupts = <0 0 0>; + interrupt-parent = <&ace_intc>; + }; + + hda_link_out: dma@79400 { + compatible = "intel,adsp-hda-link-out"; + #dma-cells = <1>; + reg = <0x00079400 0x40>; + dma-channels = <9>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&io0_domain>; + status = "okay"; + }; + + hda_link_in: dma@79800 { + compatible = "intel,adsp-hda-link-in"; + #dma-cells = <1>; + reg = <0x00079800 0x40>; + dma-channels = <11>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&io0_domain>; + status = "okay"; + }; + + /* This is actually an array of per-core designware + * controllers, but the special setup and extra + * masking layer makes it easier for MTL to handle + * this internally. + */ + ace_intc: ace_intc@94000 { + compatible = "intel,ace-intc"; + reg = <0x94000 0xc00>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = <4 0 0>; + num-irqs = <28>; + interrupt-parent = <&core_intc>; + }; + + tlb: tlb@17e000 { + compatible = "intel,adsp-mtl-tlb"; + reg = <0x17e000 0x1000>; + paddr-size = <12>; + exec-bit-idx = <14>; + write-bit-idx= <15>; + }; + + timer: timer { + compatible = "intel,adsp-timer"; + syscon = <&tts>; + }; + }; + + hdas { + #address-cells = <1>; + #size-cells = <0>; + + hda0: hda@0 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0>; + }; + hda1: hda@1 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <1>; + }; + hda2: hda@2 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <2>; + }; + hda3: hda@3 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <3>; + }; + hda4: hda@4 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <4>; + }; + hda5: hda@5 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <5>; + }; + hda6: hda@6 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <6>; + }; + hda7: hda@7 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <7>; + }; + hda8: hda@8 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <8>; + }; + hda9: hda@9 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <9>; + }; + hda10: hda@a { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0a>; + }; + hda11: hda@b { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0b>; + }; + hda12: hda@c { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0c>; + }; + hda13: hda@d { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0d>; + }; + hda14: hda@e { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0e>; + }; + hda15: hda@f { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0f>; + }; + hda16: hda@10 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x10>; + }; + hda17: hda@11 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x11>; + }; + hda18: hda@12 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x12>; + }; + }; +}; diff --git a/soc/intel/intel_adsp/Kconfig b/soc/intel/intel_adsp/Kconfig index 135fecb575aa3e..1a0cc4350d4f3d 100644 --- a/soc/intel/intel_adsp/Kconfig +++ b/soc/intel/intel_adsp/Kconfig @@ -8,6 +8,8 @@ config SOC_FAMILY_INTEL_ADSP select ARCH_SUPPORTS_COREDUMP select CPU_HAS_DCACHE select ARCH_HAS_USERSPACE if XTENSA_MMU + imply XTENSA_MMU_DOUBLE_MAP + select ARCH_HAS_USERSPACE if XTENSA_MMU select CPU_CACHE_INCOHERENT if SOC_FAMILY_INTEL_ADSP diff --git a/soc/intel/intel_adsp/ace/CMakeLists.txt b/soc/intel/intel_adsp/ace/CMakeLists.txt index 919e7993427dbb..0c9c43eb3393c9 100644 --- a/soc/intel/intel_adsp/ace/CMakeLists.txt +++ b/soc/intel/intel_adsp/ace/CMakeLists.txt @@ -19,4 +19,8 @@ zephyr_include_directories(include/${CONFIG_SOC}) zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget.c) zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget_messages.c) +if (CONFIG_XTENSA_MMU) + zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_ACE30_PTL mmu_ptl.c) +endif() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/intel/intel_adsp/ace/Kconfig b/soc/intel/intel_adsp/ace/Kconfig index ff86472466ead2..96778d274a45ae 100644 --- a/soc/intel/intel_adsp/ace/Kconfig +++ b/soc/intel/intel_adsp/ace/Kconfig @@ -14,6 +14,7 @@ config SOC_SERIES_INTEL_ADSP_ACE select HAS_PM select XTENSA_CPU_HAS_HIFI3 select XTENSA_CPU_HAS_HIFI4 + select ARCH_HAS_RESERVED_PAGE_FRAMES if MMU config SOC_INTEL_COMM_WIDGET bool "Intel Communication Widget driver" diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace30_ptl b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace30_ptl new file mode 100644 index 00000000000000..f7e0f19008f221 --- /dev/null +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace30_ptl @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + + +if SOC_INTEL_ACE30_PTL + +config MP_MAX_NUM_CPUS + default 5 + +config CPU_HAS_MMU + def_bool y + +config XTENSA_MMU + def_bool y + +config XTENSA_MMU_NUM_L2_TABLES + # Need to have enough to accommodate samples and tests. + # Also need to have some room for future expansions or + # else we will be chasing changes all the time. + default 64 + +endif diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.series b/soc/intel/intel_adsp/ace/Kconfig.defconfig.series index a860d74422693b..e96c890ff6c166 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.defconfig.series +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.series @@ -50,6 +50,9 @@ config SYS_CLOCK_TICKS_PER_SEC config XTENSA_CCOUNT_HZ default 393216000 +config INTEL_ADSP_TIMER + default y + config DYNAMIC_INTERRUPTS default y diff --git a/soc/intel/intel_adsp/ace/Kconfig.soc b/soc/intel/intel_adsp/ace/Kconfig.soc index 3cab72f8f51d8b..89ef2eb30dbd5f 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.soc +++ b/soc/intel/intel_adsp/ace/Kconfig.soc @@ -20,12 +20,21 @@ config SOC_INTEL_ACE20_LNL help ACE 2.0 Lunar Lake PCH +config SOC_INTEL_ACE30_PTL + bool + select SOC_SERIES_INTEL_ADSP_ACE + help + ACE 3.0 Panther Lake PCH + config SOC_SERIES default "intel_adsp_ace" if SOC_SERIES_INTEL_ADSP_ACE config SOC_TOOLCHAIN_NAME - default "intel_ace15_mtpm" if SOC_SERIES_INTEL_ADSP_ACE + default "intel_ace15_mtpm" if SOC_INTEL_ACE15_MTPM + default "intel_ace15_mtpm" if SOC_INTEL_ACE20_LNL + default "intel_ace30_ptl" if SOC_INTEL_ACE30_PTL config SOC default "ace15_mtpm" if SOC_INTEL_ACE15_MTPM default "ace20_lnl" if SOC_INTEL_ACE20_LNL + default "ace30_ptl" if SOC_INTEL_ACE30_PTL diff --git a/soc/intel/intel_adsp/ace/ace-link.ld b/soc/intel/intel_adsp/ace/ace-link.ld index 454893055e1712..8aaf7c75c1b26b 100644 --- a/soc/intel/intel_adsp/ace/ace-link.ld +++ b/soc/intel/intel_adsp/ace/ace-link.ld @@ -37,11 +37,21 @@ ENTRY(rom_entry); */ #ifdef CONFIG_KERNEL_COHERENCE #define RPO_SET(addr, reg) ((addr & 0x1fffffff) | (reg << 29)) +#ifdef CONFIG_MMU +#define SEGSTART_CACHED RPO_SET(ALIGN(CONFIG_MMU_PAGE_SIZE), CONFIG_XTENSA_CACHED_REGION) +#define SEGSTART_UNCACHED RPO_SET(ALIGN(CONFIG_MMU_PAGE_SIZE), CONFIG_XTENSA_UNCACHED_REGION) +#else #define SEGSTART_CACHED RPO_SET(ALIGN(64), CONFIG_XTENSA_CACHED_REGION) #define SEGSTART_UNCACHED RPO_SET(ALIGN(64), CONFIG_XTENSA_UNCACHED_REGION) +#endif +#else +#ifdef CONFIG_MMU +#define SEGSTART_CACHED ALIGN(CONFIG_MMU_PAGE_SIZE) +#define SEGSTART_UNCACHED ALIGN(CONFIG_MMU_PAGE_SIZE) #else #define SEGSTART_CACHED . #define SEGSTART_UNCACHED . +#endif #define ucram ram #endif @@ -56,6 +66,18 @@ ENTRY(rom_entry); #define NOLOAD_BASE 0x20000 #define NOLOAD_SIZE 0x100000 +#ifdef CONFIG_MMU +#define MMU_PAGE_ALIGN . = ALIGN(CONFIG_MMU_PAGE_SIZE); +#define HDR_MMU_PAGE_ALIGN ALIGN(CONFIG_MMU_PAGE_SIZE) +#define HDR_4K_OR_MMU_PAGE_ALIGN ALIGN(CONFIG_MMU_PAGE_SIZE) +#else +#define MMU_PAGE_ALIGN +#define HDR_MMU_PAGE_ALIGN +#define HDR_4K_OR_MMU_PAGE_ALIGN ALIGN(4096) +#endif + +#define SMEM_PARTITION_ALIGN(size) MMU_PAGE_ALIGN + MEMORY { vector_base_text : org = VECBASE_RESET_PADDR_SRAM, @@ -102,6 +124,11 @@ MEMORY { vector_double_text : org = DOUBLEEXC_VECTOR_PADDR_SRAM, len = MEM_VECT_TEXT_SIZE +#ifdef CONFIG_XTENSA_MMU + xtensa_vector_code : + org = DOUBLEEXC_VECTOR_PADDR_SRAM + MEM_VECT_TEXT_SIZE, + len = RAM_BASE - (DOUBLEEXC_VECTOR_PADDR_SRAM + MEM_VECT_TEXT_SIZE) +#endif imr : org = IMR_BOOT_LDR_TEXT_ENTRY_BASE, len = 0x100000 @@ -233,22 +260,77 @@ SECTIONS { _DoubleExceptionVector_text_end = .; } >vector_double_text - .text : { +#ifdef CONFIG_XTENSA_MMU + .xtensa_vector_code : { + /* There is not much space between .DoubleExceptionVector + * and the beginning of .text. So need to be careful on + * what to put in this section. It would mostly be things + * that are required to handle exceptions and interrupts. + * Also things we want to avoid TLB misses during exception + * handling. + */ + + *libarch__xtensa__core.a:xtensa_asm2_util.S.obj(.literal) + *libarch__xtensa__core.a:xtensa_asm2_util.S.obj(.iram.text) + *libarch__xtensa__core.a:xtensa_asm2_util.S.obj(.text) + + *libarch__xtensa__core.a:window_vectors.S.obj(.iram.text) + + /* For _Level1Vector */ + *libarch__xtensa__core.a:vector_handlers_util.S.obj(.iram0.text) + + *libarch__xtensa__core.a:vector_handlers.c.obj(.literal.xtensa_int?_c) + *libarch__xtensa__core.a:vector_handlers.c.obj(.text.xtensa_int?_c) + + *libarch__xtensa__core.a:userspace.S.obj(.literal.xtensa_do_syscall) + *libarch__xtensa__core.a:userspace.S.obj(.text.xtensa_do_syscall) + + } > xtensa_vector_code +#endif /* CONFIG_XTENSA_MMU */ + + .text : HDR_MMU_PAGE_ALIGN + { __text_region_start = .; + _image_ram_start = .; + z_mapped_start = .; *(.iram1 .iram1.*) *(.entry.text) *(.init.literal) *(.iram0.text) + +#ifdef CONFIG_XTENSA_MMU + /* + * The C handle blows up in size significantly when logging is enabled. + * So we can't keep this in .xtensa_vector_code above. Though we try to + * leep these close enough that, hopefully, we can avoid TLB misses. + */ + *libarch__xtensa__core.a:vector_handlers.c.obj(.literal.xtensa_excint1_c) + *libarch__xtensa__core.a:vector_handlers.c.obj(.text.xtensa_excint1_c) + + /* + * Experiment shows that system would not boot if this is away from + * VECBASE more than a few pages. So workaround the issue by putting + * xtensa_mmu_init() here. + */ + *libarch__xtensa__core.a:ptables.c.obj(.literal.xtensa_mmu_init) + *libarch__xtensa__core.a:ptables.c.obj(.text.xtensa_mmu_init) +#endif + KEEP(*(.init)) KEEP(*(.lps_vector)) - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + MMU_PAGE_ALIGN + *(.literal .text) + *(.literal.* .text.*) *(.fini.literal) KEEP(*(.fini)) *(.gnu.version) +#include + MMU_PAGE_ALIGN __text_region_end = .; } >ram - .rodata : ALIGN(4096) + .rodata : HDR_4K_OR_MMU_PAGE_ALIGN { __rodata_region_start = .; *(.rodata) @@ -258,6 +340,7 @@ SECTIONS { . = ALIGN(4); #include + #include __XT_EXCEPTION_TABLE__ = .; KEEP (*(.xt_except_table)) @@ -277,14 +360,14 @@ SECTIONS { *(.xt_except_desc_end) *(.dynamic) *(.gnu.version_d) - _image_ram_start = .; _bss_table_start = .; LONG(_bss_start) LONG(_bss_end) _bss_table_end = .; + MMU_PAGE_ALIGN } >ram - .module_init : { + .module_init : HDR_MMU_PAGE_ALIGN { _module_init_start = .; *(*.initcall) _module_init_end = .; @@ -292,21 +375,22 @@ SECTIONS { #define RAMABLE_REGION ram #define ROMABLE_REGION ram -#include - __rodata_region_end = .; - .fw_ready : { - KEEP(*(".fw_ready")); - KEEP (*(.fw_ready_metadata)) - } >ram + __common_rom_region_start = SEGSTART_CACHED; +#include + __common_rom_region_end = .; + __rodata_region_end = .; - .noinit SEGSTART_UNCACHED : { + .noinit SEGSTART_UNCACHED : HDR_MMU_PAGE_ALIGN { + __data_start = .; *(.noinit) *(.noinit.*) } >ucram - .data SEGSTART_UNCACHED : { - __data_start = .; +#include + . = SEGSTART_UNCACHED; + + .data SEGSTART_UNCACHED : HDR_MMU_PAGE_ALIGN { *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -324,6 +408,7 @@ SECTIONS { _trace_ctx_end = ABSOLUTE(.); *(.gna_model) __data_end = .; + MMU_PAGE_ALIGN } >ucram .lit4 SEGSTART_CACHED : { @@ -344,7 +429,28 @@ SECTIONS { #define RAMABLE_REGION ucram #define ROMABLE_REGION ucram + .fw_ready SEGSTART_UNCACHED : { + KEEP(*(".fw_ready")); + KEEP (*(.fw_ready_metadata)) + } > ucram + + __common_ram_region_start = .; + +#ifdef CONFIG_USERSPACE + +#define APP_SHARED_ALIGN MMU_PAGE_ALIGN +#define EMPTY_APP_SHARED_ALIGN APP_SHARED_ALIGN + + /* APP SHARED MEMORY REGION */ +#include + _app_smem_size = _app_smem_end - _app_smem_start; + _app_smem_num_words = _app_smem_size >> 2; + _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); +#endif /* CONFIG_USERSPACE */ + #include +#include + __common_ram_region_end = .; .tm_clone_table : { *(.tm_clone_table) @@ -356,6 +462,11 @@ SECTIONS { .cached SEGSTART_CACHED : { _cached_start = .; *(.cached .cached.*) +#ifdef CONFIG_USERSPACE + z_user_stacks_start = .; + *(.user_stacks*) + z_user_stacks_end = .; +#endif _cached_end = .; } >ram @@ -384,6 +495,7 @@ SECTIONS { *(.gnu.linkonce.b.*) *(COMMON) . = ALIGN(8); + MMU_PAGE_ALIGN _bss_end = .; } >ucram @@ -410,17 +522,19 @@ SECTIONS { . = SEGSTART_UNCACHED; _end = ALIGN(8); . = SEGSTART_CACHED; + z_mapped_end = .; . = L2_SRAM_BASE + L2_SRAM_SIZE; . = SEGSTART_UNCACHED; _heap_end = .; _heap_sentry = .; + . = SEGSTART_CACHED; + _image_ram_end = .; /* dma buffers */ .lpbuf (NOLOAD): { _dma_buf_start = .; *(.dma_buffers) _dma_buf_end = .; - _image_ram_end = .; } >lpram /* Non-loadable sections below. Back to cached memory so diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_boot.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_boot.h new file mode 100644 index 00000000000000..6cc07538da0c7f --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_boot.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_INTEL_ADSP_BOOT_H_ +#define ZEPHYR_SOC_INTEL_ADSP_BOOT_H_ + +#define DSPCS_REG 0x178d00 + +struct dspcs { + /* + * DSPCSx + * DSP Core Shim + * + * These registers are added by Intel outside of the Tensilica Core for general operation + * control, such as reset, stall, power gating, clock gating etc. + * Note: These registers are accessible through the host space or DSP space depending on + * ownership, as governed by SAI and RS. + */ + struct { + uint32_t cap; + uint32_t ctl; + } capctl[5]; + uint32_t unused0[6]; + + /* + * DSPBRx + * DSP Boot / Recovery + * + * These registers are added by Intel outside of the Tensilica Core for boot / recovery + * control, such as boot path, watch dog timer etc. + */ + struct { + uint32_t brcap; + uint32_t wdtcs; + uint32_t wdtipptr; + uint32_t unused1; + uint32_t bctl; + uint32_t baddr; + uint32_t battr; + uint32_t unused2; + } bootctl[5]; +}; + +#define DSPCS_CTL_SPA BIT(0) +#define DSPCS_CTL_CPA BIT(8) + +#define DSPBR_BCTL_BYPROM BIT(0) +#define DSPBR_BCTL_WAITIPCG BIT(16) +#define DSPBR_BCTL_WAITIPPG BIT(17) + +#define DSPBR_BATTR_LPSCTL_RESTORE_BOOT BIT(12) +#define DSPBR_BATTR_LPSCTL_HP_CLOCK_BOOT BIT(13) +#define DSPBR_BATTR_LPSCTL_LP_CLOCK_BOOT BIT(14) +#define DSPBR_BATTR_LPSCTL_L1_MIN_WAY BIT(15) +#define DSPBR_BATTR_LPSCTL_BATTR_SLAVE_CORE BIT(16) + +#define DSPBR_WDT_RESUME BIT(8) +#define DSPBR_WDT_RESTART_COMMAND 0x76 + +#define DSPCS (*(volatile struct dspcs *)DSPCS_REG) + +#endif /* ZEPHYR_SOC_INTEL_ADSP_BOOT_H_ */ diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_interrupt.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_interrupt.h new file mode 100644 index 00000000000000..bf912746d66b7f --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_interrupt.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_INTEL_ADSP_INTERRUPT_H_ +#define ZEPHYR_SOC_INTEL_ADSP_INTERRUPT_H_ + +/* Low priority interrupt indices */ +#define ACE_INTL_HIPC 0 +#define ACE_INTL_SBIPC 1 +#define ACE_INTL_ML 2 +#define ACE_INTL_IDCA 3 +#define ACE_INTL_LPVML 4 +#define ACE_INTL_SHA 5 +#define ACE_INTL_L1L2M 6 +#define ACE_INTL_I2S 7 +#define ACE_INTL_DMIC 8 +#define ACE_INTL_SNDW 9 +#define ACE_INTL_TTS 10 +#define ACE_INTL_WDT 11 +#define ACE_INTL_HDAHIDMA 12 +#define ACE_INTL_HDAHODMA 13 +#define ACE_INTL_HDALIDMA 14 +#define ACE_INTL_HDALODMA 15 +#define ACE_INTL_I3C 16 +#define ACE_INTL_GPDMA 17 +#define ACE_INTL_PWM 18 +#define ACE_INTL_I2C 19 +#define ACE_INTL_SPI 20 +#define ACE_INTL_UART 21 +#define ACE_INTL_GPIO 22 +#define ACE_INTL_UAOL 23 +#define ACE_INTL_IDCB 24 +#define ACE_INTL_DCW 25 +#define ACE_INTL_DTF 26 +#define ACE_INTL_FLV 27 +#define ACE_INTL_DPDMA 28 + +/* Device interrupt control for the low priority interrupts. It + * provides per-core masking and status checking: ACE_DINT is an array + * of these structs, one per core. The state is in the bottom bits, + * indexed by ACE_INTL_*. Note that some of these use more than one + * bit to discriminate sources (e.g. TTS's bits 0-2 are + * timestamp/comparator0/comparator1). It seems safe to write all 1's + * to the short to "just enable everything", but drivers should + * probably implement proper logic. + * + * Note that this block is independent of the Designware controller + * that manages the shared IRQ. Interrupts need to unmasked in both + * in order to be delivered to software. Per simulator source code, + * this is "upstream" of DW: an interrupt will not be latched into the + * status registers of the DW controller unless the IE bits here are + * set. That seems unlikely to correctly capture the hardware + * behavior (it would mean that the DW controller was being + * independently triggered multiple times by each core!). Beware. + * + * Enable an interrupt for a core with e.g.: + * + * ACE_DINT[core_id].ie[ACE_INTL_TTS] = 0xffff; + */ +struct ace_dint { + uint16_t ie[32]; /* enable */ + uint16_t is[32]; /* status (potentially masked by ie) */ + uint16_t irs[32]; /* "raw" status (hardware input state) */ + uint32_t unused[16]; +}; + +/* This register enables (1) or disable (0) the interrupt of + * each host inter-processor communication capability instance in a single register. + */ +#define DXHIPCIE_REG 0x91040 + +#define ACE_DINT ((volatile struct ace_dint *)DXHIPCIE_REG) +#define XTENSA_IRQ_NUM_MASK 0xff +#define XTENSA_IRQ_NUM_SHIFT 0 + +#define XTENSA_IRQ_NUMBER(_irq) ((_irq >> XTENSA_IRQ_NUM_SHIFT) & XTENSA_IRQ_NUM_MASK) +/* Convert between IRQ_CONNECT() numbers and ACE_INTL_* interrupts */ +#define ACE_IRQ_NUM_SHIFT 8 +#define ACE_IRQ_NUM_MASK 0xFFU +#define ACE_IRQ_FROM_ZEPHYR(_irq) (((_irq >> ACE_IRQ_NUM_SHIFT) & ACE_IRQ_NUM_MASK) - 1) + +#define ACE_INTC_IRQ DT_IRQN(DT_NODELABEL(ace_intc)) +#define ACE_IRQ_TO_ZEPHYR(_irq) \ + ((((_irq + 1) & ACE_IRQ_NUM_MASK) << ACE_IRQ_NUM_SHIFT) + ACE_INTC_IRQ) + +#endif diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_ipc_regs.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_ipc_regs.h new file mode 100644 index 00000000000000..c91e511c96c0ce --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_ipc_regs.h @@ -0,0 +1,83 @@ +/* Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_SOC_INTEL_ADSP_ACE_IPC_REGS_H +#define ZEPHYR_SOC_INTEL_ADSP_ACE_IPC_REGS_H + +#include +#include + +/** + * @file + * + * Inter Processor Communication - used for sending interrupts to and receiving + * them from another device. ACE uses it to talk to the host and the CSME. + * In general there is one of these blocks instantiated for each endpoint of a + * connection. + */ + +/** + * @brief IPC registers layout for Intel ADSP ACE1X SoC family. + */ +struct intel_adsp_ipc { + uint32_t tdr; + uint32_t tda; + uint32_t unused0[2]; + uint32_t idr; + uint32_t ida; + uint32_t unused1[2]; + uint32_t cst; + uint32_t csr; + uint32_t ctl; + uint32_t cap; + uint32_t unused2[52]; + uint32_t tdd; + uint32_t unused3[31]; + uint32_t idd; +}; + +/** + * @brief Set TDA busy bit. + * + * On ACE SoC family boards TDA bit 31 (BUSY) during IPC doorbell acknowledgment + * must be cleared (!), not set (in contrary to CAVS SoC family boards). + * This clears BUSY on the other side of the connection in IDR register. + */ +#define INTEL_ADSP_IPC_ACE1X_TDA_DONE 0 +#define INTEL_ADSP_IPC_BUSY BIT(31) +#define INTEL_ADSP_IPC_DONE BIT(31) + +#define INTEL_ADSP_IPC_CTL_TBIE BIT(0) +#define INTEL_ADSP_IPC_CTL_IDIE BIT(1) +/** + * @brief ACE SoC family Intra DSP Communication. + * + * ACE SoC platform family provides an array of IPC endpoints to be used for + * peer-to-peer communication between DSP cores - master to slave and backwards. + * Given endpoint can be accessed by: + * @code + * IDC[slave_core_id].agents[agent_id].ipc; + * @endcode + */ +struct ace_idc { + /** + * @brief IPC Agent Endpoints. + * + * Each connection is organized into two "agents" ("A" - master core and "B" - slave core). + * Each agent is wired to its own interrupt. + * Agents array represents mutually exclusive IPC endpoint access: + * (A=1/B=0) - agents[0]. + * (A=0/B=1) - agents[1]. + */ + union { + int8_t unused[512]; + struct intel_adsp_ipc ipc; + } agents[2]; +}; + +/** + * @brief Defines register for intra DSP communication. + */ +#define IDC ((volatile struct ace_idc *)INTEL_ADSP_IDC_REG_ADDRESS) + +#endif /* ZEPHYR_SOC_INTEL_ADSP_ACE_IPC_REGS_H */ diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_memory.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_memory.h new file mode 100644 index 00000000000000..1596cb489d3501 --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_memory.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_INTEL_ADSP_MEMORY_H_ +#define ZEPHYR_SOC_INTEL_ADSP_MEMORY_H_ + + +#include +#include +#include +#include + +#define L2_SRAM_BASE (DT_REG_ADDR(DT_NODELABEL(sram0))) +#define L2_SRAM_SIZE (DT_REG_SIZE(DT_NODELABEL(sram0))) + +#define L2_VIRTUAL_SRAM_BASE (DT_REG_ADDR(DT_NODELABEL(sram0virtual))) +#define L2_VIRTUAL_SRAM_SIZE (DT_REG_SIZE(DT_NODELABEL(sram0virtual))) + +#define LP_SRAM_BASE (DT_REG_ADDR(DT_NODELABEL(sram1))) +#define LP_SRAM_SIZE (DT_REG_SIZE(DT_NODELABEL(sram1))) + +#define ROM_JUMP_ADDR (LP_SRAM_BASE + 0x10) + +/* Linker-usable RAM region */ +#define RAM_BASE (L2_SRAM_BASE + CONFIG_HP_SRAM_RESERVE + VECTOR_TBL_SIZE) +#define RAM_SIZE (L2_SRAM_SIZE - CONFIG_HP_SRAM_RESERVE - VECTOR_TBL_SIZE) + + +/* L3 region (IMR), located in host memory */ + +#define L3_MEM_BASE_ADDR (DT_REG_ADDR(DT_NODELABEL(imr1))) +#define L3_MEM_SIZE (DT_REG_SIZE(DT_NODELABEL(imr1))) +#define L3_MEM_PAGE_SIZE (DT_PROP(DT_NODELABEL(imr1), block_size)) + +/* The rimage tool produces two blob addresses we need to find: one is + * our bootloader code block which starts at its entry point, the + * other is the "manifest" containing the HP-SRAM data to unpack, + * which appears 24k earlier in the DMA'd file, and thus in IMR + * memory. There's no ability to change this offset, it's a magic + * number from rimage we simply need to honor. + */ +#define IMR_BOOT_LDR_MANIFEST_OFFSET 0x42000 +#define IMR_BOOT_LDR_MANIFEST_SIZE 0x6000 +#define IMR_BOOT_LDR_MANIFEST_BASE (L3_MEM_BASE_ADDR + IMR_BOOT_LDR_MANIFEST_OFFSET) + +#define IMR_BOOT_LDR_TEXT_ENTRY_SIZE 0x180 +#define IMR_BOOT_LDR_TEXT_ENTRY_BASE (IMR_BOOT_LDR_MANIFEST_BASE + IMR_BOOT_LDR_MANIFEST_SIZE) + +#define IMR_BOOT_LDR_LIT_SIZE 0x40 +#define IMR_BOOT_LDR_LIT_BASE (IMR_BOOT_LDR_TEXT_ENTRY_BASE + \ + IMR_BOOT_LDR_TEXT_ENTRY_SIZE) + +#define IMR_BOOT_LDR_TEXT_SIZE 0x1C00 +#define IMR_BOOT_LDR_TEXT_BASE (IMR_BOOT_LDR_LIT_BASE + IMR_BOOT_LDR_LIT_SIZE) + +#define IMR_BOOT_LDR_DATA_OFFSET 0x49000 +#define IMR_BOOT_LDR_DATA_BASE (L3_MEM_BASE_ADDR + IMR_BOOT_LDR_DATA_OFFSET) +#define IMR_BOOT_LDR_DATA_SIZE 0xA8000 + +#define IMR_BOOT_LDR_BSS_OFFSET 0x110000 +#define IMR_BOOT_LDR_BSS_BASE (L3_MEM_BASE_ADDR + IMR_BOOT_LDR_BSS_OFFSET) +#define IMR_BOOT_LDR_BSS_SIZE 0x10000 + +/* stack to be used at boot, when RAM is not yet powered up */ +#define IMR_BOOT_LDR_STACK_BASE (IMR_BOOT_LDR_BSS_BASE + IMR_BOOT_LDR_BSS_SIZE) +#define IMR_BOOT_LDR_STACK_SIZE 0x1000 + +/* position of L3 heap, size of L3 heap - till end of the L3 memory */ +#define IMR_L3_HEAP_BASE (IMR_BOOT_LDR_STACK_BASE + IMR_BOOT_LDR_STACK_SIZE) +#define IMR_L3_HEAP_SIZE (L3_MEM_SIZE - \ + (IMR_L3_HEAP_BASE - L3_MEM_BASE_ADDR)) + +#define ADSP_L1_CACHE_PREFCTL_VALUE 0x1038 + +/* L1 init */ +#define ADSP_L1CC_ADDR (0x3FE80080) +#define ADSP_CxL1CCAP_ADDR (ADSP_L1CC_ADDR + 0x0000) +#define ADSP_CxL1CCFG_ADDR (ADSP_L1CC_ADDR + 0x0004) +#define ADSP_CxL1PCFG_ADDR (ADSP_L1CC_ADDR + 0x0008) + +#if (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)) + +#define ADSP_CxL1CCAP_REG (*(volatile uint32_t *)(ADSP_CxL1CCAP_ADDR)) +#define ADSP_CxL1CCFG_REG (*(volatile uint32_t *)(ADSP_CxL1CCFG_ADDR)) +#define ADSP_CxL1PCFG_REG (*(volatile uint32_t *)(ADSP_CxL1PCFG_ADDR)) + +#endif /* (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)) */ + +/* The number of set associative cache way supported on L1 Data Cache */ +#define ADSP_CxL1CCAP_DCMWC ((ADSP_CxL1CCAP_REG >> 16) & 7) +/* The number of set associative cache way supported on L1 Instruction Cache */ +#define ADSP_CxL1CCAP_ICMWC ((ADSP_CxL1CCAP_REG >> 20) & 7) + +#ifndef _LINKER +/* L2 Local Memory Management */ + +/* These registers are for the L2 memory control and status. */ +#define DFL2MM_REG 0x71d00 + +struct ace_l2mm { + uint32_t l2mcap; + uint32_t l2mpat; + uint32_t l2mecap; + uint32_t l2mecs; + uint32_t l2hsbpmptr; + uint32_t l2usbpmptr; + uint32_t l2usbmrpptr; + uint32_t l2ucmrpptr; + uint32_t l2ucmrpdptr; +}; + +#define ACE_L2MM ((volatile struct ace_l2mm *)DFL2MM_REG) + +/* DfL2MCAP */ +struct ace_l2mcap { + uint32_t l2hss : 8; + uint32_t l2uss : 4; + uint32_t l2hsbs : 4; + uint32_t l2hs2s : 8; + uint32_t l2usbs : 5; + uint32_t l2se : 1; + uint32_t el2se : 1; + uint32_t rsvd32 : 1; +}; + +#define ACE_L2MCAP ((volatile struct ace_l2mcap *)DFL2MM_REG) + +static ALWAYS_INLINE uint32_t ace_hpsram_get_bank_count(void) +{ + return ACE_L2MCAP->l2hss; +} + +static ALWAYS_INLINE uint32_t ace_lpsram_get_bank_count(void) +{ + return ACE_L2MCAP->l2uss; +} + +struct ace_hpsram_regs { + /** @brief power gating control */ + uint8_t HSxPGCTL; + /** @brief retention mode control */ + uint8_t HSxRMCTL; + uint8_t reserved[2]; + /** @brief power gating status */ + uint8_t HSxPGISTS; + uint8_t reserved1[3]; +}; + +struct ace_lpsram_regs { + /** @brief power gating control */ + uint8_t USxPGCTL; + /** @brief retention mode control */ + uint8_t USxRMCTL; + uint8_t reserved[2]; + /** @brief power gating status */ + uint8_t USxPGISTS; + uint8_t reserved1[3]; +}; +#endif + +/* These registers are for the L2 HP SRAM bank power management control and status.*/ +#define L2_HSBPM_BASE (DT_REG_ADDR(DT_NODELABEL(hsbpm))) +#define L2_HSBPM_SIZE (DT_REG_SIZE(DT_NODELABEL(hsbpm))) + +#define HPSRAM_REGS(block_idx) ((volatile struct ace_hpsram_regs *const) \ + (L2_HSBPM_BASE + L2_HSBPM_SIZE * (block_idx))) + +/* These registers are for the L2 LP SRAM bank power management control and status.*/ +#define L2_LSBPM_BASE (DT_REG_ADDR(DT_NODELABEL(lsbpm))) +#define L2_LSBPM_SIZE (DT_REG_SIZE(DT_NODELABEL(lsbpm))) + +#define LPSRAM_REGS(block_idx) ((volatile struct ace_lpsram_regs *const) \ + (L2_LSBPM_BASE + L2_LSBPM_SIZE * (block_idx))) + +#endif /* ZEPHYR_SOC_INTEL_ADSP_MEMORY_H_ */ diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_memory_regions.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_memory_regions.h new file mode 100644 index 00000000000000..912a225588b301 --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_memory_regions.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_INTEL_ADSP_MEMORY_REGIONS_H_ +#define ZEPHYR_SOC_INTEL_ADSP_MEMORY_REGIONS_H_ + +/* Define amount of regions other than core heaps that virtual memory will be split to + * currently includes shared heap and oma region and one regions set to 0 as for table + * iterator end value. + */ +#define VIRTUAL_REGION_COUNT 3 + +#define CORE_HEAP_SIZE 0x100000 +#define SHARED_HEAP_SIZE 0x100000 +#define OPPORTUNISTIC_REGION_SIZE 0x100000 + +/* size of TLB table */ +#define TLB_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, intel_adsp_mtl_tlb), 0) + +/* Attribiutes for memory regions */ +#define MEM_REG_ATTR_CORE_HEAP 1U +#define MEM_REG_ATTR_SHARED_HEAP 2U +#define MEM_REG_ATTR_OPPORTUNISTIC_MEMORY 4U + +#endif /* ZEPHYR_SOC_INTEL_ADSP_MEMORY_REGIONS_H_ */ diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_power.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_power.h new file mode 100644 index 00000000000000..f9628dbbb0dd6c --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_power.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#ifndef ZEPHYR_SOC_INTEL_ADSP_POWER_H_ +#define ZEPHYR_SOC_INTEL_ADSP_POWER_H_ + +/* Value used as delay when waiting for hw register state change. */ +#define HW_STATE_CHECK_DELAY 64 + +/* Power Control register - controls the power domain operations. */ +struct ace_pwrctl { + uint16_t rsvd0 : 5; + uint16_t wphstpg : 1; + uint16_t rsvd6 : 1; + uint16_t wphubhppg : 1; + uint16_t wpdspulppg : 1; + uint16_t wpioxpg : 2; + uint16_t rsvd11 : 2; + uint16_t wpmlpg : 1; + uint16_t rsvd14 : 2; + uint16_t phubulppg : 1; +}; + +struct ace_pwrctl2 { + uint16_t wpdsphpxpg : 5; +}; + +#define ACE_PWRCTL ((volatile struct ace_pwrctl *) &ACE_DfPMCCU.dfpwrctl) +#define ACE_PWRCTL2 ((volatile struct ace_pwrctl2 *) &ACE_DfPMCCU.dfpwrctl2) + +/* Power Status register - reports the power domain status. */ +struct ace_pwrsts { + uint16_t rsvd0 : 5; + uint16_t hstpgs : 1; + uint16_t rsvd6 : 1; + uint16_t hubhppgs : 1; + uint16_t dspulppgs : 1; + uint16_t ioxpgs : 4; + uint16_t mlpgs : 2; + uint16_t rsvd14 : 1; + uint16_t hubulppgs : 1; +}; + +struct ace_pwrsts2 { + uint16_t dsphpxpgs : 5; +}; + +#define ACE_PWRSTS ((volatile struct ace_pwrsts *) &ACE_DfPMCCU.dfpwrsts) +#define ACE_PWRSTS2 ((volatile struct ace_pwrsts2 *) &ACE_DfPMCCU.dfpwrsts2) + +/** + * @brief Power up a specific CPU. + * + * This sets the "not power gating" bit in the power control + * register to disable power gating to CPU, thus powering up + * the CPU. + * + * @param cpu_num CPU to be powered up. + */ +static ALWAYS_INLINE void soc_cpu_power_up(int cpu_num) +{ + ACE_PWRCTL2->wpdsphpxpg |= BIT(cpu_num); +} + +/** + * @brief Power down a specific CPU. + * + * This clears the "not power gating" bit in the power control + * register to enable power gating to CPU, thus powering down + * the CPU. + * + * @param cpu_num CPU to be powered down. + */ +static ALWAYS_INLINE void soc_cpu_power_down(int cpu_num) +{ + ACE_PWRCTL2->wpdsphpxpg &= ~BIT(cpu_num); +} + +/** + * @brief Test if a CPU is currently powered. + * + * This queries the power status register to see if the CPU + * is currently powered. + * + * @param cpu_num CPU to be queried. + * @return True if CPU is powered, false if now. + */ +static ALWAYS_INLINE bool soc_cpu_is_powered(int cpu_num) +{ + return (ACE_PWRSTS2->dsphpxpgs & BIT(cpu_num)) == BIT(cpu_num); +} + +/** + * @brief Retrieve node identifier for Intel ADSP HOST power domain. + */ +#define INTEL_ADSP_HST_DOMAIN_DTNODE DT_NODELABEL(hst_domain) + +/** + * @brief Intel ADSP HOST power domain pointer. + */ +#define INTEL_ADSP_HST_DOMAIN_DEV DEVICE_DT_GET(INTEL_ADSP_HST_DOMAIN_DTNODE) + +#endif /* ZEPHYR_SOC_INTEL_ADSP_POWER_H_ */ diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_shim.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_shim.h new file mode 100644 index 00000000000000..e28e6f3d8afb45 --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/adsp_shim.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_SOC_INTEL_ADSP_SHIM_H_ +#define ZEPHYR_SOC_INTEL_ADSP_SHIM_H_ + +#ifndef _ASMLANGUAGE +#include + +/** + * DfPMCCH + * Power Management / Clock Control (HST) Registers + * + * These registers block (HST domain) are for general power management + * and clock control operation for DSP FW. + */ +struct ace_dfpmcch { + uint32_t dfspsreq; /* Offset: 0x00 */ + uint32_t _unused0[3]; + uint32_t dfspsrsp; /* Offset: 0x10 */ + uint32_t _unused1[1]; + uint32_t svcfg; /* Offset: 0x18 */ + uint32_t dfltrc; /* Offset: 0x1c */ + uint32_t _unused2[8]; +}; + +/** + * DfPMCCU + * Power Management / Clock Control (ULP) Registers + * + * These registers block (ULP domain) are for general power management + * and clock control operation for DSP FW. + */ +struct ace_dfpmccu { + uint32_t dfpmccap; /* Offset: 0x00 */ + uint32_t dfhrosccf; /* Offset: 0x04 */ + uint32_t dfxosccf; /* Offset: 0x08 */ + uint32_t dflrosccf; /* Offset: 0x0c */ + uint32_t dfsiorosccf; /* Offset: 0x10 */ + uint32_t dfhsiorosccf; /* Offset: 0x14 */ + uint32_t dfipllrosccf; /* Offset: 0x18 */ + uint32_t dfirosccv; /* Offset: 0x1c */ + uint32_t dffbrcfd; /* Offset: 0x20 */ + uint32_t dfapllptr; /* Offset: 0x24 */ + uint32_t _unused0[20]; + uint32_t dfclkctl; /* Offset: 0x78 */ + uint32_t dfclksts; /* Offset: 0x7c */ + uint32_t dfintclkctl; /* Offset: 0x80 */ + uint32_t dfcrosts; /* Offset: 0x84 */ + uint32_t dfcrodiv; /* Offset: 0x88 */ + uint32_t _unused1[1]; + uint16_t dfpwrctl; /* Offset: 0x90 */ + uint16_t dfpwrsts; /* Offset: 0x92 */ + uint16_t dfpwrctl2; /* Offset: 0x94 */ + uint16_t dfpwrsts2; /* Offset: 0x96 */ + uint32_t dflpsdmas0; /* Offset: 0x98 */ + uint32_t dflpsdmas1; /* Offset: 0x9c */ + uint32_t _unused3[1]; + uint32_t dfldoctl; /* Offset: 0xa4 */ + uint32_t _unused4[2]; + uint32_t dflpsalhsso; /* Offset: 0xb0 */ + uint32_t dflpsalhss1; /* Offset: 0xb4 */ + uint32_t dflpsalhss2; /* Offset: 0xb8 */ + uint32_t dflpsalhss3; /* Offset: 0xbc */ + uint32_t _unused5[10]; +}; + +#define ACE_DfPMCCH (*((volatile struct ace_dfpmcch *)DT_REG_ADDR(DT_NODELABEL(dfpmcch)))) +#define ACE_DfPMCCU (*((volatile struct ace_dfpmccu *)DT_REG_ADDR(DT_NODELABEL(dfpmccu)))) + + +#define ADSP_TTSCAP_OFFSET 0x00 +#define ADSP_RTCWC_OFFSET 0x08 +#define ADSP_DSPWCCTL_OFFSET 0x10 +#define ADSP_DSPWCSTS_OFFSET 0x12 +#define ADSP_DSPWCAV_OFFSET 0x18 +#define ADSP_DSPWC_OFFSET 0x20 +#define ADSP_DSPWCTCS_OFFSET 0x28 +#define ADSP_DSPWCT0C_OFFSET 0x30 +#define ADSP_DSPWCT1C_OFFSET 0x38 +#define ADSP_TSCTRL_OFFSET 0x40 +#define ADSP_ISCS_OFFSET 0x44 +#define ADSP_LSCS_OFFSET 0x48 +#define ADSP_DWCCS_OFFSET 0x50 +#define ADSP_ARTCS_OFFSET 0x58 +#define ADSP_LWCCS_OFFSET 0x60 +#define ADSP_CLTSYNC_OFFSET 0x70 + + + +#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c)) + + +#define ADSP_SHIM_TSCTRL_NTK BIT(31) +#define ADSP_SHIM_TSCTRL_IONTE BIT(30) +#define ADSP_SHIM_TSCTRL_DMATS GENMASK(13, 12) +#define ADSP_SHIM_TSCTRL_CLNKS GENMASK(11, 10) +#define ADSP_SHIM_TSCTRL_HHTSE BIT(7) +#define ADSP_SHIM_TSCTRL_LWCS BIT(6) +#define ADSP_SHIM_TSCTRL_ODTS BIT(5) +#define ADSP_SHIM_TSCTRL_CDMAS GENMASK(4, 0) + +#endif /* _ASMLANGUAGE */ + +#define ACE_CLKCTL_WOVCRO BIT(4) /* Request WOVCRO clock */ + +#define SHIM_LDOCTL_HPSRAM_LDO_ON (3 << 0) +#define SHIM_LDOCTL_HPSRAM_LDO_BYPASS BIT(0) + +#define SHIM_LDOCTL_LPSRAM_LDO_ON (3 << 2) +#define SHIM_LDOCTL_LPSRAM_LDO_BYPASS BIT(2) + +#define ADSP_DMWBA_ENABLE BIT(0) +#define ADSP_DMWBA_READONLY BIT(1) + +#define ADSP_CLKCTL_OSC_SOURCE_MASK (3<<2) +#define ADSP_CLKCTL_OSC_REQUEST_MASK (~BIT_MASK(28)) + +/** LDO Control */ +#define ADSP_DSPRA_ADDRESS (0x71A60) +#define ADSP_LPGPDMACxO_ADDRESS(x) (ADSP_DSPRA_ADDRESS + 0x0000 + 0x0002*(x)) +#define ADSP_DSPIOPO_ADDRESS (ADSP_DSPRA_ADDRESS + 0x0008) +#define ADSP_GENO_ADDRESS (ADSP_DSPRA_ADDRESS + 0x000C) +#define ADSP_DSPALHO_ADDRESS (ADSP_DSPRA_ADDRESS + 0x0010) + + +#define DSP_INIT_IOPO ADSP_DSPIOPO_ADDRESS +#define IOPO_DMIC_FLAG BIT(0) +#define IOPO_DSPKOSEL_FLAG BIT(1) +#define IOPO_ANCOSEL_FLAG BIT(2) +#define IOPO_DMIXOSEL_FLAG BIT(3) +#define IOPO_SLIMOSEL_FLAG BIT(4) +#define IOPO_SNDWOSEL_FLAG BIT(5) +#define IOPO_SLIMDOSEL_FLAG BIT(20) +#define IOPO_I2SSEL_MASK (0x7 << 0x8) + +#define DSP_INIT_GENO ADSP_GENO_ADDRESS +#define GENO_MDIVOSEL BIT(1) +#define GENO_DIOPTOSEL BIT(2) + +#define ADSP_FORCE_DECOUPLED_HDMA_L1_EXIT_BIT BIT(1) + +#endif /* ZEPHYR_SOC_INTEL_ADSP_SHIM_H_ */ diff --git a/soc/intel/intel_adsp/ace/include/ace30_ptl/dmic_regs_ace3x.h b/soc/intel/intel_adsp/ace/include/ace30_ptl/dmic_regs_ace3x.h new file mode 100644 index 00000000000000..4d02abea74957b --- /dev/null +++ b/soc/intel/intel_adsp/ace/include/ace30_ptl/dmic_regs_ace3x.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DAI_DRIVER_DMIC_REGS_ACE3X_H__ +#define __INTEL_DAI_DRIVER_DMIC_REGS_ACE3X_H__ + +/* DMIC Link Synchronization */ +#define DMICSYNC_OFFSET 0x1C + +/* Sync Period */ +#define DMICSYNC_SYNCPRD GENMASK(19, 0) + +/* Sync Period Update */ +#define DMICSYNC_SYNCPU BIT(20) + +/* Sync Go */ +#define DMICSYNC_SYNCGO BIT(23) + +/* Command Sync */ +#define DMICSYNC_CMDSYNC BIT(24) + + +/* DMIC Link Control */ +#define DMICLCTL_OFFSET 0x04 + +/* Set Clock Frequency */ +#define DMICLCTL_SCF GENMASK(3, 0) + +/* Offload Enable */ +#define DMICLCTL_OFLEN BIT(4) + +/* Interrupt Enable */ +#define DMICLCTL_INTEN BIT(5) + +/* Set Power Active */ +#define DMICLCTL_SPA BIT(16) + +/* Current Power Active */ +#define DMICLCTL_CPA BIT(23) + +/* Interrupt Status */ +#define DMICLCTL_INTSTS BIT(31) + + +/* Digital Microphone x Link Vendor Specific Control */ +#define DMICLVSCTL_OFFSET 0x04 + +/* Force Clock Gating */ +#define DMICLVSCTL_FCG BIT(26) + +/* Host Link Clock Select */ +#define DMICLVSCTL_MLCS GENMASK(29, 27) + +/* Dynamic Clock Gating Disable */ +#define DMICLVSCTL_DCGD BIT(30) + +/* Idle Clock Gating Disable */ +#define DMICLVSCTL_ICGD BIT(31) + + +/* Digital Microphone PCM Stream y Channel Map + * + * Offset: 12h + 02h * y + */ +#define DMICXPCMSyCM_OFFSET 0x16 +#define DMICXPCMSyCM_SIZE 0x02 + +#endif /* !__INTEL_DAI_DRIVER_DMIC_REGS_ACE3X_H__ */ diff --git a/soc/intel/intel_adsp/ace/include/dmic_regs.h b/soc/intel/intel_adsp/ace/include/dmic_regs.h index 201c3b2d6dfa36..df69d3687f19d7 100644 --- a/soc/intel/intel_adsp/ace/include/dmic_regs.h +++ b/soc/intel/intel_adsp/ace/include/dmic_regs.h @@ -351,6 +351,8 @@ #include #elif CONFIG_SOC_INTEL_ACE15_MTPM #include +#elif CONFIG_SOC_INTEL_ACE30_PTL +#include #else #error "Unknown SoC" #endif diff --git a/soc/intel/intel_adsp/ace/mmu_ptl.c b/soc/intel/intel_adsp/ace/mmu_ptl.c new file mode 100644 index 00000000000000..a59b231fbe3fe9 --- /dev/null +++ b/soc/intel/intel_adsp/ace/mmu_ptl.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +extern char _cached_start[]; +extern char _cached_end[]; +extern char _imr_start[]; +extern char _imr_end[]; +extern char __common_rom_region_start[]; +extern char __common_rom_region_end[]; +extern char __common_ram_region_start[]; +extern char __common_ram_region_end[]; + +const struct xtensa_mmu_range xtensa_soc_mmu_ranges[] = { + { + .start = (uint32_t)__common_ram_region_start, + .end = (uint32_t)__common_ram_region_end, + .attrs = XTENSA_MMU_PERM_W, + .name = "common-ram", + }, + { + /* Workaround for D3 flows. L2 TLB wider than MMU TLB */ + .start = (uint32_t)L2_SRAM_BASE, + .end = (uint32_t)VECBASE_RESET_PADDR_SRAM, + .attrs = XTENSA_MMU_PERM_W | XTENSA_MMU_CACHED_WB, + .name = "workaround L2 TLB/MMU TLB", + }, + { + .start = (uint32_t)VECBASE_RESET_PADDR_SRAM, + .end = (uint32_t)VECBASE_RESET_PADDR_SRAM + VECTOR_TBL_SIZE, + .attrs = XTENSA_MMU_PERM_X | XTENSA_MMU_MAP_SHARED, + .name = "exceptions", + }, + { + .start = (uint32_t)_cached_start, + .end = (uint32_t)_cached_end, + .attrs = XTENSA_MMU_PERM_W | XTENSA_MMU_CACHED_WB, + .name = "cached", + }, + { + .start = (uint32_t)HP_SRAM_WIN0_BASE, + .end = (uint32_t)HP_SRAM_WIN0_BASE + (uint32_t)HP_SRAM_WIN0_SIZE, + .attrs = XTENSA_MMU_PERM_W, + .name = "win0", + }, + { + .start = (uint32_t)HP_SRAM_WIN1_BASE, + .end = (uint32_t)HP_SRAM_WIN1_BASE + (uint32_t)HP_SRAM_WIN1_SIZE, + .attrs = XTENSA_MMU_PERM_W, + .name = "win2", + }, + { + .start = (uint32_t)HP_SRAM_WIN2_BASE, + .end = (uint32_t)HP_SRAM_WIN2_BASE + (uint32_t)HP_SRAM_WIN2_SIZE, + .attrs = XTENSA_MMU_PERM_W, + .name = "win2", + }, + { + .start = (uint32_t)HP_SRAM_WIN3_BASE, + .end = (uint32_t)HP_SRAM_WIN3_BASE + (uint32_t)HP_SRAM_WIN3_SIZE, + .attrs = XTENSA_MMU_PERM_W, + .name = "win3", + }, + /* Map IMR */ + { + .start = (uint32_t)(IMR_BOOT_LDR_MANIFEST_BASE - IMR_BOOT_LDR_MANIFEST_SIZE), + .end = (uint32_t)IMR_BOOT_LDR_MANIFEST_BASE, + .attrs = XTENSA_MMU_PERM_W | XTENSA_MMU_CACHED_WB, + .name = "imr stack", + }, + { + .start = (uint32_t)IMR_BOOT_LDR_MANIFEST_BASE, + .end = (uint32_t)(IMR_BOOT_LDR_MANIFEST_BASE + IMR_BOOT_LDR_MANIFEST_SIZE), + .name = "imr text", + }, + { + .start = (uint32_t)IMR_BOOT_LDR_BSS_BASE, + .end = (uint32_t)(IMR_BOOT_LDR_BSS_BASE + IMR_BOOT_LDR_BSS_SIZE), + .name = "imr bss", + }, + { + .start = (uint32_t)IMR_BOOT_LDR_TEXT_ENTRY_BASE, + .end = (uint32_t)(IMR_BOOT_LDR_TEXT_ENTRY_BASE + IMR_BOOT_LDR_TEXT_ENTRY_SIZE), + .attrs = XTENSA_MMU_PERM_X | XTENSA_MMU_MAP_SHARED, + .name = "imr text", + }, + { + .start = (uint32_t)IMR_BOOT_LDR_STACK_BASE, + .end = (uint32_t)(IMR_BOOT_LDR_STACK_BASE + IMR_BOOT_LDR_STACK_SIZE), + .attrs = XTENSA_MMU_PERM_W | XTENSA_MMU_CACHED_WB, + .name = "imr stack", + }, + { + .start = (uint32_t)IMR_LAYOUT_ADDRESS, + /* sizeof(struct imr_layout) happens to be 0x1000 (4096) bytes. */ + .end = (uint32_t)(IMR_LAYOUT_ADDRESS + sizeof(struct imr_layout)), + .attrs = XTENSA_MMU_PERM_W | XTENSA_MMU_CACHED_WB, + .name = "imr layout", + }, + { + .start = (uint32_t)IMR_L3_HEAP_BASE, + .end = (uint32_t)(IMR_L3_HEAP_BASE + IMR_L3_HEAP_SIZE), + .attrs = XTENSA_MMU_PERM_W | XTENSA_MMU_CACHED_WB, + .name = "imr L3 heap", + }, + { + .start = (uint32_t)LP_SRAM_BASE, + .end = (uint32_t)(LP_SRAM_BASE + LP_SRAM_SIZE), + .attrs = XTENSA_MMU_PERM_W | XTENSA_MMU_CACHED_WB, + .name = "lpsram", + }, + { + .start = (uint32_t)(ADSP_L1CC_ADDR), + .end = (uint32_t)(ADSP_L1CC_ADDR + CONFIG_MMU_PAGE_SIZE), + .attrs = XTENSA_MMU_PERM_W, + .name = "l1cc", + }, + { + /* FIXME: definitely need more refinements... */ + .start = (uint32_t)0x0, + .end = (uint32_t)0x100000, + .attrs = XTENSA_MMU_PERM_W, + .name = "hwreg0", + }, + { + /* FIXME: definitely need more refinements... */ + .start = (uint32_t)0x170000, + .end = (uint32_t)0x180000, + .attrs = XTENSA_MMU_PERM_W, + .name = "hwreg1", + }, +}; + +int xtensa_soc_mmu_ranges_num = ARRAY_SIZE(xtensa_soc_mmu_ranges); diff --git a/soc/intel/intel_adsp/ace/multiprocessing.c b/soc/intel/intel_adsp/ace/multiprocessing.c index f530232e896fa0..68b8693a520d4b 100644 --- a/soc/intel/intel_adsp/ace/multiprocessing.c +++ b/soc/intel/intel_adsp/ace/multiprocessing.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -25,12 +26,28 @@ #define CPU_POWERUP_TIMEOUT_USEC 10000 +#ifdef CONFIG_XTENSA_MMU +#include +#endif /* CONFIG_XTENSA_MMU */ + #define ACE_INTC_IRQ DT_IRQN(DT_NODELABEL(ace_intc)) +#ifdef CONFIG_XTENSA_MMU +#define IPI_TLB_FLUSH 0x01 +#endif + static void ipc_isr(void *arg) { uint32_t cpu_id = arch_proc_id(); +#if defined(CONFIG_XTENSA_MMU) && (CONFIG_MP_MAX_NUM_CPUS > 1) + uint32_t msg = IDC[cpu_id].agents[0].ipc.tdr & ~INTEL_ADSP_IPC_BUSY; + + if (msg == IPI_TLB_FLUSH) { + xtensa_mmu_tlb_shootdown(); + } +#endif + /* * Clearing the BUSY bits in both TDR and TDA are needed to * complete an IDC message. If we do only one (and not both), @@ -40,7 +57,7 @@ static void ipc_isr(void *arg) * On TDR, it is to write one to clear, while on TDA, it is * to write zero to clear. */ - IDC[cpu_id].agents[0].ipc.tdr = BIT(31); + IDC[cpu_id].agents[0].ipc.tdr = INTEL_ADSP_IPC_BUSY; IDC[cpu_id].agents[0].ipc.tda = 0; #ifdef CONFIG_SMP @@ -166,6 +183,10 @@ void soc_start_core(int cpu_num) void soc_mp_startup(uint32_t cpu) { +#ifdef CONFIG_XTENSA_MMU + xtensa_mmu_init(); +#endif /* CONFIG_XTENSA_MMU */ + /* Must have this enabled always */ xtensa_irq_enable(ACE_INTC_IRQ); @@ -178,7 +199,17 @@ void soc_mp_startup(uint32_t cpu) #endif /* CONFIG_ADSP_IDLE_CLOCK_GATING */ } -void arch_sched_ipi(void) +/** + * @brief Send a IPI to other processors. + * + * @note: Leave the MSB clear when passing @param msg. + * + * @param msg Message to be sent (31-bit integer). + */ +#ifndef CONFIG_XTENSA_MMU +ALWAYS_INLINE +#endif +static void send_ipi(uint32_t msg) { uint32_t curr = arch_proc_id(); @@ -187,11 +218,23 @@ void arch_sched_ipi(void) for (int core = 0; core < num_cpus; core++) { if (core != curr && soc_cpus_active[core]) { - IDC[core].agents[1].ipc.idr = INTEL_ADSP_IPC_BUSY; + IDC[core].agents[1].ipc.idr = msg | INTEL_ADSP_IPC_BUSY; } } } +void arch_sched_ipi(void) +{ + send_ipi(0); +} + +#if defined(CONFIG_XTENSA_MMU) && (CONFIG_MP_MAX_NUM_CPUS > 1) +void xtensa_mmu_tlb_ipi(void) +{ + send_ipi(IPI_TLB_FLUSH); +} +#endif + #if CONFIG_MP_MAX_NUM_CPUS > 1 int soc_adsp_halt_cpu(int id) { diff --git a/soc/intel/intel_adsp/ace/power.c b/soc/intel/intel_adsp/ace/power.c index afc270f9afa07f..57fd8905e564df 100644 --- a/soc/intel/intel_adsp/ace/power.c +++ b/soc/intel/intel_adsp/ace/power.c @@ -122,6 +122,9 @@ struct core_state { uint32_t intenable; uint32_t ps; uint32_t bctl; +#if (XCHAL_NUM_MISC_REGS == 2) + uint32_t misc[XCHAL_NUM_MISC_REGS]; +#endif }; static struct core_state core_desc[CONFIG_MP_MAX_NUM_CPUS] = {{0}}; @@ -142,6 +145,10 @@ static ALWAYS_INLINE void _save_core_context(uint32_t core_id) core_desc[core_id].excsave2 = XTENSA_RSR("EXCSAVE2"); core_desc[core_id].excsave3 = XTENSA_RSR("EXCSAVE3"); core_desc[core_id].thread_ptr = XTENSA_RUR("THREADPTR"); +#if (XCHAL_NUM_MISC_REGS == 2) + core_desc[core_id].misc[0] = XTENSA_RSR("MISC0"); + core_desc[core_id].misc[1] = XTENSA_RSR("MISC1"); +#endif __asm__ volatile("mov %0, a0" : "=r"(core_desc[core_id].a0)); __asm__ volatile("mov %0, a1" : "=r"(core_desc[core_id].a1)); @@ -157,11 +164,18 @@ static ALWAYS_INLINE void _restore_core_context(void) { uint32_t core_id = arch_proc_id(); +#ifdef CONFIG_XTENSA_MMU + xtensa_mmu_init(); +#endif XTENSA_WSR("PS", core_desc[core_id].ps); XTENSA_WSR("VECBASE", core_desc[core_id].vecbase); XTENSA_WSR("EXCSAVE2", core_desc[core_id].excsave2); XTENSA_WSR("EXCSAVE3", core_desc[core_id].excsave3); XTENSA_WUR("THREADPTR", core_desc[core_id].thread_ptr); +#if (XCHAL_NUM_MISC_REGS == 2) + XTENSA_WSR("MISC0", core_desc[core_id].misc[0]); + XTENSA_WSR("MISC1", core_desc[core_id].misc[1]); +#endif __asm__ volatile("mov a0, %0" :: "r"(core_desc[core_id].a0)); __asm__ volatile("mov a1, %0" :: "r"(core_desc[core_id].a1)); __asm__ volatile("rsync"); diff --git a/soc/intel/intel_adsp/common/include/adsp-vectors.h b/soc/intel/intel_adsp/common/include/adsp-vectors.h index 01e660e43ea657..97f778968b8166 100644 --- a/soc/intel/intel_adsp/common/include/adsp-vectors.h +++ b/soc/intel/intel_adsp/common/include/adsp-vectors.h @@ -45,7 +45,7 @@ #define DOUBLEEXC_VECTOR_PADDR_SRAM \ (VECBASE_RESET_PADDR_SRAM + XCHAL_DOUBLEEXC_VECOFS) -#define VECTOR_TBL_SIZE 0x0400 +#define VECTOR_TBL_SIZE 0x1000 /* Vector and literal sizes */ #define MEM_VECT_LIT_SIZE 0x8 diff --git a/soc/intel/intel_adsp/common/include/cpu_init.h b/soc/intel/intel_adsp/common/include/cpu_init.h index 571ae29f5b8a8f..dea6aa9f181fa7 100644 --- a/soc/intel/intel_adsp/common/include/cpu_init.h +++ b/soc/intel/intel_adsp/common/include/cpu_init.h @@ -76,8 +76,15 @@ static ALWAYS_INLINE void cpu_early_init(void) /* Finally we need to enable the cache in the Region * Protection Option "TLB" entries. The hardware defaults * have this set to RW/uncached everywhere. + * + * If we have MMU enabled, we don't need to do this right now. + * Let use the default configuration and properly configure the + * MMU when running from RAM. */ +#ifndef CONFIG_MMU ARCH_XTENSA_SET_RPO_TLB(); +#endif + /* Initialize ATOMCTL: Hardware defaults for S32C1I use * "internal" operations, meaning they are atomic only WRT the diff --git a/soc/intel/intel_adsp/soc.yml b/soc/intel/intel_adsp/soc.yml index 757750eeb379d8..0f889aea963821 100644 --- a/soc/intel/intel_adsp/soc.yml +++ b/soc/intel/intel_adsp/soc.yml @@ -5,6 +5,7 @@ family: socs: - name: ace15_mtpm - name: ace20_lnl + - name: ace30_ptl - name: intel_adsp_cavs socs: - name: cavs25