From 634305b22980505da8e0f2af462b171e6e9f9e54 Mon Sep 17 00:00:00 2001 From: Balakishorepati Date: Fri, 25 Mar 2022 09:58:58 +0530 Subject: [PATCH 1/5] rembrandt: Add support for AMD rembrandt platform Add rembrandt platform support to build fw image. Add rembrandt_defconfig for rembrandt platform. Signed-off-by: Balakishorepati --- src/arch/xtensa/CMakeLists.txt | 7 +++++- src/arch/xtensa/configs/rembrandt_defconfig | 24 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/arch/xtensa/configs/rembrandt_defconfig diff --git a/src/arch/xtensa/CMakeLists.txt b/src/arch/xtensa/CMakeLists.txt index 7688ed19c5da..e6aff9fabc83 100644 --- a/src/arch/xtensa/CMakeLists.txt +++ b/src/arch/xtensa/CMakeLists.txt @@ -53,6 +53,11 @@ if(CONFIG_RENOIR) set(platform_folder amd/renoir) set(platform_ld_script renoir.x) endif() + +if(CONFIG_REMBRANDT) + set(platform_folder amd/rembrandt) + set(platform_ld_script rembrandt.x) +endif() # includes target_include_directories(sof_options INTERFACE @@ -542,7 +547,7 @@ set(UNSIGNED_RI byt cht hsw bdw sue) # NXP list(APPEND UNSIGNED_RI imx8 imx8x imx8m imx8ulp) # AMD -list(APPEND UNSIGNED_RI rn) +list(APPEND UNSIGNED_RI rn rmb) # Mediatek list(APPEND UNSIGNED_RI mt8186 mt8195) diff --git a/src/arch/xtensa/configs/rembrandt_defconfig b/src/arch/xtensa/configs/rembrandt_defconfig new file mode 100644 index 000000000000..8c1214301803 --- /dev/null +++ b/src/arch/xtensa/configs/rembrandt_defconfig @@ -0,0 +1,24 @@ +CONFIG_REMBRANDT=y +CONFIG_RIMAGE_SIGNING_SCHEMA="rmb" +CONFIG_TRACE_CHANNEL=7 +CONFIG_WRAP_ACTUAL_POSITION=y +CONFIG_AMD_BT=n +CONFIG_AMD_SP=n +CONFIG_CORE_COUNT=1 +CONFIG_LP_MEMORY_BANKS=0 +CONFIG_HP_MEMORY_BANKS=10 +CONFIG_FORMAT_CONVERT_HIFI3=n +CONFIG_LP_SRAM=n +CONFIG_HAVE_AGENT=n +CONFIG_COMP_SRC=n +CONFIG_COMP_FIR=n +CONFIG_COMP_IIR=n +CONFIG_COMP_DCBLOCK=n +CONFIG_COMP_TDFB=n +CONFIG_COMP_TONE=n +CONFIG_COMP_MIXER=n +CONFIG_COMP_MUX=n +CONFIG_COMP_SWITCH=n +CONFIG_COMP_KPB=n +CONFIG_COMP_SEL=n +CONFIG_COMP_ASRC=n From 129ab9ccf045b4a0a6058afc2825f2317dac9360 Mon Sep 17 00:00:00 2001 From: Balakishorepati Date: Fri, 25 Mar 2022 15:49:50 +0530 Subject: [PATCH 2/5] scripts: add rembrandt support Add rembrandt build support. Signed-off-by: Balakishorepati --- scripts/xtensa-build-all.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/xtensa-build-all.sh b/scripts/xtensa-build-all.sh index 6d852de44f45..2fb659cfbbad 100755 --- a/scripts/xtensa-build-all.sh +++ b/scripts/xtensa-build-all.sh @@ -13,6 +13,7 @@ DEFAULT_PLATFORMS=( byt cht bdw hsw tgl tgl-h apl skl kbl cnl sue icl jsl \ # Work in progress can be added to this "staging area" without breaking # the -a option for everyone. SUPPORTED_PLATFORMS=( "${DEFAULT_PLATFORMS[@]}" ) +SUPPORTED_PLATFORMS=( "${DEFAULT_PLATFORMS[@]}" rmb) BUILD_ROM=no BUILD_DEBUG=no @@ -335,6 +336,13 @@ do HOST="xtensa-rn-elf" XTENSA_TOOLS_VERSION="RI-2019.1-linux" ;; + rmb) + PLATFORM="rembrandt" + ARCH="xtensa" + XTENSA_CORE="LX7_HiFi5_PROD" + HOST="xtensa-rmb-elf" + XTENSA_TOOLS_VERSION="RI-2019.1-linux" + ;; mt8186) PLATFORM="mt8186" XTENSA_CORE="hifi5_7stg_I64D128" From b15d2a3a6e71a55170d4c73985d71039c6a41c81 Mon Sep 17 00:00:00 2001 From: Balakishorepati Date: Mon, 28 Mar 2022 13:25:15 +0530 Subject: [PATCH 3/5] drivers: amd: rembrandt: Add drivers for amd/rembrandt Add drivers for: * timer, ipc, interrupt - amd specific implementation * DMA, for copying data between HOST and DSP * BT DAI,SP DAI, HS DAI for Audio interface * I2S DMA, Controller for BT,SP and HS Signed-off-by: Balakishorepati --- src/drivers/CMakeLists.txt | 2 +- src/drivers/amd/CMakeLists.txt | 2 + src/drivers/amd/rembrandt/CMakeLists.txt | 16 + src/drivers/amd/rembrandt/acp_bt_dai.c | 95 ++++ src/drivers/amd/rembrandt/acp_bt_dma.c | 425 +++++++++++++++ src/drivers/amd/rembrandt/acp_dma.c | 662 +++++++++++++++++++++++ src/drivers/amd/rembrandt/acp_dmic_dai.c | 144 +++++ src/drivers/amd/rembrandt/acp_dmic_dma.c | 370 +++++++++++++ src/drivers/amd/rembrandt/acp_hs_dai.c | 96 ++++ src/drivers/amd/rembrandt/acp_hs_dma.c | 398 ++++++++++++++ src/drivers/amd/rembrandt/acp_sp_dai.c | 95 ++++ src/drivers/amd/rembrandt/acp_sp_dma.c | 396 ++++++++++++++ src/drivers/amd/rembrandt/interrupt.c | 420 ++++++++++++++ src/drivers/amd/rembrandt/ipc.c | 205 +++++++ src/drivers/amd/rembrandt/timer.c | 101 ++++ 15 files changed, 3426 insertions(+), 1 deletion(-) create mode 100644 src/drivers/amd/rembrandt/CMakeLists.txt create mode 100644 src/drivers/amd/rembrandt/acp_bt_dai.c create mode 100644 src/drivers/amd/rembrandt/acp_bt_dma.c create mode 100644 src/drivers/amd/rembrandt/acp_dma.c create mode 100644 src/drivers/amd/rembrandt/acp_dmic_dai.c create mode 100644 src/drivers/amd/rembrandt/acp_dmic_dma.c create mode 100644 src/drivers/amd/rembrandt/acp_hs_dai.c create mode 100644 src/drivers/amd/rembrandt/acp_hs_dma.c create mode 100644 src/drivers/amd/rembrandt/acp_sp_dai.c create mode 100644 src/drivers/amd/rembrandt/acp_sp_dma.c create mode 100644 src/drivers/amd/rembrandt/interrupt.c create mode 100644 src/drivers/amd/rembrandt/ipc.c create mode 100644 src/drivers/amd/rembrandt/timer.c diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt index 5195a5e777fd..0a07372cece6 100644 --- a/src/drivers/CMakeLists.txt +++ b/src/drivers/CMakeLists.txt @@ -8,7 +8,7 @@ if(CONFIG_INTEL) add_subdirectory(intel) endif() -if(CONFIG_RENOIR) +if(CONFIG_RENOIR OR CONFIG_REMBRANDT) add_subdirectory(amd) endif() diff --git a/src/drivers/amd/CMakeLists.txt b/src/drivers/amd/CMakeLists.txt index dd87c456b58a..ecbccd50e4f8 100644 --- a/src/drivers/amd/CMakeLists.txt +++ b/src/drivers/amd/CMakeLists.txt @@ -2,4 +2,6 @@ if(CONFIG_RENOIR) add_subdirectory(renoir) +elseif(CONFIG_REMBRANDT) + add_subdirectory(rembrandt) endif() diff --git a/src/drivers/amd/rembrandt/CMakeLists.txt b/src/drivers/amd/rembrandt/CMakeLists.txt new file mode 100644 index 000000000000..d07a2335b2c6 --- /dev/null +++ b/src/drivers/amd/rembrandt/CMakeLists.txt @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof + acp_dma.c + acp_bt_dai.c + acp_sp_dai.c + acp_dmic_dai.c + acp_hs_dai.c + interrupt.c + ipc.c + timer.c + acp_bt_dma.c + acp_sp_dma.c + acp_hs_dma.c + acp_dmic_dma.c +) diff --git a/src/drivers/amd/rembrandt/acp_bt_dai.c b/src/drivers/amd/rembrandt/acp_bt_dai.c new file mode 100644 index 000000000000..2d0016b79655 --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_bt_dai.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 4abd71ba-8619-458a-b33f-160fc0cf809b */ +DECLARE_SOF_UUID("btdai", btdai_uuid, 0x4abd71ba, 0x8619, 0x458a, + 0xb3, 0x3f, 0x16, 0x0f, 0xc0, 0xcf, 0x80, 0x9b); + +DECLARE_TR_CTX(btdai_tr, SOF_UUID(btdai_uuid), LOG_LEVEL_INFO); + +static inline int btdai_set_config(struct dai *dai, struct ipc_config_dai *common_config, + void *spec_config) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int btdai_trigger(struct dai *dai, int cmd, int direction) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int btdai_probe(struct dai *dai) +{ + /* TODO */ + return 0; +} + +static int btdai_remove(struct dai *dai) +{ + /* TODO */ + return 0; +} + +static int btdai_get_fifo(struct dai *dai, int direction, int stream_id) +{ + switch (direction) { + case DAI_DIR_PLAYBACK: + case DAI_DIR_CAPTURE: + return dai_fifo(dai, direction); + default: + dai_err(dai, "Not a valid direction"); + return -EINVAL; + } +} + +static int btdai_get_handshake(struct dai *dai, int direction, int stream_id) +{ + return dai->plat_data.fifo[direction].handshake; +} + +static int btdai_get_hw_params(struct dai *dai, + struct sof_ipc_stream_params *params, int dir) +{ + /* supported parameters */ + params->rate = ACP_DEFAULT_SAMPLE_RATE; + params->channels = ACP_DEFAULT_NUM_CHANNELS; + params->buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; + params->frame_fmt = SOF_IPC_FRAME_S16_LE; + return 0; +} + +const struct dai_driver acp_btdai_driver = { + .type = SOF_DAI_AMD_BT, + .uid = SOF_UUID(btdai_uuid), + .tctx = &btdai_tr, + .dma_dev = DMA_DEV_BT, + .dma_caps = DMA_CAP_BT, + .ops = { + .trigger = btdai_trigger, + .set_config = btdai_set_config, + .probe = btdai_probe, + .remove = btdai_remove, + .get_fifo = btdai_get_fifo, + .get_handshake = btdai_get_handshake, + .get_hw_params = btdai_get_hw_params, + }, +}; diff --git a/src/drivers/amd/rembrandt/acp_bt_dma.c b/src/drivers/amd/rembrandt/acp_bt_dma.c new file mode 100644 index 000000000000..e3bc8e43a80b --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_bt_dma.c @@ -0,0 +1,425 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* ee12fa71-4579-45d7-bde2-b32c6893a122 */ +DECLARE_SOF_UUID("acp-bt-dma", acp_bt_dma_uuid, 0xab01db67, 0x84b0, 0x4d2d, + 0x93, 0xd3, 0x0e, 0x61, 0x96, 0x80, 0x57, 0x6e); + +DECLARE_TR_CTX(acp_bt_dma_tr, SOF_UUID(acp_bt_dma_uuid), LOG_LEVEL_INFO); + +/* DMA number of buffer periods */ +#define ACP_BT_FIFO_BUFFER_SIZE 768 +#define BT_TX_FIFO_ADDR (ACP_BT_FIFO_BUFFER_SIZE * 3) +#define BT_RX_FIFO_ADDR (BT_TX_FIFO_ADDR + ACP_BT_FIFO_BUFFER_SIZE) + +/* ACP DMA transfer size */ +#define ACP_BT_DMA_TRANS_SIZE 128 + +static uint64_t prev_tx_pos; +static uint64_t prev_rx_pos; + +/* Allocate requested DMA channel if it is free */ +static struct dma_chan_data *acp_dai_bt_dma_channel_get(struct dma *dma, + unsigned int req_chan) +{ + k_spinlock_key_t key; + struct dma_chan_data *channel; + + key = k_spin_lock(&dma->lock); + if (req_chan >= dma->plat_data.channels) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_bt_dma_tr, "Channel %d not in range", req_chan); + return NULL; + } + channel = &dma->chan[req_chan]; + if (channel->status != COMP_STATE_INIT) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_bt_dma_tr, "channel already in use %d", req_chan); + return NULL; + } + atomic_add(&dma->num_channels_busy, 1); + channel->status = COMP_STATE_READY; + k_spin_unlock(&dma->lock, key); + + return channel; +} + +/* channel must not be running when this is called */ +static void acp_dai_bt_dma_channel_put(struct dma_chan_data *channel) +{ + k_spinlock_key_t key; + + notifier_unregister_all(NULL, channel); + key = k_spin_lock(&channel->dma->lock); + channel->status = COMP_STATE_INIT; + atomic_sub(&channel->dma->num_channels_busy, 1); + k_spin_unlock(&channel->dma->lock, key); +} + +static int acp_dai_bt_dma_start(struct dma_chan_data *channel) +{ + acp_bttdm_ier_t bt_ier; + acp_bttdm_iter_t bt_tdm_iter; + acp_bttdm_irer_t bt_tdm_irer; + + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + channel->status = COMP_STATE_ACTIVE; + prev_tx_pos = 0; + bt_ier = (acp_bttdm_ier_t)io_reg_read(PU_REGISTER_BASE + ACP_BTTDM_IER); + bt_ier.bits.bttdm_ien = 1; + io_reg_write((PU_REGISTER_BASE + ACP_BTTDM_IER), bt_ier.u32all); + bt_tdm_iter.u32all = 0; + bt_tdm_iter.bits.bttdm_txen = 1; + bt_tdm_iter.bits.bttdm_tx_protocol_mode = 0; + bt_tdm_iter.bits.bttdm_tx_data_path_mode = 1; + bt_tdm_iter.bits.bttdm_tx_samp_len = 2; + io_reg_write((PU_REGISTER_BASE + ACP_BTTDM_ITER), bt_tdm_iter.u32all); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + channel->status = COMP_STATE_ACTIVE; + bt_ier = (acp_bttdm_ier_t)io_reg_read(PU_REGISTER_BASE + ACP_BTTDM_IER); + bt_ier.bits.bttdm_ien = 1; + io_reg_write((PU_REGISTER_BASE + ACP_BTTDM_IER), bt_ier.u32all); + bt_tdm_irer.u32all = 0; + bt_tdm_irer.bits.bttdm_rx_en = 1; + bt_tdm_irer.bits.bttdm_rx_protocol_mode = 0; + bt_tdm_irer.bits.bttdm_rx_data_path_mode = 1; + bt_tdm_irer.bits.bttdm_rx_samplen = 2; + io_reg_write((PU_REGISTER_BASE + ACP_BTTDM_IRER), bt_tdm_irer.u32all); + } else { + tr_err(&acp_bt_dma_tr, "Start direction not defined %d", channel->direction); + return -EINVAL; + } + return 0; +} + + +static int acp_dai_bt_dma_release(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int acp_dai_bt_dma_pause(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int acp_dai_bt_dma_stop(struct dma_chan_data *channel) +{ + acp_bttdm_iter_t bt_tdm_iter; + acp_bttdm_irer_t bt_tdm_irer; + + switch (channel->status) { + case COMP_STATE_READY: + case COMP_STATE_PREPARE: + return 0; + case COMP_STATE_PAUSED: + case COMP_STATE_ACTIVE: + break; + default: + return -EINVAL; + } + channel->status = COMP_STATE_READY; + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + bt_tdm_iter = (acp_bttdm_iter_t)io_reg_read(PU_REGISTER_BASE + ACP_BTTDM_ITER); + bt_tdm_iter.bits.bttdm_txen = 0; + io_reg_write(PU_REGISTER_BASE + ACP_BTTDM_ITER, bt_tdm_iter.u32all); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + bt_tdm_irer = (acp_bttdm_irer_t)io_reg_read(PU_REGISTER_BASE + ACP_BTTDM_IRER); + bt_tdm_irer.bits.bttdm_rx_en = 0; + io_reg_write(PU_REGISTER_BASE + ACP_BTTDM_IRER, bt_tdm_irer.u32all); + } else { + tr_err(&acp_bt_dma_tr, "direction not defined %d", channel->direction); + return -EINVAL; + } + return 0; +} + +/* fill in "status" with current DMA channel state and position */ +static int acp_dai_bt_dma_status(struct dma_chan_data *channel, + struct dma_chan_status *status, + uint8_t direction) +{ + /* nothing to do on rembrandt */ + return 0; +} + +/* set the DMA channel configuration + * source/target address + * DMA transfer sizes + */ +static int acp_dai_bt_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config) +{ + uint32_t tx_ringbuff_addr; + uint32_t rx_ringbuff_addr; + uint32_t fifo_addr; + acp_bt_tx_ringbufaddr_t tx_rbuff; + acp_bt_tx_fifosize_t tx_fifo_size; + acp_bt_tx_dmasize_t tx_dma_size; + acp_bt_tx_ringbufsize_t tx_rbuff_size; + acp_bt_tx_ringbufaddr_t rx_rbuff; + acp_bt_tx_fifosize_t rx_fifo_size; + acp_bt_tx_dmasize_t rx_dma_size; + acp_bt_tx_ringbufsize_t rx_rbuff_size; + acp_bt_tx_intr_watermark_size_t tx_wtrmrk; + acp_bt_rx_intr_watermark_size_t rx_wtrmrk; + + channel->is_scheduling_source = true; + channel->direction = config->direction; + switch (config->direction) { + case DMA_DIR_MEM_TO_DEV: + config->elem_array.elems[0].src = + (config->elem_array.elems[0].src & ACP_DRAM_ADDRESS_MASK); + tx_ringbuff_addr = (config->elem_array.elems[0].src | 0x01000000); + /* BT Transmit FIFO Address and FIFO Size */ + fifo_addr = BT_TX_FIFO_ADDR; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_TX_FIFOADDR), fifo_addr); + tx_fifo_size.u32all = ACP_BT_FIFO_BUFFER_SIZE; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_TX_FIFOSIZE), tx_fifo_size.u32all); + /* Transmit RINGBUFFER Address and size */ + tx_rbuff.u32all = tx_ringbuff_addr; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_TX_RINGBUFADDR), tx_rbuff.u32all); + tx_rbuff_size.u32all = ACP_BT_FIFO_BUFFER_SIZE; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_TX_RINGBUFSIZE), + tx_rbuff_size.u32all); + /* Transmit DMA transfer size in bytes */ + tx_dma_size.u32all = ACP_DMA_TRANS_SIZE; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_TX_DMA_SIZE), tx_dma_size.u32all); + /* Watermark size for BT transfer fifo */ + tx_wtrmrk.bits.bt_tx_intr_watermark_size = ACP_BT_FIFO_BUFFER_SIZE/2; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_TX_INTR_WATERMARK_SIZE), + tx_wtrmrk.u32all); + break; + case DMA_DIR_DEV_TO_MEM: + config->elem_array.elems[0].dest = + (config->elem_array.elems[0].dest & ACP_DRAM_ADDRESS_MASK); + rx_ringbuff_addr = (config->elem_array.elems[0].dest | 0x01000000); + fifo_addr = BT_RX_FIFO_ADDR; + /* BT Receive FIFO Address and FIFO Size*/ + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_RX_FIFOADDR), fifo_addr); + rx_fifo_size.u32all = ACP_BT_FIFO_BUFFER_SIZE; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_RX_FIFOSIZE), + rx_fifo_size.u32all); + /* Receive RINGBUFFER Address and size */ + rx_rbuff.u32all = rx_ringbuff_addr; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_RX_RINGBUFADDR), + rx_rbuff.u32all); + rx_rbuff_size.u32all = ACP_BT_FIFO_BUFFER_SIZE; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_RX_RINGBUFSIZE), + rx_rbuff_size.u32all); + /* Receive DMA transfer size in bytes */ + rx_dma_size.u32all = ACP_BT_DMA_TRANS_SIZE; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_RX_DMA_SIZE), + rx_dma_size.u32all); + /* Watermark size for BT receive fifo */ + rx_wtrmrk.bits.bt_rx_intr_watermark_size = ACP_BT_FIFO_BUFFER_SIZE/2; + io_reg_write((PU_REGISTER_BASE + ACP_P1_BT_RX_INTR_WATERMARK_SIZE), + rx_wtrmrk.u32all); + break; + default: + tr_err(&acp_bt_dma_tr, "unsupported config direction"); + return -EINVAL; + } + if (!config->cyclic) { + tr_err(&acp_bt_dma_tr, "cyclic configurations only supported"); + return -EINVAL; + } + if (config->scatter) { + tr_err(&acp_bt_dma_tr, "scatter is not supported for now!"); + return -EINVAL; + } + return 0; +} + +static int acp_dai_bt_dma_copy(struct dma_chan_data *channel, int bytes, + uint32_t flags) +{ + struct dma_cb_data next = { + .channel = channel, + .elem.size = bytes, + }; + notifier_event(channel, NOTIFIER_ID_DMA_COPY, + NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); + return 0; +} + +static int acp_dai_bt_dma_probe(struct dma *dma) +{ + int channel; + + if (dma->chan) { + tr_err(&acp_bt_dma_tr, "Repeated probe"); + return -EEXIST; + } + dma->chan = rzalloc(SOF_MEM_ZONE_SYS_RUNTIME, 0, + SOF_MEM_CAPS_RAM, dma->plat_data.channels * + sizeof(struct dma_chan_data)); + if (!dma->chan) { + tr_err(&acp_bt_dma_tr, "Probe failure, unable to allocate channel descriptors"); + return -ENOMEM; + } + for (channel = 0; channel < dma->plat_data.channels; channel++) { + dma->chan[channel].dma = dma; + dma->chan[channel].index = channel; + dma->chan[channel].status = COMP_STATE_INIT; + } + atomic_init(&dma->num_channels_busy, 0); + return 0; +} + +static int acp_dai_bt_dma_remove(struct dma *dma) +{ + if (!dma->chan) { + tr_err(&acp_bt_dma_tr, "remove called without probe, it's a no-op"); + return 0; + } + + rfree(dma->chan); + dma->chan = NULL; + return 0; +} + +static int acp_dai_bt_dma_get_data_size(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free) +{ + uint64_t tx_low, curr_tx_pos, tx_high; + uint64_t rx_low, curr_rx_pos, rx_high; + + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + tx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_BT_TX_LINEARPOSITIONCNTR_LOW); + tx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_BT_TX_LINEARPOSITIONCNTR_HIGH); + curr_tx_pos = (uint64_t)((tx_high << 32) | tx_low); + *free = (curr_tx_pos - prev_tx_pos) > ACP_BT_FIFO_BUFFER_SIZE ? + (curr_tx_pos - prev_tx_pos) % ACP_BT_FIFO_BUFFER_SIZE : + curr_tx_pos - prev_tx_pos; + *avail = ACP_BT_FIFO_BUFFER_SIZE - *free; + prev_tx_pos = curr_tx_pos; + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + rx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_BT_RX_LINEARPOSITIONCNTR_LOW); + rx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_BT_RX_LINEARPOSITIONCNTR_HIGH); + curr_rx_pos = (uint64_t)((rx_high << 32) | rx_low); + *free = (curr_rx_pos - prev_rx_pos) > ACP_BT_FIFO_BUFFER_SIZE ? + (curr_rx_pos - prev_rx_pos) % ACP_BT_FIFO_BUFFER_SIZE : + (curr_rx_pos - prev_rx_pos); + *avail = ACP_BT_FIFO_BUFFER_SIZE - *free; + prev_rx_pos = curr_rx_pos; + } else { + tr_err(&acp_bt_dma_tr, "Channel direction Not defined %d", + channel->direction); + return -EINVAL; + } + return 0; +} + +static int acp_dai_bt_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) +{ + switch (type) { + case DMA_ATTR_BUFFER_ALIGNMENT: + case DMA_ATTR_COPY_ALIGNMENT: + *value = ACP_DMA_BUFFER_ALIGN_128; + break; + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + *value = PLATFORM_DCACHE_ALIGN; + break; + case DMA_ATTR_BUFFER_PERIOD_COUNT: + *value = ACP_DAI_DMA_BUFFER_PERIOD_COUNT; + break; + default: + return -ENOENT; /* Attribute not found */ + } + return 0; +} + +static int acp_dai_bt_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) +{ + uint32_t status; + acp_dsp0_intr_stat_t acp_intr_stat; + acp_dsp0_intr_cntl_t acp_intr_cntl; + + if (channel->status == COMP_STATE_INIT) + return 0; + + switch (cmd) { + case DMA_IRQ_STATUS_GET: + acp_intr_stat = (acp_dsp0_intr_stat_t) + (dma_reg_read(channel->dma, ACP_DSP0_INTR_STAT1)); + status = acp_intr_stat.bits.audio_buffer_int_stat; + return (status & (1<index)); + case DMA_IRQ_CLEAR: + acp_intr_stat.u32all = 0; + acp_intr_stat.bits.audio_buffer_int_stat = (1 << channel->index); + status = acp_intr_stat.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_STAT1, status); + return 0; + case DMA_IRQ_MASK: + acp_intr_cntl = (acp_dsp0_intr_cntl_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL1); + acp_intr_cntl.bits.audio_buffer_int_mask &= (~(1 << channel->index)); + status = acp_intr_cntl.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL1, status); + return 0; + case DMA_IRQ_UNMASK: + acp_intr_cntl = (acp_dsp0_intr_cntl_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL1); + acp_intr_cntl.bits.audio_buffer_int_mask |= (1 << channel->index); + status = acp_intr_cntl.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL1, status); + return 0; + default: + return -EINVAL; + } +} + +const struct dma_ops acp_dai_bt_dma_ops = { + .channel_get = acp_dai_bt_dma_channel_get, + .channel_put = acp_dai_bt_dma_channel_put, + .start = acp_dai_bt_dma_start, + .stop = acp_dai_bt_dma_stop, + .pause = acp_dai_bt_dma_pause, + .release = acp_dai_bt_dma_release, + .copy = acp_dai_bt_dma_copy, + .status = acp_dai_bt_dma_status, + .set_config = acp_dai_bt_dma_set_config, + .interrupt = acp_dai_bt_dma_interrupt, + .probe = acp_dai_bt_dma_probe, + .remove = acp_dai_bt_dma_remove, + .get_data_size = acp_dai_bt_dma_get_data_size, + .get_attribute = acp_dai_bt_dma_get_attribute, +}; diff --git a/src/drivers/amd/rembrandt/acp_dma.c b/src/drivers/amd/rembrandt/acp_dma.c new file mode 100644 index 000000000000..c85ddd74450e --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_dma.c @@ -0,0 +1,662 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ACP_MAX_STREAMS 8 +#define ACP_DMA_BUFFER_PERIOD_COUNT 2 +#define ACP_SYST_MEM_WINDOW 0x4000000 + +/* Need to look for proper uuid for amd platform*/ +DECLARE_SOF_UUID("acpdma", acpdma_uuid, 0x70f2d3f2, 0xcbb6, 0x4984, + 0xa2, 0xd8, 0x0d, 0xd5, 0x14, 0xb8, 0x0b, 0xc2); +DECLARE_TR_CTX(acpdma_tr, SOF_UUID(acpdma_uuid), LOG_LEVEL_INFO); + +struct acp_dma_config { + /* base address of dma buffer */ + uint32_t base; + /* size of dma buffer */ + uint32_t size; + /* write pointer of dma buffer */ + uint32_t wr_ptr; + /* read pointer of dma buffer */ + uint32_t rd_ptr; + /* read size of dma buffer */ + uint32_t rd_size; + /* write size of dma buffer */ + uint32_t wr_size; + /* system memory size defined for the stream */ + uint32_t sys_buff_size; + /* virtual system memory offset for system memory buffer */ + uint32_t phy_off; +}; + +struct acp_dma_chan_data { + /* channel index */ + uint32_t idx; + /* stream direction */ + uint32_t dir; + /* configuration data of dma */ + struct acp_dma_config config[ACP_MAX_STREAMS]; +}; + +static void dma_config_descriptor(uint32_t dscr_start_idx, uint32_t dscr_count, + acp_cfg_dma_descriptor_t *psrc_dscr, + acp_cfg_dma_descriptor_t *pdest_dscr) +{ + uint16_t dscr; + + if ((dscr_count) && (psrc_dscr) && (pdest_dscr) && + (dscr_start_idx < MAX_NUM_DMA_DESC_DSCR)) { + for (dscr = 0; dscr < dscr_count; dscr++) { + pdest_dscr[dscr_start_idx + dscr].src_addr = + psrc_dscr[dscr].src_addr; + pdest_dscr[dscr_start_idx + dscr].dest_addr = + psrc_dscr[dscr].dest_addr; + pdest_dscr[dscr_start_idx + dscr].trns_cnt.u32All = + psrc_dscr[dscr].trns_cnt.u32All; + } + } +} + +static void dma_reconfig(struct dma_chan_data *channel, uint32_t bytes) +{ + uint32_t strt_idx = 0; + uint32_t src = 0; + uint32_t dest = 0; + uint32_t tail = 0, head = 0; + uint32_t src1 = 0; + uint32_t dest1 = 0; + + acp_cfg_dma_descriptor_t psrc_dscr[ACP_MAX_STREAMS]; + acp_cfg_dma_descriptor_t *pdest_dscr; + acp_dma_cntl_0_t dma_cntl; + struct acp_dma_chan_data *acp_dma_chan; + struct acp_dma_config *dma_cfg; + + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + acp_dma_chan = dma_chan_get_data(channel); + dma_cfg = &acp_dma_chan->config[channel->index]; + pdest_dscr = (acp_cfg_dma_descriptor_t *)(pscratch_mem_cfg->acp_cfg_dma_descriptor); + if (channel->direction == DMA_DIR_HMEM_TO_LMEM) { + head = bytes; + /* Update the read and write pointers */ + dma_cfg->rd_ptr = ACP_SYST_MEM_WINDOW + dma_cfg->phy_off + dma_cfg->rd_size; + dma_cfg->wr_ptr = dma_cfg->base + dma_cfg->wr_size; + src = dma_cfg->rd_ptr; + dest = dma_cfg->wr_ptr; + psrc_dscr[strt_idx].src_addr = src; + dest = (dest & ACP_DRAM_ADDRESS_MASK); + /* Known Data hack */ + psrc_dscr[strt_idx].dest_addr = (dest | 0x01000000); + psrc_dscr[strt_idx].trns_cnt.bits.trns_cnt = bytes; + /* Configure a single descrption */ + dma_config_descriptor(strt_idx, 1, psrc_dscr, pdest_dscr); + dma_chan_reg_write(channel, ACP_DMA_DSCR_CNT_0, 1); + /* Check for wrap-around case for system buffer */ + if (dma_cfg->rd_size + bytes > dma_cfg->sys_buff_size) { + /* Configure the descriptor for head and tail */ + /* values for the wrap around case */ + tail = dma_cfg->sys_buff_size - dma_cfg->rd_size; + head = bytes - tail; + psrc_dscr[strt_idx].trns_cnt.bits.trns_cnt = tail; + psrc_dscr[strt_idx+1].src_addr = ACP_SYST_MEM_WINDOW + dma_cfg->phy_off; + dest1 = dest+tail; + dest1 = (dest1 & ACP_DRAM_ADDRESS_MASK); + psrc_dscr[strt_idx+1].dest_addr = (dest1 | 0x01000000); + psrc_dscr[strt_idx+1].trns_cnt.bits.trns_cnt = head; + dma_config_descriptor(strt_idx, 2, psrc_dscr, pdest_dscr); + dma_chan_reg_write(channel, ACP_DMA_DSCR_CNT_0, 2); + dma_cfg->rd_size = 0; + } + dma_cfg->rd_size += head; + dma_cfg->rd_size %= dma_cfg->sys_buff_size; + dma_cfg->wr_size += bytes; + dma_cfg->wr_size %= dma_cfg->size; + } else if (channel->direction == DMA_DIR_LMEM_TO_HMEM) { + head = bytes; + dma_cfg->wr_ptr = ACP_SYST_MEM_WINDOW + dma_cfg->phy_off + dma_cfg->wr_size; + dma_cfg->rd_ptr = dma_cfg->base + dma_cfg->rd_size; + src = dma_cfg->rd_ptr; + dest = dma_cfg->wr_ptr; + src = (src & ACP_DRAM_ADDRESS_MASK); + psrc_dscr[strt_idx].src_addr = (src | 0x01000000); + psrc_dscr[strt_idx].dest_addr = dest; + psrc_dscr[strt_idx].trns_cnt.bits.trns_cnt = bytes; + /* Configure a single descrption */ + dma_config_descriptor(strt_idx, 1, psrc_dscr, pdest_dscr); + dma_chan_reg_write(channel, ACP_DMA_DSCR_CNT_0, 1); + /* Check for wrap-around case for system buffer */ + if (dma_cfg->wr_size + bytes > dma_cfg->sys_buff_size) { + /* Configure the descriptor for head and + * tail values for the wrap around case + */ + tail = dma_cfg->sys_buff_size - dma_cfg->wr_size; + head = bytes - tail; + psrc_dscr[strt_idx].trns_cnt.bits.trns_cnt = tail; + src1 = src + tail; + psrc_dscr[strt_idx+1].dest_addr = ACP_SYST_MEM_WINDOW + dma_cfg->phy_off; + psrc_dscr[strt_idx+1].trns_cnt.bits.trns_cnt = head; + src1 = (src1 & ACP_DRAM_ADDRESS_MASK); + psrc_dscr[strt_idx+1].src_addr = (src1 | 0x01000000); + dma_config_descriptor(strt_idx, 2, psrc_dscr, pdest_dscr); + dma_chan_reg_write(channel, ACP_DMA_DSCR_CNT_0, 2); + dma_cfg->wr_size = 0; + } + dma_cfg->wr_size += head; + dma_cfg->wr_size %= dma_cfg->sys_buff_size; + dma_cfg->rd_size += bytes; + dma_cfg->rd_size %= dma_cfg->size; + } + /* clear the dma channel control bits */ + dma_cntl = (acp_dma_cntl_0_t) dma_chan_reg_read(channel, ACP_DMA_CNTL_0); + dma_cntl.bits.dmachrun = 0; + dma_chan_reg_write(channel, ACP_DMA_CNTL_0, dma_cntl.u32all); + /* Load start index of decriptor and priority */ + dma_chan_reg_write(channel, ACP_DMA_DSCR_STRT_IDX_0, strt_idx); + dma_chan_reg_write(channel, ACP_DMA_PRIO_0, 1); + channel->status = COMP_STATE_PREPARE; +} + +static struct dma_chan_data *acp_dma_channel_get(struct dma *dma, + unsigned int req_chan) +{ + k_spinlock_key_t key; + struct dma_chan_data *channel; + + key = k_spin_lock(&dma->lock); + if (req_chan >= dma->plat_data.channels) { + k_spin_unlock(&dma->lock, key); + tr_err(&acpdma_tr, "DMA: Channel %d not in range", req_chan); + return NULL; + } + channel = &dma->chan[req_chan]; + if (channel->status != COMP_STATE_INIT) { + k_spin_unlock(&dma->lock, key); + tr_err(&acpdma_tr, "DMA: channel already in use %d", req_chan); + return NULL; + } + atomic_add(&dma->num_channels_busy, 1); + channel->status = COMP_STATE_READY; + k_spin_unlock(&dma->lock, key); + /* reset read and write pointers */ + struct acp_dma_chan_data *acp_dma_chan = dma_chan_get_data(channel); + + acp_dma_chan->config[req_chan].rd_size = 0; + acp_dma_chan->config[req_chan].wr_size = 0; + return channel; +} + +static void acp_dma_channel_put(struct dma_chan_data *channel) +{ + k_spinlock_key_t key; + struct acp_dma_chan_data *acp_dma_chan = dma_chan_get_data(channel); + + key = k_spin_lock(&channel->dma->lock); + channel->status = COMP_STATE_INIT; + atomic_sub(&channel->dma->num_channels_busy, 1); + k_spin_unlock(&channel->dma->lock, key); + /* reset read and write pointer */ + acp_dma_chan->config[channel->index].rd_size = 0; + acp_dma_chan->config[channel->index].wr_size = 0; +} + +/* Stop the requested channel */ +static int acp_dma_stop(struct dma_chan_data *channel) +{ + acp_dma_cntl_0_t dma_cntl; + acp_dma_ch_sts_t ch_sts; + uint32_t dmach_mask; + uint32_t delay_cnt = 10000; + + switch (channel->status) { + case COMP_STATE_READY: + case COMP_STATE_PREPARE: + return 0; /* do not try to stop multiple times */ + case COMP_STATE_PAUSED: + case COMP_STATE_ACTIVE: + break; + default: + return -EINVAL; + } + channel->status = COMP_STATE_READY; + dmach_mask = (1 << channel->index); + dma_cntl = (acp_dma_cntl_0_t) dma_chan_reg_read(channel, ACP_DMA_CNTL_0); + /* Do the HW stop of the DMA */ + /* set DMAChRst bit to stop the transfer */ + dma_cntl.bits.dmachrun = 0; + dma_cntl.bits.dmachiocen = 0; + dma_chan_reg_write(channel, ACP_DMA_CNTL_0, dma_cntl.u32all); + ch_sts = (acp_dma_ch_sts_t) dma_reg_read(channel->dma, ACP_DMA_CH_STS); + if (ch_sts.bits.dmachrunsts & dmach_mask) { + /* set the reset bit for this channel to stop the dma transfer */ + dma_cntl.bits.dmachrst = 1; + dma_chan_reg_write(channel, ACP_DMA_CNTL_0, dma_cntl.u32all); + } + + while (delay_cnt > 0) { + ch_sts = (acp_dma_ch_sts_t) dma_reg_read(channel->dma, ACP_DMA_CH_STS); + if (!(ch_sts.bits.dmachrunsts & dmach_mask)) { + /* clear the reset flag after successfully stopping the dma transfer + * and break from the loop + */ + dma_cntl.bits.dmachrst = 0; + dma_chan_reg_write(channel, ACP_DMA_CNTL_0, dma_cntl.u32all); + break; + } + delay_cnt--; + } + return 0; +} + +static int acp_dma_start(struct dma_chan_data *channel) +{ + acp_dma_cntl_0_t dma_cntl; + acp_dma_ch_sts_t dma_sts; + uint32_t chan_sts; + int ret = 0; + struct timer *timer = timer_get(); + uint64_t deadline = platform_timer_get(timer) + + clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1) * 500 / 1000; + if (channel->status != COMP_STATE_PREPARE && + channel->status != COMP_STATE_SUSPEND) + return -EINVAL; + channel->status = COMP_STATE_ACTIVE; + /* Clear DMAChRun before starting the DMA Ch */ + dma_cntl = (acp_dma_cntl_0_t) dma_chan_reg_read(channel, ACP_DMA_CNTL_0); + dma_cntl.bits.dmachrun = 0; + dma_cntl.bits.dmachiocen = 0; + dma_chan_reg_write(channel, ACP_DMA_CNTL_0, dma_cntl.u32all); + + dma_cntl = (acp_dma_cntl_0_t) dma_chan_reg_read(channel, ACP_DMA_CNTL_0); + dma_cntl.bits.dmachrun = 1; + dma_cntl.bits.dmachiocen = 0; + + /* set dmachrun bit to start the transfer */ + dma_chan_reg_write(channel, ACP_DMA_CNTL_0, dma_cntl.u32all); + + /* poll for the status bit + * to finish the dma transfer + * then initiate call back function + */ + dma_sts = (acp_dma_ch_sts_t)dma_reg_read(channel->dma, ACP_DMA_CH_STS); + chan_sts = dma_sts.u32all & (1<index); + while (chan_sts) { + if (deadline < platform_timer_get(timer)) { + /* safe check in case we've got preempted after read */ + if (chan_sts) + return 0; + tr_err(&acpdma_tr, "acp-dma: timed out for dma start"); + return -ETIME; + } + dma_sts = (acp_dma_ch_sts_t)dma_reg_read(channel->dma, ACP_DMA_CH_STS); + chan_sts = dma_sts.u32all & (1<index); + } + return ret; +} + +static int acp_dma_release(struct dma_chan_data *channel) +{ + tr_info(&acpdma_tr, "DMA: release(%d)", channel->index); + if (channel->status != COMP_STATE_PAUSED) + return -EINVAL; + channel->status = COMP_STATE_ACTIVE; + return 0; +} + +static int acp_dma_pause(struct dma_chan_data *channel) +{ + tr_info(&acpdma_tr, "h/w pause is not supported, changing the status of(%d) channel", + channel->index); + if (channel->status != COMP_STATE_ACTIVE) + return -EINVAL; + channel->status = COMP_STATE_PAUSED; + return 0; +} + +static int acp_dma_copy(struct dma_chan_data *channel, int bytes, uint32_t flags) +{ + struct dma_cb_data next = { + .channel = channel, + .elem.size = bytes, + }; + acp_dma_ch_sts_t ch_sts; + uint32_t dmach_mask = (1 << channel->index); + int ret = 0; + + if (flags & DMA_COPY_ONE_SHOT) { + ret = acp_dma_start(channel); + if (ret < 0) + return ret; + ch_sts = (acp_dma_ch_sts_t) dma_reg_read(channel->dma, ACP_DMA_CH_STS); + while (ch_sts.bits.dmachrunsts & dmach_mask) { + ch_sts = (acp_dma_ch_sts_t) dma_reg_read(channel->dma, ACP_DMA_CH_STS); + if (!(ch_sts.bits.dmachrunsts & dmach_mask)) + break; + } + ret = acp_dma_stop(channel); + } + /* Reconfigure dma descriptors for stream channels only */ + if (channel->index != DMA_TRACE_CHANNEL) { + /* Reconfigure the dma descriptors for next buffer of data after the call back */ + dma_reconfig(channel, bytes); + /* Start the dma for requested channel */ + acp_dma_start(channel); + /* Stop the dma for requested channel */ + acp_dma_stop(channel); + } + notifier_event(channel, NOTIFIER_ID_DMA_COPY, + NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); + return ret; +} + +static int acp_dma_status(struct dma_chan_data *channel, + struct dma_chan_status *status, uint8_t direction) +{ + status->state = channel->status; + status->flags = 0; + status->timestamp = timer_get_system(timer_get()); + return 0; +} + +/* Some set_config helper functions */ +static int dma_setup(struct dma_chan_data *channel, + struct dma_sg_elem_array *sgelems, uint32_t dir) +{ + uint32_t dscr_cnt, dscr = 0; + uint32_t tc; + uint16_t dscr_strt_idx = 0; + uint32_t *phy_off; + uint32_t *syst_buff_size; + uint32_t src; + uint32_t dest; + uint32_t buff_size = 0; + acp_dma_cntl_0_t dma_cntl; + struct acp_dma_config *dma_cfg; + struct acp_dma_chan_data *acp_dma_chan = dma_chan_get_data(channel); + + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + dscr_cnt = sgelems->count; + /* Trace uses descriptor from index seven */ + /* and other streams use descriptors from zero */ + if (channel->index == DMA_TRACE_CHANNEL) + dscr_strt_idx = DMA_TRACE_CHANNEL; + else + dscr_strt_idx = 0; + + /* ACP DMA Descriptor in scratch memory */ + acp_cfg_dma_descriptor_t *dma_config_dscr; + + dma_config_dscr = (acp_cfg_dma_descriptor_t *)(pscratch_mem_cfg->acp_cfg_dma_descriptor); + /* physical offset of system memory */ + phy_off = (uint32_t *)(pscratch_mem_cfg->phy_offset); + /* size of system memory buffer */ + syst_buff_size = (uint32_t *)(pscratch_mem_cfg->syst_buff_size); + for (dscr = 0; dscr < dscr_cnt; dscr++) { + if (dir == DMA_DIR_HMEM_TO_LMEM) { + if (channel->index != DMA_TRACE_CHANNEL) + dma_config_dscr[dscr_strt_idx + dscr].src_addr = + (phy_off[channel->index] + ACP_SYST_MEM_WINDOW + buff_size); + else + dma_config_dscr[dscr_strt_idx + dscr].src_addr = + sgelems->elems[dscr].src + ACP_SYST_MEM_WINDOW; + dest = sgelems->elems[dscr].dest; + dest = (dest & ACP_DRAM_ADDRESS_MASK); + dma_config_dscr[dscr_strt_idx + dscr].dest_addr = (dest | 0x01000000); + dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.u32All = 0; + dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.bits.trns_cnt = + sgelems->elems[dscr].size; + } else { + if (channel->index != DMA_TRACE_CHANNEL) + dma_config_dscr[dscr_strt_idx + dscr].dest_addr = + (phy_off[channel->index] + ACP_SYST_MEM_WINDOW + buff_size); + else + dma_config_dscr[dscr_strt_idx + dscr].dest_addr = + (sgelems->elems[dscr].dest + ACP_SYST_MEM_WINDOW); + src = sgelems->elems[dscr].src; + src = (src & ACP_DRAM_ADDRESS_MASK); + dma_config_dscr[dscr_strt_idx + dscr].src_addr = + (src | 0x01000000);/*rembrandt-arch*/ + dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.u32All = 0; + dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.bits.trns_cnt = + sgelems->elems[dscr].size; + } + dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.u32All = 0; + dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.bits.trns_cnt = + sgelems->elems[dscr].size; + buff_size = sgelems->elems[dscr].size; + } + dma_config_dscr[dscr_strt_idx + (dscr-1)].trns_cnt.bits.ioc = 0; + dma_cfg = &acp_dma_chan->config[channel->index]; + /* bytes of data to be transferred for the dma */ + tc = dma_config_dscr[dscr_strt_idx].trns_cnt.bits.trns_cnt; + /* DMA configuration for stream */ + if (channel->index != DMA_TRACE_CHANNEL) { + acp_dma_chan->dir = dir; + acp_dma_chan->idx = channel->index; + dma_cfg->phy_off = phy_off[channel->index]; + dma_cfg->size = tc * dscr_cnt; + dma_cfg->sys_buff_size = syst_buff_size[channel->index]; + + if (dir == DMA_DIR_HMEM_TO_LMEM) { + /* Playback */ + dma_config_dscr[dscr_strt_idx].dest_addr = + (dma_config_dscr[dscr_strt_idx].dest_addr & 0x0FFFFFFF); + dma_cfg->base = dma_config_dscr[dscr_strt_idx].dest_addr | 0x01000000; + dma_cfg->wr_size = 0; + dma_cfg->rd_size = dma_cfg->size; + } else { + /* Capture */ + dma_config_dscr[dscr_strt_idx].src_addr = + (dma_config_dscr[dscr_strt_idx].src_addr & 0x0FFFFFFF); + dma_cfg->base = dma_config_dscr[dscr_strt_idx].src_addr | 0x01000000; + dma_cfg->wr_size = dma_cfg->size; + dma_cfg->rd_size = 0; + } + } + /* clear the dma channel control bits */ + dma_cntl = (acp_dma_cntl_0_t) dma_chan_reg_read(channel, ACP_DMA_CNTL_0); + dma_cntl.bits.dmachrun = 0; + dma_cntl.bits.dmachiocen = 0; + dma_chan_reg_write(channel, ACP_DMA_CNTL_0, dma_cntl.u32all); + + /* Program DMAChDscrStrIdx to the index + * number of the first descriptor to be processed. + */ + dma_chan_reg_write(channel, ACP_DMA_DSCR_STRT_IDX_0, dscr_strt_idx); + /* program DMAChDscrdscrcnt to the + * number of descriptors to be processed in the transfer + */ + dma_chan_reg_write(channel, ACP_DMA_DSCR_CNT_0, dscr_cnt); + /* set DMAChPrioLvl according to the priority */ + dma_chan_reg_write(channel, ACP_DMA_PRIO_0, 1); + channel->status = COMP_STATE_PREPARE; + return 0; +} + +/* set the DMA channel configuration, source/target address, buffer sizes */ +static int acp_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config) +{ + uint32_t dir; + + channel->direction = config->direction; + dir = config->direction; + if (config->cyclic) { + tr_err(&acpdma_tr, + "DMA: cyclic configurations are not supported"); + return -EINVAL; + } + if (config->scatter) { + tr_err(&acpdma_tr, + "DMA: scatter is not supported Chan.Index %d scatter %d", + channel->index, config->scatter); + return -EINVAL; + } + return dma_setup(channel, &config->elem_array, dir); +} + +static int acp_dma_probe(struct dma *dma) +{ + struct acp_dma_chan_data *acp_dma_chan; + int channel; + + if (dma->chan) { + tr_err(&acpdma_tr, "DMA: Already probe"); + return -EEXIST; + } + dma->chan = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + dma->plat_data.channels * + sizeof(struct dma_chan_data)); + if (!dma->chan) { + tr_err(&acpdma_tr, "DMA: unable to allocate channel context"); + return -ENOMEM; + } + for (channel = 0; channel < dma->plat_data.channels; channel++) { + dma->chan[channel].dma = dma; + dma->chan[channel].index = channel; + dma->chan[channel].status = COMP_STATE_INIT; + acp_dma_chan = rzalloc(SOF_MEM_ZONE_SYS_RUNTIME, 0, + SOF_MEM_CAPS_RAM, + sizeof(struct acp_dma_chan_data)); + if (!acp_dma_chan) { + rfree(dma->chan); + tr_err(&acpdma_tr, "acp-dma: %d channel %d private data alloc failed", + dma->plat_data.id, channel); + return -ENOMEM; + } + dma_chan_set_data(&dma->chan[channel], acp_dma_chan); + } + return 0; +} + +static int acp_dma_remove(struct dma *dma) +{ + int channel; + + if (!dma->chan) { + tr_err(&acpdma_tr, "DMA: Invalid remove call"); + return 0; + } + for (channel = 0; channel < dma->plat_data.channels; channel++) + rfree(dma->chan[channel].priv_data); + rfree(dma->chan); + dma->chan = NULL; + + return 0; +} + +static int acp_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) +{ + uint32_t status; + + if (channel->status == COMP_STATE_INIT) + return 0; + + switch (cmd) { + case DMA_IRQ_STATUS_GET: + status = dma_reg_read(channel->dma, ACP_DSP0_INTR_STAT) & 0xFF; + return status & (1 << channel->index); + case DMA_IRQ_CLEAR: + status = dma_reg_read(channel->dma, ACP_DSP0_INTR_STAT); + status = status & (1 << channel->index); + dma_reg_write(channel->dma, ACP_DSP0_INTR_STAT, status); + return 0; + case DMA_IRQ_MASK: + status = dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL); + status = status & (~(1 << channel->index)); + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL, status); + return 0; + case DMA_IRQ_UNMASK: + status = dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL); + status = status | (1 << channel->index); + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL, status); + return 0; + default: + return -EINVAL; + } +} + +static int acp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) +{ + switch (type) { + case DMA_ATTR_BUFFER_ALIGNMENT: + case DMA_ATTR_COPY_ALIGNMENT: + *value = ACP_DMA_BUFFER_ALIGN_128; + break; + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + *value = PLATFORM_DCACHE_ALIGN; + break; + case DMA_ATTR_BUFFER_PERIOD_COUNT: + *value = ACP_DMA_BUFFER_PERIOD_COUNT; + break; + default: + return -ENOENT; /* Attribute not found */ + } + return 0; +} + +static int acp_dma_get_data_size(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free) +{ + struct acp_dma_chan_data *acp_dma_chan = dma_chan_get_data(channel); + uint32_t data_size = 0; + uint32_t tc = 0; /* transfer count in bytes */ + + tc = acp_dma_chan->config[channel->index].size; + data_size = (uint32_t)tc; + switch (channel->direction) { + case DMA_DIR_MEM_TO_DEV: + case DMA_DIR_HMEM_TO_LMEM: + *avail = ABS(data_size) / 2; + break; + case DMA_DIR_DEV_TO_MEM: + case DMA_DIR_LMEM_TO_HMEM: + *free = ABS(data_size) / 2; + break; + default: + tr_err(&acpdma_tr, "dma_get_data_size() Invalid direction %d", + channel->direction); + return -EINVAL; + } + return 0; +} + +const struct dma_ops acp_dma_ops = { + .channel_get = acp_dma_channel_get, + .channel_put = acp_dma_channel_put, + .start = acp_dma_start, + .stop = acp_dma_stop, + .pause = acp_dma_pause, + .release = acp_dma_release, + .copy = acp_dma_copy, + .status = acp_dma_status, + .set_config = acp_dma_set_config, + .probe = acp_dma_probe, + .remove = acp_dma_remove, + .interrupt = acp_dma_interrupt, + .get_attribute = acp_dma_get_attribute, + .get_data_size = acp_dma_get_data_size, +}; diff --git a/src/drivers/amd/rembrandt/acp_dmic_dai.c b/src/drivers/amd/rembrandt/acp_dmic_dai.c new file mode 100644 index 000000000000..c755e39ad6a5 --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_dmic_dai.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +// Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*0ae40946-dfd2-4140-91-52-0d-d5-a3-ea-ae-81*/ +DECLARE_SOF_UUID("acp_dmic_dai", acp_dmic_dai_uuid, 0x0ae40946, 0xdfd2, 0x4140, + 0x91, 0x52, 0x0d, 0xd5, 0xa3, 0xea, 0xae, 0x81); + +DECLARE_TR_CTX(acp_dmic_dai_tr, SOF_UUID(acp_dmic_dai_uuid), LOG_LEVEL_INFO); + +static inline int acp_dmic_dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, + void *spec_config) +{ + struct sof_ipc_dai_config *config = spec_config; + struct acp_pdata *acpdata = dai_get_drvdata(dai); + acp_wov_clk_ctrl_t clk_ctrl; + + acpdata->config = *config; + acpdata->dmic_params = config->acpdmic; + clk_ctrl = (acp_wov_clk_ctrl_t)io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE); + clk_ctrl.u32all = 0; + switch (acpdata->dmic_params.pdm_rate) { + case 48000: + /* DMIC Clock for 48K sample rate */ + clk_ctrl.bits.brm_clk_ctrl = 7; + break; + case 16000: + /* DMIC Clock for 16K sample rate */ + clk_ctrl.bits.brm_clk_ctrl = 1; + break; + default: + dai_info(dai, "unsupported samplerate"); + return -EINVAL; + } + io_reg_write(PU_REGISTER_BASE + ACP_WOV_CLK_CTRL, clk_ctrl.u32all); + return 0; +} + +static int acp_dmic_dai_trigger(struct dai *dai, int cmd, int direction) +{ + switch (cmd) { + case COMP_TRIGGER_START: + case COMP_TRIGGER_STOP: + default: + break; + } + return 0; +} + +static int acp_dmic_dai_probe(struct dai *dai) +{ + struct acp_pdata *acp; + + dai_info(dai, "dmic dai probe"); + /* allocate private data */ + acp = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*acp)); + if (!acp) { + dai_err(dai, "dmic dai probe alloc failed"); + return -ENOMEM; + } + dai_set_drvdata(dai, acp); + return 0; +} + +static int acp_dmic_dai_remove(struct dai *dai) +{ + struct acp_pdata *acp = dai_get_drvdata(dai); + + rfree(acp); + dai_set_drvdata(dai, NULL); + return 0; +} + +static int acp_dmic_dai_get_fifo(struct dai *dai, int direction, int stream_id) +{ + switch (direction) { + case DAI_DIR_PLAYBACK: + case DAI_DIR_CAPTURE: + return dai_fifo(dai, direction); + default: + dai_err(dai, "Invalid direction"); + return -EINVAL; + } +} + +static int acp_dmic_dai_get_handshake(struct dai *dai, int direction, + int stream_id) +{ + return dai->plat_data.fifo[direction].handshake; +} + +static int acp_dmic_dai_get_hw_params(struct dai *dai, + struct sof_ipc_stream_params *params, + int dir) +{ + struct acp_pdata *acpdata = dai_get_drvdata(dai); + + switch (acpdata->dmic_params.pdm_rate) { + case 48000: + case 16000: + params->rate = acpdata->dmic_params.pdm_rate; + break; + default: + dai_info(dai, "unsupported samplerate %d", acpdata->dmic_params.pdm_rate); + params->rate = ACP_DEFAULT_SAMPLE_RATE; + } + params->channels = ACP_DEFAULT_NUM_CHANNELS; + params->buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; + params->frame_fmt = SOF_IPC_FRAME_S32_LE; + return 0; +} + +const struct dai_driver acp_dmic_dai_driver = { + .type = SOF_DAI_AMD_DMIC, + .uid = SOF_UUID(acp_dmic_dai_uuid), + .tctx = &acp_dmic_dai_tr, + .dma_dev = DMA_DEV_DMIC, + .dma_caps = DMA_CAP_DMIC, + .ops = { + .trigger = acp_dmic_dai_trigger, + .set_config = acp_dmic_dai_set_config, + .probe = acp_dmic_dai_probe, + .remove = acp_dmic_dai_remove, + .get_fifo = acp_dmic_dai_get_fifo, + .get_handshake = acp_dmic_dai_get_handshake, + .get_hw_params = acp_dmic_dai_get_hw_params, + }, +}; diff --git a/src/drivers/amd/rembrandt/acp_dmic_dma.c b/src/drivers/amd/rembrandt/acp_dmic_dma.c new file mode 100644 index 000000000000..a4c271103a87 --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_dmic_dma.c @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uint32_t dmic_rngbuff_size; +/* 109c7aba-a7ba-43c3-b9-42-59-e2-0a-66-11-be */ +DECLARE_SOF_UUID("acp_dmic_dma", acp_dmic_dma_uuid, 0x109c7aba, 0xa7ba, 0x43c3, + 0xb9, 0x42, 0x59, 0xe2, 0x0a, 0x66, 0x11, 0xbe); +DECLARE_TR_CTX(acp_dmic_dma_tr, SOF_UUID(acp_dmic_dma_uuid), LOG_LEVEL_INFO); + +/* allocate next free DMA channel */ +static struct dma_chan_data *acp_dmic_dma_channel_get(struct dma *dma, + unsigned int req_chan) +{ + k_spinlock_key_t key; + struct dma_chan_data *channel; + + key = k_spin_lock(&dma->lock); + if (req_chan >= dma->plat_data.channels) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_dmic_dma_tr, "Channel %d out of range", + req_chan); + return NULL; + } + channel = &dma->chan[req_chan]; + if (channel->status != COMP_STATE_INIT) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_dmic_dma_tr, "Cannot reuse channel %d", + req_chan); + return NULL; + } + atomic_add(&dma->num_channels_busy, 1); + channel->status = COMP_STATE_READY; + k_spin_unlock(&dma->lock, key); + return channel; +} + +static void acp_dmic_dma_channel_put(struct dma_chan_data *channel) +{ + k_spinlock_key_t key; + + notifier_unregister_all(NULL, channel); + key = k_spin_lock(&channel->dma->lock); + channel->status = COMP_STATE_INIT; + atomic_sub(&channel->dma->num_channels_busy, 1); + k_spin_unlock(&channel->dma->lock, key); +} + +static int acp_dmic_dma_start(struct dma_chan_data *channel) +{ + acp_wov_pdm_no_of_channels_t pdm_channels; + acp_wov_pdm_decimation_factor_t deci_fctr; + acp_wov_misc_ctrl_t wov_misc_ctrl; + acp_wov_pdm_dma_enable_t pdm_dma_enable; + struct timer *timer = timer_get(); + uint64_t deadline = platform_timer_get(timer) + + clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1) * 500 / 1000; + channel->status = COMP_STATE_ACTIVE; + if (channel->direction == DMA_DIR_DEV_TO_MEM) { + /* Channel for DMIC */ + pdm_channels.bits.pdm_no_of_channels = 0; + io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_NO_OF_CHANNELS, + pdm_channels.u32all); + /* Decimation Factor */ + deci_fctr.u32all = 2; + io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_DECIMATION_FACTOR, + deci_fctr.u32all); + /* PDM Control */ + wov_misc_ctrl = (acp_wov_misc_ctrl_t) + io_reg_read(PU_REGISTER_BASE + ACP_WOV_MISC_CTRL); + wov_misc_ctrl.u32all |= 0x10; + io_reg_write(PU_REGISTER_BASE + ACP_WOV_MISC_CTRL, + wov_misc_ctrl.u32all); + /* PDM Enable */ + io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_ENABLE, 1); + /* PDM DMA Enable */ + io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE, 1); + /* Check the PDM DMA Enable status bit */ + pdm_dma_enable = (acp_wov_pdm_dma_enable_t) + io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE); + while (!(uint32_t)pdm_dma_enable.bits.pdm_dma_en_status) { + if (deadline < platform_timer_get(timer)) { + /* safe check in case we've got preempted after read */ + if ((uint32_t)pdm_dma_enable.bits.pdm_dma_en_status) + return 0; + tr_err(&acp_dmic_dma_tr, "timed out for dma start"); + return -ETIME; + } + pdm_dma_enable = (acp_wov_pdm_dma_enable_t) + io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE); + } + } + return 0; +} + +static int acp_dmic_dma_release(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + tr_dbg(&acp_dmic_dma_tr, "dmic dma release()"); + return 0; +} + +static int acp_dmic_dma_pause(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + tr_dbg(&acp_dmic_dma_tr, "dmic dma pause()"); + return 0; +} + +static int acp_dmic_dma_stop(struct dma_chan_data *channel) +{ + acp_wov_pdm_dma_enable_t pdm_dma_enable; + struct timer *timer = timer_get(); + uint64_t deadline = platform_timer_get(timer) + + clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1) * 500 / 1000; + switch (channel->status) { + case COMP_STATE_READY: + case COMP_STATE_PREPARE: + return 0; + case COMP_STATE_PAUSED: + case COMP_STATE_ACTIVE: + break; + default: + return -EINVAL; + } + channel->status = COMP_STATE_READY; + /* Disable PDM DMA */ + io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE, 0); + /* Disable PDM */ + pdm_dma_enable = (acp_wov_pdm_dma_enable_t) + io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE); + /* Check PDM DMA Status */ + while ((uint32_t)pdm_dma_enable.bits.pdm_dma_en_status) { + if (deadline < platform_timer_get(timer)) { + /* safe check in case we've got preempted after read */ + if ((uint32_t)pdm_dma_enable.bits.pdm_dma_en_status) + return 0; + tr_err(&acp_dmic_dma_tr, "timed out for dma stop"); + return -ETIME; + } + pdm_dma_enable = (acp_wov_pdm_dma_enable_t) + io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE); + } + /* Disable PDM */ + io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_ENABLE, 0); + /* Clear PDM FIFO */ + io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_FIFO_FLUSH, 1); + return 0; +} + +static int acp_dmic_dma_status(struct dma_chan_data *channel, + struct dma_chan_status *status, + uint8_t direction) +{ + acp_wov_pdm_dma_enable_t pdm_dma_enable; + + pdm_dma_enable = (acp_wov_pdm_dma_enable_t) + io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_DMA_ENABLE); + return (int)(pdm_dma_enable.bits.pdm_dma_en_status); +} + +/* set the DMA channel configuration, source/target address, buffer sizes */ +static int acp_dmic_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config) +{ + uint32_t ring_buff_addr; + acp_wov_rx_ringbufsize_t dmic_ringbuff_size; + acp_wov_rx_intr_watermark_size_t watermark; + + channel->is_scheduling_source = true; + channel->direction = config->direction; + switch (config->direction) { + case DMA_DIR_DEV_TO_MEM: + case DMA_DIR_MEM_TO_DEV: + config->elem_array.elems[0].dest = + (config->elem_array.elems[0].dest & ACP_DRAM_ADDRESS_MASK); + ring_buff_addr = (config->elem_array.elems[0].dest | 0x01000000); + /* Load Ring buffer address */ + io_reg_write(PU_REGISTER_BASE + + ACP_WOV_RX_RINGBUFADDR, ring_buff_addr); + /* Load Ring buffer Size */ + dmic_rngbuff_size = (config->elem_array.elems[0].size * + config->elem_array.count); + dmic_ringbuff_size.bits.rx_ringbufsize = dmic_rngbuff_size; + io_reg_write(PU_REGISTER_BASE + + ACP_WOV_RX_RINGBUFSIZE, dmic_ringbuff_size.u32all); + /* Write the ring buffer size to register */ + watermark.bits.rx_intr_watermark_size = (dmic_rngbuff_size / 2); + io_reg_write(PU_REGISTER_BASE + + ACP_WOV_RX_INTR_WATERMARK_SIZE, watermark.u32all); + break; + default: + tr_err(&acp_dmic_dma_tr, "unsupported config direction"); + return -EINVAL; + } + if (!config->cyclic) { + tr_err(&acp_dmic_dma_tr, "cyclic configurations only supported!"); + return -EINVAL; + } + if (config->scatter) { + tr_err(&acp_dmic_dma_tr, "scatter enabled, not supported for now!"); + return -EINVAL; + } + return 0; +} + +static int acp_dmic_dma_copy(struct dma_chan_data *channel, int bytes, + uint32_t flags) +{ + struct dma_cb_data next = { + .channel = channel, + .elem.size = bytes, + }; + notifier_event(channel, NOTIFIER_ID_DMA_COPY, + NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); + return 0; +} + +static int acp_dmic_dma_probe(struct dma *dma) +{ + int channel; + + if (dma->chan) { + tr_err(&acp_dmic_dma_tr, "Repeated probe"); + return -EEXIST; + } + dma->chan = rzalloc(SOF_MEM_ZONE_SYS_RUNTIME, 0, + SOF_MEM_CAPS_RAM, dma->plat_data.channels * + sizeof(struct dma_chan_data)); + if (!dma->chan) { + tr_err(&acp_dmic_dma_tr, "unable to allocate channel descriptors"); + return -ENOMEM; + } + for (channel = 0; channel < dma->plat_data.channels; channel++) { + dma->chan[channel].dma = dma; + dma->chan[channel].index = channel; + dma->chan[channel].status = COMP_STATE_INIT; + } + atomic_init(&dma->num_channels_busy, 0); + return 0; +} + +static int acp_dmic_dma_remove(struct dma *dma) +{ + if (!dma->chan) { + tr_err(&acp_dmic_dma_tr, "remove called without probe"); + return 0; + } + rfree(dma->chan); + dma->chan = NULL; + return 0; +} + +static int acp_dmic_dma_get_data_size(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free) +{ + if (channel->direction == DMA_DIR_DEV_TO_MEM) { + *avail = dmic_rngbuff_size/2; + *free = dmic_rngbuff_size/2; + } else + tr_err(&acp_dmic_dma_tr, "Channel direction Not defined %d", + channel->direction); + return 0; +} + +static int acp_dmic_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) +{ + switch (type) { + case DMA_ATTR_BUFFER_ALIGNMENT: + case DMA_ATTR_COPY_ALIGNMENT: + *value = ACP_DMA_BUFFER_ALIGN_128; + break; + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + *value = PLATFORM_DCACHE_ALIGN; + break; + case DMA_ATTR_BUFFER_PERIOD_COUNT: + *value = ACP_DAI_DMA_BUFFER_PERIOD_COUNT; + break; + default: + return -ENOENT; /* Attribute not found */ + } + return 0; +} + +static int acp_dmic_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) +{ + uint32_t status; + acp_dsp0_intr_stat_t acp_intr_stat; + acp_dsp0_intr_cntl_t acp_intr_cntl; + + if (channel->status == COMP_STATE_INIT) + return 0; + switch (cmd) { + case DMA_IRQ_STATUS_GET: + acp_intr_stat = (acp_dsp0_intr_stat_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_STAT); + status = acp_intr_stat.bits.wov_dma_stat; + return status; + case DMA_IRQ_CLEAR: + acp_intr_stat = (acp_dsp0_intr_stat_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_STAT); + acp_intr_stat.bits.wov_dma_stat = 1; + status = acp_intr_stat.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_STAT, status); + return 0; + case DMA_IRQ_MASK: + acp_intr_cntl = (acp_dsp0_intr_cntl_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL); + acp_intr_cntl.bits.wov_dma_intr_mask = 0; + status = acp_intr_cntl.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL, status); + return 0; + case DMA_IRQ_UNMASK: + acp_intr_cntl = (acp_dsp0_intr_cntl_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL); + acp_intr_cntl.bits.wov_dma_intr_mask = 1; + status = acp_intr_cntl.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL, status); + return 0; + default: + return -EINVAL; + } +} + +const struct dma_ops acp_dmic_dma_ops = { + .channel_get = acp_dmic_dma_channel_get, + .channel_put = acp_dmic_dma_channel_put, + .start = acp_dmic_dma_start, + .stop = acp_dmic_dma_stop, + .pause = acp_dmic_dma_pause, + .release = acp_dmic_dma_release, + .copy = acp_dmic_dma_copy, + .status = acp_dmic_dma_status, + .set_config = acp_dmic_dma_set_config, + .interrupt = acp_dmic_dma_interrupt, + .probe = acp_dmic_dma_probe, + .remove = acp_dmic_dma_remove, + .get_data_size = acp_dmic_dma_get_data_size, + .get_attribute = acp_dmic_dma_get_attribute, +}; diff --git a/src/drivers/amd/rembrandt/acp_hs_dai.c b/src/drivers/amd/rembrandt/acp_hs_dai.c new file mode 100644 index 000000000000..4823408a70d5 --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_hs_dai.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 8f00c3bb-e835-4767-9a34-b8ec1041e56b */ +DECLARE_SOF_UUID("hsdai", hsdai_uuid, 0x8f00c3bb, 0xe835, 0x4767, + 0x9a, 0x34, 0xb8, 0xec, 0x10, 0x41, 0xe5, 0x6b); +DECLARE_TR_CTX(hsdai_tr, SOF_UUID(hsdai_uuid), LOG_LEVEL_INFO); + +static inline int hsdai_set_config(struct dai *dai, struct ipc_config_dai *common_config, + void *spec_config) +{ + /* set master clk for hs dai */ + io_reg_write(PU_REGISTER_BASE + ACP_I2STDM2_MSTRCLKGEN, 0x40081); + return 0; +} + +static int hsdai_trigger(struct dai *dai, int cmd, int direction) +{ + /* nothing to do on rembrandt for HS dai */ + return 0; +} + +static int hsdai_probe(struct dai *dai) +{ + /* TODO */ + return 0; +} + +static int hsdai_remove(struct dai *dai) +{ + /* TODO */ + return 0; +} + +static int hsdai_get_fifo(struct dai *dai, int direction, int stream_id) +{ + switch (direction) { + case DAI_DIR_PLAYBACK: + case DAI_DIR_CAPTURE: + return dai_fifo(dai, direction); + default: + dai_err(dai, "Invalid direction"); + return -EINVAL; + } +} + +static int hsdai_get_handshake(struct dai *dai, int direction, int stream_id) +{ + return dai->plat_data.fifo[direction].handshake; +} + +static int hsdai_get_hw_params(struct dai *dai, + struct sof_ipc_stream_params *params, + int dir) +{ + /* HS DAI currently supports only these parameters */ + params->rate = ACP_DEFAULT_SAMPLE_RATE; + params->channels = ACP_DEFAULT_NUM_CHANNELS; + params->buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; + params->frame_fmt = SOF_IPC_FRAME_S16_LE; + return 0; +} + +const struct dai_driver acp_hsdai_driver = { + .type = SOF_DAI_AMD_HS, + .uid = SOF_UUID(hsdai_uuid), + .tctx = &hsdai_tr, + .dma_dev = DMA_DEV_SP, + .dma_caps = DMA_CAP_SP, + .ops = { + .trigger = hsdai_trigger, + .set_config = hsdai_set_config, + .probe = hsdai_probe, + .remove = hsdai_remove, + .get_fifo = hsdai_get_fifo, + .get_handshake = hsdai_get_handshake, + .get_hw_params = hsdai_get_hw_params, + }, +}; diff --git a/src/drivers/amd/rembrandt/acp_hs_dma.c b/src/drivers/amd/rembrandt/acp_hs_dma.c new file mode 100644 index 000000000000..142da12aa417 --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_hs_dma.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*b414df09-9e31-4c59-8657-7afc8deba70c*/ +DECLARE_SOF_UUID("acp-hs", acp_hs_uuid, 0xb414df09, 0x9e31, 0x4c59, + 0x86, 0x57, 0x7a, 0xfc, 0x8d, 0xeb, 0xa7, 0x0c); +DECLARE_TR_CTX(acp_hs_tr, SOF_UUID(acp_hs_uuid), LOG_LEVEL_INFO); + +#define HS_FIFO_SIZE 512 +#define HS_TX_FIFO_ADDR 0x0 +#define HS_RX_FIFO_ADDR (HS_TX_FIFO_ADDR+HS_FIFO_SIZE) + +static uint64_t prev_tx_pos; +static uint64_t prev_rx_pos; +static uint32_t hs_buff_size; +/* allocate next free DMA channel */ +static struct dma_chan_data *acp_dai_hs_dma_channel_get(struct dma *dma, + unsigned int req_chan) +{ + k_spinlock_key_t key; + struct dma_chan_data *channel; + + key = k_spin_lock(&dma->lock); + if (req_chan >= dma->plat_data.channels) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_hs_tr, "Channel %d not in range", req_chan); + return NULL; + } + channel = &dma->chan[req_chan]; + if (channel->status != COMP_STATE_INIT) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_hs_tr, "channel already in use %d", req_chan); + return NULL; + } + atomic_add(&dma->num_channels_busy, 1); + channel->status = COMP_STATE_READY; + k_spin_unlock(&dma->lock, key); + return channel; +} + +/* channel must not be running when this is called */ +static void acp_dai_hs_dma_channel_put(struct dma_chan_data *channel) +{ + k_spinlock_key_t key; + + notifier_unregister_all(NULL, channel); + key = k_spin_lock(&channel->dma->lock); + channel->status = COMP_STATE_INIT; + atomic_sub(&channel->dma->num_channels_busy, 1); + k_spin_unlock(&channel->dma->lock, key); + +} + +static int acp_dai_hs_dma_start(struct dma_chan_data *channel) +{ + acp_hstdm_ier_t hs_ier; + acp_hstdm_iter_t hs_iter; + acp_hstdm_irer_t hs_irer; + + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + channel->status = COMP_STATE_ACTIVE; + prev_tx_pos = 0; + hs_ier = (acp_hstdm_ier_t)io_reg_read(PU_REGISTER_BASE + ACP_HSTDM_IER); + hs_ier.bits.hstdm_ien = 1; + io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_IER), hs_ier.u32all); + hs_iter.bits.hstdm_txen = 1; + hs_iter.bits.hstdm_tx_protocol_mode = 0; + hs_iter.bits.hstdm_tx_data_path_mode = 1; + hs_iter.bits.hstdm_tx_samp_len = 2; + io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_ITER), hs_iter.u32all); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + channel->status = COMP_STATE_ACTIVE; + prev_rx_pos = 0; + hs_ier = (acp_hstdm_ier_t)io_reg_read(PU_REGISTER_BASE + ACP_HSTDM_IER); + hs_ier.bits.hstdm_ien = 1; + io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_IER), hs_ier.u32all); + hs_irer.bits.hstdm_rx_en = 1; + hs_irer.bits.hstdm_rx_protocol_mode = 0; + hs_irer.bits.hstdm_rx_data_path_mode = 1; + hs_irer.bits.hstdm_rx_samplen = 2; + io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_IRER), hs_irer.u32all); + } else { + tr_err(&acp_hs_tr, "Start direction not defined %d", channel->direction); + return -EINVAL; + } + + return 0; +} + + +static int acp_dai_hs_dma_release(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int acp_dai_hs_dma_pause(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int acp_dai_hs_dma_stop(struct dma_chan_data *channel) +{ + acp_hstdm_irer_t hs_irer; + acp_hstdm_iter_t hs_iter; + + switch (channel->status) { + case COMP_STATE_READY: + case COMP_STATE_PREPARE: + return 0; + case COMP_STATE_PAUSED: + case COMP_STATE_ACTIVE: + break; + default: + return -EINVAL; + } + channel->status = COMP_STATE_READY; + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + hs_iter = (acp_hstdm_iter_t)io_reg_read(PU_REGISTER_BASE + ACP_HSTDM_ITER); + hs_iter.bits.hstdm_txen = 0; + io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_ITER), hs_iter.u32all); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + channel->status = COMP_STATE_READY; + hs_irer = (acp_hstdm_irer_t)io_reg_read(PU_REGISTER_BASE + ACP_HSTDM_IRER); + hs_irer.bits.hstdm_rx_en = 0; + io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_IRER), hs_irer.u32all); + } else { + tr_err(&acp_hs_tr, "Stop direction not defined %d", channel->direction); + return -EINVAL; + } + return 0; +} + +static int acp_dai_hs_dma_status(struct dma_chan_data *channel, + struct dma_chan_status *status, + uint8_t direction) +{ + /* nothing to do on rembrandt */ + return 0; +} + +/* set the DMA channel configuration, source/target address, buffer sizes */ +static int acp_dai_hs_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config) +{ + uint32_t hs_buff_addr; + uint32_t hs_fifo_addr; + + if (!config->cyclic) { + tr_err(&acp_hs_tr, "cyclic configurations only supported!"); + return -EINVAL; + } + if (config->scatter) { + tr_err(&acp_hs_tr, "scatter enabled, that is not supported for now!"); + return -EINVAL; + } + + channel->is_scheduling_source = true; + channel->direction = config->direction; + hs_buff_size = config->elem_array.elems[0].size * config->elem_array.count; + if (config->direction == DMA_DIR_MEM_TO_DEV) { + + /* HS Transmit FIFO Address and FIFO Size*/ + hs_fifo_addr = HS_TX_FIFO_ADDR; + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_TX_FIFOADDR), hs_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_TX_FIFOSIZE), (uint32_t)(HS_FIFO_SIZE)); + + /* Transmit RINGBUFFER Address and size*/ + config->elem_array.elems[0].src = (config->elem_array.elems[0].src & ACP_DRAM_ADDRESS_MASK); + hs_buff_addr = (config->elem_array.elems[0].src | 0x01000000); + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_TX_RINGBUFADDR), hs_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_TX_RINGBUFSIZE), hs_buff_size); + + /* Transmit DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_TX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE_128)); + + /* Watermark size for HS transmit FIFO - Half of HS buffer size */ + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_TX_INTR_WATERMARK_SIZE), + (hs_buff_size/2)); + + } else if (config->direction == DMA_DIR_DEV_TO_MEM) { + + /* HS Receive FIFO Address and FIFO Size*/ + hs_fifo_addr = HS_RX_FIFO_ADDR; + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_RX_FIFOADDR), hs_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_RX_FIFOSIZE), + (uint32_t)(HS_FIFO_SIZE)); + + /* Receive RINGBUFFER Address and size*/ + config->elem_array.elems[0].dest = + (config->elem_array.elems[0].dest & ACP_DRAM_ADDRESS_MASK); + hs_buff_addr = (config->elem_array.elems[0].dest | 0x01000000); + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_RX_RINGBUFADDR), hs_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_RX_RINGBUFSIZE), hs_buff_size); + + /* Receive DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_RX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE_128)); + + /* Watermark size for receive fifo - Half of HS buffer size*/ + io_reg_write((PU_REGISTER_BASE + ACP_P1_HS_RX_INTR_WATERMARK_SIZE), + (hs_buff_size/2)); + + } else { + tr_err(&acp_hs_tr, "Config channel direction undefined %d", channel->direction); + return -EINVAL; + } + + return 0; +} + +static int acp_dai_hs_dma_copy(struct dma_chan_data *channel, int bytes, + uint32_t flags) +{ + struct dma_cb_data next = { + .channel = channel, + .elem.size = bytes, + }; + notifier_event(channel, NOTIFIER_ID_DMA_COPY, + NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); + return 0; +} + +static int acp_dai_hs_dma_probe(struct dma *dma) +{ + int channel; + + if (dma->chan) { + tr_err(&acp_hs_tr, "Repeated probe"); + return -EEXIST; + } + dma->chan = rzalloc(SOF_MEM_ZONE_SYS_RUNTIME, 0, + SOF_MEM_CAPS_RAM, dma->plat_data.channels * + sizeof(struct dma_chan_data)); + if (!dma->chan) { + tr_err(&acp_hs_tr, "Probe failure,unable to allocate channel descriptors"); + return -ENOMEM; + } + for (channel = 0; channel < dma->plat_data.channels; channel++) { + dma->chan[channel].dma = dma; + dma->chan[channel].index = channel; + dma->chan[channel].status = COMP_STATE_INIT; + } + atomic_init(&dma->num_channels_busy, 0); + return 0; +} + +static int acp_dai_hs_dma_remove(struct dma *dma) +{ + if (!dma->chan) { + tr_err(&acp_hs_tr, "remove called without probe,it's a no-op"); + return 0; + } + + rfree(dma->chan); + dma->chan = NULL; + return 0; +} + +static int acp_dai_hs_dma_get_data_size(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free) +{ + uint64_t tx_low, curr_tx_pos, tx_high; + uint64_t rx_low, curr_rx_pos, rx_high; + + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + tx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_HS_TX_LINEARPOSITIONCNTR_LOW); + tx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_HS_TX_LINEARPOSITIONCNTR_HIGH); + curr_tx_pos = (uint64_t)((tx_high<<32) | tx_low); + *free = (curr_tx_pos - prev_tx_pos) > hs_buff_size ? (curr_tx_pos - prev_tx_pos) % hs_buff_size : curr_tx_pos - prev_tx_pos; + prev_tx_pos = curr_tx_pos; + *avail = hs_buff_size - *free; + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + rx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_HS_RX_LINEARPOSITIONCNTR_LOW); + rx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_HS_RX_LINEARPOSITIONCNTR_HIGH); + curr_rx_pos = (uint64_t)((rx_high<<32) | rx_low); + *free = (curr_rx_pos - prev_rx_pos) > hs_buff_size ? (curr_rx_pos - prev_rx_pos) % hs_buff_size : (curr_rx_pos - prev_rx_pos); + *avail = hs_buff_size - *free; + prev_rx_pos = curr_rx_pos; + } else { + tr_err(&acp_hs_tr, "Channel direction not defined %d", channel->direction); + return -EINVAL; + } + return 0; +} + +static int acp_dai_hs_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) +{ + switch (type) { + case DMA_ATTR_BUFFER_ALIGNMENT: + case DMA_ATTR_COPY_ALIGNMENT: + *value = ACP_DMA_BUFFER_ALIGN_128; + break; + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + *value = PLATFORM_DCACHE_ALIGN; + break; + case DMA_ATTR_BUFFER_PERIOD_COUNT: + *value = ACP_DAI_DMA_BUFFER_PERIOD_COUNT; + break; + default: + return -ENOENT; + } + return 0; +} + +static int acp_dai_hs_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) +{ + uint32_t status; + acp_dsp0_intr_stat1_t acp_intr_stat1; + acp_dsp0_intr_cntl1_t acp_intr_cntl1; + + if (channel->status == COMP_STATE_INIT) + return 0; + switch (cmd) { + case DMA_IRQ_STATUS_GET: + acp_intr_stat1 = (acp_dsp0_intr_stat1_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_STAT1); + status = acp_intr_stat1.bits.audio_buffer_int_stat; + return (status & (1<index)); + case DMA_IRQ_CLEAR: + acp_intr_stat1.u32all = 0; + acp_intr_stat1.bits.audio_buffer_int_stat = + (1 << channel->index); + status = acp_intr_stat1.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_STAT1, status); + return 0; + case DMA_IRQ_MASK: + acp_intr_cntl1 = (acp_dsp0_intr_cntl1_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL1); + acp_intr_cntl1.bits.audio_buffer_int_mask &= (~(1 << channel->index)); + status = acp_intr_cntl1.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL1, status); + return 0; + case DMA_IRQ_UNMASK: + acp_intr_cntl1 = (acp_dsp0_intr_cntl1_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL1); + acp_intr_cntl1.bits.audio_buffer_int_mask |= (1 << channel->index); + status = acp_intr_cntl1.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL1, status); + return 0; + default: + return -EINVAL; + } +} + +const struct dma_ops acp_dai_hs_dma_ops = { + .channel_get = acp_dai_hs_dma_channel_get, + .channel_put = acp_dai_hs_dma_channel_put, + .start = acp_dai_hs_dma_start, + .stop = acp_dai_hs_dma_stop, + .pause = acp_dai_hs_dma_pause, + .release = acp_dai_hs_dma_release, + .copy = acp_dai_hs_dma_copy, + .status = acp_dai_hs_dma_status, + .set_config = acp_dai_hs_dma_set_config, + .interrupt = acp_dai_hs_dma_interrupt, + .probe = acp_dai_hs_dma_probe, + .remove = acp_dai_hs_dma_remove, + .get_data_size = acp_dai_hs_dma_get_data_size, + .get_attribute = acp_dai_hs_dma_get_attribute, +}; diff --git a/src/drivers/amd/rembrandt/acp_sp_dai.c b/src/drivers/amd/rembrandt/acp_sp_dai.c new file mode 100644 index 000000000000..775397547eae --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_sp_dai.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 4abd71ba-8619-458a-b33f-160fc0cf809b */ +DECLARE_SOF_UUID("spdai", spdai_uuid, 0x4abd71ba, 0x8619, 0x458a, + 0xb3, 0x3f, 0x16, 0x0f, 0xc0, 0xcf, 0x80, 0x9b); +DECLARE_TR_CTX(spdai_tr, SOF_UUID(spdai_uuid), LOG_LEVEL_INFO); + +static inline int spdai_set_config(struct dai *dai, struct ipc_config_dai *common_config, + void *spec_config) +{ + /* nothing to do on rembrandt for SP dai */ + return 0; +} + +static int spdai_trigger(struct dai *dai, int cmd, int direction) +{ + /* nothing to do on rembrandt for SP dai */ + return 0; +} + +static int spdai_probe(struct dai *dai) +{ + /* TODO */ + return 0; +} + +static int spdai_remove(struct dai *dai) +{ + /* TODO */ + return 0; +} + +static int spdai_get_fifo(struct dai *dai, int direction, int stream_id) +{ + switch (direction) { + case DAI_DIR_PLAYBACK: + case DAI_DIR_CAPTURE: + return dai_fifo(dai, direction); + default: + dai_err(dai, "Invalid direction"); + return -EINVAL; + } +} + +static int spdai_get_handshake(struct dai *dai, int direction, int stream_id) +{ + return dai->plat_data.fifo[direction].handshake; +} + +static int spdai_get_hw_params(struct dai *dai, + struct sof_ipc_stream_params *params, + int dir) +{ + /* SP DAI currently supports only these parameters */ + params->rate = ACP_DEFAULT_SAMPLE_RATE; + params->channels = ACP_DEFAULT_NUM_CHANNELS; + params->buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; + params->frame_fmt = SOF_IPC_FRAME_S16_LE; + return 0; +} + +const struct dai_driver acp_spdai_driver = { + .type = SOF_DAI_AMD_SP, + .uid = SOF_UUID(spdai_uuid), + .tctx = &spdai_tr, + .dma_dev = DMA_DEV_SP, + .dma_caps = DMA_CAP_SP, + .ops = { + .trigger = spdai_trigger, + .set_config = spdai_set_config, + .probe = spdai_probe, + .remove = spdai_remove, + .get_fifo = spdai_get_fifo, + .get_handshake = spdai_get_handshake, + .get_hw_params = spdai_get_hw_params, + }, +}; diff --git a/src/drivers/amd/rembrandt/acp_sp_dma.c b/src/drivers/amd/rembrandt/acp_sp_dma.c new file mode 100644 index 000000000000..2868ead733f0 --- /dev/null +++ b/src/drivers/amd/rembrandt/acp_sp_dma.c @@ -0,0 +1,396 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*3ac07334-41ce-4447-a2c5-dff0d1fa1392*/ +DECLARE_SOF_UUID("acp-sp", acp_sp_uuid, 0x3ac07334, 0x41ce, 0x4447, + 0xa2, 0xc5, 0xdf, 0xf0, 0xd1, 0xfa, 0x13, 0x92); +DECLARE_TR_CTX(acp_sp_tr, SOF_UUID(acp_sp_uuid), LOG_LEVEL_INFO); + +#define SP_FIFO_SIZE 512 +#define SP_TX_FIFO_ADDR (SP_FIFO_SIZE * 2) +#define SP_RX_FIFO_ADDR (SP_TX_FIFO_ADDR+SP_FIFO_SIZE) + +static uint64_t prev_tx_pos; +static uint64_t prev_rx_pos; +static uint32_t sp_buff_size; + +/* allocate next free DMA channel */ +static struct dma_chan_data *acp_dai_sp_dma_channel_get(struct dma *dma, + unsigned int req_chan) +{ + k_spinlock_key_t key; + struct dma_chan_data *channel; + + key = k_spin_lock(&dma->lock); + if (req_chan >= dma->plat_data.channels) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_sp_tr, "Channel %d not in range", req_chan); + return NULL; + } + channel = &dma->chan[req_chan]; + if (channel->status != COMP_STATE_INIT) { + k_spin_unlock(&dma->lock, key); + tr_err(&acp_sp_tr, "channel already in use %d", req_chan); + return NULL; + } + atomic_add(&dma->num_channels_busy, 1); + channel->status = COMP_STATE_READY; + k_spin_unlock(&dma->lock, key); + return channel; +} + +/* channel must not be running when this is called */ +static void acp_dai_sp_dma_channel_put(struct dma_chan_data *channel) +{ + k_spinlock_key_t key; + + notifier_unregister_all(NULL, channel); + key = k_spin_lock(&channel->dma->lock); + channel->status = COMP_STATE_INIT; + atomic_sub(&channel->dma->num_channels_busy, 1); + k_spin_unlock(&channel->dma->lock, key); + +} + +static int acp_dai_sp_dma_start(struct dma_chan_data *channel) +{ + acp_i2stdm_ier_t sp_ier; + acp_i2stdm_iter_t sp_iter; + acp_i2stdm_irer_t sp_irer; + + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + channel->status = COMP_STATE_ACTIVE; + prev_tx_pos = 0; + sp_ier = (acp_i2stdm_ier_t)io_reg_read(PU_REGISTER_BASE + ACP_I2STDM_IER); + sp_ier.bits.i2stdm_ien = 1; + io_reg_write((PU_REGISTER_BASE + ACP_I2STDM_IER), sp_ier.u32all); + sp_iter.bits.i2stdm_txen = 1; + sp_iter.bits.i2stdm_tx_protocol_mode = 0; + sp_iter.bits.i2stdm_tx_data_path_mode = 1; + sp_iter.bits.i2stdm_tx_samp_len = 2; + io_reg_write((PU_REGISTER_BASE + ACP_I2STDM_ITER), sp_iter.u32all); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + channel->status = COMP_STATE_ACTIVE; + prev_rx_pos = 0; + sp_ier = (acp_i2stdm_ier_t)io_reg_read(PU_REGISTER_BASE + ACP_I2STDM_IER); + sp_ier.bits.i2stdm_ien = 1; + io_reg_write((PU_REGISTER_BASE + ACP_I2STDM_IER), sp_ier.u32all); + sp_irer.bits.i2stdm_rx_en = 1; + sp_irer.bits.i2stdm_rx_protocol_mode = 0; + sp_irer.bits.i2stdm_rx_data_path_mode = 1; + sp_irer.bits.i2stdm_rx_samplen = 2; + io_reg_write((PU_REGISTER_BASE + ACP_I2STDM_IRER), sp_irer.u32all); + } else { + tr_err(&acp_sp_tr, "Start direction not defined %d", channel->direction); + return -EINVAL; + } + + return 0; +} + + +static int acp_dai_sp_dma_release(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int acp_dai_sp_dma_pause(struct dma_chan_data *channel) +{ + /* nothing to do on rembrandt */ + return 0; +} + +static int acp_dai_sp_dma_stop(struct dma_chan_data *channel) +{ + acp_i2stdm_irer_t sp_irer; + acp_i2stdm_iter_t sp_iter; + + switch (channel->status) { + case COMP_STATE_READY: + case COMP_STATE_PREPARE: + return 0; + case COMP_STATE_PAUSED: + case COMP_STATE_ACTIVE: + break; + default: + return -EINVAL; + } + channel->status = COMP_STATE_READY; + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + sp_iter = (acp_i2stdm_iter_t)io_reg_read(PU_REGISTER_BASE + ACP_I2STDM_ITER); + sp_iter.bits.i2stdm_txen = 0; + io_reg_write((PU_REGISTER_BASE + ACP_I2STDM_ITER), sp_iter.u32all); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + sp_irer = (acp_i2stdm_irer_t)io_reg_read(PU_REGISTER_BASE + ACP_I2STDM_IRER); + sp_irer.bits.i2stdm_rx_en = 0; + io_reg_write((PU_REGISTER_BASE + ACP_I2STDM_IRER), sp_irer.u32all); + } else { + tr_err(&acp_sp_tr, "Stop direction not defined %d", channel->direction); + return -EINVAL; + } + return 0; +} + +static int acp_dai_sp_dma_status(struct dma_chan_data *channel, + struct dma_chan_status *status, + uint8_t direction) +{ + /* nothing to do on rembrandt */ + return 0; +} + +/* set the DMA channel configuration, source/target address, buffer sizes */ +static int acp_dai_sp_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config) +{ + uint32_t sp_buff_addr; + uint32_t sp_fifo_addr; + + if (!config->cyclic) { + tr_err(&acp_sp_tr, "cyclic configurations only supported!"); + return -EINVAL; + } + if (config->scatter) { + tr_err(&acp_sp_tr, "scatter enabled, that is not supported for now!"); + return -EINVAL; + } + + channel->is_scheduling_source = true; + channel->direction = config->direction; + sp_buff_size = config->elem_array.elems[0].size * config->elem_array.count; + + if (config->direction == DMA_DIR_MEM_TO_DEV) { + + /* SP Transmit FIFO Address and FIFO Size*/ + sp_fifo_addr = SP_TX_FIFO_ADDR; + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_TX_FIFOADDR), sp_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_TX_FIFOSIZE), (uint32_t)(SP_FIFO_SIZE)); + + /* Transmit RINGBUFFER Address and size*/ + config->elem_array.elems[0].src = (config->elem_array.elems[0].src & ACP_DRAM_ADDRESS_MASK); + sp_buff_addr = (config->elem_array.elems[0].src | 0x01000000); + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_TX_RINGBUFADDR), sp_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_TX_RINGBUFSIZE), sp_buff_size); + + /* Transmit DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_TX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE_128)); + + /* Watermark size for SP transmit FIFO - Half of SP buffer size */ + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_TX_INTR_WATERMARK_SIZE), (sp_buff_size/2)); + + } else if (config->direction == DMA_DIR_DEV_TO_MEM) { + + /* SP Receive FIFO Address and FIFO Size*/ + sp_fifo_addr = SP_RX_FIFO_ADDR; + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_RX_FIFOADDR), sp_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_RX_FIFOSIZE), + (uint32_t)(SP_FIFO_SIZE)); + + /* Receive RINGBUFFER Address and size*/ + config->elem_array.elems[0].dest = (config->elem_array.elems[0].dest & ACP_DRAM_ADDRESS_MASK); + sp_buff_addr = (config->elem_array.elems[0].dest | 0x01000000); + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_RX_RINGBUFADDR), sp_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_RX_RINGBUFSIZE), sp_buff_size); + + /* Receive DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_RX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE_128)); + + /* Watermark size for SP receive fifo - Half of SP buffer size*/ + io_reg_write((PU_REGISTER_BASE + ACP_P1_I2S_RX_INTR_WATERMARK_SIZE), (sp_buff_size/2)); + + } else { + tr_err(&acp_sp_tr, "DMA Config channel direction undefined %d", channel->direction); + return -EINVAL; + } + + return 0; +} + +static int acp_dai_sp_dma_copy(struct dma_chan_data *channel, int bytes, + uint32_t flags) +{ + struct dma_cb_data next = { + .channel = channel, + .elem.size = bytes, + }; + notifier_event(channel, NOTIFIER_ID_DMA_COPY, + NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); + return 0; +} + +static int acp_dai_sp_dma_probe(struct dma *dma) +{ + int channel; + + if (dma->chan) { + tr_err(&acp_sp_tr, "Repeated probe"); + return -EEXIST; + } + dma->chan = rzalloc(SOF_MEM_ZONE_SYS_RUNTIME, 0, + SOF_MEM_CAPS_RAM, dma->plat_data.channels * + sizeof(struct dma_chan_data)); + if (!dma->chan) { + tr_err(&acp_sp_tr, "Probe failure,unable to allocate channel descriptors"); + return -ENOMEM; + } + for (channel = 0; channel < dma->plat_data.channels; channel++) { + dma->chan[channel].dma = dma; + dma->chan[channel].index = channel; + dma->chan[channel].status = COMP_STATE_INIT; + } + atomic_init(&dma->num_channels_busy, 0); + return 0; +} + +static int acp_dai_sp_dma_remove(struct dma *dma) +{ + if (!dma->chan) { + tr_err(&acp_sp_tr, "remove called without probe,it's a no-op"); + return 0; + } + + rfree(dma->chan); + dma->chan = NULL; + return 0; +} + +static int acp_dai_sp_dma_get_data_size(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free) +{ + uint64_t tx_low, curr_tx_pos, tx_high; + uint64_t rx_low, curr_rx_pos, rx_high; + + if (channel->direction == DMA_DIR_MEM_TO_DEV) { + tx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_I2S_TX_LINEARPOSITIONCNTR_LOW); + tx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_I2S_TX_LINEARPOSITIONCNTR_HIGH); + curr_tx_pos = (uint64_t)((tx_high<<32) | tx_low); + *free = (curr_tx_pos - prev_tx_pos) > sp_buff_size ? (curr_tx_pos - prev_tx_pos) % sp_buff_size : curr_tx_pos - prev_tx_pos; + *avail = sp_buff_size - *free; + prev_tx_pos = curr_tx_pos; + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + rx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_I2S_RX_LINEARPOSITIONCNTR_LOW); + rx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_P1_I2S_RX_LINEARPOSITIONCNTR_HIGH); + curr_rx_pos = (uint64_t)((rx_high<<32) | rx_low); + *free = (curr_rx_pos - prev_rx_pos) > sp_buff_size ? (curr_rx_pos - prev_rx_pos) % sp_buff_size : (curr_rx_pos - prev_rx_pos); + *avail = sp_buff_size - *free; + prev_rx_pos = curr_rx_pos; + } else { + tr_err(&acp_sp_tr, "Channel direction not defined %d", channel->direction); + return -EINVAL; + } + return 0; +} + +static int acp_dai_sp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) +{ + switch (type) { + case DMA_ATTR_BUFFER_ALIGNMENT: + case DMA_ATTR_COPY_ALIGNMENT: + *value = ACP_DMA_BUFFER_ALIGN_128; + break; + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + *value = PLATFORM_DCACHE_ALIGN; + break; + case DMA_ATTR_BUFFER_PERIOD_COUNT: + *value = ACP_DAI_DMA_BUFFER_PERIOD_COUNT; + break; + default: + return -ENOENT; + } + return 0; +} + +static int acp_dai_sp_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) +{ + uint32_t status; + acp_dsp0_intr_stat_t acp_intr_stat; + acp_dsp0_intr_cntl_t acp_intr_cntl; + + if (channel->status == COMP_STATE_INIT) + return 0; + switch (cmd) { + case DMA_IRQ_STATUS_GET: + acp_intr_stat = (acp_dsp0_intr_stat_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_STAT1); + status = acp_intr_stat.bits.audio_buffer_int_stat; + return (status & (1<index)); + case DMA_IRQ_CLEAR: + acp_intr_stat.u32all = 0; + acp_intr_stat.bits.audio_buffer_int_stat = + (1 << channel->index); + status = acp_intr_stat.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_STAT1, status); + return 0; + case DMA_IRQ_MASK: + acp_intr_cntl = (acp_dsp0_intr_cntl_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL1); + acp_intr_cntl.bits.audio_buffer_int_mask &= (~(1 << channel->index)); + status = acp_intr_cntl.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL1, status); + return 0; + case DMA_IRQ_UNMASK: + acp_intr_cntl = (acp_dsp0_intr_cntl_t) + dma_reg_read(channel->dma, ACP_DSP0_INTR_CNTL1); + acp_intr_cntl.bits.audio_buffer_int_mask |= (1 << channel->index); + status = acp_intr_cntl.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL1, status); + return 0; + default: + return -EINVAL; + } +} + +const struct dma_ops acp_dai_sp_dma_ops = { + .channel_get = acp_dai_sp_dma_channel_get, + .channel_put = acp_dai_sp_dma_channel_put, + .start = acp_dai_sp_dma_start, + .stop = acp_dai_sp_dma_stop, + .pause = acp_dai_sp_dma_pause, + .release = acp_dai_sp_dma_release, + .copy = acp_dai_sp_dma_copy, + .status = acp_dai_sp_dma_status, + .set_config = acp_dai_sp_dma_set_config, + .interrupt = acp_dai_sp_dma_interrupt, + .probe = acp_dai_sp_dma_probe, + .remove = acp_dai_sp_dma_remove, + .get_data_size = acp_dai_sp_dma_get_data_size, + .get_attribute = acp_dai_sp_dma_get_attribute, +}; diff --git a/src/drivers/amd/rembrandt/interrupt.c b/src/drivers/amd/rembrandt/interrupt.c new file mode 100644 index 000000000000..90762782427a --- /dev/null +++ b/src/drivers/amd/rembrandt/interrupt.c @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xtos-internal.h" +#include +#include +#include +#include +#include + +/* 6533d0eb-b785-4709-84f5-347c81720189*/ +DECLARE_SOF_UUID("irq-acp", irq_acp_uuid, 0x6533d0eb, 0xb785, 0x4709, + 0x84, 0xf5, 0x34, 0x7c, 0x81, 0x72, 0x01, 0x89); + +DECLARE_TR_CTX(acp_irq_tr, SOF_UUID(irq_acp_uuid), LOG_LEVEL_INFO); + +#define IRQ_INT_MASK(irq) (1 << (irq)) +#define RESERVED_IRQS_NUM 0 +#define IRQS_NUM 9 +#define IRQS_PER_LINE 1 + +static inline uint32_t acp_irq_status_read(uint32_t reg) +{ + return io_reg_read(PU_REGISTER_BASE + reg); +} + +static inline void acp_irq_update_bits(uint32_t reg, uint32_t mask, + uint32_t value) +{ + io_reg_update_bits(PU_REGISTER_BASE + reg, mask, value); +} + +static uint32_t acp_irq_get_status(uint32_t index) +{ + acp_dsp0_intr_stat1_t acp_intr_stat1; + /* 0-7 interrupts are used */ + if (index > 7) + return 0; + if (index == IRQ_NUM_EXT_LEVEL5) { + acp_intr_stat1 = (acp_dsp0_intr_stat1_t) + io_reg_read(PU_REGISTER_BASE + ACP_DSP0_INTR_STAT1); + if (acp_intr_stat1.bits.audio_buffer_int_stat) + return acp_irq_status_read(ACP_DSP0_INTR_STAT1); + else + return acp_irq_status_read(ACP_DSP0_INTR_STAT); + } else + return acp_irq_status_read(ACP_DSP0_INTR_STAT); +} + +static void acp_irq_mask_int(uint32_t irq) +{ + uint32_t mask; + + if (irq < RESERVED_IRQS_NUM || irq >= IRQS_NUM) { + tr_err(&acp_irq_tr, "Invalid interrupt"); + return; + } + mask = IRQ_INT_MASK(irq); + if (irq == IRQ_NUM_EXT_LEVEL5) + acp_irq_update_bits(ACP_DSP0_INTR_CNTL1, mask, 0); + else + acp_irq_update_bits(ACP_DSP0_INTR_CNTL, mask, 0); +} + +static void acp_irq_unmask_int(uint32_t irq) +{ + uint32_t mask; + + if (irq < RESERVED_IRQS_NUM || irq >= IRQS_NUM) { + tr_err(&acp_irq_tr, "Invalid interrupt"); + return; + } + mask = IRQ_INT_MASK(irq); + if (irq == IRQ_NUM_EXT_LEVEL5) + acp_irq_update_bits(ACP_DSP0_INTR_CNTL1, mask, mask); + else + acp_irq_update_bits(ACP_DSP0_INTR_CNTL, mask, mask); +} + +static uint64_t acp_get_irq_interrupts(uint32_t index) +{ + return acp_irq_get_status(index); +} + +static int get_first_irq(uint64_t ints) +{ + return ffs(ints) - 1; +} + +static inline void acp_handle_irq(struct irq_cascade_desc *cascade, + uint32_t line_index, uint64_t status) +{ + int core = cpu_get_id(); + struct list_item *clist; + struct irq_desc *child = NULL; + int bit; + bool handled; + k_spinlock_key_t key; + + while (status) { + bit = get_first_irq(status); + handled = false; + status &= ~(1ull << bit); + + key = k_spin_lock(&cascade->lock); + + list_for_item(clist, &cascade->child[bit].list) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child->handler && (child->cpu_mask & 1 << core)) { + child->handler(child->handler_arg); + handled = true; + } + } + + k_spin_unlock(&cascade->lock, key); + + if (!handled) { + tr_err(&acp_irq_tr, "irq_handler(): not handled, bit %d", + bit); + acp_irq_mask_int(line_index * IRQS_PER_LINE + bit); + } + } +} + +static inline void irq_handler(void *data, uint32_t line_index) +{ + struct irq_desc *parent = data; + struct irq_cascade_desc *cascade = + container_of(parent, struct irq_cascade_desc, desc); + uint64_t status; + + status = acp_get_irq_interrupts(line_index); + if (status) + /* Handle current interrupts */ + acp_handle_irq(cascade, line_index, status); + else + tr_err(&acp_irq_tr, "invalid interrupt status"); +} + +#define DEFINE_IRQ_HANDLER(n) \ + static void irqhandler_##n(void *arg) \ + { \ + irq_handler(arg, n); \ + } + +DEFINE_IRQ_HANDLER(0) +DEFINE_IRQ_HANDLER(1) +DEFINE_IRQ_HANDLER(3) +DEFINE_IRQ_HANDLER(4) +DEFINE_IRQ_HANDLER(5) + +static void acp_irq_mask(struct irq_desc *desc, uint32_t irq, unsigned int core) +{ + acp_irq_mask_int(irq); +} + +static void acp_irq_unmask(struct irq_desc *desc, uint32_t irq, unsigned int core) +{ + acp_irq_unmask_int(irq); +} + +static const struct irq_cascade_ops irq_ops = { + .mask = acp_irq_mask, + .unmask = acp_irq_unmask, +}; + +static const struct irq_cascade_tmpl dsp_irq[] = { + { + .irq = IRQ_NUM_TIMER0, + .handler = irqhandler_0, + .ops = &irq_ops, + .global_mask = false, + }, { + .irq = IRQ_NUM_SOFTWARE0, + .handler = irqhandler_1, + .ops = &irq_ops, + .global_mask = false, + }, + { + .irq = IRQ_NUM_EXT_LEVEL3, + .handler = irqhandler_3, + .ops = &irq_ops, + .global_mask = false, + }, + { + .irq = IRQ_NUM_EXT_LEVEL4, + .handler = irqhandler_4, + .ops = &irq_ops, + .global_mask = false, + }, + { + .irq = IRQ_NUM_EXT_LEVEL5, + .handler = irqhandler_5, + .ops = &irq_ops, + .global_mask = false, + }, +}; + +void platform_interrupt_init(void) +{ + int i; + + acp_intr_route(); + /* disable all interrupts and their service routines */ + acp_intr_disable(); + for (i = 0; i < ARRAY_SIZE(dsp_irq); i++) + interrupt_cascade_register(dsp_irq + i); + acp_intr_enable(); + acp_dsp_sw_intr_enable(); +} + +void platform_interrupt_set(uint32_t irq) +{ + arch_interrupt_set(irq); +} + +void platform_interrupt_clear(uint32_t irq, uint32_t mask) +{ + switch (irq) { + case IRQ_NUM_TIMER0: + case IRQ_NUM_SOFTWARE0: + case IRQ_NUM_EXT_LEVEL3: + case IRQ_NUM_EXT_LEVEL4: + case IRQ_NUM_EXT_LEVEL5: + arch_interrupt_clear(irq); + break; + default: + break; + } +} + +uint32_t platform_interrupt_get_enabled(void) +{ + /* TODO */ + return 0; +} + +void interrupt_mask(uint32_t irq, unsigned int cpu) +{ + arch_interrupt_clear(irq); +} + +void interrupt_unmask(uint32_t irq, unsigned int cpu) +{ + arch_interrupt_set(irq); +} + + +void acp_intr_route(void) +{ + dsp_interrupt_routing_ctrl_0_t interrupt_rout_cntl_0; + dsp_interrupt_routing_ctrl_1_t interrupt_rout_cntl_1; + /* Routing the particular interrupts to the particular level */ + interrupt_rout_cntl_0 = (dsp_interrupt_routing_ctrl_0_t) io_reg_read( + (PU_REGISTER_BASE + DSP_INTERRUPT_ROUTING_CTRL_0)); + interrupt_rout_cntl_0.bits.dma_intr_level = acp_interrupt_level_5; + interrupt_rout_cntl_0.bits.az_sw_i2s_intr_level = acp_interrupt_level_5; + io_reg_write((PU_REGISTER_BASE + DSP_INTERRUPT_ROUTING_CTRL_0), + interrupt_rout_cntl_0.u32all); + + interrupt_rout_cntl_1 = (dsp_interrupt_routing_ctrl_1_t) io_reg_read( + (PU_REGISTER_BASE + DSP_INTERRUPT_ROUTING_CTRL_1)); + interrupt_rout_cntl_1.bits.host_to_dsp_intr1_level = acp_interrupt_level_3; + interrupt_rout_cntl_1.bits.wov_intr_level = acp_interrupt_level_4; + interrupt_rout_cntl_1.bits.p1_sw_i2s_intr_level = acp_interrupt_level_5; + io_reg_write((PU_REGISTER_BASE + DSP_INTERRUPT_ROUTING_CTRL_1), + interrupt_rout_cntl_1.u32all); +} + +void acp_dsp_sw_intr_enable(void) +{ + acp_dsp_sw_intr_cntl_t sw_intr_ctrl_reg; + + xthal_set_intclear(IRQ_NUM_EXT_LEVEL5); + sw_intr_ctrl_reg = (acp_dsp_sw_intr_cntl_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP_SW_INTR_CNTL)); + sw_intr_ctrl_reg.bits.dsp0_to_host_intr_mask = INTERRUPT_ENABLE; + /* Write the Software Interrupt controller register */ + io_reg_write((PU_REGISTER_BASE + ACP_DSP_SW_INTR_CNTL), sw_intr_ctrl_reg.u32all); + /* Enabling software interuppts */ + platform_interrupt_set(IRQ_NUM_EXT_LEVEL3); +} + +void acp_intr_enable(void) +{ + acp_dsp0_intr_cntl_t interrupt_cntl; + acp_dsp0_intr_stat_t interrupt_sts; + acp_dsp0_intr_cntl1_t interrupt_cntl1; + acp_dsp0_intr_stat1_t interrupt_sts1; + acp_external_intr_enb_t ext_interrupt_enb; + + platform_interrupt_clear(IRQ_NUM_EXT_LEVEL5, 0); + platform_interrupt_clear(IRQ_NUM_TIMER0, 0); + interrupt_sts.u32all = 0; + /* Clear status of all interrupts in ACP_DSP0_INTR_STAT register */ + interrupt_sts.bits.dmaiocstat = 0xFF; + interrupt_sts.bits.audio_buffer_int_stat = 0x3F; + interrupt_sts.bits.wov_dma_stat = INTERRUPT_ENABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_STAT), + interrupt_sts.u32all); + interrupt_sts1.u32all = 0; + interrupt_sts1.bits.audio_buffer_int_stat = 0x3F; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_STAT1), + interrupt_sts1.u32all); + /* Disable the ACP to Host interrupts */ + ext_interrupt_enb.bits.acpextintrenb = INTERRUPT_ENABLE; + io_reg_write((PU_REGISTER_BASE + ACP_EXTERNAL_INTR_ENB), + ext_interrupt_enb.u32all); + interrupt_cntl = (acp_dsp0_intr_cntl_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP0_INTR_CNTL)); + interrupt_cntl.u32all = 0; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL), interrupt_cntl.u32all); + interrupt_cntl.bits.dmaiocmask = 0xFF; + interrupt_cntl.bits.wov_dma_intr_mask = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL), interrupt_cntl.u32all); + interrupt_cntl1 = (acp_dsp0_intr_cntl1_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP0_INTR_CNTL1)); + interrupt_cntl1.u32all = 0; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL1), interrupt_cntl1.u32all); + interrupt_cntl1.bits.audio_buffer_int_mask = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL1), interrupt_cntl1.u32all); + platform_interrupt_set(IRQ_NUM_EXT_LEVEL5); + platform_interrupt_set(IRQ_NUM_EXT_LEVEL4); +} + +void acp_intr_disable(void) +{ + acp_dsp0_intr_stat_t interrupt_status; + acp_dsp0_intr_stat1_t interrupt_status1; + acp_external_intr_enb_t ext_interrupt_enb; + acp_dsp0_intr_cntl_t interrupt_cntl; + acp_dsp0_intr_cntl1_t interrupt_cntl1; + + interrupt_status = (acp_dsp0_intr_stat_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP0_INTR_STAT)); + /* Check and Clear all the Interrupt status bits */ + interrupt_status.bits.dmaiocstat = 0xFF; + interrupt_status.bits.wov_dma_stat = INTERRUPT_ENABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_STAT), interrupt_status.u32all); + interrupt_status1 = (acp_dsp0_intr_stat1_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP0_INTR_STAT1)); + /* Check and Clear all the Interrupt status bits */ + interrupt_status1.bits.audio_buffer_int_stat = 0x3F; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_STAT1), interrupt_status1.u32all); + + /* Disable the ACP to Host interrupts */ + ext_interrupt_enb.bits.acpextintrenb = INTERRUPT_CLEAR; + io_reg_write((PU_REGISTER_BASE + ACP_EXTERNAL_INTR_ENB), ext_interrupt_enb.u32all); + /* Disable all the required ACP interrupts + * in acp_dsp0_intr_cntl_t register + */ + interrupt_cntl = (acp_dsp0_intr_cntl_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP0_INTR_CNTL)); + interrupt_cntl.bits.dmaiocmask = INTERRUPT_DISABLE; + interrupt_cntl.bits.wov_dma_intr_mask = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL), interrupt_cntl.u32all); + interrupt_cntl1 = (acp_dsp0_intr_cntl1_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP0_INTR_CNTL1)); + interrupt_cntl1.bits.audio_buffer_int_mask = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL1), interrupt_cntl1.u32all); + platform_interrupt_clear(IRQ_NUM_EXT_LEVEL5, 0); + platform_interrupt_clear(IRQ_NUM_EXT_LEVEL3, 0); + platform_interrupt_clear(IRQ_NUM_EXT_LEVEL4, 0); + platform_interrupt_clear(IRQ_NUM_TIMER1, 0); + platform_interrupt_clear(IRQ_NUM_TIMER0, 0); +} + +void acp_dsp_sw_intr_disable(void) +{ + acp_dsp_sw_intr_cntl_t sw_intr_ctrl_reg; + /* Read the register */ + sw_intr_ctrl_reg = (acp_dsp_sw_intr_cntl_t) io_reg_read((PU_REGISTER_BASE + + ACP_DSP_SW_INTR_CNTL)); + sw_intr_ctrl_reg.bits.dsp0_to_host_intr_mask = INTERRUPT_DISABLE; + /* Write the Software Interrupt controller register */ + io_reg_write((PU_REGISTER_BASE + ACP_DSP_SW_INTR_CNTL), sw_intr_ctrl_reg.u32all); + platform_interrupt_clear(IRQ_NUM_EXT_LEVEL3, 0); +} + +/* This function triggers a host interrupt from ACP DSP */ +void acp_dsp_to_host_intr_trig(void) +{ + acp_sw_intr_trig_t sw_intr_trig; + /* Read the Software Interrupt controller register and update */ + sw_intr_trig = (acp_sw_intr_trig_t) io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + sw_intr_trig.bits.trig_dsp0_to_host_intr = INTERRUPT_ENABLE; + /* Write the Software Interrupt controller register */ + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); +} + +/* Clear the Acknowledge ( status) for the host to DSP inteerupt */ +void acp_ack_intr_from_host(void) +{ + /* acknowledge the host interrupt */ + acp_dsp_sw_intr_stat_t sw_intr_stat; + + sw_intr_stat = (acp_dsp_sw_intr_stat_t)io_reg_read(PU_REGISTER_BASE + + ACP_DSP_SW_INTR_STAT); + sw_intr_stat.bits.host_to_dsp0_intr1_stat = INTERRUPT_ENABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP_SW_INTR_STAT), sw_intr_stat.u32all); +} diff --git a/src/drivers/amd/rembrandt/ipc.c b/src/drivers/amd/rembrandt/ipc.c new file mode 100644 index 000000000000..a302e49809b5 --- /dev/null +++ b/src/drivers/amd/rembrandt/ipc.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 49be8ff3-71a3-4456-bb7e-4723f2e5730c */ +DECLARE_SOF_UUID("rembrandt-ipc-task", ipc_task_uuid, 0x49be8ff3, 0x71a3, 0x4456, + 0xbb, 0x7e, 0x47, 0x23, 0xf2, 0xe5, 0x73, 0x0c); + +volatile acp_scratch_mem_config_t *pscratch_mem_cfg = (volatile acp_scratch_mem_config_t *) + (PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); +static inline uint32_t sof_ipc_host_status(void) +{ + return (pscratch_mem_cfg->acp_host_ack_write | pscratch_mem_cfg->acp_host_msg_write); +} + +static inline uint32_t sof_ipc_host_msg_flag(void) +{ + return pscratch_mem_cfg->acp_host_msg_write; +} + +static inline uint32_t sof_ipc_host_ack_flag(void) +{ + return pscratch_mem_cfg->acp_host_ack_write; +} + +static inline uint32_t sof_ipc_dsp_status(void) +{ + return (pscratch_mem_cfg->acp_dsp_msg_write | pscratch_mem_cfg->acp_dsp_ack_write); +} + +static inline void sof_ipc_host_ack_clear(void) +{ + pscratch_mem_cfg->acp_host_ack_write = 0; +} + +static inline void sof_ipc_host_msg_clear(void) +{ + pscratch_mem_cfg->acp_host_msg_write = 0; +} + +static inline void sof_ipc_dsp_ack_set(void) +{ + pscratch_mem_cfg->acp_dsp_ack_write = 1; +} + +static inline void sof_ipc_dsp_msg_set(void) +{ + pscratch_mem_cfg->acp_dsp_msg_write = 1; +} + +static void irq_handler(void *arg) +{ + struct ipc *ipc = arg; + uint32_t status; + uint32_t lock; + acp_dsp_sw_intr_stat_t swintrstat; + acp_sw_intr_trig_t swintrtrig; + + swintrstat = (acp_dsp_sw_intr_stat_t)io_reg_read(PU_REGISTER_BASE + ACP_DSP_SW_INTR_STAT); + status = swintrstat.u32all & HOST_TO_DSP_INTR; + if (status) { + /* Interrupt source */ + if (sof_ipc_host_status()) { + lock = io_reg_read(PU_REGISTER_BASE + ACP_AXI2DAGB_SEM_0); + while (lock) + lock = io_reg_read(PU_REGISTER_BASE + ACP_AXI2DAGB_SEM_0); + /* Check if it is response from host */ + if (sof_ipc_host_ack_flag()) { + /* Clear the ACK from host */ + sof_ipc_host_ack_clear(); + /* Clear the Host to DSP Status Register */ + acp_ack_intr_from_host(); + /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + swintrtrig = (acp_sw_intr_trig_t) + io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + swintrtrig.bits.trig_host_to_dsp0_intr1 = INTERRUPT_DISABLE; + swintrtrig.bits.trig_dsp0_to_host_intr = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), + swintrtrig.u32all); + } + /* Check if new message from host */ + if (sof_ipc_host_msg_flag()) { + /* Clear the msg bit from host */ + sof_ipc_host_msg_clear(); + /* Clear the Host to DSP Status Register */ + acp_ack_intr_from_host(); + ipc_schedule_process(ipc); + } + io_reg_write((PU_REGISTER_BASE + ACP_AXI2DAGB_SEM_0), lock); + } else { + tr_err(&ipc_tr, "IPC:interrupt without setting flags host status 0x%x", + sof_ipc_host_status()); + } + } +} + +enum task_state ipc_platform_do_cmd(struct ipc *ipc) +{ + struct ipc_cmd_hdr *hdr; + + hdr = mailbox_validate(); + ipc_cmd(hdr); + return SOF_TASK_STATE_COMPLETED; +} + +void ipc_platform_complete_cmd(struct ipc *ipc) +{ + acp_sw_intr_trig_t sw_intr_trig; + + /* Set Dsp Ack for msg from host */ + sof_ipc_dsp_ack_set(); + /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + sw_intr_trig = (acp_sw_intr_trig_t) + io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + sw_intr_trig.bits.trig_host_to_dsp0_intr1 = INTERRUPT_DISABLE; + sw_intr_trig.bits.trig_dsp0_to_host_intr = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); + /* now interrupt host to tell it we have sent a message */ + acp_dsp_to_host_intr_trig(); + /* Disable the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + sw_intr_trig = (acp_sw_intr_trig_t)io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + sw_intr_trig.bits.trig_dsp0_to_host_intr = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); + if (ipc->pm_prepare_D3) { + while (1) + wait_for_interrupt(0); + } +} + +int ipc_platform_send_msg(const struct ipc_msg *msg) +{ + int ret = 0; + acp_sw_intr_trig_t sw_intr_trig; + acp_dsp_sw_intr_stat_t sw_intr_stat; + uint32_t status; + uint32_t lock; + /* Check if host cleared the status for previous messages */ + sw_intr_stat = (acp_dsp_sw_intr_stat_t) + io_reg_read(PU_REGISTER_BASE + ACP_DSP_SW_INTR_STAT); + status = sw_intr_stat.bits.dsp0_to_host_intr_stat; + if (sof_ipc_dsp_status() || status) { + sw_intr_stat = (acp_dsp_sw_intr_stat_t) + io_reg_read(PU_REGISTER_BASE + ACP_DSP_SW_INTR_STAT); + status = sw_intr_stat.bits.dsp0_to_host_intr_stat; + return ret; + } + lock = io_reg_read(PU_REGISTER_BASE + ACP_AXI2DAGB_SEM_0); + while (lock) + lock = io_reg_read(PU_REGISTER_BASE + ACP_AXI2DAGB_SEM_0); + /* Write new message in the mailbox */ + mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); + /* Need to set DSP message flag */ + sof_ipc_dsp_msg_set(); + /* now interrupt host to tell it we have sent a message */ + acp_dsp_to_host_intr_trig(); + /* Disable the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + sw_intr_trig = (acp_sw_intr_trig_t)io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + sw_intr_trig.bits.trig_dsp0_to_host_intr = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); + io_reg_write((PU_REGISTER_BASE + ACP_AXI2DAGB_SEM_0), lock); + return ret; +} + +int platform_ipc_init(struct ipc *ipc) +{ + ipc_set_drvdata(ipc, NULL); + /* schedule */ + schedule_task_init_edf(&ipc->ipc_task, SOF_UUID(ipc_task_uuid), + &ipc_task_ops, ipc, 0, 0); + arch_interrupt_clear(IRQ_NUM_EXT_LEVEL3); + interrupt_register(IRQ_NUM_EXT_LEVEL3, irq_handler, ipc); + /* Enabling software interuppts */ + interrupt_enable(IRQ_NUM_EXT_LEVEL3, ipc); + return 0; +} diff --git a/src/drivers/amd/rembrandt/timer.c b/src/drivers/amd/rembrandt/timer.c new file mode 100644 index 000000000000..fc00b22e21a5 --- /dev/null +++ b/src/drivers/amd/rembrandt/timer.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void platform_timer_start(struct timer *timer) +{ + /* Nothing to do here */ +} + +void platform_timer_stop(struct timer *timer) +{ + arch_timer_disable(timer); +} + +int64_t platform_timer_set(struct timer *timer, uint64_t ticks) +{ + return arch_timer_set(timer, ticks); +} + +void platform_timer_clear(struct timer *timer) +{ + arch_timer_clear(timer); +} + +uint64_t platform_timer_get(struct timer *timer) +{ + return arch_timer_get_system(timer); +} + +uint64_t platform_timer_get_atomic(struct timer *timer) +{ + return arch_timer_get_system(timer); +} + +void platform_host_timestamp(struct comp_dev *host, + struct sof_ipc_stream_posn *posn) +{ + int err; + + err = comp_position(host, posn); + if (err == 0) + posn->flags |= SOF_TIME_HOST_VALID | SOF_TIME_HOST_64; +} + +void platform_dai_timestamp(struct comp_dev *dai, + struct sof_ipc_stream_posn *posn) +{ + int err; + + err = comp_position(dai, posn); + if (err == 0) + posn->flags |= SOF_TIME_DAI_VALID; + + posn->wallclock = timer_get_system(timer_get()) - posn->wallclock; + posn->flags |= SOF_TIME_WALL_VALID | SOF_TIME_WALL_64; +} + +void platform_dai_wallclock(struct comp_dev *dai, uint64_t *wallclock) +{ + *wallclock = timer_get_system(timer_get()); +} + +int timer_register(struct timer *timer, void(*handler)(void *arg), void *arg) +{ + switch (timer->id) { + case TIMER0: + case TIMER1: + return arch_timer_register(timer, handler, arg); + default: + return -EINVAL; + } +} + +void timer_unregister(struct timer *timer, void *arg) +{ + interrupt_unregister(timer->irq, arg); +} + +void timer_enable(struct timer *timer, void *arg, int core) +{ + interrupt_enable(timer->irq, arg); +} + +void timer_disable(struct timer *timer, void *arg, int core) +{ + interrupt_disable(timer->irq, arg); +} From 1d5827736612e9a149e269079b461d4e32820385 Mon Sep 17 00:00:00 2001 From: Balakishorepati Date: Mon, 28 Mar 2022 22:09:10 +0530 Subject: [PATCH 4/5] platform: Add support for amd rembrandt platform This adds support for platform drivers (dai, dma, clk) and general platform initialization. Signed-off-by: Balakishorepati --- src/platform/CMakeLists.txt | 2 +- src/platform/Kconfig | 12 + src/platform/amd/CMakeLists.txt | 5 +- src/platform/amd/rembrandt/CMakeLists.txt | 5 + .../include/arch/xtensa/config/core-isa.h | 672 +++++++++++++++ .../include/arch/xtensa/config/core-matmap.h | 317 +++++++ .../include/arch/xtensa/config/defs.h | 38 + .../include/arch/xtensa/config/specreg.h | 108 +++ .../include/arch/xtensa/config/system.h | 262 ++++++ .../include/arch/xtensa/config/tie-asm.h | 366 +++++++++ .../include/arch/xtensa/config/tie.h | 211 +++++ .../include/arch/xtensa/tie/xt_datacache.h | 132 +++ .../include/platform/chip_offset_byte.h | 157 ++++ .../include/platform/chip_registers.h | 774 ++++++++++++++++++ .../rembrandt/include/platform/drivers/idc.h | 28 + .../include/platform/drivers/interrupt.h | 111 +++ .../include/platform/fw_scratch_mem.h | 120 +++ .../amd/rembrandt/include/platform/lib/clk.h | 48 ++ .../amd/rembrandt/include/platform/lib/cpu.h | 35 + .../amd/rembrandt/include/platform/lib/dai.h | 20 + .../amd/rembrandt/include/platform/lib/dma.h | 31 + .../rembrandt/include/platform/lib/mailbox.h | 54 ++ .../rembrandt/include/platform/lib/memory.h | 172 ++++ .../include/platform/lib/pm_runtime.h | 61 ++ .../amd/rembrandt/include/platform/platform.h | 105 +++ .../rembrandt/include/platform/trace/trace.h | 22 + src/platform/amd/rembrandt/lib/CMakeLists.txt | 8 + src/platform/amd/rembrandt/lib/clk.c | 145 ++++ src/platform/amd/rembrandt/lib/dai.c | 152 ++++ src/platform/amd/rembrandt/lib/dma.c | 113 +++ src/platform/amd/rembrandt/lib/memory.c | 95 +++ src/platform/amd/rembrandt/platform.c | 136 +++ src/platform/amd/rembrandt/rembrandt.x.in | 577 +++++++++++++ 33 files changed, 5092 insertions(+), 2 deletions(-) create mode 100644 src/platform/amd/rembrandt/CMakeLists.txt create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/config/core-isa.h create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/config/core-matmap.h create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/config/defs.h create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/config/specreg.h create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/config/system.h create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/config/tie-asm.h create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/config/tie.h create mode 100644 src/platform/amd/rembrandt/include/arch/xtensa/tie/xt_datacache.h create mode 100644 src/platform/amd/rembrandt/include/platform/chip_offset_byte.h create mode 100644 src/platform/amd/rembrandt/include/platform/chip_registers.h create mode 100644 src/platform/amd/rembrandt/include/platform/drivers/idc.h create mode 100644 src/platform/amd/rembrandt/include/platform/drivers/interrupt.h create mode 100644 src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h create mode 100644 src/platform/amd/rembrandt/include/platform/lib/clk.h create mode 100644 src/platform/amd/rembrandt/include/platform/lib/cpu.h create mode 100644 src/platform/amd/rembrandt/include/platform/lib/dai.h create mode 100644 src/platform/amd/rembrandt/include/platform/lib/dma.h create mode 100644 src/platform/amd/rembrandt/include/platform/lib/mailbox.h create mode 100644 src/platform/amd/rembrandt/include/platform/lib/memory.h create mode 100644 src/platform/amd/rembrandt/include/platform/lib/pm_runtime.h create mode 100644 src/platform/amd/rembrandt/include/platform/platform.h create mode 100644 src/platform/amd/rembrandt/include/platform/trace/trace.h create mode 100644 src/platform/amd/rembrandt/lib/CMakeLists.txt create mode 100644 src/platform/amd/rembrandt/lib/clk.c create mode 100644 src/platform/amd/rembrandt/lib/dai.c create mode 100644 src/platform/amd/rembrandt/lib/dma.c create mode 100644 src/platform/amd/rembrandt/lib/memory.c create mode 100644 src/platform/amd/rembrandt/platform.c create mode 100644 src/platform/amd/rembrandt/rembrandt.x.in diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 8aafccd8ec4c..7e3d046a0c81 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -25,7 +25,7 @@ elseif(CONFIG_IMX8M) add_subdirectory(imx8m) elseif(CONFIG_IMX8ULP) add_subdirectory(imx8ulp) -elseif(CONFIG_RENOIR) +elseif(CONFIG_RENOIR OR CONFIG_REMBRANDT) add_subdirectory(amd) elseif(CONFIG_MT8186) add_subdirectory(mt8186) diff --git a/src/platform/Kconfig b/src/platform/Kconfig index 3c5b5a8a7f69..69407163ff7e 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -245,6 +245,18 @@ config RENOIR help Select if your target platform is renoir-compatible +config REMBRANDT + bool "Build for Rembrandt" + select XT_INTERRUPT_LEVEL_5 + select XT_INTERRUPT_LEVEL_3 + select XT_INTERRUPT_LEVEL_1 + select XT_INTERRUPT_LEVEL_4 + select XT_WAITI_DELAY + select XTENSA_EXCLUSIVE + select SCHEDULE_DMA_MULTI_CHANNEL + help + Select if your target platform is rembrandt-compatible + config MT8186 bool "Build for MTK MT8186" select XT_INTERRUPT_LEVEL_1 diff --git a/src/platform/amd/CMakeLists.txt b/src/platform/amd/CMakeLists.txt index 5f22cec48b6f..c7373783cc74 100644 --- a/src/platform/amd/CMakeLists.txt +++ b/src/platform/amd/CMakeLists.txt @@ -1,3 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause - +if(CONFIG_RENOIR) add_subdirectory(renoir) +elseif(CONFIG_REMBRANDT) + add_subdirectory(rembrandt) +endif() diff --git a/src/platform/amd/rembrandt/CMakeLists.txt b/src/platform/amd/rembrandt/CMakeLists.txt new file mode 100644 index 000000000000..ec909d60035f --- /dev/null +++ b/src/platform/amd/rembrandt/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(lib) + +add_local_sources(sof platform.c) diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/config/core-isa.h b/src/platform/amd/rembrandt/include/arch/xtensa/config/core-isa.h new file mode 100644 index 000000000000..36cfd4756638 --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/config/core-isa.h @@ -0,0 +1,672 @@ +/* + * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa + * processor CORE configuration + * + * See , which includes this file, for more details. + */ + +/* Xtensa processor core configuration information. + + Customer ID=12153; Build=0x878bf; Copyright (c) 1999-2020 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _XTENSA_CORE_CONFIGURATION_H +#define _XTENSA_CORE_CONFIGURATION_H + +//depot/dev/Homewood/Xtensa/SWConfig/hal/core-common.h.tph#24 - edit change 444323 (text+ko) + +/**************************************************************************** + Parameters Useful for Any Code, USER or PRIVILEGED + ****************************************************************************/ + +/* + * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is + * configured, and a value of 0 otherwise. These macros are always defined. + */ + + +/*---------------------------------------------------------------------- + ISA + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ +#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */ +#define XCHAL_NUM_AREGS 64 /* num of physical addr regs */ +#define XCHAL_NUM_AREGS_LOG2 6 /* log2(XCHAL_NUM_AREGS) */ +#define XCHAL_MAX_INSTRUCTION_SIZE 16 /* max instr bytes (3..8) */ +#define XCHAL_HAVE_DEBUG 1 /* debug option */ +#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ +#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */ +#define XCHAL_LOOP_BUFFER_SIZE 256 /* zero-ov. loop instr buffer size */ +#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ +#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */ +#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */ +#define XCHAL_HAVE_DEPBITS 0 /* DEPBITS instruction */ +#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */ +#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ +#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ +#define XCHAL_HAVE_MUL32_HIGH 1 /* MULUH/MULSH instructions */ +#define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */ +#define XCHAL_HAVE_L32R 1 /* L32R instruction */ +#define XCHAL_HAVE_ABSOLUTE_LITERALS 0 /* non-PC-rel (extended) L32R */ +#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ +#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ +#define XCHAL_HAVE_EXCLUSIVE 0 /* L32EX/S32EX instructions */ +#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ +#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ +#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */ +#define XCHAL_HAVE_ABS 1 /* ABS instruction */ +#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */ +#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */ +#define XCHAL_HAVE_SPECULATION 0 /* speculation */ +#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ +#define XCHAL_NUM_CONTEXTS 1 /* */ +#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */ +#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ +#define XCHAL_HAVE_PRID 0 /* processor ID register */ +#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ +#define XCHAL_HAVE_MX 0 /* MX core (Tensilica internal) */ +#define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */ +#define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */ +#define XCHAL_HAVE_PSO 0 /* Power Shut-Off */ +#define XCHAL_HAVE_PSO_CDM 0 /* core/debug/mem pwr domains */ +#define XCHAL_HAVE_PSO_FULL_RETENTION 0 /* all regs preserved on PSO */ +#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */ +#define XCHAL_HAVE_BOOLEANS 1 /* boolean registers */ +#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ +#define XCHAL_CP_MAXCFG 2 /* max allowed cp id plus one */ +#define XCHAL_HAVE_MAC16 0 /* MAC16 package */ +#define XCHAL_HAVE_LX 1 /* LX core */ +#define XCHAL_HAVE_NX 0 /* NX core (starting RH) */ + +#define XCHAL_HAVE_SUPERGATHER 0 /* SuperGather */ + +#define XCHAL_HAVE_FUSION 0 /* Fusion*/ +#define XCHAL_HAVE_FUSION_FP 0 /* Fusion FP option */ +#define XCHAL_HAVE_FUSION_LOW_POWER 0 /* Fusion Low Power option */ +#define XCHAL_HAVE_FUSION_AES 0 /* Fusion BLE/Wifi AES-128 CCM option */ +#define XCHAL_HAVE_FUSION_CONVENC 0 /* Fusion Conv Encode option */ +#define XCHAL_HAVE_FUSION_LFSR_CRC 0 /* Fusion LFSR-CRC option */ +#define XCHAL_HAVE_FUSION_BITOPS 0 /* Fusion Bit Operations Support option */ +#define XCHAL_HAVE_FUSION_AVS 0 /* Fusion AVS option */ +#define XCHAL_HAVE_FUSION_16BIT_BASEBAND 0 /* Fusion 16-bit Baseband option */ +#define XCHAL_HAVE_FUSION_VITERBI 0 /* Fusion Viterbi option */ +#define XCHAL_HAVE_FUSION_SOFTDEMAP 0 /* Fusion Soft Bit Demap option */ +#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ +#define XCHAL_HAVE_HIFI5 1 /* HiFi5 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI5_NN_MAC 1 /* HiFi5 Audio Engine NN-MAC option */ +#define XCHAL_HAVE_HIFI5_VFPU 1 /* HiFi5 Audio Engine Single-Precision VFPU option */ +#define XCHAL_HAVE_HIFI5_HP_VFPU 1 /* HiFi5 Audio Engine Half-Precision VFPU option */ +#define XCHAL_HAVE_HIFI4 0 /* HiFi4 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI4_VFPU 1 /* HiFi4 Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI3 1 /* HiFi3 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3_VFPU 1 /* HiFi3 Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI3Z 0 /* HiFi3Z Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3Z_VFPU 0 /* HiFi3Z Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI2EP 0 /* HiFi2EP */ +#define XCHAL_HAVE_HIFI_MINI 0 + + + +#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ +#define XCHAL_HAVE_USER_DPFPU 0 /* user DP floating-point pkg */ +#define XCHAL_HAVE_USER_SPFPU 1 /* user SP floating-point pkg */ +#define XCHAL_HAVE_FP 1 /* single prec floating point */ +#define XCHAL_HAVE_FP_DIV 1 /* FP with DIV instructions */ +#define XCHAL_HAVE_FP_RECIP 1 /* FP with RECIP instructions */ +#define XCHAL_HAVE_FP_SQRT 1 /* FP with SQRT instructions */ +#define XCHAL_HAVE_FP_RSQRT 1 /* FP with RSQRT instructions */ +#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ +#define XCHAL_HAVE_DFP_DIV 0 /* DFP with DIV instructions */ +#define XCHAL_HAVE_DFP_RECIP 0 /* DFP with RECIP instructions*/ +#define XCHAL_HAVE_DFP_SQRT 0 /* DFP with SQRT instructions */ +#define XCHAL_HAVE_DFP_RSQRT 0 /* DFP with RSQRT instructions*/ +#define XCHAL_HAVE_DFP_ACCEL 0 /* double precision FP acceleration pkg */ +#define XCHAL_HAVE_DFP_accel XCHAL_HAVE_DFP_ACCEL /* for backward compatibility */ + +#define XCHAL_HAVE_DFPU_SINGLE_ONLY 0 /* DFPU Coprocessor, single precision only */ +#define XCHAL_HAVE_DFPU_SINGLE_DOUBLE 0 /* DFPU Coprocessor, single and double precision */ +#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ +#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ + +#define XCHAL_HAVE_FUSIONG 0 /* FusionG */ +#define XCHAL_HAVE_FUSIONG3 0 /* FusionG3 */ +#define XCHAL_HAVE_FUSIONG6 0 /* FusionG6 */ +#define XCHAL_HAVE_FUSIONG_SP_VFPU 0 /* sp_vfpu option on FusionG */ +#define XCHAL_HAVE_FUSIONG_DP_VFPU 0 /* dp_vfpu option on FusionG */ +#define XCHAL_FUSIONG_SIMD32 0 /* simd32 for FusionG */ + +#define XCHAL_HAVE_FUSIONJ 0 /* FusionJ */ +#define XCHAL_HAVE_FUSIONJ6 0 /* FusionJ6 */ +#define XCHAL_HAVE_FUSIONJ_SP_VFPU 0 /* sp_vfpu option on FusionJ */ +#define XCHAL_HAVE_FUSIONJ_DP_VFPU 0 /* dp_vfpu option on FusionJ */ +#define XCHAL_FUSIONJ_SIMD32 0 /* simd32 for FusionJ */ + +#define XCHAL_HAVE_PDX 0 /* PDX-LX */ +#define XCHAL_PDX_SIMD32 0 /* simd32 for PDX */ +#define XCHAL_HAVE_PDX4 0 /* PDX4-LX */ +#define XCHAL_HAVE_PDX8 0 /* PDX8-LX */ +#define XCHAL_HAVE_PDX16 0 /* PDX16-LX */ +#define XCHAL_HAVE_PDXNX 0 /* PDX-NX */ + +#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ +#define XCHAL_HAVE_CONNXD2_DUALLSFLIX 0 /* ConnX D2 & Dual LoadStore Flix */ +#define XCHAL_HAVE_BALL 0 +#define XCHAL_HAVE_BALLAP 0 +#define XCHAL_HAVE_BBE16 0 /* ConnX BBE16 pkg */ +#define XCHAL_HAVE_BBE16_RSQRT 0 /* BBE16 & vector recip sqrt */ +#define XCHAL_HAVE_BBE16_VECDIV 0 /* BBE16 & vector divide */ +#define XCHAL_HAVE_BBE16_DESPREAD 0 /* BBE16 & despread */ +#define XCHAL_HAVE_CONNX_B10 0 /* ConnX B10 pkg*/ +#define XCHAL_HAVE_CONNX_B20 0 /* ConnX B20 pkg*/ +#define XCHAL_HAVE_CONNX_B_SP_VFPU 0 /* Single-precision Vector Floating-point option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_SPX_VFPU 0 /* Single-precision Extended Vector Floating-point option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_HPX_VFPU 0 /* Half-precision Extended Vector Floating-point option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_32B_MAC 0 /* 32-bit vector MAC (real and complex), FIR & FFT option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_VITERBI 0 /* Viterbi option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_TURBO 0 /* Turbo option on ConnX B10 & B20 */ +#define XCHAL_HAVE_BBENEP 0 /* ConnX BBENEP pkgs */ +#define XCHAL_HAVE_BBENEP_SP_VFPU 0 /* sp_vfpu option on BBE-EP */ +#define XCHAL_HAVE_BSP3 0 /* ConnX BSP3 pkg */ +#define XCHAL_HAVE_BSP3_TRANSPOSE 0 /* BSP3 & transpose32x32 */ +#define XCHAL_HAVE_SSP16 0 /* ConnX SSP16 pkg */ +#define XCHAL_HAVE_SSP16_VITERBI 0 /* SSP16 & viterbi */ +#define XCHAL_HAVE_TURBO16 0 /* ConnX Turbo16 pkg */ +#define XCHAL_HAVE_BBP16 0 /* ConnX BBP16 pkg */ +#define XCHAL_HAVE_FLIX3 0 /* basic 3-way FLIX option */ +#define XCHAL_HAVE_GRIVPEP 0 /* General Release of IVPEP */ +#define XCHAL_HAVE_GRIVPEP_HISTOGRAM 0 /* Histogram option on GRIVPEP */ + +#define XCHAL_HAVE_VISION 0 /* Vision P5/P6 */ +#define XCHAL_VISION_SIMD16 0 /* simd16 for Vision P5/P6 */ +#define XCHAL_VISION_TYPE 0 /* Vision P5, P6, Q6 or Q7 */ +#define XCHAL_VISION_QUAD_MAC_TYPE 0 /* quad_mac option on Vision P6 */ +#define XCHAL_HAVE_VISION_HISTOGRAM 0 /* histogram option on Vision P5/P6 */ +#define XCHAL_HAVE_VISION_SP_VFPU 0 /* sp_vfpu option on Vision P5/P6/Q6/Q7 */ +#define XCHAL_HAVE_VISION_SP_VFPU_2XFMAC 0 /* sp_vfpu_2xfma option on Vision Q7 */ +#define XCHAL_HAVE_VISION_HP_VFPU 0 /* hp_vfpu option on Vision P6/Q6 */ +#define XCHAL_HAVE_VISION_HP_VFPU_2XFMAC 0 /* hp_vfpu_2xfma option on Vision Q7 */ + +#define XCHAL_HAVE_VISIONC 0 /* Vision C */ + +#define XCHAL_HAVE_XNNE 0 /* XNNE */ + +/*---------------------------------------------------------------------- + MISC + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_LOADSTORE_UNITS 2 /* load/store units */ +#define XCHAL_NUM_WRITEBUFFER_ENTRIES 16 /* size of write buffer */ +#define XCHAL_INST_FETCH_WIDTH 16 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 16 /* data width in bytes */ +#define XCHAL_DATA_PIPE_DELAY 2 /* d-side pipeline delay + (1 = 5-stage, 2 = 7-stage) */ +#define XCHAL_CLOCK_GATING_GLOBAL 1 /* global clock gating */ +#define XCHAL_CLOCK_GATING_FUNCUNIT 1 /* funct. unit clock gating */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ +#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ +#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ +#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ + +#define XCHAL_UNIFIED_LOADSTORE 0 + +#define XCHAL_SW_VERSION 1401000 /* sw version of this header */ +#define XCHAL_SW_MINOR_VERSION 1401000 /* same, with zeroed micro and patch */ +#define XCHAL_SW_MICRO_VERSION 1401000 /* same, with zeroed patch */ + +#define XCHAL_CORE_ID "LX7_HiFi5_PROD" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_BUILD_UNIQUE_ID 0x000878BF /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC2038286 /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x284878BF /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX7.1.1" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2810 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION_MICRO /* subdot ver# of targeted hw */ +#define XCHAL_HW_VERSION 281010 /* major*100+(major<2810 ? minor : minor*10+micro) */ +#define XCHAL_HW_REL_LX7 1 +#define XCHAL_HW_REL_LX7_1 1 +#define XCHAL_HW_REL_LX7_1_1 1 +#define XCHAL_HW_CONFIGID_RELIABLE 1 +/* If software targets a *range* of hardware versions, these are the bounds: */ +#define XCHAL_HW_MIN_VERSION_MAJOR 2810 /* major v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MINOR 1 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MICRO 0 /* micro v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 281010 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2810 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 1 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MICRO /* micro v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 281010 /* latest targeted hw */ + +/* Config is enabled for functional safety: */ +#define XCHAL_HAVE_FUNC_SAFETY 0 + +#define XCHAL_HAVE_APB 0 + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_ICACHE_LINESIZE 128 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 128 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 7 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 7 /* log2(D line size in bytes) */ + +#define XCHAL_ICACHE_SIZE 131072 /* I-cache size in bytes or 0 */ +#define XCHAL_ICACHE_SIZE_LOG2 17 +#define XCHAL_DCACHE_SIZE 131072 /* D-cache size in bytes or 0 */ +#define XCHAL_DCACHE_SIZE_LOG2 17 + +#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */ +#define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */ + +#define XCHAL_HAVE_PREFETCH 1 /* PREFCTL register */ +#define XCHAL_HAVE_PREFETCH_L1 1 /* prefetch to L1 cache */ +#define XCHAL_PREFETCH_CASTOUT_LINES 1 /* dcache pref. castout bufsz */ +#define XCHAL_PREFETCH_ENTRIES 16 /* cache prefetch entries */ +#define XCHAL_PREFETCH_BLOCK_ENTRIES 8 /* prefetch block streams */ +#define XCHAL_HAVE_CACHE_BLOCKOPS 1 /* block prefetch for caches */ +#define XCHAL_HAVE_CME_DOWNGRADES 0 +#define XCHAL_HAVE_ICACHE_TEST 1 /* Icache test instructions */ +#define XCHAL_HAVE_DCACHE_TEST 1 /* Dcache test instructions */ +#define XCHAL_HAVE_ICACHE_DYN_WAYS 1 /* Icache dynamic way support */ +#define XCHAL_HAVE_DCACHE_DYN_WAYS 1 /* Dcache dynamic way support */ +#define XCHAL_HAVE_ICACHE_DYN_ENABLE 1 /* Icache enabled via MEMCTL */ +#define XCHAL_HAVE_DCACHE_DYN_ENABLE 1 /* Dcache enabled via MEMCTL */ + +#define XCHAL_L1SCACHE_SIZE 0 +#define XCHAL_L1SCACHE_SIZE_LOG2 0 +#define XCHAL_L1SCACHE_WAYS 1 +#define XCHAL_L1SCACHE_WAYS_LOG2 0 +#define XCHAL_L1SCACHE_ACCESS_SIZE 0 +#define XCHAL_L1SCACHE_BANKS 1 + +#define XCHAL_HAVE_L2 0 /* NX L2 cache controller */ + +/* This one is a form of caching, though not architecturally visible: */ +#define XCHAL_HAVE_BRANCH_PREDICTION 0 /* branch [target] prediction */ + + + + +/**************************************************************************** + Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code + ****************************************************************************/ + + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_PIF 1 /* any outbound bus present */ + +#define XCHAL_HAVE_AXI 1 /* AXI bus */ +#define XCHAL_HAVE_AXI_ECC 1 /* ECC on AXI bus */ +#define XCHAL_HAVE_ACELITE 0 /* ACELite bus */ + +#define XCHAL_HAVE_PIF_WR_RESP 1 /* pif write response */ +#define XCHAL_HAVE_PIF_REQ_ATTR 1 /* pif attribute */ + +/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ + +/* Number of cache sets in log2(lines per way): */ +#define XCHAL_ICACHE_SETWIDTH 8 +#define XCHAL_DCACHE_SETWIDTH 8 + +/* Cache set associativity (number of ways): */ +#define XCHAL_ICACHE_WAYS 4 +#define XCHAL_ICACHE_WAYS_LOG2 2 +#define XCHAL_DCACHE_WAYS 4 +#define XCHAL_DCACHE_WAYS_LOG2 2 + +/* Cache features: */ +#define XCHAL_ICACHE_LINE_LOCKABLE 1 +#define XCHAL_DCACHE_LINE_LOCKABLE 1 +#define XCHAL_ICACHE_ECC_PARITY 0 +#define XCHAL_DCACHE_ECC_PARITY 0 +#define XCHAL_ICACHE_ECC_WIDTH 4 +#define XCHAL_DCACHE_ECC_WIDTH 1 + +/* Cache access size in bytes (affects operation of SICW instruction): */ +#define XCHAL_ICACHE_ACCESS_SIZE 16 +#define XCHAL_DCACHE_ACCESS_SIZE 16 + +#define XCHAL_DCACHE_BANKS 2 /* number of banks */ + +/* The number of Cache lines associated with a single cache tag */ +#define XCHAL_DCACHE_LINES_PER_TAG_LOG2 0 + +/* Number of encoded cache attr bits (see for decoded bits): */ +#define XCHAL_CA_BITS 4 + + +/*---------------------------------------------------------------------- + INTERNAL I/D RAM/ROMs and XLMI + ----------------------------------------------------------------------*/ +#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */ +#define XCHAL_NUM_INSTRAM 1 /* number of core instr. RAMs */ +#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */ +#define XCHAL_NUM_DATARAM 1 /* number of core data RAMs */ +#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ +#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */ +#define XCHAL_HAVE_IRAMCFG 0 /* IRAMxCFG register present */ +#define XCHAL_HAVE_DRAMCFG 0 /* DRAMxCFG register present */ + +/* Instruction RAM 0: */ +#define XCHAL_INSTRAM0_VADDR 0x7F000000 /* virtual address */ +#define XCHAL_INSTRAM0_PADDR 0x7F000000 /* physical address */ +#define XCHAL_INSTRAM0_SIZE 1048576 /* size in bytes */ +#define XCHAL_INSTRAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XCHAL_HAVE_INSTRAM0 1 +#define XCHAL_INSTRAM0_HAVE_IDMA 0 /* idma supported by this local memory */ + +/* Data RAM 0: */ +#define XCHAL_DATARAM0_VADDR 0xE0000000 /* virtual address */ +#define XCHAL_DATARAM0_PADDR 0xE0000000 /* physical address */ +#define XCHAL_DATARAM0_SIZE 1048576 /* size in bytes */ +#define XCHAL_DATARAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XCHAL_DATARAM0_BANKS 2 /* number of banks */ +#define XCHAL_HAVE_DATARAM0 1 +#define XCHAL_DATARAM0_HAVE_IDMA 0 /* idma supported by this local memory */ + + +#define XCHAL_HAVE_IDMA 0 + + +#define XCHAL_HAVE_IMEM_LOADSTORE 1 /* can load/store to IROM/IRAM*/ + +/*---------------------------------------------------------------------- + INTERRUPTS and TIMERS + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ +#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ +#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ +#define XCHAL_NUM_TIMERS 2 /* number of CCOMPAREn regs */ +#define XCHAL_NUM_INTERRUPTS 9 /* number of interrupts */ +#define XCHAL_NUM_INTERRUPTS_LOG2 4 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XCHAL_NUM_EXTINTERRUPTS 5 /* num of external interrupts */ +#define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels + (not including level zero) */ + + +#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#define XCHAL_EXCM_LEVEL 5 /* level masked by PS.EXCM */ + /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ + +/* Masks of interrupts at each interrupt level: */ +#define XCHAL_INTLEVEL1_MASK 0x00000143 +#define XCHAL_INTLEVEL2_MASK 0x00000004 +#define XCHAL_INTLEVEL3_MASK 0x00000008 +#define XCHAL_INTLEVEL4_MASK 0x00000010 +#define XCHAL_INTLEVEL5_MASK 0x00000020 +#define XCHAL_INTLEVEL6_MASK 0x00000000 +#define XCHAL_INTLEVEL7_MASK 0x00000080 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x00000143 +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x00000147 +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x0000014F +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x0000015F +#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x0000017F +#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x0000017F +#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x000001FF + +/* Level of each interrupt: */ +#define XCHAL_INT0_LEVEL 1 +#define XCHAL_INT1_LEVEL 1 +#define XCHAL_INT2_LEVEL 2 +#define XCHAL_INT3_LEVEL 3 +#define XCHAL_INT4_LEVEL 4 +#define XCHAL_INT5_LEVEL 5 +#define XCHAL_INT6_LEVEL 1 +#define XCHAL_INT7_LEVEL 7 +#define XCHAL_INT8_LEVEL 1 +#define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */ +#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ +#define XCHAL_NMILEVEL 7 /* NMI "level" (for use with + EXCSAVE/EPS/EPC_n, RFI n) */ + +/* Type of each interrupt: */ +#define XCHAL_INT0_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT1_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT2_TYPE XTHAL_INTTYPE_WRITE_ERROR +#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT7_TYPE XTHAL_INTTYPE_NMI +#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL + +/* Masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFFFFE00 +#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x00000138 +#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000000 +#define XCHAL_INTTYPE_MASK_NMI 0x00000080 +#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000002 +#define XCHAL_INTTYPE_MASK_TIMER 0x00000041 +#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000004 +#define XCHAL_INTTYPE_MASK_DBG_REQUEST 0x00000000 +#define XCHAL_INTTYPE_MASK_BREAKIN 0x00000000 +#define XCHAL_INTTYPE_MASK_TRAX 0x00000000 +#define XCHAL_INTTYPE_MASK_PROFILING 0x00000000 +#define XCHAL_INTTYPE_MASK_IDMA_DONE 0x00000000 +#define XCHAL_INTTYPE_MASK_IDMA_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_GS_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_L2_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_L2_STATUS 0x00000000 +#define XCHAL_INTTYPE_MASK_COR_ECC_ERR 0x00000000 + +/* Interrupt numbers assigned to specific interrupt sources: */ +#define XCHAL_TIMER0_INTERRUPT 0 /* CCOMPARE0 */ +#define XCHAL_TIMER1_INTERRUPT 6 /* CCOMPARE1 */ +#define XCHAL_TIMER2_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_NMI_INTERRUPT 7 /* non-maskable interrupt */ +#define XCHAL_WRITE_ERROR_INTERRUPT 2 + +/* Interrupt numbers for levels at which only one interrupt is configured: */ +#define XCHAL_INTLEVEL2_NUM 2 +#define XCHAL_INTLEVEL3_NUM 3 +#define XCHAL_INTLEVEL4_NUM 4 +#define XCHAL_INTLEVEL5_NUM 5 +#define XCHAL_INTLEVEL7_NUM 7 +/* (There are many interrupts each at level(s) 1.) */ + + +/* + * External interrupt mapping. + * These macros describe how Xtensa processor interrupt numbers + * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) + * map to external BInterrupt pins, for those interrupts + * configured as external (level-triggered, edge-triggered, or NMI). + * See the Xtensa processor databook for more details. + */ + +/* Core interrupt numbers mapped to each EXTERNAL BInterrupt pin number: */ +#define XCHAL_EXTINT0_NUM 3 /* (intlevel 3) */ +#define XCHAL_EXTINT1_NUM 4 /* (intlevel 4) */ +#define XCHAL_EXTINT2_NUM 5 /* (intlevel 5) */ +#define XCHAL_EXTINT3_NUM 7 /* (intlevel 7) */ +#define XCHAL_EXTINT4_NUM 8 /* (intlevel 1) */ +/* EXTERNAL BInterrupt pin numbers mapped to each core interrupt number: */ +#define XCHAL_INT3_EXTNUM 0 /* (intlevel 3) */ +#define XCHAL_INT4_EXTNUM 1 /* (intlevel 4) */ +#define XCHAL_INT5_EXTNUM 2 /* (intlevel 5) */ +#define XCHAL_INT7_EXTNUM 3 /* (intlevel 7) */ +#define XCHAL_INT8_EXTNUM 4 /* (intlevel 1) */ + +#define XCHAL_HAVE_ISB 0 /* No ISB */ +#define XCHAL_ISB_VADDR 0 /* N/A */ +#define XCHAL_HAVE_ITB 0 /* No ITB */ +#define XCHAL_ITB_VADDR 0 /* N/A */ + +#define XCHAL_HAVE_KSL 0 /* Kernel Stack Limit */ +#define XCHAL_HAVE_ISL 0 /* Interrupt Stack Limit */ +#define XCHAL_HAVE_PSL 0 /* Pageable Stack Limit */ + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture + number: 1 == XEA1 (until T1050) + 2 == XEA2 (T1040 onwards) + 3 == XEA3 (LX8/NX/SX onwards) + 0 == XEAX (extern) or TX */ +#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XCHAL_HAVE_XEA3 0 /* Exception Architecture 3 */ +#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ +#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ +#define XCHAL_HAVE_IMPRECISE_EXCEPTIONS 0 /* imprecise exception option */ +#define XCHAL_EXCCAUSE_NUM 64 /* Number of exceptions */ +#define XCHAL_HAVE_HALT 0 /* halt architecture option */ +#define XCHAL_HAVE_BOOTLOADER 0 /* boot loader (for TX) */ +#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ +#define XCHAL_HAVE_VECTOR_SELECT 0 /* relocatable vectors */ +#define XCHAL_HAVE_VECBASE 0 /* relocatable vectors */ + +#define XCHAL_RESET_VECOFS 0x00000000 +#define XCHAL_RESET_VECTOR_VADDR 0x7F000000 +#define XCHAL_RESET_VECTOR_PADDR 0x7F000000 +#define XCHAL_USER_VECOFS 0x00000000 +#define XCHAL_USER_VECTOR_VADDR 0x7F000740 +#define XCHAL_USER_VECTOR_PADDR 0x7F000740 +#define XCHAL_KERNEL_VECOFS 0x00000000 +#define XCHAL_KERNEL_VECTOR_VADDR 0x7F000700 +#define XCHAL_KERNEL_VECTOR_PADDR 0x7F000700 +#define XCHAL_DOUBLEEXC_VECOFS 0x00000000 +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x7F0007C0 +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x7F0007C0 +#define XCHAL_WINDOW_OF4_VECOFS 0x00000000 +#define XCHAL_WINDOW_UF4_VECOFS 0x00000040 +#define XCHAL_WINDOW_OF8_VECOFS 0x00000080 +#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0 +#define XCHAL_WINDOW_OF12_VECOFS 0x00000100 +#define XCHAL_WINDOW_UF12_VECOFS 0x00000140 +#define XCHAL_WINDOW_VECTORS_VADDR 0x7F000400 +#define XCHAL_WINDOW_VECTORS_PADDR 0x7F000400 +#define XCHAL_INTLEVEL2_VECOFS 0x00000000 +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x7F000580 +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x7F000580 +#define XCHAL_INTLEVEL3_VECOFS 0x00000000 +#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x7F0005C0 +#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x7F0005C0 +#define XCHAL_INTLEVEL4_VECOFS 0x00000000 +#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x7F000600 +#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x7F000600 +#define XCHAL_INTLEVEL5_VECOFS 0x00000000 +#define XCHAL_INTLEVEL5_VECTOR_VADDR 0x7F000640 +#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x7F000640 +#define XCHAL_INTLEVEL6_VECOFS 0x00000000 +#define XCHAL_INTLEVEL6_VECTOR_VADDR 0x7F000680 +#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x7F000680 +#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS +#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR +#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR +#define XCHAL_NMI_VECOFS 0x00000000 +#define XCHAL_NMI_VECTOR_VADDR 0x7F0006C0 +#define XCHAL_NMI_VECTOR_PADDR 0x7F0006C0 +#define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS +#define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR +#define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR + + +/*---------------------------------------------------------------------- + DEBUG MODULE + ----------------------------------------------------------------------*/ + +/* Misc */ +#define XCHAL_HAVE_DEBUG_ERI 0 /* ERI to debug module */ +#define XCHAL_HAVE_DEBUG_APB 0 /* APB to debug module */ +#define XCHAL_HAVE_DEBUG_JTAG 1 /* JTAG to debug module */ + +/* On-Chip Debug (OCD) */ +#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ +#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */ +#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */ +#define XCHAL_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option (to LX4) */ +#define XCHAL_HAVE_OCD_LS32DDR 1 /* L32DDR/S32DDR (faster OCD) */ + +/* TRAX (in core) */ +#define XCHAL_HAVE_TRAX 0 /* TRAX in debug module */ +#define XCHAL_TRAX_MEM_SIZE 0 /* TRAX memory size in bytes */ +#define XCHAL_TRAX_MEM_SHAREABLE 0 /* start/end regs; ready sig. */ +#define XCHAL_TRAX_ATB_WIDTH 0 /* ATB width (bits), 0=no ATB */ +#define XCHAL_TRAX_TIME_WIDTH 0 /* timestamp bitwidth, 0=none */ + +/* Perf counters */ +#define XCHAL_NUM_PERF_COUNTERS 0 /* performance counters */ + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* See core-matmap.h header file for more details. */ + +#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ +#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ +#define XCHAL_SPANNING_WAY 0 /* TLB spanning way number */ +#define XCHAL_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */ +#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ +#define XCHAL_HAVE_MIMIC_CACHEATTR 1 /* region protection */ +#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ +#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table + [autorefill] and protection) + usable for an MMU-based OS */ + +/* If none of the above last 5 are set, it's a custom TLB configuration. */ + +#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */ +#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */ +#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */ + +/*---------------------------------------------------------------------- + MPU + ----------------------------------------------------------------------*/ +#define XCHAL_HAVE_MPU 0 +#define XCHAL_MPU_ENTRIES 0 + +#define XCHAL_MPU_ALIGN_REQ 1 /* MPU requires alignment of entries to background map */ +#define XCHAL_MPU_BACKGROUND_ENTRIES 0 /* number of entries in bg map*/ +#define XCHAL_MPU_BG_CACHEADRDIS 0 /* default CACHEADRDIS for bg */ + +#define XCHAL_MPU_ALIGN_BITS 0 +#define XCHAL_MPU_ALIGN 0 + +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + + +#endif /* _XTENSA_CORE_CONFIGURATION_H */ + diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/config/core-matmap.h b/src/platform/amd/rembrandt/include/arch/xtensa/config/core-matmap.h new file mode 100644 index 000000000000..dfac414b0092 --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/config/core-matmap.h @@ -0,0 +1,317 @@ +/* + * xtensa/config/core-matmap.h -- Memory access and translation mapping + * parameters (CHAL) of the Xtensa processor core configuration. + * + * If you are using Xtensa Tools, see (which includes + * this file) for more details. + * + * In the Xtensa processor products released to date, all parameters + * defined in this file are derivable (at least in theory) from + * information contained in the core-isa.h header file. + * In particular, the following core configuration parameters are relevant: + * XCHAL_HAVE_CACHEATTR + * XCHAL_HAVE_MIMIC_CACHEATTR + * XCHAL_HAVE_XLT_CACHEATTR + * XCHAL_HAVE_PTP_MMU + * XCHAL_ITLB_ARF_ENTRIES_LOG2 + * XCHAL_DTLB_ARF_ENTRIES_LOG2 + * XCHAL_DCACHE_IS_WRITEBACK + * XCHAL_ICACHE_SIZE (presence of I-cache) + * XCHAL_DCACHE_SIZE (presence of D-cache) + * XCHAL_HW_VERSION_MAJOR + * XCHAL_HW_VERSION_MINOR + */ + +/* Customer ID=12153; Build=0x878bf; Copyright (c) 1999-2020 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + +#ifndef XTENSA_CONFIG_CORE_MATMAP_H +#define XTENSA_CONFIG_CORE_MATMAP_H + + +/*---------------------------------------------------------------------- + CACHE (MEMORY ACCESS) ATTRIBUTES + ----------------------------------------------------------------------*/ + + + +/* Cache Attribute encodings -- lists of access modes for each cache attribute: */ +#define XCHAL_FCA_LIST XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION +#define XCHAL_LCA_LIST XTHAL_LAM_CACHED_NOALLOC XCHAL_SEP \ + XTHAL_LAM_CACHED XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_CACHED XCHAL_SEP \ + XTHAL_LAM_CACHED XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION +#define XCHAL_SCA_LIST XTHAL_SAM_WRITETHRU XCHAL_SEP \ + XTHAL_SAM_WRITETHRU XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_WRITEBACK XCHAL_SEP \ + XTHAL_SAM_WRITEBACK_NOALLOC XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION + +#define XCHAL_CA_R (0xC0 | 0x40000000) +#define XCHAL_CA_RX (0xD0 | 0x40000000) +#define XCHAL_CA_RW (0xE0 | 0x40000000) +#define XCHAL_CA_RWX (0xF0 | 0x40000000) + +/* + * Specific encoded cache attribute values of general interest. + * If a specific cache mode is not available, the closest available + * one is returned instead (eg. writethru instead of writeback, + * bypass instead of writethru). + */ +#define XCHAL_CA_BYPASS 2 /* cache disabled (bypassed) mode */ +#define XCHAL_CA_BYPASSBUF 6 /* cache disabled (bypassed) bufferable mode */ +#define XCHAL_CA_WRITETHRU 1 /* cache enabled (write-through) mode */ +#define XCHAL_CA_WRITEBACK 4 /* cache enabled (write-back) mode */ +#define XCHAL_HAVE_CA_WRITEBACK_NOALLOC 1 /* write-back no-allocate availability */ +#define XCHAL_CA_WRITEBACK_NOALLOC 5 /* cache enabled (write-back no-allocate) mode */ +#define XCHAL_CA_ILLEGAL 15 /* no access allowed (all cause exceptions) mode */ + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* + * General notes on MMU parameters. + * + * Terminology: + * ASID = address-space ID (acts as an "extension" of virtual addresses) + * VPN = virtual page number + * PPN = physical page number + * CA = encoded cache attribute (access modes) + * TLB = translation look-aside buffer (term is stretched somewhat here) + * I = instruction (fetch accesses) + * D = data (load and store accesses) + * way = each TLB (ITLB and DTLB) consists of a number of "ways" + * that simultaneously match the virtual address of an access; + * a TLB successfully translates a virtual address if exactly + * one way matches the vaddr; if none match, it is a miss; + * if multiple match, one gets a "multihit" exception; + * each way can be independently configured in terms of number of + * entries, page sizes, which fields are writable or constant, etc. + * set = group of contiguous ways with exactly identical parameters + * ARF = auto-refill; hardware services a 1st-level miss by loading a PTE + * from the page table and storing it in one of the auto-refill ways; + * if this PTE load also misses, a miss exception is posted for s/w. + * min-wired = a "min-wired" way can be used to map a single (minimum-sized) + * page arbitrarily under program control; it has a single entry, + * is non-auto-refill (some other way(s) must be auto-refill), + * all its fields (VPN, PPN, ASID, CA) are all writable, and it + * supports the XCHAL_MMU_MIN_PTE_PAGE_SIZE page size (a current + * restriction is that this be the only page size it supports). + * + * TLB way entries are virtually indexed. + * TLB ways that support multiple page sizes: + * - must have all writable VPN and PPN fields; + * - can only use one page size at any given time (eg. setup at startup), + * selected by the respective ITLBCFG or DTLBCFG special register, + * whose bits n*4+3 .. n*4 index the list of page sizes for way n + * (XCHAL_xTLB_SETm_PAGESZ_LOG2_LIST for set m corresponding to way n); + * this list may be sparse for auto-refill ways because auto-refill + * ways have independent lists of supported page sizes sharing a + * common encoding with PTE entries; the encoding is the index into + * this list; unsupported sizes for a given way are zero in the list; + * selecting unsupported sizes results in undefine hardware behaviour; + * - is only possible for ways 0 thru 7 (due to ITLBCFG/DTLBCFG definition). + */ + +#define XCHAL_MMU_ASID_INVALID 0 /* ASID value indicating invalid address space */ +#define XCHAL_MMU_ASID_KERNEL 0 /* ASID value indicating kernel (ring 0) address space */ +#define XCHAL_MMU_SR_BITS 0 /* number of size-restriction bits supported */ +#define XCHAL_MMU_CA_BITS 4 /* number of bits needed to hold cache attribute encoding */ +#define XCHAL_MMU_MAX_PTE_PAGE_SIZE 29 /* max page size in a PTE structure (log2) */ +#define XCHAL_MMU_MIN_PTE_PAGE_SIZE 29 /* min page size in a PTE structure (log2) */ + + +/*** Instruction TLB: ***/ + +#define XCHAL_ITLB_WAY_BITS 0 /* number of bits holding the ways */ +#define XCHAL_ITLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ +#define XCHAL_ITLB_ARF_WAYS 0 /* number of auto-refill ways */ +#define XCHAL_ITLB_SETS 1 /* number of sets (groups of ways with identical settings) */ + +/* Way set to which each way belongs: */ +#define XCHAL_ITLB_WAY0_SET 0 + +/* Ways sets that are used by hardware auto-refill (ARF): */ +#define XCHAL_ITLB_ARF_SETS 0 /* number of auto-refill sets */ + +/* Way sets that are "min-wired" (see terminology comment above): */ +#define XCHAL_ITLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ + + +/* ITLB way set 0 (group of ways 0 thru 0): */ +#define XCHAL_ITLB_SET0_WAY 0 /* index of first way in this way set */ +#define XCHAL_ITLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ +#define XCHAL_ITLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ +#define XCHAL_ITLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ +#define XCHAL_ITLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ +#define XCHAL_ITLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ +#define XCHAL_ITLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; + 2^PAGESZ_BITS entries in list, unsupported entries are zero */ +#define XCHAL_ITLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_PPN_CONSTMASK 0xE0000000 /* constant PPN bits, including entry index bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ +/* Constant VPN values for each entry of ITLB way set 0 (because VPN_CONSTMASK is non-zero): */ +#define XCHAL_ITLB_SET0_E0_VPN_CONST 0x00000000 +#define XCHAL_ITLB_SET0_E1_VPN_CONST 0x20000000 +#define XCHAL_ITLB_SET0_E2_VPN_CONST 0x40000000 +#define XCHAL_ITLB_SET0_E3_VPN_CONST 0x60000000 +#define XCHAL_ITLB_SET0_E4_VPN_CONST 0x80000000 +#define XCHAL_ITLB_SET0_E5_VPN_CONST 0xA0000000 +#define XCHAL_ITLB_SET0_E6_VPN_CONST 0xC0000000 +#define XCHAL_ITLB_SET0_E7_VPN_CONST 0xE0000000 +/* Constant PPN values for each entry of ITLB way set 0 (because PPN_CONSTMASK is non-zero): */ +#define XCHAL_ITLB_SET0_E0_PPN_CONST 0x00000000 +#define XCHAL_ITLB_SET0_E1_PPN_CONST 0x20000000 +#define XCHAL_ITLB_SET0_E2_PPN_CONST 0x40000000 +#define XCHAL_ITLB_SET0_E3_PPN_CONST 0x60000000 +#define XCHAL_ITLB_SET0_E4_PPN_CONST 0x80000000 +#define XCHAL_ITLB_SET0_E5_PPN_CONST 0xA0000000 +#define XCHAL_ITLB_SET0_E6_PPN_CONST 0xC0000000 +#define XCHAL_ITLB_SET0_E7_PPN_CONST 0xE0000000 +/* Reset CA values for each entry of ITLB way set 0 (because SET0_CA_RESET is non-zero): */ +#define XCHAL_ITLB_SET0_E0_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E1_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E2_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E3_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E4_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E5_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E6_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E7_CA_RESET 0x02 + + +/*** Data TLB: ***/ + +#define XCHAL_DTLB_WAY_BITS 0 /* number of bits holding the ways */ +#define XCHAL_DTLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ +#define XCHAL_DTLB_ARF_WAYS 0 /* number of auto-refill ways */ +#define XCHAL_DTLB_SETS 1 /* number of sets (groups of ways with identical settings) */ + +/* Way set to which each way belongs: */ +#define XCHAL_DTLB_WAY0_SET 0 + +/* Ways sets that are used by hardware auto-refill (ARF): */ +#define XCHAL_DTLB_ARF_SETS 0 /* number of auto-refill sets */ + +/* Way sets that are "min-wired" (see terminology comment above): */ +#define XCHAL_DTLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ + + +/* DTLB way set 0 (group of ways 0 thru 0): */ +#define XCHAL_DTLB_SET0_WAY 0 /* index of first way in this way set */ +#define XCHAL_DTLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ +#define XCHAL_DTLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ +#define XCHAL_DTLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ +#define XCHAL_DTLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ +#define XCHAL_DTLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ +#define XCHAL_DTLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; + 2^PAGESZ_BITS entries in list, unsupported entries are zero */ +#define XCHAL_DTLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_PPN_CONSTMASK 0xE0000000 /* constant PPN bits, including entry index bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ +/* Constant VPN values for each entry of DTLB way set 0 (because VPN_CONSTMASK is non-zero): */ +#define XCHAL_DTLB_SET0_E0_VPN_CONST 0x00000000 +#define XCHAL_DTLB_SET0_E1_VPN_CONST 0x20000000 +#define XCHAL_DTLB_SET0_E2_VPN_CONST 0x40000000 +#define XCHAL_DTLB_SET0_E3_VPN_CONST 0x60000000 +#define XCHAL_DTLB_SET0_E4_VPN_CONST 0x80000000 +#define XCHAL_DTLB_SET0_E5_VPN_CONST 0xA0000000 +#define XCHAL_DTLB_SET0_E6_VPN_CONST 0xC0000000 +#define XCHAL_DTLB_SET0_E7_VPN_CONST 0xE0000000 +/* Constant PPN values for each entry of DTLB way set 0 (because PPN_CONSTMASK is non-zero): */ +#define XCHAL_DTLB_SET0_E0_PPN_CONST 0x00000000 +#define XCHAL_DTLB_SET0_E1_PPN_CONST 0x20000000 +#define XCHAL_DTLB_SET0_E2_PPN_CONST 0x40000000 +#define XCHAL_DTLB_SET0_E3_PPN_CONST 0x60000000 +#define XCHAL_DTLB_SET0_E4_PPN_CONST 0x80000000 +#define XCHAL_DTLB_SET0_E5_PPN_CONST 0xA0000000 +#define XCHAL_DTLB_SET0_E6_PPN_CONST 0xC0000000 +#define XCHAL_DTLB_SET0_E7_PPN_CONST 0xE0000000 +/* Reset CA values for each entry of DTLB way set 0 (because SET0_CA_RESET is non-zero): */ +#define XCHAL_DTLB_SET0_E0_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E1_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E2_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E3_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E4_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E5_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E6_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E7_CA_RESET 0x02 + + + + +#endif /*XTENSA_CONFIG_CORE_MATMAP_H*/ + diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/config/defs.h b/src/platform/amd/rembrandt/include/arch/xtensa/config/defs.h new file mode 100644 index 000000000000..0da4586ce0d3 --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/config/defs.h @@ -0,0 +1,38 @@ +/* Definitions for Xtensa instructions, types, and protos. */ + +/* Customer ID=12153; Build=0x878bf; Copyright (c) 2003-2004 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* NOTE: This file exists only for backward compatibility with T1050 + and earlier Xtensa releases. It includes only a subset of the + available header files. */ + +#ifndef _XTENSA_BASE_HEADER +#define _XTENSA_BASE_HEADER + +#ifdef __XTENSA__ + +#include +#include +#include + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_BASE_HEADER */ diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/config/specreg.h b/src/platform/amd/rembrandt/include/arch/xtensa/config/specreg.h new file mode 100644 index 000000000000..bac44571c963 --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/config/specreg.h @@ -0,0 +1,108 @@ +/* + * Xtensa Special Register symbolic names + */ + +/* $Id: //depot/rel/Homewood/ib.1/Xtensa/SWConfig/hal/specreg.h.tpp#1 $ */ + +/* Customer ID=12153; Build=0x878bf; Copyright (c) 1998-2002 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef XTENSA_SPECREG_H +#define XTENSA_SPECREG_H + +/* Include these special register bitfield definitions, for historical reasons: */ +#include + + +/* Special registers: */ +#define LBEG 0 +#define LEND 1 +#define LCOUNT 2 +#define SAR 3 +#define BR 4 +#define SCOMPARE1 12 +#define PREFCTL 40 +#define WINDOWBASE 72 +#define WINDOWSTART 73 +#define IBREAKENABLE 96 +#define MEMCTL 97 +#define ATOMCTL 99 +#define DDR 104 +#define IBREAKA_0 128 +#define IBREAKA_1 129 +#define DBREAKA_0 144 +#define DBREAKA_1 145 +#define DBREAKC_0 160 +#define DBREAKC_1 161 +#define EPC_1 177 +#define EPC_2 178 +#define EPC_3 179 +#define EPC_4 180 +#define EPC_5 181 +#define EPC_6 182 +#define EPC_7 183 +#define DEPC 192 +#define EPS_2 194 +#define EPS_3 195 +#define EPS_4 196 +#define EPS_5 197 +#define EPS_6 198 +#define EPS_7 199 +#define EXCSAVE_1 209 +#define EXCSAVE_2 210 +#define EXCSAVE_3 211 +#define EXCSAVE_4 212 +#define EXCSAVE_5 213 +#define EXCSAVE_6 214 +#define EXCSAVE_7 215 +#define CPENABLE 224 +#define INTERRUPT 226 +#define INTENABLE 228 +#define PS 230 +#define EXCCAUSE 232 +#define DEBUGCAUSE 233 +#define CCOUNT 234 +#define PRID 235 +#define ICOUNT 236 +#define ICOUNTLEVEL 237 +#define EXCVADDR 238 +#define CCOMPARE_0 240 +#define CCOMPARE_1 241 +#define MISC_REG_0 244 +#define MISC_REG_1 245 + + +/* Special cases (bases of special register series): */ +#define IBREAKA 128 +#define DBREAKA 144 +#define DBREAKC 160 +#define EPC 176 +#define EPS 192 +#define EXCSAVE 208 +#define CCOMPARE 240 + +/* Special names for read-only and write-only interrupt registers: */ +#define INTREAD 226 +#define INTSET 226 +#define INTCLEAR 227 + +#endif /* XTENSA_SPECREG_H */ + diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/config/system.h b/src/platform/amd/rembrandt/include/arch/xtensa/config/system.h new file mode 100644 index 000000000000..46ddf9d302a0 --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/config/system.h @@ -0,0 +1,262 @@ +/* + * xtensa/config/system.h -- HAL definitions that are dependent on SYSTEM configuration + * + * NOTE: The location and contents of this file are highly subject to change. + * + * Source for configuration-independent binaries (which link in a + * configuration-specific HAL library) must NEVER include this file. + * The HAL itself has historically included this file in some instances, + * but this is not appropriate either, because the HAL is meant to be + * core-specific but system independent. + */ + +/* Customer ID=12153; Build=0x878bf; Copyright (c) 2000-2010 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + +#ifndef XTENSA_CONFIG_SYSTEM_H +#define XTENSA_CONFIG_SYSTEM_H + + +/*---------------------------------------------------------------------- + CONFIGURED SOFTWARE OPTIONS + ----------------------------------------------------------------------*/ + +#define XSHAL_USE_ABSOLUTE_LITERALS 0 /* (sw-only option, whether software uses absolute literals) */ +#define XSHAL_HAVE_TEXT_SECTION_LITERALS 1 /* Set if there is some memory that allows both code and literals. */ + +#define XSHAL_ABI XTHAL_ABI_WINDOWED /* (sw-only option, selected ABI) */ +/* The above maps to one of the following constants: */ +#define XTHAL_ABI_WINDOWED 0 +#define XTHAL_ABI_CALL0 1 + +#define XSHAL_CLIB XTHAL_CLIB_XCLIB /* (sw-only option, selected C library) */ +/* The above maps to one of the following constants: */ +#define XTHAL_CLIB_NEWLIB 0 +#define XTHAL_CLIB_UCLIBC 1 +#define XTHAL_CLIB_XCLIB 2 + +#define XSHAL_USE_FLOATING_POINT 1 + +#define XSHAL_FLOATING_POINT_ABI 1 + +/* SW workarounds enabled for HW errata: */ + +/*---------------------------------------------------------------------- + DEVICE ADDRESSES + ----------------------------------------------------------------------*/ + +/* + * Strange place to find these, but the configuration GUI + * allows moving these around to account for various core + * configurations. Specific boards (and their BSP software) + * will have specific meanings for these components. + */ + +/* I/O Block areas: */ +#define XSHAL_IOBLOCK_CACHED_VADDR 0x70000000 +#define XSHAL_IOBLOCK_CACHED_PADDR 0x70000000 +#define XSHAL_IOBLOCK_CACHED_SIZE 0x0E000000 + +#define XSHAL_IOBLOCK_BYPASS_VADDR 0x90000000 +#define XSHAL_IOBLOCK_BYPASS_PADDR 0x90000000 +#define XSHAL_IOBLOCK_BYPASS_SIZE 0x0E000000 + +/* System ROM: */ +#define XSHAL_ROM_VADDR 0x50000000 +#define XSHAL_ROM_PADDR 0x50000000 +#define XSHAL_ROM_SIZE 0x00020000 +/* Largest available area (free of vectors): */ +#define XSHAL_ROM_AVAIL_VADDR 0x50000000 +#define XSHAL_ROM_AVAIL_VSIZE 0x00020000 + +/* System RAM: */ +#define XSHAL_RAM_VADDR 0x60000000 +#define XSHAL_RAM_PADDR 0x60000000 +#define XSHAL_RAM_VSIZE 0x1F000000 +#define XSHAL_RAM_PSIZE 0x1F000000 +#define XSHAL_RAM_SIZE XSHAL_RAM_PSIZE +/* Largest available area (free of vectors): */ +#define XSHAL_RAM_AVAIL_VADDR 0x60000000 +#define XSHAL_RAM_AVAIL_VSIZE 0x1F000000 + +/* + * Shadow system RAM (same device as system RAM, at different address). + * (Emulation boards need this for the SONIC Ethernet driver + * when data caches are configured for writeback mode.) + * NOTE: on full MMU configs, this points to the BYPASS virtual address + * of system RAM, ie. is the same as XSHAL_RAM_* except that virtual + * addresses are viewed through the BYPASS static map rather than + * the CACHED static map. + */ +#define XSHAL_RAM_BYPASS_VADDR 0x20000000 +#define XSHAL_RAM_BYPASS_PADDR 0x20000000 +#define XSHAL_RAM_BYPASS_PSIZE 0x1F000000 + +/* Alternate system RAM (different device than system RAM): */ + +/* Some available location in which to place devices in a simulation (eg. XTMP): */ +#define XSHAL_SIMIO_CACHED_VADDR 0xC0000000 +#define XSHAL_SIMIO_BYPASS_VADDR 0xC0000000 +#define XSHAL_SIMIO_PADDR 0xC0000000 +#define XSHAL_SIMIO_SIZE 0x20000000 + + +/*---------------------------------------------------------------------- + * For use by reference testbench exit and diagnostic routines. + */ +#define XSHAL_MAGIC_EXIT 0xc0000000 +#define XSHAL_STL_INFO_LOCATION 0x54 + +/*---------------------------------------------------------------------- + * DEVICE-ADDRESS DEPENDENT... + * + * Values written to CACHEATTR special register (or its equivalent) + * to enable and disable caches in various modes. + *----------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------- + BACKWARD COMPATIBILITY ... + ----------------------------------------------------------------------*/ + +/* + * NOTE: the following two macros are DEPRECATED. Use the latter + * board-specific macros instead, which are specially tuned for the + * particular target environments' memory maps. + */ +#define XSHAL_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS /* disable caches in bypass mode */ +#define XSHAL_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT /* default setting to enable caches (no writeback!) */ + +/*---------------------------------------------------------------------- + GENERIC + ----------------------------------------------------------------------*/ + +/* For the following, a 512MB region is used if it contains a system (PIF) RAM, + * system (PIF) ROM, local memory, or XLMI. */ + +/* These set any unused 512MB region to cache-BYPASS attribute: */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEBACK 0x42224422 /* enable caches in write-back mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEALLOC 0x12221122 /* enable caches in write-allocate mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITETHRU 0x12221122 /* enable caches in write-through mode */ +#define XSHAL_ALLVALID_CACHEATTR_BYPASS 0x22222222 /* disable caches in bypass mode */ +#define XSHAL_ALLVALID_CACHEATTR_DEFAULT XSHAL_ALLVALID_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/* These set any unused 512MB region to ILLEGAL attribute: */ +#define XSHAL_STRICT_CACHEATTR_WRITEBACK 0x4FFF44FF /* enable caches in write-back mode */ +#define XSHAL_STRICT_CACHEATTR_WRITEALLOC 0x1FFF11FF /* enable caches in write-allocate mode */ +#define XSHAL_STRICT_CACHEATTR_WRITETHRU 0x1FFF11FF /* enable caches in write-through mode */ +#define XSHAL_STRICT_CACHEATTR_BYPASS 0x2FFF22FF /* disable caches in bypass mode */ +#define XSHAL_STRICT_CACHEATTR_DEFAULT XSHAL_STRICT_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/* These set the first 512MB, if unused, to ILLEGAL attribute to help catch + * NULL-pointer dereference bugs; all other unused 512MB regions are set + * to cache-BYPASS attribute: */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEBACK 0x4222442F /* enable caches in write-back mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC 0x1222112F /* enable caches in write-allocate mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITETHRU 0x1222112F /* enable caches in write-through mode */ +#define XSHAL_TRAPNULL_CACHEATTR_BYPASS 0x2222222F /* disable caches in bypass mode */ +#define XSHAL_TRAPNULL_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/*---------------------------------------------------------------------- + ISS (Instruction Set Simulator) SPECIFIC ... + ----------------------------------------------------------------------*/ + +/* For now, ISS defaults to the TRAPNULL settings: */ +#define XSHAL_ISS_CACHEATTR_WRITEBACK XSHAL_TRAPNULL_CACHEATTR_WRITEBACK +#define XSHAL_ISS_CACHEATTR_WRITEALLOC XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC +#define XSHAL_ISS_CACHEATTR_WRITETHRU XSHAL_TRAPNULL_CACHEATTR_WRITETHRU +#define XSHAL_ISS_CACHEATTR_BYPASS XSHAL_TRAPNULL_CACHEATTR_BYPASS +#define XSHAL_ISS_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK + +#define XSHAL_ISS_PIPE_REGIONS 0 +#define XSHAL_ISS_SDRAM_REGIONS 0 + + +/*---------------------------------------------------------------------- + XT2000 BOARD SPECIFIC ... + ----------------------------------------------------------------------*/ + +/* For the following, a 512MB region is used if it contains any system RAM, + * system ROM, local memory, XLMI, or other XT2000 board device or memory. + * Regions containing devices are forced to cache-BYPASS mode regardless + * of whether the macro is _WRITEBACK vs. _BYPASS etc. */ + +/* These set any 512MB region unused on the XT2000 to ILLEGAL attribute: */ +#define XSHAL_XT2000_CACHEATTR_WRITEBACK 0x4FF2442F /* enable caches in write-back mode */ +#define XSHAL_XT2000_CACHEATTR_WRITEALLOC 0x1FF2112F /* enable caches in write-allocate mode */ +#define XSHAL_XT2000_CACHEATTR_WRITETHRU 0x1FF2112F /* enable caches in write-through mode */ +#define XSHAL_XT2000_CACHEATTR_BYPASS 0x2FF2222F /* disable caches in bypass mode */ +#define XSHAL_XT2000_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +#define XSHAL_XT2000_PIPE_REGIONS 0x00000000 /* BusInt pipeline regions */ +#define XSHAL_XT2000_SDRAM_REGIONS 0x00000044 /* BusInt SDRAM regions */ + + +/*---------------------------------------------------------------------- + VECTOR INFO AND SIZES + ----------------------------------------------------------------------*/ + +#define XSHAL_VECTORS_PACKED 0 /* UNUSED */ +#define XSHAL_STATIC_VECTOR_SELECT 0 +#define XSHAL_RESET_VECTOR_VADDR 0x7F000000 +#define XSHAL_RESET_VECTOR_PADDR 0x7F000000 + +/* + * Sizes allocated to vectors by the system (memory map) configuration. + * These sizes are constrained by core configuration (eg. one vector's + * code cannot overflow into another vector) but are dependent on the + * system or board (or LSP) memory map configuration. + * + * Whether or not each vector happens to be in a system ROM is also + * a system configuration matter, sometimes useful, included here also: + */ +#define XSHAL_RESET_VECTOR_SIZE 0x00000300 +#define XSHAL_RESET_VECTOR_ISROM 0 +#define XSHAL_USER_VECTOR_SIZE 0x00000038 +#define XSHAL_USER_VECTOR_ISROM 0 +#define XSHAL_PROGRAMEXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_USEREXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_KERNEL_VECTOR_SIZE 0x00000038 +#define XSHAL_KERNEL_VECTOR_ISROM 0 +#define XSHAL_STACKEDEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_KERNELEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_DOUBLEEXC_VECTOR_SIZE 0x00000040 +#define XSHAL_DOUBLEEXC_VECTOR_ISROM 0 +#define XSHAL_WINDOW_VECTORS_SIZE 0x00000178 +#define XSHAL_WINDOW_VECTORS_ISROM 0 +#define XSHAL_INTLEVEL2_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL2_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL3_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL3_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL4_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL4_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL5_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL5_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL6_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL6_VECTOR_ISROM 0 +#define XSHAL_DEBUG_VECTOR_SIZE XSHAL_INTLEVEL6_VECTOR_SIZE +#define XSHAL_DEBUG_VECTOR_ISROM XSHAL_INTLEVEL6_VECTOR_ISROM +#define XSHAL_NMI_VECTOR_SIZE 0x00000038 +#define XSHAL_NMI_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL7_VECTOR_SIZE XSHAL_NMI_VECTOR_SIZE + +#endif /*XTENSA_CONFIG_SYSTEM_H*/ + diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/config/tie-asm.h b/src/platform/amd/rembrandt/include/arch/xtensa/config/tie-asm.h new file mode 100644 index 000000000000..9ec7b495afd9 --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/config/tie-asm.h @@ -0,0 +1,366 @@ +/* + * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file contains assembly-language definitions (assembly + macros, etc.) for this specific Xtensa processor's TIE extensions + and options. It is customized to this Xtensa processor configuration. + + Customer ID=12153; Build=0x878bf; Copyright (c) 1999-2020 Cadence Design Systems Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _XTENSA_CORE_TIE_ASM_H +#define _XTENSA_CORE_TIE_ASM_H + +#include + +/* Selection parameter values for save-area save/restore macros: */ +/* Option vs. TIE: */ +#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ +#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ +#define XTHAL_SAS_ANYOT 0x0003 /* both of the above */ +/* Whether used automatically by compiler: */ +#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ +#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ +#define XTHAL_SAS_ANYCC 0x000C /* both of the above */ +/* ABI handling across function calls: */ +#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ +#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ +#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ +#define XTHAL_SAS_ANYABI 0x0070 /* all of the above three */ +/* Misc */ +#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ +#define XTHAL_SAS3(optie,ccuse,abi) ( ((optie) & XTHAL_SAS_ANYOT) \ + | ((ccuse) & XTHAL_SAS_ANYCC) \ + | ((abi) & XTHAL_SAS_ANYABI) ) + + + /* + * Macro to store all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 4 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_NCP_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters: + * continue If macro invoked as part of a larger store sequence, set to 1 + * if this is not the first in the sequence. Defaults to 0. + * ofs Offset from start of larger sequence (from value of first ptr + * in sequence) at which to store. Defaults to next available space + * (or 0 if is 0). + * select Select what category(ies) of registers to store, as a bitmask + * (see XTHAL_SAS_xxx constants). Defaults to all registers. + * alloc Select what category(ies) of registers to allocate; if any + * category is selected here that is not in , space for + * the corresponding registers is skipped without doing any load. + */ + .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Optional global registers used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\select) + xchal_sa_align \ptr, 0, 1016, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wur.threadptr \at1 // threadptr option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1016, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + // Optional caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 1012, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wsr.br \at1 // boolean option + l32i \at1, \ptr, .Lxchal_ofs_+4 + wsr.scompare1 \at1 // conditional store option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1012, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .endif + .endm // xchal_ncp_load + + +#define XCHAL_NCP_NUM_ATMPS 1 + + /* + * Macro to store the state of TIE coprocessor AudioEngineLX. + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 16 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_CP1_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters are the same as for xchal_ncp_store. + */ +#define xchal_cp_AudioEngineLX_store xchal_cp1_store + .macro xchal_cp1_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Custom caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 0, 16, 16 + ae_s64.i aed0, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed1, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed2, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed3, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed4, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed5, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed6, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed7, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed8, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed9, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed10, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed11, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed12, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed13, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed14, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed15, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed16, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed17, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed18, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed19, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed20, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed21, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed22, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed23, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed24, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed25, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed26, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed27, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed28, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed29, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed30, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed31, \ptr, .Lxchal_ofs_+48 + ae_movae \at1, aep0 + s8i \at1, \ptr, .Lxchal_ofs_+56 + ae_movae \at1, aep1 + s8i \at1, \ptr, .Lxchal_ofs_+57 + ae_movae \at1, aep2 + s8i \at1, \ptr, .Lxchal_ofs_+58 + ae_movae \at1, aep3 + s8i \at1, \ptr, .Lxchal_ofs_+59 + addi.a \ptr, \ptr, 64 + ae_salign128.i u0, \ptr, .Lxchal_ofs_+0 + ae_salign128.i u1, \ptr, .Lxchal_ofs_+16 + ae_salign128.i u2, \ptr, .Lxchal_ofs_+32 + ae_salign128.i u3, \ptr, .Lxchal_ofs_+48 + addi.a \ptr, \ptr, -320 + ae_movdrzbvc aed0 // ureg AE_ZBIASV8C + ae_s64.i aed0, \ptr, .Lxchal_ofs_+0 + 0 + ae_movvfcrfsr aed0 // ureg FCR_FSR + ae_s64.i aed0, \ptr, .Lxchal_ofs_+8 + 0 + rur.ae_ovf_sar \at1 // ureg 240 + s32i \at1, \ptr, .Lxchal_ofs_+16 + rur.ae_bithead \at1 // ureg 241 + s32i \at1, \ptr, .Lxchal_ofs_+20 + rur.ae_ts_fts_bu_bp \at1 // ureg 242 + s32i \at1, \ptr, .Lxchal_ofs_+24 + rur.ae_cw_sd_no \at1 // ureg 243 + s32i \at1, \ptr, .Lxchal_ofs_+28 + rur.ae_cbegin0 \at1 // ureg 246 + s32i \at1, \ptr, .Lxchal_ofs_+32 + rur.ae_cend0 \at1 // ureg 247 + s32i \at1, \ptr, .Lxchal_ofs_+36 + rur.ae_cbegin1 \at1 // ureg 248 + s32i \at1, \ptr, .Lxchal_ofs_+40 + rur.ae_cend1 \at1 // ureg 249 + s32i \at1, \ptr, .Lxchal_ofs_+44 + rur.ae_cbegin2 \at1 // ureg 250 + s32i \at1, \ptr, .Lxchal_ofs_+48 + rur.ae_cend2 \at1 // ureg 251 + s32i \at1, \ptr, .Lxchal_ofs_+52 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 384 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 16, 16 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 384 + .endif + .endm // xchal_cp1_store + + /* + * Macro to load the state of TIE coprocessor AudioEngineLX. + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 16 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_CP1_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters are the same as for xchal_ncp_load. + */ +#define xchal_cp_AudioEngineLX_load xchal_cp1_load + .macro xchal_cp1_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Custom caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 0, 16, 16 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+0 + 0 // ureg AE_ZBIASV8C + ae_movzbvcdr aed0 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+8 + 0 // ureg FCR_FSR + ae_movfcrfsrv aed0 + l32i \at1, \ptr, .Lxchal_ofs_+16 + wur.ae_ovf_sar \at1 // ureg 240 + l32i \at1, \ptr, .Lxchal_ofs_+20 + wur.ae_bithead \at1 // ureg 241 + l32i \at1, \ptr, .Lxchal_ofs_+24 + wur.ae_ts_fts_bu_bp \at1 // ureg 242 + l32i \at1, \ptr, .Lxchal_ofs_+28 + wur.ae_cw_sd_no \at1 // ureg 243 + l32i \at1, \ptr, .Lxchal_ofs_+32 + wur.ae_cbegin0 \at1 // ureg 246 + l32i \at1, \ptr, .Lxchal_ofs_+36 + wur.ae_cend0 \at1 // ureg 247 + l32i \at1, \ptr, .Lxchal_ofs_+40 + wur.ae_cbegin1 \at1 // ureg 248 + l32i \at1, \ptr, .Lxchal_ofs_+44 + wur.ae_cend1 \at1 // ureg 249 + l32i \at1, \ptr, .Lxchal_ofs_+48 + wur.ae_cbegin2 \at1 // ureg 250 + l32i \at1, \ptr, .Lxchal_ofs_+52 + wur.ae_cend2 \at1 // ureg 251 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed1, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed2, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed3, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed4, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed5, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed6, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed7, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed8, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed9, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed10, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed11, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed12, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed13, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed14, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed15, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed16, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed17, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed18, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed19, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed20, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed21, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed22, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed23, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed24, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed25, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed26, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed27, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed28, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed29, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed30, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed31, \ptr, .Lxchal_ofs_+48 + addi.a \ptr, \ptr, 56 + l8ui \at1, \ptr, .Lxchal_ofs_+0 + ae_movea aep0, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+1 + ae_movea aep1, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+2 + ae_movea aep2, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+3 + ae_movea aep3, \at1 + addi.a \ptr, \ptr, 8 + ae_lalign128.i u0, \ptr, .Lxchal_ofs_+0 + ae_lalign128.i u1, \ptr, .Lxchal_ofs_+16 + ae_lalign128.i u2, \ptr, .Lxchal_ofs_+32 + ae_lalign128.i u3, \ptr, .Lxchal_ofs_+48 + .set .Lxchal_pofs_, .Lxchal_pofs_ + 320 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 64 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 16, 16 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 384 + .endif + .endm // xchal_cp1_load + +#define XCHAL_CP1_NUM_ATMPS 1 +#define XCHAL_SA_NUM_ATMPS 1 + + /* Empty macros for unconfigured coprocessors: */ + .macro xchal_cp0_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp0_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + +#endif /*_XTENSA_CORE_TIE_ASM_H*/ + diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/config/tie.h b/src/platform/amd/rembrandt/include/arch/xtensa/config/tie.h new file mode 100644 index 000000000000..760c76a78b4f --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/config/tie.h @@ -0,0 +1,211 @@ +/* + * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file describes this specific Xtensa processor's TIE extensions + that extend basic Xtensa core functionality. It is customized to this + Xtensa processor configuration. + + Customer ID=12153; Build=0x878bf; Copyright (c) 1999-2020 Cadence Design Systems Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef XTENSA_CORE_TIE_H +#define XTENSA_CORE_TIE_H + +/* parasoft-begin-suppress ALL "This file not MISRA checked." */ + +#define XCHAL_CP_NUM 1 /* number of coprocessors */ +#define XCHAL_CP_MAX 2 /* max CP ID + 1 (0 if none) */ +#define XCHAL_CP_MASK 0x02 /* bitmask of all CPs by ID */ +#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ + +/* Basic parameters of each coprocessor: */ +#define XCHAL_CP1_NAME "AudioEngineLX" +#define XCHAL_CP1_IDENT AudioEngineLX +#define XCHAL_CP1_SA_SIZE 384 /* size of state save area */ +#define XCHAL_CP1_SA_ALIGN 16 /* min alignment of save area */ +#define XCHAL_CP_ID_AUDIOENGINELX 1 /* coprocessor ID (0..7) */ + +/* Filler info for unassigned coprocessors, to simplify arrays etc: */ +#define XCHAL_CP0_SA_SIZE 0 +#define XCHAL_CP0_SA_ALIGN 1 +#define XCHAL_CP2_SA_SIZE 0 +#define XCHAL_CP2_SA_ALIGN 1 +#define XCHAL_CP3_SA_SIZE 0 +#define XCHAL_CP3_SA_ALIGN 1 +#define XCHAL_CP4_SA_SIZE 0 +#define XCHAL_CP4_SA_ALIGN 1 +#define XCHAL_CP5_SA_SIZE 0 +#define XCHAL_CP5_SA_ALIGN 1 +#define XCHAL_CP6_SA_SIZE 0 +#define XCHAL_CP6_SA_ALIGN 1 +#define XCHAL_CP7_SA_SIZE 0 +#define XCHAL_CP7_SA_ALIGN 1 + +/* Save area for non-coprocessor optional and custom (TIE) state: */ +#define XCHAL_NCP_SA_SIZE 12 +#define XCHAL_NCP_SA_ALIGN 4 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 400 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 16 /* actual minimum alignment */ + +/* + * Detailed contents of save areas. + * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) + * before expanding the XCHAL_xxx_SA_LIST() macros. + * + * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, + * dbnum,base,regnum,bitsz,gapsz,reset,x...) + * + * s = passed from XCHAL_*_LIST(s), eg. to select how to expand + * ccused = set if used by compiler without special options or code + * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) + * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) + * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) + * name = lowercase reg name (no quotes) + * galign = group byte alignment (power of 2) (galign >= align) + * align = register byte alignment (power of 2) + * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) + * (not including any pad bytes required to galign this or next reg) + * dbnum = unique target number f/debug (see ) + * base = reg shortname w/o index (or sr=special, ur=TIE user reg) + * regnum = reg index in regfile, or special/TIE-user reg number + * bitsz = number of significant bits (regfile width, or ur/sr mask bits) + * gapsz = intervening bits, if bitsz bits not stored contiguously + * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) + * reset = register reset value (or 0 if undefined at reset) + * x = reserved for future use (0 until then) + * + * To filter out certain registers, e.g. to expand only the non-global + * registers used by the compiler, you can do something like this: + * + * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) + * #define SELCC0(p...) + * #define SELCC1(abikind,p...) SELAK##abikind(p) + * #define SELAK0(p...) REG(p) + * #define SELAK1(p...) REG(p) + * #define SELAK2(p...) + * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ + * ...what you want to expand... + */ + +#define XCHAL_NCP_SA_NUM 3 +#define XCHAL_NCP_SA_LIST(s) \ + XCHAL_SA_REG(s,1,2,1,1, threadptr, 4, 4, 4,0x03E7, ur,231, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, br, 4, 4, 4,0x0204, sr,4 , 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, scompare1, 4, 4, 4,0x020C, sr,12 , 32,0,0,0) + +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) /* empty */ + +#define XCHAL_CP1_SA_NUM 52 +#define XCHAL_CP1_SA_LIST(s) \ + XCHAL_SA_REG(s,0,0,1,0, ae_zbiasv8c,16, 8, 8,0x1029, ur,-1 , 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, fcr_fsr, 8, 8, 8,0x102A, ur,-1 , 7,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_ovf_sar, 4, 4, 4,0x03F0, ur,240, 15,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_bithead, 4, 4, 4,0x03F1, ur,241, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0,ae_ts_fts_bu_bp, 4, 4, 4,0x03F2, ur,242, 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cw_sd_no, 4, 4, 4,0x03F3, ur,243, 29,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin0, 4, 4, 4,0x03F6, ur,246, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend0, 4, 4, 4,0x03F7, ur,247, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin1, 4, 4, 4,0x03F8, ur,248, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend1, 4, 4, 4,0x03F9, ur,249, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin2, 4, 4, 4,0x03FA, ur,250, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend2, 4, 4, 4,0x03FB, ur,251, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed0, 8, 8, 8,0x1000, aed,0 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed1, 8, 8, 8,0x1001, aed,1 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed2, 8, 8, 8,0x1002, aed,2 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed3, 8, 8, 8,0x1003, aed,3 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed4, 8, 8, 8,0x1004, aed,4 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed5, 8, 8, 8,0x1005, aed,5 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed6, 8, 8, 8,0x1006, aed,6 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed7, 8, 8, 8,0x1007, aed,7 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed8, 8, 8, 8,0x1008, aed,8 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed9, 8, 8, 8,0x1009, aed,9 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed10, 8, 8, 8,0x100A, aed,10 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed11, 8, 8, 8,0x100B, aed,11 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed12, 8, 8, 8,0x100C, aed,12 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed13, 8, 8, 8,0x100D, aed,13 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed14, 8, 8, 8,0x100E, aed,14 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed15, 8, 8, 8,0x100F, aed,15 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed16, 8, 8, 8,0x1010, aed,16 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed17, 8, 8, 8,0x1011, aed,17 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed18, 8, 8, 8,0x1012, aed,18 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed19, 8, 8, 8,0x1013, aed,19 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed20, 8, 8, 8,0x1014, aed,20 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed21, 8, 8, 8,0x1015, aed,21 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed22, 8, 8, 8,0x1016, aed,22 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed23, 8, 8, 8,0x1017, aed,23 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed24, 8, 8, 8,0x1018, aed,24 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed25, 8, 8, 8,0x1019, aed,25 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed26, 8, 8, 8,0x101A, aed,26 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed27, 8, 8, 8,0x101B, aed,27 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed28, 8, 8, 8,0x101C, aed,28 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed29, 8, 8, 8,0x101D, aed,29 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed30, 8, 8, 8,0x101E, aed,30 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed31, 8, 8, 8,0x101F, aed,31 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep0, 1, 1, 1,0x1024, aep,0 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep1, 1, 1, 1,0x1025, aep,1 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep2, 1, 1, 1,0x1026, aep,2 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep3, 1, 1, 1,0x1027, aep,3 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u0,16,16,16,0x1020, u,0 ,128,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u1,16,16,16,0x1021, u,1 ,128,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u2,16,16,16,0x1022, u,2 ,128,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u3,16,16,16,0x1023, u,3 ,128,0,0,0) + +#define XCHAL_CP2_SA_NUM 0 +#define XCHAL_CP2_SA_LIST(s) /* empty */ + +#define XCHAL_CP3_SA_NUM 0 +#define XCHAL_CP3_SA_LIST(s) /* empty */ + +#define XCHAL_CP4_SA_NUM 0 +#define XCHAL_CP4_SA_LIST(s) /* empty */ + +#define XCHAL_CP5_SA_NUM 0 +#define XCHAL_CP5_SA_LIST(s) /* empty */ + +#define XCHAL_CP6_SA_NUM 0 +#define XCHAL_CP6_SA_LIST(s) /* empty */ + +#define XCHAL_CP7_SA_NUM 0 +#define XCHAL_CP7_SA_LIST(s) /* empty */ + +/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ +#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16 +/* Byte length of instruction from its first byte, per FLIX. */ +#define XCHAL_BYTE0_FORMAT_LENGTHS \ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16 + +/* parasoft-end-suppress ALL "This file not MISRA checked." */ + +#endif /* XTENSA_CORE_TIE_H */ + diff --git a/src/platform/amd/rembrandt/include/arch/xtensa/tie/xt_datacache.h b/src/platform/amd/rembrandt/include/arch/xtensa/tie/xt_datacache.h new file mode 100644 index 000000000000..8e83064e2923 --- /dev/null +++ b/src/platform/amd/rembrandt/include/arch/xtensa/tie/xt_datacache.h @@ -0,0 +1,132 @@ +// Customer ID=12153; Build=0x878bf; Copyright (c) 2017 Cadence Design Systems, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +/* Definitions for the xt_datacache TIE package */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_datacache_HEADER +#define _XTENSA_xt_datacache_HEADER + +/* parasoft-begin-suppress ALL "This file not MISRA checked." */ + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#ifndef _ASMLANGUAGE +#ifndef _NOCLANGUAGE +#ifndef __ASSEMBLER__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_datacache_DHI(const int * s, immediate i); +extern void _TIE_xt_datacache_DHI_B(const int * s, int i); +extern void _TIE_xt_datacache_DHU(const int * s, immediate i); +extern void _TIE_xt_datacache_DHWB(const int * s, immediate i); +extern void _TIE_xt_datacache_DHWBI(const int * s, immediate i); +extern void _TIE_xt_datacache_DHWBI_B(const int * s, int i); +extern void _TIE_xt_datacache_DHWB_B(const int * s, int i); +extern void _TIE_xt_datacache_DII(const int * s, immediate i); +extern void _TIE_xt_datacache_DIU(const int * s, immediate i); +extern void _TIE_xt_datacache_DIWB(const int * s, immediate i); +extern void _TIE_xt_datacache_DIWBI(const int * s, immediate i); +extern void _TIE_xt_datacache_DIWBUI_P(const int * s /*inout*/); +extern void _TIE_xt_datacache_DPFL(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFM_B(const int * s, int i); +extern void _TIE_xt_datacache_DPFM_BF(const int * s, int i); +extern void _TIE_xt_datacache_DPFR(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFRO(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFR_B(const int * s, int i); +extern void _TIE_xt_datacache_DPFR_BF(const int * s, int i); +extern void _TIE_xt_datacache_DPFW(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFWO(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFW_B(const int * s, int i); +extern void _TIE_xt_datacache_DPFW_BF(const int * s, int i); +extern int _TIE_xt_datacache_LDCT(const int * s); +extern int _TIE_xt_datacache_LDCW(const int * s); +extern void _TIE_xt_datacache_PFEND_A(void); +extern void _TIE_xt_datacache_PFEND_O(void); +extern void _TIE_xt_datacache_PFNXT_F(void); +extern void _TIE_xt_datacache_PFWAIT_A(void); +extern void _TIE_xt_datacache_PFWAIT_R(void); +extern void _TIE_xt_datacache_SDCT(int t, int * s); +extern void _TIE_xt_datacache_SDCW(int t, int * s); + +#endif /*__ASSEMBLER__*/ +#endif /*_NOCLANGUAGE*/ +#endif /*_ASMLANGUAGE*/ + +#define XT_DHI _TIE_xt_datacache_DHI +#define XT_DHI_B _TIE_xt_datacache_DHI_B +#define XT_DHU _TIE_xt_datacache_DHU +#define XT_DHWB _TIE_xt_datacache_DHWB +#define XT_DHWBI _TIE_xt_datacache_DHWBI +#define XT_DHWBI_B _TIE_xt_datacache_DHWBI_B +#define XT_DHWB_B _TIE_xt_datacache_DHWB_B +#define XT_DII _TIE_xt_datacache_DII +#define XT_DIU _TIE_xt_datacache_DIU +#define XT_DIWB _TIE_xt_datacache_DIWB +#define XT_DIWBI _TIE_xt_datacache_DIWBI +#define XT_DIWBUI_P _TIE_xt_datacache_DIWBUI_P +#define XT_DPFL _TIE_xt_datacache_DPFL +#define XT_DPFM_B _TIE_xt_datacache_DPFM_B +#define XT_DPFM_BF _TIE_xt_datacache_DPFM_BF +#define XT_DPFR _TIE_xt_datacache_DPFR +#define XT_DPFRO _TIE_xt_datacache_DPFRO +#define XT_DPFR_B _TIE_xt_datacache_DPFR_B +#define XT_DPFR_BF _TIE_xt_datacache_DPFR_BF +#define XT_DPFW _TIE_xt_datacache_DPFW +#define XT_DPFWO _TIE_xt_datacache_DPFWO +#define XT_DPFW_B _TIE_xt_datacache_DPFW_B +#define XT_DPFW_BF _TIE_xt_datacache_DPFW_BF +#define XT_LDCT _TIE_xt_datacache_LDCT +#define XT_LDCW _TIE_xt_datacache_LDCW +#define XT_PFEND_A _TIE_xt_datacache_PFEND_A +#define XT_PFEND_O _TIE_xt_datacache_PFEND_O +#define XT_PFNXT_F _TIE_xt_datacache_PFNXT_F +#define XT_PFWAIT_A _TIE_xt_datacache_PFWAIT_A +#define XT_PFWAIT_R _TIE_xt_datacache_PFWAIT_R +#define XT_SDCT _TIE_xt_datacache_SDCT +#define XT_SDCW _TIE_xt_datacache_SDCW + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ + + +/* parasoft-end-suppress ALL "This file not MISRA checked." */ + +#endif /* !_XTENSA_xt_datacache_HEADER */ diff --git a/src/platform/amd/rembrandt/include/platform/chip_offset_byte.h b/src/platform/amd/rembrandt/include/platform/chip_offset_byte.h new file mode 100644 index 000000000000..86843a20867c --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/chip_offset_byte.h @@ -0,0 +1,157 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ + +#ifndef _RMB_OFFSET_HEADER +#define _RMB_OFFSET_HEADER + +#define PU_REGISTER_BASE (0x9FD00000 - 0x01240000) +#define PU_SCRATCH_REG_BASE (0x9FF00000 - 0x01250000) + +/* Registers from ACP_DMA block */ +#define ACP_DMA_CNTL_0 0x1240000 +#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020 +#define ACP_DMA_DSCR_CNT_0 0x1240040 +#define ACP_DMA_PRIO_0 0x1240060 +#define ACP_DMA_CUR_DSCR_0 0x1240080 +#define ACP_DMA_CUR_TRANS_CNT_0 0x12400A0 +#define ACP_DMA_DESC_BASE_ADDR 0x12400E0 +#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4 +#define ACP_DMA_CH_STS 0x12400E8 +#define ACP_DMA_CH_GROUP 0x12400EC +#define ACP_DMA_CH_RST_STS 0x12400F0 + +/* Registers from ACP_MISC block */ +#define ACP_DSP0_INTR_CNTL 0x1241800 +#define ACP_DSP0_INTR_STAT 0x1241804 +#define ACP_DSP_SW_INTR_CNTL 0x1241808 +#define ACP_DSP_SW_INTR_STAT 0x124180C +#define ACP_SW_INTR_TRIG 0x1241810 +#define DSP_INTERRUPT_ROUTING_CTRL_0 0x1241814 +#define DSP_INTERRUPT_ROUTING_CTRL_1 0x1241818 +#define ACP_AXI2DAGB_SEM_0 0x1241874 +#define ACP_DSP0_INTR_CNTL1 0x1241920 +#define ACP_DSP0_INTR_STAT1 0x1241924 +#define ACP_SRBM_CLIENT_BASE_ADDR 0x12419EC +#define ACP_SRBM_CLIENT_RDDATA 0x12419F0 +#define ACP_SRBM_CYCLE_STS 0x12419F4 +#define ACP_SRBM_CLIENT_CONFIG 0x12419F8 + +/* Registers from ACP_P1_MISC block */ +#define ACP_EXTERNAL_INTR_ENB 0x1241A00 +#define ACP_EXTERNAL_INTR_CNTL 0x1241A04 +#define ACP_EXTERNAL_INTR_CNTL1 0x1241A08 +#define ACP_EXTERNAL_INTR_STAT 0x1241A0C +#define ACP_EXTERNAL_INTR_STAT1 0x1241A10 + +/* Registers from ACP_I2S_TDM block */ +#define ACP_I2STDM_IER 0x1242400 +#define ACP_I2STDM_IRER 0x1242404 +#define ACP_I2STDM_RXFRMT 0x1242408 +#define ACP_I2STDM_ITER 0x124240C +#define ACP_I2STDM_TXFRMT 0x1242410 +#define ACP_I2STDM0_MSTRCLKGEN 0x1242414 +#define ACP_I2STDM1_MSTRCLKGEN 0x1242418 +#define ACP_I2STDM2_MSTRCLKGEN 0x124241C +#define ACP_I2STDM_REFCLKGEN 0x1242420 + +/* Registers from ACP_BT_TDM block */ +#define ACP_BTTDM_IER 0x1242800 +#define ACP_BTTDM_IRER 0x1242804 +#define ACP_BTTDM_RXFRMT 0x1242808 +#define ACP_BTTDM_ITER 0x124280C +#define ACP_BTTDM_TXFRMT 0x1242810 +#define ACP_HSTDM_IER 0x1242814 +#define ACP_HSTDM_IRER 0x1242818 +#define ACP_HSTDM_RXFRMT 0x124281C +#define ACP_HSTDM_ITER 0x1242820 +#define ACP_HSTDM_TXFRMT 0x1242824 + +/* Registers from ACP_WOV block */ +#define ACP_WOV_PDM_ENABLE 0x1242C04 +#define ACP_WOV_PDM_DMA_ENABLE 0x1242C08 +#define ACP_WOV_RX_RINGBUFADDR 0x1242C0C +#define ACP_WOV_RX_RINGBUFSIZE 0x1242C10 +#define ACP_WOV_RX_LINKPOSITIONCNTR 0x1242C14 +#define ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH 0x1242C18 +#define ACP_WOV_RX_LINEARPOSITIONCNTR_LOW 0x1242C1C +#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x1242C20 +#define ACP_WOV_PDM_FIFO_FLUSH 0x1242C24 +#define ACP_WOV_PDM_NO_OF_CHANNELS 0x1242C28 +#define ACP_WOV_PDM_DECIMATION_FACTOR 0x1242C2C +#define ACP_WOV_PDM_VAD_CTRL 0x1242C30 +#define ACP_WOV_WAKE 0x1242C54 +#define ACP_WOV_BUFFER_STATUS 0x1242C58 +#define ACP_WOV_MISC_CTRL 0x1242C5C +#define ACP_WOV_CLK_CTRL 0x1242C60 +#define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x1242C64 +#define ACP_WOV_ERROR_STATUS_REGISTER 0x1242C68 +#define ACP_PDM_CLKDIV 0x1242C6C + +/* Registers from ACP_P1_AUDIO_BUFFERS block */ +#define ACP_P1_I2S_RX_RINGBUFADDR 0x1243A00 +#define ACP_P1_I2S_RX_RINGBUFSIZE 0x1243A04 +#define ACP_P1_I2S_RX_LINKPOSITIONCNTR 0x1243A08 +#define ACP_P1_I2S_RX_FIFOADDR 0x1243A0C +#define ACP_P1_I2S_RX_FIFOSIZE 0x1243A10 +#define ACP_P1_I2S_RX_DMA_SIZE 0x1243A14 +#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1243A18 +#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_LOW 0x1243A1C +#define ACP_P1_I2S_RX_INTR_WATERMARK_SIZE 0x1243A20 +#define ACP_P1_I2S_TX_RINGBUFADDR 0x1243A24 +#define ACP_P1_I2S_TX_RINGBUFSIZE 0x1243A28 +#define ACP_P1_I2S_TX_LINKPOSITIONCNTR 0x1243A2C +#define ACP_P1_I2S_TX_FIFOADDR 0x1243A30 +#define ACP_P1_I2S_TX_FIFOSIZE 0x1243A34 +#define ACP_P1_I2S_TX_DMA_SIZE 0x1243A38 +#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x1243A3C +#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1243A40 +#define ACP_P1_I2S_TX_INTR_WATERMARK_SIZE 0x1243A44 +#define ACP_P1_BT_RX_RINGBUFADDR 0x1243A48 +#define ACP_P1_BT_RX_RINGBUFSIZE 0x1243A4C +#define ACP_P1_BT_RX_LINKPOSITIONCNTR 0x1243A50 +#define ACP_P1_BT_RX_FIFOADDR 0x1243A54 +#define ACP_P1_BT_RX_FIFOSIZE 0x1243A58 +#define ACP_P1_BT_RX_DMA_SIZE 0x1243A5C +#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1243A60 +#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_LOW 0x1243A64 +#define ACP_P1_BT_RX_INTR_WATERMARK_SIZE 0x1243A68 +#define ACP_P1_BT_TX_RINGBUFADDR 0x1243A6C +#define ACP_P1_BT_TX_RINGBUFSIZE 0x1243A70 +#define ACP_P1_BT_TX_LINKPOSITIONCNTR 0x1243A74 +#define ACP_P1_BT_TX_FIFOADDR 0x1243A78 +#define ACP_P1_BT_TX_FIFOSIZE 0x1243A7C +#define ACP_P1_BT_TX_DMA_SIZE 0x1243A80 +#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1243A84 +#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_LOW 0x1243A88 +#define ACP_P1_BT_TX_INTR_WATERMARK_SIZE 0x1243A8C +#define ACP_P1_HS_RX_RINGBUFADDR 0x1243A90 +#define ACP_P1_HS_RX_RINGBUFSIZE 0x1243A94 +#define ACP_P1_HS_RX_LINKPOSITIONCNTR 0x1243A98 +#define ACP_P1_HS_RX_FIFOADDR 0x1243A9C +#define ACP_P1_HS_RX_FIFOSIZE 0x1243AA0 +#define ACP_P1_HS_RX_DMA_SIZE 0x1243AA4 +#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_HIGH 0x1243AA8 +#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_LOW 0x1243AAC +#define ACP_P1_HS_RX_INTR_WATERMARK_SIZE 0x1243AB0 +#define ACP_P1_HS_TX_RINGBUFADDR 0x1243AB4 +#define ACP_P1_HS_TX_RINGBUFSIZE 0x1243AB8 +#define ACP_P1_HS_TX_LINKPOSITIONCNTR 0x1243ABC +#define ACP_P1_HS_TX_FIFOADDR 0x1243AC0 +#define ACP_P1_HS_TX_FIFOSIZE 0x1243AC4 +#define ACP_P1_HS_TX_DMA_SIZE 0x1243AC8 +#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_HIGH 0x1243ACC +#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_LOW 0x1243AD0 +#define ACP_P1_HS_TX_INTR_WATERMARK_SIZE 0x1243AD4 + +#define MP1_SMN_C2PMSG_69 0x58A14 +#define MP1_SMN_C2PMSG_85 0x58A54 +#define MP1_SMN_C2PMSG_93 0x58A74 + +#define MP0_C2PMSG_73 0x3810A24 +#define MP0_C2PMSG_114 0x3810AC8 +#endif diff --git a/src/platform/amd/rembrandt/include/platform/chip_registers.h b/src/platform/amd/rembrandt/include/platform/chip_registers.h new file mode 100644 index 000000000000..5a261317cf3a --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/chip_registers.h @@ -0,0 +1,774 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#if !defined(_RMB_REG_HEADER) +#define _RMB_REG_HEADER + +typedef union acp_dma_cntl_0 { + struct { + unsigned int dmachrst:1; + unsigned int dmachrun:1; + unsigned int dmachiocen:1; + unsigned int :29; + } bits; + unsigned int u32all; +} acp_dma_cntl_0_t; + +typedef union acp_dma_ch_sts { + struct { + unsigned int dmachrunsts:8; + unsigned int :24; + } bits; + unsigned int u32all; +} acp_dma_ch_sts_t; + +typedef union acp_external_intr_enb { + struct { + unsigned int acpextintrenb:1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_external_intr_enb_t; + +typedef union acp_dsp0_intr_cntl { + struct { + unsigned int dmaiocmask:8; + unsigned int :8; + unsigned int wov_dma_intr_mask:1; + unsigned int :6; + unsigned int audio_buffer_int_mask:6; + unsigned int :3; + } bits; + unsigned int u32all; +} acp_dsp0_intr_cntl_t; + +typedef union acp_dsp0_intr_stat { + struct { + unsigned int dmaiocstat:8; + unsigned int :8; + unsigned int wov_dma_stat:1; + unsigned int :6; + unsigned int audio_buffer_int_stat:6; + unsigned int :3; + } bits; + unsigned int u32all; +} acp_dsp0_intr_stat_t; + +typedef union acp_dsp0_intr_cntl1 { + struct { + unsigned int acp_fusion_dsp_ext_timer1_timeoutmask :1; + unsigned int fusion_dsp_watchdog_timeoutmask :1; + unsigned int soundwire_mask :1; + unsigned int audio_buffer_int_mask :6; + unsigned int :23; + } bits; + unsigned int u32all; +} acp_dsp0_intr_cntl1_t; + +typedef union acp_dsp0_intr_stat1 { + struct { + unsigned int acp_fusion_dsp_timer1_timeoutstat :1; + unsigned int fusion_dsp_watchdog_timeoutstat :1; + unsigned int soundwire_stat :1; + unsigned int audio_buffer_int_stat :6; + unsigned int :23; + } bits; + unsigned int u32all; +} acp_dsp0_intr_stat1_t; + +typedef union acp_dsp_sw_intr_cntl { + struct { + unsigned int :2; + unsigned int dsp0_to_host_intr_mask:1; + unsigned int :29; + } bits; + unsigned int u32all; +} acp_dsp_sw_intr_cntl_t; + +typedef union acp_dsp_sw_intr_stat { + struct { + unsigned int host_to_dsp0_intr1_stat:1; + unsigned int host_to_dsp0_intr2_stat:1; + unsigned int dsp0_to_host_intr_stat:1; + unsigned int host_to_dsp0_intr3_stat:1; + unsigned int :28; + } bits; + unsigned int u32all; +} acp_dsp_sw_intr_stat_t; + +typedef union acp_sw_intr_trig { + struct { + unsigned int trig_host_to_dsp0_intr1:1; + unsigned int :1; + unsigned int trig_dsp0_to_host_intr:1; + unsigned int :29; + } bits; + unsigned int u32all; +} acp_sw_intr_trig_t; + +typedef union dsp_interrupt_routing_ctrl_0 { + struct { + unsigned int dma_intr_level:3; + unsigned int :18; + unsigned int watchdog_intr_level:3; + unsigned int az_sw_i2s_intr_level:3; + unsigned int sha_intr_level:3; + unsigned int :2; + } bits; + unsigned int u32all; +} dsp_interrupt_routing_ctrl_0_t; + +typedef union dsp_interrupt_routing_ctrl_1 { + struct { + unsigned int host_to_dsp_intr1_level:3; + unsigned int host_to_dsp_intr2_level:3; + unsigned int src_intr_level:3; + unsigned int mailbox_intr_level:3; + unsigned int error_intr_level:3; + unsigned int wov_intr_level:3; + unsigned int fusion_timer1_intr_level:3; + unsigned int fusion_watchdog_intr_level:3; + unsigned int p1_sw_i2s_intr_level:3; + unsigned int :5; + } bits; + unsigned int u32all; +} dsp_interrupt_routing_ctrl_1_t; + +typedef union acp_i2s_rx_ringbufaddr { + struct { + unsigned int i2s_rx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_rx_ringbufaddr_t; + +typedef union acp_i2s_rx_ringbufsize { + struct { + unsigned int i2s_rx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_rx_ringbufsize_t; + +typedef union acp_i2s_rx_linkpositioncntr { + struct { + unsigned int i2s_rx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_rx_linkpositioncntr_t; + +typedef union acp_i2s_rx_fifoaddr { + struct { + unsigned int i2s_rx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_rx_fifoaddr_t; + +typedef union acp_i2s_rx_fifosize { + struct { + unsigned int i2s_rx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_rx_fifosize_t; + +typedef union acp_i2s_rx_dma_size { + struct { + unsigned int i2s_rx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_rx_dma_size_t; + +typedef union acp_i2s_rx_linearpositioncntr_high { + struct { + unsigned int i2s_rx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_i2s_rx_linearpositioncntr_high_t; + +typedef union acp_i2s_rx_linearpositioncntr_low { + struct { + unsigned int i2s_rx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_i2s_rx_linearpositioncntr_low_t; + +typedef union acp_i2s_rx_watermark_size { + struct { + unsigned int i2s_rx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_rx_intr_watermark_size_t; + +typedef union acp_i2s_tx_ringbufaddr { + struct { + unsigned int i2s_tx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_tx_ringbufaddr_t; + +typedef union acp_i2s_tx_ringbufsize { + struct { + unsigned int i2s_tx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_tx_ringbufsize_t; + +typedef union acp_i2s_tx_linkpositioncntr { + struct { + unsigned int i2s_tx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_tx_linkpositioncntr_t; + +typedef union acp_i2s_tx_fifoaddr { + struct { + unsigned int i2s_tx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_tx_fifoaddr_t; + +typedef union acp_i2s_tx_fifosize { + struct { + unsigned int i2s_tx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_tx_fifosize_t; + +typedef union acp_i2s_tx_dma_size { + struct { + unsigned int i2s_tx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_tx_dma_size_t; + +typedef union acp_i2s_tx_linearpositioncntr_high { + struct { + unsigned int i2s_tx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_i2s_tx_linearpositioncntr_hight_t; + +typedef union acp_i2s_tx_linearpositioncntr_low { + struct { + unsigned int i2s_tx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_i2s_tx_linearpositioncntr_low_t; + +typedef union acp_i2s_tx_intr_watermark_size { + struct { + unsigned int i2s_tx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_tx_intr_watermark_size_t; + +typedef union acp_bt_rx_ringbufaddr { + struct { + unsigned int bt_rx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_rx_ringbufaddr_t; + +typedef union acp_bt_rx_ringbufsize { + struct { + unsigned int bt_rx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_rx_ringbufsize_t; + +typedef union acp_bt_rx_linkpositioncntr { + struct { + unsigned int bt_rx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_rx_linkpositioncntr_t; + +typedef union acp_bt_rx_fifoaddr { + struct { + unsigned int bt_rx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_rx_fifoaddr_t; + +typedef union acp_bt_rx_fifosize { + struct { + unsigned int bt_rx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_rx_fifosize_t; + +typedef union acp_bt_rx_dma_size { + struct { + unsigned int bt_rx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_rx_dma_size_t; + +typedef union acp_bt_rx_linearpositioncntr_high { + struct { + unsigned int bt_rx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_bt_rx_linearpositioncntr_high_t; + +typedef union acp_bt_rx_linearpositioncntr_low { + struct { + unsigned int bt_rx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_bt_rx_linearpositioncntr_low_t; + +typedef union acp_bt_rx_intr_watermark_size { + struct { + unsigned int bt_rx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_rx_intr_watermark_size_t; + +typedef union acp_bt_tx_ringbufaddr { + struct { + unsigned int bt_tx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_tx_ringbufaddr_t; + +typedef union acp_bt_tx_ringbufsize { + struct { + unsigned int bt_tx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_tx_ringbufsize_t; + +typedef union acp_bt_tx_linkpositiontcntr { + struct { + unsigned int bt_tx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_tx_linkpositiontcntr_t; + +typedef union acp_bt_tx_fifoaddr { + struct { + unsigned int bt_tx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_tx_fifoaddr_t; + +typedef union acp_bt_tx_fifosize { + struct { + unsigned int bt_tx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_tx_fifosize_t; + +typedef union acp_bt_tx_dmasize { + struct { + unsigned int bt_tx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_tx_dmasize_t; + +typedef union acp_bt_tx_linearpositioncntr_high { + struct { + unsigned int bt_tx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_bt_tx_linearpositioncntr_high_t; + +typedef union acp_bt_tx_linearpositioncntr_low { + struct { + unsigned int bt_tx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_bt_tx_linearpositioncntr_low_t; + +typedef union acp_bt_tx_intr_watermark_size { + struct { + unsigned int bt_tx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_tx_intr_watermark_size_t; + +typedef union acp_i2stdm_ier { + struct { + unsigned int i2stdm_ien:1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_i2stdm_ier_t; + +typedef union acp_i2stdm_irer { + struct { + unsigned int i2stdm_rx_en:1; + unsigned int i2stdm_rx_protocol_mode:1; + unsigned int i2stdm_rx_data_path_mode:1; + unsigned int i2stdm_rx_samplen:3; + unsigned int i2stdm_rx_status:1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_i2stdm_irer_t; + +typedef union acp_i2stdm_iter { + struct { + unsigned int i2stdm_txen:1; + unsigned int i2stdm_tx_protocol_mode:1; + unsigned int i2stdm_tx_data_path_mode:1; + unsigned int i2stdm_tx_samp_len:3; + unsigned int i2stdm_tx_status:1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_i2stdm_iter_t; + +typedef union acp_bttdm_ier { + struct { + unsigned int bttdm_ien:1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_bttdm_ier_t; + +typedef union acp_bttdm_irer { + struct { + unsigned int bttdm_rx_en:1; + unsigned int bttdm_rx_protocol_mode:1; + unsigned int bttdm_rx_data_path_mode:1; + unsigned int bttdm_rx_samplen:3; + unsigned int bttdm_rx_status:1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_bttdm_irer_t; + +typedef union acp_bttdm_iter { + struct { + unsigned int bttdm_txen :1; + unsigned int bttdm_tx_protocol_mode :1; + unsigned int bttdm_tx_data_path_mode :1; + unsigned int bttdm_tx_samp_len :3; + unsigned int bttdm_tx_status :1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_bttdm_iter_t; + +typedef union acp_wov_pdm_dma_enable { + struct { + unsigned int pdm_dma_en :1; + unsigned int pdm_dma_en_status :1; + unsigned int :30; + } bits; +unsigned int u32all; +} acp_wov_pdm_dma_enable_t; + +typedef union acp_wov_rx_ringbufaddr { + struct { + unsigned int rx_ringbufaddr :27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_wov_rx_ringbufaddr_t; + +typedef union acp_wov_rx_ringbufsize { + struct { + unsigned int rx_ringbufsize :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_wov_rx_ringbufsize_t; + +typedef union acp_wov_rx_intr_watermark_size { + struct { + unsigned int rx_intr_watermark_size :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_wov_rx_intr_watermark_size_t; + +typedef union acp_wov_pdm_no_of_channels { + struct { + unsigned int pdm_no_of_channels :2; + unsigned int :30; + } bits; + unsigned int u32all; +} acp_wov_pdm_no_of_channels_t; + +typedef union acp_wov_pdm_decimation_factor { + struct { + unsigned int pdm_decimation_factor :2; + unsigned int :30; + } bits; + unsigned int u32all; +} acp_wov_pdm_decimation_factor_t; + +typedef union acp_wov_misc_ctrl { + struct { + unsigned int :3; + unsigned int pcm_data_shift_ctrl :2; + unsigned int :27; + } bits; + unsigned int u32all; +} acp_wov_misc_ctrl_t; + +typedef union acp_wov_clk_ctrl { + struct { + unsigned int brm_clk_ctrl :4; + unsigned int pdm_vad_clkdiv :2; + unsigned int :26; + } bits; + unsigned int u32all; +} acp_wov_clk_ctrl_t; + +typedef union acp_srbm_cycle_sts { + struct { + unsigned int srbm_clients_sts :1; + unsigned int :7; + } bits; + unsigned int u32all; +} acp_srbm_cycle_sts_t; + +typedef union acp_hs_rx_ringbufaddr { + struct { + unsigned int hs_rx_ringbufaddr :32; + } bits; + unsigned int u32all; +} acp_hs_rx_ringbufaddr_t; + +typedef union acp_hs_rx_ringbufsize { + struct { + unsigned int hs_rx_ringbufsize :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_rx_ringbufsize_t; + +typedef union acp_hs_rx_linkpositioncntr { + struct { + unsigned int hs_rx_linkpositioncntr :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_rx_linkpositioncntr_t; + +typedef union acp_hs_rx_fifoaddr { + struct { + unsigned int hs_rx_fifoaddr :27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_hs_rx_fifoaddr_t; + +typedef union acp_hs_rx_fifosize { + struct { + unsigned int hs_rx_fifosize :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_rx_fifosize_t; + +typedef union acp_hs_rx_dma_size { + struct { + unsigned int hs_rx_dma_size :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_rx_dma_size_t; + +typedef union acp_hs_rx_linearpositioncntr_high { + struct { + unsigned int hs_rx_linearpositioncntr_high :32; + } bits; + unsigned int u32all; +} acp_hs_rx_linearpositioncntr_high_t; + +typedef union acp_hs_rx_linearpositioncntr_low { + struct { + unsigned int hs_rx_linearpositioncntr_low :32; + } bits; + unsigned int u32all; +} acp_hs_rx_linearpositioncntr_low_t; + +typedef union acp_hs_rx_intr_watermark_size { + struct { + unsigned int hs_rx_intr_watermark_size :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_rx_intr_watermark_size_t; + +typedef union acp_hs_tx_ringbufaddr { + struct { + unsigned int hs_tx_ringbufaddr :32; + } bits; + unsigned int u32all; +} acp_hs_tx_ringbufaddr_t; + +typedef union acp_hs_tx_ringbufsize { + struct { + unsigned int hs_tx_ringbufsize :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_tx_ringbufsize_t; + +typedef union acp_hs_tx_linkpositioncntr { + struct { + unsigned int hs_tx_linkpositioncntr :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_tx_linkpositioncntr_t; + +typedef union acp_hs_tx_fifoaddr { + struct { + unsigned int hs_tx_fifoaddr :27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_hs_tx_fifoaddr_t; + +typedef union acp_hs_tx_fifosize { + struct { + unsigned int hs_tx_fifosize :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_tx_fifosize_t; + +typedef union acp_hs_tx_dma_size { + struct { + unsigned int hs_tx_dma_size :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_tx_dma_size_t; + +typedef union acp_hs_tx_linearpositioncntr_high { + struct { + unsigned int hs_tx_linearpositioncntr_high :32; + } bits; + unsigned int u32all; +} acp_hs_tx_linearpositioncntr_high_t; + +typedef union acp_hs_tx_linearpositioncntr_low { + struct { + unsigned int hs_tx_linearpositioncntr_low :32; + } bits; + unsigned int u32all; +} acp_hs_tx_linearpositioncntr_low_t; + +typedef union acp_hs_tx_intr_watermark_size { + struct { + unsigned int hs_tx_intr_watermark_size :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_tx_intr_watermark_size_t; + +typedef union acp_i2stdm_rxfrmt { + struct { + unsigned int i2stdm_frame_len :9; + unsigned int :6; + unsigned int i2stdm_num_slots :3; + unsigned int i2stdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_i2stdm_rxfrmt_t; + +typedef union acp_i2stdm_txfrmt { + struct { + unsigned int i2stdm_frame_len :9; + unsigned int :6; + unsigned int i2stdm_num_slots :3; + unsigned int i2stdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_i2stdm_txfrmt_t; + +typedef union acp_hstdm_ier { + struct { + unsigned int hstdm_ien :1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_hstdm_ier_t; + +typedef union acp_hstdm_irer { + struct { + unsigned int hstdm_rx_en :1; + unsigned int hstdm_rx_protocol_mode :1; + unsigned int hstdm_rx_data_path_mode :1; + unsigned int hstdm_rx_samplen :3; + unsigned int hstdm_rx_status :1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_hstdm_irer_t; + +typedef union acp_hstdm_rxfrmt { + struct { + unsigned int hstdm_frame_len :9; + unsigned int :6; + unsigned int hstdm_num_slots :3; + unsigned int hstdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_hstdm_rxfrmt_t; + +typedef union acp_hstdm_iter { + struct { + unsigned int hstdm_txen :1; + unsigned int hstdm_tx_protocol_mode :1; + unsigned int hstdm_tx_data_path_mode :1; + unsigned int hstdm_tx_samp_len :3; + unsigned int hstdm_tx_status :1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_hstdm_iter_t; + +typedef union acp_hstdm_txfrmt { + struct { + unsigned int hstdm_frame_len :9; + unsigned int :6; + unsigned int hstdm_num_slots :3; + unsigned int hstdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_hstdm_txfrmt_t; + +#endif diff --git a/src/platform/amd/rembrandt/include/platform/drivers/idc.h b/src/platform/amd/rembrandt/include/platform/drivers/idc.h new file mode 100644 index 000000000000..6f587c073909 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/drivers/idc.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_DRIVERS_IDC_H__ + +#ifndef __PLATFORM_DRIVERS_IDC_H__ +#define __PLATFORM_DRIVERS_IDC_H__ + +#include + +struct idc_msg; + +static inline int idc_send_msg(struct idc_msg *msg, + uint32_t mode) { return 0; } + +static inline int idc_init(void) { return 0; } + +#endif /* __PLATFORM_DRIVERS_IDC_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/drivers/idc.h" + +#endif /* __SOF_DRIVERS_IDC_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/drivers/interrupt.h b/src/platform/amd/rembrandt/include/platform/drivers/interrupt.h new file mode 100644 index 000000000000..3efb0ef9bf6e --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/drivers/interrupt.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_DRIVERS_INTERRUPT_H__ + +#ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ +#define __PLATFORM_DRIVERS_INTERRUPT_H__ + +#include +#include +#include + +#define PLATFORM_IRQ_HW_NUM 9 + +#define PLATFORM_IRQ_FIRST_CHILD PLATFORM_IRQ_HW_NUM + +#define PLATFORM_IRQ_CHILDREN 0 + +/* IRQ numbers - wrt Tensilica DSP */ +#define IRQ_NUM_SOFTWARE0 1 /* level 1 */ + +#define IRQ_NUM_TIMER0 0 /* level 1 */ + +#define IRQ_NUM_EXT_LEVEL3 3 /* level 1 */ + +#define IRQ_NUM_TIMER1 6 /* level 2 */ + +#define IRQ_NUM_EXT_LEVEL4 4 /* level 2 */ + +#define IRQ_NUM_EXT_LEVEL5 5 /* level 3 */ + +/* IRQ Masks */ +#define IRQ_MASK_SOFTWARE0 (1 << IRQ_NUM_SOFTWARE0) + +#define IRQ_MASK_TIMER0 (1 << IRQ_NUM_TIMER0) + +#define IRQ_MASK_TIMER1 (1 << IRQ_NUM_TIMER1) + +#define IRQ_MASK_EXT_LEVEL3 (1 << IRQ_NUM_EXT_LEVEL3) + +#define IRQ_MASK_EXT_LEVEL4 (1 << IRQ_NUM_EXT_LEVEL4) + +#define IRQ_MASK_EXT_LEVEL5 (1 << IRQ_NUM_EXT_LEVEL5) + + +#define HOST_TO_DSP_INTR 0x1 + +#define _XTSTR(x) # x + +#define XTSTR(x) _XTSTR(x) + + +/* Enabling flag */ +#define INTERRUPT_ENABLE 1 + +/* Clearing flag */ +#define INTERRUPT_CLEAR 0 + +/* Disable flag */ +#define INTERRUPT_DISABLE 0 + +/* brief Tensilica Interrupt Levels. */ +typedef enum { + acp_interrupt_level_3 = 0, + + acp_interrupt_level_4, + + acp_interrupt_level_5, + + acp_interrupt_level_nmi, + + acp_interrupt_level_max +} artos_interrupt_levels_t; + +/* brief Tensilica timer control */ +typedef enum { + acp_timer_cntl_disable = 0, + + acp_timer_cntl_oneshot, + + acp_timer_cntl_periodic, + + acp_timer_cntl_max +} artos_timer_control_t; + +/* Disable Host to DSP interrupt */ +void acp_dsp_sw_intr_disable(void); + +void acp_intr_route(void); + +void acp_dsp_to_host_intr_trig(void); + +void acp_ack_intr_from_host(void); + +void acp_dsp_sw_intr_enable(void); + +void acp_intr_enable(void); + +void acp_intr_disable(void); + +#endif /* __PLATFORM_DRIVERS_INTERRUPT_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/drivers/interrupt.h" + +#endif /* __SOF_DRIVERS_INTERRUPT_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h b/src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h new file mode 100644 index 000000000000..75d940a78d96 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD. All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifndef __EXT_SCRATCH_MEM_H__ +#define __EXT_SCRATCH_MEM_H__ + +#include + +/* MAX number of DMA descriptors */ +#define MAX_NUM_DMA_DESC_DSCR 64 +#define SCRATCH_REG_OFFSET 0x1250000 + +typedef struct acp_atu_grp_pte { + uint32_t low_part; + uint32_t high_part; +} __attribute__((packed, aligned(4))) acp_atu_grp_pte_t; + +typedef union acp_cfg_dma_trns_cnt { + struct{ + uint32_t trns_cnt : 19; + uint32_t reserved : 12; + uint32_t ioc : 1; + } bits; + unsigned int u32All; +} __attribute__((packed, aligned(4))) acp_cfg_dma_trns_cnt_t; + +typedef struct acp_config_dma_descriptor { + uint32_t src_addr; + uint32_t dest_addr; + acp_cfg_dma_trns_cnt_t trns_cnt; + uint32_t reserved; +} __attribute__((packed, aligned(4))) acp_cfg_dma_descriptor_t; + +typedef struct acp_config_dma_misc { + uint32_t channelstatus; + uint32_t channel; + uint32_t flag; +} __attribute__((packed, aligned(4))) acp_cfg_dma_misc_t; + +typedef struct acp_scratch_memory_config { + /* ACP out box buffer */ + uint8_t acp_outbox_buffer[MAILBOX_DSPBOX_SIZE]; + + /* ACP in box buffer */ + uint8_t acp_inbox_buffer[MAILBOX_HOSTBOX_SIZE]; + + /* ACP debug box buffer */ + uint8_t acp_debug_buffer[MAILBOX_DEBUG_SIZE]; + + /* ACP exception box buffer */ + uint8_t acp_except_buffer[MAILBOX_EXCEPTION_SIZE]; + + /* ACP stream buffer */ + uint8_t acp_stream_buffer[MAILBOX_STREAM_SIZE]; + + /* ACP trace buffer */ + uint8_t acp_trace_buffer[MAILBOX_TRACE_SIZE]; + + /* Host msg write flag */ + uint32_t acp_host_msg_write; + + /* Host ack flag */ + uint32_t acp_host_ack_write; + + /* Dsp msg write flag */ + uint32_t acp_dsp_msg_write; + + /* Dsp ack flag */ + uint32_t acp_dsp_ack_write; + + /* ACP pte1 table */ + acp_atu_grp_pte_t acp_atugrp1_pte[16]; + + /* ACP pte2 table */ + acp_atu_grp_pte_t acp_atugrp2_pte[16]; + + /* ACP pte3 table */ + acp_atu_grp_pte_t acp_atugrp3_pte[16]; + + /* ACP pte4 table */ + acp_atu_grp_pte_t acp_atugrp4_pte[16]; + + /* ACP pte5 table */ + acp_atu_grp_pte_t acp_atugrp5_pte[16]; + + /* ACP pte6 table */ + acp_atu_grp_pte_t acp_atugrp6_pte[16]; + + /* ACP pte7 table */ + acp_atu_grp_pte_t acp_atugrp7_pte[16]; + + /* ACP pte8 table */ + acp_atu_grp_pte_t acp_atugrp8_pte[16]; + + /* ACP DMA Descriptor */ + acp_cfg_dma_descriptor_t acp_cfg_dma_descriptor[MAX_NUM_DMA_DESC_DSCR]; + + /* Stream physical offset */ + uint32_t phy_offset[8]; + + /* Stream system memeory size */ + uint32_t syst_buff_size[8]; + + /* Fifo buffers are not part of scratch memory on Rembrandt */ + /* Added fifo members to align with Driver structure */ + /* ACP transmit fifo buffer */ + uint8_t acp_transmit_fifo_buffer[768] __attribute__((aligned(128))); + + /* ACP receive fifo buffer */ + uint8_t acp_receive_fifo_buffer[768] __attribute__((aligned(128))); + + uint32_t reserve[]; +} __attribute__((packed, aligned(4))) acp_scratch_mem_config_t; + +#endif /* __EXT_SCRATCH_MEM_H__ */ + diff --git a/src/platform/amd/rembrandt/include/platform/lib/clk.h b/src/platform/amd/rembrandt/include/platform/lib/clk.h new file mode 100644 index 000000000000..e5f67caaad80 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/lib/clk.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_LIB_CLK_H__ + +#ifndef __PLATFORM_LIB_CLK_H__ +#define __PLATFORM_LIB_CLK_H__ + +#include +#include + +struct sof; + +#define CLK_CPU(x) (x) + +#define CPU_DEFAULT_IDX 0 + +#define CLK_DEFAULT_CPU_HZ 600000000 +#define CLK_MAX_CPU_HZ 600000000 + +#define NUM_CLOCKS 2 + +#define NUM_CPU_FREQ 1 + +#define ACP_MASTER_REG_ACCESS_ADDRESS 0x3400 + +#define MP1_APERTURE_ID 0x0 + +#define ACP_FIRST_REG_OFFSET 0x01240000 + +#define ACP_SMU_MSG_SET_ACLK 0x3 + + +void acp_change_clock_notify(uint32_t clockFreq); + +void platform_clock_init(struct sof *sof); + +#endif /* __PLATFORM_LIB_CLK_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/lib/clk.h" + +#endif /* __SOF_LIB_CLK_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/lib/cpu.h b/src/platform/amd/rembrandt/include/platform/lib/cpu.h new file mode 100644 index 000000000000..c5a9f9f91d5d --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/lib/cpu.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ + +/* + * file platform/lib/cpu.h + * brief DSP core parameters. + */ +#ifdef __SOF_LIB_CPU_H__ + +#ifndef __PLATFORM_LIB_CPU_H__ +#define __PLATFORM_LIB_CPU_H__ + +/* brief Number of available DSP cores (conf. by kconfig) */ +#define PLATFORM_CORE_COUNT CONFIG_CORE_COUNT + +/* brief Maximum allowed number of DSP cores */ +#define MAX_CORE_COUNT 1 + +/* brief Id of master DSP core */ +#define PLATFORM_MASTER_CORE_ID 0 + +#define PLATFORM_PRIMARY_CORE_ID 0 + +#endif /* __PLATFORM_LIB_CPU_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/lib/cpu.h" + +#endif /* __SOF_LIB_CPU_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/lib/dai.h b/src/platform/amd/rembrandt/include/platform/lib/dai.h new file mode 100644 index 000000000000..fd505c6721da --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/lib/dai.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_LIB_DAI_H__ + +#ifndef __PLATFORM_LIB_DAI_H__ +#define __PLATFORM_LIB_DAI_H__ + + +#endif /* __PLATFORM_LIB_DAI_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/lib/dai.h" + +#endif /* __SOF_LIB_DAI_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/lib/dma.h b/src/platform/amd/rembrandt/include/platform/lib/dma.h new file mode 100644 index 000000000000..d8d3e5bf7b06 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/lib/dma.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_LIB_DMA_H__ + +#ifndef __PLATFORM_LIB_DMA_H__ +#define __PLATFORM_LIB_DMA_H__ + +#define PLATFORM_NUM_DMACS 4 + +/* max number of supported DMA channels */ +#define PLATFORM_MAX_DMA_CHAN 8 + +#define DMA_ID_DMA0 0 +#define DMA_ID_HOST 1 +#define DMA_ID_DAI 2 +#define DMA_ID_DAI_SP 3 +#define DMA_ID_DAI_DMIC 4 +#define DMA_ID_DAI_HS 5 + +#define dma_chan_irq(dma, chan) dma_irq(dma) + +#define dma_chan_irq_name(dma, chan) dma_irq_name(dma) +#endif /* __PLATFORM_LIB_DMA_H__ */ +#else +#error "This file shouldn't be included from outside of sof/lib/dma.h" +#endif /* __SOF_LIB_DMA_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/lib/mailbox.h b/src/platform/amd/rembrandt/include/platform/lib/mailbox.h new file mode 100644 index 000000000000..50ac354eb726 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/lib/mailbox.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_LIB_MAILBOX_H__ + +#ifndef __PLATFORM_LIB_MAILBOX_H__ +#define __PLATFORM_LIB_MAILBOX_H__ + +#include + +#define MAILBOX_DSPBOX_SIZE SRAM_OUTBOX_SIZE +#define MAILBOX_DSPBOX_BASE SRAM_OUTBOX_BASE +#define MAILBOX_DSPBOX_OFFSET SRAM_OUTBOX_OFFSET + +#define MAILBOX_HOSTBOX_SIZE SRAM_INBOX_SIZE +#define MAILBOX_HOSTBOX_BASE SRAM_INBOX_BASE +#define MAILBOX_HOSTBOX_OFFSET SRAM_INBOX_OFFSET + +#define MAILBOX_DEBUG_SIZE SRAM_DEBUG_SIZE +#define MAILBOX_DEBUG_BASE SRAM_DEBUG_BASE +#define MAILBOX_DEBUG_OFFSET SRAM_DEBUG_OFFSET + +#define MAILBOX_TRACE_SIZE SRAM_TRACE_SIZE +#define MAILBOX_TRACE_BASE SRAM_TRACE_BASE +#define MAILBOX_TRACE_OFFSET SRAM_TRACE_OFFSET + +#define MAILBOX_EXCEPTION_SIZE SRAM_EXCEPT_SIZE +#define MAILBOX_EXCEPTION_BASE SRAM_EXCEPT_BASE +#define MAILBOX_EXCEPTION_OFFSET SRAM_EXCEPT_OFFSET + +#define MAILBOX_STREAM_SIZE SRAM_STREAM_SIZE + +#define MAILBOX_STREAM_BASE SRAM_STREAM_BASE +#define MAILBOX_STREAM_OFFSET SRAM_STREAM_OFFSET + +static inline void mailbox_sw_reg_write(size_t offset, uint32_t src) +{ + volatile uint32_t *ptr; + + ptr = (volatile uint32_t *)(MAILBOX_DEBUG_BASE + offset); + *ptr = src; +} + +#endif /* __PLATFORM_LIB_MAILBOX_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/lib/mailbox.h" + +#endif /* __SOF_LIB_MAILBOX_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/lib/memory.h b/src/platform/amd/rembrandt/include/platform/lib/memory.h new file mode 100644 index 000000000000..8683a54957e2 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/lib/memory.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_LIB_MEMORY_H__ + +#ifndef __PLATFORM_LIB_MEMORY_H__ +#define __PLATFORM_LIB_MEMORY_H__ + +#include +#include + +/* data cache line alignment */ +#define PLATFORM_DCACHE_ALIGN 128 + +/* physical DSP addresses */ +#define IRAM_BASE 0x7F000000 +#define IRAM_SIZE 0x20000 + +#define DRAM0_BASE 0xE0000000 +#define DRAM0_SIZE 0x37000 +#define DRAM1_SIZE 0x29000 +#define SRAM0_BASE 0x9FF00000 + +#define DMA0_BASE PU_REGISTER_BASE +#define DMA0_SIZE 0x4 + +/* DAI DMA register base address */ +#define DAI_BASE (PU_REGISTER_BASE + ACP_I2S_RX_RINGBUFADDR) +#define DAI_BASE_REM (PU_REGISTER_BASE + ACP_P1_I2S_RX_RINGBUFADDR) +#define DAI_SIZE 0x4 +#define BT_TX_FIFO_OFFST (ACP_P1_BT_TX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) +#define BT_RX_FIFO_OFFST (ACP_P1_BT_RX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) + +#define HS_TX_FIFO_OFFST (ACP_P1_HS_TX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) +#define HS_RX_FIFO_OFFST (ACP_P1_HS_TX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) + +#define UUID_ENTRY_ELF_BASE 0x1FFFA000 +#define UUID_ENTRY_ELF_SIZE 0x6000 + +/* Log buffer base need to be updated properly, these are used in linker scripts */ +#define LOG_ENTRY_ELF_BASE 0x20000000 +#define LOG_ENTRY_ELF_SIZE 0x2000000 + +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + +/* Stack configuration */ +#define SOF_STACK_SIZE 0x1000 +#define SOF_STACK_TOTAL_SIZE SOF_STACK_SIZE +#define SOF_STACK_END (DRAM0_BASE + DRAM0_SIZE) +#define SOF_STACK_BASE (SOF_STACK_END + SOF_STACK_SIZE) + +/* Mailbox configuration */ +#define SRAM_OUTBOX_BASE SRAM0_BASE +#define SRAM_OUTBOX_SIZE 0x200 +#define SRAM_OUTBOX_OFFSET 0 + +#define SRAM_INBOX_BASE (SRAM_OUTBOX_BASE + SRAM_OUTBOX_SIZE) +#define SRAM_INBOX_SIZE 0x200 +#define SRAM_INBOX_OFFSET SRAM_OUTBOX_SIZE + +#define SRAM_DEBUG_BASE (SRAM_INBOX_BASE + SRAM_INBOX_SIZE) +#define SRAM_DEBUG_SIZE 0x400 +#define SRAM_DEBUG_OFFSET (SRAM_INBOX_OFFSET + SRAM_INBOX_SIZE) + +#define SRAM_EXCEPT_BASE (SRAM_DEBUG_BASE + SRAM_DEBUG_SIZE) +#define SRAM_EXCEPT_SIZE 0x400 +#define SRAM_EXCEPT_OFFSET (SRAM_DEBUG_OFFSET + SRAM_DEBUG_SIZE) + +#define SRAM_STREAM_BASE (SRAM_EXCEPT_BASE + SRAM_EXCEPT_SIZE) +#define SRAM_STREAM_SIZE 0x400 +#define SRAM_STREAM_OFFSET (SRAM_EXCEPT_OFFSET + SRAM_EXCEPT_SIZE) + +#define SRAM_TRACE_BASE (SRAM_STREAM_BASE + SRAM_STREAM_SIZE) +#define SRAM_TRACE_SIZE 0x400 +#define SRAM_TRACE_OFFSET (SRAM_STREAM_OFFSET + SRAM_STREAM_SIZE) +#define SOF_MAILBOX_SIZE (SRAM_INBOX_SIZE + SRAM_OUTBOX_SIZE \ + + SRAM_DEBUG_SIZE + SRAM_EXCEPT_SIZE \ + + SRAM_STREAM_SIZE + SRAM_TRACE_SIZE) + +/* Heap section sizes for module pool */ +#define HEAP_RT_COUNT8 0 +#define HEAP_RT_COUNT16 48 +#define HEAP_RT_COUNT32 48 +#define HEAP_RT_COUNT64 32 +#define HEAP_RT_COUNT128 48 +#define HEAP_RT_COUNT256 32 +#define HEAP_RT_COUNT512 4 +#define HEAP_RT_COUNT1024 12 +#define HEAP_RT_COUNT2048 12 + +/* Heap section sizes for system runtime heap */ +#define HEAP_SYS_RT_COUNT64 64 +#define HEAP_SYS_RT_COUNT512 20 /*rembrandt-arch*/ +#define HEAP_SYS_RT_COUNT1024 6 + +/* Heap configuration */ +#define HEAP_SYSTEM_BASE (SOF_STACK_BASE + SOF_STACK_SIZE) +#define HEAP_SYSTEM_SIZE 0xe000 +#define HEAP_SYSTEM_0_BASE HEAP_SYSTEM_BASE +#define HEAP_SYS_RUNTIME_BASE (HEAP_SYSTEM_BASE + HEAP_SYSTEM_SIZE) +#define HEAP_SYS_RUNTIME_SIZE (HEAP_SYS_RT_COUNT64 * 64 + HEAP_SYS_RT_COUNT512 * 512 + \ + HEAP_SYS_RT_COUNT1024 * 1024) + +#define HEAP_RUNTIME_BASE (HEAP_SYS_RUNTIME_BASE + HEAP_SYS_RUNTIME_SIZE) +#define HEAP_RUNTIME_SIZE \ + (HEAP_RT_COUNT8 * 8 + HEAP_RT_COUNT16 * 16 + \ + HEAP_RT_COUNT32 * 32 + HEAP_RT_COUNT64 * 64 + \ + HEAP_RT_COUNT128 * 128 + HEAP_RT_COUNT256 * 256 + \ + HEAP_RT_COUNT512 * 512 + HEAP_RT_COUNT1024 * 1024 + \ + HEAP_RT_COUNT2048 * 2048) + +#define HEAP_BUFFER_BASE (HEAP_RUNTIME_BASE + HEAP_RUNTIME_SIZE) +#define HEAP_BUFFER_SIZE (0xF000) +#define HEAP_BUFFER_BLOCK_SIZE 0x180 +#define HEAP_BUFFER_COUNT (HEAP_BUFFER_SIZE / HEAP_BUFFER_BLOCK_SIZE) + +#define PLATFORM_HEAP_SYSTEM 1 +#define PLATFORM_HEAP_SYSTEM_RUNTIME 1 +#define PLATFORM_HEAP_RUNTIME 1 +#define PLATFORM_HEAP_BUFFER 1 + +/* Vector and literal sizes - not in core-isa.h */ +#define SOF_MEM_VECT_LIT_SIZE 0x7 +#define SOF_MEM_VECT_TEXT_SIZE 0x37 +#define SOF_MEM_VECT_SIZE (SOF_MEM_VECT_TEXT_SIZE + SOF_MEM_VECT_LIT_SIZE) + +#define SOF_MEM_RESET_TEXT_SIZE 0x400 +#define SOF_MEM_RESET_LIT_SIZE 0x8 +#define SOF_MEM_VECBASE_LIT_SIZE 0x178 +#define SOF_MEM_WIN_TEXT_SIZE 0x178 + +#define SOF_MEM_RO_SIZE 0x8 + +#define uncache_to_cache(address) address +#define cache_to_uncache(address) address +#define is_uncached(address) 0 + +#define HEAP_BUF_ALIGNMENT PLATFORM_DCACHE_ALIGN + +/* brief EDF task's default stack size in bytes */ +#define PLATFORM_TASK_DEFAULT_STACK_SIZE 3072 + +#if !defined(__ASSEMBLER__) && !defined(LINKER) +struct sof; + + +#define SHARED_DATA +void platform_init_memmap(struct sof *sof); + +static inline void *platform_shared_get(void *ptr, int bytes) +{ + return ptr; +} + +static inline void *platform_rfree_prepare(void *ptr) +{ + return ptr; +} +#endif + +#endif /* __PLATFORM_LIB_MEMORY_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/lib/memory.h" + +#endif /* __SOF_LIB_MEMORY_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/lib/pm_runtime.h b/src/platform/amd/rembrandt/include/platform/lib/pm_runtime.h new file mode 100644 index 000000000000..7c8f0c800075 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/lib/pm_runtime.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_LIB_PM_RUNTIME_H__ + +#ifndef __PLATFORM_LIB_PM_RUNTIME_H__ +#define __PLATFORM_LIB_PM_RUNTIME_H__ + +#include + +struct pm_runtime_data; + +/* + * brief Initializes platform specific runtime power management. + * param[in,out] prd Runtime power management data. + */ +static inline void platform_pm_runtime_init(struct pm_runtime_data *prd) { } + +/* + * brief Retrieves platform specific power management resource. + * + * param[in] context Type of power management context. + * param[in] index Index of the device. + * param[in] flags Flags, set of RPM. + */ +static inline void platform_pm_runtime_get(uint32_t context, uint32_t index, + uint32_t flags) { } + +/* + * brief Releases platform specific power management resource. + * + * param[in] context Type of power management context. + * param[in] index Index of the device. + * param[in] flags Flags, set of RPM. + */ +static inline void platform_pm_runtime_put(uint32_t context, uint32_t index, + uint32_t flags) { } + +static inline void platform_pm_runtime_enable(uint32_t context, + uint32_t index) {} + +static inline void platform_pm_runtime_disable(uint32_t context, + uint32_t index) {} + +static inline bool platform_pm_runtime_is_active(uint32_t context, + uint32_t index) +{ + return false; +} + +#endif /* __PLATFORM_LIB_PM_RUNTIME_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/lib/pm_runtime.h" + +#endif /* __SOF_LIB_PM_RUNTIME_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/platform.h b/src/platform/amd/rembrandt/include/platform/platform.h new file mode 100644 index 000000000000..cac3282e00e3 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/platform.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_PLATFORM_H__ + +#ifndef __PLATFORM_PLATFORM_H__ +#define __PLATFORM_PLATFORM_H__ + +#if !defined(__ASSEMBLER__) && !defined(LINKER) + +#include +#include +#include +#include +#include +#include +#include +#include + +struct ll_schedule_domain; +struct timer; + +#define PLATFORM_DEFAULT_CLOCK CLK_CPU(0) + +/* IPC Interrupt */ +#define PLATFORM_IPC_INTERRUPT IRQ_EXT_IPC_LEVEL_3 +#define PLATFORM_IPC_INTERRUPT_NAME NULL + +/* Host page size */ +#define HOST_PAGE_SIZE 65536 + +/* pipeline IRQ */ +#define PLATFORM_SCHEDULE_IRQ IRQ_NUM_SOFTWARE0 +#define PLATFORM_SCHEDULE_IRQ_NAME NULL + +/* Platform stream capabilities */ +#define PLATFORM_MAX_CHANNELS 4 +#define PLATFORM_MAX_STREAMS 5 + +/* local buffer size of DMA tracing */ +#define DMA_TRACE_LOCAL_SIZE 8192 + +/* trace bytes flushed during panic */ +#define DMA_FLUSH_TRACE_SIZE (MAILBOX_TRACE_SIZE >> 2) + +/* the interval of DMA trace copying */ +#define DMA_TRACE_PERIOD 500000 + +/* + * the interval of reschedule DMA trace copying in special case like half + * fullness of local DMA trace buffer + */ +#define DMA_TRACE_RESCHEDULE_TIME 100 + +/* DSP default delay in cycles */ +#define PLATFORM_DEFAULT_DELAY 12 + +/* default dma trace channel */ +#define DMA_TRACE_CHANNEL 7 + +/* debug offset */ +#define ACP_SOF_FW_STATUS 0 + +/* Platform defined panic code */ +static inline void platform_panic(uint32_t p) +{ + acp_sw_intr_trig_t sw_intr_trig; + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + + pscratch_mem_cfg->acp_dsp_msg_write = p; + mailbox_sw_reg_write(ACP_SOF_FW_STATUS, p); + /* Read the Software Interrupt controller register and update */ + sw_intr_trig = (acp_sw_intr_trig_t) io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + sw_intr_trig.bits.trig_dsp0_to_host_intr = INTERRUPT_ENABLE; + /* Write the Software Interrupt trigger register */ + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); +} + +/* + * brief Platform specific CPU entering idle. + * May be power-optimized using platform specific capabilities. + * @param level Interrupt level. + */ +static inline void platform_wait_for_interrupt(int level) +{ + arch_wait_for_interrupt(level); +} + +extern intptr_t _module_init_start; +extern intptr_t _module_init_end; +#endif + +#endif /* __PLATFORM_PLATFORM_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/platform.h" + +#endif /* __SOF_PLATFORM_H__ */ diff --git a/src/platform/amd/rembrandt/include/platform/trace/trace.h b/src/platform/amd/rembrandt/include/platform/trace/trace.h new file mode 100644 index 000000000000..505113a1d2d6 --- /dev/null +++ b/src/platform/amd/rembrandt/include/platform/trace/trace.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * Bala Kishore + */ +#ifdef __SOF_TRACE_TRACE_H__ + +#ifndef __PLATFORM_TRACE_TRACE_H__ +#define __PLATFORM_TRACE_TRACE_H__ + +/* Platform defined trace code */ +#define platform_trace_point(__x) + +#endif /* __PLATFORM_TRACE_TRACE_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/trace/trace.h" + +#endif /* __SOF_TRACE_TRACE_H__ */ diff --git a/src/platform/amd/rembrandt/lib/CMakeLists.txt b/src/platform/amd/rembrandt/lib/CMakeLists.txt new file mode 100644 index 000000000000..271a099cc6a9 --- /dev/null +++ b/src/platform/amd/rembrandt/lib/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof + clk.c + dai.c + dma.c + memory.c +) diff --git a/src/platform/amd/rembrandt/lib/clk.c b/src/platform/amd/rembrandt/lib/clk.c new file mode 100644 index 000000000000..2d856f0db584 --- /dev/null +++ b/src/platform/amd/rembrandt/lib/clk.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 AMD. All rights reserved. +// +// Author: Basavaraj Hiregoudar + +#include +#include +#include +#include +#include +#include +#include +#include + +const struct freq_table platform_cpu_freq[] = { + {600000000, 600000 }, +}; + +STATIC_ASSERT(NUM_CPU_FREQ == ARRAY_SIZE(platform_cpu_freq), + invalid_number_of_cpu_frequencies); + +static SHARED_DATA struct clock_info platform_clocks_info[NUM_CLOCKS]; + +static int acp_reg_read_via_smn(uint32_t reg_offset, + uint32_t size) +{ + uint32_t reg_value; + uint32_t delay_cnt = 10000; + uint32_t smn_client_base_addr = (reg_offset >> 10); + uint32_t region_start_addr = (smn_client_base_addr << 10); + uint32_t apertureid = ((reg_offset >> 20) & 0xFFF); + acp_srbm_cycle_sts_t acp_srbm_cycle_sts; + + /* Configuring the MP1 Aperture Id in SRB_client_config register */ + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_CONFIG), apertureid); + /* Configuring the base address of MP1 */ + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_BASE_ADDR), smn_client_base_addr); + /* dummy read to the to the address offset 0x3400 */ + /* Master config offset to access register outside of ACP */ + reg_value = (uint32_t)io_reg_read(PU_REGISTER_BASE + + (ACP_MASTER_REG_ACCESS_ADDRESS + reg_offset - region_start_addr + ACP_FIRST_REG_OFFSET)); + if (reg_value) + reg_value = 0; + /* reading status register to check above read request is completed or not */ + acp_srbm_cycle_sts = (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + + ACP_SRBM_CYCLE_STS); + /* Waiting for status to be set to '0' */ + while (delay_cnt > 0) { + if (!acp_srbm_cycle_sts.bits.srbm_clients_sts) { + /* when status is '0' from above read the data from data register */ + return (uint32_t) io_reg_read(PU_REGISTER_BASE + ACP_SRBM_CLIENT_RDDATA); + } + acp_srbm_cycle_sts = (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + + ACP_SRBM_CYCLE_STS); + delay_cnt--; + } + return -1; +} + +static void acp_reg_write_via_smn(uint32_t reg_offset, + uint32_t value, uint32_t size) +{ + uint32_t delay_cnt = 10000; + uint32_t smn_client_base_addr = (reg_offset >> 10); + uint32_t region_start_addr = (smn_client_base_addr << 10); + uint32_t apertureid = ((reg_offset >> 20) & 0xFFF); + acp_srbm_cycle_sts_t acp_srbm_cycle_sts; + + /* Configuring the MP1 Aperture Id in SRB_client_config register */ + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_CONFIG), apertureid); + /* Configuring the base address of MP1 */ + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_BASE_ADDR), smn_client_base_addr); + /* write to the address offset 0x3400 + * Master config offset to access register outside of ACP + */ + io_reg_write((PU_REGISTER_BASE + + (ACP_MASTER_REG_ACCESS_ADDRESS + reg_offset - region_start_addr + ACP_FIRST_REG_OFFSET)), + value); + /* reading status register to check above read request is completed or not */ + acp_srbm_cycle_sts = + (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + ACP_SRBM_CYCLE_STS); + /* Waiting for status to be set to '0' */ + while (delay_cnt > 0) { + acp_srbm_cycle_sts = (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + + ACP_SRBM_CYCLE_STS); + if (!acp_srbm_cycle_sts.bits.srbm_clients_sts) + return; + delay_cnt--; + } +} + +static void get_response_from_smu(void) +{ + uint32_t ret_value; + uint32_t count = 0; + + do { + ret_value = acp_reg_read_via_smn(MP1_SMN_C2PMSG_93, sizeof(int)); + if (count > 0x007fffff) + count = 0; + count++; + } while (ret_value == 0); +} + + +void acp_change_clock_notify(uint32_t clock_freq) +{ + /* converting Hz to Mhz */ + clock_freq = (clock_freq / 1000000); + /* Writing response zero to the response register + * so that it cab reset to '0' for further response + */ + acp_reg_write_via_smn(MP1_SMN_C2PMSG_93, + 0, sizeof(int)); + /* Writing clock frequency value in Mhz in the Argument register */ + acp_reg_write_via_smn(MP1_SMN_C2PMSG_85, + clock_freq, sizeof(int)); + /* Writing Message to message register */ + /* Writing Aclk change message to message register */ + acp_reg_write_via_smn(MP1_SMN_C2PMSG_69, + ACP_SMU_MSG_SET_ACLK, sizeof(int)); + /* Waiting for SMU response */ + get_response_from_smu(); +} + +void platform_clock_init(struct sof *sof) +{ + int i = 0; + + sof->clocks = platform_clocks_info; + for (i = 0; i < CONFIG_CORE_COUNT; i++) { + sof->clocks[i] = (struct clock_info) { + .freqs_num = NUM_CPU_FREQ, + .freqs = platform_cpu_freq, + .default_freq_idx = CPU_DEFAULT_IDX, + .current_freq_idx = CPU_DEFAULT_IDX, + .notification_id = NOTIFIER_ID_CPU_FREQ, + .notification_mask = NOTIFIER_TARGET_CORE_MASK(i), + .set_freq = NULL, + }; + k_spinlock_init(&sof->clocks[i].lock); + } + acp_change_clock_notify(600000000); +} diff --git a/src/platform/amd/rembrandt/lib/dai.c b/src/platform/amd/rembrandt/lib/dai.c new file mode 100644 index 000000000000..896ec8a8b9f5 --- /dev/null +++ b/src/platform/amd/rembrandt/lib/dai.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct dai acp_dmic_dai[] = { + { + .index = 0, + .plat_data = { + .base = DMA0_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DMA0_BASE, + .depth = 8, + .handshake = 0, + }, + .base = DMA0_BASE, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DMA0_BASE, + .depth = 8, + .handshake = 1, + }, + }, + .drv = &acp_dmic_dai_driver, + }, +}; + +static struct dai hsdai[] = { + { + .index = 0, + .plat_data = { + .base = DAI_BASE_REM, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE_REM + HS_TX_FIFO_OFFST, + .depth = 8, + .handshake = 1, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE_REM + HS_RX_FIFO_OFFST, + .depth = 8, + .handshake = 0, + }, + }, + .drv = &acp_hsdai_driver, + }, +}; +#ifdef ACP_SP_ENABLE +static struct dai spdai[] = { + { + .index = 0, + .plat_data = { + .base = DAI_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE + BT_TX_FIFO_OFFST, + .depth = 8, + .handshake = 5, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE + BT_RX_FIFO_OFFST, + .depth = 8, + .handshake = 4, + }, + }, + .drv = &acp_spdai_driver, + } +}; +#endif +#ifdef ACP_BT_ENABLE +static struct dai btdai[] = { + { + .index = 0, + .plat_data = { + .base = DAI_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE + BT_TX_FIFO_OFFST, + .depth = 8, + .handshake = 3, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE + BT_RX_FIFO_OFFST, + .depth = 8, + .handshake = 2, + }, + }, + .drv = &acp_btdai_driver, + }, +}; +#endif + +const struct dai_type_info dti[] = { + { + .type = SOF_DAI_AMD_DMIC, + .dai_array = acp_dmic_dai, + .num_dais = ARRAY_SIZE(acp_dmic_dai) + }, + { + .type = SOF_DAI_AMD_HS, + .dai_array = hsdai, + .num_dais = ARRAY_SIZE(hsdai) + }, +#ifdef ACP_SP_ENABLE + { + .type = SOF_DAI_AMD_SP, + .dai_array = spdai, + .num_dais = ARRAY_SIZE(spdai) + }, +#endif +#ifdef ACP_BT_ENABLE + { + .type = SOF_DAI_AMD_BT, + .dai_array = btdai, + .num_dais = ARRAY_SIZE(btdai) + }, +#endif +}; + +const struct dai_info lib_dai = { + .dai_type_array = dti, + .num_dai_types = ARRAY_SIZE(dti) +}; + +int dai_init(struct sof *sof) +{ + int i; + + /* initialize spin locks early to enable ref counting */ + for (i = 0; i < ARRAY_SIZE(acp_dmic_dai); i++) + k_spinlock_init(&acp_dmic_dai[i].lock); + for (i = 0; i < ARRAY_SIZE(hsdai); i++) + k_spinlock_init(&hsdai[i].lock); +#ifdef ACP_SP_ENABLE + for (i = 0; i < ARRAY_SIZE(spdai); i++) + k_spinlock_init(&spdai[i].lock); +#endif +#ifdef ACP_BT_ENABLE + /* initialize spin locks early to enable ref counting */ + for (i = 0; i < ARRAY_SIZE(btdai); i++) + k_spinlock_init(&btdai[i].lock); +#endif + sof->dai_info = &lib_dai; + return 0; +} diff --git a/src/platform/amd/rembrandt/lib/dma.c b/src/platform/amd/rembrandt/lib/dma.c new file mode 100644 index 000000000000..0dc19cf6c959 --- /dev/null +++ b/src/platform/amd/rembrandt/lib/dma.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct dma_ops acp_dma_ops; +extern struct dma_ops acp_dmic_dma_ops; +#ifdef ACP_BT_ENABLE +extern struct dma_ops acp_dai_bt_dma_ops; +#endif +#ifdef ACP_SP_ENABLE +extern struct dma_ops acp_dai_sp_dma_ops; +#endif +extern struct dma_ops acp_dai_hs_dma_ops; + +SHARED_DATA struct dma dma[PLATFORM_NUM_DMACS] = { +{ + .plat_data = { + .id = DMA_ID_DMA0, + .dir = DMA_DIR_LMEM_TO_HMEM | DMA_DIR_HMEM_TO_LMEM, + .devs = DMA_DEV_HOST, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + }, + .ops = &acp_dma_ops, +}, +{ + .plat_data = { + .id = DMA_ID_DAI_DMIC, + .dir = DMA_DIR_DEV_TO_MEM, + .devs = DMA_DEV_DMIC, + .caps = DMA_CAP_DMIC, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL4, + }, + .ops = &acp_dmic_dma_ops, +}, +{ + .plat_data = { + .id = DMA_ID_DAI_HS, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_SP, + .caps = DMA_CAP_SP, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + }, + .ops = &acp_dai_hs_dma_ops, +}, +#ifdef ACP_SP_ENABLE +{ + .plat_data = { + .id = DMA_ID_DAI_SP, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_SP, + .caps = DMA_CAP_SP, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + }, + .ops = &acp_dai_sp_dma_ops, +}, +#endif + +#ifdef ACP_BT_ENABLE +{ + .plat_data = { + .id = DMA_ID_DAI, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_BT, + .caps = DMA_CAP_BT, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + }, + .ops = &acp_dai_bt_dma_ops, +}, +#endif +}; + +const struct dma_info lib_dma = { + .dma_array = dma, + .num_dmas = ARRAY_SIZE(dma) +}; + +int acp_dma_init(struct sof *sof) +{ + int i; + + /* early lock initialization for ref counting */ + for (i = 0; i < ARRAY_SIZE(dma); i++) + k_spinlock_init(&dma[i].lock); + sof->dma_info = &lib_dma; + return 0; +} diff --git a/src/platform/amd/rembrandt/lib/memory.c b/src/platform/amd/rembrandt/lib/memory.c new file mode 100644 index 000000000000..765107c7e2e4 --- /dev/null +++ b/src/platform/amd/rembrandt/lib/memory.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2022 AMD +// +// Author:Basavaraj Hiregoudar + +#include +#include +#include +#include +#include +#include + +/* Heap blocks for system runtime */ +static SHARED_DATA struct block_hdr sys_rt_block64[HEAP_SYS_RT_COUNT64]; +static SHARED_DATA struct block_hdr sys_rt_block512[HEAP_SYS_RT_COUNT512]; +static SHARED_DATA struct block_hdr sys_rt_block1024[HEAP_SYS_RT_COUNT1024]; + +/* Heap memory for system runtime */ +static SHARED_DATA struct block_map sys_rt_heap_map[] = { + BLOCK_DEF(64, HEAP_SYS_RT_COUNT64, sys_rt_block64), + BLOCK_DEF(512, HEAP_SYS_RT_COUNT512, sys_rt_block512), + BLOCK_DEF(1024, HEAP_SYS_RT_COUNT1024, sys_rt_block1024), +}; + +/* Heap blocks for modules */ +static SHARED_DATA struct block_hdr mod_block16[HEAP_RT_COUNT16]; +static SHARED_DATA struct block_hdr mod_block32[HEAP_RT_COUNT32]; +static SHARED_DATA struct block_hdr mod_block64[HEAP_RT_COUNT64]; +static SHARED_DATA struct block_hdr mod_block128[HEAP_RT_COUNT128]; +static SHARED_DATA struct block_hdr mod_block256[HEAP_RT_COUNT256]; +static SHARED_DATA struct block_hdr mod_block512[HEAP_RT_COUNT512]; +static SHARED_DATA struct block_hdr mod_block1024[HEAP_RT_COUNT1024]; +static SHARED_DATA struct block_hdr mod_block2048[HEAP_RT_COUNT2048]; + +/* Heap memory map for modules */ +static SHARED_DATA struct block_map rt_heap_map[] = { + BLOCK_DEF(16, HEAP_RT_COUNT16, mod_block16), + BLOCK_DEF(32, HEAP_RT_COUNT32, mod_block32), + BLOCK_DEF(64, HEAP_RT_COUNT64, mod_block64), + BLOCK_DEF(128, HEAP_RT_COUNT128, mod_block128), + BLOCK_DEF(256, HEAP_RT_COUNT256, mod_block256), + BLOCK_DEF(512, HEAP_RT_COUNT512, mod_block512), + BLOCK_DEF(1024, HEAP_RT_COUNT1024, mod_block1024), + BLOCK_DEF(2048, HEAP_RT_COUNT2048, mod_block2048), +}; + +/* Heap blocks for buffers */ +static SHARED_DATA struct block_hdr buf_block[HEAP_BUFFER_COUNT]; + +/* Heap memory map for buffers */ +static SHARED_DATA struct block_map buf_heap_map[] = { + BLOCK_DEF(HEAP_BUFFER_BLOCK_SIZE, HEAP_BUFFER_COUNT, buf_block), +}; + +static SHARED_DATA struct mm memmap = { + .system[0] = { + .heap = HEAP_SYSTEM_BASE, + .size = HEAP_SYSTEM_SIZE, + .info = {.free = HEAP_SYSTEM_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, + }, + .system_runtime[0] = { + .blocks = ARRAY_SIZE(sys_rt_heap_map), + .map = sys_rt_heap_map, + .heap = HEAP_SYS_RUNTIME_BASE, + .size = HEAP_SYS_RUNTIME_SIZE, + .info = {.free = HEAP_SYS_RUNTIME_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, + }, + .runtime[0] = { + .blocks = ARRAY_SIZE(rt_heap_map), + .map = rt_heap_map, + .heap = HEAP_RUNTIME_BASE, + .size = HEAP_RUNTIME_SIZE, + .info = {.free = HEAP_RUNTIME_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, + }, + .buffer[0] = { + .blocks = ARRAY_SIZE(buf_heap_map), + .map = buf_heap_map, + .heap = HEAP_BUFFER_BASE, + .size = HEAP_BUFFER_SIZE, + .info = {.free = HEAP_BUFFER_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA | SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_HP, + }, + .total = {.free = HEAP_SYSTEM_SIZE + HEAP_SYS_RUNTIME_SIZE + + HEAP_RUNTIME_SIZE + HEAP_BUFFER_SIZE,}, +}; + +void platform_init_memmap(struct sof *sof) +{ + /* memmap has been initialized statically as a part of .data */ + sof->memory_map = &memmap; +} diff --git a/src/platform/amd/rembrandt/platform.c b/src/platform/amd/rembrandt/platform.c new file mode 100644 index 000000000000..91af2f069fea --- /dev/null +++ b/src/platform/amd/rembrandt/platform.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2022 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// Bala Kishore + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct sof; +static const struct sof_ipc_fw_ready ready + __attribute__((section(".fw_ready"))) = { + .hdr = { + .cmd = SOF_IPC_FW_READY, + .size = sizeof(struct sof_ipc_fw_ready), + }, + /* dspbox is for DSP initiated IPC, hostbox is for host initiated IPC */ + .version = { + .hdr.size = sizeof(struct sof_ipc_fw_version), + .micro = SOF_MICRO, + .minor = SOF_MINOR, + .major = SOF_MAJOR, +#ifdef DEBUG_BUILD + /* only added in debug for reproducability in releases */ + .build = SOF_BUILD, + .date = __DATE__, + .time = __TIME__, +#endif + .tag = SOF_TAG, + .abi_version = SOF_ABI_VERSION, + }, + .flags = DEBUG_SET_FW_READY_FLAGS, +}; + +static SHARED_DATA struct timer timer = { + .id = TIMER0, + .irq = IRQ_NUM_TIMER0, +}; + +int platform_init(struct sof *sof) +{ + int ret; + + sof->platform_timer = &timer; + sof->cpu_timers = &timer; + /* to view system memory */ + platform_interrupt_init(); + platform_clock_init(sof); + scheduler_init_edf(); + /* init low latency domains and schedulers */ + /* CONFIG_SYSTICK_PERIOD set as PLATFORM_DEFAULT_CLOCK */ + sof->platform_timer_domain = timer_domain_init(sof->platform_timer, + PLATFORM_DEFAULT_CLOCK); + scheduler_init_ll(sof->platform_timer_domain); + platform_timer_start(sof->platform_timer); + /*CONFIG_SYSTICK_PERIOD hardcoded as 200000*/ + sa_init(sof, 200000); + clock_set_freq(CLK_CPU(cpu_get_id()), CLK_MAX_CPU_HZ); + /* init DMA */ + ret = acp_dma_init(sof); + if (ret < 0) + return -ENODEV; + /* Init DMA platform domain */ + sof->platform_dma_domain = dma_multi_chan_domain_init(&sof->dma_info->dma_array[0], + sizeof(sof->dma_info->dma_array), PLATFORM_DEFAULT_CLOCK, true); + scheduler_init_ll(sof->platform_dma_domain); + /* initialize the host IPC mechanisms */ + ipc_init(sof); + /* initialize the DAI mechanisms */ + ret = dai_init(sof); + if (ret < 0) + return -ENODEV; +#if CONFIG_TRACE + /* Initialize DMA for Trace*/ + trace_point(TRACE_BOOT_PLATFORM_DMA_TRACE); + sof->dmat->config.elem_array.elems = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + sizeof(struct dma_sg_elem) * 1); + sof->dmat->config.elem_array.count = 1; + sof->dmat->config.elem_array.elems->dest = 0x03800000; + sof->dmat->config.elem_array.elems->size = 65536; + sof->dmat->config.scatter = 0; + dma_trace_init_complete(sof->dmat); +#endif + /* show heap status */ + heap_trace_all(1); + return 0; +} + +int platform_boot_complete(uint32_t boot_message) +{ + acp_sw_intr_trig_t swintrtrig; + + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + mailbox_dspbox_write(0, &ready, sizeof(ready)); + pscratch_mem_cfg->acp_dsp_msg_write = 1; + acp_dsp_to_host_intr_trig(); + /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + swintrtrig = (acp_sw_intr_trig_t)io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + swintrtrig.bits.trig_dsp0_to_host_intr = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), swintrtrig.u32all); + clock_set_freq(CLK_CPU(cpu_get_id()), CLK_DEFAULT_CPU_HZ); + return 0; +} +int platform_context_save(struct sof *sof) +{ + return 0; +} diff --git a/src/platform/amd/rembrandt/rembrandt.x.in b/src/platform/amd/rembrandt/rembrandt.x.in new file mode 100644 index 000000000000..c44808ec3cd1 --- /dev/null +++ b/src/platform/amd/rembrandt/rembrandt.x.in @@ -0,0 +1,577 @@ +/* + * Linker Script for AMD Rembrandt + * + * This script is run through the GNU C preprocessor to align the memory + * offsets with headers. + * + * Use spaces for formatting as cpp ignore tab sizes. + */ + +#include +#include + +OUTPUT_ARCH(xtensa) + +MEMORY +{ + vector_reset_text : + org = XCHAL_RESET_VECTOR_PADDR, + len = SOF_MEM_RESET_TEXT_SIZE + vector_reset_lit : + org = XCHAL_RESET_VECTOR_PADDR + SOF_MEM_RESET_TEXT_SIZE, + len = SOF_MEM_RESET_LIT_SIZE + vector_base_text : + org = XCHAL_WINDOW_VECTORS_VADDR, //XCHAL_VECBASE_RESET_PADDR, + len = SOF_MEM_VECBASE_LIT_SIZE + vector_int2_lit : + org = XCHAL_INTLEVEL2_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int2_text : + org = XCHAL_INTLEVEL2_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int3_lit : + org = XCHAL_INTLEVEL3_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int3_text : + org = XCHAL_INTLEVEL3_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int4_lit : + org = XCHAL_INTLEVEL4_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int4_text : + org = XCHAL_INTLEVEL4_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int5_lit : + org = XCHAL_INTLEVEL5_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int5_text : + org = XCHAL_INTLEVEL5_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int6_lit : + org = XCHAL_INTLEVEL6_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int6_text : + org = XCHAL_INTLEVEL6_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + + vector_int7_lit : + org = XCHAL_INTLEVEL7_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int7_text : + org = XCHAL_INTLEVEL7_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_kernel_lit : + org = XCHAL_KERNEL_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_kernel_text : + org = XCHAL_KERNEL_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_user_lit : + org = XCHAL_USER_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_user_text : + org = XCHAL_USER_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_double_lit : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_double_text : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + sof_iram_text_start : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR + SOF_MEM_VECT_TEXT_SIZE, + len = IRAM_BASE + (XCHAL_DOUBLEEXC_VECTOR_PADDR + SOF_MEM_VECT_TEXT_SIZE) + sof_sdram0 : + org = DRAM0_BASE, + len = DRAM0_SIZE + system_heap : + org = HEAP_SYSTEM_BASE, + len = HEAP_SYSTEM_SIZE + system_runtime_heap : + org = HEAP_SYS_RUNTIME_BASE, + len = HEAP_SYS_RUNTIME_SIZE + runtime_heap : + org = HEAP_RUNTIME_BASE, + len = HEAP_RUNTIME_SIZE + buffer_heap : + org = HEAP_BUFFER_BASE, + len = HEAP_BUFFER_SIZE + sof_stack : + org = SOF_STACK_BASE, + len = SOF_STACK_BASE - SOF_STACK_END, +sof_sdram1 : + org = HEAP_BUFFER_BASE + HEAP_BUFFER_SIZE, + len = DRAM1_SIZE- (HEAP_SYSTEM_SIZE +HEAP_SYS_RUNTIME_SIZE + HEAP_RUNTIME_SIZE + HEAP_BUFFER_SIZE + SOF_STACK_SIZE ) + static_uuid_entries_seg (!ari) : + org = UUID_ENTRY_ELF_BASE, + len = UUID_ENTRY_ELF_SIZE + static_log_entries_seg (!ari) : + org = LOG_ENTRY_ELF_BASE, + len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE +} + +PHDRS +{ + vector_reset_text_phdr PT_LOAD; + vector_reset_lit_phdr PT_LOAD; + vector_base_text_phdr PT_LOAD; + vector_base_lit_phdr PT_LOAD; + vector_int2_text_phdr PT_LOAD; + vector_int2_lit_phdr PT_LOAD; + vector_int3_text_phdr PT_LOAD; + vector_int3_lit_phdr PT_LOAD; + vector_int4_text_phdr PT_LOAD; + vector_int4_lit_phdr PT_LOAD; + vector_int5_text_phdr PT_LOAD; + vector_int5_lit_phdr PT_LOAD; + vector_int6_text_phdr PT_LOAD; + vector_int6_lit_phdr PT_LOAD; + vector_int7_text_phdr PT_LOAD; + vector_int7_lit_phdr PT_LOAD; + vector_kernel_text_phdr PT_LOAD; + vector_kernel_lit_phdr PT_LOAD; + vector_user_text_phdr PT_LOAD; + vector_user_lit_phdr PT_LOAD; + vector_double_text_phdr PT_LOAD; + vector_double_lit_phdr PT_LOAD; + sof_iram_text_start_phdr PT_LOAD; + sof_sdram0_phdr PT_LOAD; + sof_stack_phdr PT_LOAD; + system_heap_phdr PT_LOAD; + system_runtime_heap_phdr PT_LOAD; + runtime_heap_phdr PT_LOAD; + buffer_heap_phdr PT_LOAD; + sof_sdram1_phdr PT_LOAD; + static_uuid_entries_phdr PT_NOTE; + static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; +} + +/* Default entry point: */ +ENTRY(_ResetVector) +_rom_store_table = 0; + +/* ABI0 does not use Window base */ +PROVIDE(_memmap_vecbase_reset = XCHAL_WINDOW_VECTORS_VADDR); + +/* Various memory-map dependent cache attribute settings: */ +_memmap_cacheattr_wb_base = 0x44024000; +_memmap_cacheattr_wt_base = 0x11021000; +_memmap_cacheattr_bp_base = 0x22022000; +_memmap_cacheattr_unused_mask = 0x00F00FFF; +_memmap_cacheattr_wb_trapnull = 0x4422422F; +_memmap_cacheattr_wba_trapnull = 0x4422422F; +_memmap_cacheattr_wbna_trapnull = 0x25222222; +_memmap_cacheattr_wt_trapnull = 0x1122122F; +_memmap_cacheattr_bp_trapnull = 0x2222222F; +_memmap_cacheattr_wb_strict = 0x44F24FFF; +_memmap_cacheattr_wt_strict = 0x11F21FFF; +_memmap_cacheattr_bp_strict = 0x22F22FFF; +_memmap_cacheattr_wb_allvalid = 0x44224222; +_memmap_cacheattr_wt_allvalid = 0x11221222; +_memmap_cacheattr_bp_allvalid = 0x22222222; +PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + + +SECTIONS +{ + .ResetVector.text : ALIGN(4) + { + _ResetVector_text_start = ABSOLUTE(.); + KEEP (*(.ResetVector.text)) + _ResetVector_text_end = ABSOLUTE(.); + } >vector_reset_text :vector_reset_text_phdr + + .ResetVector.literal : ALIGN(4) + { + _ResetVector_literal_start = ABSOLUTE(.); + *(.ResetVector.literal) + _ResetVector_literal_end = ABSOLUTE(.); + } >vector_reset_lit :vector_reset_lit_phdr + + .WindowVectors.text : ALIGN(4) + { + _WindowVectors_text_start = ABSOLUTE(.); + KEEP (*(.WindowVectors.text)) + _WindowVectors_text_end = ABSOLUTE(.); + } >vector_base_text :vector_base_text_phdr + + .Level2InterruptVector.literal : ALIGN(4) + { + _Level2InterruptVector_literal_start = ABSOLUTE(.); + *(.Level2InterruptVector.literal) + _Level2InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int2_lit :vector_int2_lit_phdr + + .Level2InterruptVector.text : ALIGN(4) + { + _Level2InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level2InterruptVector.text)) + _Level2InterruptVector_text_end = ABSOLUTE(.); + } >vector_int2_text :vector_int2_text_phdr + + .Level3InterruptVector.literal : ALIGN(4) + { + _Level3InterruptVector_literal_start = ABSOLUTE(.); + *(.Level3InterruptVector.literal) + _Level3InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int3_lit :vector_int3_lit_phdr + + .Level3InterruptVector.text : ALIGN(4) + { + _Level3InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level3InterruptVector.text)) + _Level3InterruptVector_text_end = ABSOLUTE(.); + } >vector_int3_text :vector_int3_text_phdr + + .Level4InterruptVector.literal : ALIGN(4) + { + _Level4InterruptVector_literal_start = ABSOLUTE(.); + *(.Level4InterruptVector.literal) + _Level4InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int4_lit :vector_int4_lit_phdr + + .Level4InterruptVector.text : ALIGN(4) + { + _Level4InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level4InterruptVector.text)) + _Level4InterruptVector_text_end = ABSOLUTE(.); + } >vector_int4_text :vector_int4_text_phdr + + .Level5InterruptVector.literal : ALIGN(4) + { + _Level5InterruptVector_literal_start = ABSOLUTE(.); + *(.Level5InterruptVector.literal) + _Level5InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int5_lit :vector_int5_lit_phdr + + .Level5InterruptVector.text : ALIGN(4) + { + _Level5InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level5InterruptVector.text)) + _Level5InterruptVector_text_end = ABSOLUTE(.); + } >vector_int5_text :vector_int5_text_phdr + + .DebugExceptionVector.literal : ALIGN(4) + { + _DebugExceptionVector_literal_start = ABSOLUTE(.); + *(.DebugExceptionVector.literal) + _DebugExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int6_lit :vector_int6_lit_phdr + + .DebugExceptionVector.text : ALIGN(4) + { + _DebugExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DebugExceptionVector.text)) + _DebugExceptionVector_text_end = ABSOLUTE(.); + } >vector_int6_text :vector_int6_text_phdr + + .NMIExceptionVector.literal : ALIGN(4) + { + _NMIExceptionVector_literal_start = ABSOLUTE(.); + *(.NMIExceptionVector.literal) + _NMIExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int7_lit :vector_int5_lit_phdr + + .NMIExceptionVector.text : ALIGN(4) + { + _NMIExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.NMIExceptionVector.text)) + _NMIExceptionVector_text_end = ABSOLUTE(.); + } >vector_int7_text :vector_int5_text_phdr + + .KernelExceptionVector.literal : ALIGN(4) + { + _KernelExceptionVector_literal_start = ABSOLUTE(.); + *(.KernelExceptionVector.literal) + _KernelExceptionVector_literal_end = ABSOLUTE(.); + } >vector_kernel_lit :vector_kernel_lit_phdr + + .KernelExceptionVector.text : ALIGN(4) + { + _KernelExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.KernelExceptionVector.text)) + _KernelExceptionVector_text_end = ABSOLUTE(.); + } >vector_kernel_text :vector_kernel_text_phdr + + .UserExceptionVector.literal : ALIGN(4) + { + _UserExceptionVector_literal_start = ABSOLUTE(.); + *(.UserExceptionVector.literal) + _UserExceptionVector_literal_end = ABSOLUTE(.); + } >vector_user_lit :vector_user_lit_phdr + + .UserExceptionVector.text : ALIGN(4) + { + _UserExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.UserExceptionVector.text)) + _UserExceptionVector_text_end = ABSOLUTE(.); + } >vector_user_text :vector_user_text_phdr + + .DoubleExceptionVector.literal : ALIGN(4) + { + _DoubleExceptionVector_literal_start = ABSOLUTE(.); + *(.DoubleExceptionVector.literal) + _DoubleExceptionVector_literal_end = ABSOLUTE(.); + } >vector_double_lit :vector_double_lit_phdr + + .DoubleExceptionVector.text : ALIGN(4) + { + _DoubleExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DoubleExceptionVector.text)) + _DoubleExceptionVector_text_end = ABSOLUTE(.); + } >vector_double_text :vector_double_text_phdr + + .iram.text : ALIGN(4) + { + _stext = .; + _iram_text_start = ABSOLUTE(.); + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + _iram_text_end = ABSOLUTE(.); + } >sof_iram_text_start :sof_iram_text_start_phdr + + /* stack */ + _end = SOF_STACK_END; + PROVIDE(end = SOF_STACK_END); + _stack_sentry = SOF_STACK_END; + __stack = SOF_STACK_BASE; + + .text : ALIGN(4) + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.entry.text) + *(.init.literal) + KEEP(*(.init)) + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + KEEP(*(.fini)) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >sof_iram_text_start :sof_iram_text_start_phdr + + + .rodata : ALIGN(4) + { + _rodata_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); + KEEP (*(.xt_except_table)) + KEEP (*(.gcc_except_table)) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + KEEP (*(.eh_frame)) + /* C++ constructor and destructor tables, properly ordered: */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); /* this table MUST be 4-byte aligned */ + _bss_table_start = ABSOLUTE(.); + LONG(_bss_start) + LONG(_bss_end) + _bss_table_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + } >sof_sdram0 :sof_sdram0_phdr + + .module_init : ALIGN(4) + { + _module_init_start = ABSOLUTE(.); + *(*.initcall) + _module_init_end = ABSOLUTE(.); + } >sof_sdram0 :sof_sdram0_phdr + + .data : ALIGN(4) + { + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + KEEP(*(.gnu.linkonce.d.*personality*)) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + KEEP(*(.jcr)) + _trace_ctx_start = ABSOLUTE(.); + *(.trace_ctx) + _trace_ctx_end = ABSOLUTE(.); + _data_end = ABSOLUTE(.); + } >sof_sdram0 :sof_sdram0_phdr + + .lit4 : ALIGN(4) + { + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + } >sof_sdram0 :sof_sdram0_phdr + + .fw_ready : ALIGN(4) + { + KEEP (*(.fw_ready)) + } >sof_sdram0 :sof_sdram0_phdr + + + .bss (NOLOAD) : ALIGN(8) + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } >sof_sdram0 :sof_sdram0_phdr + + +.sof_stack (NOLOAD) : ALIGN(8) + { + . = ALIGN (4096); + _sof_stack_start = ABSOLUTE(.); + . = . + SOF_STACK_TOTAL_SIZE; + _sof_stack_end = ABSOLUTE(.); + } >sof_stack :sof_stack_phdr + + .reset.rodata : ALIGN(4) + { + _reset_rodata_start = ABSOLUTE(.); + *(.reset.rodata) + _reset_rodata_end = ABSOLUTE(.); + } >sof_sdram0 :sof_sdram0_phdr + + .system_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (32); + _system_heap_start = ABSOLUTE(.); + . = . + HEAP_SYSTEM_SIZE; + _system_heap_end = ABSOLUTE(.); + } >system_heap :system_heap_phdr + + .system_runtime_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (HEAP_BUF_ALIGNMENT); + _system_runtime_heap_start = ABSOLUTE(.); + . = . + HEAP_SYS_RUNTIME_SIZE; + _system_runtime_heap_end = ABSOLUTE(.); + } >system_runtime_heap :system_runtime_heap_phdr + + .runtime_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (32); + _runtime_heap_start = ABSOLUTE(.); + . = . + HEAP_RUNTIME_SIZE; + _runtime_heap_end = ABSOLUTE(.); + } >runtime_heap :runtime_heap_phdr + + .buffer_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (HEAP_BUF_ALIGNMENT); + _buffer_heap_start = ABSOLUTE(.); + . = . + HEAP_BUFFER_SIZE; + _buffer_heap_end = ABSOLUTE(.); + } >buffer_heap :buffer_heap_phdr + + .static_uuid_entries (COPY) : ALIGN(1024) + { + *(*.static_uuids) + } > static_uuid_entries_seg :static_uuid_entries_phdr + + .static_log_entries (COPY) : ALIGN(1024) + { + *(*.static_log*) + } > static_log_entries_seg :static_log_entries_phdr + + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .xt.insn 0 : + { + KEEP (*(.xt.insn)) + KEEP (*(.gnu.linkonce.x.*)) + } + .xt.prop 0 : + { + KEEP (*(.xt.prop)) + KEEP (*(.xt.prop.*)) + KEEP (*(.gnu.linkonce.prop.*)) + } + .xt.lit 0 : + { + KEEP (*(.xt.lit)) + KEEP (*(.xt.lit.*)) + KEEP (*(.gnu.linkonce.p.*)) + } + .xt.profile_range 0 : + { + KEEP (*(.xt.profile_range)) + KEEP (*(.gnu.linkonce.profile_range.*)) + } + .xt.profile_ranges 0 : + { + KEEP (*(.xt.profile_ranges)) + KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) + } + .xt.profile_files 0 : + { + KEEP (*(.xt.profile_files)) + KEEP (*(.gnu.linkonce.xt.profile_files.*)) + } + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr + +} From 040bf243026cb228e5e06c8c6bd3e6a670c20e72 Mon Sep 17 00:00:00 2001 From: Balakishorepati Date: Wed, 13 Apr 2022 22:43:12 +0530 Subject: [PATCH 5/5] dai: support for amd specific hs dai id Add support for hs i2s instance on rembrandt platform. Signed-off-by: Balakishorepati --- src/include/ipc/dai.h | 2 ++ src/include/sof/drivers/acp_dai_dma.h | 24 ++++++++++++++++-------- src/include/sof/lib/dma.h | 3 +-- src/ipc/ipc3/dai.c | 7 +++++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/include/ipc/dai.h b/src/include/ipc/dai.h index 124d391f5fc5..b06b66ff35bb 100644 --- a/src/include/ipc/dai.h +++ b/src/include/ipc/dai.h @@ -89,6 +89,7 @@ enum sof_ipc_dai_type { SOF_DAI_AMD_BT, /**< Amd BT */ SOF_DAI_AMD_SP, /**< Amd SP */ SOF_DAI_AMD_DMIC, /**< Amd DMIC */ + SOF_DAI_AMD_HS, /**< Amd HS */ SOF_DAI_MEDIATEK_AFE /**< Mtk AFE */ }; @@ -117,6 +118,7 @@ struct sof_ipc_dai_config { struct sof_ipc_dai_acp_params acpbt; struct sof_ipc_dai_acp_params acpsp; struct sof_ipc_dai_acpdmic_params acpdmic; + struct sof_ipc_dai_acp_params acphs; struct sof_ipc_dai_afe_params afe; }; } __attribute__((packed, aligned(4))); diff --git a/src/include/sof/drivers/acp_dai_dma.h b/src/include/sof/drivers/acp_dai_dma.h index bc7f64e9b3af..21db03bfee59 100644 --- a/src/include/sof/drivers/acp_dai_dma.h +++ b/src/include/sof/drivers/acp_dai_dma.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2021 AMD. All rights reserved. + * Copyright(c) 2022 AMD. All rights reserved. * * Author: Basavaraj Hiregoudar * Anup Kulkarni @@ -17,7 +17,11 @@ #include #if CONFIG_AMD_BT -#define ACP_BT_ENABLE + #define ACP_BT_ENABLE +#endif + +#if CONFIG_AMD_SP + #define ACP_SP_ENABLE #endif int acp_dma_init(struct sof *sof); @@ -25,19 +29,23 @@ int acp_dma_init(struct sof *sof); #define ACP_DMA_BUFFER_PERIOD_COUNT 2 /* default max number of channels supported */ -#define ACP_DEFAULT_NUM_CHANNELS 2 +#define ACP_DEFAULT_NUM_CHANNELS 2 /* default sample rate */ -#define ACP_DEFAULT_SAMPLE_RATE 48000 +#define ACP_DEFAULT_SAMPLE_RATE 48000 + +#define ACP_DMA_BUFFER_ALIGN 64 +#define ACP_DMA_BUFFER_ALIGN_128 128 +#define ACP_DMA_TRANS_SIZE 64 +#define ACP_DMA_TRANS_SIZE_128 128 +#define ACP_DAI_DMA_BUFFER_PERIOD_COUNT 2 +#define ACP_DRAM_ADDRESS_MASK 0x0FFFFFFF -#define ACP_DMA_BUFFER_ALIGN 64 -#define ACP_DMA_TRANS_SIZE 64 -#define ACP_DAI_DMA_BUFFER_PERIOD_COUNT 2 -#define ACP_DRAM_ADDRESS_MASK 0x0FFFFFFF extern const struct dai_driver acp_spdai_driver; extern const struct dai_driver acp_btdai_driver; extern const struct dai_driver acp_dmic_dai_driver; +extern const struct dai_driver acp_hsdai_driver; /* ACP private data */ struct acp_pdata { diff --git a/src/include/sof/lib/dma.h b/src/include/sof/lib/dma.h index b95581128300..b9c11e8bd32d 100644 --- a/src/include/sof/lib/dma.h +++ b/src/include/sof/lib/dma.h @@ -47,10 +47,9 @@ struct comp_buffer; #define DMA_CAP_HDA BIT(0) /**< HDA DMA */ #define DMA_CAP_GP_LP BIT(1) /**< GP LP DMA */ #define DMA_CAP_GP_HP BIT(2) /**< GP HP DMA */ -#define DMA_CAP_BT BIT(3) /**< DMA I2S */ +#define DMA_CAP_BT BIT(3) /**< BT DMA */ #define DMA_CAP_SP BIT(4) /**< SP DMA */ #define DMA_CAP_DMIC BIT(5) /**< ACP DMA DMIC > */ - /* DMA dev type bitmasks used to define the type of DMA */ #define DMA_DEV_HOST BIT(0) /**< connectable to host */ diff --git a/src/ipc/ipc3/dai.c b/src/ipc/ipc3/dai.c index c780e88c5169..884fdd9ab7d8 100644 --- a/src/ipc/ipc3/dai.c +++ b/src/ipc/ipc3/dai.c @@ -73,6 +73,10 @@ int dai_config_dma_channel(struct comp_dev *dev, void *spec_config) channel = dai_get_handshake(dd->dai, dai->direction, dd->stream_id); break; + case SOF_DAI_AMD_HS: + channel = dai_get_handshake(dd->dai, dai->direction, + dd->stream_id); + break; case SOF_DAI_MEDIATEK_AFE: handshake = dai_get_handshake(dd->dai, dai->direction, dd->stream_id); @@ -157,6 +161,9 @@ int ipc_dai_data_config(struct comp_dev *dev) dev->ipc_config.frame_fmt = SOF_IPC_FRAME_S32_LE; dd->dma_buffer->stream.frame_fmt = dev->ipc_config.frame_fmt; break; + case SOF_DAI_AMD_HS: + dev->ipc_config.frame_fmt = SOF_IPC_FRAME_S16_LE; + break; case SOF_DAI_MEDIATEK_AFE: break; default: