diff --git a/rimage b/rimage index d1f91efdc1e1..7e738ca7c67e 160000 --- a/rimage +++ b/rimage @@ -1 +1 @@ -Subproject commit d1f91efdc1e19093df9c88f0b9779010b0177616 +Subproject commit 7e738ca7c67e338abbc1877ab745febbc3ac3207 diff --git a/scripts/qemu-check.sh b/scripts/qemu-check.sh index 57500490fa6f..28bd056f64c4 100755 --- a/scripts/qemu-check.sh +++ b/scripts/qemu-check.sh @@ -3,7 +3,7 @@ # Copyright(c) 2018 Intel Corporation. All rights reserved. set -e -SUPPORTED_PLATFORMS=(byt cht bdw hsw apl icl skl kbl cnl imx8 imx8x imx8m) +SUPPORTED_PLATFORMS=(byt cht bdw hsw apl icl skl kbl cnl imx8 imx8x imx8m imx8ulp) READY_MSG="6c 00 00 00 00 00 00 70" SOF_DIR=$(cd "$(dirname "$0")" && cd .. && pwd) @@ -139,7 +139,7 @@ do SHM_MBOX=qemu-bridge-hp-sram-mem has_rom=true ;; - imx8 | imx8x | imx8m) + imx8 | imx8x | imx8m | imx8ulp) READY_IPC="00 00 00 00 00 00 04 c0" SHM_IPC_REG=qemu-bridge-mu-io SHM_MBOX=qemu-bridge-mbox-io diff --git a/scripts/xtensa-build-all.sh b/scripts/xtensa-build-all.sh index 69a16ccb40c2..795dd5446dcb 100755 --- a/scripts/xtensa-build-all.sh +++ b/scripts/xtensa-build-all.sh @@ -6,7 +6,7 @@ set -e SUPPORTED_PLATFORMS=(byt cht bdw hsw apl skl kbl cnl sue icl jsl \ - imx8 imx8x imx8m tgl tgl-h) + imx8 imx8x imx8m imx8ulp tgl tgl-h) BUILD_ROM=no BUILD_DEBUG=no BUILD_FORCE_UP=no @@ -314,6 +314,12 @@ do HOST="xtensa-imx8m-elf" XTENSA_TOOLS_VERSION="RG-2017.8-linux" ;; + imx8ulp) + PLATFORM="imx8ulp" + XTENSA_CORE="hifi4_nxp2_ulp_prod" + HOST="xtensa-imx8ulp-elf" + XTENSA_TOOLS_VERSION="RG-2017.8-linux" + ;; esac diff --git a/src/arch/xtensa/CMakeLists.txt b/src/arch/xtensa/CMakeLists.txt index c3ad99834d71..31b1760f88b5 100644 --- a/src/arch/xtensa/CMakeLists.txt +++ b/src/arch/xtensa/CMakeLists.txt @@ -29,6 +29,8 @@ elseif(CONFIG_IMX8X) set(platform_folder imx8) elseif(CONFIG_IMX8M) set(platform_folder imx8m) +elseif(CONFIG_IMX8ULP) + set(platform_folder imx8ulp) endif() if(CONFIG_CAVS) diff --git a/src/arch/xtensa/configs/imx8ulp_defconfig b/src/arch/xtensa/configs/imx8ulp_defconfig new file mode 100644 index 000000000000..28247a20678e --- /dev/null +++ b/src/arch/xtensa/configs/imx8ulp_defconfig @@ -0,0 +1,4 @@ +CONFIG_IMX8ULP=y +CONFIG_HAVE_AGENT=n +CONFIG_FORMAT_CONVERT_HIFI3=n +CONFIG_KPB_FORCE_COPY_TYPE_NORMAL=n diff --git a/src/audio/dai.c b/src/audio/dai.c index d12d68cbc4cd..53bffce773f0 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -116,7 +116,7 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) void *buffer_ptr; int ret; - comp_dbg(dev, "dai_dma_cb()"); + //comp_info(dev, "dai_dma_cb()"); next->status = DMA_CB_STATUS_RELOAD; @@ -354,7 +354,7 @@ static int dai_playback_params(struct comp_dev *dev, uint32_t period_bytes, fifo = dai_get_fifo(dd->dai, dev->direction, dd->stream_id); - comp_info(dev, "dai_playback_params() fifo 0x%x", fifo); + comp_info(dev, "dai_playback_params() fifo 0x%x, src %x", fifo, dd->dma_buffer->stream.addr); err = dma_sg_alloc(&config->elem_array, SOF_MEM_ZONE_RUNTIME, config->direction, @@ -433,6 +433,20 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes, return 0; } +static int dai_comp_hw_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) +{ + struct dai_data *dd = comp_get_drvdata(dev); + int ret; + comp_info(dev, "dai_comp_hw_params()"); + /* configure hw dai stream params */ + ret = dai_hw_params(dd->dai, params); + if (ret < 0) { + comp_err(dev, "dai_comp_hw_params(): dai_hw_params failed ret %d", ret); + return ret; + } + return 0; +} + static int dai_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) { @@ -455,6 +469,12 @@ static int dai_params(struct comp_dev *dev, return -EINVAL; } + err = dai_comp_hw_params(dev, params); + if (err < 0) { + comp_err(dev, "dai_params(): dai_comp_hw_params failed err %d", err); + return err; + } + if (dev->direction == SOF_IPC_STREAM_PLAYBACK) dd->local_buffer = list_first_item(&dev->bsource_list, struct comp_buffer, @@ -551,7 +571,10 @@ static int dai_params(struct comp_dev *dev, static int dai_prepare(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); + struct sof_ipc_comp_dai *dai = COMP_GET_IPC(dev, sof_ipc_comp_dai); int ret = 0; + dd->chan->srcid = dai_get_srcid(dd->dai, dai->direction, + dd->stream_id); comp_dbg(dev, "dai_prepare()"); @@ -732,7 +755,7 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd) /* DAI not in a group, use normal trigger */ if (!group) { - comp_dbg(dev, "dai_comp_trigger(), non-atomic trigger"); + comp_info(dev, "dai_comp_trigger(), non-atomic trigger"); return dai_comp_trigger_internal(dev, cmd); } @@ -967,7 +990,9 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) case SOF_DAI_IMX_SAI: handshake = dai_get_handshake(dd->dai, dai->direction, dd->stream_id); + comp_info(dev, "dai_config(), handshake = %d", handshake); channel = EDMA_HS_GET_CHAN(handshake); + comp_info(dev, "dai_config(), channel = %d", channel); dd->config.burst_elems = dd->dai->plat_data.fifo[dai->direction].depth; diff --git a/src/audio/host.c b/src/audio/host.c index 0c456a99fe8c..02f876977e4e 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -133,7 +133,7 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes) struct comp_buffer *source; struct comp_buffer *sink; int ret; - + static int count = 0; if (dev->direction == SOF_IPC_STREAM_PLAYBACK) ret = dma_buffer_copy_from(hd->dma_buffer, hd->local_buffer, @@ -168,9 +168,17 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes) if (hd->local_pos >= hd->host_size) hd->local_pos = 0; + count++; + if (count % 100 == 0) + comp_info(dev, "count %d, local pos %d, host size %d, period_bytes %d", count, hd->local_pos, hd->host_size, hd->host_period_bytes); + + if (count % 100 == 0) + comp_info(dev, "hd local pos %d, host size %d, no stream_pos %d", hd->local_pos, hd->host_size, hd->no_stream_position); /* Don't send stream position if no_stream_position == 1 */ if (!hd->no_stream_position) { hd->report_pos += bytes; + if (count % 100 == 0) + comp_info(dev, "hd host_period_bytes %d, report_pos %d", hd->host_period_bytes, hd->report_pos); /* host_period_bytes is set to zero to disable position update * by IPC for FW version before 3.11, so send IPC message to @@ -178,15 +186,18 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes) */ if (hd->host_period_bytes != 0 && hd->report_pos >= hd->host_period_bytes) { + comp_info(dev, "count %d, local pos %d, host size %d, period_bytes %d", count, hd->local_pos, hd->host_size, hd->host_period_bytes); hd->report_pos = 0; /* send timestamped position to host * (updates position first, by calling ops.position()) */ pipeline_get_timestamp(dev->pipeline, dev, &hd->posn); + comp_info(dev, "host period bytes %d, local pos %d, pipeline posnoffset %x", hd->host_period_bytes, hd->local_pos, dev->pipeline->posn_offset); mailbox_stream_write(dev->pipeline->posn_offset, &hd->posn, sizeof(hd->posn)); ipc_msg_send(hd->msg, &hd->posn, false); + //ipc_msg_send(hd->msg, &hd->posn, true); } } } @@ -238,7 +249,7 @@ static void host_dma_cb(void *arg, enum notify_id type, void *data) struct host_data *hd = comp_get_drvdata(dev); uint32_t bytes = next->elem.size; - comp_cl_dbg(&comp_host, "host_dma_cb() %p", &comp_host); + //comp_cl_info(&comp_host, "host_dma_cb() %p, bytes %x", &comp_host, bytes); /* update position */ host_update_position(dev, bytes); @@ -297,7 +308,7 @@ static int host_copy_one_shot(struct comp_dev *dev) uint32_t copy_bytes = 0; int ret = 0; - comp_dbg(dev, "host_copy_one_shot()"); + //comp_info(dev, "host_copy_one_shot()"); copy_bytes = host_get_copy_bytes_one_shot(dev); if (!copy_bytes) { @@ -392,7 +403,7 @@ static int host_copy_normal(struct comp_dev *dev) uint32_t flags = 0; int ret = 0; - comp_dbg(dev, "host_copy_normal()"); + comp_info(dev, "host_copy_normal()"); if (hd->copy_type == COMP_COPY_BLOCKING) flags |= DMA_COPY_BLOCKING; @@ -425,6 +436,7 @@ static int create_local_elems(struct comp_dev *dev, uint32_t buffer_count, if (hd->host.elem_array.count) { elem_array = &hd->local.elem_array; + comp_err(dev, "create_local_elems(): dma_sg_alloc A"); /* config buffer will be used as proxy */ err = dma_sg_alloc(&hd->config.elem_array, SOF_MEM_ZONE_RUNTIME, dir, 1, 0, 0, 0); @@ -436,6 +448,7 @@ static int create_local_elems(struct comp_dev *dev, uint32_t buffer_count, elem_array = &hd->config.elem_array; } + comp_err(dev, "create_local_elems(): dma_sg_alloc() "); err = dma_sg_alloc(elem_array, SOF_MEM_ZONE_RUNTIME, dir, buffer_count, buffer_bytes, (uintptr_t)(hd->dma_buffer->stream.addr), 0); @@ -462,7 +475,7 @@ static int host_trigger(struct comp_dev *dev, int cmd) struct host_data *hd = comp_get_drvdata(dev); int ret = 0; - comp_dbg(dev, "host_trigger()"); + comp_info(dev, "host_trigger()"); ret = comp_set_state(dev, cmd); if (ret < 0) @@ -769,6 +782,7 @@ static int host_params(struct comp_dev *dev, return -ENODEV; } + comp_info(dev, "host_params(), dma_set_config"); err = dma_set_config(hd->chan, &hd->config); if (err < 0) { comp_err(dev, "host_params(): dma_set_config() failed"); @@ -844,6 +858,7 @@ static int host_position(struct comp_dev *dev, /* TODO: improve accuracy by adding current DMA position */ posn->host_posn = hd->local_pos; + comp_info(dev, "host_posn %x", (int)posn->host_posn); return 0; } diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 81c0a4d799e3..8d51495f4b9b 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -753,6 +753,8 @@ pipeline_should_report_enodata_on_trigger(struct comp_dev *rsrc, return false; } +int count=1; + static int pipeline_comp_trigger(struct comp_dev *current, struct comp_buffer *calling_buf, struct pipeline_walk_context *ctx, int dir) @@ -763,15 +765,19 @@ static int pipeline_comp_trigger(struct comp_dev *current, pipeline_is_same_sched_comp(current->pipeline, ppl_data->start->pipeline); int err; + int val; - pipe_dbg(current->pipeline, "pipeline_comp_trigger(), current->comp.id = %u, dir = %u", - dev_comp_id(current), dir); + pipe_info(current->pipeline, "pipeline_comp_trigger(), current->comp.id = %u, dir = %u, count %d", + dev_comp_id(current), dir, count); + count++; + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + pipe_info(current->pipeline, "pipeline comp tirgger IMX GCR %x", val); /* trigger should propagate to the connected pipelines, * which need to be scheduled together */ if (!is_single_ppl && !is_same_sched) { - pipe_dbg(current->pipeline, "pipeline_comp_trigger(), current is from another pipeline"); + pipe_info(current->pipeline, "pipeline_comp_trigger(), current is from another pipeline"); if (pipeline_should_report_enodata_on_trigger(current, ctx, dir)) @@ -780,6 +786,7 @@ static int pipeline_comp_trigger(struct comp_dev *current, return 0; } + //pipe_info(current->pipeline, "is shared %d, cpu is me %d\n", current->is_shared, cpu_is_me(current->comp.core)); /* send command to the component and update pipeline state */ err = comp_trigger(current, ppl_data->cmd); if (err < 0 || err == PPL_STATUS_PATH_STOP) @@ -845,8 +852,10 @@ static void pipeline_schedule_triggered(struct pipeline_walk_context *ctx, switch (cmd) { case COMP_TRIGGER_PAUSE: case COMP_TRIGGER_STOP: + pipe_info(p, "pipeline schedule trigger stop..."); pipeline_schedule_cancel(p); p->status = COMP_STATE_PAUSED; + pipe_info(p, "pipeline schedule trigger stop return"); break; case COMP_TRIGGER_RELEASE: case COMP_TRIGGER_START: @@ -862,6 +871,7 @@ static void pipeline_schedule_triggered(struct pipeline_walk_context *ctx, } irq_local_enable(flags); + return; } /* trigger pipeline */ @@ -874,6 +884,7 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd) .skip_incomplete = true, }; int ret; + int val; pipe_info(p, "pipe trigger cmd %d", cmd); @@ -900,7 +911,10 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd) } pipeline_schedule_triggered(&walk_ctx, cmd); - + + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + pipe_info(p, "pipe IMX GCR %x", val); + pipe_info(p, "pipe trigger return"); return ret; } @@ -1215,7 +1229,7 @@ static enum task_state pipeline_task(void *arg) struct pipeline *p = arg; int err; - pipe_dbg(p, "pipeline_task()"); + //pipe_info(p, "pipeline_task(), task %p", &(p->pipe_task)); /* are we in xrun ? */ if (p->xrun_bytes) { diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index 01044de0e40e..a269be14e9ce 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -714,6 +714,7 @@ static int volume_copy(struct comp_dev *dev) uint32_t sink_bytes; uint32_t frames; int64_t prev_sum = 0; + int val; comp_dbg(dev, "volume_copy()"); @@ -725,9 +726,12 @@ static int volume_copy(struct comp_dev *dev) /* Get source, sink, number of frames etc. to process. */ comp_get_copy_limits_with_lock(source, sink, &c); - comp_dbg(dev, "volume_copy(), source_bytes = 0x%x, sink_bytes = 0x%x", + comp_info(dev, "volume_copy(), source_bytes = 0x%x, sink_bytes = 0x%x", c.source_bytes, c.sink_bytes); + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + comp_info(dev, "volume IMX GCR %x", val); + while (c.frames) { if (cd->ramp_finished || cd->vol_ramp_frames > c.frames) { /* without ramping process all at once */ diff --git a/src/drivers/Kconfig b/src/drivers/Kconfig index 50e15ac0e0e7..022ee57c1954 100644 --- a/src/drivers/Kconfig +++ b/src/drivers/Kconfig @@ -25,6 +25,20 @@ config IMX_EDMA help Select this to enable support for i.MX EDMA DMA controller. +config IMX_IRQ + bool "i.MX IRQ" + default n + depends on IMX + help + Select this to enable support for i.MX interrupt with irq. + +config IMX_NOIRQ + bool "i.MX NO IRQ" + default n + depends on IMX + help + Select this to enable support for i.MX interrupt without irq. + config IPC_POLLING bool "Enable IPC Polling support" default n diff --git a/src/drivers/generic/dummy-dma.c b/src/drivers/generic/dummy-dma.c index b99085fd2fca..6e0f9ad2c824 100644 --- a/src/drivers/generic/dummy-dma.c +++ b/src/drivers/generic/dummy-dma.c @@ -98,6 +98,8 @@ static ssize_t dummy_dma_copy_crt_elem(struct dma_chan_pdata *pdata, remaining_size = orig_size - pdata->elem_progress; copy_size = MIN(remaining_size, bytes); + //tr_info(&ddma_tr,"rptr %x, wptr %x", (uint32_t)rptr, (uint32_t)wptr); +// tr_info(&ddma_tr,"orig_size %x, remaining_size %x, copy_size %x", orig_size, remaining_size, copy_size); /* On playback, invalidate host buffer (it may lie in a cached area). * Otherwise we could be playing stale data. * On capture this should be safe as host.c does a writeback before @@ -109,6 +111,7 @@ static ssize_t dummy_dma_copy_crt_elem(struct dma_chan_pdata *pdata, ret = memcpy_s((void *)wptr, remaining_size, (void *)rptr, copy_size); assert(!ret); +// tr_info(&ddma_tr, "memcpys done"); /* On capture, writeback the host buffer (it may lie in a cached area). * On playback, also writeback because host.c does an invalidate to * be able to use the data transferred by the DMA. @@ -191,6 +194,7 @@ static ssize_t dummy_dma_do_copies(struct dma_chan_pdata *pdata, int bytes) ssize_t copied = 0; ssize_t crt_copied; + //tr_info(&ddma_tr,"dummy copies, avail %x", avail); if (!avail) return -ENODATA; @@ -205,6 +209,7 @@ static ssize_t dummy_dma_do_copies(struct dma_chan_pdata *pdata, int bytes) bytes -= crt_copied; copied += crt_copied; } + //tr_info(&ddma_tr,"dummy copies return"); return copied; } diff --git a/src/drivers/imx/CMakeLists.txt b/src/drivers/imx/CMakeLists.txt index 94e3c11ecc48..f0dc696bba8a 100644 --- a/src/drivers/imx/CMakeLists.txt +++ b/src/drivers/imx/CMakeLists.txt @@ -3,7 +3,6 @@ add_local_sources(sof esai.c sai.c - interrupt.c ipc.c timer.c sdma.c @@ -12,3 +11,9 @@ add_local_sources(sof if(CONFIG_IMX_EDMA) add_local_sources(sof edma.c) endif() +if(CONFIG_IMX_NOIRQ) + add_local_sources(sof interrupt-noirq.c) +endif() +if(CONFIG_IMX_IRQ) + add_local_sources(sof interrupt.c) +endif() diff --git a/src/drivers/imx/edma.c b/src/drivers/imx/edma.c index ab99412412f3..938cf77b685b 100644 --- a/src/drivers/imx/edma.c +++ b/src/drivers/imx/edma.c @@ -91,7 +91,7 @@ static struct dma_chan_data *edma_channel_get(struct dma *dma, uint32_t flags; struct dma_chan_data *channel; - tr_dbg(&edma_tr, "EDMA: channel_get(%d)", req_chan); + tr_info(&edma_tr, "EDMA: channel_get(%d)", req_chan); spin_lock_irq(&dma->lock, flags); if (req_chan >= dma->plat_data.channels) { @@ -171,7 +171,6 @@ static int edma_pause(struct dma_chan_data *channel) return -EINVAL; channel->status = COMP_STATE_PAUSED; - /* Disable HW requests */ dma_chan_reg_update_bits(channel, EDMA_CH_CSR, EDMA_CH_CSR_ERQ_EARQ, 0); @@ -209,6 +208,7 @@ static int edma_copy(struct dma_chan_data *channel, int bytes, uint32_t flags) .channel = channel, .elem.size = bytes, }; + //tr_info(&edma_tr, "EDMA: copy"); notifier_event(channel, NOTIFIER_ID_DMA_COPY, NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); @@ -266,6 +266,7 @@ static int edma_validate_nonsg_config(struct dma_sg_elem_array *sgelems, * \param[in] sgelems The scatter-gather elems, from the config * \param[in] src_width Width of transfer on source end * \param[in] dest_width Width of transfer on destination end + * \param[in] srcid eventid for 8ulp * \return 0 on success, negative on error * * Computes the TCD to be uploaded to the hardware registers. In the @@ -275,7 +276,7 @@ static int edma_validate_nonsg_config(struct dma_sg_elem_array *sgelems, static int edma_setup_tcd(struct dma_chan_data *channel, int16_t soff, int16_t doff, bool cyclic, bool sg, bool irqoff, struct dma_sg_elem_array *sgelems, int src_width, - int dest_width, uint32_t burst_elems) + int dest_width, uint32_t burst_elems, uint32_t srcid) { int rc; uint32_t sbase, dbase, total_size, elem_count, elem_size, size; @@ -301,6 +302,7 @@ static int edma_setup_tcd(struct dma_chan_data *channel, int16_t soff, sbase = sgelems->elems[0].src; dbase = sgelems->elems[0].dest; + tr_info(&edma_tr, "edma_setup_tcd, sbase %x, dbase %x", sbase, dbase); total_size = 2 * sgelems->elems[0].size; /* TODO more flexible elem_count and elem_size * calculations @@ -324,7 +326,14 @@ static int edma_setup_tcd(struct dma_chan_data *channel, int16_t soff, if (rc < 0) return rc; + /* only impact 8ulp platform */ + if (srcid) { + if (!dma_chan_reg_read(channel, EDMA_CH_MUX)) + dma_chan_reg_write(channel, EDMA_CH_MUX, srcid); + } + //tr_info(&edma_tr, "edma_setup_tcd B"); /* Configure the in-hardware TCD */ + sbase = 0x8e000000 + (sbase - 0x1a000000); dma_chan_reg_write(channel, EDMA_TCD_SADDR, sbase); dma_chan_reg_write16(channel, EDMA_TCD_SOFF, soff); dma_chan_reg_write16(channel, EDMA_TCD_ATTR, rc); @@ -348,6 +357,7 @@ static int edma_set_config(struct dma_chan_data *channel, { int16_t soff = 0; int16_t doff = 0; + int ret; tr_info(&edma_tr, "EDMA: set config"); @@ -377,10 +387,14 @@ static int edma_set_config(struct dma_chan_data *channel, return -EINVAL; } - return edma_setup_tcd(channel, soff, doff, config->cyclic, + tr_info(&edma_tr, "EDMA: channel index %d, soff %d, doff %d, srcid %d", + channel->index, soff, doff, channel->srcid); + ret = edma_setup_tcd(channel, soff, doff, config->cyclic, config->scatter, config->irq_disabled, &config->elem_array, config->src_width, - config->dest_width, config->burst_elems); + config->dest_width, config->burst_elems, channel->srcid); + tr_info(&edma_tr, "EDMA: set config return"); + return ret; } /* restore DMA context after leaving D3 */ @@ -450,6 +464,7 @@ static int edma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) case DMA_IRQ_STATUS_GET: return dma_chan_reg_read(channel, EDMA_CH_INT); case DMA_IRQ_CLEAR: + //tr_info(&edma_tr, "EDMA interrupt clear, channel idx %d", channel->index); dma_chan_reg_write(channel, EDMA_CH_INT, 1); return 0; case DMA_IRQ_MASK: diff --git a/src/drivers/imx/interrupt-noirq.c b/src/drivers/imx/interrupt-noirq.c new file mode 100644 index 000000000000..7c752e7f1667 --- /dev/null +++ b/src/drivers/imx/interrupt-noirq.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2021 NXP +// +// Author: Peng Zhang + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* fa00558c-d653-4851-a03a-b21f125a9524 */ +DECLARE_SOF_UUID("noirq-imx", noirq_imx_uuid, 0xfa00558c, 0xd653, 0x4851, + 0xa0, 0x3a, 0xb2, 0x1f, 0x12, 0x5a, 0x95, 0x24); + +DECLARE_TR_CTX(noirq_i_tr, SOF_UUID(noirq_imx_uuid), LOG_LEVEL_INFO); + +int irqstr_get_sof_int(int irqstr_int) +{ + return irqstr_int; +} + +void platform_interrupt_init(void) +{ + return; +} + +void platform_interrupt_set(uint32_t irq) +{ + arch_interrupt_set(irq); + return; +} + +void platform_interrupt_clear(uint32_t irq, uint32_t mask) +{ + arch_interrupt_clear(irq); + return; +} + +uint32_t platform_interrupt_get_enabled(void) +{ + return 0; +} + +void interrupt_mask(uint32_t irq, unsigned int cpu) +{ + return; +} + +void interrupt_unmask(uint32_t irq, unsigned int cpu) +{ + return; +} diff --git a/src/drivers/imx/ipc.c b/src/drivers/imx/ipc.c index 4a727653605d..36c53494a090 100644 --- a/src/drivers/imx/ipc.c +++ b/src/drivers/imx/ipc.c @@ -43,45 +43,49 @@ static void irq_handler(void *arg) uint32_t status; /* Interrupt arrived, check src */ - status = imx_mu_read(IMX_MU_xSR); + status = imx_mu_read(IMX_MU_xSR(IMX_MU_VERSION, IMX_MU_GSR)); - tr_dbg(&ipc_tr, "ipc: irq isr 0x%x", status); + tr_info(&ipc_tr, "ipc: irq isr 0x%x", status); /* reply message(done) from host */ - if (status & IMX_MU_xSR_GIPn(1)) { + if (status & IMX_MU_xSR_GIPn(IMX_MU_VERSION, 1)) { /* Disable GP interrupt #1 */ - imx_mu_xcr_rmw(0, IMX_MU_xCR_GIEn(1)); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, 0, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 1)); /* Clear GP pending interrupt #1 */ - imx_mu_xsr_rmw(IMX_MU_xSR_GIPn(1), 0); + imx_mu_xsr_rmw(IMX_MU_VERSION, IMX_MU_GSR, IMX_MU_xSR_GIPn(IMX_MU_VERSION, 1), 0); interrupt_clear(PLATFORM_IPC_INTERRUPT); ipc->is_notification_pending = false; /* unmask GP interrupt #1 */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIEn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 1), 0); } /* new message from host */ - if (status & IMX_MU_xSR_GIPn(0)) { + if (status & IMX_MU_xSR_GIPn(IMX_MU_VERSION, 0)) { /* Disable GP interrupt #0 */ - imx_mu_xcr_rmw(0, IMX_MU_xCR_GIEn(0)); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, 0, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 0)); /* Clear GP pending interrupt #0 */ - imx_mu_xsr_rmw(IMX_MU_xSR_GIPn(0), 0); + imx_mu_xsr_rmw(IMX_MU_VERSION, IMX_MU_GSR, IMX_MU_xSR_GIPn(IMX_MU_VERSION, 0), 0); interrupt_clear(PLATFORM_IPC_INTERRUPT); ipc_schedule_process(ipc); } + status = imx_mu_read(IMX_MU_xSR(IMX_MU_VERSION, IMX_MU_GSR)); + + tr_info(&ipc_tr, "check ipc: irq isr 0x%x", status); } enum task_state ipc_platform_do_cmd(void *data) { struct ipc *ipc = ipc_get(); struct sof_ipc_cmd_hdr *hdr; + int val; /* Use struct ipc_data *iipc = ipc_get_drvdata(ipc); if needed */ /* perform command */ @@ -90,18 +94,21 @@ enum task_state ipc_platform_do_cmd(void *data) platform_shared_commit(ipc, sizeof(*ipc)); + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + tr_info(&ipc_tr, "ipc platform do cmd IMX GCR %x", val); return SOF_TASK_STATE_COMPLETED; } void ipc_platform_complete_cmd(void *data) { struct ipc *ipc = data; + int val; /* enable GP interrupt #0 - accept new messages */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIEn(0), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 0), 0); /* request GP interrupt #0 - notify host that reply is ready */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(0), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(IMX_MU_VERSION, 0), 0); // TODO: signal audio work to enter D3 in normal context /* are we about to enter D3 ? */ @@ -112,17 +119,22 @@ void ipc_platform_complete_cmd(void *data) wait_for_interrupt(0); } + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + tr_info(&ipc_tr, "IMX GCR %x", val); platform_shared_commit(ipc, sizeof(*ipc)); + tr_info(&ipc_tr, "ipc_platform_complete_cmd return"); } int ipc_platform_send_msg(struct ipc_msg *msg) { struct ipc *ipc = ipc_get(); int ret = 0; + int val; + tr_info(&ipc_tr, "ipc: msg tx -> 0x%x, pend %d, val %x", msg->header, ipc->is_notification_pending, imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)) & IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1)); /* can't send notification when one is in progress */ if (ipc->is_notification_pending || - imx_mu_read(IMX_MU_xCR) & IMX_MU_xCR_GIRn(1)) { + imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)) & IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1)) { ret = -EBUSY; goto out; } @@ -130,15 +142,17 @@ int ipc_platform_send_msg(struct ipc_msg *msg) /* now send the message */ mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); list_item_del(&msg->list); - tr_dbg(&ipc_tr, "ipc: msg tx -> 0x%x", msg->header); ipc->is_notification_pending = true; /* now interrupt host to tell it we have sent a message */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1), 0); platform_shared_commit(msg, sizeof(*msg)); + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + tr_info(&ipc_tr, "IMX GCR %x", val); + out: platform_shared_commit(ipc, sizeof(*ipc)); @@ -197,7 +211,7 @@ int platform_ipc_init(struct ipc *ipc) /* enable GP #0 for Host -> DSP message notification * enable GP #1 for DSP -> Host message notification */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIEn(0) | IMX_MU_xCR_GIEn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 0) | IMX_MU_xCR_GIEn(IMX_MU_VERSION, 1), 0); platform_shared_commit(ipc, sizeof(*ipc)); @@ -215,10 +229,11 @@ int ipc_platform_poll_init(void) void ipc_platform_poll_set_cmd_done(void) { /* enable GP interrupt #0 - accept new messages */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIEn(0), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 0), 0); /* request GP interrupt #0 - notify host that reply is ready */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(0), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(IMX_MU_VERSION, 0), 0); + tr_info(&ipc_tr, "ipc_platform_poll_set cmd_done"); } /* read the IPC register for any new command messages */ @@ -227,16 +242,16 @@ int ipc_platform_poll_is_cmd_pending(void) uint32_t status; /* Interrupt arrived, check src */ - status = imx_mu_read(IMX_MU_xSR); + status = imx_mu_read(IMX_MU_xSR(IMX_MU_VERSION, IMX_MU_GSR)); /* new message from host */ - if (status & IMX_MU_xSR_GIPn(0)) { + if (status & IMX_MU_xSR_GIPn(IMX_MU_VERSION, 0)) { /* Disable GP interrupt #0 */ - imx_mu_xcr_rmw(0, IMX_MU_xCR_GIEn(0)); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, 0, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 0)); /* Clear GP pending interrupt #0 */ - imx_mu_xsr_rmw(IMX_MU_xSR_GIPn(0), 0); + imx_mu_xsr_rmw(IMX_MU_VERSION, IMX_MU_GSR, IMX_MU_xSR_GIPn(IMX_MU_VERSION, 0), 0); interrupt_clear(PLATFORM_IPC_INTERRUPT); @@ -253,20 +268,20 @@ int ipc_platform_poll_is_host_ready(void) uint32_t status; /* Interrupt arrived, check src */ - status = imx_mu_read(IMX_MU_xSR); + status = imx_mu_read(IMX_MU_xSR(IMX_MU_VERSION, IMX_MU_GSR)); /* reply message(done) from host */ - if (status & IMX_MU_xSR_GIPn(1)) { + if (status & IMX_MU_xSR_GIPn(IMX_MU_VERSION, 1)) { /* Disable GP interrupt #1 */ - imx_mu_xcr_rmw(0, IMX_MU_xCR_GIEn(1)); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, 0, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 1)); /* Clear GP pending interrupt #1 */ - imx_mu_xsr_rmw(IMX_MU_xSR_GIPn(1), 0); + imx_mu_xsr_rmw(IMX_MU_VERSION, IMX_MU_GSR, IMX_MU_xSR_GIPn(IMX_MU_VERSION, 1), 0); interrupt_clear(PLATFORM_IPC_INTERRUPT); /* unmask GP interrupt #1 */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIEn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GIER, IMX_MU_xCR_GIEn(IMX_MU_VERSION, 1), 0); /* host done */ return 1; @@ -279,15 +294,16 @@ int ipc_platform_poll_is_host_ready(void) int ipc_platform_poll_tx_host_msg(struct ipc_msg *msg) { /* can't send notification when one is in progress */ - if (imx_mu_read(IMX_MU_xCR) & IMX_MU_xCR_GIRn(1)) + if (imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)) & IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1)) return 0; /* now send the message */ mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); /* now interrupt host to tell it we have sent a message */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1), 0); + tr_info(&ipc_tr, "ipc_platform_poll_tx_host_msg"); /* message sent */ platform_shared_commit(msg, sizeof(*msg)); return 1; diff --git a/src/drivers/imx/sai.c b/src/drivers/imx/sai.c index 6ea552106c94..a071be1d8634 100644 --- a/src/drivers/imx/sai.c +++ b/src/drivers/imx/sai.c @@ -24,9 +24,6 @@ DECLARE_SOF_UUID("sai", sai_uuid, 0x9302adf5, 0x88be, 0x4234, DECLARE_TR_CTX(sai_tr, SOF_UUID(sai_uuid), LOG_LEVEL_INFO); -#define REG_TX_DIR 0 -#define REG_RX_DIR 1 - static void sai_start(struct dai *dai, int direction) { dai_info(dai, "SAI: sai_start"); @@ -87,6 +84,14 @@ static void sai_start(struct dai *dai, int direction) dai_update_bits(dai, REG_SAI_MCTL, REG_SAI_MCTL_MCLK_EN, REG_SAI_MCTL_MCLK_EN); #endif + //tmp + dai_write(dai, REG_SAI_XCR1(direction), 0x0000007A); + dai_write(dai, REG_SAI_XCR2(direction), 0x05000017); + dai_write(dai, REG_SAI_XCR3(direction), 0x00010000); + dai_write(dai, REG_SAI_XCR4(direction), 0x08010039); + dai_write(dai, REG_SAI_XCR5(direction), 0x0F0F0F00); + dai_write(dai, REG_SAI_XMR(direction), 0xFFFFFFFE); + dai_write(dai, REG_SAI_XCSR(direction), 0x50100f01); /* transmit/receive data channel enable */ dai_update_bits(dai, REG_SAI_XCR3(direction), @@ -95,6 +100,9 @@ static void sai_start(struct dai *dai, int direction) /* transmitter/receiver enable */ dai_update_bits(dai, REG_SAI_XCSR(direction), REG_SAI_CSR_TERE, REG_SAI_CSR_TERE); + + //tmp + //interrupt_enable(IRQ_SAI5_NUM, dai); } static void sai_stop(struct dai *dai, int direction) @@ -102,7 +110,7 @@ static void sai_stop(struct dai *dai, int direction) dai_info(dai, "SAI: sai_stop"); uint32_t xcsr = 0U; - + int ret = 0; /* Disable DMA request */ dai_update_bits(dai, REG_SAI_XCSR(direction), REG_SAI_CSR_FRDE, 0); @@ -119,24 +127,30 @@ static void sai_stop(struct dai *dai, int direction) /* Disable transmitter/receiver */ if (direction == DAI_DIR_CAPTURE) { dai_update_bits(dai, REG_SAI_XCSR(DAI_DIR_CAPTURE), REG_SAI_CSR_TERE, 0); - poll_for_register_delay(dai_base(dai) + REG_SAI_XCSR(DAI_DIR_CAPTURE), - REG_SAI_CSR_TERE, 0, 100); + ret = poll_for_register_delay(dai_base(dai) + + REG_SAI_XCSR(DAI_DIR_CAPTURE), + REG_SAI_CSR_TERE, 0, 100); + /* Check if the opposite direction is also disabled */ xcsr = dai_read(dai, REG_SAI_XCSR(DAI_DIR_PLAYBACK)); if (!(xcsr & REG_SAI_CSR_FRDE)) { dai_update_bits(dai, REG_SAI_XCSR(DAI_DIR_PLAYBACK), REG_SAI_CSR_TERE, 0); - poll_for_register_delay(dai_base(dai) + REG_SAI_XCSR(DAI_DIR_PLAYBACK), - REG_SAI_CSR_TERE, 0, 100); + ret = poll_for_register_delay(dai_base(dai) + + REG_SAI_XCSR(DAI_DIR_PLAYBACK), + REG_SAI_CSR_TERE, 0, 100); } } else { /* Check if the opposite direction is also disabled */ xcsr = dai_read(dai, REG_SAI_XCSR(DAI_DIR_CAPTURE)); if (!(xcsr & REG_SAI_CSR_FRDE)) { dai_update_bits(dai, REG_SAI_XCSR(DAI_DIR_PLAYBACK), REG_SAI_CSR_TERE, 0); - poll_for_register_delay(dai_base(dai) + REG_SAI_XCSR(DAI_DIR_PLAYBACK), - REG_SAI_CSR_TERE, 0, 100); + ret = poll_for_register_delay(dai_base(dai) + + REG_SAI_XCSR(DAI_DIR_PLAYBACK), + REG_SAI_CSR_TERE, 0, 100); } } + if (ret < 0) + dai_warn(dai, "sai: poll for register delay failed"); } static int sai_context_store(struct dai *dai) @@ -149,19 +163,19 @@ static int sai_context_restore(struct dai *dai) return 0; } -static inline int sai_set_config(struct dai *dai, - struct sof_ipc_dai_config *config) +static inline int sai_set_config(struct dai *dai, struct sof_ipc_dai_config *config) { dai_info(dai, "SAI: sai_set_config"); - uint32_t val_cr2 = 0, val_cr4 = 0, val_cr5 = 0; - uint32_t mask_cr2 = 0, mask_cr4 = 0, mask_cr5 = 0; + uint32_t val_cr2 = 0, val_cr4 = 0; + uint32_t mask_cr2 = 0, mask_cr4 = 0; struct sai_pdata *sai = dai_get_drvdata(dai); - /* TODO: this value will be provided by config */ - uint32_t sywd = 32; sai->config = *config; sai->params = config->sai; + val_cr4 |= REG_SAI_CR4_MF; + sai->dsp_mode = false; + switch (config->format & SOF_DAI_FMT_FORMAT_MASK) { case SOF_DAI_FMT_I2S: /* @@ -172,9 +186,6 @@ static inline int sai_set_config(struct dai *dai, */ val_cr2 |= REG_SAI_CR2_BCP; val_cr4 |= REG_SAI_CR4_FSE | REG_SAI_CR4_FSP; - val_cr4 |= REG_SAI_CR4_SYWD(sywd); - val_cr4 |= REG_SAI_CR4_MF; - val_cr4 |= REG_SAI_CR4_FSE; break; case SOF_DAI_FMT_LEFT_J: /* @@ -182,8 +193,6 @@ static inline int sai_set_config(struct dai *dai, * frame sync asserts with the first bit of the frame. */ val_cr2 |= REG_SAI_CR2_BCP; - val_cr4 |= REG_SAI_CR4_SYWD(sywd); - val_cr4 |= REG_SAI_CR4_MF; break; case SOF_DAI_FMT_DSP_A: /* @@ -194,9 +203,7 @@ static inline int sai_set_config(struct dai *dai, */ val_cr2 |= REG_SAI_CR2_BCP; val_cr4 |= REG_SAI_CR4_FSE; - val_cr4 |= REG_SAI_CR4_SYWD(0U); - val_cr4 |= REG_SAI_CR4_MF; - val_cr4 |= REG_SAI_CR4_FSE; + sai->dsp_mode = true; break; case SOF_DAI_FMT_DSP_B: /* @@ -204,18 +211,15 @@ static inline int sai_set_config(struct dai *dai, * frame sync asserts with the first bit of the frame. */ val_cr2 |= REG_SAI_CR2_BCP; - val_cr4 |= REG_SAI_CR4_SYWD(0U); - val_cr4 |= REG_SAI_CR4_MF; + sai->dsp_mode = true; break; case SOF_DAI_FMT_PDM: val_cr2 |= REG_SAI_CR2_BCP; val_cr4 &= ~REG_SAI_CR4_MF; - val_cr4 |= REG_SAI_CR4_MF; + sai->dsp_mode = true; break; case SOF_DAI_FMT_RIGHT_J: - val_cr4 |= REG_SAI_CR4_SYWD(sywd); - val_cr4 |= REG_SAI_CR4_MF; - break; + /* To be done, currently not supported */ default: return -EINVAL; } @@ -242,75 +246,46 @@ static inline int sai_set_config(struct dai *dai, return -EINVAL; } + sai->consumer_mode = false; + /* DAI clock provider masks */ switch (config->format & SOF_DAI_FMT_CLOCK_PROVIDER_MASK) { case SOF_DAI_FMT_CBC_CFC: dai_info(dai, "SAI: codec is consumer"); - val_cr2 |= REG_SAI_CR2_MSEL_MCLK1; val_cr2 |= REG_SAI_CR2_BCD_MSTR; - val_cr2 |= SAI_CLOCK_DIV; /* TODO: determine dynamically.*/ val_cr4 |= REG_SAI_CR4_FSD_MSTR; break; case SOF_DAI_FMT_CBP_CFP: dai_info(dai, "SAI: codec is provider"); /* - * fields CR2_DIV and CR2_MSEL not relevant in consumer mode. * fields CR2_BCD and CR4_MFSD already at 0 */ + sai->consumer_mode = true; break; case SOF_DAI_FMT_CBC_CFP: val_cr2 |= REG_SAI_CR2_BCD_MSTR; - val_cr2 |= SAI_CLOCK_DIV; /* TODO: determine dynamically.*/ break; case SOF_DAI_FMT_CBP_CFC: val_cr4 |= REG_SAI_CR4_FSD_MSTR; - val_cr2 |= SAI_CLOCK_DIV; /* TODO: determine dynamically.*/ + sai->consumer_mode = true; break; default: return -EINVAL; } - /* TODO: set number of slots from config */ - val_cr4 |= REG_SAI_CR4_FRSZ(SAI_TDM_SLOTS); - val_cr4 |= REG_SAI_CR4_CHMOD; - - val_cr5 |= REG_SAI_CR5_WNW(sywd) | REG_SAI_CR5_W0W(sywd) | - REG_SAI_CR5_FBT(sywd); + mask_cr2 = REG_SAI_CR2_BCP | REG_SAI_CR2_BCD_MSTR; + mask_cr4 = REG_SAI_CR4_MF | REG_SAI_CR4_FSE | + REG_SAI_CR4_FSP | REG_SAI_CR4_FSD_MSTR; - mask_cr2 = REG_SAI_CR2_BCP | REG_SAI_CR2_BCD_MSTR | - REG_SAI_CR2_MSEL_MASK | REG_SAI_CR2_DIV_MASK; + dai_update_bits(dai, REG_SAI_TCR1, REG_SAI_CR1_RFW_MASK, + dai->plat_data.fifo[DAI_DIR_PLAYBACK].watermark); + dai_update_bits(dai, REG_SAI_TCR2, mask_cr2, val_cr2); + dai_update_bits(dai, REG_SAI_TCR4, mask_cr4, val_cr4); - mask_cr4 = REG_SAI_CR4_MF | REG_SAI_CR4_FSE | - REG_SAI_CR4_FSP | REG_SAI_CR4_FSD_MSTR | - REG_SAI_CR4_FRSZ_MASK | REG_SAI_CR4_SYWD_MASK | - REG_SAI_CR4_CHMOD_MASK; - - - mask_cr5 = REG_SAI_CR5_WNW_MASK | REG_SAI_CR5_W0W_MASK | - REG_SAI_CR5_FBT_MASK; - - /* TODO: for the time being use half FIFO size as watermark */ - dai_update_bits(dai, REG_SAI_XCR1(REG_TX_DIR), - REG_SAI_CR1_RFW_MASK, SAI_FIFO_WORD_SIZE / 2); - dai_update_bits(dai, REG_SAI_XCR2(REG_TX_DIR), mask_cr2, val_cr2); - dai_update_bits(dai, REG_SAI_XCR4(REG_TX_DIR), mask_cr4, val_cr4); - dai_update_bits(dai, REG_SAI_XCR5(REG_TX_DIR), mask_cr5, val_cr5); - /* turn on (set to zero) stereo slot */ - dai_update_bits(dai, REG_SAI_XMR(REG_TX_DIR), REG_SAI_XMR_MASK, - ~(BIT(0) | BIT(1))); - - val_cr2 |= REG_SAI_CR2_SYNC; - mask_cr2 |= REG_SAI_CR2_SYNC_MASK; - - /* TODO: for the time being use half FIFO size as watermark */ - dai_update_bits(dai, REG_SAI_XCR1(REG_RX_DIR), - REG_SAI_CR1_RFW_MASK, SAI_FIFO_WORD_SIZE / 2); - dai_update_bits(dai, REG_SAI_XCR2(REG_RX_DIR), mask_cr2, val_cr2); - dai_update_bits(dai, REG_SAI_XCR4(REG_RX_DIR), mask_cr4, val_cr4); - dai_update_bits(dai, REG_SAI_XCR5(REG_RX_DIR), mask_cr5, val_cr5); - /* turn on (set to zero) stereo slot */ - dai_update_bits(dai, REG_SAI_XMR(REG_RX_DIR), REG_SAI_XMR_MASK, - ~(BIT(0) | BIT(1))); + dai_update_bits(dai, REG_SAI_RCR1, REG_SAI_CR1_RFW_MASK, + dai->plat_data.fifo[DAI_DIR_CAPTURE].watermark); + dai_update_bits(dai, REG_SAI_RCR2, mask_cr2, val_cr2); + dai_update_bits(dai, REG_SAI_RCR4, mask_cr4, val_cr4); return 0; } @@ -342,6 +317,15 @@ static int sai_trigger(struct dai *dai, int cmd, int direction) return 0; } +#if 0 +static void sai_irq_handler(void *args) +{ + struct dai *dai = (struct dai*)args; + dai_info(dai, "sai irq handler"); + return; +} +#endif + static int sai_probe(struct dai *dai) { struct sai_pdata *sai; @@ -356,6 +340,12 @@ static int sai_probe(struct dai *dai) } dai_set_drvdata(dai, sai); + /** + * Synchronize RX on TX by default + * @todo: to provision from topology via set_config + */ + sai->sync_mode = SAI_SYNC_ON_TX; + /* Software Reset for both Tx and Rx */ dai_update_bits(dai, REG_SAI_TCSR, REG_SAI_CSR_SR, REG_SAI_CSR_SR); dai_update_bits(dai, REG_SAI_RCSR, REG_SAI_CSR_SR, REG_SAI_CSR_SR); @@ -378,6 +368,8 @@ static int sai_probe(struct dai *dai) dai_write(dai, REG_SAI_RCR5, 0U); dai_write(dai, REG_SAI_RMR, 0U); + // tmp + //interrupt_register(IRQ_SAI5_NUM, sai_irq_handler, dai); return 0; } @@ -398,6 +390,11 @@ static int sai_get_fifo(struct dai *dai, int direction, int stream_id) } } +static int sai_get_srcid(struct dai *dai, int direction, int stream_id) +{ + return direction ? dai->plat_data.dmamux_rx_num : dai->plat_data.dmamux_tx_num; +} + static int sai_get_hw_params(struct dai *dai, struct sof_ipc_stream_params *params, int dir) @@ -413,6 +410,101 @@ static int sai_get_hw_params(struct dai *dai, return 0; } +static int sai_get_word_width(enum sof_ipc_frame fmt) +{ + switch (fmt) { + case SOF_IPC_FRAME_S16_LE: + return 16; + case SOF_IPC_FRAME_S24_4LE: + return 24; + case SOF_IPC_FRAME_S32_LE: + return 32; + default: + return -EINVAL; + } +} + +static int sai_hw_params(struct dai *dai, + struct sof_ipc_stream_params *params) +{ + struct sai_pdata *sai = dai_get_drvdata(dai); + bool rx = (params->direction == DAI_DIR_CAPTURE); + uint32_t rate = params->rate; + uint32_t channels = params->channels; + uint32_t word_width = sai_get_word_width(params->frame_fmt); + uint32_t val_cr2 = 0, val_cr3 = 0, val_cr4 = 0, val_cr5 = 0; + uint32_t mask_cr2 = 0, mask_cr3 = 0, mask_cr4 = 0, mask_cr5 = 0; + uint32_t slots = (channels == 1) ? 2 : channels; + uint32_t slot_width = word_width; + uint32_t pins, bclk, ratio, div; + + dai_info(dai, "SAI: sai_hw_params"); + + if (sai->params.tdm_slots) + slots = sai->params.tdm_slots; + + if (sai->params.tdm_slot_width) + slot_width = sai->params.tdm_slot_width; + + pins = DIV_ROUND_UP(channels, slots); + bclk = rate * slots * slot_width; + + dai_update_bits(dai, REG_SAI_XCR1(rx), REG_SAI_CR1_RFW_MASK, + dai->plat_data.fifo[params->direction].watermark); + + mask_cr3 = REG_SAI_CR3_TRCE_MASK; + val_cr3 = REG_SAI_CR3_TRCE(((1 << pins) - 1)); + + mask_cr4 = REG_SAI_CR4_SYWD_MASK | REG_SAI_CR4_FRSZ_MASK | REG_SAI_CR4_CHMOD_MASK; + val_cr4 |= (sai->dsp_mode ? 0 : REG_SAI_CR4_SYWD(slot_width)); + val_cr4 |= REG_SAI_CR4_FRSZ(slots); + val_cr4 |= (rx ? 0 : REG_SAI_CR4_CHMOD); + + mask_cr5 = REG_SAI_CR5_WNW_MASK | REG_SAI_CR5_W0W_MASK | REG_SAI_CR5_FBT_MASK; + val_cr5 = REG_SAI_CR5_WNW(slot_width) | REG_SAI_CR5_W0W(slot_width); + val_cr5 |= REG_SAI_CR5_FBT(word_width); + dai_update_bits(dai, REG_SAI_XCR3(rx), mask_cr3, val_cr3); + dai_update_bits(dai, REG_SAI_XCR4(rx), mask_cr4, val_cr4); + dai_update_bits(dai, REG_SAI_XCR5(rx), mask_cr5, val_cr5); + dai_update_bits(dai, REG_SAI_XMR(rx), REG_SAI_XMR_MASK, + ~0UL - ((1 << MIN(channels, slots)) - 1)); + + if (!sai->consumer_mode) { + ratio = sai->params.mclk_rate / bclk; + div = (ratio == 1 ? 0 : (ratio >> 1) - 1); + + mask_cr2 = REG_SAI_CR2_MSEL_MASK | REG_SAI_CR2_DIV_MASK; + val_cr2 = REG_SAI_CR2_MSEL_MCLK1 | div; +#ifdef CONFIG_IMX8M + mask_cr2 |= REG_SAI_CR2_BYP; + val_cr2 |= (ratio == 1 ? REG_SAI_CR2_BYP : 0); +#endif + if (rx && sai->sync_mode == SAI_SYNC_ON_TX) { + dai_update_bits(dai, REG_SAI_XCR2(rx), REG_SAI_CR2_SYNC_MASK | mask_cr2, + REG_SAI_CR2_SYNC); + dai_update_bits(dai, REG_SAI_XCR2(!rx), mask_cr2, val_cr2); + } else if (!rx && sai->sync_mode == SAI_SYNC_ON_RX) { + dai_update_bits(dai, REG_SAI_XCR2(!rx), REG_SAI_CR2_SYNC_MASK | mask_cr2, + REG_SAI_CR2_SYNC); + dai_update_bits(dai, REG_SAI_XCR2(rx), mask_cr2, val_cr2); + } else { + dai_update_bits(dai, REG_SAI_XCR2(rx), mask_cr2 | REG_SAI_CR2_SYNC_MASK, + val_cr2); + dai_update_bits(dai, REG_SAI_XCR2(!rx), REG_SAI_CR2_SYNC_MASK, 0); + } + + if ((rx && sai->sync_mode == SAI_SYNC_ON_TX) || + (!rx && sai->sync_mode == SAI_SYNC_ON_RX)) { + dai_update_bits(dai, REG_SAI_XCR1(!rx), REG_SAI_CR1_RFW_MASK, + dai->plat_data.fifo[(params->direction + 1) % 2].watermark); + dai_update_bits(dai, REG_SAI_XCR4(!rx), mask_cr4, val_cr4); + dai_update_bits(dai, REG_SAI_XCR5(!rx), mask_cr5, val_cr5); + } + } + + return 0; +} + const struct dai_driver sai_driver = { .type = SOF_DAI_IMX_SAI, .uid = SOF_UUID(sai_uuid), @@ -427,5 +519,7 @@ const struct dai_driver sai_driver = { .get_handshake = sai_get_handshake, .get_fifo = sai_get_fifo, .get_hw_params = sai_get_hw_params, + .get_srcid = sai_get_srcid, + .hw_params = sai_hw_params, }, }; diff --git a/src/include/sof/drivers/edma.h b/src/include/sof/drivers/edma.h index b03761e25297..6e7fa84d7edf 100644 --- a/src/include/sof/drivers/edma.h +++ b/src/include/sof/drivers/edma.h @@ -20,6 +20,7 @@ #define EDMA_CH_INT 0x08 #define EDMA_CH_SBR 0x0C #define EDMA_CH_PRI 0x10 +#define EDMA_CH_MUX 0x14 #define EDMA_TCD_SADDR 0x20 #define EDMA_TCD_SOFF 0x24 #define EDMA_TCD_ATTR 0x26 @@ -95,4 +96,18 @@ #define EDMA0_SAI_CHAN_RX_IRQ 349 #define EDMA0_SAI_CHAN_TX_IRQ 349 +/* fix 8ulp sai chan*/ +#define EDMA2_CHAN0 0 +#define EDMA2_CHAN1 1 +/* 8ulp edma2 */ +#define EDMA2_CHAN0_IRQ 6 +#define EDMA2_CHAN1_IRQ 7 +#define EDMA2_CHAN2_IRQ 8 +#define EDMA2_CHAN3_IRQ 9 +#define EDMA2_CHAN4_IRQ 10 +#define EDMA2_CHAN5_IRQ 11 +#define EDMA2_CHAN6_IRQ 12 +#define EDMA2_CHAN7_IRQ 13 +#define EDMA2_CHAN_MAX 8 + #endif /* __SOF_DRIVERS_EDMA_H__ */ diff --git a/src/include/sof/drivers/mu.h b/src/include/sof/drivers/mu.h index 3ad5781a7c05..d7b645a4f9cd 100644 --- a/src/include/sof/drivers/mu.h +++ b/src/include/sof/drivers/mu.h @@ -13,27 +13,61 @@ #include #include +enum imx_mu_type { + IMX_MU_V1, + IMX_MU_V2, +}; + +#ifdef CONFIG_IMX8ULP +#define IMX_MU_VERSION IMX_MU_V2 +#else +#define IMX_MU_VERSION IMX_MU_V1 +#endif + +enum imx_mu_xcr { + IMX_MU_GIER = 0x110, + IMX_MU_GCR = 0x114, + IMX_MU_TCR = 0x120, + IMX_MU_RCR = 0x128, +}; + +enum imx_mu_xsr { + IMX_MU_SR = 0x0c, + IMX_MU_GSR = 0x118, + IMX_MU_TSR = 0x124, + IMX_MU_RSR = 0x12c, +}; + +#ifdef CONFIG_IMX8ULP +/* Transmit Register */ +#define IMX_MU_xTRn(x) (0x200 + 4 * (x)) +/* Receive Register */ +#define IMX_MU_xRRn(x) (0x280 + 4 * (x)) + +#else /* Transmit Register */ #define IMX_MU_xTRn(x) (0x00 + 4 * (x)) /* Receive Register */ #define IMX_MU_xRRn(x) (0x10 + 4 * (x)) + +#endif /* Status Register */ -#define IMX_MU_xSR 0x20 -#define IMX_MU_xSR_GIPn(x) BIT(28 + (3 - (x))) -#define IMX_MU_xSR_RFn(x) BIT(24 + (3 - (x))) -#define IMX_MU_xSR_TEn(x) BIT(20 + (3 - (x))) +#define IMX_MU_xSR(type, index) (type & IMX_MU_V2 ? index : 0x20) +#define IMX_MU_xSR_GIPn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x)))) +#define IMX_MU_xSR_RFn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x)))) +#define IMX_MU_xSR_TEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x)))) #define IMX_MU_xSR_BRDIP BIT(9) /* Control Register */ -#define IMX_MU_xCR 0x24 +#define IMX_MU_xCR(type, index) (type & IMX_MU_V2 ? index : 0x24) /* General Purpose Interrupt Enable */ -#define IMX_MU_xCR_GIEn(x) BIT(28 + (3 - (x))) +#define IMX_MU_xCR_GIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x)))) /* Receive Interrupt Enable */ -#define IMX_MU_xCR_RIEn(x) BIT(24 + (3 - (x))) +#define IMX_MU_xCR_RIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x)))) /* Transmit Interrupt Enable */ -#define IMX_MU_xCR_TIEn(x) BIT(20 + (3 - (x))) +#define IMX_MU_xCR_TIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x)))) /* General Purpose Interrupt Request */ -#define IMX_MU_xCR_GIRn(x) BIT(16 + (3 - (x))) +#define IMX_MU_xCR_GIRn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(16 + (3 - (x)))) static inline uint32_t imx_mu_read(uint32_t reg) { @@ -45,26 +79,26 @@ static inline void imx_mu_write(uint32_t val, uint32_t reg) *((volatile uint32_t*)(MU_BASE + reg)) = val; } -static inline uint32_t imx_mu_xcr_rmw(uint32_t set, uint32_t clr) +static inline uint32_t imx_mu_xcr_rmw(uint32_t type, uint32_t idx, uint32_t set, uint32_t clr) { volatile uint32_t val; - val = imx_mu_read(IMX_MU_xCR); + val = imx_mu_read(IMX_MU_xCR(type, idx)); val &= ~clr; val |= set; - imx_mu_write(val, IMX_MU_xCR); + imx_mu_write(val, IMX_MU_xCR(type, idx)); return val; } -static inline uint32_t imx_mu_xsr_rmw(uint32_t set, uint32_t clr) +static inline uint32_t imx_mu_xsr_rmw(uint32_t type, uint32_t idx, uint32_t set, uint32_t clr) { volatile uint32_t val; - val = imx_mu_read(IMX_MU_xSR); + val = imx_mu_read(IMX_MU_xSR(type, idx)); val &= ~clr; val |= set; - imx_mu_write(val, IMX_MU_xSR); + imx_mu_write(val, IMX_MU_xSR(type, idx)); return val; } diff --git a/src/include/sof/drivers/sai.h b/src/include/sof/drivers/sai.h index d7bd0ffa6fc7..352605570cda 100644 --- a/src/include/sof/drivers/sai.h +++ b/src/include/sof/drivers/sai.h @@ -18,6 +18,8 @@ #ifdef CONFIG_IMX8M #define SAI_OFS 8 +#elif CONFIG_IMX8ULP +#define SAI_OFS 8 #else #define SAI_OFS 0 #endif @@ -243,12 +245,11 @@ #define SAI_FIFO_WORD_SIZE 64 #endif -/* Divides down the audio main clock to generate the bit clock when - * configured for an internal bit clock. - * The division value is (DIV + 1) * 2. - */ -#define SAI_CLOCK_DIV 0x7 -#define SAI_TDM_SLOTS 2 +enum sai_sync_mode { + SAI_ASYNC = 0, /* asynchronous RX and TX */ + SAI_SYNC_ON_TX = 1, /* RX synchronized on TX */ + SAI_SYNC_ON_RX = 2, /* TX synchronized on RX */ +}; extern const struct dai_driver sai_driver; @@ -256,6 +257,9 @@ extern const struct dai_driver sai_driver; struct sai_pdata { struct sof_ipc_dai_config config; struct sof_ipc_dai_sai_params params; + enum sai_sync_mode sync_mode; + bool consumer_mode; + bool dsp_mode; }; #endif /*__SOF_DRIVERS_SAI_H__ */ diff --git a/src/include/sof/lib/dai.h b/src/include/sof/lib/dai.h index e97fd6180900..62564f6f279b 100644 --- a/src/include/sof/lib/dai.h +++ b/src/include/sof/lib/dai.h @@ -77,7 +77,9 @@ struct dai_ops { int (*pm_context_store)(struct dai *dai); int (*get_hw_params)(struct dai *dai, struct sof_ipc_stream_params *params, int dir); + int (*hw_params)(struct dai *dai, struct sof_ipc_stream_params *params); int (*get_handshake)(struct dai *dai, int direction, int stream_id); + int (*get_srcid)(struct dai *dai, int direction, int stream_id); int (*get_fifo)(struct dai *dai, int direction, int stream_id); int (*probe)(struct dai *dai); int (*remove)(struct dai *dai); @@ -141,6 +143,8 @@ struct dai_plat_data { int irq; const char *irq_name; uint32_t flags; + uint32_t dmamux_rx_num; + uint32_t dmamux_tx_num; struct dai_plat_fifo_data fifo[2]; }; @@ -383,6 +387,19 @@ static inline int dai_get_hw_params(struct dai *dai, return ret; } +static inline int dai_hw_params(struct dai *dai, + struct sof_ipc_stream_params *params) +{ + int ret; + if (dai->drv->ops.hw_params) + ret = dai->drv->ops.hw_params(dai, params); + + platform_shared_commit(dai, sizeof(*dai)); + + ret = 0; + return ret; +} + /** * \brief Get Digital Audio interface DMA Handshake */ @@ -396,6 +413,19 @@ static inline int dai_get_handshake(struct dai *dai, int direction, return ret; } +/** + * \brief Get Digital Audio interface DMA srcid + */ +static inline int dai_get_srcid(struct dai *dai, int direction, + int stream_id) +{ + int ret = dai->drv->ops.get_srcid(dai, direction, stream_id); + + platform_shared_commit(dai, sizeof(*dai)); + + return ret; +} + /** * \brief Get Digital Audio interface FIFO address */ diff --git a/src/include/sof/lib/dma.h b/src/include/sof/lib/dma.h index 59c3a398ea30..3a90926bb150 100644 --- a/src/include/sof/lib/dma.h +++ b/src/include/sof/lib/dma.h @@ -210,6 +210,7 @@ struct dma_chan_data { uint32_t index; uint32_t core; uint64_t period; /* DMA channel's transfer period in us */ + uint32_t srcid; /* true if this DMA channel is the scheduling source */ bool is_scheduling_source; diff --git a/src/ipc/handler.c b/src/ipc/handler.c index a1b722a11776..256d38cee9c2 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -94,6 +94,7 @@ struct sof_ipc_cmd_hdr *mailbox_validate(void) /* read component values from the inbox */ mailbox_hostbox_read(hdr, SOF_IPC_MSG_MAX_SIZE, 0, sizeof(*hdr)); +// tr_info(&ipc_tr, "mailbox_validate"); /* validate component header */ if (hdr->size < sizeof(*hdr) || hdr->size > SOF_IPC_MSG_MAX_SIZE) { tr_err(&ipc_tr, "ipc: invalid size 0x%x", hdr->size); @@ -210,7 +211,7 @@ static int ipc_stream_pcm_params(uint32_t stream) if (!cpu_is_me(pcm_dev->core)) return ipc_process_on_core(pcm_dev->core); - tr_dbg(&ipc_tr, "ipc: comp %d -> params", pcm_params.comp_id); + tr_info(&ipc_tr, "ipc: comp %d -> params", pcm_params.comp_id); /* sanity check comp */ if (!pcm_dev->cd->pipeline) { @@ -294,6 +295,7 @@ static int ipc_stream_pcm_params(uint32_t stream) reply.posn_offset = pcm_dev->cd->pipeline->posn_offset; mailbox_hostbox_write(0, &reply, sizeof(reply)); platform_shared_commit(pcm_dev, sizeof(*pcm_dev)); + return 1; error: @@ -412,7 +414,7 @@ static int ipc_stream_trigger(uint32_t header) if (!cpu_is_me(pcm_dev->core)) return ipc_process_on_core(pcm_dev->core); - tr_dbg(&ipc_tr, "ipc: comp %d -> trigger cmd 0x%x", + tr_info(&ipc_tr, "ipc: comp %d -> trigger cmd 0x%x", stream.comp_id, ipc_cmd); switch (ipc_cmd) { @@ -445,6 +447,8 @@ static int ipc_stream_trigger(uint32_t header) platform_shared_commit(pcm_dev, sizeof(*pcm_dev)); + if (ipc_cmd == SOF_IPC_STREAM_TRIG_STOP) + tr_info(&ipc_tr, "ipc stream trigger return"); return ret; } @@ -452,6 +456,7 @@ static int ipc_glb_stream_message(uint32_t header) { uint32_t cmd = iCS(header); + tr_info(&ipc_tr, "ipc: glb stream msg cmd 0x%x", cmd); switch (cmd) { case SOF_IPC_STREAM_PCM_PARAMS: return ipc_stream_pcm_params(header); @@ -470,6 +475,8 @@ static int ipc_glb_stream_message(uint32_t header) tr_err(&ipc_tr, "ipc: unknown stream cmd 0x%x", cmd); return -EINVAL; } + if (cmd == SOF_IPC_STREAM_TRIG_STOP) + tr_info(&ipc_tr, "ipc: glb stream msg cmd 0x%x", cmd); } /* @@ -715,6 +722,7 @@ static int ipc_dma_trace_config(uint32_t header) return 0; #endif + tr_info(&ipc_tr, "ipc dma trace config..."); #if CONFIG_HOST_PTABLE err = ipc_process_host_buffer(ipc, ¶ms.buffer, SOF_IPC_STREAM_CAPTURE, @@ -723,12 +731,14 @@ static int ipc_dma_trace_config(uint32_t header) if (err < 0) goto error; + tr_info(&ipc_tr, "ipc dma trace config1..."); err = dma_trace_host_buffer(dmat, &elem_array, ring_size); if (err < 0) { tr_err(&ipc_tr, "ipc: trace failed to set host buffers %d", err); goto error; } + tr_info(&ipc_tr, "ipc dma trace config2..."); #else /* stream tag of capture stream for DMA trace */ dmat->stream_tag = params.stream_tag; @@ -807,6 +817,7 @@ static int ipc_glb_trace_message(uint32_t header) switch (cmd) { case SOF_IPC_TRACE_DMA_PARAMS: case SOF_IPC_TRACE_DMA_PARAMS_EXT: + return 0; return ipc_dma_trace_config(header); case SOF_IPC_TRACE_FILTER_UPDATE: return ipc_trace_filter_update(header); @@ -1400,6 +1411,7 @@ void ipc_cmd(struct sof_ipc_cmd_hdr *hdr) type = iGS(hdr->cmd); + tr_info(&ipc_tr, "ipc_cmd %x.", type); switch (type) { case SOF_IPC_GLB_REPLY: ret = 0; @@ -1448,7 +1460,7 @@ void ipc_cmd(struct sof_ipc_cmd_hdr *hdr) platform_shared_commit(hdr, hdr->size); out: - tr_dbg(&ipc_tr, "ipc: last request 0x%x returned %d", type, ret); + tr_info(&ipc_tr, "ipc: last request 0x%x returned %d", type, ret); /* if ret > 0, reply created and copied by cmd() */ if (ret <= 0) { @@ -1466,6 +1478,7 @@ void ipc_msg_send(struct ipc_msg *msg, void *data, bool high_priority) struct ipc *ipc = ipc_get(); uint32_t flags; int ret; + int val; spin_lock_irq(&ipc->lock, flags); @@ -1482,6 +1495,9 @@ void ipc_msg_send(struct ipc_msg *msg, void *data, bool high_priority) goto out; } + tr_info(&ipc_tr, "ipc: msg->list %x, msp->list next %x, ipc list %x", (void *)&msg->list, msg->list.next, (void *)&ipc->msg_list); + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + tr_info(&ipc_tr, "IMX GCR %x", val); /* add to queue unless already there */ if (list_is_empty(&msg->list)) { if (high_priority) diff --git a/src/ipc/ipc-host-ptable.c b/src/ipc/ipc-host-ptable.c index 9860326f64ca..138c4c72e5d3 100644 --- a/src/ipc/ipc-host-ptable.c +++ b/src/ipc/ipc-host-ptable.c @@ -89,6 +89,7 @@ static int ipc_get_page_descriptors(struct dma *dmac, uint8_t *page_table, struct dma_chan_data *chan; uint32_t dma_copy_align; int ret = 0; + //int *ptr = (void*)0x1aff1000; /* get DMA channel from DMAC */ chan = dma_channel_get(dmac, 0); @@ -109,6 +110,7 @@ static int ipc_get_page_descriptors(struct dma *dmac, uint8_t *page_table, elem.dest = (uintptr_t)page_table; elem.src = ring->phy_addr; + tr_info(&ipc_tr, "ipc_get_page_descriptors, src %x, dest %x", elem.src, elem.dest); /* source buffer size is always PAGE_SIZE bytes */ /* 20 bits for each page, round up to minimum DMA copy size */ ret = dma_get_attribute(dmac, DMA_ATTR_COPY_ALIGNMENT, &dma_copy_align); @@ -121,6 +123,7 @@ static int ipc_get_page_descriptors(struct dma *dmac, uint8_t *page_table, config.elem_array.elems = &elem; config.elem_array.count = 1; + tr_info(&ipc_tr, "ipc_get_page_descriptors(): dma_set_config()"); ret = dma_set_config(chan, &config); if (ret < 0) { tr_err(&ipc_tr, "ipc_get_page_descriptors(): dma_set_config() failed"); @@ -149,6 +152,7 @@ int ipc_process_host_buffer(struct ipc *ipc, struct ipc_data_host_buffer *data_host_buffer; int err; + /* data host buffer is local */ data_host_buffer = ipc_platform_get_host_buffer(ipc); dma_sg_init(elem_array); diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c index 16cea90be793..48f612367175 100644 --- a/src/ipc/ipc.c +++ b/src/ipc/ipc.c @@ -640,7 +640,9 @@ int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config) */ if (dai->dai_index == config->dai_index && dai->type == config->type) { + tr_info(&ipc_tr, "comp_dai_config"); ret = comp_dai_config(icd->cd, config); + tr_info(&ipc_tr, "comp_dai_config return"); platform_shared_commit(icd, sizeof(*icd)); if (ret < 0) break; diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 24f25554758b..67e7c7df9228 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -579,11 +579,11 @@ static void trace_heap_blocks(struct mm_heap *heap) struct block_map *block_map; int i; - tr_err(&mem_tr, "heap: 0x%x size %d blocks %d caps 0x%x", heap->heap, + /*tr_info(&mem_tr, "heap: 0x%x size %d blocks %d caps 0x%x", heap->heap, heap->size, heap->blocks, heap->caps); - tr_err(&mem_tr, " used %d free %d", heap->info.used, + tr_info(&mem_tr, " used %d free %d", heap->info.used, heap->info.free); - +*/ for (i = 0; i < heap->blocks; i++) { block_map = &heap->map[i]; @@ -1115,23 +1115,23 @@ void heap_trace(struct mm_heap *heap, int size) int j; for (i = 0; i < size; i++) { - tr_info(&mem_tr, " heap: 0x%x size %d blocks %d caps 0x%x", + /*tr_info(&mem_tr, " heap: 0x%x size %d blocks %d caps 0x%x", heap->heap, heap->size, heap->blocks, heap->caps); tr_info(&mem_tr, " used %d free %d", heap->info.used, heap->info.free); - +*/ /* map[j]'s base is calculated based on map[j-1] */ for (j = 1; j < heap->blocks; j++) { current_map = &heap->map[j]; - +/* tr_info(&mem_tr, " block %d base 0x%x size %d", j, current_map->base, current_map->block_size); tr_info(&mem_tr, " count %d free %d", current_map->count, current_map->free_count); - +*/ platform_shared_commit(current_map, sizeof(*current_map)); } @@ -1148,12 +1148,9 @@ void heap_trace_all(int force) /* has heap changed since last shown */ if (memmap->heap_trace_updated || force) { - tr_info(&mem_tr, "heap: buffer status"); heap_trace(memmap->buffer, PLATFORM_HEAP_BUFFER); - tr_info(&mem_tr, "heap: runtime status"); heap_trace(memmap->runtime, PLATFORM_HEAP_RUNTIME); #if CONFIG_CORE_COUNT > 1 - tr_info(&mem_tr, "heap: runtime shared status"); heap_trace(memmap->runtime_shared, PLATFORM_HEAP_RUNTIME_SHARED); #endif } diff --git a/src/lib/dma.c b/src/lib/dma.c index dba4945a1a0d..fab5a7e6f05e 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -178,6 +178,8 @@ int dma_sg_alloc(struct dma_sg_elem_array *elem_array, elem_array->elems[i].dest = dma_buffer_addr; break; } + tr_info(&dma_tr, "dma_sg_alloc(), src = %p, dest = %x", + elem_array->elems[i].src, elem_array->elems[i].dest); dma_buffer_addr += buffer_bytes; } diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index cb28c166abe0..ba21cd264302 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -23,6 +23,8 @@ elseif(CONFIG_IMX8 OR CONFIG_IMX8X) add_subdirectory(imx8) elseif(CONFIG_IMX8M) add_subdirectory(imx8m) +elseif(CONFIG_IMX8ULP) + add_subdirectory(imx8ulp) endif() if(CONFIG_CAVS) diff --git a/src/platform/Kconfig b/src/platform/Kconfig index 9f60f6e09d88..108aefe5c479 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -178,6 +178,7 @@ config IMX8 select WAITI_DELAY select IMX select IMX_EDMA + select IMX_IRQ select SCHEDULE_DMA_MULTI_CHANNEL help Select if your target platform is imx8-compatible @@ -193,6 +194,7 @@ config IMX8X select WAITI_DELAY select IMX select IMX_EDMA + select IMX_IRQ select SCHEDULE_DMA_MULTI_CHANNEL help Select if your target platform is imx8x-compatible @@ -207,10 +209,28 @@ config IMX8M select DUMMY_DMA select WAITI_DELAY select IMX + select IMX_IRQ select SCHEDULE_DMA_MULTI_CHANNEL help Select if your target platform is imx8m-compatible +config IMX8ULP + bool "Build for NXP i.MX8ULP" + select HAVE_RESET_VECTOR_ROM + select INTERRUPT_LEVEL_1 + select INTERRUPT_LEVEL_2 + select INTERRUPT_LEVEL_3 + select HOST_PTABLE + select DUMMY_DMA + select WAITI_DELAY + select IMX + select IMX_EDMA + select IMX_NOIRQ + select SCHEDULE_DMA_MULTI_CHANNEL + help + Select if your target platform is imx8ulp-compatible. + imx.8ulp support dsp. + endchoice config MAX_CORE_COUNT @@ -367,6 +387,7 @@ config RIMAGE_SIGNING_SCHEMA default "imx8" if IMX8 default "imx8x" if IMX8X default "imx8m" if IMX8M + default "imx8ulp" if IMX8ULP default "" help Signing schema name used by rimage to decide how to build final binary diff --git a/src/platform/imx8/include/platform/platform.h b/src/platform/imx8/include/platform/platform.h index c6f038e1fc5e..d0c912f99e06 100644 --- a/src/platform/imx8/include/platform/platform.h +++ b/src/platform/imx8/include/platform/platform.h @@ -72,7 +72,7 @@ static inline void platform_panic(uint32_t p) mailbox_sw_reg_write(SRAM_REG_FW_STATUS, p); /* Notify application processor */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(1), 0); } /** diff --git a/src/platform/imx8/platform.c b/src/platform/imx8/platform.c index da86a3179803..656b4eeac236 100644 --- a/src/platform/imx8/platform.c +++ b/src/platform/imx8/platform.c @@ -134,7 +134,7 @@ int platform_boot_complete(uint32_t boot_message) mailbox_dspbox_write(0, &ready, sizeof(ready)); /* now interrupt host to tell it we are done booting */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(1), 0); /* boot now complete so we can relax the CPU */ /* For now skip this to gain more processing performance diff --git a/src/platform/imx8m/platform.c b/src/platform/imx8m/platform.c index 238a6ebc1b37..70299182e8bb 100644 --- a/src/platform/imx8m/platform.c +++ b/src/platform/imx8m/platform.c @@ -133,7 +133,7 @@ int platform_boot_complete(uint32_t boot_message) mailbox_dspbox_write(0, &ready, sizeof(ready)); /* now interrupt host to tell it we are done booting */ - imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(1), 0); + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1), 0); /* boot now complete so we can relax the CPU */ /* For now skip this to gain more processing performance diff --git a/src/platform/imx8ulp/CMakeLists.txt b/src/platform/imx8ulp/CMakeLists.txt new file mode 100644 index 000000000000..ec909d60035f --- /dev/null +++ b/src/platform/imx8ulp/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/imx8ulp/imx8ulp.x.in b/src/platform/imx8ulp/imx8ulp.x.in new file mode 100644 index 000000000000..d3cf0b622063 --- /dev/null +++ b/src/platform/imx8ulp/imx8ulp.x.in @@ -0,0 +1,531 @@ +/* + * Linker Script for i.MX8 QXP + * + * 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_VECTOR0_PADDR, + len = SOF_MEM_RESET_TEXT_SIZE + vector_reset_lit : + org = XCHAL_RESET_VECTOR0_PADDR + SOF_MEM_RESET_TEXT_SIZE, + len = SOF_MEM_RESET_LIT_SIZE + vector_base_text : + org = 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_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 + IRAM_SIZE) - (XCHAL_DOUBLEEXC_VECTOR_PADDR + SOF_MEM_VECT_TEXT_SIZE) + sof_sdram0 : + org = SDRAM0_BASE, + len = SDRAM0_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_END, + len = SOF_STACK_BASE - SOF_STACK_END + sof_sdram1 : + org = SDRAM1_BASE, + len = SDRAM1_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_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; + system_heap_phdr PT_LOAD; + system_runtime_heap_phdr PT_LOAD; + runtime_heap_phdr PT_LOAD; + buffer_heap_phdr PT_LOAD; + sof_stack_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_VECBASE_RESET_PADDR); + +/* 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; +_memmap_cacheattr_imx8_wt_allvalid = 0x22212222; +PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_imx8_wt_allvalid); + +_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 + + .DebugExceptionVector.literal : ALIGN(4) + { + _DebugExceptionVector_literal_start = ABSOLUTE(.); + *(.DebugExceptionVector.literal) + _DebugExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int4_lit :vector_int4_lit_phdr + + .DebugExceptionVector.text : ALIGN(4) + { + _DebugExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DebugExceptionVector.text)) + _DebugExceptionVector_text_end = ABSOLUTE(.); + } >vector_int4_text :vector_int4_text_phdr + + .NMIExceptionVector.literal : ALIGN(4) + { + _NMIExceptionVector_literal_start = ABSOLUTE(.); + *(.NMIExceptionVector.literal) + _NMIExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int5_lit :vector_int5_lit_phdr + + .NMIExceptionVector.text : ALIGN(4) + { + _NMIExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.NMIExceptionVector.text)) + _NMIExceptionVector_text_end = ABSOLUTE(.); + } >vector_int5_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 + + .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(.); + *(*.module_init) + _module_init_end = ABSOLUTE(.); + } >sof_sdram0 :sof_sdram0_phdr + + .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_sdram0 :sof_sdram0_phdr + + .reset.rodata : ALIGN(4) + { + _reset_rodata_start = ABSOLUTE(.); + *(.reset.rodata) + _reset_rodata_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 + + .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 + + /* stack */ + _end = SOF_STACK_END; + PROVIDE(end = SOF_STACK_END); + _stack_sentry = SOF_STACK_END; + __stack = SOF_STACK_BASE; + + .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.*)) + } + + .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 + + .sof_stack (NOLOAD) : ALIGN(8) + { + . = ALIGN (4096); + _sof_stack_start = ABSOLUTE(.); + . = . + SOF_STACK_TOTAL_SIZE; + _sof_stack_end = ABSOLUTE(.); + } >sof_stack :sof_stack_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 + + .fw_ready : ALIGN(4) + { + KEEP (*(.fw_ready)) + KEEP (*(.fw_ready_metadata)) + } >sof_sdram0 :sof_sdram0_phdr + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr +} diff --git a/src/platform/imx8ulp/include/arch/xtensa/config/core-isa.h b/src/platform/imx8ulp/include/arch/xtensa/config/core-isa.h new file mode 100644 index 000000000000..899f7c606b21 --- /dev/null +++ b/src/platform/imx8ulp/include/arch/xtensa/config/core-isa.h @@ -0,0 +1,673 @@ +/* + * 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=13270; Build=0x92cb6; Copyright (c) 1999-2021 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 + + +/**************************************************************************** + 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 32 /* num of physical addr regs */ +#define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */ +#define XCHAL_MAX_INSTRUCTION_SIZE 11 /* 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_POPC 0*/ /* POPC instruction */ +/*#define XCHAL_HAVE_CRC 0*/ /* CRC 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 1 /* MAC16 package */ + +#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_HIFI4 1 /* HiFi4 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI4_VFPU 1 /* HiFi4 Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI3 1 /* HiFi3 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3_VFPU 0 /* HiFi3 Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI3Z 0 /* HiFi3Z Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3Z_VFPU 0 /* HiFi3Z Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI2EP 0 /* HiFi2EP */ +#define XCHAL_HAVE_HIFI_MINI 0 + + + +#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ +#define XCHAL_HAVE_USER_DPFPU 0 /* user DP floating-point pkg */ +#define XCHAL_HAVE_USER_SPFPU 1 /* user SP floating-point pkg */ +#define XCHAL_HAVE_FP 1 /* single prec floating point */ +#define XCHAL_HAVE_FP_DIV 1 /* FP with DIV instructions */ +#define XCHAL_HAVE_FP_RECIP 1 /* FP with RECIP instructions */ +#define XCHAL_HAVE_FP_SQRT 1 /* FP with SQRT instructions */ +#define XCHAL_HAVE_FP_RSQRT 1 /* FP with RSQRT instructions */ +#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ +#define XCHAL_HAVE_DFP_DIV 0 /* DFP with DIV instructions */ +#define XCHAL_HAVE_DFP_RECIP 0 /* DFP with RECIP instructions*/ +#define XCHAL_HAVE_DFP_SQRT 0 /* DFP with SQRT instructions */ +#define XCHAL_HAVE_DFP_RSQRT 0 /* DFP with RSQRT instructions*/ +#define XCHAL_HAVE_DFP_ACCEL 1 /* 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_PDX 0 /* PDX */ +#define XCHAL_PDX_SIMD32 0 /* simd32 for PDX */ +#define XCHAL_HAVE_PDX4 0 /* PDX4 */ +#define XCHAL_HAVE_PDX8 0 /* PDX8 */ +#define XCHAL_HAVE_PDX16 0 /* PDX16 */ + +#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ +#define XCHAL_HAVE_CONNXD2_DUALLSFLIX 0 /* ConnX D2 & Dual LoadStore Flix */ +#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_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, or P3 */ +#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 */ +#define XCHAL_HAVE_VISION_HP_VFPU 0 /* hp_vfpu option on Vision P6 */ + +#define XCHAL_HAVE_VISIONC 0 /* Vision C */ + +/*---------------------------------------------------------------------- + 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 16 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 16 /* data width in bytes */ +#define XCHAL_DATA_PIPE_DELAY 2 /* d-side pipeline delay + (1 = 5-stage, 2 = 7-stage) */ +#define XCHAL_CLOCK_GATING_GLOBAL 1 /* global clock gating */ +#define XCHAL_CLOCK_GATING_FUNCUNIT 1 /* funct. unit clock gating */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ +#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ +#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ +#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ + +#define XCHAL_SW_VERSION 1200008 /* sw version of this header */ + +#define XCHAL_CORE_ID "hifi4_nxp2_ulp_prod" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_BUILD_UNIQUE_ID 0x00092CB6 /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC203B286 /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x2908A8C2 /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX7.0.8" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2700 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 8 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION 270008 /* major*100+minor */ +#define XCHAL_HW_REL_LX7 1 +#define XCHAL_HW_REL_LX7_0 1 +#define XCHAL_HW_REL_LX7_0_8 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 8 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 270008 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2700 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 8 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 270008 /* latest targeted hw */ + + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_ICACHE_LINESIZE 128 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 128 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 7 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 7 /* log2(D line size in bytes) */ + +#define XCHAL_ICACHE_SIZE 32768 /* I-cache size in bytes or 0 */ +#define XCHAL_DCACHE_SIZE 65536 /* D-cache size in bytes or 0 */ + +#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 dcache */ +#define XCHAL_PREFETCH_CASTOUT_LINES 1 /* dcache pref. castout bufsz */ +#define XCHAL_PREFETCH_ENTRIES 16 /* cache prefetch entries */ +#define XCHAL_PREFETCH_BLOCK_ENTRIES 8 /* prefetch block streams */ +#define XCHAL_HAVE_CACHE_BLOCKOPS 1 /* block prefetch for caches */ +#define XCHAL_HAVE_ICACHE_TEST 1 /* Icache test instructions */ +#define XCHAL_HAVE_DCACHE_TEST 1 /* Dcache test instructions */ +#define XCHAL_HAVE_ICACHE_DYN_WAYS 0 /* Icache dynamic way support */ +#define XCHAL_HAVE_DCACHE_DYN_WAYS 0 /* Dcache dynamic way support */ + + + + +/**************************************************************************** + 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 6 +#define XCHAL_DCACHE_SETWIDTH 7 + +/* Cache set associativity (number of ways): */ +#define XCHAL_ICACHE_WAYS 4 +#define XCHAL_DCACHE_WAYS 4 + +/* 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 + +/* Cache access size in bytes (affects operation of SICW instruction): */ +#define XCHAL_ICACHE_ACCESS_SIZE 16 +#define XCHAL_DCACHE_ACCESS_SIZE 16 + +#define XCHAL_DCACHE_BANKS 4 /* number of banks */ + +/* 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 */ + +/* Instruction RAM 0: */ +#define XCHAL_INSTRAM0_VADDR 0x21170000 /* virtual address */ +#define XCHAL_INSTRAM0_PADDR 0x21170000 /* physical address */ +#define XCHAL_INSTRAM0_SIZE 65536 /* 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 0x21180000 /* virtual address */ +#define XCHAL_DATARAM0_PADDR 0x21180000 /* physical address */ +#define XCHAL_DATARAM0_SIZE 65536 /* size in bytes */ +#define XCHAL_DATARAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XCHAL_DATARAM0_BANKS 4 /* 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_IDMA_TRANSPOSE 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_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#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 32 /* number of interrupts */ +#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XCHAL_NUM_EXTINTERRUPTS 27 /* num of external interrupts */ +#define XCHAL_NUM_INTLEVELS 4 /* number of interrupt levels + (not including level zero) */ +#define XCHAL_EXCM_LEVEL 2 /* 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 0x0000FFC0 +#define XCHAL_INTLEVEL2_MASK 0x00FF0006 +#define XCHAL_INTLEVEL3_MASK 0xFF000038 +#define XCHAL_INTLEVEL4_MASK 0x00000000 +#define XCHAL_INTLEVEL5_MASK 0x00000001 +#define XCHAL_INTLEVEL6_MASK 0x00000000 +#define XCHAL_INTLEVEL7_MASK 0x00000000 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x0000FFC0 +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x00FFFFC6 +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0xFFFFFFFE +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0xFFFFFFFE +#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0xFFFFFFFF +#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0xFFFFFFFF +#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0xFFFFFFFF + +/* Level of each interrupt: */ +#define XCHAL_INT0_LEVEL 5 +#define XCHAL_INT1_LEVEL 2 +#define XCHAL_INT2_LEVEL 2 +#define XCHAL_INT3_LEVEL 3 +#define XCHAL_INT4_LEVEL 3 +#define XCHAL_INT5_LEVEL 3 +#define XCHAL_INT6_LEVEL 1 +#define XCHAL_INT7_LEVEL 1 +#define XCHAL_INT8_LEVEL 1 +#define XCHAL_INT9_LEVEL 1 +#define XCHAL_INT10_LEVEL 1 +#define XCHAL_INT11_LEVEL 1 +#define XCHAL_INT12_LEVEL 1 +#define XCHAL_INT13_LEVEL 1 +#define XCHAL_INT14_LEVEL 1 +#define XCHAL_INT15_LEVEL 1 +#define XCHAL_INT16_LEVEL 2 +#define XCHAL_INT17_LEVEL 2 +#define XCHAL_INT18_LEVEL 2 +#define XCHAL_INT19_LEVEL 2 +#define XCHAL_INT20_LEVEL 2 +#define XCHAL_INT21_LEVEL 2 +#define XCHAL_INT22_LEVEL 2 +#define XCHAL_INT23_LEVEL 2 +#define XCHAL_INT24_LEVEL 3 +#define XCHAL_INT25_LEVEL 3 +#define XCHAL_INT26_LEVEL 3 +#define XCHAL_INT27_LEVEL 3 +#define XCHAL_INT28_LEVEL 3 +#define XCHAL_INT29_LEVEL 3 +#define XCHAL_INT30_LEVEL 3 +#define XCHAL_INT31_LEVEL 3 +#define XCHAL_DEBUGLEVEL 4 /* debug interrupt level */ +#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ +#define XCHAL_NMILEVEL 5 /* NMI "level" (for use with + EXCSAVE/EPS/EPC_n, RFI n) */ + +/* Type of each interrupt: */ +#define XCHAL_INT0_TYPE XTHAL_INTTYPE_NMI +#define XCHAL_INT1_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT2_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT3_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT4_TYPE XTHAL_INTTYPE_PROFILING +#define XCHAL_INT5_TYPE XTHAL_INTTYPE_WRITE_ERROR +#define XCHAL_INT6_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT7_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT10_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT11_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT13_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT14_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT19_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT20_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT21_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT22_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT23_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT24_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT25_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT26_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT27_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT28_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT29_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT30_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT31_TYPE XTHAL_INTTYPE_EXTERN_LEVEL + +/* Masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0x00000000 +#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000002 +#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000000 +#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0xFFFFFFC0 +#define XCHAL_INTTYPE_MASK_TIMER 0x0000000C +#define XCHAL_INTTYPE_MASK_NMI 0x00000001 +#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000020 +#define XCHAL_INTTYPE_MASK_PROFILING 0x00000010 +#define XCHAL_INTTYPE_MASK_IDMA_DONE 0x00000000 +#define XCHAL_INTTYPE_MASK_IDMA_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_GS_ERR 0x00000000 + +/* Interrupt numbers assigned to specific interrupt sources: */ +#define XCHAL_TIMER0_INTERRUPT 2 /* CCOMPARE0 */ +#define XCHAL_TIMER1_INTERRUPT 3 /* CCOMPARE1 */ +#define XCHAL_TIMER2_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_NMI_INTERRUPT 0 /* non-maskable interrupt */ +#define XCHAL_WRITE_ERROR_INTERRUPT 5 +#define XCHAL_PROFILING_INTERRUPT 4 + +/* Interrupt numbers for levels at which only one interrupt is configured: */ +#define XCHAL_INTLEVEL5_NUM 0 +/* (There are many interrupts each at level(s) 1, 2, 3.) */ + + +/* + * 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 0 /* (intlevel 5) */ +#define XCHAL_EXTINT1_NUM 6 /* (intlevel 1) */ +#define XCHAL_EXTINT2_NUM 7 /* (intlevel 1) */ +#define XCHAL_EXTINT3_NUM 8 /* (intlevel 1) */ +#define XCHAL_EXTINT4_NUM 9 /* (intlevel 1) */ +#define XCHAL_EXTINT5_NUM 10 /* (intlevel 1) */ +#define XCHAL_EXTINT6_NUM 11 /* (intlevel 1) */ +#define XCHAL_EXTINT7_NUM 12 /* (intlevel 1) */ +#define XCHAL_EXTINT8_NUM 13 /* (intlevel 1) */ +#define XCHAL_EXTINT9_NUM 14 /* (intlevel 1) */ +#define XCHAL_EXTINT10_NUM 15 /* (intlevel 1) */ +#define XCHAL_EXTINT11_NUM 16 /* (intlevel 2) */ +#define XCHAL_EXTINT12_NUM 17 /* (intlevel 2) */ +#define XCHAL_EXTINT13_NUM 18 /* (intlevel 2) */ +#define XCHAL_EXTINT14_NUM 19 /* (intlevel 2) */ +#define XCHAL_EXTINT15_NUM 20 /* (intlevel 2) */ +#define XCHAL_EXTINT16_NUM 21 /* (intlevel 2) */ +#define XCHAL_EXTINT17_NUM 22 /* (intlevel 2) */ +#define XCHAL_EXTINT18_NUM 23 /* (intlevel 2) */ +#define XCHAL_EXTINT19_NUM 24 /* (intlevel 3) */ +#define XCHAL_EXTINT20_NUM 25 /* (intlevel 3) */ +#define XCHAL_EXTINT21_NUM 26 /* (intlevel 3) */ +#define XCHAL_EXTINT22_NUM 27 /* (intlevel 3) */ +#define XCHAL_EXTINT23_NUM 28 /* (intlevel 3) */ +#define XCHAL_EXTINT24_NUM 29 /* (intlevel 3) */ +#define XCHAL_EXTINT25_NUM 30 /* (intlevel 3) */ +#define XCHAL_EXTINT26_NUM 31 /* (intlevel 3) */ +/* EXTERNAL BInterrupt pin numbers mapped to each core interrupt number: */ +#define XCHAL_INT0_EXTNUM 0 /* (intlevel 5) */ +#define XCHAL_INT6_EXTNUM 1 /* (intlevel 1) */ +#define XCHAL_INT7_EXTNUM 2 /* (intlevel 1) */ +#define XCHAL_INT8_EXTNUM 3 /* (intlevel 1) */ +#define XCHAL_INT9_EXTNUM 4 /* (intlevel 1) */ +#define XCHAL_INT10_EXTNUM 5 /* (intlevel 1) */ +#define XCHAL_INT11_EXTNUM 6 /* (intlevel 1) */ +#define XCHAL_INT12_EXTNUM 7 /* (intlevel 1) */ +#define XCHAL_INT13_EXTNUM 8 /* (intlevel 1) */ +#define XCHAL_INT14_EXTNUM 9 /* (intlevel 1) */ +#define XCHAL_INT15_EXTNUM 10 /* (intlevel 1) */ +#define XCHAL_INT16_EXTNUM 11 /* (intlevel 2) */ +#define XCHAL_INT17_EXTNUM 12 /* (intlevel 2) */ +#define XCHAL_INT18_EXTNUM 13 /* (intlevel 2) */ +#define XCHAL_INT19_EXTNUM 14 /* (intlevel 2) */ +#define XCHAL_INT20_EXTNUM 15 /* (intlevel 2) */ +#define XCHAL_INT21_EXTNUM 16 /* (intlevel 2) */ +#define XCHAL_INT22_EXTNUM 17 /* (intlevel 2) */ +#define XCHAL_INT23_EXTNUM 18 /* (intlevel 2) */ +#define XCHAL_INT24_EXTNUM 19 /* (intlevel 3) */ +#define XCHAL_INT25_EXTNUM 20 /* (intlevel 3) */ +#define XCHAL_INT26_EXTNUM 21 /* (intlevel 3) */ +#define XCHAL_INT27_EXTNUM 22 /* (intlevel 3) */ +#define XCHAL_INT28_EXTNUM 23 /* (intlevel 3) */ +#define XCHAL_INT29_EXTNUM 24 /* (intlevel 3) */ +#define XCHAL_INT30_EXTNUM 25 /* (intlevel 3) */ +#define XCHAL_INT31_EXTNUM 26 /* (intlevel 3) */ + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture + number: 1 == XEA1 (old) + 2 == XEA2 (new) + 0 == XEAX (extern) or TX */ +#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ +#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ +#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 1 /* relocatable vectors */ +#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */ +#define XCHAL_VECBASE_RESET_VADDR 0x21170400 /* VECBASE reset value */ +#define XCHAL_VECBASE_RESET_PADDR 0x21170400 +#define XCHAL_RESET_VECBASE_OVERLAP 0 + +#define XCHAL_RESET_VECTOR0_VADDR 0x21170000 +#define XCHAL_RESET_VECTOR0_PADDR 0x21170000 +#define XCHAL_RESET_VECTOR1_VADDR 0x20100000 +#define XCHAL_RESET_VECTOR1_PADDR 0x20100000 +#define XCHAL_RESET_VECTOR_VADDR 0x21170000 +#define XCHAL_RESET_VECTOR_PADDR 0x21170000 +#define XCHAL_USER_VECOFS 0x0000021C +#define XCHAL_USER_VECTOR_VADDR 0x2117061C +#define XCHAL_USER_VECTOR_PADDR 0x2117061C +#define XCHAL_KERNEL_VECOFS 0x000001FC +#define XCHAL_KERNEL_VECTOR_VADDR 0x211705FC +#define XCHAL_KERNEL_VECTOR_PADDR 0x211705FC +#define XCHAL_DOUBLEEXC_VECOFS 0x0000023C +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x2117063C +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x2117063C +#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 0x21170400 +#define XCHAL_WINDOW_VECTORS_PADDR 0x21170400 +#define XCHAL_INTLEVEL2_VECOFS 0x0000017C +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x2117057C +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x2117057C +#define XCHAL_INTLEVEL3_VECOFS 0x0000019C +#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x2117059C +#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x2117059C +#define XCHAL_INTLEVEL4_VECOFS 0x000001BC +#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x211705BC +#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x211705BC +#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL4_VECOFS +#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL4_VECTOR_VADDR +#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL4_VECTOR_PADDR +#define XCHAL_NMI_VECOFS 0x000001DC +#define XCHAL_NMI_VECTOR_VADDR 0x211705DC +#define XCHAL_NMI_VECTOR_PADDR 0x211705DC +#define XCHAL_INTLEVEL5_VECOFS XCHAL_NMI_VECOFS +#define XCHAL_INTLEVEL5_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR +#define XCHAL_INTLEVEL5_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR + + +/*---------------------------------------------------------------------- + DEBUG MODULE + ----------------------------------------------------------------------*/ + +/* Misc */ +#define XCHAL_HAVE_DEBUG_ERI 1 /* ERI to debug module */ +#define XCHAL_HAVE_DEBUG_APB 1 /* 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 2 /* 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/imx8ulp/include/arch/xtensa/config/core-matmap.h b/src/platform/imx8ulp/include/arch/xtensa/config/core-matmap.h new file mode 100644 index 000000000000..f25903591617 --- /dev/null +++ b/src/platform/imx8ulp/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=13270; Build=0x92cb6; Copyright (c) 1999-2021 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/imx8ulp/include/arch/xtensa/config/defs.h b/src/platform/imx8ulp/include/arch/xtensa/config/defs.h new file mode 100644 index 000000000000..6d4851ca7c41 --- /dev/null +++ b/src/platform/imx8ulp/include/arch/xtensa/config/defs.h @@ -0,0 +1,38 @@ +/* Definitions for Xtensa instructions, types, and protos. */ + +/* Customer ID=13270; Build=0x92cb6; Copyright (c) 2003-2004 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* NOTE: This file exists only for backward compatibility with T1050 + and earlier Xtensa releases. It includes only a subset of the + available header files. */ + +#ifndef _XTENSA_BASE_HEADER +#define _XTENSA_BASE_HEADER + +#ifdef __XTENSA__ + +#include +#include +#include + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_BASE_HEADER */ diff --git a/src/platform/imx8ulp/include/arch/xtensa/config/specreg.h b/src/platform/imx8ulp/include/arch/xtensa/config/specreg.h new file mode 100644 index 000000000000..c48a496320a2 --- /dev/null +++ b/src/platform/imx8ulp/include/arch/xtensa/config/specreg.h @@ -0,0 +1,109 @@ +/* + * Xtensa Special Register symbolic names + */ + +/* $Id: //depot/rel/Foxhill/dot.8/Xtensa/SWConfig/hal/specreg.h.tpp#1 $ */ + +/* Customer ID=13270; Build=0x92cb6; 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 ACCLO 16 +#define ACCHI 17 +#define MR_0 32 +#define MR_1 33 +#define MR_2 34 +#define MR_3 35 +#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 DEPC 192 +#define EPS_2 194 +#define EPS_3 195 +#define EPS_4 196 +#define EPS_5 197 +#define EXCSAVE_1 209 +#define EXCSAVE_2 210 +#define EXCSAVE_3 211 +#define EXCSAVE_4 212 +#define EXCSAVE_5 213 +#define CPENABLE 224 +#define INTERRUPT 226 +#define INTENABLE 228 +#define PS 230 +#define VECBASE 231 +#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 MR 32 +#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/imx8ulp/include/arch/xtensa/config/system.h b/src/platform/imx8ulp/include/arch/xtensa/config/system.h new file mode 100644 index 000000000000..5d3394622d2c --- /dev/null +++ b/src/platform/imx8ulp/include/arch/xtensa/config/system.h @@ -0,0 +1,270 @@ +/* + * 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=13270; Build=0x92cb6; 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 + +/*#include */ + + + +/*---------------------------------------------------------------------- + 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 +/* Alternatives: */ +/*#define XSHAL_WINDOWED_ABI 1*/ /* set if windowed ABI selected */ +/*#define XSHAL_CALL0_ABI 0*/ /* set if call0 ABI selected */ + +#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 +/* Alternatives: */ +/*#define XSHAL_NEWLIB 1*/ /* set if newlib C library selected */ +/*#define XSHAL_UCLIBC 0*/ /* set if uCLibC C library selected */ +/*#define XSHAL_XCLIB 0*/ /* set if Xtensa C library selected */ + +#define XSHAL_USE_FLOATING_POINT 1 + +#define XSHAL_FLOATING_POINT_ABI 1 + +/* SW workarounds enabled for HW errata: */ + +/* SW options for functional safety: */ +#define XSHAL_FUNC_SAFETY_ENABLED 0 + +/*---------------------------------------------------------------------- + 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 0x50000000 +#define XSHAL_IOBLOCK_BYPASS_PADDR 0x50000000 +#define XSHAL_IOBLOCK_BYPASS_SIZE 0x0E000000 + +/* System ROM: */ +/*#define XSHAL_ROM_[VP]ADDR ...not configured...*/ +/*#define XSHAL_ROM_SIZE ...not configured...*/ +/*#define XSHAL_ROM_AVAIL_V{ADDR,SIZE} ...not configured...*/ + +/* System RAM: */ +#define XSHAL_RAM_VADDR 0x00000000 +#define XSHAL_RAM_PADDR 0x00000000 +#define XSHAL_RAM_VSIZE 0x21100000 +#define XSHAL_RAM_PSIZE 0x21100000 +#define XSHAL_RAM_SIZE XSHAL_RAM_PSIZE +/* Largest available area (free of vectors): */ +#define XSHAL_RAM_AVAIL_VADDR 0x00000004 +#define XSHAL_RAM_AVAIL_VSIZE 0x210FFFFC + +/* + * 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 0x80000000 +#define XSHAL_RAM_BYPASS_PADDR 0x80000000 +#define XSHAL_RAM_BYPASS_PSIZE 0x20000000 + +/* Alternate system RAM (different device than system RAM): */ +/*#define XSHAL_ALTRAM_[VP]ADDR ...not configured...*/ +/*#define XSHAL_ALTRAM_SIZE ...not configured...*/ + +/* 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 0x60000000 + +/*---------------------------------------------------------------------- + * 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 0x22222244 /* enable caches in write-back mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEALLOC 0x22222211 /* enable caches in write-allocate mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITETHRU 0x22222211 /* 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 0xFFFFFF44 /* enable caches in write-back mode */ +#define XSHAL_STRICT_CACHEATTR_WRITEALLOC 0xFFFFFF11 /* enable caches in write-allocate mode */ +#define XSHAL_STRICT_CACHEATTR_WRITETHRU 0xFFFFFF11 /* enable caches in write-through mode */ +#define XSHAL_STRICT_CACHEATTR_BYPASS 0xFFFFFF22 /* 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 0x22222244 /* enable caches in write-back mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC 0x22222211 /* enable caches in write-allocate mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITETHRU 0x22222211 /* enable caches in write-through mode */ +#define XSHAL_TRAPNULL_CACHEATTR_BYPASS 0x22222222 /* 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 0xFFF24244 /* enable caches in write-back mode */ +#define XSHAL_XT2000_CACHEATTR_WRITEALLOC 0xFFF21211 /* enable caches in write-allocate mode */ +#define XSHAL_XT2000_CACHEATTR_WRITETHRU 0xFFF21211 /* enable caches in write-through mode */ +#define XSHAL_XT2000_CACHEATTR_BYPASS 0xFFF22222 /* 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 0x00000101 /* BusInt SDRAM regions */ + + +/*---------------------------------------------------------------------- + VECTOR INFO AND SIZES + ----------------------------------------------------------------------*/ + +#define XSHAL_VECTORS_PACKED 0 +#define XSHAL_STATIC_VECTOR_SELECT 0 +#define XSHAL_RESET_VECTOR_VADDR 0x21170000 +#define XSHAL_RESET_VECTOR_PADDR 0x21170000 + +/* + * 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 0x000002E0 +#define XSHAL_RESET_VECTOR_ISROM 0 +#define XSHAL_USER_VECTOR_SIZE 0x0000001C +#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 0x0000001C +#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 0x0000001C +#define XSHAL_DOUBLEEXC_VECTOR_ISROM 0 +#define XSHAL_WINDOW_VECTORS_SIZE 0x00000178 +#define XSHAL_WINDOW_VECTORS_ISROM 0 +#define XSHAL_INTLEVEL2_VECTOR_SIZE 0x0000001C +#define XSHAL_INTLEVEL2_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL3_VECTOR_SIZE 0x0000001C +#define XSHAL_INTLEVEL3_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL4_VECTOR_SIZE 0x0000001C +#define XSHAL_INTLEVEL4_VECTOR_ISROM 0 +#define XSHAL_DEBUG_VECTOR_SIZE XSHAL_INTLEVEL4_VECTOR_SIZE +#define XSHAL_DEBUG_VECTOR_ISROM XSHAL_INTLEVEL4_VECTOR_ISROM +#define XSHAL_NMI_VECTOR_SIZE 0x0000001C +#define XSHAL_NMI_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL5_VECTOR_SIZE XSHAL_NMI_VECTOR_SIZE + + +#endif /*XTENSA_CONFIG_SYSTEM_H*/ + diff --git a/src/platform/imx8ulp/include/arch/xtensa/config/tie-asm.h b/src/platform/imx8ulp/include/arch/xtensa/config/tie-asm.h new file mode 100644 index 000000000000..ecc74e894724 --- /dev/null +++ b/src/platform/imx8ulp/include/arch/xtensa/config/tie-asm.h @@ -0,0 +1,384 @@ +/* + * 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=13270; Build=0x92cb6; Copyright (c) 1999-2021 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 + +/* 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 used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 1012, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wsr.ACCLO \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+4 + wsr.ACCHI \at1 // MAC16 option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1012, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .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, 996, 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 + l32i \at1, \ptr, .Lxchal_ofs_+8 + wsr.M0 \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+12 + wsr.M1 \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+16 + wsr.M2 \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+20 + wsr.M3 \at1 // MAC16 option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 24 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 996, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 24 + .endif + // 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, 1008, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wur.F64R_LO \at1 // ureg 234 + l32i \at1, \ptr, .Lxchal_ofs_+4 + wur.F64R_HI \at1 // ureg 235 + l32i \at1, \ptr, .Lxchal_ofs_+8 + wur.F64S \at1 // ureg 236 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 12 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1008, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 12 + .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_+40 + ae_s64.i aed1, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed2, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + ae_s64.i aed3, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed4, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed5, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed6, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed7, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed8, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed9, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed10, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + ae_s64.i aed11, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed12, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed13, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed14, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed15, \ptr, .Lxchal_ofs_+32 + ae_movae \at1, aep0 + s8i \at1, \ptr, .Lxchal_ofs_+40 + ae_movae \at1, aep1 + s8i \at1, \ptr, .Lxchal_ofs_+41 + ae_movae \at1, aep2 + s8i \at1, \ptr, .Lxchal_ofs_+42 + ae_movae \at1, aep3 + s8i \at1, \ptr, .Lxchal_ofs_+43 + ae_salign64.i u0, \ptr, .Lxchal_ofs_+48 + ae_salign64.i u1, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + ae_salign64.i u2, \ptr, .Lxchal_ofs_+0 + ae_salign64.i u3, \ptr, .Lxchal_ofs_+8 + addi \ptr, \ptr, -192 + 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 + rur.AE_CBEGIN1 \at1 // ureg 248 + s32i \at1, \ptr, .Lxchal_ofs_+32 + rur.AE_CEND1 \at1 // ureg 249 + s32i \at1, \ptr, .Lxchal_ofs_+36 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 208 + .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_ + 208 + .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 + l32i \at1, \ptr, .Lxchal_ofs_+32 + wur.AE_CBEGIN1 \at1 // ureg 248 + l32i \at1, \ptr, .Lxchal_ofs_+36 + wur.AE_CEND1 \at1 // ureg 249 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed1, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed2, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + ae_l64.i aed3, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed4, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed5, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed6, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed7, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed8, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed9, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed10, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + ae_l64.i aed11, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed12, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed13, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed14, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed15, \ptr, .Lxchal_ofs_+32 + addi \ptr, \ptr, 40 + l8ui \at1, \ptr, .Lxchal_ofs_+0 + ae_movea aep0, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+1 + ae_movea aep1, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+2 + ae_movea aep2, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+3 + ae_movea aep3, \at1 + addi \ptr, \ptr, 8 + 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_ + 176 + .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_ + 208 + .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/imx8ulp/include/arch/xtensa/config/tie.h b/src/platform/imx8ulp/include/arch/xtensa/config/tie.h new file mode 100644 index 000000000000..d40fcd566f75 --- /dev/null +++ b/src/platform/imx8ulp/include/arch/xtensa/config/tie.h @@ -0,0 +1,197 @@ +/* + * 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=13270; Build=0x92cb6; Copyright (c) 1999-2021 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 + +#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 208 /* 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 48 +#define XCHAL_NCP_SA_ALIGN 4 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 256 /* 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 12 +#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,1,0,0,1, acclo, 4, 4, 4,0x0210, sr,16 , 32,0,0,0) \ + XCHAL_SA_REG(s,1,0,0,1, acchi, 4, 4, 4,0x0211, sr,17 , 8,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) \ + XCHAL_SA_REG(s,0,0,0,1, m0, 4, 4, 4,0x0220, sr,32 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m1, 4, 4, 4,0x0221, sr,33 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m2, 4, 4, 4,0x0222, sr,34 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m3, 4, 4, 4,0x0223, sr,35 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, f64r_lo, 4, 4, 4,0x03EA, ur,234, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, f64r_hi, 4, 4, 4,0x03EB, ur,235, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, f64s, 4, 4, 4,0x03EC, ur,236, 32,0,0,0) + +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) /* empty */ + +#define XCHAL_CP1_SA_NUM 33 +#define XCHAL_CP1_SA_LIST(s) \ + XCHAL_SA_REG(s,0,0,1,0, fcr_fsr, 8, 8, 8,0x1029, ur,-1 , 7,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_ovf_sar, 4, 4, 4,0x03F0, ur,240, 15,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_bithead, 4, 4, 4,0x03F1, ur,241, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0,ae_ts_fts_bu_bp, 4, 4, 4,0x03F2, ur,242, 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cw_sd_no, 4, 4, 4,0x03F3, ur,243, 29,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin0, 4, 4, 4,0x03F6, ur,246, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend0, 4, 4, 4,0x03F7, ur,247, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin1, 4, 4, 4,0x03F8, ur,248, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend1, 4, 4, 4,0x03F9, ur,249, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed0, 8, 8, 8,0x1010, aed,0 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed1, 8, 8, 8,0x1011, aed,1 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed2, 8, 8, 8,0x1012, aed,2 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed3, 8, 8, 8,0x1013, aed,3 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed4, 8, 8, 8,0x1014, aed,4 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed5, 8, 8, 8,0x1015, aed,5 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed6, 8, 8, 8,0x1016, aed,6 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed7, 8, 8, 8,0x1017, aed,7 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed8, 8, 8, 8,0x1018, aed,8 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed9, 8, 8, 8,0x1019, aed,9 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed10, 8, 8, 8,0x101A, aed,10 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed11, 8, 8, 8,0x101B, aed,11 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed12, 8, 8, 8,0x101C, aed,12 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed13, 8, 8, 8,0x101D, aed,13 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed14, 8, 8, 8,0x101E, aed,14 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed15, 8, 8, 8,0x101F, aed,15 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep0, 1, 1, 1,0x1024, aep,0 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep1, 1, 1, 1,0x1025, aep,1 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep2, 1, 1, 1,0x1026, aep,2 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep3, 1, 1, 1,0x1027, aep,3 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u0, 8, 8, 8,0x1020, u,0 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u1, 8, 8, 8,0x1021, u,1 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u2, 8, 8, 8,0x1022, u,2 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u3, 8, 8, 8,0x1023, 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,6,11, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,6,11 + +#endif /*_XTENSA_CORE_TIE_H*/ + diff --git a/src/platform/imx8ulp/include/platform/drivers/idc.h b/src/platform/imx8ulp/include/platform/drivers/idc.h new file mode 100644 index 000000000000..6d1a4186a2f6 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/drivers/idc.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2019 NXP + * + * Author: Daniel Baluta + */ + +#ifdef __SOF_DRIVERS_IDC_H__ + +#ifndef __PLATFORM_DRIVERS_IDC_H__ +#define __PLATFORM_DRIVERS_IDC_H__ + +#include + +struct idc_msg; + +static inline int idc_send_msg(struct idc_msg *msg, + uint32_t mode) { return 0; } + +static inline int idc_init(void) { return 0; } + +#endif /* __PLATFORM_DRIVERS_IDC_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/drivers/idc.h" + +#endif /* __SOF_DRIVERS_IDC_H__ */ diff --git a/src/platform/imx8ulp/include/platform/drivers/interrupt.h b/src/platform/imx8ulp/include/platform/drivers/interrupt.h new file mode 100644 index 000000000000..e7193b02190a --- /dev/null +++ b/src/platform/imx8ulp/include/platform/drivers/interrupt.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2019 NXP + * + * Author: Daniel Baluta + */ + +#ifdef __SOF_DRIVERS_INTERRUPT_H__ + +#ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ +#define __PLATFORM_DRIVERS_INTERRUPT_H__ + +#include + + +/* IRQ numbers */ +#define IRQ_DSP_SYS_NMI 0 +#define IRQ_NUM_SOFTWARE0 1 +#define IRQ_NUM_TIMER0 2 +#define IRQ_NUM_TIMER1 3 +#define DSP_Profiling_IRQ_L3 4 +#define DSP_Wer_L3 5 +#define DMA2_c0_ErrTranc 6 +#define IRQ_NUM_MU2 14 +#define IRQ_NUM_MU3 15 +#define IRQ_SAI5_NUM 23 +#define IRQ_SAI6_NUM 24 +#define IRQ_SAI7_NUM 25 + +#define PLATFORM_IRQ_HW_NUM XCHAL_NUM_INTERRUPTS +#define PLATFORM_IRQ_CHILDREN 0 /* Each cascaded struct covers 64 IRQs */ +/* IMX: Covered steer IRQs are modulo-64 aligned. */ +#define PLATFORM_IRQ_FIRST_CHILD 0 + +// ----------------- need remove + +//#define IRQ_NUM_SOFTWARE0 8 /* Level 1 */ +//#define IRQ_NUM_TIMER0 2 /* Level 2 */ +//#define IRQ_NUM_MU 7 /* Level 2 */ +//#define IRQ_NUM_SOFTWARE1 9 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP0 19 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP1 20 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP2 21 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP3 22 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP4 23 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP5 24 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP6 25 /* Level 2 */ +//#define IRQ_NUM_IRQSTR_DSP7 26 /* Level 2 */ + +/* +#define IRQSTR_BASE_ADDR 0x510A0000 +#define IRQSTR_CHANCTL 0x00 +#define IRQSTR_CH_MASK(n) (0x04 + 0x04 * (15 - (n))) +#define IRQSTR_CH_SET(n) (0x44 + 0x04 * (15 - (n))) +#define IRQSTR_CH_STATUS(n) (0x84 + 0x04 * (15 - (n))) +#define IRQSTR_MASTER_DISABLE 0xC4 +#define IRQSTR_MASTER_STATUS 0xC8 + +#define IRQSTR_RESERVED_IRQS_NUM 32 +#define IRQSTR_IRQS_NUM 512 +#define IRQSTR_IRQS_REGISTERS_NUM 16 +#define IRQSTR_IRQS_PER_LINE 64 +*/ + +/* no irqstr in 8ulp */ +#define IRQSTR_CH_MASK(n) (0x04 + 0x04 * (15 - (n))) +#define IRQSTR_RESERVED_IRQS_NUM 0 +#define IRQSTR_IRQS_NUM 0 +#define IRQSTR_IRQS_REGISTERS_NUM 0 +#define IRQSTR_IRQS_PER_LINE 0 + +int irqstr_get_sof_int(int irqstr_int); +#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/imx8ulp/include/platform/lib/clk.h b/src/platform/imx8ulp/include/platform/lib/clk.h new file mode 100644 index 000000000000..6d52972da9e5 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/lib/clk.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2019 NXP + * + * Author: Daniel Baluta + */ + +#ifdef __SOF_LIB_CLK_H__ + +#ifndef __PLATFORM_LIB_CLK_H__ +#define __PLATFORM_LIB_CLK_H__ + +#include + +struct sof; + +#define CLK_CPU(x) (x) + +#define CPU_DEFAULT_IDX 0 + +#ifdef CONFIG_IMX8 +#define CLK_DEFAULT_CPU_HZ 666000000 +#define CLK_MAX_CPU_HZ 666000000 +#else /* CONFIG_IMX8X */ +#define CLK_DEFAULT_CPU_HZ 640000000 +#define CLK_MAX_CPU_HZ 640000000 +#endif + +#define NUM_CLOCKS 1 + +#define NUM_CPU_FREQ 1 + +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/imx8ulp/include/platform/lib/cpu.h b/src/platform/imx8ulp/include/platform/lib/cpu.h new file mode 100644 index 000000000000..a05eb8dfde37 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/lib/cpu.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +/** + * \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 Id of primary DSP core */ +#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/imx8ulp/include/platform/lib/dai.h b/src/platform/imx8ulp/include/platform/lib/dai.h new file mode 100644 index 000000000000..667e93ddfbf8 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/lib/dai.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2019 NXP + * + * Author: Daniel Baluta + */ + +#ifdef __SOF_LIB_DAI_H__ + +#ifndef __PLATFORM_LIB_DAI_H__ +#define __PLATFORM_LIB_DAI_H__ + +#define DMAMUX2_SAI5_RX_NUM 69 +#define DMAMUX2_SAI5_TX_NUM 70 +#define DMAMUX2_SAI6_RX_NUM 71 +#define DMAMUX2_SAI6_TX_NUM 72 +#define DMAMUX2_SAI7_RX_NUM 73 +#define DMAMUX2_SAI7_TX_NUM 74 + +#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/imx8ulp/include/platform/lib/dma.h b/src/platform/imx8ulp/include/platform/lib/dma.h new file mode 100644 index 000000000000..0634be796652 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/lib/dma.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2021 NXP + * + * Author: Peng Zhang + */ + +#ifdef __SOF_LIB_DMA_H__ + +#ifndef __PLATFORM_LIB_DMA_H__ +#define __PLATFORM_LIB_DMA_H__ + +#define PLATFORM_NUM_DMACS 3 + +/* max number of supported DMA channels */ +#define PLATFORM_MAX_DMA_CHAN 32 + +#define DMA_ID_EDMA2 0 +#define DMA_ID_HOST 1 + +#define dma_chan_irq(dma, chan) \ + (((int *)dma->plat_data.drv_plat_data)[chan]) +#define dma_chan_irq_name(dma, chan) NULL + +#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/imx8ulp/include/platform/lib/mailbox.h b/src/platform/imx8ulp/include/platform/lib/mailbox.h new file mode 100644 index 000000000000..eab792648731 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/lib/mailbox.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2021 NXP + * + * Author: Peng Zhang + */ + +#ifdef __SOF_LIB_MAILBOX_H__ + +#ifndef __PLATFORM_LIB_MAILBOX_H__ +#define __PLATFORM_LIB_MAILBOX_H__ + +#include +#include +#include + +/* + * The Window Region on i.MX8 SRAM is organised like this :- + * +--------------------------------------------------------------------------+ + * | Offset | Region | Size | + * +---------------------+----------------+-----------------------------------+ + * | SRAM_TRACE_BASE | Trace Buffer | SRAM_TRACE_SIZE | + * +---------------------+----------------+-----------------------------------+ + * | SRAM_DEBUG_BASE | Debug data | SRAM_DEBUG_SIZE | + * +---------------------+----------------+-----------------------------------+ + * | SRAM_INBOX_BASE | Inbox | SRAM_INBOX_SIZE | + * +---------------------+----------------+-----------------------------------+ + * | SRAM_OUTBOX_BASE | Outbox | SRAM_MAILBOX_SIZE | + * +---------------------+----------------+-----------------------------------+ + */ + +#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/imx8ulp/include/platform/lib/memory.h b/src/platform/imx8ulp/include/platform/lib/memory.h new file mode 100644 index 000000000000..d5bc1af82fe5 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/lib/memory.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2021 NXP + * + */ + +#ifdef __SOF_LIB_MEMORY_H__ + +#ifndef __PLATFORM_LIB_MEMORY_H__ +#define __PLATFORM_LIB_MEMORY_H__ + +#include + + +/* data cache line alignment */ +#define PLATFORM_DCACHE_ALIGN sizeof(void *) + +/* physical DSP addresses */ + +#define IRAM_BASE 0x21170000 +#define IRAM_SIZE 0x10000 + +#define DRAM0_BASE 0x21180000 +#define DRAM0_SIZE 0x10000 + +#define SDRAM0_BASE 0x1a000000 +#define SDRAM0_SIZE 0x800000 + +#define SDRAM1_BASE 0x1a800000 +#define SDRAM1_SIZE 0x800000 + +/* MU3: ASide (A35) BSide (HIFI4) */ +#define XSHAL_MU3_SIDEB_BYPASS_PADDR 0x2DA20000 +#define MU_BASE XSHAL_MU3_SIDEB_BYPASS_PADDR + +#define EDMA2_BASE 0x2D810000 +#define EDMA2_SIZE 0x10000 + +#define SAI_5_BASE 0x29890000 +#define SAI_5_SIZE 0x00010000 +#define SAI_6_BASE 0x2DA90000 +#define SAI_6_SIZE 0x00010000 +#define SAI_7_BASE 0x2DAA0000 +#define SAI_7_SIZE 0x00010000 + +#define UUID_ENTRY_ELF_BASE 0x1FFFA000 +#define UUID_ENTRY_ELF_SIZE 0x6000 + +#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 + +/* + * The Heap and Stack on i.MX8 are organised like this :- + * + * +--------------------------------------------------------------------------+ + * | Offset | Region | Size | + * +---------------------+----------------+-----------------------------------+ + * | SDRAM_BASE | RO Data | SOF_DATA_SIZE | + * | | Data | | + * | | BSS | | + * +---------------------+----------------+-----------------------------------+ + * | HEAP_SYSTEM_BASE | System Heap | HEAP_SYSTEM_SIZE | + * +---------------------+----------------+-----------------------------------+ + * | HEAP_RUNTIME_BASE | Runtime Heap | HEAP_RUNTIME_SIZE | + * +---------------------+----------------+-----------------------------------+ + * | HEAP_BUFFER_BASE | Module Buffers | HEAP_BUFFER_SIZE | + * +---------------------+----------------+-----------------------------------+ + * | SOF_STACK_END | Stack | SOF_STACK_SIZE | + * +---------------------+----------------+-----------------------------------+ + * | SOF_STACK_BASE | | | + * +---------------------+----------------+-----------------------------------+ + */ + +/* Mailbox configuration */ +#define SRAM_OUTBOX_BASE SDRAM1_BASE +#define SRAM_OUTBOX_SIZE 0x1000 +#define SRAM_OUTBOX_OFFSET 0 + +#define SRAM_INBOX_BASE (SRAM_OUTBOX_BASE + SRAM_OUTBOX_SIZE) +#define SRAM_INBOX_SIZE 0x1000 +#define SRAM_INBOX_OFFSET SRAM_OUTBOX_SIZE + +#define SRAM_DEBUG_BASE (SRAM_INBOX_BASE + SRAM_INBOX_SIZE) +#define SRAM_DEBUG_SIZE 0x2800 +#define SRAM_DEBUG_OFFSET (SRAM_INBOX_OFFSET + SRAM_INBOX_SIZE) + +#define SRAM_EXCEPT_BASE (SRAM_DEBUG_BASE + SRAM_DEBUG_SIZE) +#define SRAM_EXCEPT_SIZE 0x800 +#define SRAM_EXCEPT_OFFSET (SRAM_DEBUG_OFFSET + SRAM_DEBUG_SIZE) + +#define SRAM_STREAM_BASE (SRAM_EXCEPT_BASE + SRAM_EXCEPT_SIZE) +#define SRAM_STREAM_SIZE 0x1000 +#define SRAM_STREAM_OFFSET (SRAM_EXCEPT_OFFSET + SRAM_EXCEPT_SIZE) + +#define SRAM_TRACE_BASE (SRAM_STREAM_BASE + SRAM_STREAM_SIZE) +#define SRAM_TRACE_SIZE 0x1000 +#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 32 +#define HEAP_RT_COUNT256 32 +#define HEAP_RT_COUNT512 4 +#define HEAP_RT_COUNT1024 4 +#define HEAP_RT_COUNT2048 4 + +/* Heap section sizes for system runtime heap */ +#define HEAP_SYS_RT_COUNT64 128 +#define HEAP_SYS_RT_COUNT512 16 +#define HEAP_SYS_RT_COUNT1024 8 + +/* Heap configuration */ + +#define HEAP_SYSTEM_BASE SDRAM1_BASE + SOF_MAILBOX_SIZE +#define HEAP_SYSTEM_SIZE 0xe000 + +#define HEAP_SYSTEM_0_BASE HEAP_SYSTEM_BASE + +#define HEAP_SYS_RUNTIME_BASE (HEAP_SYSTEM_BASE + HEAP_SYSTEM_SIZE) +#define HEAP_SYS_RUNTIME_SIZE \ + (HEAP_SYS_RT_COUNT64 * 64 + HEAP_SYS_RT_COUNT512 * 512 + \ + HEAP_SYS_RT_COUNT1024 * 1024) + +#define HEAP_RUNTIME_BASE (HEAP_SYS_RUNTIME_BASE + HEAP_SYS_RUNTIME_SIZE) +#define HEAP_RUNTIME_SIZE \ + (HEAP_RT_COUNT8 * 8 + HEAP_RT_COUNT16 * 16 + \ + HEAP_RT_COUNT32 * 32 + HEAP_RT_COUNT64 * 64 + \ + HEAP_RT_COUNT128 * 128 + HEAP_RT_COUNT256 * 256 + \ + HEAP_RT_COUNT512 * 512 + HEAP_RT_COUNT1024 * 1024 + \ + HEAP_RT_COUNT2048 * 2048) + +#define HEAP_BUFFER_BASE (HEAP_RUNTIME_BASE + HEAP_RUNTIME_SIZE) +#define HEAP_BUFFER_SIZE \ + (SDRAM1_SIZE - SOF_MAILBOX_SIZE - HEAP_RUNTIME_SIZE - SOF_STACK_TOTAL_SIZE -\ + HEAP_SYS_RUNTIME_SIZE - HEAP_SYSTEM_SIZE) + +#define HEAP_BUFFER_BLOCK_SIZE 0x100 +#define HEAP_BUFFER_COUNT (HEAP_BUFFER_SIZE / HEAP_BUFFER_BLOCK_SIZE) + +#define PLATFORM_HEAP_SYSTEM 1 /* one per core */ +#define PLATFORM_HEAP_SYSTEM_RUNTIME 1 /* one per core */ +#define PLATFORM_HEAP_RUNTIME 1 +#define PLATFORM_HEAP_BUFFER 1 + +/* Stack configuration */ +#define SOF_STACK_SIZE 0x1000 +#define SOF_STACK_TOTAL_SIZE SOF_STACK_SIZE +#define SOF_STACK_BASE (SDRAM1_BASE + SDRAM1_SIZE) +#define SOF_STACK_END (SOF_STACK_BASE - SOF_STACK_TOTAL_SIZE) + +/* Vector and literal sizes - not in core-isa.h */ +#define SOF_MEM_VECT_LIT_SIZE 0x4 +#define SOF_MEM_VECT_TEXT_SIZE 0x1c +#define SOF_MEM_VECT_SIZE (SOF_MEM_VECT_TEXT_SIZE + SOF_MEM_VECT_LIT_SIZE) + +#define SOF_MEM_RESET_TEXT_SIZE 0x2e0 +#define SOF_MEM_RESET_LIT_SIZE 0x120 +#define SOF_MEM_VECBASE_LIT_SIZE 0x178 + +#define SOF_MEM_RO_SIZE 0x8 + +#define HEAP_BUF_ALIGNMENT DCACHE_LINE_SIZE + +/** \brief EDF task's default stack size in bytes. */ +#define PLATFORM_TASK_DEFAULT_STACK_SIZE 3072 + +#if !defined(__ASSEMBLER__) && !defined(LINKER) + +struct sof; + +/** + * \brief Data shared between different cores. + * Does nothing, since IMX doesn't support SMP. + */ +#define SHARED_DATA + +void platform_init_memmap(struct sof *sof); + +static inline void *platform_shared_get(void *ptr, int bytes) +{ + return ptr; +} + +/** + * \brief Function for keeping shared data synchronized. + * It's used after usage of data shared by different cores. + * Such data is either statically marked with SHARED_DATA + * or dynamically allocated with SOF_MEM_FLAG_SHARED flag. + * Does nothing, since IMX doesn't support SMP. + */ +static inline void platform_shared_commit(void *ptr, int bytes) { } + +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/imx8ulp/include/platform/lib/pm_runtime.h b/src/platform/imx8ulp/include/platform/lib/pm_runtime.h new file mode 100644 index 000000000000..f2b85b2e9d4e --- /dev/null +++ b/src/platform/imx8ulp/include/platform/lib/pm_runtime.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2019 NXP + * + * Author: Daniel Baluta + */ + +#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/imx8ulp/include/platform/platform.h b/src/platform/imx8ulp/include/platform/platform.h new file mode 100644 index 000000000000..0a40c2f0fc88 --- /dev/null +++ b/src/platform/imx8ulp/include/platform/platform.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2019 NXP + * + * Author: Daniel Baluta + */ + +#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) +#define LPSRAM_SIZE 16384 + +/* IPC Interrupt */ +#define PLATFORM_IPC_INTERRUPT IRQ_NUM_MU3 +#define PLATFORM_IPC_INTERRUPT_NAME NULL + +/* Host page size */ +#define HOST_PAGE_SIZE 4096 +#define PLATFORM_PAGE_TABLE_SIZE 256 + +/* 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 HOST_PAGE_SIZE + +/* 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 + +#define SRAM_REG_FW_STATUS 0x4 + +/* Platform defined panic code */ +static inline void platform_panic(uint32_t p) +{ + /* Store the error code in the debug box so the + * application processor can pick it up. Takes up 4 bytes + * from the debug box. + */ + mailbox_sw_reg_write(SRAM_REG_FW_STATUS, p); + + /* Notify application processor */ + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1), 0); +} + +/** + * \brief Platform specific CPU entering idle. + * May be power-optimized using platform specific capabilities. + * @param level Interrupt level. + */ +static inline void platform_wait_for_interrupt(int level) +{ + arch_wait_for_interrupt(level); +} + +extern intptr_t _module_init_start; +extern intptr_t _module_init_end; +#endif + +#endif /* __PLATFORM_PLATFORM_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/platform.h" + +#endif /* __SOF_PLATFORM_H__ */ diff --git a/src/platform/imx8ulp/include/platform/trace/trace.h b/src/platform/imx8ulp/include/platform/trace/trace.h new file mode 100644 index 000000000000..fe02bb4656ee --- /dev/null +++ b/src/platform/imx8ulp/include/platform/trace/trace.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +#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/imx8ulp/lib/CMakeLists.txt b/src/platform/imx8ulp/lib/CMakeLists.txt new file mode 100644 index 000000000000..271a099cc6a9 --- /dev/null +++ b/src/platform/imx8ulp/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/imx8ulp/lib/clk.c b/src/platform/imx8ulp/lib/clk.c new file mode 100644 index 000000000000..6a2f4773e643 --- /dev/null +++ b/src/platform/imx8ulp/lib/clk.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2019 Intel Corporation. All rights reserved. +// +// Author: Tomasz Lauda +// Janusz Jankowski + +#include +#include +#include +#include +#include +#include +#include + +const struct freq_table platform_cpu_freq[] = { +#ifdef CONFIG_IMX8 + { 666000000, 666000 }, +#else /* CONFIG_IMX8X */ + { 640000000, 640000 }, +#endif +}; + +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]; + +void platform_clock_init(struct sof *sof) +{ + int i; + + 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, + }; + + spinlock_init(&sof->clocks[i].lock); + } + + platform_shared_commit(sof->clocks, sizeof(*sof->clocks) * NUM_CLOCKS); +} diff --git a/src/platform/imx8ulp/lib/dai.c b/src/platform/imx8ulp/lib/dai.c new file mode 100644 index 000000000000..361b144a0e48 --- /dev/null +++ b/src/platform/imx8ulp/lib/dai.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2019 NXP +// +// Author: Daniel Baluta + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static SHARED_DATA struct dai sai[] = { +{ + .index = 5, + .plat_data = { + .base = SAI_5_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = SAI_5_BASE + REG_SAI_TDR0, + /* use depth to model the HW FIFO size: + * each channel includes a 64 x 32 bit FIFO + * that can be accessed using Transmit or + * Receive Data Registers + */ + .depth = 64, /* in 4 bytes words */ + .handshake = EDMA_HANDSHAKE(EDMA2_CHAN0_IRQ, + EDMA2_CHAN0), + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = SAI_5_BASE + REG_SAI_RDR0, + .depth = 64, /* in 4 bytes words */ + .handshake = EDMA_HANDSHAKE(EDMA2_CHAN1_IRQ, + EDMA2_CHAN1), + }, + .dmamux_rx_num = DMAMUX2_SAI5_RX_NUM, + .dmamux_tx_num = DMAMUX2_SAI5_TX_NUM, + }, + .drv = &sai_driver, +}, +}; + +const struct dai_type_info dti[] = { + { + .type = SOF_DAI_IMX_SAI, + .dai_array = sai, + .num_dais = ARRAY_SIZE(sai) + }, +}; + +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(sai); i++) + spinlock_init(&sai[i].lock); + + platform_shared_commit(sai, sizeof(*sai)); + + sof->dai_info = &lib_dai; + + return 0; +} diff --git a/src/platform/imx8ulp/lib/dma.c b/src/platform/imx8ulp/lib/dma.c new file mode 100644 index 000000000000..d804947b6a5e --- /dev/null +++ b/src/platform/imx8ulp/lib/dma.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2021 NXP +// +// Author: Peng Zhang + +#include +#include +#include +#include +#include +#include +#include + +extern struct dma_ops dummy_dma_ops; +extern struct dma_ops edma_ops; + +const int edma2_ints[EDMA2_CHAN_MAX] = { + [EDMA2_CHAN0] = EDMA2_CHAN0_IRQ, + [EDMA2_CHAN1] = EDMA2_CHAN1_IRQ, +}; + +SHARED_DATA struct dma dma[PLATFORM_NUM_DMACS] = { +{ + .plat_data = { + .id = DMA_ID_EDMA2, + .dir = DMA_DIR_MEM_TO_DEV | DMA_DIR_DEV_TO_MEM, + .devs = DMA_DEV_SAI, + .base = EDMA2_BASE, + .chan_size = EDMA2_SIZE, + .channels = 8, + .drv_plat_data = edma2_ints, + }, + .ops = &edma_ops, +}, +{ + .plat_data = { + .id = DMA_ID_HOST, + .dir = DMA_DIR_HMEM_TO_LMEM | DMA_DIR_LMEM_TO_HMEM, + .devs = DMA_DEV_HOST, + .channels = 16, + }, + .ops = &dummy_dma_ops, +}, +}; + +const struct dma_info lib_dma = { + .dma_array = dma, + .num_dmas = ARRAY_SIZE(dma) +}; + +int dmac_init(struct sof *sof) +{ + int i; + + /* early lock initialization for ref counting */ + for (i = 0; i < ARRAY_SIZE(dma); i++) + spinlock_init(&dma[i].lock); + + platform_shared_commit(dma, sizeof(*dma)); + + sof->dma_info = &lib_dma; + + return 0; +} diff --git a/src/platform/imx8ulp/lib/memory.c b/src/platform/imx8ulp/lib/memory.c new file mode 100644 index 000000000000..57a434b4ba20 --- /dev/null +++ b/src/platform/imx8ulp/lib/memory.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2019 NXP +// +// Author: Daniel Baluta + +#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_CACHE | + 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_CACHE | + 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_CACHE | + 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_CACHE | + SOF_MEM_CAPS_DMA, + }, + .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/imx8ulp/platform.c b/src/platform/imx8ulp/platform.c new file mode 100644 index 000000000000..811468ae2021 --- /dev/null +++ b/src/platform/imx8ulp/platform.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2019 NXP +// +// Author: Daniel Baluta + +#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 + __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, + .src_hash = SOF_SRC_HASH, + }, + .flags = DEBUG_SET_FW_READY_FLAGS, +}; + +#define NUM_IMX_WINDOWS 6 + +const struct ext_man_windows xsram_window + __aligned(EXT_MAN_ALIGN) __section(".fw_metadata") __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_IMX_WINDOWS, + .window = { + { + .type = SOF_IPC_REGION_UPBOX, + .id = 0, /* map to host window 0 */ + .flags = 0, // TODO: set later + .size = MAILBOX_DSPBOX_SIZE, + .offset = MAILBOX_DSPBOX_OFFSET, + }, + { + .type = SOF_IPC_REGION_DOWNBOX, + .id = 0, /* map to host window 0 */ + .flags = 0, // TODO: set later + .size = MAILBOX_HOSTBOX_SIZE, + .offset = MAILBOX_HOSTBOX_OFFSET, + }, + { + .type = SOF_IPC_REGION_DEBUG, + .id = 0, /* map to host window 0 */ + .flags = 0, // TODO: set later + .size = MAILBOX_DEBUG_SIZE, + .offset = MAILBOX_DEBUG_OFFSET, + }, + { + .type = SOF_IPC_REGION_TRACE, + .id = 0, /* map to host window 0 */ + .flags = 0, // TODO: set later + .size = MAILBOX_TRACE_SIZE, + .offset = MAILBOX_TRACE_OFFSET, + }, + { + .type = SOF_IPC_REGION_STREAM, + .id = 0, /* map to host window 0 */ + .flags = 0, // TODO: set later + .size = MAILBOX_STREAM_SIZE, + .offset = MAILBOX_STREAM_OFFSET, + }, + { + .type = SOF_IPC_REGION_EXCEPTION, + .id = 0, /* map to host window 0 */ + .flags = 0, // TODO: set later + .size = MAILBOX_EXCEPTION_SIZE, + .offset = MAILBOX_EXCEPTION_OFFSET, + }, + }, + } +}; + +SHARED_DATA struct timer timer = { + .id = TIMER0, /* internal timer */ + .irq = IRQ_NUM_TIMER0, +}; + +int platform_boot_complete(uint32_t boot_message) +{ + mailbox_dspbox_write(0, &ready, sizeof(ready)); + + /* now interrupt host to tell it we are done booting */ + imx_mu_xcr_rmw(IMX_MU_VERSION, IMX_MU_GCR, IMX_MU_xCR_GIRn(IMX_MU_VERSION, 1), 0); + + /* boot now complete so we can relax the CPU */ + /* For now skip this to gain more processing performance + * for SRC component. + */ + /* clock_set_freq(CLK_CPU, CLK_DEFAULT_CPU_HZ); */ + + return 0; +} + +int platform_init(struct sof *sof) +{ + int ret; + + sof->platform_timer = &timer; + sof->cpu_timers = &timer; + + platform_interrupt_init(); + platform_clock_init(sof); + scheduler_init_edf(); + + /* init low latency domains and schedulers */ + 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); + sa_init(sof, CONFIG_SYSTICK_PERIOD); + + clock_set_freq(CLK_CPU(cpu_get_id()), CLK_MAX_CPU_HZ); + + /* init DMA */ + ret = dmac_init(sof); + if (ret < 0) + return -ENODEV; + + /* Init EDMA platform domain */ + sof->platform_dma_domain = dma_multi_chan_domain_init + (&sof->dma_info->dma_array[0], 1, + PLATFORM_DEFAULT_CLOCK, false); + + /* i.MX platform DMA domain will be full synchronous, no time dependent */ + sof->platform_dma_domain->full_sync = true; + scheduler_init_ll(sof->platform_dma_domain); + + /* initialize the host IPC mechanims */ + ipc_init(sof); + + ret = dai_init(sof); + if (ret < 0) + return -ENODEV; + +#if CONFIG_TRACE + /* Initialize DMA for Trace*/ + trace_point(TRACE_BOOT_PLATFORM_DMA_TRACE); + dma_trace_init_complete(sof->dmat); +#endif + + /* show heap status */ + heap_trace_all(1); + + return 0; +} diff --git a/src/probe/probe.c b/src/probe/probe.c index 2eb1261bb2a3..c375369c5cf0 100644 --- a/src/probe/probe.c +++ b/src/probe/probe.c @@ -142,6 +142,7 @@ static int probe_dma_init(struct probe_dma_ext *dma, uint32_t direction) if (err < 0) return err; + tr_info(&pr_tr, "probe_dma_init, elem_addr %x", elem_addr); elem_addr = (uint32_t)dma->dmapb.addr; config.direction = direction; diff --git a/src/schedule/dma_multi_chan_domain.c b/src/schedule/dma_multi_chan_domain.c index 0ee88d3234f4..9c126e26d0ac 100644 --- a/src/schedule/dma_multi_chan_domain.c +++ b/src/schedule/dma_multi_chan_domain.c @@ -53,6 +53,7 @@ static void dma_multi_chan_domain_irq_handler(void *data) { struct dma_domain_data *domain_data = data; + //tr_info(&ll_tr, "dma_multi_chan_domain_irq_handler()"); /* just call registered handler */ domain_data->handler(domain_data->arg); diff --git a/src/schedule/edf_schedule.c b/src/schedule/edf_schedule.c index 5164b6b0f523..9f25abaa8a27 100644 --- a/src/schedule/edf_schedule.c +++ b/src/schedule/edf_schedule.c @@ -43,6 +43,7 @@ static void schedule_edf(void *data); static void schedule_edf_task_run(struct task *task, void *data) { + //tr_info(&edf_tr, "schedule_edf_task_run"); while (1) { /* execute task run function and remove task from the list * only if completed @@ -65,7 +66,7 @@ static void edf_scheduler_run(void *data) uint64_t deadline; uint32_t flags; - tr_dbg(&edf_tr, "edf_scheduler_run()"); + //tr_info(&edf_tr, "edf_scheduler_run()"); irq_local_disable(flags); @@ -108,6 +109,7 @@ static int schedule_edf_task(void *data, struct task *task, uint64_t start, (void) period; /* not used */ (void) start; /* not used */ + //tr_info(&edf_tr, "scheduler_edf_task()"); irq_local_disable(flags); /* not enough MCPS to complete */ @@ -128,6 +130,7 @@ static int schedule_edf_task(void *data, struct task *task, uint64_t start, schedule_edf(data); + //tr_info(&edf_tr, "return scheduler_edf_task()"); return 0; } @@ -138,6 +141,7 @@ int schedule_task_init_edf(struct task *task, const struct sof_uuid_entry *uid, struct edf_task_pdata *edf_pdata = NULL; int ret = 0; + //tr_info(&edf_tr, "schedule_task_init_edf()"); ret = schedule_task_init(task, uid, SOF_SCHEDULE_EDF, 0, ops->run, data, core, flags); if (ret < 0) @@ -185,7 +189,7 @@ static int schedule_edf_task_running(void *data, struct task *task) struct edf_task_pdata *edf_pdata = edf_sch_get_pdata(task); uint32_t flags; - tr_dbg(&edf_tr, "schedule_edf_task_running()"); + //tr_info(&edf_tr, "schedule_edf_task_running()"); irq_local_disable(flags); @@ -201,7 +205,7 @@ static int schedule_edf_task_complete(void *data, struct task *task) { uint32_t flags; - tr_dbg(&edf_tr, "schedule_edf_task_complete()"); + //tr_info(&edf_tr, "schedule_edf_task_complete()"); irq_local_disable(flags); @@ -219,7 +223,7 @@ static int schedule_edf_task_cancel(void *data, struct task *task) { uint32_t flags; - tr_dbg(&edf_tr, "schedule_edf_task_cancel()"); + //tr_info(&edf_tr, "schedule_edf_task_cancel()"); irq_local_disable(flags); @@ -239,6 +243,7 @@ static int schedule_edf_task_free(void *data, struct task *task) struct edf_task_pdata *edf_pdata = edf_sch_get_pdata(task); uint32_t flags; + //tr_info(&edf_tr, "schedule_edf_task_free"); irq_local_disable(flags); task->state = SOF_TASK_STATE_FREE; @@ -257,7 +262,7 @@ int scheduler_init_edf(void) { struct edf_schedule_data *edf_sch; - tr_info(&edf_tr, "edf_scheduler_init()"); + //tr_info(&edf_tr, "edf_scheduler_init()"); edf_sch = rzalloc(SOF_MEM_ZONE_SYS, 0, SOF_MEM_CAPS_RAM, sizeof(*edf_sch)); @@ -285,6 +290,7 @@ static void scheduler_free_edf(void *data) { struct edf_schedule_data *edf_sch = data; uint32_t flags; + //tr_info(&edf_tr, "scheduler_free_edf"); irq_local_disable(flags); @@ -302,6 +308,7 @@ static void scheduler_free_edf(void *data) static void schedule_edf(void *data) { + //tr_info(&edf_tr, "schedule_edf()"); struct edf_schedule_data *edf_sch = data; interrupt_set(edf_sch->irq); diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index ac72a810ef90..30c73530ae94 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -109,7 +109,7 @@ static void schedule_ll_tasks_execute(struct ll_schedule_data *sch) if (task->state != SOF_TASK_STATE_PENDING) continue; - tr_dbg(&ll_tr, "task %p %pU being started...", task, task->uid); + //tr_info(&ll_tr, "task %p %pU being started...", task, task->uid); task->state = task_run(task); @@ -159,7 +159,8 @@ static void schedule_ll_clients_reschedule(struct ll_schedule_data *sch) { struct list_item *wlist; struct list_item *tlist; - struct task *task, *task_take; + struct task *task; + struct task *task_take_dbg = NULL; uint64_t next_tick = UINT64_MAX; /* rearm only if there is work to do */ @@ -171,12 +172,13 @@ static void schedule_ll_clients_reschedule(struct ll_schedule_data *sch) /* update to use the earlier tick */ if (task->start < next_tick) { next_tick = task->start; - task_take = task; + task_take_dbg = task; } } - tr_dbg(&ll_tr, "schedule_ll_clients_reschedule next_tick %u task_take %p", - (unsigned int)next_tick, task_take); + tr_dbg(&ll_tr, + "schedule_ll_clients_reschedule next_tick %u task_take %p", + (unsigned int)next_tick, task_take_dbg); domain_set(sch->domain, next_tick); } diff --git a/src/schedule/task.c b/src/schedule/task.c index cee068f049ac..fd538bab378e 100644 --- a/src/schedule/task.c +++ b/src/schedule/task.c @@ -39,6 +39,8 @@ typedef enum task_state (*task_main)(void *); DECLARE_SOF_UUID("main-task", main_task_uuid, 0x37f1d41f, 0x252d, 0x448d, 0xb9, 0xc4, 0x1e, 0x2b, 0xee, 0x8e, 0x1b, 0xf1); +DECLARE_TR_CTX(main_tr, SOF_UUID(main_task_uuid), LOG_LEVEL_INFO); + static void sys_module_init(void) { intptr_t *module_init = (intptr_t *)(&_module_init_start); @@ -55,12 +57,16 @@ static uint64_t task_main_deadline(void *data) enum task_state task_main_primary_core(void *data) { struct ipc *ipc = ipc_get(); - + int val; /* main audio processing loop */ while (1) { + //tr_err(&main_tr, "task_main_primary_core, pm D3 %d", ipc->pm_prepare_D3); /* sleep until next IPC or DMA */ wait_for_interrupt(0); + + val = imx_mu_read(IMX_MU_xCR(IMX_MU_VERSION, IMX_MU_GCR)); + tr_info(&main_tr, "task main IMX GCR %x", val); if (!ipc->pm_prepare_D3) ipc_send_queued_msg(); @@ -75,6 +81,7 @@ void task_main_init(void) struct task **main_task = task_main_get(); int cpu = cpu_get_id(); int ret; + //tr_err(&main_tr, "task_main_init"); task_main main_main = cpu == PLATFORM_PRIMARY_CORE_ID ? &task_main_primary_core : &task_main_secondary_core; struct task_ops ops = { @@ -92,6 +99,7 @@ void task_main_init(void) void task_main_free(void) { + //tr_err(&main_tr, "task_main_free"); schedule_task_free(*task_main_get()); } @@ -119,8 +127,11 @@ int task_main_start(struct sof *sof) if (ret < 0) return ret; + /* 8ulp can run at here */ /* task initialized in edf_scheduler_init */ - schedule_task(*task_main_get(), 0, UINT64_MAX); + tr_err(&main_tr, "start main task..."); + ret = schedule_task(*task_main_get(), 0, UINT64_MAX); + tr_err(&main_tr, "start main task end..."); /* something bad happened */ return -EIO; diff --git a/src/trace/dma-trace.c b/src/trace/dma-trace.c index 8c2690ac29b0..bc377a8ddbea 100644 --- a/src/trace/dma-trace.c +++ b/src/trace/dma-trace.c @@ -80,6 +80,7 @@ static enum task_state trace_work(void *data) /* DMA trace copying is working */ d->copy_in_progress = 1; + //tr_info(&dt_tr, "trace_work(): dma_copy_to_host_nowait, host off %d", d->posn.host_offset); /* copy this section to host */ size = dma_copy_to_host_nowait(&d->dc, config, d->posn.host_offset, buffer->r_ptr, size); @@ -254,6 +255,7 @@ static int dma_trace_start(struct dma_trace_data *d) config.dest_width = sizeof(uint32_t); config.cyclic = 0; + tr_info(&dt_tr, "dma_trace_start()"); err = dma_sg_alloc(&config.elem_array, SOF_MEM_ZONE_SYS, config.direction, elem_num, elem_size, elem_addr, 0); diff --git a/tools/topology/CMakeLists.txt b/tools/topology/CMakeLists.txt index cce80a38dcd9..920e818d849b 100644 --- a/tools/topology/CMakeLists.txt +++ b/tools/topology/CMakeLists.txt @@ -129,6 +129,7 @@ set(TPLGS "sof-jsl-da7219\;sof-jsl-da7219\;-DPLATFORM=jsl" "sof-jsl-da7219\;sof-jsl-da7219-mx98360a\;-DPLATFORM=jsl-dedede" "sof-imx8mp-wm8960\;sof-imx8mp-wm8960" + "sof-imx8ulp-wm8960\;sof-imx8ulp-wm8960" "sof-smart-amplifier-nocodec\;sof-smart-amplifier-nocodec" "sof-jsl-rt5682\;sof-jsl-rt5682-rt1015\;-DPLATFORM=jsl-rt1015" "sof-jsl-rt5682\;sof-jsl-rt5682-mx98360a\;-DPLATFORM=jsl-dedede" diff --git a/tools/topology/sof-imx8ulp-wm8960.m4 b/tools/topology/sof-imx8ulp-wm8960.m4 new file mode 100644 index 000000000000..dc9891bb6d3b --- /dev/null +++ b/tools/topology/sof-imx8ulp-wm8960.m4 @@ -0,0 +1,82 @@ +# +# Topology for i.MX8ULP board with wm8960 codec +# + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`sai.m4') +include(`pcm.m4') +include(`buffer.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include DSP configuration +include(`platform/imx/imx8qxp.m4') + +# +# Define the pipelines +# +# PCM0 <----> volume <-----> SAI5 (connect to BT) +# + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate, +dnl time_domain, sched_comp) + +# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s32le. +# Set 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, + 1, 0, 2, s32le, + 1000, 0, 0, + 48000, 48000, 48000) + +# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s32le. +# Set 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, + 2, 0, 2, s32le, + 1000, 0, 0, + 48000, 48000, 48000) +# +# DAIs configuration +# + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl period, priority, core, time_domain) + +# playback DAI is SAI6 using 2 periods +# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-playback.m4, + 1, SAI, 5, sai5-bt-sco-pcm-wb, + PIPELINE_SOURCE_1, 2, s32le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +# capture DAI is SAI6 using 2 periods +# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-capture.m4, + 2, SAI, 5, sai5-bt-sco-pcm-wb, + PIPELINE_SINK_2, 2, s32le, + 1000, 0, 0) + + +# PCM Low Latency, id 0 + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) +PCM_DUPLEX_ADD(Port0, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) + +dnl DAI_CONFIG(type, idx, link_id, name, sai_config) +DAI_CONFIG(SAI, 5, 0, sai5-bt-sco-pcm-wb, + SAI_CONFIG(I2S, SAI_CLOCK(mclk, 12288000, codec_mclk_out), + SAI_CLOCK(bclk, 3072000, codec_slave), + SAI_CLOCK(fsync, 48000, codec_slave), + SAI_TDM(2, 32, 3, 3), + SAI_CONFIG_DATA(SAI, 5, 0)))