From nobody Thu Oct 2 11:52:35 2025 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E0CA29AB13; Wed, 17 Sep 2025 07:54:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.61.82.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758095650; cv=none; b=F9n4pQwMu6HqT1iMCeeqO9N+ZrHhzoTaPjPs0mI3y8zN+Zfb9lVVGubcwyNBM87cW787NLQP8kUwqLq+MPV3mG3VljC8OvPrbhiRNwqVZphL3NGoTmueTcyWingUmOXi3lP6Pf3KN7/oZ/g5OEuB4Qk4WoVUZqjAPblTPZtqTvE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758095650; c=relaxed/simple; bh=uR/VCzBgggJ1b5EXwPk6rLimKDxU94OwJl6RwzVEuUs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WrbfX5ybScozvE0QuZcRMxIMyM6B/FEz8rBmk8XlLqDvCQRW4u9+pwdk/6rt9HawVSv8xuWGHghtb13Ma3H3qzJGzI+EvaqzQY96rKSVfKfa50ErF2h6M2aMP+qInr/YGX1nddXdvz3+/NK3H+7EdwC5Yshv4mKO9wuXwVjDnvI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com; spf=pass smtp.mailfrom=mediatek.com; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b=n33H4OIA; arc=none smtp.client-ip=210.61.82.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mediatek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="n33H4OIA" X-UUID: 79e47880939b11f0b33aeb1e7f16c2b6-20250917 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=uznzB13p4amR3AHMGxiS0rK/8bL739hCWyhx0iAq2QA=; b=n33H4OIAdIJeGke968BUbIcrlttTdjyvJS0YRjgsSBUWKNC1HT8j/FeuImn22wis9L1Rz8YGZZH0ZB8tzZ5DeEN0ncOYJQge9EPG69BQWYY5i4xkvZr82EtGb8cKNKcb5HgmdHTuSCYtdumTsn5YPuSvpLXLrNnD491h2Jgf1rA=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.3.4,REQID:aa1451a8-100d-4503-9cd1-29c7139199be,IP:0,UR L:25,TC:0,Content:-5,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:20 X-CID-META: VersionHash:1ca6b93,CLOUDID:6e9f69a9-24df-464e-9c88-e53ab7cf7153,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:81|82|102|836,TC:-5,Content:0|15|50, EDM:-3,IP:nil,URL:11|97|99|83|106|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:ni l,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 2,SSN|SDN X-CID-BAS: 2,SSN|SDN,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-CID-RHF: D41D8CD98F00B204E9800998ECF8427E X-UUID: 79e47880939b11f0b33aeb1e7f16c2b6-20250917 Received: from mtkmbs14n1.mediatek.inc [(172.21.101.75)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 833157554; Wed, 17 Sep 2025 15:54:02 +0800 Received: from mtkmbs11n1.mediatek.inc (172.21.101.185) by mtkmbs13n2.mediatek.inc (172.21.101.108) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.39; Wed, 17 Sep 2025 15:54:00 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs11n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1258.39 via Frontend Transport; Wed, 17 Sep 2025 15:53:59 +0800 From: hailong.fan To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Liam Girdwood , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Daniel Baluta , Kai Vehmanen , Pierre-Louis Bossart , Mark Brown , Jaroslav Kysela , Takashi Iwai CC: , , , , , , , Hailong Fan Subject: [PATCH v3 1/2] dt-bindings: dsp: mediatek: add mt8196 dsp document Date: Wed, 17 Sep 2025 15:53:05 +0800 Message-ID: <20250917075336.5985-2-hailong.fan@mediatek.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20250917075336.5985-1-hailong.fan@mediatek.com> References: <20250917075336.5985-1-hailong.fan@mediatek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-MTK: N Content-Type: text/plain; charset="utf-8" From: Hailong Fan Add device tree binding documentation for the MediaTek MT8196 DSP. The DSP is used by the Sound Open Firmware driver node and includes registers, clocks, memory regions, and a mailbox for DSP communication. Signed-off-by: Hailong Fan --- .../bindings/dsp/mediatek,mt8196-dsp.yaml | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 Documentation/devicetree/bindings/dsp/mediatek,mt8196-d= sp.yaml diff --git a/Documentation/devicetree/bindings/dsp/mediatek,mt8196-dsp.yaml= b/Documentation/devicetree/bindings/dsp/mediatek,mt8196-dsp.yaml new file mode 100644 index 000000000000..af0f9d71200f --- /dev/null +++ b/Documentation/devicetree/bindings/dsp/mediatek,mt8196-dsp.yaml @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dsp/mediatek,mt8196-dsp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek mt8196 DSP core + +maintainers: + - Hailong Fan + +description: | + The MediaTek mt8196 SoC contains a DSP core used for advanced pre- + and post-audio processing. This DSP is typically used by the Sound + Open Firmware (SOF) driver and requires registers, clocks, memory + regions, and a mailbox for communication. + +properties: + compatible: + const: mediatek,mt8196-dsp + + reg: + items: + - description: DSP configuration registers + - description: DSP SRAM + - description: DSP secure registers + - description: DSP bus registers + + reg-names: + items: + - const: cfg + - const: sram + - const: sec + - const: bus + + clocks: + items: + - description: mux for audio dsp clock + - description: audio dsp 26M clock source + - description: audio dsp PLL clock source + + clock-names: + items: + - const: audiodsp + - const: sys_clk + - const: adsppll + + power-domains: + maxItems: 1 + + mboxes: + items: + - description: mailbox for receiving audio DSP requests. + - description: mailbox for transmitting requests to audio DSP. + + mbox-names: + items: + - const: rx + - const: tx + + memory-region: + items: + - description: dma buffer between host and DSP. + - description: DSP system memory. + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - power-domains + - mboxes + - mbox-names + +additionalProperties: false + +examples: + - | + #include + #include + adsp@1a000000 { + compatible =3D "mediatek,mt8196-dsp"; + reg =3D <0x1a000000 0x5000>, + <0x1a210000 0x80000>, + <0x1a345000 0x300>, + <0x1a00f000 0x1000>; + reg-names =3D "cfg", "sram", "sec", "bus"; + clocks =3D <&cksys_clk CLK_CK_ADSP_SEL>, + <&cksys_clk CLK_CK_TCK_26M_MX9>, + <&cksys_clk CLK_CK_ADSPPLL>; + clock-names =3D "audiodsp", + "sys_clk", + "adsppll"; + power-domains =3D <&scpsys MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT>; + mboxes =3D <&adsp_mailbox0>, <&adsp_mailbox1>; + mbox-names =3D "rx", "tx"; + }; --=20 2.45.2 From nobody Thu Oct 2 11:52:35 2025 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F070305E0A; Wed, 17 Sep 2025 07:54:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.61.82.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758095657; cv=none; b=N6fjeVlNgGBbrW2BojJue1kuk03wAD3lahFm10CrrHL16EqIzw7QD277EYKbIgNjkF0yk1UoKmzdVEJVuaf9Reu8fuHEhJfWeRZGk9h7UC5b8bgYMmXuCVJBqAOyRPKry/JNksQ9dpWfTjrfmtwbKoK89PzqVGnaHy+ZxyJTw0E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758095657; c=relaxed/simple; bh=i1DcLzCLJV6yorXL56n2EzWYpMaaO2AdIj8MQcmIuJA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZthFz8fd14a72CYcRuZlu+Bp+OsBwIPk6oVZBPc6lDF92I2PIrSK4vmUSSHm/Im2CjZu596GygxMfWsoRQ32nwvNaTdn7Z+K7AcD37ef5UHydssvhfiEdtrxmZRJe2l7Y/kfy8udQFCrQMRkHfa+36TBVv6txz0wk5KWe44MNqw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com; spf=pass smtp.mailfrom=mediatek.com; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b=B1RG8IFA; arc=none smtp.client-ip=210.61.82.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mediatek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="B1RG8IFA" X-UUID: 7dee8f7e939b11f0b33aeb1e7f16c2b6-20250917 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=yVjjgT1CNECFvwQKq6abRtOfwRGJas87GErWbwMaWBA=; b=B1RG8IFAGtplyOUgjyrpl3FCfRquI+gOg8WGLKd/hiZO0iO1WaMarPuTiYX6XSd+VBW80d/pLJn/O3O7FqBKfhXu/UW2RYfjUKDr/taudo138xWpKU+SU8d7uCkgFWS/OtV9DEGJ/cLMfxAGXjo9IGAxf61NfXMlHwAxTxt/zKg=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.3.4,REQID:7a34d33f-cffc-4e70-8952-f11e185323fa,IP:0,UR L:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:-25 X-CID-META: VersionHash:1ca6b93,CLOUDID:108de184-5317-4626-9d82-238d715c253f,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:81|82|102|836,TC:-5,Content:0|15|50, EDM:-3,IP:nil,URL:0,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OS A:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 2,SSN|SDN X-CID-BAS: 2,SSN|SDN,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-CID-RHF: D41D8CD98F00B204E9800998ECF8427E X-UUID: 7dee8f7e939b11f0b33aeb1e7f16c2b6-20250917 Received: from mtkmbs14n1.mediatek.inc [(172.21.101.75)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 589302128; Wed, 17 Sep 2025 15:54:09 +0800 Received: from mtkmbs11n1.mediatek.inc (172.21.101.185) by MTKMBS09N2.mediatek.inc (172.21.101.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.39; Wed, 17 Sep 2025 15:54:07 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs11n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1258.39 via Frontend Transport; Wed, 17 Sep 2025 15:54:06 +0800 From: hailong.fan To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Liam Girdwood , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Daniel Baluta , Kai Vehmanen , Pierre-Louis Bossart , Mark Brown , Jaroslav Kysela , Takashi Iwai CC: , , , , , , , Hailong Fan Subject: [PATCH v3 2/2] ASoC: SOF: MediaTek: Add mt8196 hardware support Date: Wed, 17 Sep 2025 15:53:06 +0800 Message-ID: <20250917075336.5985-3-hailong.fan@mediatek.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20250917075336.5985-1-hailong.fan@mediatek.com> References: <20250917075336.5985-1-hailong.fan@mediatek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-MTK: N Content-Type: text/plain; charset="utf-8" From: Hailong Fan Add support of SOF on MediaTek mt8196 SoC. MT8196 has a Cadence HiFi-5 DSP core that is responsible for running the operating system and application programs. The IPC communication between the AP and DSP is based on shared DRAM and mailbox interrupt. Signed-off-by: Hailong Fan --- sound/soc/sof/mediatek/Kconfig | 9 + sound/soc/sof/mediatek/Makefile | 1 + sound/soc/sof/mediatek/mt8196/Makefile | 3 + sound/soc/sof/mediatek/mt8196/mt8196-clk.c | 98 +++ sound/soc/sof/mediatek/mt8196/mt8196-clk.h | 23 + sound/soc/sof/mediatek/mt8196/mt8196-loader.c | 60 ++ sound/soc/sof/mediatek/mt8196/mt8196.c | 556 ++++++++++++++++++ sound/soc/sof/mediatek/mt8196/mt8196.h | 124 ++++ 8 files changed, 874 insertions(+) create mode 100644 sound/soc/sof/mediatek/mt8196/Makefile create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196-clk.c create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196-clk.h create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196-loader.c create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196.c create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196.h diff --git a/sound/soc/sof/mediatek/Kconfig b/sound/soc/sof/mediatek/Kconfig index 4a2eddf6009a..36eb6f5c080b 100644 --- a/sound/soc/sof/mediatek/Kconfig +++ b/sound/soc/sof/mediatek/Kconfig @@ -42,4 +42,13 @@ config SND_SOC_SOF_MT8195 Say Y if you have such a device. If unsure select "N". =20 +config SND_SOC_SOF_MT8196 + tristate "SOF support for MT8196 audio DSP" + select SND_SOC_SOF_MTK_COMMON + depends on MTK_ADSP_IPC + help + This adds support for Sound Open Firmware for MediaTek platforms + using the mt8196 processors. + Say Y if you have such a device. + If unsure select "N". endif ## SND_SOC_SOF_MTK_TOPLEVEL diff --git a/sound/soc/sof/mediatek/Makefile b/sound/soc/sof/mediatek/Makef= ile index 29c5afb2f3d6..3e36d538679e 100644 --- a/sound/soc/sof/mediatek/Makefile +++ b/sound/soc/sof/mediatek/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_SOF_MTK_COMMON) +=3D mtk-adsp-common.o obj-$(CONFIG_SND_SOC_SOF_MT8195) +=3D mt8195/ obj-$(CONFIG_SND_SOC_SOF_MT8186) +=3D mt8186/ +obj-$(CONFIG_SND_SOC_SOF_MT8196) +=3D mt8196/ diff --git a/sound/soc/sof/mediatek/mt8196/Makefile b/sound/soc/sof/mediate= k/mt8196/Makefile new file mode 100644 index 000000000000..245ff4cb387c --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +snd-sof-mt8196-objs :=3D mt8196.o mt8196-clk.o mt8196-loader.o +obj-$(CONFIG_SND_SOC_SOF_MT8196) +=3D snd-sof-mt8196.o diff --git a/sound/soc/sof/mediatek/mt8196/mt8196-clk.c b/sound/soc/sof/med= iatek/mt8196/mt8196-clk.c new file mode 100644 index 000000000000..01ad942072db --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196-clk.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Copyright(c) 2025 MediaTek Inc. All rights reserved. + * Author: Hailong Fan + */ + +// Hardware interface for mt8196 DSP clock + +#include +#include + +#include "../../sof-audio.h" +#include "../../ops.h" +#include "../adsp_helper.h" +#include "mt8196.h" +#include "mt8196-clk.h" + +static const char *adsp_clks[ADSP_CLK_MAX] =3D { + [CLK_TOP_AUDIODSP] =3D "audiodsp", + [CLK_TOP_SYS_CLK] =3D "sys_clk", + [CLK_TOP_ADSPPLL] =3D "adsppll", + +}; + +int mt8196_adsp_init_clock(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv =3D sdev->pdata->hw_pdata; + struct device *dev =3D sdev->dev; + int i; + + priv->clk =3D devm_kcalloc(dev, ADSP_CLK_MAX, sizeof(*priv->clk), GFP_KER= NEL); + if (!priv->clk) + return -ENOMEM; + + for (i =3D 0; i < ADSP_CLK_MAX; i++) { + priv->clk[i] =3D devm_clk_get(dev, adsp_clks[i]); + + if (IS_ERR(priv->clk[i])) + return PTR_ERR(priv->clk[i]); + } + + return 0; +} + +static int adsp_enable_all_clock(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv =3D sdev->pdata->hw_pdata; + struct device *dev =3D sdev->dev; + int ret; + + ret =3D clk_prepare_enable(priv->clk[CLK_TOP_AUDIODSP]); + if (ret) { + dev_err(dev, "%s clk_prepare_enable(audiodsp) fail %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +static void adsp_disable_all_clock(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv =3D sdev->pdata->hw_pdata; + + clk_disable_unprepare(priv->clk[CLK_TOP_AUDIODSP]); +} + +int mt8196_adsp_clock_on(struct snd_sof_dev *sdev) +{ + struct device *dev =3D sdev->dev; + int ret; + + ret =3D adsp_enable_all_clock(sdev); + if (ret) { + dev_err(dev, "failed to adsp_enable_clock: %d\n", ret); + return ret; + } + + ret =3D snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CK_EN, + UART_BT_EN | DMA_AXI_EN | DMA1_EN, + UART_BT_EN | DMA_AXI_EN | DMA1_EN); + if (ret < 0) + dev_err(sdev->dev, "Failed to update CK register: %d\n", ret); + + ret =3D snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_UART_CTRL, + UART_BCLK_CG | UART_RSTN, + UART_BCLK_CG | UART_RSTN); + if (ret < 0) + dev_err(sdev->dev, "Failed to update UART register: %d\n", ret); + + return 0; +} + +void mt8196_adsp_clock_off(struct snd_sof_dev *sdev) +{ + snd_sof_dsp_write(sdev, DSP_REG_BAR, ADSP_UART_CTRL, 0); + adsp_disable_all_clock(sdev); +} diff --git a/sound/soc/sof/mediatek/mt8196/mt8196-clk.h b/sound/soc/sof/med= iatek/mt8196/mt8196-clk.h new file mode 100644 index 000000000000..deaac1342eb6 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196-clk.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * Copyright(c) 2025 MediaTek Inc. All rights reserved. + * Author: Hailong Fan + */ + +#ifndef __MT8196_CLK_H +#define __MT8196_CLK_H + +struct snd_sof_dev; + +/* DSP clock */ +enum adsp_clk_id { + CLK_TOP_AUDIODSP, + CLK_TOP_SYS_CLK, + CLK_TOP_ADSPPLL, + ADSP_CLK_MAX +}; + +int mt8196_adsp_init_clock(struct snd_sof_dev *sdev); +int mt8196_adsp_clock_on(struct snd_sof_dev *sdev); +void mt8196_adsp_clock_off(struct snd_sof_dev *sdev); +#endif diff --git a/sound/soc/sof/mediatek/mt8196/mt8196-loader.c b/sound/soc/sof/= mediatek/mt8196/mt8196-loader.c new file mode 100644 index 000000000000..7063221d7753 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196-loader.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Copyright(c) 2025 MediaTek Inc. All rights reserved. + * Author: Hailong Fan + */ + +// Hardware interface for mt8196 DSP code loader + +#include +#include "mt8196.h" +#include "../../ops.h" + +void mt8196_sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_= addr) +{ + /* step1. clr ADSP_ALTVEC_C0 */ + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVEC_C0, 0); + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVECSEL, 0); + + /* step2. set core boot address */ + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVEC_C0, boot_addr); + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVECSEL, ADSP_ALTVECSEL_C0= ); + + /* step3. set RUNSTALL to stop core */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_RUNSTALL, + RUNSTALL, RUNSTALL); + + /* enable mbox 0 & 1 IRQ */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_MBOX_IRQ_EN, + DSP_MBOX0_IRQ_EN | DSP_MBOX1_IRQ_EN, + DSP_MBOX0_IRQ_EN | DSP_MBOX1_IRQ_EN); + + /* step4. assert core reset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN, + SW_RSTN_C0 | SW_DBG_RSTN_C0, + SW_RSTN_C0 | SW_DBG_RSTN_C0); + + /* hardware requirement */ + udelay(1); + + /* step5. release core reset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN, + SW_RSTN_C0 | SW_DBG_RSTN_C0, + 0); + + /* step6. clear RUNSTALL to start core */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_RUNSTALL, + RUNSTALL, 0); +} + +void mt8196_sof_hifixdsp_shutdown(struct snd_sof_dev *sdev) +{ + /* set RUNSTALL to stop core */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_RUNSTALL, + RUNSTALL, RUNSTALL); + + /* assert core reset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN, + SW_RSTN_C0 | SW_DBG_RSTN_C0, + SW_RSTN_C0 | SW_DBG_RSTN_C0); +} diff --git a/sound/soc/sof/mediatek/mt8196/mt8196.c b/sound/soc/sof/mediate= k/mt8196/mt8196.c new file mode 100644 index 000000000000..079a0b303780 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196.c @@ -0,0 +1,556 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Copyright(c) 2025 MediaTek Inc. All rights reserved. + * Author: Hailong Fan + */ + +/* + * Hardware interface for audio DSP on mt8196 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../../ops.h" +#include "../../sof-of-dev.h" +#include "../adsp_helper.h" +#include "../mtk-adsp-common.h" +#include "mt8196.h" +#include "mt8196-clk.h" + +static void sof_reg_write_bits(struct snd_sof_dev *sdev, u32 bar, u32 offs= et, u32 value, + u8 bits, u8 len) +{ + u32 mask, val; + int ret; + + mask =3D GENMASK(len + bits - 1, bits); + val =3D (value << bits) & mask; + + ret =3D snd_sof_dsp_update_bits(sdev, bar, offset, mask, val); + if (ret < 0) + dev_err(sdev->dev, "Failed to update DSP register: %d\n", ret); +} + +static u32 reg_read_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset, u8= bits, u8 len) +{ + u32 target_bit_field, curr_value; + + target_bit_field =3D GENMASK(len + bits - 1, bits); + curr_value =3D snd_sof_dsp_read(sdev, bar, offset); + + return (curr_value & target_bit_field) >> bits; +} + +static int mt8196_get_mailbox_offset(struct snd_sof_dev *sdev) +{ + return MBOX_OFFSET; +} + +static int mt8196_get_window_offset(struct snd_sof_dev *sdev, u32 id) +{ + return MBOX_OFFSET; +} + +static const struct mtk_adsp_ipc_ops dsp_ops =3D { + .handle_reply =3D mtk_adsp_handle_reply, + .handle_request =3D mtk_adsp_handle_request, +}; + +static int platform_parse_resource(struct platform_device *pdev, void *dat= a) +{ + struct resource *mmio; + struct resource res; + struct device_node *mem_region; + struct device *dev =3D &pdev->dev; + struct mtk_adsp_chip_info *adsp =3D data; + int ret; + + ret =3D of_reserved_mem_device_init(dev); + if (ret) { + dev_err(dev, "of_reserved_mem_device_init failed\n"); + return ret; + } + + mem_region =3D of_parse_phandle(dev->of_node, "memory-region", 1); + if (!mem_region) { + dev_err(dev, "no memory-region sysmem phandle\n"); + return -ENODEV; + } + + ret =3D of_address_to_resource(mem_region, 0, &res); + of_node_put(mem_region); + if (ret) { + dev_err(dev, "of_address_to_resource sysmem failed\n"); + return ret; + } + + adsp->pa_dram =3D (phys_addr_t)res.start; + if (adsp->pa_dram & DRAM_REMAP_MASK) { + dev_err(dev, "adsp memory(%#x) is not 4K-aligned\n", + (u32)adsp->pa_dram); + return -EINVAL; + } + + adsp->dramsize =3D resource_size(&res); + if (adsp->dramsize < TOTAL_SIZE_SHARED_DRAM_FROM_TAIL) { + dev_err(dev, "adsp memory(%#x) is not enough for share\n", + adsp->dramsize); + return -EINVAL; + } + + dev_dbg(dev, "dram pbase=3D%pa size=3D%#x\n", &adsp->pa_dram, adsp->drams= ize); + + mmio =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); + if (!mmio) { + dev_err(dev, "no ADSP-CFG register resource\n"); + return -ENXIO; + } + + adsp->va_cfgreg =3D devm_ioremap_resource(dev, mmio); + if (IS_ERR(adsp->va_cfgreg)) + return PTR_ERR(adsp->va_cfgreg); + + adsp->pa_cfgreg =3D (phys_addr_t)mmio->start; + adsp->cfgregsize =3D resource_size(mmio); + + mmio =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); + if (!mmio) { + dev_err(dev, "no SRAM resource\n"); + return -ENXIO; + } + + adsp->pa_sram =3D (phys_addr_t)mmio->start; + adsp->sramsize =3D resource_size(mmio); + + dev_dbg(dev, "sram pbase=3D%pa size=3D%#x\n", &adsp->pa_sram, adsp->srams= ize); + + mmio =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec"); + if (!mmio) { + dev_err(dev, "no SEC register resource\n"); + return -ENXIO; + } + + adsp->va_secreg =3D devm_ioremap_resource(dev, mmio); + if (IS_ERR(adsp->va_secreg)) + return PTR_ERR(adsp->va_secreg); + + adsp->pa_secreg =3D (phys_addr_t)mmio->start; + adsp->secregsize =3D resource_size(mmio); + + dev_dbg(dev, "secreg pbase=3D%pa size=3D%#x\n", &adsp->pa_secreg, adsp->s= ecregsize); + + mmio =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "bus"); + if (!mmio) { + dev_err(dev, "no BUS register resource\n"); + return -ENXIO; + } + + adsp->va_busreg =3D devm_ioremap_resource(dev, mmio); + if (IS_ERR(adsp->va_busreg)) + return PTR_ERR(adsp->va_busreg); + + adsp->pa_busreg =3D (phys_addr_t)mmio->start; + adsp->busregsize =3D resource_size(mmio); + + dev_dbg(dev, "busreg pbase=3D%pa, vbase=3D%pa, size=3D%#x\n", &adsp->pa_b= usreg, + &adsp->va_busreg, adsp->busregsize); + + return 0; +} + +static void adsp_sram_power_on(struct snd_sof_dev *sdev) +{ + int i; + + for (i =3D 0; i < ADSP_SRAM_CHANNEL_NUM; i++) { + sof_reg_write_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON, 0, i, 1); + while (1) { + if (reg_read_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_ACK, i, 1) =3D= =3D 0) + break; + } + } +} + +static void adsp_sram_power_off(struct snd_sof_dev *sdev) +{ + int i; + + for (i =3D 0; i < ADSP_SRAM_CHANNEL_NUM; i++) { + sof_reg_write_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON, 1, i, 1); + while (1) { + if (reg_read_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_ACK, i, 1) =3D= =3D 1) + break; + } + } +} + +/* Init the basic DSP DRAM address */ +static int adsp_memory_remap_init(struct snd_sof_dev *sdev, struct mtk_ads= p_chip_info *adsp) +{ + u32 from, to; + + from =3D adsp_remap_region_from(DRAM_PHYS_BASE_FROM_DSP_VIEW, DSP_DRAM_SI= ZE); + to =3D (u32)ADSP_REMAP_REGION_TO(adsp->pa_dram); + + snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, AUDIO_BUS_CFG_RSV_10, from); + snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR, to); + + snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, AUDIO_BUS_CFG_BUS_REMAP_CTR= L, 1, 1); + + return 0; +} + +static int mt8196_run(struct snd_sof_dev *sdev) +{ + u32 adsp_bootup_addr; + + adsp_bootup_addr =3D SRAM_PHYS_BASE_FROM_DSP_VIEW; + dev_dbg(sdev->dev, "HIFIxDSP boot from base : 0x%08X\n", adsp_bootup_addr= ); + mt8196_sof_hifixdsp_boot_sequence(sdev, adsp_bootup_addr); + + return 0; +} + +static int mt8196_dsp_probe(struct snd_sof_dev *sdev) +{ + struct platform_device *pdev =3D to_platform_device(sdev->dev); + struct adsp_priv *priv; + int ret; + + priv =3D devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + sdev->pdata->hw_pdata =3D priv; + priv->dev =3D sdev->dev; + priv->sdev =3D sdev; + + priv->adsp =3D devm_kzalloc(&pdev->dev, sizeof(struct mtk_adsp_chip_info)= , GFP_KERNEL); + if (!priv->adsp) + return -ENOMEM; + + ret =3D platform_parse_resource(pdev, priv->adsp); + if (ret) + return ret; + + sdev->bar[SOF_FW_BLK_TYPE_IRAM] =3D devm_ioremap(sdev->dev, + priv->adsp->pa_sram, + priv->adsp->sramsize); + if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { + dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n", + &priv->adsp->pa_sram, priv->adsp->sramsize); + return -ENOMEM; + } + + priv->adsp->va_sram =3D sdev->bar[SOF_FW_BLK_TYPE_IRAM]; + dev_dbg(sdev->dev, "pa_sram %pa,va: %pa, size %#x\n", + &priv->adsp->pa_sram, &priv->adsp->va_sram, priv->adsp->sramsize); + + sdev->bar[SOF_FW_BLK_TYPE_SRAM] =3D devm_ioremap(sdev->dev, + priv->adsp->pa_dram, + priv->adsp->dramsize); + + if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { + dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n", + &priv->adsp->pa_dram, priv->adsp->dramsize); + return -ENOMEM; + } + + priv->adsp->va_dram =3D sdev->bar[SOF_FW_BLK_TYPE_SRAM]; + + dev_dbg(sdev->dev, "pa_dram %pa, va: %pa, size %#x\n", + &priv->adsp->pa_dram, &priv->adsp->va_dram, priv->adsp->dramsize); + + sdev->bar[DSP_REG_BAR] =3D priv->adsp->va_cfgreg; + sdev->bar[DSP_SECREG_BAR] =3D priv->adsp->va_secreg; + sdev->bar[DSP_BUSREG_BAR] =3D priv->adsp->va_busreg; + + sdev->mmio_bar =3D SOF_FW_BLK_TYPE_SRAM; + sdev->mailbox_bar =3D SOF_FW_BLK_TYPE_SRAM; + + /* set default mailbox offset for FW ready message */ + sdev->dsp_box.offset =3D mt8196_get_mailbox_offset(sdev); + + /* enable adsp clock before touching registers */ + ret =3D mt8196_adsp_init_clock(sdev); + if (ret) { + dev_err(sdev->dev, "mt8196_adsp_init_clock failed\n"); + return ret; + } + + ret =3D mt8196_adsp_clock_on(sdev); + if (ret) { + dev_err(sdev->dev, "mt8196_adsp_clock_on fail!\n"); + return ret; + } + + ret =3D adsp_memory_remap_init(sdev, priv->adsp); + if (ret) { + dev_err(sdev->dev, "adsp_memory_remap_init fail!\n"); + return ret; + } + + adsp_sram_power_on(sdev); + + priv->ipc_dev =3D platform_device_register_data(&pdev->dev, "mtk-adsp-ipc= ", + PLATFORM_DEVID_NONE, + pdev, sizeof(*pdev)); + if (IS_ERR(priv->ipc_dev)) { + ret =3D PTR_ERR(priv->ipc_dev); + dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n"); + goto err_adsp_off; + } + + priv->dsp_ipc =3D dev_get_drvdata(&priv->ipc_dev->dev); + if (!priv->dsp_ipc) { + ret =3D -EPROBE_DEFER; + dev_err(sdev->dev, "failed to get drvdata\n"); + goto exit_pdev_unregister; + } + + mtk_adsp_ipc_set_data(priv->dsp_ipc, priv); + priv->dsp_ipc->ops =3D &dsp_ops; + + return 0; + +exit_pdev_unregister: + platform_device_unregister(priv->ipc_dev); +err_adsp_off: + adsp_sram_power_off(sdev); + mt8196_adsp_clock_off(sdev); + + return ret; +} + +static void mt8196_dsp_remove(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv =3D sdev->pdata->hw_pdata; + + platform_device_unregister(priv->ipc_dev); + mt8196_sof_hifixdsp_shutdown(sdev); + adsp_sram_power_off(sdev); + mt8196_adsp_clock_off(sdev); +} + +static int mt8196_dsp_shutdown(struct snd_sof_dev *sdev) +{ + return snd_sof_suspend(sdev->dev); +} + +static int mt8196_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) +{ + struct adsp_priv *priv =3D sdev->pdata->hw_pdata; + + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_IO_CONFIG, ADSP_CLK_SEL, = 0); + clk_set_parent(priv->clk[CLK_TOP_AUDIODSP], priv->clk[CLK_TOP_SYS_CLK]); + mt8196_sof_hifixdsp_shutdown(sdev); + adsp_sram_power_off(sdev); + mt8196_adsp_clock_off(sdev); + + return 0; +} + +static int mt8196_dsp_resume(struct snd_sof_dev *sdev) +{ + int ret; + struct adsp_priv *priv =3D sdev->pdata->hw_pdata; + + ret =3D mt8196_adsp_clock_on(sdev); + if (ret) { + dev_err(sdev->dev, "mt8196_adsp_clock_on fail!"); + return ret; + } + + clk_set_parent(priv->clk[CLK_TOP_AUDIODSP], priv->clk[CLK_TOP_ADSPPLL]); + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_IO_CONFIG, ADSP_CLK_SEL, = BIT(31)); + adsp_sram_power_on(sdev); + + return 0; +} + +static void mt8196_adsp_dump(struct snd_sof_dev *sdev, u32 flags) +{ + u32 dbg_pc, dbg_data, dbg_inst, dbg_ls0stat, dbg_status, faultinfo; + + /* dump debug registers */ + dbg_pc =3D snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGPC); + dbg_data =3D snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGDATA); + dbg_inst =3D snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGINST); + dbg_ls0stat =3D snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGLS0STAT); + dbg_status =3D snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGSTATUS); + faultinfo =3D snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PFAULTINFO); + + dev_info(sdev->dev, "adsp dump : pc %#x, data %#x, dbg_inst %#x,", + dbg_pc, dbg_data, dbg_inst); + dev_info(sdev->dev, "ls0stat %#x, status %#x, faultinfo %#x", + dbg_ls0stat, dbg_status, faultinfo); + + mtk_adsp_dump(sdev, flags); +} + +/* + * DL_24CH, DL1, UL0, UL1, UL2 are registered as SOF FE, so creating the c= orresponding + * SOF BE to complete the pipeline. + */ +static struct snd_soc_dai_driver mt8196_dai[] =3D { +{ + .name =3D "SOF_DL_24CH", + .playback =3D { + .channels_min =3D CHAN_MIN, + .channels_max =3D CHAN_MAX, + }, +}, +{ + .name =3D "SOF_DL1", + .playback =3D { + .channels_min =3D CHAN_MIN, + .channels_max =3D CHAN_MAX, + }, +}, +{ + .name =3D "SOF_UL0", + .capture =3D { + .channels_min =3D 1, + .channels_max =3D 2, + }, +}, +{ + .name =3D "SOF_UL1", + .capture =3D { + .channels_min =3D CHAN_MIN, + .channels_max =3D CHAN_MAX, + }, +}, +{ + .name =3D "SOF_UL2", + .capture =3D { + .channels_min =3D CHAN_MIN, + .channels_max =3D CHAN_MAX, + }, +}, +}; + +/* mt8196 ops */ +static const struct snd_sof_dsp_ops sof_mt8196_ops =3D { + /* probe and remove */ + .probe =3D mt8196_dsp_probe, + .remove =3D mt8196_dsp_remove, + .shutdown =3D mt8196_dsp_shutdown, + + /* DSP core boot */ + .run =3D mt8196_run, + + /* Block IO */ + .block_read =3D sof_block_read, + .block_write =3D sof_block_write, + + /* Mailbox IO */ + .mailbox_read =3D sof_mailbox_read, + .mailbox_write =3D sof_mailbox_write, + + /* Register IO */ + .write =3D sof_io_write, + .read =3D sof_io_read, + .write64 =3D sof_io_write64, + .read64 =3D sof_io_read64, + + /* ipc */ + .send_msg =3D mtk_adsp_send_msg, + .get_mailbox_offset =3D mt8196_get_mailbox_offset, + .get_window_offset =3D mt8196_get_window_offset, + .ipc_msg_data =3D sof_ipc_msg_data, + .set_stream_data_offset =3D sof_set_stream_data_offset, + + /* misc */ + .get_bar_index =3D mtk_adsp_get_bar_index, + + /* stream callbacks */ + .pcm_open =3D sof_stream_pcm_open, + .pcm_hw_params =3D mtk_adsp_stream_pcm_hw_params, + .pcm_pointer =3D mtk_adsp_stream_pcm_pointer, + .pcm_close =3D sof_stream_pcm_close, + + /* firmware loading */ + .load_firmware =3D snd_sof_load_firmware_memcpy, + + /* Firmware ops */ + .dsp_arch_ops =3D &sof_xtensa_arch_ops, + + /* DAI drivers */ + .drv =3D mt8196_dai, + .num_drv =3D ARRAY_SIZE(mt8196_dai), + + /* Debug information */ + .dbg_dump =3D mt8196_adsp_dump, + .debugfs_add_region_item =3D snd_sof_debugfs_add_region_item_iomem, + + /* PM */ + .suspend =3D mt8196_dsp_suspend, + .resume =3D mt8196_dsp_resume, + + /* ALSA HW info flags */ + .hw_info =3D SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, +}; + +static struct snd_sof_of_mach sof_mt8196_machs[] =3D { + { + .compatible =3D "mediatek,mt8196", + .sof_tplg_filename =3D "sof-mt8196.tplg", + }, + {} +}; + +static const struct sof_dev_desc sof_of_mt8196_desc =3D { + .of_machines =3D sof_mt8196_machs, + .ipc_supported_mask =3D BIT(SOF_IPC_TYPE_3), + .ipc_default =3D SOF_IPC_TYPE_3, + .default_fw_path =3D { + [SOF_IPC_TYPE_3] =3D "mediatek/sof", + }, + .default_tplg_path =3D { + [SOF_IPC_TYPE_3] =3D "mediatek/sof-tplg", + }, + .default_fw_filename =3D { + [SOF_IPC_TYPE_3] =3D "sof-mt8196.ri", + }, + .nocodec_tplg_filename =3D "sof-mt8196-nocodec.tplg", + .ops =3D &sof_mt8196_ops, +}; + +static const struct of_device_id sof_of_mt8196_ids[] =3D { + { .compatible =3D "mediatek,mt8196-dsp", .data =3D &sof_of_mt8196_desc}, + { } +}; +MODULE_DEVICE_TABLE(of, sof_of_mt8196_ids); + +/* DT driver definition */ +static struct platform_driver snd_sof_of_mt8196_driver =3D { + .probe =3D sof_of_probe, + .remove =3D sof_of_remove, + .shutdown =3D sof_of_shutdown, + .driver =3D { + .name =3D "sof-audio-of-mt8196", + .pm =3D pm_ptr(&sof_of_pm), + .of_match_table =3D sof_of_mt8196_ids, + }, +}; +module_platform_driver(snd_sof_of_mt8196_driver); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("SOF support for MT8196 platforms"); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SND_SOC_SOF_MTK_COMMON"); diff --git a/sound/soc/sof/mediatek/mt8196/mt8196.h b/sound/soc/sof/mediate= k/mt8196/mt8196.h new file mode 100644 index 000000000000..5d2e14827bc2 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * Copyright(c) 2025 MediaTek Inc. All rights reserved. + * Author: Hailong Fan + */ + +#ifndef __MT8196_H +#define __MT8196_H + +struct mtk_adsp_chip_info; +struct snd_sof_dev; + +#define DSP_REG_BAR 4 +#define DSP_SECREG_BAR 5 +#define DSP_BUSREG_BAR 6 +#define CHAN_MIN 1 +#define CHAN_MAX 2 + +/*************************************************************************= **** + * R E G I S T E R TABLE + *************************************************************************= ****/ +/* dsp cfg */ +#define ADSP_CFGREG_SW_RSTN 0x0000 +#define SW_DBG_RSTN_C0 BIT(0) +#define SW_RSTN_C0 BIT(4) +#define ADSP_IO_CONFIG 0x000C +#define ADSP_CLK_SEL BIT(31) +#define ADSP_HIFI_RUNSTALL 0x0108 +#define TRACEMEMREADY BIT(15) +#define RUNSTALL BIT(12) +#define ADSP_IRQ_MASK 0x0030 +#define ADSP_DVFSRC_REQ 0x0040 +#define ADSP_DDREN_REQ_0 0x0044 +#define ADSP_SEMAPHORE 0x0064 +#define ADSP_WDT_CON_C0 0x007C +#define ADSP_MBOX_IRQ_EN 0x009C +#define DSP_MBOX0_IRQ_EN BIT(0) +#define DSP_MBOX1_IRQ_EN BIT(1) +#define DSP_MBOX2_IRQ_EN BIT(2) +#define DSP_MBOX3_IRQ_EN BIT(3) +#define DSP_MBOX4_IRQ_EN BIT(4) +#define DSP_PDEBUGPC 0x013C +#define DSP_PDEBUGDATA 0x0140 +#define DSP_PDEBUGINST 0x0144 +#define DSP_PDEBUGLS0STAT 0x0148 +#define DSP_PDEBUGSTATUS 0x014C +#define DSP_PFAULTINFO 0x0150 +#define ADSP_CK_EN 0x1000 +#define DMA1_EN BIT(12) +#define DMA_AXI_EN BIT(13) +#define UART_BT_EN BIT(14) +#define DMA_EN BIT(4) +#define UART_EN BIT(5) +#define ADSP_UART_CTRL 0x1010 +#define UART_BCLK_CG BIT(0) +#define UART_RSTN BIT(3) + +/* dsp sec */ +#define ADSP_PRID 0x0 +#define ADSP_ALTVEC_C0 0x04 +#define ADSP_ALTVECSEL 0x0C +#define MT8196_ADSP_ALTVECSEL_C0 1 + +#define ADSP_ALTVECSEL_C0 MT8196_ADSP_ALTVECSEL_C0 + +/* dsp bus */ +#define AUDIO_BUS_CFG_RSV_10 0x30 +#define ADSP_SRAM_POOL_CON 0x190 +#define ADSP_SRAM_POOL_ACK 0x1A0 +#define ADSP_SRAM_CHANNEL_NUM 6 +#define DSP_SRAM_POOL_PD_MASK 0xF00F /* [0:3] and [12:15] */ +#define DSP_C0_EMI_MAP_ADDR 0xA00 /* ADSP Core0 To EMI Address Remap */ +#define DSP_C0_DMAEMI_MAP_ADDR 0xA08 /* DMA0 To EMI Address Remap */ +#define AUDIO_BUS_CFG_BUS_REMAP_CTRL 0x016C +#define AUDIO_BUS_DSP2EMI_REMAP0 0x0A00 +#define AUDIO_BUS_DSP2EMI_REMAP1 0x0A04 +#define AUDIO_BUS_DMA2EMI_REMAP0 0x0A08 +#define AUDIO_BUS_DMA2EMI_REMAP1 0x0A0C + +/* DSP memories */ +#define MBOX_OFFSET 0x500000 /* DRAM */ +#define MBOX_SIZE 0x1000 /* consistent with which in memory.h of sof f= w */ +#define DSP_DRAM_SIZE 0x900000 /* 9M */ + +/*remap dram between AP and DSP view, 4KB aligned*/ +#define SRAM_PHYS_BASE_FROM_DSP_VIEW 0x4e100000 /* MT8196 DSP view */ +#define DRAM_PHYS_BASE_FROM_DSP_VIEW 0x90000000 /* MT8196 DSP view */ +#define DRAM_REMAP_SHIFT 12 +#define DRAM_REMAP_MASK 0xFFF + +/* remap */ +#define ADSP_REMAP_REGION +#define ADSP_EMI_REMAP_SET_TOTAL (4) +#define EMI_REMAP_REGION (AUDIO_BUS_CFG_RSV_10) +#define EMI_REMAP_REPLACE (AUDIO_BUS_DSP2EMI_REMAP0) +#define EMI_REMAP_EN (1U) +#define ADSP_REMAP_REGION_TO(start) (((start) >> 25) << 9) +#define UPPER_16_SHIFT 16 +#define LOWER_16_MASK 0xFFFF +#define UPPER_16_MASK 0xFFFF0000 +#define REMAP_ALIGN_SIZE 0x10000 + +#define SIZE_SHARED_DRAM_DL 0x40000 /*Shared buffer for Downlink*/ +#define SIZE_SHARED_DRAM_UL 0x40000 /*Shared buffer for Uplink*/ +#define TOTAL_SIZE_SHARED_DRAM_FROM_TAIL (SIZE_SHARED_DRAM_DL + SIZE_SHARE= D_DRAM_UL) + +void mt8196_sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_= addr); +void mt8196_sof_hifixdsp_shutdown(struct snd_sof_dev *sdev); + +static inline u32 mix_begin_and_end_addr(u32 begin, u32 end) +{ + return ((begin >> UPPER_16_SHIFT) & LOWER_16_MASK) | (end & UPPER_16_MASK= ); +} + +static inline u32 remap_roundup(u32 val, u32 align) +{ + return (val + (align - 1)) & ~(align - 1); +} + +static inline u32 adsp_remap_region_from(u32 start, u32 size) +{ + return mix_begin_and_end_addr(start, remap_roundup(start + size, REMAP_AL= IGN_SIZE)); +} +#endif --=20 2.45.2