Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion scripts/xtensa-build-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set -e
# Platforms with a toolchain available in the latest Docker image and
# built by the -a option.
DEFAULT_PLATFORMS=( byt cht bdw hsw apl skl kbl cnl sue icl jsl \
imx8 imx8x imx8m imx8ulp tgl tgl-h rn mt8195 )
imx8 imx8x imx8m imx8ulp tgl tgl-h rn mt8186 mt8195 )
Comment thread
tinghan-shen marked this conversation as resolved.
Outdated

# Work in progress can be added to this "staging area" without breaking
# the -a option for everyone.
Expand Down Expand Up @@ -335,6 +335,12 @@ do
HOST="xtensa-rn-elf"
XTENSA_TOOLS_VERSION="RF-2016.4-linux"
;;
mt8186)
PLATFORM="mt8186"
XTENSA_CORE="hifi5_7stg_I64D128"
HOST="xtensa-mt8186-elf"
XTENSA_TOOLS_VERSION="RI-2020.5-linux"
;;
mt8195)
PLATFORM="mt8195"
XTENSA_CORE="hifi4_8195_PROD"
Expand Down
4 changes: 3 additions & 1 deletion src/arch/xtensa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ elseif(CONFIG_IMX8M)
set(platform_folder imx8m)
elseif(CONFIG_IMX8ULP)
set(platform_folder imx8ulp)
elseif(CONFIG_MT8186)
set(platform_folder mt8186)
elseif(CONFIG_MT8195)
set(platform_folder mt8195)
endif()
Expand Down Expand Up @@ -542,7 +544,7 @@ list(APPEND UNSIGNED_RI imx8 imx8x imx8m imx8ulp)
# AMD
list(APPEND UNSIGNED_RI rn)
# Mediatek
list(APPEND UNSIGNED_RI mt8195)
list(APPEND UNSIGNED_RI mt8186 mt8195)

# Signed and non-deterministic but sof_ri_info.py is not compatible with
# manifest v1.5? "CSE manifest magic number not found"
Expand Down
17 changes: 17 additions & 0 deletions src/arch/xtensa/configs/mt8186_defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CONFIG_MT8186=y
CONFIG_CORE_COUNT=1
CONFIG_XT_VIRTUAL_OPS=1
CONFIG_COMP_VOLUME=y
CONFIG_COMP_SRC=n
Comment thread
cujomalainey marked this conversation as resolved.
Outdated
CONFIG_COMP_FIR=n
CONFIG_COMP_IIR=n
CONFIG_COMP_DCBLOCK=n
CONFIG_COMP_TDFB=n
CONFIG_COMP_TONE=n
CONFIG_COMP_MIXER=n
CONFIG_COMP_MUX=n
CONFIG_COMP_SWITCH=n
CONFIG_COMP_KPB=n
CONFIG_COMP_SEL=n
CONFIG_COMP_ASRC=n

3 changes: 3 additions & 0 deletions src/drivers/mediatek/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
if(CONFIG_MT8195)
add_subdirectory(mt8195)
endif()
if(CONFIG_MT8186)
add_subdirectory(mt8186)
endif()
4 changes: 4 additions & 0 deletions src/drivers/mediatek/mt8186/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: BSD-3-Clause

add_local_sources(sof interrupt.c ipc.c timer.c)

227 changes: 227 additions & 0 deletions src/drivers/mediatek/mt8186/interrupt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2022 Mediatek. All rights reserved.
//
// Author: Allen-KH Cheng <allen-kh.cheng@mediatek.com>
// Tinghan Shen <tinghan.shen@mediatek.com>

#include <errno.h>
#include <inttypes.h>
#include <sof/bit.h>
#include <sof/common.h>
#include <sof/drivers/interrupt.h>
#include <sof/lib/cpu.h>
#include <sof/lib/io.h>
#include <sof/lib/memory.h>
#include <sof/lib/uuid.h>
#include <sof/list.h>
#include <sof/spinlock.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#define PENDING_IRQ_INDEX_MAX 32

/* d2e3f730-df39-42ee-81a8-39bfb4d024c2 */
DECLARE_SOF_UUID("irq-mt8186", irq_mt8186_uuid, 0xd2e3f730, 0xdf39, 0x42ee,
0x81, 0xa8, 0x39, 0xbf, 0xb4, 0xd0, 0x24, 0xc2);

DECLARE_TR_CTX(int_tr, SOF_UUID(irq_mt8186_uuid), LOG_LEVEL_INFO);

static void mtk_irq_init(void)
{
/* disable all ADSP IRQ */
io_reg_write(MTK_ADSP_IRQ_EN, 0);

/* mask all IRQs between ADSP and other subsys */
io_reg_write(MTK_ADSP_IRQ_MASK, MTK_DSP_OUT_IRQ_MASK);
}

static void mtk_irq_mask(struct irq_desc *desc, uint32_t irq, unsigned int core)
{
if (!desc) {
io_reg_update_bits(MTK_ADSP_IRQ_EN, BIT(irq), 0);
} else {
switch (desc->irq) {
case MTK_DSP_IRQ_MAILBOX:
io_reg_update_bits(MTK_ADSP_IRQ_EN, BIT(desc->irq), 0);
break;
default:
tr_err(&int_tr, "Invalid interrupt %d", desc->irq);
return;
}
}
}

static void mtk_irq_unmask(struct irq_desc *desc, uint32_t irq, unsigned int core)
{
if (!desc) {
io_reg_update_bits(MTK_ADSP_IRQ_EN, BIT(irq), BIT(irq));
} else {
switch (desc->irq) {
case MTK_DSP_IRQ_MAILBOX:
io_reg_update_bits(MTK_ADSP_IRQ_EN, BIT(desc->irq), BIT(desc->irq));
break;
default:
tr_err(&int_tr, "Invalid interrupt %d", desc->irq);
return;
}
}
}

static uint32_t mtk_irq_group_pending_status(uint32_t irq)
{
uint32_t irq_status = 0;

if (irq == MTK_DSP_IRQ_MAILBOX &&
(io_reg_read(MTK_ADSP_IRQ_STATUS) & BIT(MTK_DSP_IRQ_MAILBOX))) {
irq_status = io_reg_read(MTK_MBOX_IRQ_IN) & MTK_DSP_MBOX_MASK;
}

return irq_status;
}

static uint32_t mtk_get_pending_index(uint32_t current, uint32_t *next)
{
uint32_t index;
Comment thread
tinghan-shen marked this conversation as resolved.
Outdated

if (current == 0)
return PENDING_IRQ_INDEX_MAX;

/* ffs returns one plus the index of the least significant 1-bit of input int */
index = ffs(current) - 1;

/* remove the handling index from current pending status */
*next = current & ~(1ull << index);

return index;
}

static inline void mtk_handle_group_pending_irq(struct irq_cascade_desc *cascade,
uint32_t line_index, uint32_t status)
{
int core = cpu_get_id();
struct list_item *clist;
struct irq_desc *child = NULL;
uint32_t idx;
uint32_t next_status;
bool handled;

idx = mtk_get_pending_index(status, &next_status);
while (idx < PENDING_IRQ_INDEX_MAX) {
handled = false;

spin_lock(&cascade->lock);
list_for_item(clist, &cascade->child[idx].list) {
child = container_of(clist, struct irq_desc, irq_list);

if (child->handler && (child->cpu_mask & 1 << core)) {
child->handler(child->handler_arg);
handled = true;
}
}
spin_unlock(&cascade->lock);

if (!handled) {
tr_err(&int_tr, "Not handle irq %u in group %u",
idx, line_index);
}

idx = mtk_get_pending_index(next_status, &next_status);
}
}

static inline void mtk_irq_group_handler(void *data, uint32_t line_index)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious why this is all inline? if you add another call to your macro below it will duplicate all this code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting @lgirdwood this seems rather inflated, what are your thoughts here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, these could be optimized. Lets merge this first and get the build results as we could make the same change to all platforms. @tinghan-shen pls can you try this change and report any size changes to the binary. Thanks.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think NXP would see the biggest effect since they have multiple IRQs @dbaluta

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to build mt8186 on both gcc11 and xcc, and compare the size of sof.ri.
No difference on gcc11.
64 bytes larger on xcc after remove "inline".

{
struct irq_desc *parent = data;
struct irq_cascade_desc *cascade =
container_of(parent, struct irq_cascade_desc, desc);
uint32_t status;

status = mtk_irq_group_pending_status(line_index);
if (status)
mtk_handle_group_pending_irq(cascade, line_index, status);
else
tr_err(&int_tr, "No pending irq in group %d", line_index);
}

#define DEFINE_IRQ_HANDLER(n) \
static void irqhandler_##n(void *arg) \
{ \
mtk_irq_group_handler(arg, n); \
}

DEFINE_IRQ_HANDLER(2)

static const char mtk_irq_mailbox[] = "mtk_irq_mailbox";

static const struct irq_cascade_ops irq_ops = {
.mask = mtk_irq_mask,
.unmask = mtk_irq_unmask,
};

static const struct irq_cascade_tmpl dsp_irq[] = {
{
.name = mtk_irq_mailbox,
.irq = MTK_DSP_IRQ_MAILBOX,
.handler = irqhandler_2,
.ops = &irq_ops,
.global_mask = false,
},
};

int mtk_irq_group_id(uint32_t in_irq)
{
if (in_irq >= MTK_MAX_IRQ_NUM)
in_irq -= MTK_MAX_IRQ_NUM;

return interrupt_get_irq(in_irq, dsp_irq[0].name);
}

void platform_interrupt_init(void)
{
int i;

mtk_irq_init();
for (i = 0; i < ARRAY_SIZE(dsp_irq); i++)
interrupt_cascade_register(dsp_irq + i);
}

void platform_interrupt_set(uint32_t irq)
{
if (interrupt_is_dsp_direct(irq))
arch_interrupt_set(irq);
}

void platform_interrupt_clear(uint32_t irq, uint32_t mask)
{
if (interrupt_is_dsp_direct(irq))
arch_interrupt_clear(irq);
}

uint32_t platform_interrupt_get_enabled(void)
{
return 0;
}

void interrupt_mask(uint32_t irq, unsigned int cpu)
{
struct irq_cascade_desc *cascade = interrupt_get_parent(irq);

if (cascade && cascade->ops->mask)
cascade->ops->mask(&cascade->desc, irq - cascade->irq_base,
cpu);
else
mtk_irq_mask(NULL, irq, 0);
}

void interrupt_unmask(uint32_t irq, unsigned int cpu)
{
struct irq_cascade_desc *cascade = interrupt_get_parent(irq);

if (cascade && cascade->ops->unmask)
cascade->ops->unmask(&cascade->desc, irq - cascade->irq_base,
cpu);
else
mtk_irq_unmask(NULL, irq, 0);
}
Loading