From 715726ac1cfa9be8b72ba8513dfe5f56f73a7110 Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 12:15:22 +0530 Subject: [PATCH 1/9] drivers: amd: create common driver code for different amd platforms - Renoir and Rembrandt have the common functionality. Moving the common code to common folder as per the recommendation from maintainers and to support future platform's common functionality. - Remove unused code. Signed-off-by: SaiSurya, Ch --- src/drivers/CMakeLists.txt | 2 +- src/drivers/amd/CMakeLists.txt | 2 +- src/drivers/amd/common/CMakeLists.txt | 11 + .../amd/{rembrandt => common}/acp_bt_dai.c | 14 +- src/drivers/amd/common/acp_dma.c | 386 ++++++++++++++++ .../amd/{rembrandt => common}/acp_dmic_dai.c | 4 +- src/drivers/amd/common/acp_dmic_dma.c | 223 ++++++++++ src/drivers/amd/common/acp_sp_dma.c | 161 +++++++ src/drivers/amd/common/ipc.c | 102 +++++ src/drivers/amd/{rembrandt => common}/timer.c | 4 +- src/drivers/amd/rembrandt/CMakeLists.txt | 3 - src/drivers/amd/rembrandt/acp_dma.c | 419 +----------------- src/drivers/amd/rembrandt/acp_dmic_dma.c | 202 +-------- src/drivers/amd/rembrandt/acp_sp_dma.c | 158 +------ src/drivers/amd/rembrandt/interrupt.c | 2 +- src/drivers/amd/rembrandt/ipc.c | 86 +--- src/drivers/amd/renoir/CMakeLists.txt | 3 - src/drivers/amd/renoir/acp_bt_dai.c | 96 ---- src/drivers/amd/renoir/acp_dma.c | 416 +---------------- src/drivers/amd/renoir/acp_dmic_dai.c | 171 ------- src/drivers/amd/renoir/acp_dmic_dma.c | 212 +-------- src/drivers/amd/renoir/acp_sp_dma.c | 157 +------ src/drivers/amd/renoir/interrupt.c | 4 +- src/drivers/amd/renoir/ipc.c | 90 +--- src/drivers/amd/renoir/timer.c | 102 ----- 25 files changed, 982 insertions(+), 2048 deletions(-) create mode 100644 src/drivers/amd/common/CMakeLists.txt rename src/drivers/amd/{rembrandt => common}/acp_bt_dai.c (86%) create mode 100644 src/drivers/amd/common/acp_dma.c rename src/drivers/amd/{rembrandt => common}/acp_dmic_dai.c (97%) create mode 100644 src/drivers/amd/common/acp_dmic_dma.c create mode 100644 src/drivers/amd/common/acp_sp_dma.c create mode 100644 src/drivers/amd/common/ipc.c rename src/drivers/amd/{rembrandt => common}/timer.c (94%) delete mode 100644 src/drivers/amd/renoir/acp_bt_dai.c delete mode 100644 src/drivers/amd/renoir/acp_dmic_dai.c delete mode 100644 src/drivers/amd/renoir/timer.c diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt index 0a07372cece6..80267d220df1 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 OR CONFIG_REMBRANDT) +if(CONFIG_AMD) add_subdirectory(amd) endif() diff --git a/src/drivers/amd/CMakeLists.txt b/src/drivers/amd/CMakeLists.txt index ecbccd50e4f8..db3d00b2797f 100644 --- a/src/drivers/amd/CMakeLists.txt +++ b/src/drivers/amd/CMakeLists.txt @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause - +add_subdirectory(common) if(CONFIG_RENOIR) add_subdirectory(renoir) elseif(CONFIG_REMBRANDT) diff --git a/src/drivers/amd/common/CMakeLists.txt b/src/drivers/amd/common/CMakeLists.txt new file mode 100644 index 000000000000..4e74f474d72f --- /dev/null +++ b/src/drivers/amd/common/CMakeLists.txt @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof + acp_dma.c + acp_bt_dai.c + acp_dmic_dai.c + ipc.c + timer.c + acp_sp_dma.c + acp_dmic_dma.c +) diff --git a/src/drivers/amd/rembrandt/acp_bt_dai.c b/src/drivers/amd/common/acp_bt_dai.c similarity index 86% rename from src/drivers/amd/rembrandt/acp_bt_dai.c rename to src/drivers/amd/common/acp_bt_dai.c index 8c5ac623fb5a..9a83af18b16d 100644 --- a/src/drivers/amd/rembrandt/acp_bt_dai.c +++ b/src/drivers/amd/common/acp_bt_dai.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BSD-3-Clause // -//Copyright(c) 2022 AMD. All rights reserved. +//Copyright(c) 2023 AMD. All rights reserved. // //Author: Basavaraj Hiregoudar -// Bala Kishore +// SaiSurya, Ch #include #include @@ -18,22 +18,22 @@ #include #include -/* 4abd71ba-8619-458a-b33f-160fc0cf809b */ -DECLARE_SOF_UUID("btdai", btdai_uuid, 0x4abd71ba, 0x8619, 0x458a, - 0xb3, 0x3f, 0x16, 0x0f, 0xc0, 0xcf, 0x80, 0x9b); +/* 20865bfe-b833-4ff9-b22a-0482c3477497 */ +DECLARE_SOF_UUID("btdai", btdai_uuid, 0x20865bfe, 0xb833, 0x4ff9, + 0xb2, 0x2a, 0x04, 0x82, 0xc3, 0x47, 0x74, 0x97); 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, const void *spec_config) { - /* nothing to do on rembrandt */ + /* nothing to do */ return 0; } static int btdai_trigger(struct dai *dai, int cmd, int direction) { - /* nothing to do on rembrandt */ + /* nothing to do */ return 0; } diff --git a/src/drivers/amd/common/acp_dma.c b/src/drivers/amd/common/acp_dma.c new file mode 100644 index 000000000000..f71020ba74ad --- /dev/null +++ b/src/drivers/amd/common/acp_dma.c @@ -0,0 +1,386 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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); + +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 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; + 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 + */ + do { + dma_sts = (acp_dma_ch_sts_t)dma_reg_read(channel->dma, ACP_DMA_CH_STS); + chan_sts = dma_sts.u32all & (1 << channel->index); + if (!chan_sts) + return 0; + } while (platform_timer_get(timer) <= deadline); + + tr_err(&acpdma_tr, "acp-dma: timed out for dma start"); + + return -ETIME; +} + +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); + 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 */ + amd_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; +} + +/* 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_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/common/acp_dmic_dai.c similarity index 97% rename from src/drivers/amd/rembrandt/acp_dmic_dai.c rename to src/drivers/amd/common/acp_dmic_dai.c index d63eeece6f9d..30ee401ce2c1 100644 --- a/src/drivers/amd/rembrandt/acp_dmic_dai.c +++ b/src/drivers/amd/common/acp_dmic_dai.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BSD-3-Clause // -//Copyright(c) 2022 AMD. All rights reserved. +//Copyright(c) 2023 AMD. All rights reserved. // // Author: Basavaraj Hiregoudar -// Bala Kishore +// SaiSurya, Ch #include #include diff --git a/src/drivers/amd/common/acp_dmic_dma.c b/src/drivers/amd/common/acp_dmic_dma.c new file mode 100644 index 000000000000..e53d8924847d --- /dev/null +++ b/src/drivers/amd/common/acp_dmic_dma.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 + +extern uint32_t dmic_rngbuff_size; + +/* dc2199ea-cdae-4d23-a413-ffe442f785f2 */ +DECLARE_SOF_UUID("acp_dmic_dma", acp_dmic_dma_uuid, 0xdc2199ea, 0xcdae, 0x4d23, + 0xa4, 0x13, 0xff, 0xe4, 0x42, 0xf7, 0x85, 0xf2); +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_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_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); +} + +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 >> 1; + *free = dmic_rngbuff_size >> 1; + } else { + tr_err(&acp_dmic_dma_tr, "Channel direction Not defined %d", + channel->direction); + } + + tr_info(&acp_dmic_dma_tr, "avail %d and free %d", + avail[0], free[0]); + 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.u32all = 0; + 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/common/acp_sp_dma.c b/src/drivers/amd/common/acp_sp_dma.c new file mode 100644 index 000000000000..04f3e3c1a7fa --- /dev/null +++ b/src/drivers/amd/common/acp_sp_dma.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 + +/* 2ef92c66-78a4-41f7-b52f-5539707a9382 */ +DECLARE_SOF_UUID("acp-sp", acp_sp_uuid, 0x2ef92c66, 0x78a4, 0x41f7, + 0xb5, 0x2f, 0x55, 0x39, 0x70, 0x7a, 0x93, 0x82); +DECLARE_TR_CTX(acp_sp_tr, SOF_UUID(acp_sp_uuid), LOG_LEVEL_INFO); + +/* 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_release(struct dma_chan_data *channel) +{ + /* nothing to do */ + return 0; +} + +static int acp_dai_sp_dma_pause(struct dma_chan_data *channel) +{ + /* nothing to do */ + 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 */ + 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; +} + +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/common/ipc.c b/src/drivers/amd/common/ipc.c new file mode 100644 index 000000000000..d70b14c7e8bf --- /dev/null +++ b/src/drivers/amd/common/ipc.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 + +/* 49be8ff3-71a3-4456-bb7e-4723f2e5730c */ +DECLARE_SOF_UUID("ipc-task", ipc_task_uuid, 0x49be8ff3, 0x71a3, 0x4456, + 0xbb, 0x7e, 0x47, 0x23, 0xf2, 0xe5, 0x73, 0x0c); + +extern volatile acp_scratch_mem_config_t *pscratch_mem_cfg; + +inline uint32_t sof_ipc_host_status(void) +{ + return (pscratch_mem_cfg->acp_host_ack_write | pscratch_mem_cfg->acp_host_msg_write); +} + +inline uint32_t sof_ipc_host_msg_flag(void) +{ + return pscratch_mem_cfg->acp_host_msg_write; +} + +inline uint32_t sof_ipc_host_ack_flag(void) +{ + return pscratch_mem_cfg->acp_host_ack_write; +} + +inline uint32_t sof_ipc_dsp_status(void) +{ + return (pscratch_mem_cfg->acp_dsp_msg_write | pscratch_mem_cfg->acp_dsp_ack_write); +} + +inline void sof_ipc_host_ack_clear(void) +{ + pscratch_mem_cfg->acp_host_ack_write = 0; +} + +inline void sof_ipc_host_msg_clear(void) +{ + pscratch_mem_cfg->acp_host_msg_write = 0; +} + +inline void sof_ipc_dsp_ack_set(void) +{ + pscratch_mem_cfg->acp_dsp_ack_write = 1; +} + +inline void sof_ipc_dsp_msg_set(void) +{ + pscratch_mem_cfg->acp_dsp_msg_write = 1; +} + +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; +} + +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, amd_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/common/timer.c similarity index 94% rename from src/drivers/amd/rembrandt/timer.c rename to src/drivers/amd/common/timer.c index 615ceadf97a5..e2fa9d3d9e6c 100644 --- a/src/drivers/amd/rembrandt/timer.c +++ b/src/drivers/amd/common/timer.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BSD-3-Clause // -//Copyright(c) 2022 AMD. All rights reserved. +//Copyright(c) 2023 AMD. All rights reserved. // //Author: Basavaraj Hiregoudar -// Bala Kishore +// SaiSurya, Ch #include #include diff --git a/src/drivers/amd/rembrandt/CMakeLists.txt b/src/drivers/amd/rembrandt/CMakeLists.txt index d07a2335b2c6..24e80e3e76d7 100644 --- a/src/drivers/amd/rembrandt/CMakeLists.txt +++ b/src/drivers/amd/rembrandt/CMakeLists.txt @@ -2,13 +2,10 @@ 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 diff --git a/src/drivers/amd/rembrandt/acp_dma.c b/src/drivers/amd/rembrandt/acp_dma.c index 5eb2eb490881..940ba1392077 100644 --- a/src/drivers/amd/rembrandt/acp_dma.c +++ b/src/drivers/amd/rembrandt/acp_dma.c @@ -21,65 +21,9 @@ #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) +void amd_dma_reconfig(struct dma_chan_data *channel, uint32_t bytes) { uint32_t strt_idx = 0; uint32_t src = 0; @@ -179,210 +123,9 @@ static void dma_reconfig(struct dma_chan_data *channel, uint32_t bytes) 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) +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; @@ -425,7 +168,7 @@ static int dma_setup(struct dma_chan_data *channel, dest = sgelems->elems[dscr].dest; dest = (dest & ACP_DRAM_ADDRESS_MASK); dma_config_dscr[dscr_strt_idx + dscr].dest_addr = (dest | ACP_SRAM); - dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.u32All = 0; + 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 { @@ -439,11 +182,11 @@ static int dma_setup(struct dma_chan_data *channel, src = (src & ACP_DRAM_ADDRESS_MASK); dma_config_dscr[dscr_strt_idx + dscr].src_addr = (src | ACP_SRAM);/*rembrandt-arch*/ - dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.u32All = 0; + 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.u32all = 0; dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.bits.trns_cnt = sgelems->elems[dscr].size; buff_size = sgelems->elems[dscr].size; @@ -496,110 +239,7 @@ static int dma_setup(struct dma_chan_data *channel, 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) +int acp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) { switch (type) { case DMA_ATTR_BUFFER_ALIGNMENT: @@ -617,46 +257,3 @@ static int acp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value } 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_dma.c b/src/drivers/amd/rembrandt/acp_dmic_dma.c index 8f90407605e6..32d242171eb6 100644 --- a/src/drivers/amd/rembrandt/acp_dmic_dma.c +++ b/src/drivers/amd/rembrandt/acp_dmic_dma.c @@ -31,52 +31,16 @@ #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); +DECLARE_TR_CTX(acp_dmic_dma_rmb_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; -} +uint32_t dmic_rngbuff_size; -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) +int acp_dmic_dma_start(struct dma_chan_data *channel) { acp_wov_pdm_decimation_factor_t deci_fctr; acp_wov_misc_ctrl_t wov_misc_ctrl; @@ -121,7 +85,7 @@ static int acp_dmic_dma_start(struct dma_chan_data *channel) /* 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"); + tr_err(&acp_dmic_dma_rmb_tr, "timed out for dma start"); return -ETIME; } pdm_dma_enable = (acp_wov_pdm_dma_enable_t) @@ -131,21 +95,7 @@ static int acp_dmic_dma_start(struct dma_chan_data *channel) 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) +int acp_dmic_dma_stop(struct dma_chan_data *channel) { acp_wov_pdm_dma_enable_t pdm_dma_enable; acp_hstdm_iter_t hs_iter; @@ -176,7 +126,7 @@ static int acp_dmic_dma_stop(struct dma_chan_data *channel) /* 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"); + tr_err(&acp_dmic_dma_rmb_tr, "timed out for dma stop"); return -ETIME; } pdm_dma_enable = (acp_wov_pdm_dma_enable_t) @@ -198,20 +148,9 @@ static int acp_dmic_dma_stop(struct dma_chan_data *channel) 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) +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; @@ -240,80 +179,21 @@ static int acp_dmic_dma_set_config(struct dma_chan_data *channel, ACP_WOV_RX_INTR_WATERMARK_SIZE, watermark.u32all); break; default: - tr_err(&acp_dmic_dma_tr, "unsupported config direction"); + tr_err(&acp_dmic_dma_rmb_tr, "unsupported config direction"); return -EINVAL; } if (!config->cyclic) { - tr_err(&acp_dmic_dma_tr, "cyclic configurations only supported!"); + tr_err(&acp_dmic_dma_rmb_tr, "cyclic configurations only supported!"); return -EINVAL; } if (config->scatter) { - tr_err(&acp_dmic_dma_tr, "scatter enabled, not supported for now!"); + tr_err(&acp_dmic_dma_rmb_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 >> 1; - *free = dmic_rngbuff_size >> 1; - } 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) +int acp_dmic_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) { switch (type) { case DMA_ATTR_BUFFER_ALIGNMENT: @@ -331,59 +211,3 @@ static int acp_dmic_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t * } 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.u32all = 0; - 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_sp_dma.c b/src/drivers/amd/rembrandt/acp_sp_dma.c index 69951f4f485b..912e626d727c 100644 --- a/src/drivers/amd/rembrandt/acp_sp_dma.c +++ b/src/drivers/amd/rembrandt/acp_sp_dma.c @@ -31,60 +31,21 @@ #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); +DECLARE_TR_CTX(acp_sp_rmb_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) -#define SP_IER_DISABLE 0x0 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) +int acp_dai_sp_dma_start(struct dma_chan_data *channel) { acp_i2stdm_ier_t sp_ier; acp_i2stdm_iter_t sp_iter; @@ -124,27 +85,14 @@ static int acp_dai_sp_dma_start(struct dma_chan_data *channel) 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); + tr_err(&acp_sp_rmb_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) +int acp_dai_sp_dma_stop(struct dma_chan_data *channel) { acp_i2stdm_irer_t sp_irer; acp_i2stdm_iter_t sp_iter; @@ -170,7 +118,7 @@ static int acp_dai_sp_dma_stop(struct dma_chan_data *channel) 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); + tr_err(&acp_sp_rmb_tr, "Stop direction not defined %d", channel->direction); return -EINVAL; } sp_iter = (acp_i2stdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_ITER)); @@ -189,27 +137,19 @@ static int acp_dai_sp_dma_stop(struct dma_chan_data *channel) 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) +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!"); + tr_err(&acp_sp_rmb_tr, "cyclic configurations only supported!"); return -EINVAL; } if (config->scatter) { - tr_err(&acp_sp_tr, "scatter enabled, that is not supported for now!"); + tr_err(&acp_sp_rmb_tr, "scatter enabled, that is not supported for now!"); return -EINVAL; } @@ -261,63 +201,16 @@ static int acp_dai_sp_dma_set_config(struct dma_chan_data *channel, (sp_buff_size >> 1)); } else { - tr_err(&acp_sp_tr, "DMA Config channel direction undefined %d", channel->direction); + tr_err(&acp_sp_rmb_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) +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; @@ -341,13 +234,13 @@ static int acp_dai_sp_dma_get_data_size(struct dma_chan_data *channel, *free = (sp_buff_size >> 1); *avail = (sp_buff_size >> 1); } else { - tr_err(&acp_sp_tr, "Channel direction not defined %d", channel->direction); + tr_err(&acp_sp_rmb_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) +int acp_dai_sp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) { switch (type) { case DMA_ATTR_BUFFER_ALIGNMENT: @@ -366,7 +259,7 @@ static int acp_dai_sp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t return 0; } -static int acp_dai_sp_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) +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; @@ -405,20 +298,3 @@ static int acp_dai_sp_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_ 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 index e226f2632866..93b03d66978b 100644 --- a/src/drivers/amd/rembrandt/interrupt.c +++ b/src/drivers/amd/rembrandt/interrupt.c @@ -407,7 +407,7 @@ void acp_dsp_to_host_intr_trig(void) io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); } -/* Clear the Acknowledge ( status) for the host to DSP inteerupt */ +/* Clear the Acknowledge ( status) for the host to DSP interrupt */ void acp_ack_intr_from_host(void) { /* acknowledge the host interrupt */ diff --git a/src/drivers/amd/rembrandt/ipc.c b/src/drivers/amd/rembrandt/ipc.c index 99097359dd3d..8628ffecfb4f 100644 --- a/src/drivers/amd/rembrandt/ipc.c +++ b/src/drivers/amd/rembrandt/ipc.c @@ -31,66 +31,21 @@ #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); +#include 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) +void amd_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; - acp_future_reg_aclk_0_t acp_reg_aclk; 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; - acp_reg_aclk = (acp_future_reg_aclk_0_t) - io_reg_read(PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0); if (status) { /* Interrupt source */ if (sof_ipc_host_status()) { @@ -101,9 +56,6 @@ static void irq_handler(void *arg) if (sof_ipc_host_ack_flag()) { /* Clear the ACK from host */ sof_ipc_host_ack_clear(); - acp_reg_aclk.bits.host_aclk = 0; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), - acp_reg_aclk.u32all); /* Clear the Host to DSP Status Register */ acp_ack_intr_from_host(); /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ @@ -118,9 +70,6 @@ static void irq_handler(void *arg) if (sof_ipc_host_msg_flag()) { /* Clear the msg bit from host */ sof_ipc_host_msg_clear(); - acp_reg_aclk.bits.host_msg = 0; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), - acp_reg_aclk.u32all); /* Clear the Host to DSP Status Register */ acp_ack_intr_from_host(); ipc_schedule_process(ipc); @@ -133,26 +82,12 @@ static void irq_handler(void *arg) } } -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; - acp_future_reg_aclk_0_t acp_reg_aclk; /* Set Dsp Ack for msg from host */ sof_ipc_dsp_ack_set(); - acp_reg_aclk = (acp_future_reg_aclk_0_t) - io_reg_read(PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0); - acp_reg_aclk.bits.dsp_aclk = 1; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), acp_reg_aclk.u32all); /* 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); @@ -176,7 +111,6 @@ 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; - acp_future_reg_aclk_0_t acp_reg_aclk; uint32_t status; uint32_t lock; /* Check if host cleared the status for previous messages */ @@ -196,10 +130,6 @@ int ipc_platform_send_msg(const struct ipc_msg *msg) mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); /* Need to set DSP message flag */ sof_ipc_dsp_msg_set(); - acp_reg_aclk = (acp_future_reg_aclk_0_t) - io_reg_read(PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0); - acp_reg_aclk.bits.dsp_msg = 1; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), acp_reg_aclk.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 */ @@ -215,15 +145,3 @@ void ipc_platform_send_msg_direct(const struct ipc_msg *msg) /* TODO: add support */ } -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/renoir/CMakeLists.txt b/src/drivers/amd/renoir/CMakeLists.txt index 2ccb1a622421..3987a52c2446 100644 --- a/src/drivers/amd/renoir/CMakeLists.txt +++ b/src/drivers/amd/renoir/CMakeLists.txt @@ -2,12 +2,9 @@ add_local_sources(sof acp_dma.c - acp_bt_dai.c acp_sp_dai.c - acp_dmic_dai.c interrupt.c ipc.c - timer.c acp_bt_dma.c acp_sp_dma.c acp_dmic_dma.c diff --git a/src/drivers/amd/renoir/acp_bt_dai.c b/src/drivers/amd/renoir/acp_bt_dai.c deleted file mode 100644 index 7546c5eee8b0..000000000000 --- a/src/drivers/amd/renoir/acp_bt_dai.c +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -//Copyright(c) 2021 AMD. All rights reserved. -// -//Author: Basavaraj Hiregoudar -// Anup Kulkarni -// 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, - const void *spec_config) -{ - /* nothing to do on renoir */ - return 0; -} - -static int btdai_trigger(struct dai *dai, int cmd, int direction) -{ - /* nothing to do on renoir */ - 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, "btdai_get_fifo(): 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/renoir/acp_dma.c b/src/drivers/amd/renoir/acp_dma.c index 550dc4444ef4..c21775692ff3 100644 --- a/src/drivers/amd/renoir/acp_dma.c +++ b/src/drivers/amd/renoir/acp_dma.c @@ -22,65 +22,9 @@ #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) +void amd_dma_reconfig(struct dma_chan_data *channel, uint32_t bytes) { uint32_t strt_idx = 0; uint32_t src; @@ -171,211 +115,9 @@ static void dma_reconfig(struct dma_chan_data *channel, uint32_t bytes) 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; - - 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 */ - struct acp_dma_chan_data *acp_dma_chan = dma_chan_get_data(channel); - - 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) +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; @@ -416,7 +158,7 @@ static int dma_setup(struct dma_chan_data *channel, dma_config_dscr[dscr_strt_idx + dscr].src_addr = sgelems->elems[dscr].src & ACP_DRAM_ADDRESS_MASK; } - dma_config_dscr[dscr_strt_idx + dscr].trns_cnt.u32All = 0; + 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; } @@ -464,110 +206,7 @@ static int dma_setup(struct dma_chan_data *channel, 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) +int acp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) { switch (type) { case DMA_ATTR_BUFFER_ALIGNMENT: @@ -585,46 +224,3 @@ static int acp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value } 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; - uint32_t tc; /* transfer count in bytes */ - - tc = acp_dma_chan->config[channel->index].size; - data_size = (int32_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/renoir/acp_dmic_dai.c b/src/drivers/amd/renoir/acp_dmic_dai.c deleted file mode 100644 index cdf1260e1705..000000000000 --- a/src/drivers/amd/renoir/acp_dmic_dai.c +++ /dev/null @@ -1,171 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -//Copyright(c) 2021 AMD. All rights reserved. -// -// Author: Basavaraj Hiregoudar -// Anup Kulkarni -// 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, - const void *spec_config) -{ - dai_info(dai, "ACP: acp_dmic_set_config"); - acp_wov_pdm_no_of_channels_t pdm_channels; - const 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; - pdm_channels.u32all = io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_NO_OF_CHANNELS); - 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_err(dai, "ACP:acp_dmic_set_config unsupported samplerate"); - return -EINVAL; - } - io_reg_write(PU_REGISTER_BASE + ACP_WOV_CLK_CTRL, clk_ctrl.u32all); - switch (acpdata->dmic_params.pdm_ch) { - case 2: - pdm_channels.bits.pdm_no_of_channels = 0; - break; - case 4: - pdm_channels.bits.pdm_no_of_channels = 1; - break; - default: - dai_err(dai, "ACP:acp_dmic_set_config unsupported channels"); - return -EINVAL; - } - io_reg_write(PU_REGISTER_BASE + ACP_WOV_PDM_NO_OF_CHANNELS, - pdm_channels.u32all); - return 0; -} - -static int acp_dmic_dai_trigger(struct dai *dai, int cmd, int direction) -{ - dai_dbg(dai, "acp_dmic_dai_trigger"); - 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, "ACP: acp_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, "acp_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); - - dai_info(dai, "acp_dmic_dai_remove()"); - 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, "acp_dmic_dai_get_fifo(): 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_err(dai, "ACP:unsupported samplerate %d", acpdata->dmic_params.pdm_rate); - return -EINVAL; - } - switch (acpdata->dmic_params.pdm_ch) { - case 2: - case 4: - params->channels = acpdata->dmic_params.pdm_ch; - break; - default: - dai_err(dai, "ACP:unsupported channels %d", acpdata->dmic_params.pdm_ch); - return -EINVAL; - } - 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/renoir/acp_dmic_dma.c b/src/drivers/amd/renoir/acp_dmic_dma.c index 00f40400f8ac..6d2b26a889c2 100644 --- a/src/drivers/amd/renoir/acp_dmic_dma.c +++ b/src/drivers/amd/renoir/acp_dmic_dma.c @@ -31,52 +31,15 @@ #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); +DECLARE_TR_CTX(acp_dmic_dma_rn_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, "ACP_DMIC: 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, "ACP_DMIC: 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; -} +uint32_t dmic_rngbuff_size; -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) +int acp_dmic_dma_start(struct dma_chan_data *channel) { acp_wov_pdm_decimation_factor_t deci_fctr; acp_wov_misc_ctrl_t wov_misc_ctrl; @@ -123,7 +86,7 @@ static int acp_dmic_dma_start(struct dma_chan_data *channel) /* 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, "DMICDMA: timed out for dma start"); + tr_err(&acp_dmic_dma_rn_tr, "DMICDMA: timed out for dma start"); return -ETIME; } pdm_dma_enable = (acp_wov_pdm_dma_enable_t) @@ -133,21 +96,7 @@ static int acp_dmic_dma_start(struct dma_chan_data *channel) return 0; } -static int acp_dmic_dma_release(struct dma_chan_data *channel) -{ - /* nothing to do on renoir */ - tr_dbg(&acp_dmic_dma_tr, "acp_dmic_dma_release()"); - return 0; -} - -static int acp_dmic_dma_pause(struct dma_chan_data *channel) -{ - /* nothing to do on renoir */ - tr_dbg(&acp_dmic_dma_tr, "acp_dmic_dma_pause()"); - return 0; -} - -static int acp_dmic_dma_stop(struct dma_chan_data *channel) +int acp_dmic_dma_stop(struct dma_chan_data *channel) { acp_wov_pdm_dma_enable_t pdm_dma_enable; acp_i2stdm_iter_t sp_iter; @@ -178,7 +127,7 @@ static int acp_dmic_dma_stop(struct dma_chan_data *channel) /* 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, "DMIC-DMA: timed out for dma stop"); + tr_err(&acp_dmic_dma_rn_tr, "DMIC-DMA: timed out for dma stop"); return -ETIME; } pdm_dma_enable = (acp_wov_pdm_dma_enable_t) @@ -201,20 +150,9 @@ static int acp_dmic_dma_stop(struct dma_chan_data *channel) 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) +int acp_dmic_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config) { uint32_t ring_buff_addr; acp_wov_rx_ringbufaddr_t dmic_ringbuff_addr; @@ -245,86 +183,24 @@ static int acp_dmic_dma_set_config(struct dma_chan_data *channel, ACP_WOV_RX_INTR_WATERMARK_SIZE, watermark.u32all); break; default: - tr_err(&acp_dmic_dma_tr, - "dmic dma_set_config() unsupported config direction"); + tr_err(&acp_dmic_dma_rn_tr, + "dmic dma_set_config() unsupported config direction"); return -EINVAL; } if (!config->cyclic) { - tr_err(&acp_dmic_dma_tr, - "DMIC DMA: cyclic configurations only supported!"); + tr_err(&acp_dmic_dma_rn_tr, + "DMIC DMA: cyclic configurations only supported!"); return -EINVAL; } if (config->scatter) { - tr_err(&acp_dmic_dma_tr, - "DMIC DMA: scatter enabled, not supported for now!"); + tr_err(&acp_dmic_dma_rn_tr, + "DMIC DMA: 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, "ACP_DMIC_DMA: Repeated probe"); - return -EEXIST; - } - tr_dbg(&acp_dmic_dma_tr, "ACP_DMIC_DMA: probe"); - 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, - "ACP_DMIC_DMA: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, - "ACP_DMIC_DMA: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 >> 1; - *free = dmic_rngbuff_size >> 1; - } 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) +int acp_dmic_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) { switch (type) { case DMA_ATTR_BUFFER_ALIGNMENT: @@ -342,59 +218,3 @@ static int acp_dmic_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t * } 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.u32all = 0; - 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/renoir/acp_sp_dma.c b/src/drivers/amd/renoir/acp_sp_dma.c index aeee79cfd781..9000657aa998 100644 --- a/src/drivers/amd/renoir/acp_sp_dma.c +++ b/src/drivers/amd/renoir/acp_sp_dma.c @@ -32,57 +32,19 @@ #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_IER_DISABLE 0x0 + 0xa2, 0xc5, 0xdf, 0xf0, 0xd1, 0xfa, 0x13, 0x92); +DECLARE_TR_CTX(acp_sp_rn_tr, SOF_UUID(acp_sp_uuid), LOG_LEVEL_INFO); static uint64_t prev_tx_pos; static uint64_t prev_rx_pos; static uint32_t sp_buff_size_playback; static uint32_t sp_buff_size_capture; /* 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) +int acp_dai_sp_dma_start(struct dma_chan_data *channel) { acp_i2stdm_ier_t sp_ier; acp_i2stdm_iter_t sp_iter; @@ -119,26 +81,14 @@ static int acp_dai_sp_dma_start(struct dma_chan_data *channel) 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); + tr_err(&acp_sp_rn_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 renoir */ - return 0; -} - -static int acp_dai_sp_dma_pause(struct dma_chan_data *channel) -{ - /* nothing to do on renoir */ - return 0; -} - -static int acp_dai_sp_dma_stop(struct dma_chan_data *channel) +int acp_dai_sp_dma_stop(struct dma_chan_data *channel) { acp_i2stdm_irer_t sp_irer; acp_i2stdm_iter_t sp_iter; @@ -164,7 +114,7 @@ static int acp_dai_sp_dma_stop(struct dma_chan_data *channel) 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); + tr_err(&acp_sp_rn_tr, "Stop direction not defined %d", channel->direction); return -EINVAL; } sp_iter = (acp_i2stdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_ITER)); @@ -183,27 +133,19 @@ static int acp_dai_sp_dma_stop(struct dma_chan_data *channel) 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 renoir */ - 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) +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!"); + tr_err(&acp_sp_rn_tr, "cyclic configurations only supported!"); return -EINVAL; } if (config->scatter) { - tr_err(&acp_sp_tr, "scatter enabled, that is not supported for now!"); + tr_err(&acp_sp_rn_tr, "scatter enabled, that is not supported for now!"); return -EINVAL; } @@ -258,62 +200,15 @@ static int acp_dai_sp_dma_set_config(struct dma_chan_data *channel, (sp_buff_size_capture >> 1)); } else { - tr_err(&acp_sp_tr, "config channel direction undefined %d", channel->direction); + tr_err(&acp_sp_rn_tr, "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) +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; @@ -339,13 +234,13 @@ static int acp_dai_sp_dma_get_data_size(struct dma_chan_data *channel, *avail = (sp_buff_size_capture >> 1); *free = (sp_buff_size_capture >> 1); } else { - tr_err(&acp_sp_tr, "Channel direction not defined %d", channel->direction); + tr_err(&acp_sp_rn_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) +int acp_dai_sp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value) { switch (type) { case DMA_ATTR_BUFFER_ALIGNMENT: @@ -364,7 +259,7 @@ static int acp_dai_sp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t return 0; } -static int acp_dai_sp_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) +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; @@ -403,21 +298,3 @@ static int acp_dai_sp_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_ 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/renoir/interrupt.c b/src/drivers/amd/renoir/interrupt.c index fcede00a6f14..487ef620f810 100644 --- a/src/drivers/amd/renoir/interrupt.c +++ b/src/drivers/amd/renoir/interrupt.c @@ -359,7 +359,7 @@ void acp_dsp_sw_intr_disable(void) } /* This function triggers a host interrupt from ACP DSP */ -void acp_dsp_to_host_Intr_trig(void) +void acp_dsp_to_host_intr_trig(void) { acp_sw_intr_trig_t sw_intr_trig; /* Read the Software Interrupt controller register and update */ @@ -370,7 +370,7 @@ void acp_dsp_to_host_Intr_trig(void) io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); } -/* Clear the Acknowledge ( status) for the host to DSP inteerupt */ +/* Clear the Acknowledge ( status) for the host to DSP interrupt */ void acp_ack_intr_from_host(void) { /* acknowledge the host interrupt */ diff --git a/src/drivers/amd/renoir/ipc.c b/src/drivers/amd/renoir/ipc.c index a5a89cd5b92b..b718f57540ba 100644 --- a/src/drivers/amd/renoir/ipc.c +++ b/src/drivers/amd/renoir/ipc.c @@ -32,54 +32,12 @@ #include #include #include - -/* 49be8ff3-71a3-4456-bb7e-4723f2e5730c */ -DECLARE_SOF_UUID("renoir-ipc-task", ipc_task_uuid, 0x49be8ff3, 0x71a3, 0x4456, - 0xbb, 0x7e, 0x47, 0x23, 0xf2, 0xe5, 0x73, 0x0c); +#include volatile acp_scratch_mem_config_t *pscratch_mem_cfg = (volatile acp_scratch_mem_config_t *) (PU_REGISTER_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) +void amd_irq_handler(void *arg) { struct ipc *ipc = arg; uint32_t status; @@ -88,12 +46,9 @@ static void irq_handler(void *arg) bool lock_fail = false; acp_dsp_sw_intr_stat_t swintrstat; acp_sw_intr_trig_t swintrtrig; - acp_future_reg_aclk_0_t acp_reg_aclk; 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; - acp_reg_aclk = (acp_future_reg_aclk_0_t) - io_reg_read(PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0); if (status) { /* Interrupt source */ if (sof_ipc_host_status()) { @@ -114,9 +69,6 @@ static void irq_handler(void *arg) if (sof_ipc_host_ack_flag()) { /* Clear the ACK from host */ sof_ipc_host_ack_clear(); - acp_reg_aclk.bits.host_aclk = 0; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), - acp_reg_aclk.u32all); /* Clear the Host to DSP Status Register */ acp_ack_intr_from_host(); /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ @@ -131,9 +83,6 @@ static void irq_handler(void *arg) if (sof_ipc_host_msg_flag()) { /* Clear the msg bit from host */ sof_ipc_host_msg_clear(); - acp_reg_aclk.bits.host_msg = 0; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), - acp_reg_aclk.u32all); /* Clear the Host to DSP Status Register */ acp_ack_intr_from_host(); ipc_schedule_process(ipc); @@ -146,26 +95,12 @@ static void irq_handler(void *arg) } } -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; - acp_future_reg_aclk_0_t acp_reg_aclk; /* Set Dsp Ack for msg from host */ sof_ipc_dsp_ack_set(); - acp_reg_aclk = (acp_future_reg_aclk_0_t) - io_reg_read(PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0); - acp_reg_aclk.bits.dsp_aclk = 1; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), acp_reg_aclk.u32all); /* 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); @@ -173,7 +108,7 @@ void ipc_platform_complete_cmd(struct ipc *ipc) 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(); + acp_dsp_to_host_intr_trig(); if (ipc->pm_prepare_D3) { while (1) wait_for_interrupt(0); @@ -184,7 +119,6 @@ int ipc_platform_send_msg(const struct ipc_msg *msg) { acp_sw_intr_trig_t sw_intr_trig; acp_dsp_sw_intr_stat_t sw_intr_stat; - acp_future_reg_aclk_0_t acp_reg_aclk; uint32_t status; uint32_t lock; uint32_t delay_cnt = 10000; @@ -212,12 +146,8 @@ int ipc_platform_send_msg(const struct ipc_msg *msg) /* Need to set DSP message flag */ sof_ipc_dsp_msg_set(); - acp_reg_aclk = (acp_future_reg_aclk_0_t) - io_reg_read(PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0); - acp_reg_aclk.bits.dsp_msg = 1; - io_reg_write((PU_REGISTER_BASE + ACP_FUTURE_REG_ACLK_0), acp_reg_aclk.u32all); /* now interrupt host to tell it we have sent a message */ - acp_dsp_to_host_Intr_trig(); + 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; @@ -231,15 +161,3 @@ void ipc_platform_send_msg_direct(const struct ipc_msg *msg) /* TODO: add support */ } -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/renoir/timer.c b/src/drivers/amd/renoir/timer.c deleted file mode 100644 index 8a0b80cccaf0..000000000000 --- a/src/drivers/amd/renoir/timer.c +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -//Copyright(c) 2021 AMD. All rights reserved. -// -//Author: Basavaraj Hiregoudar -// Anup Kulkarni -// 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 6cf3c87d207834c63bbbd10f6dbeb080373397c7 Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 12:44:53 +0530 Subject: [PATCH 2/9] platform: amd: create common platform code for different amd platforms - Renoir and rembrandt have the common functionality. Moving the common code to common folder as per the recommendation from maintainers and to support future platform's common functionality. - Remove unused code. Signed-off-by: SaiSurya, Ch --- src/arch/xtensa/CMakeLists.txt | 4 ++ src/platform/CMakeLists.txt | 2 +- src/platform/Kconfig | 10 +++ src/platform/amd/CMakeLists.txt | 1 + src/platform/amd/common/CMakeLists.txt | 3 + .../amd/common/include/platform/acp_dma.h | 54 ++++++++++++++++ .../common/include/platform/acp_dmic_dma.h | 23 +++++++ .../amd/common/include/platform/acp_sp_dma.h | 27 ++++++++ .../include/platform/drivers/idc.h | 4 +- .../amd/common/include/platform/ipc.h | 23 +++++++ .../include/platform/lib/clk.h | 6 +- .../include/platform/lib/cpu.h | 4 +- .../include/platform/lib/dai.h | 4 +- .../include/platform/lib/dma.h | 4 +- .../include/platform/lib/mailbox.h | 4 +- .../include/platform/lib/pm_runtime.h | 4 +- .../include/platform/trace/trace.h | 4 +- .../include/platform/chip_offset_byte.h | 1 - .../include/platform/chip_registers.h | 11 ---- .../include/platform/fw_scratch_mem.h | 2 +- .../include/platform/chip_offset_byte.h | 1 - .../renoir/include/platform/chip_registers.h | 11 ---- .../amd/renoir/include/platform/drivers/idc.h | 29 --------- .../include/platform/drivers/interrupt.h | 2 +- .../renoir/include/platform/fw_scratch_mem.h | 2 +- .../amd/renoir/include/platform/lib/clk.h | 49 --------------- .../amd/renoir/include/platform/lib/cpu.h | 33 ---------- .../amd/renoir/include/platform/lib/dai.h | 21 ------- .../amd/renoir/include/platform/lib/dma.h | 34 ---------- .../amd/renoir/include/platform/lib/mailbox.h | 55 ---------------- .../renoir/include/platform/lib/pm_runtime.h | 62 ------------------- .../amd/renoir/include/platform/trace/trace.h | 23 ------- src/platform/amd/renoir/platform.c | 2 +- 33 files changed, 167 insertions(+), 352 deletions(-) create mode 100644 src/platform/amd/common/CMakeLists.txt create mode 100644 src/platform/amd/common/include/platform/acp_dma.h create mode 100644 src/platform/amd/common/include/platform/acp_dmic_dma.h create mode 100644 src/platform/amd/common/include/platform/acp_sp_dma.h rename src/platform/amd/{rembrandt => common}/include/platform/drivers/idc.h (83%) create mode 100644 src/platform/amd/common/include/platform/ipc.h rename src/platform/amd/{rembrandt => common}/include/platform/lib/clk.h (85%) rename src/platform/amd/{rembrandt => common}/include/platform/lib/cpu.h (85%) rename src/platform/amd/{rembrandt => common}/include/platform/lib/dai.h (75%) rename src/platform/amd/{rembrandt => common}/include/platform/lib/dma.h (86%) rename src/platform/amd/{rembrandt => common}/include/platform/lib/mailbox.h (92%) rename src/platform/amd/{rembrandt => common}/include/platform/lib/pm_runtime.h (93%) rename src/platform/amd/{rembrandt => common}/include/platform/trace/trace.h (79%) delete mode 100644 src/platform/amd/renoir/include/platform/drivers/idc.h delete mode 100644 src/platform/amd/renoir/include/platform/lib/clk.h delete mode 100644 src/platform/amd/renoir/include/platform/lib/cpu.h delete mode 100644 src/platform/amd/renoir/include/platform/lib/dai.h delete mode 100644 src/platform/amd/renoir/include/platform/lib/dma.h delete mode 100644 src/platform/amd/renoir/include/platform/lib/mailbox.h delete mode 100644 src/platform/amd/renoir/include/platform/lib/pm_runtime.h delete mode 100644 src/platform/amd/renoir/include/platform/trace/trace.h diff --git a/src/arch/xtensa/CMakeLists.txt b/src/arch/xtensa/CMakeLists.txt index 80e3074b8772..4f8fd6ee65e6 100644 --- a/src/arch/xtensa/CMakeLists.txt +++ b/src/arch/xtensa/CMakeLists.txt @@ -33,6 +33,10 @@ get_filename_component(_plf_ld_script ${platform_folder} NAME) set(platform_ld_script ${_plf_ld_script}.x) set(platform_rom_ld_script rom.x) +if(CONFIG_AMD) + target_include_directories(sof_options INTERFACE ${PROJECT_SOURCE_DIR}/src/platform/amd/common/include) +endif() + # includes # None of these should be included if Zephyr strict headers are used. diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index b68f56a72409..5077ca864226 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -13,7 +13,7 @@ elseif(CONFIG_IMX8M) add_subdirectory(imx8m) elseif(CONFIG_IMX8ULP) add_subdirectory(imx8ulp) -elseif(CONFIG_RENOIR OR CONFIG_REMBRANDT) +elseif(CONFIG_AMD) add_subdirectory(amd) elseif(CONFIG_MT8186) add_subdirectory(mt8186) diff --git a/src/platform/Kconfig b/src/platform/Kconfig index d9b600020b37..cf65d24317dc 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -149,6 +149,7 @@ config RENOIR select XT_INTERRUPT_LEVEL_1 select XT_INTERRUPT_LEVEL_4 select XT_WAITI_DELAY + select AMD select SCHEDULE_DMA_MULTI_CHANNEL help Select if your target platform is renoir-compatible @@ -161,6 +162,7 @@ config REMBRANDT select XT_INTERRUPT_LEVEL_4 select XT_WAITI_DELAY select XTENSA_EXCLUSIVE + select AMD select SCHEDULE_DMA_MULTI_CHANNEL help Select if your target platform is rembrandt-compatible @@ -262,6 +264,13 @@ config MEDIATEK This has to be selected for every MediaTek platform. It enables MediaTek platforms-specific features. +config AMD + bool + default n + help + This has to be selected for every AMD platform. + It enables AMD platforms-specific features. + config CAVS bool default n @@ -403,6 +412,7 @@ config RIMAGE_SIGNING_SCHEMA default "imx8m" if IMX8M default "imx8ulp" if IMX8ULP default "rn" if RENOIR + default "rmb" if REMBRANDT default "mt8186" if MT8186 default "mt8188" if MT8188 default "mt8195" if MT8195 diff --git a/src/platform/amd/CMakeLists.txt b/src/platform/amd/CMakeLists.txt index c7373783cc74..d3092e1ca1ea 100644 --- a/src/platform/amd/CMakeLists.txt +++ b/src/platform/amd/CMakeLists.txt @@ -1,4 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause +add_subdirectory(common) if(CONFIG_RENOIR) add_subdirectory(renoir) elseif(CONFIG_REMBRANDT) diff --git a/src/platform/amd/common/CMakeLists.txt b/src/platform/amd/common/CMakeLists.txt new file mode 100644 index 000000000000..fe55f14509aa --- /dev/null +++ b/src/platform/amd/common/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof) diff --git a/src/platform/amd/common/include/platform/acp_dma.h b/src/platform/amd/common/include/platform/acp_dma.h new file mode 100644 index 000000000000..06c2bcbce08c --- /dev/null +++ b/src/platform/amd/common/include/platform/acp_dma.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + *Copyright(c) 2023 AMD. All rights reserved. + * + *Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ + +#ifndef _COMMON_DMA_HEADER +#define _COMMON_DMA_HEADER + +#include + +#define ACP_MAX_STREAMS 8 +#define ACP_DMA_BUFFER_PERIOD_COUNT 2 +#define ACP_SYST_MEM_WINDOW 0x4000000 + +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]; +}; + +void amd_dma_reconfig(struct dma_chan_data *channel, uint32_t bytes); +int dma_setup(struct dma_chan_data *channel, + struct dma_sg_elem_array *sgelems, uint32_t dir); +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); +int acp_dma_get_attribute(struct dma *dma, uint32_t type, + uint32_t *value); +#endif diff --git a/src/platform/amd/common/include/platform/acp_dmic_dma.h b/src/platform/amd/common/include/platform/acp_dmic_dma.h new file mode 100644 index 000000000000..a02a825c465f --- /dev/null +++ b/src/platform/amd/common/include/platform/acp_dmic_dma.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD. All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ + +#ifndef _COMMON_DMIC_DMA_HEADER +#define _COMMON_DMIC_DMA_HEADER + +#include +#include + +/* 109c7aba-a7ba-43c3-b9-42-59-e2-0a-66-11-be */ + +int acp_dmic_dma_start(struct dma_chan_data *channel); +int acp_dmic_dma_stop(struct dma_chan_data *channel); +int acp_dmic_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config); +int acp_dmic_dma_get_attribute(struct dma *dma, + uint32_t type, uint32_t *value); +#endif diff --git a/src/platform/amd/common/include/platform/acp_sp_dma.h b/src/platform/amd/common/include/platform/acp_sp_dma.h new file mode 100644 index 000000000000..dcb2ed5119ae --- /dev/null +++ b/src/platform/amd/common/include/platform/acp_sp_dma.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + *Copyright(c) 2023 AMD. All rights reserved. + * + *Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ + +#ifndef _COMMON_SP_DMA_HEADER +#define _COMMON_SP_DMA_HEADER + +#include +#include + +#define SP_FIFO_SIZE 512 +#define SP_IER_DISABLE 0x0 + +int acp_dai_sp_dma_start(struct dma_chan_data *channel); +int acp_dai_sp_dma_stop(struct dma_chan_data *channel); +/* set the DMA channel configuration, source/target address, buffer sizes */ +int acp_dai_sp_dma_set_config(struct dma_chan_data *channel, + struct dma_sg_config *config); +int acp_dai_sp_dma_get_data_size(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free); +int acp_dai_sp_dma_get_attribute(struct dma *dma, uint32_t type, uint32_t *value); +int acp_dai_sp_dma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd); +#endif diff --git a/src/platform/amd/rembrandt/include/platform/drivers/idc.h b/src/platform/amd/common/include/platform/drivers/idc.h similarity index 83% rename from src/platform/amd/rembrandt/include/platform/drivers/idc.h rename to src/platform/amd/common/include/platform/drivers/idc.h index 494bc30e112b..03b3aae68ba8 100644 --- a/src/platform/amd/rembrandt/include/platform/drivers/idc.h +++ b/src/platform/amd/common/include/platform/drivers/idc.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ #if defined(__XTOS_RTOS_IDC_H__) || defined(__ZEPHYR_RTOS_IDC_H__) diff --git a/src/platform/amd/common/include/platform/ipc.h b/src/platform/amd/common/include/platform/ipc.h new file mode 100644 index 000000000000..26c392776662 --- /dev/null +++ b/src/platform/amd/common/include/platform/ipc.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD. All rights reserved. + * + *Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#ifndef _COMMON_IPC_HEADER +#define _COMMON_IPC_HEADER + +#include +#include + +uint32_t sof_ipc_host_status(void); +uint32_t sof_ipc_host_ack_flag(void); +void sof_ipc_host_ack_clear(void); +uint32_t sof_ipc_host_msg_flag(void); +void sof_ipc_host_msg_clear(void); +void sof_ipc_dsp_ack_set(void); +uint32_t sof_ipc_dsp_status(void); +void sof_ipc_dsp_msg_set(void); +void amd_irq_handler(void *arg); +#endif diff --git a/src/platform/amd/rembrandt/include/platform/lib/clk.h b/src/platform/amd/common/include/platform/lib/clk.h similarity index 85% rename from src/platform/amd/rembrandt/include/platform/lib/clk.h rename to src/platform/amd/common/include/platform/lib/clk.h index e5f67caaad80..54101527270f 100644 --- a/src/platform/amd/rembrandt/include/platform/lib/clk.h +++ b/src/platform/amd/common/include/platform/lib/clk.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ #ifdef __SOF_LIB_CLK_H__ @@ -22,7 +22,7 @@ struct sof; #define CLK_DEFAULT_CPU_HZ 600000000 #define CLK_MAX_CPU_HZ 600000000 -#define NUM_CLOCKS 2 +#define NUM_CLOCKS 1 #define NUM_CPU_FREQ 1 diff --git a/src/platform/amd/rembrandt/include/platform/lib/cpu.h b/src/platform/amd/common/include/platform/lib/cpu.h similarity index 85% rename from src/platform/amd/rembrandt/include/platform/lib/cpu.h rename to src/platform/amd/common/include/platform/lib/cpu.h index c5a9f9f91d5d..5ac72135c0db 100644 --- a/src/platform/amd/rembrandt/include/platform/lib/cpu.h +++ b/src/platform/amd/common/include/platform/lib/cpu.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ /* diff --git a/src/platform/amd/rembrandt/include/platform/lib/dai.h b/src/platform/amd/common/include/platform/lib/dai.h similarity index 75% rename from src/platform/amd/rembrandt/include/platform/lib/dai.h rename to src/platform/amd/common/include/platform/lib/dai.h index fd505c6721da..3354501e9c70 100644 --- a/src/platform/amd/rembrandt/include/platform/lib/dai.h +++ b/src/platform/amd/common/include/platform/lib/dai.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ #ifdef __SOF_LIB_DAI_H__ diff --git a/src/platform/amd/rembrandt/include/platform/lib/dma.h b/src/platform/amd/common/include/platform/lib/dma.h similarity index 86% rename from src/platform/amd/rembrandt/include/platform/lib/dma.h rename to src/platform/amd/common/include/platform/lib/dma.h index 844022b829eb..50a8a511b506 100644 --- a/src/platform/amd/rembrandt/include/platform/lib/dma.h +++ b/src/platform/amd/common/include/platform/lib/dma.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ #ifdef __SOF_LIB_DMA_H__ diff --git a/src/platform/amd/rembrandt/include/platform/lib/mailbox.h b/src/platform/amd/common/include/platform/lib/mailbox.h similarity index 92% rename from src/platform/amd/rembrandt/include/platform/lib/mailbox.h rename to src/platform/amd/common/include/platform/lib/mailbox.h index 50ac354eb726..9ef95b01db01 100644 --- a/src/platform/amd/rembrandt/include/platform/lib/mailbox.h +++ b/src/platform/amd/common/include/platform/lib/mailbox.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ #ifdef __SOF_LIB_MAILBOX_H__ diff --git a/src/platform/amd/rembrandt/include/platform/lib/pm_runtime.h b/src/platform/amd/common/include/platform/lib/pm_runtime.h similarity index 93% rename from src/platform/amd/rembrandt/include/platform/lib/pm_runtime.h rename to src/platform/amd/common/include/platform/lib/pm_runtime.h index 7c8f0c800075..542d73a2e179 100644 --- a/src/platform/amd/rembrandt/include/platform/lib/pm_runtime.h +++ b/src/platform/amd/common/include/platform/lib/pm_runtime.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ #ifdef __SOF_LIB_PM_RUNTIME_H__ diff --git a/src/platform/amd/rembrandt/include/platform/trace/trace.h b/src/platform/amd/common/include/platform/trace/trace.h similarity index 79% rename from src/platform/amd/rembrandt/include/platform/trace/trace.h rename to src/platform/amd/common/include/platform/trace/trace.h index 505113a1d2d6..08980eb539b0 100644 --- a/src/platform/amd/rembrandt/include/platform/trace/trace.h +++ b/src/platform/amd/common/include/platform/trace/trace.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 AMD.All rights reserved. + * Copyright(c) 2023 AMD.All rights reserved. * * Author: Basavaraj Hiregoudar - * Bala Kishore + * SaiSurya, Ch */ #ifdef __SOF_TRACE_TRACE_H__ diff --git a/src/platform/amd/rembrandt/include/platform/chip_offset_byte.h b/src/platform/amd/rembrandt/include/platform/chip_offset_byte.h index 27b465ce79a5..f20152a11708 100644 --- a/src/platform/amd/rembrandt/include/platform/chip_offset_byte.h +++ b/src/platform/amd/rembrandt/include/platform/chip_offset_byte.h @@ -34,7 +34,6 @@ #define ACP_SW_INTR_TRIG 0x1241810 #define DSP_INTERRUPT_ROUTING_CTRL_0 0x1241814 #define DSP_INTERRUPT_ROUTING_CTRL_1 0x1241818 -#define ACP_FUTURE_REG_ACLK_0 0x1241854 #define ACP_AXI2DAGB_SEM_0 0x1241874 #define ACP_DSP0_INTR_CNTL1 0x1241920 #define ACP_DSP0_INTR_STAT1 0x1241924 diff --git a/src/platform/amd/rembrandt/include/platform/chip_registers.h b/src/platform/amd/rembrandt/include/platform/chip_registers.h index bfae2b8d2cc2..2c2ab79bc1b3 100644 --- a/src/platform/amd/rembrandt/include/platform/chip_registers.h +++ b/src/platform/amd/rembrandt/include/platform/chip_registers.h @@ -771,17 +771,6 @@ typedef union acp_hstdm_txfrmt { unsigned int u32all; } acp_hstdm_txfrmt_t; -typedef union acp_future_reg_aclk_0 { - struct { - unsigned int dsp_msg:1; - unsigned int dsp_aclk:1; - unsigned int host_msg:1; - unsigned int host_aclk:1; - unsigned int :28; - } bits; - unsigned int u32all; -} acp_future_reg_aclk_0_t; - typedef union acp_clkmux_sel { struct { unsigned int acp_clkmux_sel : 3; diff --git a/src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h b/src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h index b164901591f0..1b0a0dea44d3 100644 --- a/src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h +++ b/src/platform/amd/rembrandt/include/platform/fw_scratch_mem.h @@ -25,7 +25,7 @@ typedef union acp_cfg_dma_trns_cnt { uint32_t reserved : 12; uint32_t ioc : 1; } bits; - unsigned int u32All; + unsigned int u32all; } __attribute__((packed, aligned(4))) acp_cfg_dma_trns_cnt_t; typedef struct acp_config_dma_descriptor { diff --git a/src/platform/amd/renoir/include/platform/chip_offset_byte.h b/src/platform/amd/renoir/include/platform/chip_offset_byte.h index 5a3af7eec690..3d65cc33d54d 100644 --- a/src/platform/amd/renoir/include/platform/chip_offset_byte.h +++ b/src/platform/amd/renoir/include/platform/chip_offset_byte.h @@ -32,7 +32,6 @@ #define ACP_SW_INTR_TRIG 0x124181C #define ACP_SMU_MAILBOX 0x1241820 #define DSP_INTERRUPT_ROUTING_CTRL 0x1241824 -#define ACP_FUTURE_REG_ACLK_0 0x1241860 #define ACP_TIMER 0x1241874 #define ACP_TIMER_CNTL 0x1241878 #define ACP_AXI2DAGB_SEM_0 0x1241880 diff --git a/src/platform/amd/renoir/include/platform/chip_registers.h b/src/platform/amd/renoir/include/platform/chip_registers.h index e79d8285f175..643050afb9f9 100644 --- a/src/platform/amd/renoir/include/platform/chip_registers.h +++ b/src/platform/amd/renoir/include/platform/chip_registers.h @@ -521,17 +521,6 @@ typedef union acp_srbm_cycle_sts { unsigned int u32all; } acp_srbm_cycle_sts_t; -typedef union acp_future_reg_aclk_0 { - struct { - unsigned int dsp_msg:1; - unsigned int dsp_aclk:1; - unsigned int host_msg:1; - unsigned int host_aclk:1; - unsigned int :28; - } bits; - unsigned int u32all; -} acp_future_reg_aclk_0_t; - typedef union acp_i2stdm_rxfrmt { struct { unsigned int i2stdm_frame_len :9; diff --git a/src/platform/amd/renoir/include/platform/drivers/idc.h b/src/platform/amd/renoir/include/platform/drivers/idc.h deleted file mode 100644 index c25e6ce4626f..000000000000 --- a/src/platform/amd/renoir/include/platform/drivers/idc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * Bala Kishore - */ -#if defined(__XTOS_RTOS_IDC_H__) || defined(__ZEPHYR_RTOS_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 Zephyr/XTOS's rtos/idc.h" - -#endif diff --git a/src/platform/amd/renoir/include/platform/drivers/interrupt.h b/src/platform/amd/renoir/include/platform/drivers/interrupt.h index 61dda2141464..328ffb832ca6 100644 --- a/src/platform/amd/renoir/include/platform/drivers/interrupt.h +++ b/src/platform/amd/renoir/include/platform/drivers/interrupt.h @@ -93,7 +93,7 @@ void acp_dsp_sw_intr_disable(void); void acp_intr_route(void); -void acp_dsp_to_host_Intr_trig(void); +void acp_dsp_to_host_intr_trig(void); void acp_ack_intr_from_host(void); diff --git a/src/platform/amd/renoir/include/platform/fw_scratch_mem.h b/src/platform/amd/renoir/include/platform/fw_scratch_mem.h index 23286e105150..db779b8cfb03 100644 --- a/src/platform/amd/renoir/include/platform/fw_scratch_mem.h +++ b/src/platform/amd/renoir/include/platform/fw_scratch_mem.h @@ -26,7 +26,7 @@ typedef union acp_cfg_dma_trns_cnt { uint32_t reserved : 12; uint32_t ioc : 1; } bits; - unsigned int u32All; + unsigned int u32all; } __attribute__((packed, aligned(4))) acp_cfg_dma_trns_cnt_t; typedef struct acp_config_dma_descriptor { diff --git a/src/platform/amd/renoir/include/platform/lib/clk.h b/src/platform/amd/renoir/include/platform/lib/clk.h deleted file mode 100644 index 2c637cf7e907..000000000000 --- a/src/platform/amd/renoir/include/platform/lib/clk.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * 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 1 - -#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/renoir/include/platform/lib/cpu.h b/src/platform/amd/renoir/include/platform/lib/cpu.h deleted file mode 100644 index 5687010318c5..000000000000 --- a/src/platform/amd/renoir/include/platform/lib/cpu.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * 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 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/renoir/include/platform/lib/dai.h b/src/platform/amd/renoir/include/platform/lib/dai.h deleted file mode 100644 index 2db51ac88bdc..000000000000 --- a/src/platform/amd/renoir/include/platform/lib/dai.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * 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/renoir/include/platform/lib/dma.h b/src/platform/amd/renoir/include/platform/lib/dma.h deleted file mode 100644 index 8f7e70b1a476..000000000000 --- a/src/platform/amd/renoir/include/platform/lib/dma.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * 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_ID_DAI_SP_VIRTUAL 6 -#define DMA_ID_DAI_HS_VIRTUAL 7 - -#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/renoir/include/platform/lib/mailbox.h b/src/platform/amd/renoir/include/platform/lib/mailbox.h deleted file mode 100644 index 29c948efcee2..000000000000 --- a/src/platform/amd/renoir/include/platform/lib/mailbox.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * 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/renoir/include/platform/lib/pm_runtime.h b/src/platform/amd/renoir/include/platform/lib/pm_runtime.h deleted file mode 100644 index 874d5cab2c49..000000000000 --- a/src/platform/amd/renoir/include/platform/lib/pm_runtime.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * 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/renoir/include/platform/trace/trace.h b/src/platform/amd/renoir/include/platform/trace/trace.h deleted file mode 100644 index c33168d49b7e..000000000000 --- a/src/platform/amd/renoir/include/platform/trace/trace.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 AMD.All rights reserved. - * - * Author: Basavaraj Hiregoudar - * Anup Kulkarni - * 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/renoir/platform.c b/src/platform/amd/renoir/platform.c index fd71831be51e..eecb8d61af56 100644 --- a/src/platform/amd/renoir/platform.c +++ b/src/platform/amd/renoir/platform.c @@ -187,7 +187,7 @@ int platform_boot_complete(uint32_t boot_message) (volatile acp_scratch_mem_config_t *)(PU_REGISTER_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(); + 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; From f57df6305b929499ba81f11fbf9ee90f8995b735 Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 16:16:27 +0530 Subject: [PATCH 3/9] platform: Add vangogh platform support Add vangogh platform support Signed-off-by: SaiSurya, Ch --- src/platform/amd/vangogh/CMakeLists.txt | 5 + .../include/arch/xtensa/config/core-isa.h | 672 +++++++++++++++++ .../include/arch/xtensa/config/core-matmap.h | 317 ++++++++ .../include/arch/xtensa/config/specreg.h | 108 +++ .../include/arch/xtensa/config/system.h | 256 +++++++ .../include/arch/xtensa/config/tie-asm.h | 292 ++++++++ .../vangogh/include/arch/xtensa/config/tie.h | 186 +++++ .../include/arch/xtensa/tie/xt_datacache.h | 4 + .../include/platform/chip_offset_byte.h | 150 ++++ .../vangogh/include/platform/chip_registers.h | 707 ++++++++++++++++++ .../include/platform/drivers/interrupt.h | 109 +++ .../vangogh/include/platform/fw_scratch_mem.h | 121 +++ .../amd/vangogh/include/platform/lib/memory.h | 170 +++++ .../amd/vangogh/include/platform/platform.h | 98 +++ src/platform/amd/vangogh/lib/CMakeLists.txt | 8 + src/platform/amd/vangogh/lib/clk.c | 145 ++++ src/platform/amd/vangogh/lib/dai.c | 115 +++ src/platform/amd/vangogh/lib/dma.c | 107 +++ src/platform/amd/vangogh/lib/memory.c | 96 +++ src/platform/amd/vangogh/platform.c | 208 ++++++ src/platform/amd/vangogh/vangogh.x.in | 577 ++++++++++++++ 21 files changed, 4451 insertions(+) create mode 100644 src/platform/amd/vangogh/CMakeLists.txt create mode 100644 src/platform/amd/vangogh/include/arch/xtensa/config/core-isa.h create mode 100644 src/platform/amd/vangogh/include/arch/xtensa/config/core-matmap.h create mode 100644 src/platform/amd/vangogh/include/arch/xtensa/config/specreg.h create mode 100644 src/platform/amd/vangogh/include/arch/xtensa/config/system.h create mode 100644 src/platform/amd/vangogh/include/arch/xtensa/config/tie-asm.h create mode 100644 src/platform/amd/vangogh/include/arch/xtensa/config/tie.h create mode 100755 src/platform/amd/vangogh/include/arch/xtensa/tie/xt_datacache.h create mode 100644 src/platform/amd/vangogh/include/platform/chip_offset_byte.h create mode 100644 src/platform/amd/vangogh/include/platform/chip_registers.h create mode 100644 src/platform/amd/vangogh/include/platform/drivers/interrupt.h create mode 100644 src/platform/amd/vangogh/include/platform/fw_scratch_mem.h create mode 100644 src/platform/amd/vangogh/include/platform/lib/memory.h create mode 100644 src/platform/amd/vangogh/include/platform/platform.h create mode 100644 src/platform/amd/vangogh/lib/CMakeLists.txt create mode 100644 src/platform/amd/vangogh/lib/clk.c create mode 100644 src/platform/amd/vangogh/lib/dai.c create mode 100644 src/platform/amd/vangogh/lib/dma.c create mode 100644 src/platform/amd/vangogh/lib/memory.c create mode 100644 src/platform/amd/vangogh/platform.c create mode 100644 src/platform/amd/vangogh/vangogh.x.in diff --git a/src/platform/amd/vangogh/CMakeLists.txt b/src/platform/amd/vangogh/CMakeLists.txt new file mode 100644 index 000000000000..ec909d60035f --- /dev/null +++ b/src/platform/amd/vangogh/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/vangogh/include/arch/xtensa/config/core-isa.h b/src/platform/amd/vangogh/include/arch/xtensa/config/core-isa.h new file mode 100644 index 000000000000..d6d5af62f9ea --- /dev/null +++ b/src/platform/amd/vangogh/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=7490; Build=0x8176c; Copyright (c) 1999-2019 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 8 /* 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 1 /* 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 0 /* HiFi5 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI5_NN_MAC 0 /* HiFi5 Audio Engine NN-MAC option */ +#define XCHAL_HAVE_HIFI5_VFPU 0 /* HiFi5 Audio Engine Single-Precision VFPU option */ +#define XCHAL_HAVE_HIFI5_HP_VFPU 0 /* HiFi5 Audio Engine Half-Precision VFPU option */ +#define XCHAL_HAVE_HIFI4 0 /* HiFi4 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI4_VFPU 0 /* 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 1 /* HiFi3Z Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3Z_VFPU 1 /* 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 32 /* size of write buffer */ +#define XCHAL_INST_FETCH_WIDTH 8 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 8 /* 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 "ACP_5_0_001_PROD" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_BUILD_UNIQUE_ID 0x0008176C /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC2F3CBFE /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x22481571 /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX7.0.9" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2700 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 9 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION_MICRO /* subdot ver# of targeted hw */ +#define XCHAL_HW_VERSION 270009 /* major*100+(major<2810 ? minor : minor*10+micro) */ +#define XCHAL_HW_REL_LX7 1 +#define XCHAL_HW_REL_LX7_0 1 +#define XCHAL_HW_REL_LX7_0_9 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 2700 /* major v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MINOR 9 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MICRO 0 /* micro v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 270009 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2700 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 9 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MICRO /* micro v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 270009 /* 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 64 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 64 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 6 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 6 /* 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 8 /* cache prefetch entries */ +#define XCHAL_PREFETCH_BLOCK_ENTRIES 0 /* prefetch block streams */ +#define XCHAL_HAVE_CACHE_BLOCKOPS 0 /* 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 0 /* 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 9 +#define XCHAL_DCACHE_SETWIDTH 9 + +/* 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 8 +#define XCHAL_DCACHE_ACCESS_SIZE 8 + +#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 0x20000000 /* virtual address */ +#define XCHAL_INSTRAM0_PADDR 0x20000000 /* 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 0x00000103 +#define XCHAL_INTLEVEL2_MASK 0x00000004 +#define XCHAL_INTLEVEL3_MASK 0x00000008 +#define XCHAL_INTLEVEL4_MASK 0x00000010 +#define XCHAL_INTLEVEL5_MASK 0x00000060 +#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 0x00000103 +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x00000107 +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x0000010F +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x0000011F +#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 5 +#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_INTLEVEL7_NUM 7 +/* (There are many interrupts each at level(s) 1, 5.) */ + + +/* + * 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 0x20000000 +#define XCHAL_RESET_VECTOR_PADDR 0x20000000 +#define XCHAL_USER_VECOFS 0x00000000 +#define XCHAL_USER_VECTOR_VADDR 0x20000740 +#define XCHAL_USER_VECTOR_PADDR 0x20000740 +#define XCHAL_KERNEL_VECOFS 0x00000000 +#define XCHAL_KERNEL_VECTOR_VADDR 0x20000700 +#define XCHAL_KERNEL_VECTOR_PADDR 0x20000700 +#define XCHAL_DOUBLEEXC_VECOFS 0x00000000 +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x200007C0 +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x200007C0 +#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 0x20000400 +#define XCHAL_WINDOW_VECTORS_PADDR 0x20000400 +#define XCHAL_INTLEVEL2_VECOFS 0x00000000 +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x20000580 +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x20000580 +#define XCHAL_INTLEVEL3_VECOFS 0x00000000 +#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x200005C0 +#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x200005C0 +#define XCHAL_INTLEVEL4_VECOFS 0x00000000 +#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x20000600 +#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x20000600 +#define XCHAL_INTLEVEL5_VECOFS 0x00000000 +#define XCHAL_INTLEVEL5_VECTOR_VADDR 0x20000640 +#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x20000640 +#define XCHAL_INTLEVEL6_VECOFS 0x00000000 +#define XCHAL_INTLEVEL6_VECTOR_VADDR 0x20000680 +#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x20000680 +#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 0x200006C0 +#define XCHAL_NMI_VECTOR_PADDR 0x200006C0 +#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/vangogh/include/arch/xtensa/config/core-matmap.h b/src/platform/amd/vangogh/include/arch/xtensa/config/core-matmap.h new file mode 100644 index 000000000000..711f34d9af39 --- /dev/null +++ b/src/platform/amd/vangogh/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=7490; Build=0x8176c; Copyright (c) 1999-2019 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/vangogh/include/arch/xtensa/config/specreg.h b/src/platform/amd/vangogh/include/arch/xtensa/config/specreg.h new file mode 100644 index 000000000000..ce2b5dc4d541 --- /dev/null +++ b/src/platform/amd/vangogh/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=7490; Build=0x8176c; 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/vangogh/include/arch/xtensa/config/system.h b/src/platform/amd/vangogh/include/arch/xtensa/config/system.h new file mode 100644 index 000000000000..cdc6537bfdc1 --- /dev/null +++ b/src/platform/amd/vangogh/include/arch/xtensa/config/system.h @@ -0,0 +1,256 @@ +/* + * 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=7490; Build=0x8176c; 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_NEWLIB /* (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: */ + +/* System RAM: */ +#define XSHAL_RAM_VADDR 0x60000000 +#define XSHAL_RAM_PADDR 0x60000000 +#define XSHAL_RAM_VSIZE 0x1FE00000 +#define XSHAL_RAM_PSIZE 0x1FE00000 +#define XSHAL_RAM_SIZE XSHAL_RAM_PSIZE +/* Largest available area (free of vectors): */ +#define XSHAL_RAM_AVAIL_VADDR 0x60000000 +#define XSHAL_RAM_AVAIL_VSIZE 0x1FE00000 + +/* + * 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 0x40000000 +#define XSHAL_RAM_BYPASS_PADDR 0x40000000 +#define XSHAL_RAM_BYPASS_PSIZE 0x1FE00000 + +/* 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 0x4c + +/*---------------------------------------------------------------------- + * 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 0x42224242 /* enable caches in write-back mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEALLOC 0x12221212 /* enable caches in write-allocate mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITETHRU 0x12221212 /* 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 0x4FFF4F4F /* enable caches in write-back mode */ +#define XSHAL_STRICT_CACHEATTR_WRITEALLOC 0x1FFF1F1F /* enable caches in write-allocate mode */ +#define XSHAL_STRICT_CACHEATTR_WRITETHRU 0x1FFF1F1F /* enable caches in write-through mode */ +#define XSHAL_STRICT_CACHEATTR_BYPASS 0x2FFF2F2F /* 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 0x4222424F /* enable caches in write-back mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC 0x1222121F /* enable caches in write-allocate mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITETHRU 0x1222121F /* 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 0x4FF2424F /* enable caches in write-back mode */ +#define XSHAL_XT2000_CACHEATTR_WRITEALLOC 0x1FF2121F /* enable caches in write-allocate mode */ +#define XSHAL_XT2000_CACHEATTR_WRITETHRU 0x1FF2121F /* 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 0x00000050 /* BusInt SDRAM regions */ + + +/*---------------------------------------------------------------------- + VECTOR INFO AND SIZES + ----------------------------------------------------------------------*/ + +#define XSHAL_VECTORS_PACKED 0 /* UNUSED */ +#define XSHAL_STATIC_VECTOR_SELECT 0 +#define XSHAL_RESET_VECTOR_VADDR 0x20000000 +#define XSHAL_RESET_VECTOR_PADDR 0x20000000 + +/* + * 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/vangogh/include/arch/xtensa/config/tie-asm.h b/src/platform/amd/vangogh/include/arch/xtensa/config/tie-asm.h new file mode 100644 index 000000000000..e03bace79955 --- /dev/null +++ b/src/platform/amd/vangogh/include/arch/xtensa/config/tie-asm.h @@ -0,0 +1,292 @@ +/* + * 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=7490; Build=0x8176c; Copyright (c) 1999-2019 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 8 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, 8, 8 + ae_s64.i aed0, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed1, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed2, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed3, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed4, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed5, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed6, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed7, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed8, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed9, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed10, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed11, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed12, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed13, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed14, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed15, \ptr, .Lxchal_ofs_+24 + ae_salign64.i u0, \ptr, .Lxchal_ofs_+32 + ae_salign64.i u1, \ptr, .Lxchal_ofs_+40 + ae_salign64.i u2, \ptr, .Lxchal_ofs_+48 + ae_salign64.i u3, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, -128 + ae_movvfcrfsr aed0 // ureg FCR_FSR + ae_s64.i aed0, \ptr, .Lxchal_ofs_+0 + 0 + rur.ae_ovf_sar \at1 // ureg 240 + s32i \at1, \ptr, .Lxchal_ofs_+8 + rur.ae_bithead \at1 // ureg 241 + s32i \at1, \ptr, .Lxchal_ofs_+12 + rur.ae_ts_fts_bu_bp \at1 // ureg 242 + s32i \at1, \ptr, .Lxchal_ofs_+16 + rur.ae_cw_sd_no \at1 // ureg 243 + s32i \at1, \ptr, .Lxchal_ofs_+20 + rur.ae_cbegin0 \at1 // ureg 246 + s32i \at1, \ptr, .Lxchal_ofs_+24 + rur.ae_cend0 \at1 // ureg 247 + s32i \at1, \ptr, .Lxchal_ofs_+28 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 192 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 8, 8 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 192 + .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 8 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, 8, 8 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+0 + 0 // ureg FCR_FSR + ae_movfcrfsrv aed0 + l32i \at1, \ptr, .Lxchal_ofs_+8 + wur.ae_ovf_sar \at1 // ureg 240 + l32i \at1, \ptr, .Lxchal_ofs_+12 + wur.ae_bithead \at1 // ureg 241 + l32i \at1, \ptr, .Lxchal_ofs_+16 + wur.ae_ts_fts_bu_bp \at1 // ureg 242 + l32i \at1, \ptr, .Lxchal_ofs_+20 + wur.ae_cw_sd_no \at1 // ureg 243 + l32i \at1, \ptr, .Lxchal_ofs_+24 + wur.ae_cbegin0 \at1 // ureg 246 + l32i \at1, \ptr, .Lxchal_ofs_+28 + wur.ae_cend0 \at1 // ureg 247 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed1, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed2, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed3, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed4, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed5, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed6, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed7, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed8, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed9, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed10, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed11, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed12, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed13, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed14, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed15, \ptr, .Lxchal_ofs_+24 + addi.a \ptr, \ptr, 32 + ae_lalign64.i u0, \ptr, .Lxchal_ofs_+0 + ae_lalign64.i u1, \ptr, .Lxchal_ofs_+8 + ae_lalign64.i u2, \ptr, .Lxchal_ofs_+16 + ae_lalign64.i u3, \ptr, .Lxchal_ofs_+24 + .set .Lxchal_pofs_, .Lxchal_pofs_ + 160 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 32 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 8, 8 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 192 + .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/vangogh/include/arch/xtensa/config/tie.h b/src/platform/amd/vangogh/include/arch/xtensa/config/tie.h new file mode 100644 index 000000000000..3a5f1106d316 --- /dev/null +++ b/src/platform/amd/vangogh/include/arch/xtensa/config/tie.h @@ -0,0 +1,186 @@ +/* + * 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=7490; Build=0x8176c; Copyright (c) 1999-2019 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 192 /* size of state save area */ +#define XCHAL_CP1_SA_ALIGN 8 /* 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 208 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 8 /* 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 27 +#define XCHAL_CP1_SA_LIST(s) \ + XCHAL_SA_REG(s,0,0,1,0, fcr_fsr, 8, 8, 8,0x1015, ur,-1 , 7,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_ovf_sar, 4, 4, 4,0x03F0, ur,240, 8,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,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, u0, 8, 8, 8,0x1010, u,0 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u1, 8, 8, 8,0x1011, u,1 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u2, 8, 8, 8,0x1012, u,2 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u3, 8, 8, 8,0x1013, u,3 , 64,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. */ +/* (not available, must use XCHAL_BYTE0_FORMAT_LENGTHS for this processor) */ +/* 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,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,5,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,5,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,5,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8 + +/* parasoft-end-suppress ALL "This file not MISRA checked." */ + +#endif /* XTENSA_CORE_TIE_H */ + diff --git a/src/platform/amd/vangogh/include/arch/xtensa/tie/xt_datacache.h b/src/platform/amd/vangogh/include/arch/xtensa/tie/xt_datacache.h new file mode 100755 index 000000000000..7fcaa456ca16 --- /dev/null +++ b/src/platform/amd/vangogh/include/arch/xtensa/tie/xt_datacache.h @@ -0,0 +1,4 @@ +#ifndef __cstub_xt_datacache_h__ +#define __cstub_xt_datacache_h__ + +#endif diff --git a/src/platform/amd/vangogh/include/platform/chip_offset_byte.h b/src/platform/amd/vangogh/include/platform/chip_offset_byte.h new file mode 100644 index 000000000000..adac7315de69 --- /dev/null +++ b/src/platform/amd/vangogh/include/platform/chip_offset_byte.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#ifndef _VANGOGH_OFFSET_HEADER +#define _VANGOGH_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_DESC_BASE_ADDR 0x12400E0 +#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4 +#define ACP_DMA_CH_STS 0x12400E8 + +#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020 +#define ACP_DMA_DSCR_CNT_0 0x1240040 +#define ACP_DMA_PRIO_0 0x1240060 + +/* Registers from ACP_MISC block */ +#define ACP_CLKMUX_SEL 0x124142C +#define ACP_EXTERNAL_INTR_ENB 0x1241800 +#define ACP_EXTERNAL_INTR_STAT 0x1241808 +#define ACP_DSP0_INTR_CNTL 0x124180C +#define ACP_DSP0_INTR_STAT 0x1241810 +#define ACP_DSP_SW_INTR_CNTL 0x1241814 +#define ACP_DSP_SW_INTR_STAT 0x1241818 +#define ACP_SW_INTR_TRIG 0x124181C +#define ACP_SMU_MAILBOX 0x1241820 +#define DSP_INTERRUPT_ROUTING_CTRL_0 0x1241824 +#define DSP_INTERRUPT_ROUTING_CTRL_1 0x1241828 + +#define ACP_TIMER 0x1241878 +#define ACP_TIMER_CNTL 0x124187C +#define ACP_AXI2DAGB_SEM_0 0x1241884 + +#define ACP_SRBM_CLIENT_BASE_ADDR 0x1241BBC +#define ACP_SRBM_CLIENT_RDDATA 0x1241BC0 +#define ACP_SRBM_CYCLE_STS 0x1241BC4 +#define ACP_SRBM_CLIENT_CONFIG 0x1241BC8 + +/* Registers from ACP_AUDIO_BUFFERS block */ +#define ACP_I2S_RX_RINGBUFADDR 0x1242000 +#define ACP_I2S_RX_RINGBUFSIZE 0x1242004 +#define ACP_I2S_RX_LINKPOSITIONCNTR 0x1242008 +#define ACP_I2S_RX_FIFOADDR 0x124200C +#define ACP_I2S_RX_FIFOSIZE 0x1242010 +#define ACP_I2S_RX_DMA_SIZE 0x1242014 +#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1242018 +#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x124201C +#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020 +#define ACP_I2S_TX_RINGBUFADDR 0x1242024 +#define ACP_I2S_TX_RINGBUFSIZE 0x1242028 +#define ACP_I2S_TX_LINKPOSITIONCNTR 0x124202C +#define ACP_I2S_TX_FIFOADDR 0x1242030 +#define ACP_I2S_TX_FIFOSIZE 0x1242034 +#define ACP_I2S_TX_DMA_SIZE 0x1242038 +#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x124203C +#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1242040 +#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044 +#define ACP_BT_RX_RINGBUFADDR 0x1242048 +#define ACP_BT_RX_RINGBUFSIZE 0x124204C +#define ACP_BT_RX_LINKPOSITIONCNTR 0x1242050 +#define ACP_BT_RX_FIFOADDR 0x1242054 +#define ACP_BT_RX_FIFOSIZE 0x1242058 +#define ACP_BT_RX_DMA_SIZE 0x124205C +#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060 +#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064 +#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068 +#define ACP_BT_TX_RINGBUFADDR 0x124206C +#define ACP_BT_TX_RINGBUFSIZE 0x1242070 +#define ACP_BT_TX_LINKPOSITIONCNTR 0x1242074 +#define ACP_BT_TX_FIFOADDR 0x1242078 +#define ACP_BT_TX_FIFOSIZE 0x124207C +#define ACP_BT_TX_DMA_SIZE 0x1242080 +#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084 +#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088 +#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C +#define ACP_HS_RX_RINGBUFADDR 0x1242090 +#define ACP_HS_RX_RINGBUFSIZE 0x1242094 +#define ACP_HS_RX_LINKPOSITIONCNTR 0x1242098 +#define ACP_HS_RX_FIFOADDR 0x124209C +#define ACP_HS_RX_FIFOSIZE 0x12420A0 +#define ACP_HS_RX_DMA_SIZE 0x12420A4 +#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8 +#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC +#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0 +#define ACP_HS_TX_RINGBUFADDR 0x12420B4 +#define ACP_HS_TX_RINGBUFSIZE 0x12420B8 +#define ACP_HS_TX_LINKPOSITIONCNTR 0x12420BC +#define ACP_HS_TX_FIFOADDR 0x12420C0 +#define ACP_HS_TX_FIFOSIZE 0x12420C4 +#define ACP_HS_TX_DMA_SIZE 0x12420C8 +#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC +#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0 +#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4 + +/* 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 + +/* Registers from ACP_HS_TDM block */ +#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_VAD_ENABLE 0x1242C00 +#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_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 MP1_SMN_C2PMSG_69 0x58A14 +#define MP1_SMN_C2PMSG_85 0x58A54 +#define MP1_SMN_C2PMSG_93 0x58A74 +#endif diff --git a/src/platform/amd/vangogh/include/platform/chip_registers.h b/src/platform/amd/vangogh/include/platform/chip_registers.h new file mode 100644 index 000000000000..f7e89d18dedb --- /dev/null +++ b/src/platform/amd/vangogh/include/platform/chip_registers.h @@ -0,0 +1,707 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#if !defined(_VANGOGH_REG_HEADER) +#define _VANGOGH_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_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 :14; + } 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_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_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_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_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_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; + +#endif + diff --git a/src/platform/amd/vangogh/include/platform/drivers/interrupt.h b/src/platform/amd/vangogh/include/platform/drivers/interrupt.h new file mode 100644 index 000000000000..6197427cdf92 --- /dev/null +++ b/src/platform/amd/vangogh/include/platform/drivers/interrupt.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#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 5 + +#define PLATFORM_IRQ_CHILDREN 32 + +/* 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 BIT(IRQ_NUM_SOFTWARE0) + +#define IRQ_MASK_TIMER0 BIT(IRQ_NUM_TIMER0) + +#define IRQ_MASK_TIMER1 BIT(IRQ_NUM_TIMER1) + +#define IRQ_MASK_EXT_LEVEL3 BIT(IRQ_NUM_EXT_LEVEL3) + +#define IRQ_MASK_EXT_LEVEL4 BIT(IRQ_NUM_EXT_LEVEL4) + +#define IRQ_MASK_EXT_LEVEL5 BIT(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/vangogh/include/platform/fw_scratch_mem.h b/src/platform/amd/vangogh/include/platform/fw_scratch_mem.h new file mode 100644 index 000000000000..9890110540ef --- /dev/null +++ b/src/platform/amd/vangogh/include/platform/fw_scratch_mem.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD. All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#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 Vangogh */ + /* Added fifo members to align with Driver structure */ + /* ACP transmit fifo buffers */ + uint8_t acp_transmit_fifo_buffer[768] __attribute__((aligned(64))); + uint8_t acp_transmit_hs_fifo_buffer[768] __attribute__((aligned(64))); + + /* ACP receive fifo buffer */ + uint8_t acp_receive_fifo_buffer[768] __attribute__((aligned(64))); + + uint32_t reserve[]; +} __attribute__((packed, aligned(4))) acp_scratch_mem_config_t; + +#endif /* __EXT_SCRATCH_MEM_H__ */ + diff --git a/src/platform/amd/vangogh/include/platform/lib/memory.h b/src/platform/amd/vangogh/include/platform/lib/memory.h new file mode 100644 index 000000000000..6e0b768cc57a --- /dev/null +++ b/src/platform/amd/vangogh/include/platform/lib/memory.h @@ -0,0 +1,170 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#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 64 + +/* physical DSP addresses */ +#define IRAM_BASE 0x20000000 +#define IRAM_SIZE 0x40000 + +#define DRAM0_BASE 0xE0000000 +#define DRAM0_SIZE 0x80000 +#define DRAM1_SIZE 0x80000 + +#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_SIZE 0x4 +#define BT_TX_FIFO_OFFST (ACP_BT_TX_FIFOADDR - ACP_I2S_RX_RINGBUFADDR) +#define BT_RX_FIFO_OFFST (ACP_BT_RX_FIFOADDR - ACP_I2S_RX_RINGBUFADDR) + +#define HS_TX_FIFO_OFFST (ACP_HS_TX_FIFOADDR - ACP_I2S_RX_RINGBUFADDR) +#define HS_RX_FIFO_OFFST (ACP_HS_RX_FIFOADDR - ACP_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 0x9FF00000 +#define SRAM_OUTBOX_SIZE 0x400 +#define SRAM_OUTBOX_OFFSET 0 + +#define SRAM_INBOX_BASE (SRAM_OUTBOX_BASE + SRAM_OUTBOX_SIZE) +#define SRAM_INBOX_SIZE 0x400 +#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 13 +#define HEAP_RT_COUNT2048 24 + +/* Heap section sizes for system runtime heap */ +#define HEAP_SYS_RT_COUNT64 64 +#define HEAP_SYS_RT_COUNT512 22 /*vangogh-arch*/ +#define HEAP_SYS_RT_COUNT1024 30 + +/* Heap configuration */ +#define HEAP_SYSTEM_BASE (SOF_STACK_BASE + SOF_STACK_SIZE) +#define HEAP_SYSTEM_SIZE 0x14400 +#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 (0x15400) +#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/vangogh/include/platform/platform.h b/src/platform/amd/vangogh/include/platform/platform.h new file mode 100644 index 000000000000..efdda9d6b446 --- /dev/null +++ b/src/platform/amd/vangogh/include/platform/platform.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#ifdef __SOF_PLATFORM_H__ + +#ifndef __PLATFORM_PLATFORM_H__ +#define __PLATFORM_PLATFORM_H__ + +#if !defined(__ASSEMBLER__) && !defined(LINKER) + +#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; + + 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. + */ +void platform_wait_for_interrupt(int 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/vangogh/lib/CMakeLists.txt b/src/platform/amd/vangogh/lib/CMakeLists.txt new file mode 100644 index 000000000000..271a099cc6a9 --- /dev/null +++ b/src/platform/amd/vangogh/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/vangogh/lib/clk.c b/src/platform/amd/vangogh/lib/clk.c new file mode 100644 index 000000000000..25f7befed373 --- /dev/null +++ b/src/platform/amd/vangogh/lib/clk.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 AMD. All rights reserved. +// +// Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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, + }; + } + acp_change_clock_notify(600000000); +} diff --git a/src/platform/amd/vangogh/lib/dai.c b/src/platform/amd/vangogh/lib/dai.c new file mode 100644 index 000000000000..d47eee304ab4 --- /dev/null +++ b/src/platform/amd/vangogh/lib/dai.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct dai hsdai[] = { + { + .index = 1, + .plat_data = { + .base = DAI_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE + HS_TX_FIFO_OFFST, + .depth = 8, + .handshake = 1, + }, + }, + .drv = &acp_hsdai_driver, + }, +}; + +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, + } +}; + +#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_HS, + .dai_array = hsdai, + .num_dais = ARRAY_SIZE(hsdai) + }, + { + .type = SOF_DAI_AMD_SP, + .dai_array = spdai, + .num_dais = ARRAY_SIZE(spdai) + }, +#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(hsdai); i++) + k_spinlock_init(&hsdai[i].lock); + for (i = 0; i < ARRAY_SIZE(spdai); i++) + k_spinlock_init(&spdai[i].lock); +#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/vangogh/lib/dma.c b/src/platform/amd/vangogh/lib/dma.c new file mode 100644 index 000000000000..cd764542dcfa --- /dev/null +++ b/src/platform/amd/vangogh/lib/dma.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACP_ADDR_MASK 0x9DEB0000 + +extern struct dma_ops acp_dma_ops; +#ifdef ACP_BT_ENABLE +extern struct dma_ops acp_dai_bt_dma_ops; +#endif +extern struct dma_ops acp_dai_sp_dma_ops; +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_HS, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_HS, + .caps = DMA_CAP_HS, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + .irq_name = "irqsteer1", + }, + .ops = &acp_dai_hs_dma_ops, +}, +{ + .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, + .irq_name = "irqsteer1", + }, + .ops = &acp_dai_sp_dma_ops, +}, + +#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; + uint32_t descr_base; + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + descr_base = (uint32_t)(&pscratch_mem_cfg->acp_cfg_dma_descriptor); + descr_base = (descr_base - ACP_ADDR_MASK); + /* configure dma descriptor base addr */ + io_reg_write((PU_REGISTER_BASE + ACP_DMA_DESC_BASE_ADDR), descr_base); + io_reg_write((PU_REGISTER_BASE + ACP_DMA_DESC_MAX_NUM_DSCR), 0x1); + + /* 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/vangogh/lib/memory.c b/src/platform/amd/vangogh/lib/memory.c new file mode 100644 index 000000000000..d4a0ab144706 --- /dev/null +++ b/src/platform/amd/vangogh/lib/memory.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2023 AMD. All rights reserved. +// +// Author:Basavaraj Hiregoudar +// SaiSurya, Ch + +#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/vangogh/platform.c b/src/platform/amd/vangogh/platform.c new file mode 100644 index 000000000000..ad06fbb4b3cd --- /dev/null +++ b/src/platform/amd/vangogh/platform.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 +#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, +}; + +#define NUM_ACP_WINDOWS 6 + +const struct ext_man_windows xsram_window + __aligned(EXT_MAN_ALIGN) __unused = { + .hdr = { + .type = EXT_MAN_ELEM_WINDOW, + .elem_size = ALIGN_UP_COMPILE(sizeof(struct ext_man_windows), EXT_MAN_ALIGN), + }, + .window = { + .ext_hdr = { + .hdr.cmd = SOF_IPC_FW_READY, + .hdr.size = sizeof(struct sof_ipc_window), + .type = SOF_IPC_EXT_WINDOW, + }, + .num_windows = NUM_ACP_WINDOWS, + .window = { + { + .type = SOF_IPC_REGION_UPBOX, + .id = 0, + .flags = 0, + .size = MAILBOX_DSPBOX_SIZE, + .offset = MAILBOX_DSPBOX_OFFSET, + }, + { + .type = SOF_IPC_REGION_DOWNBOX, + .id = 0, + .flags = 0, + .size = MAILBOX_HOSTBOX_SIZE, + .offset = MAILBOX_HOSTBOX_OFFSET, + }, + { + .type = SOF_IPC_REGION_DEBUG, + .id = 0, + .flags = 0, + .size = MAILBOX_DEBUG_SIZE, + .offset = MAILBOX_DEBUG_OFFSET, + }, + { + .type = SOF_IPC_REGION_TRACE, + .id = 0, + .flags = 0, + .size = MAILBOX_TRACE_SIZE, + .offset = MAILBOX_TRACE_OFFSET, + }, + { + .type = SOF_IPC_REGION_STREAM, + .id = 0, + .flags = 0, + .size = MAILBOX_STREAM_SIZE, + .offset = MAILBOX_STREAM_OFFSET, + }, + { + .type = SOF_IPC_REGION_EXCEPTION, + .id = 0, + .flags = 0, + .size = MAILBOX_EXCEPTION_SIZE, + .offset = MAILBOX_EXCEPTION_OFFSET, + }, + }, + }, +}; + +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 */ + interrupt_init(sof); + 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)); + mailbox_dspbox_write(sizeof(ready), &xsram_window.window, sizeof(xsram_window.window)); + 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; +} + +void platform_wait_for_interrupt(int level) +{ + arch_wait_for_interrupt(level); +} diff --git a/src/platform/amd/vangogh/vangogh.x.in b/src/platform/amd/vangogh/vangogh.x.in new file mode 100644 index 000000000000..860bf21987fb --- /dev/null +++ b/src/platform/amd/vangogh/vangogh.x.in @@ -0,0 +1,577 @@ +/* + * Linker Script for AMD Vangogh + * + * 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 b01869f046a1e7c994b135b857dcd72504f779df Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 14:44:27 +0530 Subject: [PATCH 4/9] drivers: amd: vangogh: add drivers support for vangogh platform Add drivers support for vangogh platform. Signed-off-by: SaiSurya, Ch --- src/drivers/amd/vangogh/CMakeLists.txt | 13 + src/drivers/amd/vangogh/acp_bt_dma.c | 430 ++++++++++++++++++++++++ src/drivers/amd/vangogh/acp_dma.c | 261 +++++++++++++++ src/drivers/amd/vangogh/acp_dmic_dma.c | 219 ++++++++++++ src/drivers/amd/vangogh/acp_hs_dai.c | 99 ++++++ src/drivers/amd/vangogh/acp_hs_dma.c | 431 ++++++++++++++++++++++++ src/drivers/amd/vangogh/acp_sp_dai.c | 96 ++++++ src/drivers/amd/vangogh/acp_sp_dma.c | 303 +++++++++++++++++ src/drivers/amd/vangogh/interrupt.c | 440 +++++++++++++++++++++++++ src/drivers/amd/vangogh/ipc.c | 147 +++++++++ 10 files changed, 2439 insertions(+) create mode 100644 src/drivers/amd/vangogh/CMakeLists.txt create mode 100644 src/drivers/amd/vangogh/acp_bt_dma.c create mode 100644 src/drivers/amd/vangogh/acp_dma.c create mode 100644 src/drivers/amd/vangogh/acp_dmic_dma.c create mode 100644 src/drivers/amd/vangogh/acp_hs_dai.c create mode 100644 src/drivers/amd/vangogh/acp_hs_dma.c create mode 100644 src/drivers/amd/vangogh/acp_sp_dai.c create mode 100644 src/drivers/amd/vangogh/acp_sp_dma.c create mode 100644 src/drivers/amd/vangogh/interrupt.c create mode 100644 src/drivers/amd/vangogh/ipc.c diff --git a/src/drivers/amd/vangogh/CMakeLists.txt b/src/drivers/amd/vangogh/CMakeLists.txt new file mode 100644 index 000000000000..24e80e3e76d7 --- /dev/null +++ b/src/drivers/amd/vangogh/CMakeLists.txt @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof + acp_dma.c + acp_sp_dai.c + acp_hs_dai.c + interrupt.c + ipc.c + acp_bt_dma.c + acp_sp_dma.c + acp_hs_dma.c + acp_dmic_dma.c +) diff --git a/src/drivers/amd/vangogh/acp_bt_dma.c b/src/drivers/amd/vangogh/acp_bt_dma.c new file mode 100644 index 000000000000..92ba4b86d2f7 --- /dev/null +++ b/src/drivers/amd/vangogh/acp_bt_dma.c @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 BT_FIFO_SIZE 768 + +/* ACP DMA transfer size */ +#define ACP_BT_DMA_TRANS_SIZE 128 +#define BT_IER_DISABLE 0x0 +/* Vangogh hw specific addr map */ +#define ACP_DRAM_PHY_TRNS 0x0DEB0000 + +static uint64_t prev_tx_pos; +static uint64_t prev_rx_pos; +static uint32_t bt_buff_size; + +/* 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; + + bt_tdm_iter = (acp_bttdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_BTTDM_ITER)); + bt_tdm_irer = (acp_bttdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_BTTDM_IRER)); + + if (!bt_tdm_iter.bits.bttdm_txen && !bt_tdm_irer.bits.bttdm_rx_en) + /* Request SMU to set aclk to 600 Mhz */ + acp_change_clock_notify(600000000); + + 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 vangogh */ + return 0; +} + +static int acp_dai_bt_dma_pause(struct dma_chan_data *channel) +{ + /* nothing to do on vangogh */ + 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; + } + + bt_tdm_iter = (acp_bttdm_iter_t)io_reg_read(PU_REGISTER_BASE + ACP_BTTDM_ITER); + bt_tdm_irer = (acp_bttdm_irer_t)io_reg_read(PU_REGISTER_BASE + ACP_BTTDM_IRER); + if (!bt_tdm_iter.bits.bttdm_txen && !bt_tdm_irer.bits.bttdm_rx_en) { + io_reg_write((PU_REGISTER_BASE + ACP_BTTDM_IER), BT_IER_DISABLE); + /* Request SMU to scale down aclk to minimum clk */ + acp_change_clock_notify(0); + } + + 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 vangogh */ + 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 bt_ringbuff_addr; + uint32_t bt_fifo_addr; + + 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 enabled, that is not supported for now"); + return -EINVAL; + } + + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_REGISTER_BASE + SCRATCH_REG_OFFSET); + channel->is_scheduling_source = true; + channel->direction = config->direction; + bt_buff_size = config->elem_array.elems[0].size * config->elem_array.count; + + switch (config->direction) { + case DMA_DIR_MEM_TO_DEV: + + /* BT Transmit FIFO Address and FIFO Size */ + bt_fifo_addr = (uint32_t)(&pscratch_mem_cfg->acp_transmit_fifo_buffer); + bt_fifo_addr = (bt_fifo_addr & ACP_DRAM_ADDRESS_MASK); + bt_fifo_addr = (bt_fifo_addr - ACP_DRAM_PHY_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_BT_TX_FIFOADDR), bt_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_BT_TX_FIFOSIZE), (uint32_t)(BT_FIFO_SIZE)); + + /* Transmit RINGBUFFER Address and size */ + config->elem_array.elems[0].src = + (config->elem_array.elems[0].src & ACP_DRAM_ADDRESS_MASK); + bt_ringbuff_addr = (config->elem_array.elems[0].src | 0x01000000); + io_reg_write((PU_REGISTER_BASE + ACP_BT_TX_RINGBUFADDR), bt_ringbuff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_BT_TX_RINGBUFSIZE), bt_buff_size); + + /* Transmit DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_BT_TX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE_128)); + /* Watermark size for BT transfer fifo */ + io_reg_write((PU_REGISTER_BASE + ACP_BT_TX_INTR_WATERMARK_SIZE), + (bt_buff_size >> 1)); + break; + case DMA_DIR_DEV_TO_MEM: + + /* BT Receive FIFO Address and FIFO Size*/ + bt_fifo_addr = (uint32_t)(&pscratch_mem_cfg->acp_receive_fifo_buffer); + bt_fifo_addr = (bt_fifo_addr & ACP_DRAM_ADDRESS_MASK); + bt_fifo_addr = (bt_fifo_addr - ACP_DRAM_PHY_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_BT_RX_FIFOADDR), bt_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_BT_RX_FIFOSIZE), (uint32_t)(BT_FIFO_SIZE)); + + /* Receive RINGBUFFER Address and size */ + config->elem_array.elems[0].dest = + (config->elem_array.elems[0].dest & ACP_DRAM_ADDRESS_MASK); + bt_ringbuff_addr = (config->elem_array.elems[0].dest | 0x01000000); + io_reg_write((PU_REGISTER_BASE + ACP_BT_RX_RINGBUFADDR), bt_ringbuff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_BT_RX_RINGBUFSIZE), bt_buff_size); + + /* Receive DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_BT_RX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE_128)); + /* Watermark size for BT receive fifo */ + io_reg_write((PU_REGISTER_BASE + ACP_BT_RX_INTR_WATERMARK_SIZE), + (bt_buff_size >> 1)); + break; + default: + tr_err(&acp_bt_dma_tr, "unsupported config direction"); + 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_BT_TX_LINEARPOSITIONCNTR_LOW); + tx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH); + curr_tx_pos = (uint64_t)((tx_high << 32) | tx_low); + prev_tx_pos = curr_tx_pos; + *free = bt_buff_size >> 1; + *avail = bt_buff_size >> 1; + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + rx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_BT_RX_LINEARPOSITIONCNTR_LOW); + rx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH); + curr_rx_pos = (uint64_t)((rx_high << 32) | rx_low); + prev_rx_pos = curr_rx_pos; + *free = bt_buff_size >> 1; + *avail = bt_buff_size >> 1; + } 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_STAT)); + status = acp_intr_stat.bits.audio_buffer_int_stat; + return (status & (1 << channel->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_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.audio_buffer_int_mask &= (~(1 << channel->index)); + 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.audio_buffer_int_mask |= (1 << channel->index); + 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_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/vangogh/acp_dma.c b/src/drivers/amd/vangogh/acp_dma.c new file mode 100644 index 000000000000..aed98db5726d --- /dev/null +++ b/src/drivers/amd/vangogh/acp_dma.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void amd_dma_reconfig(struct dma_chan_data *channel, uint32_t bytes) +{ + uint32_t strt_idx = 0; + uint32_t src; + uint32_t dest; + uint32_t tail, head; + uint32_t src1; + uint32_t dest1; + + 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); + psrc_dscr[strt_idx].dest_addr = (dest | ACP_DRAM_ADDR_TRNS); + 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 | ACP_DRAM_ADDR_TRNS); + 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 | ACP_DRAM_ADDR_TRNS); + 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 | ACP_DRAM_ADDR_TRNS); + 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; +} + +/* Some set_config helper functions */ +int dma_setup(struct dma_chan_data *channel, + struct dma_sg_elem_array *sgelems, uint32_t dir) +{ + uint32_t dscr_cnt, dscr; + uint32_t tc; + uint16_t dscr_strt_idx; + 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 | ACP_DRAM_ADDR_TRNS); + 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 | ACP_DRAM_ADDR_TRNS); + 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 & ACP_DRAM_ADDRESS_MASK); + dma_cfg->base = + dma_config_dscr[dscr_strt_idx].dest_addr | ACP_DRAM_ADDR_TRNS; + 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 & ACP_DRAM_ADDRESS_MASK); + dma_cfg->base = + dma_config_dscr[dscr_strt_idx].src_addr | ACP_DRAM_ADDR_TRNS; + 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; +} + +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; +} diff --git a/src/drivers/amd/vangogh/acp_dmic_dma.c b/src/drivers/amd/vangogh/acp_dmic_dma.c new file mode 100644 index 000000000000..6d1a67369573 --- /dev/null +++ b/src/drivers/amd/vangogh/acp_dmic_dma.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 + +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_vgh_tr, SOF_UUID(acp_dmic_dma_uuid), LOG_LEVEL_INFO); + +uint32_t dmic_rngbuff_size; + +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; + acp_hstdm_iter_t hs_iter; + acp_hstdm_irer_t hs_irer; + uint32_t acp_pdm_en; + + struct timer *timer = timer_get(); + uint64_t deadline = platform_timer_get(timer) + + clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1) * 500 / 1000; + hs_iter = (acp_hstdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_ITER)); + hs_irer = (acp_hstdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_IRER)); + acp_pdm_en = (uint32_t)io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_ENABLE); + + if (!hs_iter.bits.hstdm_txen && !hs_irer.bits.hstdm_rx_en && !acp_pdm_en) { + io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_ACLK_CLK_SEL); + /* Request SMU to set aclk to 600 Mhz */ + acp_change_clock_notify(600000000); + } + 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_vgh_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; +} + +int acp_dmic_dma_stop(struct dma_chan_data *channel) +{ + acp_wov_pdm_dma_enable_t pdm_dma_enable; + acp_hstdm_iter_t hs_iter; + acp_hstdm_irer_t hs_irer; + uint32_t acp_pdm_en; + 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_vgh_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); + hs_iter = (acp_hstdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_ITER)); + hs_irer = (acp_hstdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_IRER)); + acp_pdm_en = (uint32_t)io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_ENABLE); + + if (!hs_iter.bits.hstdm_txen && !hs_irer.bits.hstdm_rx_en && !acp_pdm_en) { + /* Request SMU to set aclk to minimum aclk */ + acp_change_clock_notify(0); + io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_INTERNAL_CLK_SEL); + } + + return 0; +} + +/* set the DMA channel configuration, source/target address, buffer sizes */ +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 >> 1); + io_reg_write(PU_REGISTER_BASE + + ACP_WOV_RX_INTR_WATERMARK_SIZE, watermark.u32all); + break; + default: + tr_err(&acp_dmic_dma_vgh_tr, "unsupported config direction"); + return -EINVAL; + } + if (!config->cyclic) { + tr_err(&acp_dmic_dma_vgh_tr, "cyclic configurations only supported!"); + return -EINVAL; + } + if (config->scatter) { + tr_err(&acp_dmic_dma_vgh_tr, "scatter enabled, not supported for now!"); + return -EINVAL; + } + return 0; +} + +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; + 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; +} diff --git a/src/drivers/amd/vangogh/acp_hs_dai.c b/src/drivers/amd/vangogh/acp_hs_dai.c new file mode 100644 index 000000000000..cf31a8e92907 --- /dev/null +++ b/src/drivers/amd/vangogh/acp_hs_dai.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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, + const 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 vangogh 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) +{ + int handshake = dai->plat_data.fifo[direction].handshake; + + interrupt_get_irq(handshake, "irqsteer1"); + 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_HS, + .dma_caps = DMA_CAP_HS, + .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/vangogh/acp_hs_dma.c b/src/drivers/amd/vangogh/acp_hs_dma.c new file mode 100644 index 000000000000..1244482cf354 --- /dev/null +++ b/src/drivers/amd/vangogh/acp_hs_dma.c @@ -0,0 +1,431 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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_IER_DISABLE 0x0 +/* Vangogh hw specific addr map */ +#define ACP_DRAM_PHY_TRNS 0x0DEB0000 + +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; + uint32_t acp_pdm_en; + + hs_iter = (acp_hstdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_ITER)); + hs_irer = (acp_hstdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_IRER)); + acp_pdm_en = (uint32_t)io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_ENABLE); + + if (!hs_iter.bits.hstdm_txen && !hs_irer.bits.hstdm_rx_en && !acp_pdm_en) { + io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_ACLK_CLK_SEL); + /* Request SMU to set aclk to 600 Mhz */ + acp_change_clock_notify(600000000); + } + + 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 vangogh */ + return 0; +} + +static int acp_dai_hs_dma_pause(struct dma_chan_data *channel) +{ + /* nothing to do on vangogh */ + 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; + acp_i2stdm_irer_t sp_irer; + acp_i2stdm_iter_t sp_iter; + uint32_t acp_pdm_en; + + 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; + } + hs_iter = (acp_hstdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_ITER)); + hs_irer = (acp_hstdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_IRER)); + sp_iter = (acp_i2stdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_ITER)); + sp_irer = (acp_i2stdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_IRER)); + acp_pdm_en = (uint32_t)io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_ENABLE); + if (!hs_iter.bits.hstdm_txen && !hs_irer.bits.hstdm_rx_en && !sp_iter.bits.i2stdm_txen && + !sp_irer.bits.i2stdm_rx_en) { + io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_IER), HS_IER_DISABLE); + /* Request SMU to scale down aclk to minimum clk */ + if (!acp_pdm_en) { + acp_change_clock_notify(0); + io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_INTERNAL_CLK_SEL); + } + } + 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 vangogh */ + 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; + } + + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + 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 = (uint32_t)(&pscratch_mem_cfg->acp_transmit_hs_fifo_buffer); + hs_fifo_addr = (hs_fifo_addr & ACP_DRAM_ADDRESS_MASK); + hs_fifo_addr = (hs_fifo_addr - ACP_DRAM_PHY_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_HS_TX_FIFOADDR), hs_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_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 | ACP_DRAM_ADDR_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_HS_TX_RINGBUFADDR), hs_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_HS_TX_RINGBUFSIZE), hs_buff_size); + + /* Transmit DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_HS_TX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE)); + + /* Watermark size for HS transmit FIFO - Half of HS buffer size */ + io_reg_write((PU_REGISTER_BASE + ACP_HS_TX_INTR_WATERMARK_SIZE), + (hs_buff_size >> 1)); + + } else if (config->direction == DMA_DIR_DEV_TO_MEM) { + /* HS Receive FIFO Address and FIFO Size*/ + hs_fifo_addr = (uint32_t)(&pscratch_mem_cfg->acp_receive_fifo_buffer); + hs_fifo_addr = (hs_fifo_addr & ACP_DRAM_ADDRESS_MASK); + hs_fifo_addr = (hs_fifo_addr - ACP_DRAM_PHY_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_HS_RX_FIFOADDR), hs_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_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 | ACP_DRAM_ADDR_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_HS_RX_RINGBUFADDR), hs_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_HS_RX_RINGBUFSIZE), hs_buff_size); + + /* Receive DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_HS_RX_DMA_SIZE), + (uint32_t)(ACP_DMA_TRANS_SIZE)); + + /* Watermark size for receive fifo - Half of HS buffer size*/ + io_reg_write((PU_REGISTER_BASE + ACP_HS_RX_INTR_WATERMARK_SIZE), + (hs_buff_size >> 1)); + + } 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, + }; + tr_info(&acp_hs_tr, "acp_dai_hs_dma_copy "); + 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_HS_TX_LINEARPOSITIONCNTR_LOW); + tx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); + curr_tx_pos = (uint64_t)((tx_high << 32) | tx_low); + prev_tx_pos = curr_tx_pos; + *free = (hs_buff_size >> 1); + *avail = (hs_buff_size >> 1); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + rx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_HS_RX_LINEARPOSITIONCNTR_LOW); + rx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); + curr_rx_pos = (uint64_t)((rx_high << 32) | rx_low); + prev_rx_pos = curr_rx_pos; + *free = (hs_buff_size >> 1); + *avail = (hs_buff_size >> 1); + } 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; + 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_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.audio_buffer_int_stat; + return (status & (1 << channel->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_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.audio_buffer_int_mask &= (~(1 << channel->index)); + 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.audio_buffer_int_mask |= (1 << channel->index); + 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_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/vangogh/acp_sp_dai.c b/src/drivers/amd/vangogh/acp_sp_dai.c new file mode 100644 index 000000000000..62a40ef266bb --- /dev/null +++ b/src/drivers/amd/vangogh/acp_sp_dai.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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, + const void *spec_config) +{ + /* nothing to do on vangogh for SP dai */ + io_reg_write(PU_REGISTER_BASE + ACP_I2STDM0_MSTRCLKGEN, 0x40081); + return 0; +} + +static int spdai_trigger(struct dai *dai, int cmd, int direction) +{ + /* nothing to do on vangogh 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/vangogh/acp_sp_dma.c b/src/drivers/amd/vangogh/acp_sp_dma.c new file mode 100644 index 000000000000..00b2dce064b5 --- /dev/null +++ b/src/drivers/amd/vangogh/acp_sp_dma.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 + +/*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_vgh_tr, SOF_UUID(acp_sp_uuid), LOG_LEVEL_INFO); + +/* Vangogh hw specific addr map */ +#define ACP_DRAM_PHY_TRNS 0x0DEB0000 + +static uint64_t prev_tx_pos; +static uint64_t prev_rx_pos; +static uint32_t sp_buff_size; + +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; + + sp_iter = (acp_i2stdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_ITER)); + sp_irer = (acp_i2stdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_IRER)); + + if (!sp_iter.bits.i2stdm_txen && !sp_irer.bits.i2stdm_rx_en) + /* Request SMU to set aclk to 600 Mhz */ + acp_change_clock_notify(600000000); + + 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_vgh_tr, "Start direction not defined %d", channel->direction); + return -EINVAL; + } + + return 0; +} + +int acp_dai_sp_dma_stop(struct dma_chan_data *channel) +{ + acp_i2stdm_irer_t sp_irer; + acp_i2stdm_iter_t sp_iter; + acp_hstdm_iter_t hs_iter; + acp_hstdm_irer_t hs_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) { + 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_vgh_tr, "Stop direction not defined %d", channel->direction); + return -EINVAL; + } + sp_iter = (acp_i2stdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_ITER)); + sp_irer = (acp_i2stdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_I2STDM_IRER)); + hs_iter = (acp_hstdm_iter_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_ITER)); + hs_irer = (acp_hstdm_irer_t)io_reg_read((PU_REGISTER_BASE + ACP_HSTDM_IRER)); + if (!sp_iter.bits.i2stdm_txen && !sp_irer.bits.i2stdm_rx_en && !hs_iter.bits.hstdm_txen && + !hs_irer.bits.hstdm_rx_en) { + io_reg_write((PU_REGISTER_BASE + ACP_I2STDM_IER), SP_IER_DISABLE); + /* Request SMU to scale down aclk to minimum clk */ + acp_change_clock_notify(0); + io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_INTERNAL_CLK_SEL); + } + return 0; +} + +/* set the DMA channel configuration, source/target address, buffer sizes */ +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_vgh_tr, "cyclic configurations only supported!"); + return -EINVAL; + } + if (config->scatter) { + tr_err(&acp_sp_vgh_tr, "scatter enabled, that is not supported for now!"); + return -EINVAL; + } + + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + 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 = (uint32_t)(&pscratch_mem_cfg->acp_transmit_fifo_buffer); + sp_fifo_addr = (sp_fifo_addr & ACP_DRAM_ADDRESS_MASK); + sp_fifo_addr = (sp_fifo_addr - ACP_DRAM_PHY_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_I2S_TX_FIFOADDR), sp_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_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 | ACP_DRAM_ADDR_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_I2S_TX_RINGBUFADDR), sp_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_I2S_TX_RINGBUFSIZE), sp_buff_size); + + /* Transmit DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_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_I2S_TX_INTR_WATERMARK_SIZE), + (sp_buff_size >> 1)); + + } else if (config->direction == DMA_DIR_DEV_TO_MEM) { + /* SP Receive FIFO Address and FIFO Size*/ + sp_fifo_addr = (uint32_t)(&pscratch_mem_cfg->acp_receive_fifo_buffer); + sp_fifo_addr = (sp_fifo_addr & ACP_DRAM_ADDRESS_MASK); + sp_fifo_addr = (sp_fifo_addr - ACP_DRAM_PHY_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_I2S_RX_FIFOADDR), sp_fifo_addr); + io_reg_write((PU_REGISTER_BASE + ACP_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 | ACP_DRAM_ADDR_TRNS); + io_reg_write((PU_REGISTER_BASE + ACP_I2S_RX_RINGBUFADDR), sp_buff_addr); + io_reg_write((PU_REGISTER_BASE + ACP_I2S_RX_RINGBUFSIZE), sp_buff_size); + + /* Receive DMA transfer size in bytes */ + io_reg_write((PU_REGISTER_BASE + ACP_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_I2S_RX_INTR_WATERMARK_SIZE), + (sp_buff_size >> 1)); + + } else { + tr_err(&acp_sp_vgh_tr, "DMA Config channel direction undefined %d", + channel->direction); + return -EINVAL; + } + + return 0; +} + +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_I2S_TX_LINEARPOSITIONCNTR_LOW); + tx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH); + curr_tx_pos = (uint64_t)((tx_high << 32) | tx_low); + prev_tx_pos = curr_tx_pos; + //TODO timer-based scheduling + *free = (sp_buff_size >> 1); + *avail = (sp_buff_size >> 1); + } else if (channel->direction == DMA_DIR_DEV_TO_MEM) { + rx_low = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW); + rx_high = (uint32_t)io_reg_read(PU_REGISTER_BASE + + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH); + curr_rx_pos = (uint64_t)((rx_high << 32) | rx_low); + prev_rx_pos = curr_rx_pos; + //TODO timer-based scheduling + *free = (sp_buff_size >> 1); + *avail = (sp_buff_size >> 1); + } else { + tr_err(&acp_sp_vgh_tr, "Channel direction not defined %d", channel->direction); + return -EINVAL; + } + return 0; +} + +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; +} + +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_STAT); + status = acp_intr_stat.bits.audio_buffer_int_stat; + return (status & (1 << channel->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_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.audio_buffer_int_mask &= (~(1 << channel->index)); + 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.audio_buffer_int_mask |= (1 << channel->index); + status = acp_intr_cntl.u32all; + dma_reg_write(channel->dma, ACP_DSP0_INTR_CNTL, status); + return 0; + default: + return -EINVAL; + } +} diff --git a/src/drivers/amd/vangogh/interrupt.c b/src/drivers/amd/vangogh/interrupt.c new file mode 100644 index 000000000000..4e107ced7722 --- /dev/null +++ b/src/drivers/amd/vangogh/interrupt.c @@ -0,0 +1,440 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch +#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) +{ + /* 0-7 interrupts are used */ + if (index > 7) + return 0; + 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); + 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); + 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_5(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); + bit = 5;//bit-23;//HARDCODING + + 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)) { + k_spin_unlock(&cascade->lock, key); + child->handler(child->handler_arg); + k_spin_lock(&cascade->lock); + 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 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 void irqhandler_5(void *data) +{ + uint32_t line_index = 5; + struct irq_desc *parent = data; + struct irq_cascade_desc *cascade = + container_of(parent, struct irq_cascade_desc, desc); + uint64_t status; + + line_index = 5; + status = acp_get_irq_interrupts(line_index); + + if (status) + /* Handle current interrupts */ + acp_handle_irq_5(cascade, line_index, status); + else + tr_err(&acp_irq_tr, "invalid interrupt status"); +} + +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) + +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, + }, + { + .name = "irqsteer1", + .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; + 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_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); + /* 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.audio_buffer_int_mask = INTERRUPT_DISABLE; + interrupt_cntl.bits.wov_dma_intr_mask = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL), interrupt_cntl.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_external_intr_enb_t ext_interrupt_enb; + acp_dsp0_intr_cntl_t interrupt_cntl; + + 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.audio_buffer_int_stat = 0x3F; + interrupt_status.bits.wov_dma_stat = INTERRUPT_ENABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_STAT), interrupt_status.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.audio_buffer_int_mask = INTERRUPT_DISABLE; + interrupt_cntl.bits.wov_dma_intr_mask = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_DSP0_INTR_CNTL), interrupt_cntl.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 interrupt */ +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/vangogh/ipc.c b/src/drivers/amd/vangogh/ipc.c new file mode 100644 index 000000000000..05f3de709310 --- /dev/null +++ b/src/drivers/amd/vangogh/ipc.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#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 + +volatile acp_scratch_mem_config_t *pscratch_mem_cfg = (volatile acp_scratch_mem_config_t *) + (PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + +void amd_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()); + } + } +} + +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; +} + +void ipc_platform_send_msg_direct(const struct ipc_msg *msg) +{ + /* TODO: add support */ +} + From cc09d9942c54c4cf98863280b505617d11b52c99 Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 13:57:15 +0530 Subject: [PATCH 5/9] Add HS I2S DMA capabilities. Define HS I2S DMA capabilities. Signed-off-by: SaiSurya, Ch --- src/include/sof/drivers/acp_dai_dma.h | 1 + xtos/include/sof/lib/dma.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/include/sof/drivers/acp_dai_dma.h b/src/include/sof/drivers/acp_dai_dma.h index ce75e95ebb37..bd3e7280cbd2 100644 --- a/src/include/sof/drivers/acp_dai_dma.h +++ b/src/include/sof/drivers/acp_dai_dma.h @@ -42,6 +42,7 @@ int acp_dma_init(struct sof *sof); #define ACP_DRAM_ADDRESS_MASK 0x0FFFFFFF #define ACP_ACLK_CLK_SEL 0x3 #define ACP_INTERNAL_CLK_SEL 0x0 +#define ACP_DRAM_ADDR_TRNS 0x01000000 extern const struct dai_driver acp_spdai_driver; extern const struct dai_driver acp_sp_virtual_dai_driver; diff --git a/xtos/include/sof/lib/dma.h b/xtos/include/sof/lib/dma.h index 30fa889699bb..85080e70c18b 100644 --- a/xtos/include/sof/lib/dma.h +++ b/xtos/include/sof/lib/dma.h @@ -57,6 +57,7 @@ struct comp_buffer; #define DMA_CAP_DMIC BIT(5) /**< ACP DMA DMIC > */ #define DMA_CAP_SP_VIRTUAL BIT(6) /**< SP VIRTUAL DMA */ #define DMA_CAP_HS_VIRTUAL BIT(7) /**< HS VIRTUAL DMA */ +#define DMA_CAP_HS BIT(8) /**< HS DMA */ /* DMA dev type bitmasks used to define the type of DMA */ @@ -73,6 +74,7 @@ struct comp_buffer; #define DMA_DEV_AFE_MEMIF BIT(10) /**< connectable to AFE fifo */ #define DMA_DEV_SP_VIRTUAL BIT(11) /**< connectable to ACP SP VIRTUAL I2S */ #define DMA_DEV_HS_VIRTUAL BIT(12) /**< connectable to ACP HS VIRTUAL I2S */ +#define DMA_DEV_HS BIT(13) /**< connectable to ACP HS I2S */ /* DMA access privilege flag */ #define DMA_ACCESS_EXCLUSIVE 1 From a14d19f6fd06ac25713d64bb8cd92b128166314b Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 12:56:17 +0530 Subject: [PATCH 6/9] src: arch: xtensa: configs: add defconfig Add defconfig for vangogh platform. Signed-off-by: SaiSurya, Ch --- src/arch/xtensa/configs/vangogh_defconfig | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/arch/xtensa/configs/vangogh_defconfig diff --git a/src/arch/xtensa/configs/vangogh_defconfig b/src/arch/xtensa/configs/vangogh_defconfig new file mode 100644 index 000000000000..74a140b8dbf2 --- /dev/null +++ b/src/arch/xtensa/configs/vangogh_defconfig @@ -0,0 +1,26 @@ +CONFIG_VANGOGH=y +CONFIG_RIMAGE_SIGNING_SCHEMA="vangogh" +CONFIG_TRACE_CHANNEL=7 +CONFIG_WRAP_ACTUAL_POSITION=y +CONFIG_AMD_BT=n +CONFIG_CORE_COUNT=1 +CONFIG_LP_MEMORY_BANKS=0 +CONFIG_HP_MEMORY_BANKS=20 +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 +CONFIG_TRACE=y +CONFIG_TRACEE=y +CONFIG_TRACEV=y From d762132dbac30cecd57113d79111905c4f3c2e4a Mon Sep 17 00:00:00 2001 From: SaiSurya Ch Date: Wed, 5 Jul 2023 12:11:40 +0530 Subject: [PATCH 7/9] tools: topology: add vangogh topology support Add vangogh platform topology for nau8821,max988388. Signed-off-by: SaiSurya Ch --- tools/topology/topology1/CMakeLists.txt | 1 + tools/topology/topology1/sof-acp-vangogh.m4 | 68 +++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 tools/topology/topology1/sof-acp-vangogh.m4 diff --git a/tools/topology/topology1/CMakeLists.txt b/tools/topology/topology1/CMakeLists.txt index 0f126e1ada9b..48e945f7737a 100644 --- a/tools/topology/topology1/CMakeLists.txt +++ b/tools/topology/topology1/CMakeLists.txt @@ -217,6 +217,7 @@ set(TPLGS "sof-rn-rt5682-rt1019\;sof-rn-rt5682-rt1019-dts\;-DDTS=`DTS'" "sof-rn-rt5682-max98360\;sof-rn-rt5682-max98360" "sof-acp-rmb\;sof-acp-rmb" + "sof-acp-vangogh\;sof-vangogh-nau8821-max" "sof-acp-rmb-dmic4ch\;sof-acp-rmb-dmic4ch" "sof-acp-rmb-tdm8ch-dmic4ch-rt5682-rt1019\;sof-acp-rmb-tdm8ch-dmic4ch-rt5682-rt1019" "sof-acp-rmb-tdm8ch-dmic2ch-nau8825-max98360\;sof-acp-rmb-tdm8ch-dmic2ch-nau8825-max98360" diff --git a/tools/topology/topology1/sof-acp-vangogh.m4 b/tools/topology/topology1/sof-acp-vangogh.m4 new file mode 100644 index 000000000000..27cfbc96da79 --- /dev/null +++ b/tools/topology/topology1/sof-acp-vangogh.m4 @@ -0,0 +1,68 @@ +# +# Topology for Vangogh with I2S SP and I2S HS. +# + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`acp-hs.m4') +include(`acp-sp.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include ACP DSP configuration +include(`platform/amd/acp.m4') + +# Playback pipeline 1 on PCM 0 using max 2 channels of s16le. +# Schedule 96 frames per 2000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 1, 0, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +# playback DAI is ACPSP using 2 periods +DAI_ADD(sof/pipe-dai-playback.m4, 1, ACPSP, 0, acp-headset-codec, +PIPELINE_SOURCE_1, 2, s16le, 2000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +DAI_CONFIG(ACPSP, 0, 0, acp-headset-codec, + ACPSP_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_slave), + ACP_CLOCK(fsync, 48000, codec_slave), + ACP_TDM(2, 32, 3, 3),ACPSP_CONFIG_DATA(ACPSP, 0, 48000, 2, 0))) + +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 2, 1, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +# playback DAI is ACPSP using 2 periods +DAI_ADD(sof/pipe-dai-playback.m4, 2, ACPHS, 1, acp-amp-codec, +PIPELINE_SOURCE_2, 2, s16le, 2000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +DAI_CONFIG(ACPHS, 1, 1, acp-amp-codec, + ACPHS_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_slave), + ACP_CLOCK(fsync, 48000, codec_slave), + ACP_TDM(2, 32, 3, 3),ACPHS_CONFIG_DATA(ACPHS, 1, 48000, 2, 0))) + + +# Capture pipeline 2 on PCM 0 using max 2 channels of s16le. +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 3, 0, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +# Capture DAI is ACPSP using 2 periods +DAI_ADD(sof/pipe-dai-capture.m4, 3, ACPSP, 0, acp-headset-codec, +PIPELINE_SINK_3, 2, s16le, 2000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +# PCM id 0 +PCM_DUPLEX_ADD(I2SSP, 0, PIPELINE_PCM_1, PIPELINE_PCM_3) + +# PCM id 1 +PCM_PLAYBACK_ADD(I2SHS, 1, PIPELINE_PCM_2) From 0d492b1f1cfbc0debe27f2a42ba30cd4fff67c0c Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 13:54:18 +0530 Subject: [PATCH 8/9] amd: vangogh: add build support for vangogh Add build support to enable vangogh platform. Signed-off-by: SaiSurya, Ch --- src/arch/xtensa/CMakeLists.txt | 4 +++- src/drivers/amd/CMakeLists.txt | 2 ++ src/platform/Kconfig | 14 ++++++++++++++ src/platform/amd/CMakeLists.txt | 4 +++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/arch/xtensa/CMakeLists.txt b/src/arch/xtensa/CMakeLists.txt index 4f8fd6ee65e6..1d9bac023bac 100644 --- a/src/arch/xtensa/CMakeLists.txt +++ b/src/arch/xtensa/CMakeLists.txt @@ -16,6 +16,8 @@ elseif(CONFIG_RENOIR) set(platform_folder amd/renoir) elseif(CONFIG_REMBRANDT) set(platform_folder amd/rembrandt) +elseif(CONFIG_VANGOGH) + set(platform_folder amd/vangogh) elseif(CONFIG_MT8186) set(platform_folder mt8186) elseif(CONFIG_MT8188) @@ -468,7 +470,7 @@ add_custom_target( # NXP set(UNSIGNED_RI imx8 imx8x imx8m imx8ulp) # AMD -list(APPEND UNSIGNED_RI rn rmb) +list(APPEND UNSIGNED_RI rn rmb vangogh) # MediaTek list(APPEND UNSIGNED_RI mt8186 mt8188 mt8195) diff --git a/src/drivers/amd/CMakeLists.txt b/src/drivers/amd/CMakeLists.txt index db3d00b2797f..f3c352bb17fc 100644 --- a/src/drivers/amd/CMakeLists.txt +++ b/src/drivers/amd/CMakeLists.txt @@ -4,4 +4,6 @@ if(CONFIG_RENOIR) add_subdirectory(renoir) elseif(CONFIG_REMBRANDT) add_subdirectory(rembrandt) +elseif(CONFIG_VANGOGH) + add_subdirectory(vangogh) endif() diff --git a/src/platform/Kconfig b/src/platform/Kconfig index cf65d24317dc..33908090dba2 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -167,6 +167,19 @@ config REMBRANDT help Select if your target platform is rembrandt-compatible +config VANGOGH + bool "Build for Vangogh" + 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 AMD + select SCHEDULE_DMA_MULTI_CHANNEL + help + Select if your target platform is vangogh-compatible + config MT8186 bool "Build for MTK MT8186" select XT_INTERRUPT_LEVEL_1 @@ -413,6 +426,7 @@ config RIMAGE_SIGNING_SCHEMA default "imx8ulp" if IMX8ULP default "rn" if RENOIR default "rmb" if REMBRANDT + default "vangogh" if VANGOGH default "mt8186" if MT8186 default "mt8188" if MT8188 default "mt8195" if MT8195 diff --git a/src/platform/amd/CMakeLists.txt b/src/platform/amd/CMakeLists.txt index d3092e1ca1ea..f3c352bb17fc 100644 --- a/src/platform/amd/CMakeLists.txt +++ b/src/platform/amd/CMakeLists.txt @@ -1,7 +1,9 @@ # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(common) if(CONFIG_RENOIR) -add_subdirectory(renoir) + add_subdirectory(renoir) elseif(CONFIG_REMBRANDT) add_subdirectory(rembrandt) +elseif(CONFIG_VANGOGH) + add_subdirectory(vangogh) endif() From d299710ae3a994ea6266f7085d203f65d99df9f0 Mon Sep 17 00:00:00 2001 From: "SaiSurya, Ch" Date: Tue, 20 Jun 2023 13:02:58 +0530 Subject: [PATCH 9/9] scripts: add support for vangogh platform Add support for Vangogh platform in build scripts. Signed-off-by: SaiSurya, Ch --- scripts/xtensa-build-all.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/xtensa-build-all.sh b/scripts/xtensa-build-all.sh index 059cd07fb283..e8cae4417964 100755 --- a/scripts/xtensa-build-all.sh +++ b/scripts/xtensa-build-all.sh @@ -9,7 +9,7 @@ set -e # They must have a toolchain available in the latest Docker image. DEFAULT_PLATFORMS=( imx8 imx8x imx8m imx8ulp - rn rmb + rn rmb vangogh mt8186 mt8195 ) @@ -235,6 +235,13 @@ do HOST="xtensa-rmb-elf" XTENSA_TOOLS_VERSION="RI-2019.1-linux" ;; + vangogh) + PLATFORM="vangogh" + ARCH="xtensa" + XTENSA_CORE="ACP_5_0_001_PROD" + HOST="xtensa-vangogh-elf" + XTENSA_TOOLS_VERSION="RI-2019.1-linux" + ;; mt8186) PLATFORM="mt8186" XTENSA_CORE="hifi5_7stg_I64D128"