diff --git a/package/kernel/econet-eth/Makefile b/package/kernel/econet-eth/Makefile new file mode 100644 index 0000000000..1de42b52f3 --- /dev/null +++ b/package/kernel/econet-eth/Makefile @@ -0,0 +1,35 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=econet-eth +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/cjdelisle/econet_eth.git +PKG_MIRROR_HASH:=764e18fe2f87cb0c742711c18ed995a2270b02f0072e7a0938906d0246287111 +PKG_SOURCE_DATE:=2025-11-07 +PKG_SOURCE_VERSION:=40aac736a46fec0d96beadd7513c53d1f0459737 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/econet-eth + SUBMENU:=Network Devices + TITLE:=EcoNet EN751221 Ethernet Driver + DEPENDS:=@TARGET_econet + FILES:=$(PKG_BUILD_DIR)/econet-eth.ko + AUTOLOAD:=$(call AutoLoad,90,econet-eth) +endef + +define KernelPackage/econet-eth/description + Out-of-tree ethernet driver for EcoNet EN751221 devices. +endef + +define Build/Prepare + $(call Build/Prepare/Default) +endef + +define Build/Compile + $(KERNEL_MAKE) M=$(PKG_BUILD_DIR) modules +endef + +$(eval $(call KernelPackage,econet-eth)) diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile index eee9c767ce..4d90281731 100644 --- a/package/kernel/qca-nss-dp/Makefile +++ b/package/kernel/qca-nss-dp/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_URL:=https://github.com/openwrt/qca-nss-dp.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2025-05-12 -PKG_SOURCE_VERSION:=07b87bf513ffe58ce8dd00eb2edf68b5b9bde518 -PKG_MIRROR_HASH:=795ffccf1f4d61b6a5e0a6964ce21efa7b7b3c73b31b93140c56af7d970293b9 +PKG_SOURCE_DATE:=2025-11-24 +PKG_SOURCE_VERSION:=19c51af0c5be0afcbd57a9e0e50928759d7d08da +PKG_MIRROR_HASH:=96aafb7c8f09ecde036ed706535111368874b06cd412a7b9df950415e5b4b334 PKG_BUILD_PARALLEL:=1 PKG_FLAGS:=nonshared diff --git a/package/network/services/odhcpd/Makefile b/package/network/services/odhcpd/Makefile index 74266b21c8..2a0e421f3b 100644 --- a/package/network/services/odhcpd/Makefile +++ b/package/network/services/odhcpd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcpd.git -PKG_MIRROR_HASH:=1b9d5324c377f99e2cec3a92a71e9e979a1e4cf16023fea59b5799bcbdbb36d5 -PKG_SOURCE_DATE:=2025-11-27 -PKG_SOURCE_VERSION:=d21e504b38ab4c880c43b7f1649104bb2f0d2d8b +PKG_MIRROR_HASH:=cddf1a82865e1a064ff7aaf7b86e6ba076387f8717c95a0a0f0e49cebdd60dfd +PKG_SOURCE_DATE:=2025-12-01 +PKG_SOURCE_VERSION:=6fbd70c0834279f5836585a90d7c957fbb23a7e5 PKG_MAINTAINER:=Álvaro Fernández Rojas PKG_LICENSE:=GPL-2.0 diff --git a/package/system/rpcd/Makefile b/package/system/rpcd/Makefile index 22e73f21fc..593eb3a84a 100644 --- a/package/system/rpcd/Makefile +++ b/package/system/rpcd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/rpcd.git -PKG_MIRROR_HASH:=b7b813e0b76f586bfe3432ef94883bd1b079c48003666a2128fbf028109a1a65 -PKG_SOURCE_DATE:=2025-11-10 -PKG_SOURCE_VERSION:=483263c7b0cd3922b93be2cf9dad5eeccbb9fedb +PKG_MIRROR_HASH:=1a701b15746f34eb19532f195d738611364a18acaf45c0197626c31ab59976ce +PKG_SOURCE_DATE:=2025-12-03 +PKG_SOURCE_VERSION:=ffb9961c1f8bc50830fdd4e144570f11062c2601 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/package/utils/busybox/Makefile b/package/utils/busybox/Makefile index 63c1dceee3..e5b7c2c780 100644 --- a/package/utils/busybox/Makefile +++ b/package/utils/busybox/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=busybox PKG_VERSION:=1.37.0 -PKG_RELEASE:=5 +PKG_RELEASE:=6 PKG_FLAGS:=essential PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 diff --git a/package/utils/busybox/patches/100-libbb-dump-fix-dumping-of-signed-values-without-expl.patch b/package/utils/busybox/patches/100-libbb-dump-fix-dumping-of-signed-values-without-expl.patch new file mode 100644 index 0000000000..665dc6042c --- /dev/null +++ b/package/utils/busybox/patches/100-libbb-dump-fix-dumping-of-signed-values-without-expl.patch @@ -0,0 +1,68 @@ +From: Sven Wegener +Subject: [PATCH] libbb/dump: fix dumping of signed values without explicit + size specifier + +Message-ID: <05d87e73-d0e0-d9ef-561a-8a9180888627@stealer.net> + +Commit e2287f99fe6f21fd6435ad04340170ad4ba5f6b3 added support for the 64 +bit signed format %lld, accidentally changing the default size of the %d +format to eight bytes and producing the following: + +root at openwrt:~# for i in $(seq 0 7); do hexdump -s $i -n 1 -e '"%d\n"' /dev/mtdblock0; done +0 +0 +0 +0 +0 +0 +0 +0 +root at openwrt:~# for i in $(seq 0 7); do hexdump -s $i -n 1 -e '/4 "%d\n"' /dev/mtdblock0; done +255 +0 +0 +16 +0 +0 +0 +0 + +With -n 1 the input is zero-padded. On big-endian, when the input is copied +into the 64 bit variable, the input byte ends up in the highest byte. As the %d +format only interprets the lower 32 bits, the input byte is lost during +printing. + +Depending on how the architecture passes 64 bit parameters, the same +happens on little-endian as well. x86 (little-endian) works correctly, +but MIPS experiences the same behavior on big-endian and little-endian. + +Fixes: e2287f99fe6f21fd6435ad04340170ad4ba5f6b3 +See: https://github.com/openwrt/openwrt/issues/18808 +Signed-off-by: Sven Wegener +--- + libbb/dump.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/libbb/dump.c ++++ b/libbb/dump.c +@@ -192,16 +192,17 @@ static NOINLINE void rewrite(priv_dumper + if (*p1 == 'l') { /* %lld etc */ + ++p2; + ++p1; +- } ++ byte_count_str = "\010\004\002\001"; ++ } else { + DO_INT_CONV: ++ byte_count_str = "\004\002\001"; ++ } + e = strchr(int_convs, *p1); /* "diouxX"? */ + if (!e) + goto DO_BAD_CONV_CHAR; + pr->flags = F_INT; +- byte_count_str = "\010\004\002\001"; + if (e > int_convs + 1) { /* not d or i? */ + pr->flags = F_UINT; +- byte_count_str++; + } + goto DO_BYTE_COUNT; + } else diff --git a/target/linux/airoha/an7581/config-6.12 b/target/linux/airoha/an7581/config-6.12 index 77bd649276..da40adadaf 100644 --- a/target/linux/airoha/an7581/config-6.12 +++ b/target/linux/airoha/an7581/config-6.12 @@ -357,9 +357,14 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SGL_ALLOC=y CONFIG_SKB_EXTENSIONS=y CONFIG_SMP=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_AN7581=y +CONFIG_SND_SOC_AN7581_WM8960=y CONFIG_SOCK_RX_QUEUE_MAPPING=y CONFIG_SOC_BUS=y CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOUND=y CONFIG_SPARSEMEM=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP=y diff --git a/target/linux/airoha/dts/an7581-evb-emmc.dts b/target/linux/airoha/dts/an7581-evb-emmc.dts index 25d9b87af0..ee800b6131 100644 --- a/target/linux/airoha/dts/an7581-evb-emmc.dts +++ b/target/linux/airoha/dts/an7581-evb-emmc.dts @@ -28,6 +28,19 @@ }; }; +&sound { + audio-routing = "Headphone", "HP_L", + "Headphone", "HP_R", + "LINPUT1", "AMIC", + "RINPUT1", "AMIC"; + + status = "okay"; + + codec { + sound-dai = <&wm8960>; + }; +}; + &en7581_pinctrl { gpio-ranges = <&en7581_pinctrl 0 13 47>; @@ -160,6 +173,11 @@ &i2c0 { status = "okay"; + + wm8960: codec@1a { + compatible = "wlf,wm8960"; + reg = <0x1a>; + }; }; &pcie0 { diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index e50048ac94..786044f254 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -360,6 +360,16 @@ regulator-always-on; }; + sound: sound { + compatible = "airoha,an7581-wm8960-sound"; + + status = "disabled"; + + platform { + sound-dai = <&afe>; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; @@ -419,6 +429,13 @@ status = "disabled"; }; + afe: afe@1fbe2200 { + compatible = "airoha,an7581-afe"; + reg = <0x0 0x1fbe2200 0x0 0x9000>; + + interrupts = ; + }; + uart4: serial@1fbf0600 { compatible = "airoha,en7523-uart"; reg = <0x0 0x1fbf0600 0x0 0x30>; diff --git a/target/linux/airoha/patches-6.12/123-01-ASoC-mediatek-move-some-header-to-global-include.patch b/target/linux/airoha/patches-6.12/123-01-ASoC-mediatek-move-some-header-to-global-include.patch deleted file mode 100644 index c9cdb9a326..0000000000 --- a/target/linux/airoha/patches-6.12/123-01-ASoC-mediatek-move-some-header-to-global-include.patch +++ /dev/null @@ -1,410 +0,0 @@ -From 527123b53739a2f73ca924b9c6e2f63dc66739a5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 1 Aug 2025 11:06:56 +0200 -Subject: [PATCH 1/3] ASoC: mediatek: move some header to global include - -In preparation for support of Airoha SoC sound system based on Mediatek -AFE, move some header to global include to prevent having to use complex -redirection for inclusion. - -Signed-off-by: Christian Marangi ---- - .../common => include/sound/mediatek}/mtk-afe-fe-dai.h | 0 - .../sound/mediatek}/mtk-afe-platform-driver.h | 0 - sound/soc/mediatek/common/mtk-afe-fe-dai.c | 4 ++-- - sound/soc/mediatek/common/mtk-afe-platform-driver.c | 2 +- - sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt6797/mt6797-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c | 2 +- - sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c | 2 +- - sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt8186/mt8186-misc-control.c | 4 ++-- - sound/soc/mediatek/mt8186/mt8186-mt6366-common.c | 2 +- - sound/soc/mediatek/mt8186/mt8186-mt6366.c | 2 +- - sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt8188/mt8188-mt6359.c | 2 +- - sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 2 +- - sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 4 ++-- - sound/soc/mediatek/mt8195/mt8195-mt6359.c | 2 +- - sound/soc/mediatek/mt8365/mt8365-afe-pcm.c | 4 ++-- - 22 files changed, 32 insertions(+), 32 deletions(-) - rename {sound/soc/mediatek/common => include/sound/mediatek}/mtk-afe-fe-dai.h (100%) - rename {sound/soc/mediatek/common => include/sound/mediatek}/mtk-afe-platform-driver.h (100%) - ---- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c -+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c -@@ -11,9 +11,9 @@ - #include - #include - #include --#include "mtk-afe-platform-driver.h" -+#include - #include --#include "mtk-afe-fe-dai.h" -+#include - #include "mtk-base-afe.h" - - #define AFE_BASE_END_OFFSET 8 ---- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c -+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c -@@ -10,7 +10,7 @@ - #include - #include - --#include "mtk-afe-platform-driver.h" -+#include - #include "mtk-base-afe.h" - - int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe) ---- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c -+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c -@@ -16,8 +16,8 @@ - - #include "mt2701-afe-common.h" - #include "mt2701-afe-clock-ctrl.h" --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - static const struct snd_pcm_hardware mt2701_afe_hardware = { - .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED ---- a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c -+++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c -@@ -16,8 +16,8 @@ - #include "mt6797-afe-clk.h" - #include "mt6797-interconnection.h" - #include "mt6797-reg.h" --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - enum { - MTK_AFE_RATE_8K = 0, ---- a/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c -+++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c -@@ -16,8 +16,8 @@ - - #include "mt7986-afe-common.h" - #include "mt7986-reg.h" --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - enum { - MTK_AFE_RATE_8K = 0, ---- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c -+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c -@@ -19,8 +19,8 @@ - #include - #include "mt8173-afe-common.h" - #include "../common/mtk-base-afe.h" --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - /***************************************************************************** - * R E G I S T E R D E F I N I T I O N ---- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c -+++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c -@@ -18,8 +18,8 @@ - #include "mt8183-afe-clk.h" - #include "mt8183-interconnection.h" - #include "mt8183-reg.h" --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - enum { - MTK_AFE_RATE_8K = 0, ---- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c -+++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c -@@ -16,7 +16,7 @@ - - #include "../../codecs/da7219.h" - #include "../../codecs/rt1015.h" --#include "../common/mtk-afe-platform-driver.h" -+#include - #include "mt8183-afe-common.h" - - #define DA7219_CODEC_DAI "da7219-hifi" ---- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c -+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c -@@ -15,7 +15,7 @@ - - #include "../../codecs/rt1015.h" - #include "../../codecs/ts3a227e.h" --#include "../common/mtk-afe-platform-driver.h" -+#include - #include "mt8183-afe-common.h" - - #define RT1015_CODEC_DAI "rt1015-aif" ---- a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c -+++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c -@@ -15,8 +15,8 @@ - #include - #include - --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - #include "mt8186-afe-common.h" - #include "mt8186-afe-clk.h" ---- a/sound/soc/mediatek/mt8186/mt8186-misc-control.c -+++ b/sound/soc/mediatek/mt8186/mt8186-misc-control.c -@@ -11,8 +11,8 @@ - #include - #include - --#include "../common/mtk-afe-fe-dai.h" --#include "../common/mtk-afe-platform-driver.h" -+#include -+#include - #include "mt8186-afe-common.h" - - static const char * const mt8186_sgen_mode_str[] = { ---- a/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c -+++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c -@@ -9,7 +9,7 @@ - #include - - #include "../../codecs/mt6358.h" --#include "../common/mtk-afe-platform-driver.h" -+#include - #include "mt8186-afe-common.h" - #include "mt8186-mt6366-common.h" - ---- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c -+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c -@@ -24,8 +24,8 @@ - #include "mt8188-afe-common.h" - #include "mt8188-afe-clk.h" - #include "mt8188-reg.h" --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - #define MT8188_MEMIF_BUFFER_BYTES_ALIGN (0x40) - #define MT8188_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff) ---- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c -+++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c -@@ -17,8 +17,8 @@ - #include - #include - --#include "../common/mtk-afe-fe-dai.h" --#include "../common/mtk-afe-platform-driver.h" -+#include -+#include - - #include "mt8192-afe-common.h" - #include "mt8192-afe-clk.h" ---- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c -+++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c -@@ -20,8 +20,8 @@ - #include "mt8195-afe-common.h" - #include "mt8195-afe-clk.h" - #include "mt8195-reg.h" --#include "../common/mtk-afe-platform-driver.h" --#include "../common/mtk-afe-fe-dai.h" -+#include -+#include - - #define MT8195_MEMIF_BUFFER_BYTES_ALIGN (0x40) - #define MT8195_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff) ---- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c -+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c -@@ -19,7 +19,7 @@ - #include "../../codecs/mt6359.h" - #include "../../codecs/rt1011.h" - #include "../../codecs/rt5682.h" --#include "../common/mtk-afe-platform-driver.h" -+#include - #include "../common/mtk-dsp-sof-common.h" - #include "../common/mtk-soc-card.h" - #include "../common/mtk-soundcard-driver.h" ---- /dev/null -+++ b/include/sound/mediatek/mtk-afe-fe-dai.h -@@ -0,0 +1,53 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition -+ * -+ * Copyright (c) 2016 MediaTek Inc. -+ * Author: Garlic Tseng -+ */ -+ -+#ifndef _MTK_AFE_FE_DAI_H_ -+#define _MTK_AFE_FE_DAI_H_ -+ -+struct snd_soc_dai_ops; -+struct mtk_base_afe; -+struct mtk_base_afe_memif; -+ -+int mtk_afe_fe_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai); -+void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai); -+int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai); -+int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai); -+int mtk_afe_fe_prepare(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai); -+int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd, -+ struct snd_soc_dai *dai); -+ -+extern const struct snd_soc_dai_ops mtk_afe_fe_ops; -+ -+int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe); -+int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id); -+int mtk_afe_suspend(struct snd_soc_component *component); -+int mtk_afe_resume(struct snd_soc_component *component); -+ -+int mtk_memif_set_enable(struct mtk_base_afe *afe, int id); -+int mtk_memif_set_disable(struct mtk_base_afe *afe, int id); -+int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, -+ unsigned char *dma_area, -+ dma_addr_t dma_addr, -+ size_t dma_bytes); -+int mtk_memif_set_channel(struct mtk_base_afe *afe, -+ int id, unsigned int channel); -+int mtk_memif_set_rate(struct mtk_base_afe *afe, -+ int id, unsigned int rate); -+int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream, -+ int id, unsigned int rate); -+int mtk_memif_set_format(struct mtk_base_afe *afe, -+ int id, snd_pcm_format_t format); -+int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe, -+ int id, int pbuf_size); -+#endif ---- /dev/null -+++ b/include/sound/mediatek/mtk-afe-platform-driver.h -@@ -0,0 +1,28 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition -+ * -+ * Copyright (c) 2016 MediaTek Inc. -+ * Author: Garlic Tseng -+ */ -+ -+#ifndef _MTK_AFE_PLATFORM_DRIVER_H_ -+#define _MTK_AFE_PLATFORM_DRIVER_H_ -+ -+#define AFE_PCM_NAME "mtk-afe-pcm" -+extern const struct snd_soc_component_driver mtk_afe_pcm_platform; -+ -+struct mtk_base_afe; -+struct snd_pcm; -+struct snd_soc_component; -+struct snd_soc_pcm_runtime; -+ -+snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component, -+ struct snd_pcm_substream *substream); -+int mtk_afe_pcm_new(struct snd_soc_component *component, -+ struct snd_soc_pcm_runtime *rtd); -+ -+int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe); -+int mtk_afe_add_sub_dai_control(struct snd_soc_component *component); -+#endif -+ ---- a/sound/soc/mediatek/common/mtk-afe-fe-dai.h -+++ /dev/null -@@ -1,53 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition -- * -- * Copyright (c) 2016 MediaTek Inc. -- * Author: Garlic Tseng -- */ -- --#ifndef _MTK_AFE_FE_DAI_H_ --#define _MTK_AFE_FE_DAI_H_ -- --struct snd_soc_dai_ops; --struct mtk_base_afe; --struct mtk_base_afe_memif; -- --int mtk_afe_fe_startup(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai); --void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai); --int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params, -- struct snd_soc_dai *dai); --int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai); --int mtk_afe_fe_prepare(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai); --int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd, -- struct snd_soc_dai *dai); -- --extern const struct snd_soc_dai_ops mtk_afe_fe_ops; -- --int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe); --int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id); --int mtk_afe_suspend(struct snd_soc_component *component); --int mtk_afe_resume(struct snd_soc_component *component); -- --int mtk_memif_set_enable(struct mtk_base_afe *afe, int id); --int mtk_memif_set_disable(struct mtk_base_afe *afe, int id); --int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, -- unsigned char *dma_area, -- dma_addr_t dma_addr, -- size_t dma_bytes); --int mtk_memif_set_channel(struct mtk_base_afe *afe, -- int id, unsigned int channel); --int mtk_memif_set_rate(struct mtk_base_afe *afe, -- int id, unsigned int rate); --int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream, -- int id, unsigned int rate); --int mtk_memif_set_format(struct mtk_base_afe *afe, -- int id, snd_pcm_format_t format); --int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe, -- int id, int pbuf_size); --#endif ---- a/sound/soc/mediatek/common/mtk-afe-platform-driver.h -+++ /dev/null -@@ -1,28 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition -- * -- * Copyright (c) 2016 MediaTek Inc. -- * Author: Garlic Tseng -- */ -- --#ifndef _MTK_AFE_PLATFORM_DRIVER_H_ --#define _MTK_AFE_PLATFORM_DRIVER_H_ -- --#define AFE_PCM_NAME "mtk-afe-pcm" --extern const struct snd_soc_component_driver mtk_afe_pcm_platform; -- --struct mtk_base_afe; --struct snd_pcm; --struct snd_soc_component; --struct snd_soc_pcm_runtime; -- --snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component, -- struct snd_pcm_substream *substream); --int mtk_afe_pcm_new(struct snd_soc_component *component, -- struct snd_soc_pcm_runtime *rtd); -- --int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe); --int mtk_afe_add_sub_dai_control(struct snd_soc_component *component); --#endif -- diff --git a/target/linux/airoha/patches-6.12/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch b/target/linux/airoha/patches-6.12/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch index 00578601c4..b5cd4982f1 100644 --- a/target/linux/airoha/patches-6.12/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch +++ b/target/linux/airoha/patches-6.12/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch @@ -1,94 +1,102 @@ -From 9989af6ed0dba86f57ac4aa1574f9ce9b1e640af Mon Sep 17 00:00:00 2001 +From 131f599fd0464f8e685610d9e24dadd8fbb4ba76 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 31 Jul 2025 15:32:32 +0200 -Subject: [PATCH 2/3] ASoC: airoha: Add AFE and I2S driver for Airoha AN7581 +Subject: [PATCH] ASoC: airoha: Add AFE and machine driver for Airoha AN7581 Add support for the Sound system present on Airoha AN7581 SoC. This is based on the mediatek AFE drivers. -Also add the I2S driver to create an actual sound card for the AFE. +Also add the machine driver to create an actual sound card for the AFE. Signed-off-by: Christian Marangi --- - sound/soc/Kconfig | 1 + - sound/soc/Makefile | 1 + - sound/soc/airoha/Kconfig | 19 + - sound/soc/airoha/Makefile | 2 + - sound/soc/airoha/an7581/Makefile | 8 + - sound/soc/airoha/an7581/an7581-afe-common.h | 35 ++ - sound/soc/airoha/an7581/an7581-afe-pcm.c | 455 ++++++++++++++++++++ - sound/soc/airoha/an7581/an7581-i2s.c | 110 +++++ - sound/soc/airoha/an7581/an7581-reg.h | 29 ++ - 9 files changed, 660 insertions(+) - create mode 100644 sound/soc/airoha/Kconfig - create mode 100644 sound/soc/airoha/Makefile - create mode 100644 sound/soc/airoha/an7581/Makefile - create mode 100644 sound/soc/airoha/an7581/an7581-afe-common.h - create mode 100644 sound/soc/airoha/an7581/an7581-afe-pcm.c - create mode 100644 sound/soc/airoha/an7581/an7581-i2s.c - create mode 100644 sound/soc/airoha/an7581/an7581-reg.h + MAINTAINERS | 8 + + sound/soc/mediatek/Kconfig | 20 + + sound/soc/mediatek/Makefile | 1 + + sound/soc/mediatek/an7581/Makefile | 9 + + sound/soc/mediatek/an7581/an7581-afe-common.h | 39 ++ + sound/soc/mediatek/an7581/an7581-afe-pcm.c | 497 ++++++++++++++++++ + sound/soc/mediatek/an7581/an7581-dai-etdm.c | 407 ++++++++++++++ + sound/soc/mediatek/an7581/an7581-reg.h | 88 ++++ + sound/soc/mediatek/an7581/an7581-wm8960.c | 170 ++++++ + 9 files changed, 1239 insertions(+) + create mode 100644 sound/soc/mediatek/an7581/Makefile + create mode 100644 sound/soc/mediatek/an7581/an7581-afe-common.h + create mode 100644 sound/soc/mediatek/an7581/an7581-afe-pcm.c + create mode 100644 sound/soc/mediatek/an7581/an7581-dai-etdm.c + create mode 100644 sound/soc/mediatek/an7581/an7581-reg.h + create mode 100644 sound/soc/mediatek/an7581/an7581-wm8960.c ---- a/sound/soc/Kconfig -+++ b/sound/soc/Kconfig -@@ -86,6 +86,7 @@ config SND_SOC_ACPI +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -728,6 +728,14 @@ F: Documentation/devicetree/bindings/phy + F: drivers/phy/phy-airoha-pcie-regs.h + F: drivers/phy/phy-airoha-pcie.c + ++AIROHA SOUND DRIVER ++M: Christian Marangi ++L: linux-sound@vger.kernel.org ++S: Maintained ++F: Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml ++F: Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml ++F: sound/soc/mediatek/an7581/* ++ + AIROHA SPI SNFI DRIVER + M: Lorenzo Bianconi + M: Ray Liu +--- a/sound/soc/mediatek/Kconfig ++++ b/sound/soc/mediatek/Kconfig +@@ -3,6 +3,26 @@ config SND_SOC_MEDIATEK + tristate + select REGMAP_MMIO - # All the supported SoCs - source "sound/soc/adi/Kconfig" -+source "sound/soc/airoha/Kconfig" - source "sound/soc/amd/Kconfig" - source "sound/soc/apple/Kconfig" - source "sound/soc/atmel/Kconfig" ---- a/sound/soc/Makefile -+++ b/sound/soc/Makefile -@@ -40,6 +40,7 @@ obj-$(CONFIG_SND_SOC) += codecs/ - obj-$(CONFIG_SND_SOC) += generic/ - obj-$(CONFIG_SND_SOC) += apple/ - obj-$(CONFIG_SND_SOC) += adi/ -+obj-$(CONFIG_SND_SOC) += airoha/ - obj-$(CONFIG_SND_SOC) += amd/ - obj-$(CONFIG_SND_SOC) += atmel/ - obj-$(CONFIG_SND_SOC) += au1x/ ---- /dev/null -+++ b/sound/soc/airoha/Kconfig -@@ -0,0 +1,19 @@ -+# SPDX-License-Identifier: GPL-2.0-only +config SND_SOC_AN7581 + tristate "ASoC support for Airoha AN7581 chip" + depends on ARCH_AIROHA || COMPILE_TEST + select SND_SOC_MEDIATEK + help -+ This adds ASoC driver for Airoha AN7581 boards ++ This adds ASoC platform driver support for Airoha AN7581 chip + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N". + -+config SND_SOC_AN7581_I2S -+ tristate "I2S support for Airoha AN7581 chip" -+ depends on SND_SOC_AN7581 ++config SND_SOC_AN7581_WM8960 ++ tristate "ASoc Audio driver for Airoha AN7581 with WM8960 codec" ++ depends on SND_SOC_AN7581 && I2C ++ select SND_SOC_WM8960 + help -+ This adds I2S driver for Airoha AN7581 boards -+ that can be used with other codecs. ++ This adds support for ASoC machine driver for Airoha AN7581 ++ boards with the WM8960 codecs. + Select Y if you have such device. + If unsure select "N". ---- /dev/null -+++ b/sound/soc/airoha/Makefile -@@ -0,0 +1,2 @@ -+# SPDX-License-Identifier: GPL-2.0 ++ + config SND_SOC_MT2701 + tristate "ASoC support for Mediatek MT2701 chip" + depends on ARCH_MEDIATEK +--- a/sound/soc/mediatek/Makefile ++++ b/sound/soc/mediatek/Makefile +@@ -1,5 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_SND_SOC_MEDIATEK) += common/ +obj-$(CONFIG_SND_SOC_AN7581) += an7581/ + obj-$(CONFIG_SND_SOC_MT2701) += mt2701/ + obj-$(CONFIG_SND_SOC_MT6797) += mt6797/ + obj-$(CONFIG_SND_SOC_MT7986) += mt7986/ --- /dev/null -+++ b/sound/soc/airoha/an7581/Makefile -@@ -0,0 +1,8 @@ ++++ b/sound/soc/mediatek/an7581/Makefile +@@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +# platform driver +snd-soc-an7581-afe-y := \ -+ an7581-afe-pcm.o ++ an7581-afe-pcm.o \ ++ an7581-dai-etdm.o + +obj-$(CONFIG_SND_SOC_AN7581) += snd-soc-an7581-afe.o -+obj-$(CONFIG_SND_SOC_AN7581_I2S) += an7581-i2s.o ++obj-$(CONFIG_SND_SOC_AN7581_WM8960) += an7581-wm8960.o --- /dev/null -+++ b/sound/soc/airoha/an7581/an7581-afe-common.h -@@ -0,0 +1,35 @@ ++++ b/sound/soc/mediatek/an7581/an7581-afe-common.h +@@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * an7581-afe-common.h -- Airoha AN7581 audio driver definitions @@ -106,7 +114,8 @@ Signed-off-by: Christian Marangi + AN7581_MEMIF_DL1, + AN7581_MEMIF_UL1, + AN7581_MEMIF_NUM, -+ AN7581_DAI_NUM = AN7581_MEMIF_NUM, ++ AN7581_DAI_ETDM = AN7581_MEMIF_NUM, ++ AN7581_DAI_NUM, +}; + +enum { @@ -123,10 +132,13 @@ Signed-off-by: Christian Marangi +unsigned int an7581_afe_rate_transform(struct device *dev, + unsigned int rate); + ++/* dai register */ ++int an7581_dai_etdm_register(struct mtk_base_afe *afe); ++ +#endif --- /dev/null -+++ b/sound/soc/airoha/an7581/an7581-afe-pcm.c -@@ -0,0 +1,455 @@ ++++ b/sound/soc/mediatek/an7581/an7581-afe-pcm.c +@@ -0,0 +1,497 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Airoha ALSA SoC AFE platform driver for AN7581 @@ -139,31 +151,32 @@ Signed-off-by: Christian Marangi +#include +#include +#include ++#include + +#include "an7581-afe-common.h" +#include "an7581-reg.h" -+#include -+#include ++#include "../common/mtk-afe-platform-driver.h" ++#include "../common/mtk-afe-fe-dai.h" + +enum { -+ ARH_AFE_RATE_7K = 16, + ARH_AFE_RATE_8K = 0, -+ ARH_AFE_RATE_11K = 17, + ARH_AFE_RATE_12K = 1, -+ ARH_AFE_RATE_14K = 18, + ARH_AFE_RATE_16K = 2, -+ ARH_AFE_RATE_22K = 19, + ARH_AFE_RATE_24K = 3, -+ ARH_AFE_RATE_29K = 20, + ARH_AFE_RATE_32K = 4, -+ ARH_AFE_RATE_44K = 21, + ARH_AFE_RATE_48K = 5, -+ ARH_AFE_RATE_88K = 22, + ARH_AFE_RATE_96K = 6, -+ ARH_AFE_RATE_176K = 23, + ARH_AFE_RATE_192K = 7, -+ ARH_AFE_RATE_352K = 24, + ARH_AFE_RATE_384K = 8, ++ ARH_AFE_RATE_7K = 16, ++ ARH_AFE_RATE_11K = 17, ++ ARH_AFE_RATE_14K = 18, ++ ARH_AFE_RATE_22K = 19, ++ ARH_AFE_RATE_29K = 20, ++ ARH_AFE_RATE_44K = 21, ++ ARH_AFE_RATE_88K = 22, ++ ARH_AFE_RATE_176K = 23, ++ ARH_AFE_RATE_352K = 24, +}; + +unsigned int an7581_afe_rate_transform(struct device *dev, unsigned int rate) @@ -275,7 +288,7 @@ Signed-off-by: Christian Marangi + .capture = { + .stream_name = "UL1", + .channels_min = 1, -+ .channels_max = 2, ++ .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = ARH_PCM_FORMATS, + }, @@ -283,6 +296,25 @@ Signed-off-by: Christian Marangi + }, +}; + ++static const struct snd_soc_dapm_widget an7581_memif_widgets[] = { ++ /* DL */ ++ SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0), ++ SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0), ++ ++ /* UL */ ++ SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0, NULL, 0), ++ SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0, NULL, 0), ++}; ++ ++static const struct snd_soc_dapm_route an7581_memif_routes[] = { ++ {"I032", NULL, "DL1"}, ++ {"I033", NULL, "DL1"}, ++ {"UL1", NULL, "O018"}, ++ {"UL1", NULL, "O019"}, ++ {"O018", NULL, "I150"}, ++ {"O019", NULL, "I151"}, ++}; ++ +static const struct snd_soc_component_driver an7581_afe_pcm_dai_component = { + .name = "an7581-afe-pcm-dai", +}; @@ -299,14 +331,20 @@ Signed-off-by: Christian Marangi + .fs_maskbit = -1, + .mono_reg = -1, + .mono_shift = -1, -+ .hd_reg = -1, -+ .hd_shift = -1, ++ .hd_reg = AFE_DL1_CON0, ++ .hd_shift = AFE_HD_SHIFT, + .enable_reg = AFE_DAC_CON0, -+ .enable_shift = 17, ++ .enable_shift = AFE_DL1_ENABLE_SHIFT, + .msb_reg = -1, + .msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, ++ .pbuf_reg = AFE_DL1_CON0, ++ .pbuf_mask = AFE_PBUF_SIZE_MASK, ++ .pbuf_shift = AFE_PBUF_SIZE_SHIFT, ++ .minlen_reg = AFE_DL1_CON0, ++ .minlen_mask = AFE_MINLEN_MASK, ++ .minlen_shift = AFE_MINLEN_SHIFT, + }, + [AN7581_MEMIF_UL1] = { + .name = "UL1", @@ -319,12 +357,12 @@ Signed-off-by: Christian Marangi + .fs_maskbit = -1, + .mono_reg = -1, + .mono_shift = -1, -+ .hd_reg = -1, -+ .hd_shift = -1, ++ .hd_reg = AFE_UL1_CON0, ++ .hd_shift = AFE_HD_SHIFT, + .enable_reg = AFE_DAC_CON0, -+ .enable_shift = 1, -+ .msb_reg = -1, -+ .msb_shift = -1, ++ .enable_shift = AFE_UL1_ENABLE_SHIFT, ++ .msb_reg = AFE_UL1_CON0, ++ .msb_shift = AFE_MSB_SHIFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, @@ -333,29 +371,29 @@ Signed-off-by: Christian Marangi +static const struct mtk_base_irq_data irq_data[AN7581_IRQ_NUM] = { + [AN7581_IRQ_0] = { + .id = AN7581_IRQ_0, -+ .irq_cnt_reg = -1, -+ .irq_cnt_shift = -1, -+ .irq_cnt_maskbit = -1, ++ .irq_cnt_reg = AFE_IRQ_CNT, ++ .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, ++ .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, ++ .irq_en_reg = AFE_IRQ_CON0, ++ .irq_en_shift = AFE_IRQ_ON_SHIFT, ++ .irq_fs_reg = -1, ++ .irq_fs_shift = -1, ++ .irq_fs_maskbit = -1, ++ .irq_clr_reg = AFE_IRQ_CON0, ++ .irq_clr_shift = AFE_IRQ_CLR_SHIFT, ++ }, ++ [AN7581_IRQ_1] = { ++ .id = AN7581_IRQ_1, ++ .irq_cnt_reg = AFE_IRQ1_CNT, ++ .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, ++ .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_en_reg = AFE_IRQ1_CON0, -+ .irq_en_shift = 4, ++ .irq_en_shift = AFE_IRQ_ON_SHIFT, + .irq_fs_reg = -1, + .irq_fs_shift = -1, + .irq_fs_maskbit = -1, + .irq_clr_reg = AFE_IRQ1_CON0, -+ .irq_clr_shift = 0, -+ }, -+ [AN7581_IRQ_1] = { -+ .id = AN7581_IRQ_1, -+ .irq_cnt_reg = -1, -+ .irq_cnt_shift = -1, -+ .irq_cnt_maskbit = -1, -+ .irq_en_reg = AFE_IRQ0_CON0, -+ .irq_en_shift = 4, -+ .irq_fs_reg = -1, -+ .irq_fs_shift = -1, -+ .irq_fs_maskbit = -1, -+ .irq_clr_reg = AFE_IRQ0_CON0, -+ .irq_clr_shift = 1, ++ .irq_clr_shift = AFE_IRQ_CLR_SHIFT, + }, +}; + @@ -378,9 +416,9 @@ Signed-off-by: Christian Marangi + regmap_read(afe->regmap, AFE_IRQ_STS, &status); + + if (status & AFE_IRQ_STS_RECORD) -+ reg = AFE_IRQ0_CON0; -+ else + reg = AFE_IRQ1_CON0; ++ else ++ reg = AFE_IRQ_CON0; + + regmap_set_bits(afe->regmap, reg, BIT(2)); + regmap_clear_bits(afe->regmap, reg, BIT(2)); @@ -429,18 +467,25 @@ Signed-off-by: Christian Marangi + dai->dai_drivers = an7581_memif_dai_driver; + dai->num_dai_drivers = ARRAY_SIZE(an7581_memif_dai_driver); + ++ dai->dapm_widgets = an7581_memif_widgets; ++ dai->num_dapm_widgets = ARRAY_SIZE(an7581_memif_widgets); ++ dai->dapm_routes = an7581_memif_routes; ++ dai->num_dapm_routes = ARRAY_SIZE(an7581_memif_routes); ++ + return 0; +} + +typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] = { ++ an7581_dai_etdm_register, + an7581_dai_memif_register, +}; + +static int an7581_afe_pcm_dev_probe(struct platform_device *pdev) +{ -+ struct mtk_base_afe *afe; + struct an7581_afe_private *afe_priv; ++ struct reset_control *reset; ++ struct mtk_base_afe *afe; + struct device *dev; + int i, irq_id, ret; + @@ -458,6 +503,15 @@ Signed-off-by: Christian Marangi + afe->dev = &pdev->dev; + dev = afe->dev; + ++ reset = devm_reset_control_get_exclusive(dev, NULL); ++ if (IS_ERR(reset)) ++ return PTR_ERR(reset); ++ ++ /* Global reset I2S */ ++ reset_control_assert(reset); ++ usleep_range(10, 20); ++ reset_control_deassert(reset); ++ + afe->base_addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(afe->base_addr)) + return PTR_ERR(afe->base_addr); @@ -576,15 +630,516 @@ Signed-off-by: Christian Marangi + .pm = pm_ptr(&an7581_afe_pm_ops), + }, + .probe = an7581_afe_pcm_dev_probe, -+ .remove_new = an7581_afe_pcm_dev_remove, ++ .remove = an7581_afe_pcm_dev_remove, +}; +module_platform_driver(an7581_afe_pcm_driver); + +MODULE_DESCRIPTION("Airoha SoC AFE platform driver for ALSA AN7581"); +MODULE_LICENSE("GPL"); --- /dev/null -+++ b/sound/soc/airoha/an7581/an7581-i2s.c -@@ -0,0 +1,110 @@ ++++ b/sound/soc/mediatek/an7581/an7581-dai-etdm.c +@@ -0,0 +1,407 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Airoha ALSA SoC Audio DAI eTDM Control ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include "an7581-afe-common.h" ++#include "an7581-reg.h" ++ ++#define HOPPING_CLK 0 ++#define APLL_CLK 1 ++#define MTK_DAI_ETDM_FORMAT_I2S 0 ++#define MTK_DAI_ETDM_FORMAT_DSPA 4 ++#define MTK_DAI_ETDM_FORMAT_DSPB 5 ++ ++enum { ++ MTK_ETDM_RATE_8K = 0, ++ MTK_ETDM_RATE_12K = 1, ++ MTK_ETDM_RATE_16K = 2, ++ MTK_ETDM_RATE_24K = 3, ++ MTK_ETDM_RATE_32K = 4, ++ MTK_ETDM_RATE_48K = 5, ++ MTK_ETDM_RATE_96K = 6, ++ MTK_ETDM_RATE_192K = 7, ++ MTK_ETDM_RATE_384K = 8, ++ MTK_ETDM_RATE_7K = 16, ++ MTK_ETDM_RATE_11K = 17, ++ MTK_ETDM_RATE_14K = 18, ++ MTK_ETDM_RATE_22K = 19, ++ MTK_ETDM_RATE_29K = 20, ++ MTK_ETDM_RATE_44K = 21, ++ MTK_ETDM_RATE_88K = 22, ++ MTK_ETDM_RATE_176K = 23, ++ MTK_ETDM_RATE_352K = 24, ++}; ++ ++struct mtk_dai_etdm_priv { ++ bool bck_inv; ++ bool lrck_inv; ++ bool slave_mode; ++ unsigned int format; ++}; ++ ++static unsigned int an7581_etdm_rate_transform(struct device *dev, unsigned int rate) ++{ ++ switch (rate) { ++ case 7350: ++ return MTK_ETDM_RATE_7K; ++ case 8000: ++ return MTK_ETDM_RATE_8K; ++ case 11025: ++ return MTK_ETDM_RATE_11K; ++ case 12000: ++ return MTK_ETDM_RATE_12K; ++ case 14700: ++ return MTK_ETDM_RATE_14K; ++ case 16000: ++ return MTK_ETDM_RATE_16K; ++ case 22050: ++ return MTK_ETDM_RATE_22K; ++ case 24000: ++ return MTK_ETDM_RATE_24K; ++ case 29400: ++ return MTK_ETDM_RATE_29K; ++ case 32000: ++ return MTK_ETDM_RATE_32K; ++ case 44100: ++ return MTK_ETDM_RATE_44K; ++ case 48000: ++ return MTK_ETDM_RATE_48K; ++ case 88200: ++ return MTK_ETDM_RATE_88K; ++ case 96000: ++ return MTK_ETDM_RATE_96K; ++ case 176400: ++ return MTK_ETDM_RATE_176K; ++ case 192000: ++ return MTK_ETDM_RATE_192K; ++ case 352800: ++ return MTK_ETDM_RATE_352K; ++ case 384000: ++ return MTK_ETDM_RATE_384K; ++ default: ++ dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n", ++ __func__, rate, MTK_ETDM_RATE_48K); ++ return MTK_ETDM_RATE_48K; ++ } ++} ++ ++static int get_etdm_wlen(unsigned int bitwidth) ++{ ++ return bitwidth <= 16 ? 16 : 32; ++} ++ ++static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = { ++ /* DL */ ++ SND_SOC_DAPM_MIXER("I150", SND_SOC_NOPM, 0, 0, NULL, 0), ++ SND_SOC_DAPM_MIXER("I151", SND_SOC_NOPM, 0, 0, NULL, 0), ++ ++ /* UL */ ++ SND_SOC_DAPM_MIXER("O124", SND_SOC_NOPM, 0, 0, NULL, 0), ++ SND_SOC_DAPM_MIXER("O125", SND_SOC_NOPM, 0, 0, NULL, 0), ++}; ++ ++static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { ++ {"I150", NULL, "ETDM Capture"}, ++ {"I151", NULL, "ETDM Capture"}, ++ {"ETDM Playback", NULL, "O124"}, ++ {"ETDM Playback", NULL, "O125"}, ++ {"O124", NULL, "I032"}, ++ {"O125", NULL, "I033"}, ++}; ++ ++/* dai ops */ ++static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ return 0; ++} ++ ++static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++} ++ ++static unsigned int get_etdm_ch_fixup(unsigned int channels) ++{ ++ if (channels > 16) ++ return 24; ++ else if (channels > 8) ++ return 16; ++ else if (channels > 4) ++ return 8; ++ else if (channels > 2) ++ return 4; ++ else ++ return 2; ++} ++ ++static int mtk_dai_etdm_config(struct mtk_base_afe *afe, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai, ++ int stream) ++{ ++ struct an7581_afe_private *afe_priv = afe->platform_priv; ++ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id]; ++ unsigned int rate = params_rate(params); ++ unsigned int etdm_rate = an7581_etdm_rate_transform(afe->dev, rate); ++ unsigned int channels = params_channels(params); ++ unsigned int bit_width = params_width(params); ++ unsigned int wlen = get_etdm_wlen(bit_width); ++ unsigned int val = 0; ++ unsigned int mask = 0; ++ ++ dev_dbg(afe->dev, "%s(), stream %d, rate %u, bitwidth %u\n", ++ __func__, stream, rate, bit_width); ++ ++ /* CON0 */ ++ mask |= ETDM_BIT_LEN; ++ val |= FIELD_PREP(ETDM_BIT_LEN, bit_width - 1); ++ mask |= ETDM_WRD_LEN; ++ val |= FIELD_PREP(ETDM_WRD_LEN, wlen - 1); ++ mask |= ETDM_FMT; ++ val |= FIELD_PREP(ETDM_FMT, etdm_data->format); ++ mask |= ETDM_CH_NUM; ++ val |= FIELD_PREP(ETDM_CH_NUM, get_etdm_ch_fixup(channels) - 1); ++ mask |= ETDM_MODE; ++ val |= ETDM_MODE; ++ ++ switch (stream) { ++ case SNDRV_PCM_STREAM_PLAYBACK: ++ /* set ETDM_OUT1_CON0 */ ++ regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, mask, val); ++ ++ /* set ETDM_OUT1_CON1 */ ++ regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, ++ EDTM_DIRECT_INPUT_MASTER_BCK | ++ EDTM_LRCK_AUTO_MODE | ++ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | ++ EDTM_INITIAL_POINT | EDTM_INITIAL_COUNT, ++ EDTM_DIRECT_INPUT_MASTER_BCK | ++ EDTM_LRCK_AUTO_MODE | ++ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | ++ FIELD_PREP(EDTM_INITIAL_POINT, 14) | ++ FIELD_PREP(EDTM_INITIAL_COUNT, 14)); ++ ++ /* set ETDM_OUT1_CON4 */ ++ regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, OUT_SEL_FS, ++ FIELD_PREP(OUT_SEL_FS, etdm_rate)); ++ break; ++ case SNDRV_PCM_STREAM_CAPTURE: ++ /* set ETDM_IN1_CON0 */ ++ regmap_update_bits(afe->regmap, ETDM_IN1_CON0, mask, val); ++ regmap_set_bits(afe->regmap, ETDM_IN1_CON0, ETDM_SYNC); ++ ++ /* set ETDM_IN1_CON1 */ ++ regmap_update_bits(afe->regmap, ETDM_IN1_CON1, ++ EDTM_LRCK_AUTO_MODE | ++ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | ++ EDTM_INITIAL_POINT | EDTM_INITIAL_COUNT, ++ EDTM_LRCK_AUTO_MODE | ++ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | ++ FIELD_PREP(EDTM_INITIAL_POINT, 14) | ++ FIELD_PREP(EDTM_INITIAL_COUNT, 14)); ++ ++ /* set ETDM_IN1_CON3 */ ++ regmap_update_bits(afe->regmap, ETDM_IN1_CON3, IN_SEL_FS, ++ FIELD_PREP(IN_SEL_FS, etdm_rate)); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ unsigned int rate = params_rate(params); ++ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); ++ ++ regmap_update_bits(afe->regmap, ETDM_COWORK_CON0, ++ EDTM_IN1_SLAVE_SEL, FIELD_PREP(EDTM_IN1_SLAVE_SEL, 1)); ++ regmap_update_bits(afe->regmap, ETDM_COWORK_CON0, ++ EDTM_OUT1_SLAVE_SEL, FIELD_PREP(EDTM_OUT1_SLAVE_SEL, 1)); ++ regmap_update_bits(afe->regmap, ETDM_COWORK_CON1, ++ EDTM_IN1_SDATA0_SEL, FIELD_PREP(EDTM_IN1_SDATA0_SEL, 0)); ++ ++ switch (rate) { ++ case 8000: ++ case 12000: ++ case 16000: ++ case 24000: ++ case 32000: ++ case 48000: ++ case 96000: ++ case 192000: ++ mtk_dai_etdm_config(afe, params, dai, substream->stream); ++ return 0; ++ default: ++ dev_err(afe->dev, ++ "Sample rate %d invalid. Supported rates: 8/12/16/24/32/48/96/192 kHz\n", ++ rate); ++ return -EINVAL; ++ } ++} ++ ++static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); ++ ++ dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id); ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ regmap_set_bits(afe->regmap, ETDM_IN1_CON0, ETDM_EN); ++ regmap_set_bits(afe->regmap, ETDM_OUT1_CON0, ETDM_EN); ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ regmap_clear_bits(afe->regmap, ETDM_IN1_CON0, ETDM_EN); ++ regmap_clear_bits(afe->regmap, ETDM_OUT1_CON0, ETDM_EN); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ++{ ++ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); ++ struct an7581_afe_private *afe_priv = afe->platform_priv; ++ struct mtk_dai_etdm_priv *etdm_data; ++ void *priv_data; ++ ++ switch (dai->id) { ++ case AN7581_DAI_ETDM: ++ break; ++ default: ++ dev_warn(afe->dev, "%s(), id %d not support\n", ++ __func__, dai->id); ++ return -EINVAL; ++ } ++ ++ priv_data = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_etdm_priv), ++ GFP_KERNEL); ++ if (!priv_data) ++ return -ENOMEM; ++ ++ afe_priv->dai_priv[dai->id] = priv_data; ++ etdm_data = afe_priv->dai_priv[dai->id]; ++ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S; ++ break; ++ case SND_SOC_DAIFMT_DSP_A: ++ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA; ++ break; ++ case SND_SOC_DAIFMT_DSP_B: ++ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_NB_NF: ++ etdm_data->bck_inv = false; ++ etdm_data->lrck_inv = false; ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ etdm_data->bck_inv = false; ++ etdm_data->lrck_inv = true; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ etdm_data->bck_inv = true; ++ etdm_data->lrck_inv = false; ++ break; ++ case SND_SOC_DAIFMT_IB_IF: ++ etdm_data->bck_inv = true; ++ etdm_data->lrck_inv = true; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBP_CFP: ++ etdm_data->slave_mode = true; ++ break; ++ case SND_SOC_DAIFMT_CBC_CFC: ++ etdm_data->slave_mode = false; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static const struct snd_soc_dai_ops mtk_dai_etdm_ops = { ++ .startup = mtk_dai_etdm_startup, ++ .shutdown = mtk_dai_etdm_shutdown, ++ .hw_params = mtk_dai_etdm_hw_params, ++ .trigger = mtk_dai_etdm_trigger, ++ .set_fmt = mtk_dai_etdm_set_fmt, ++}; ++ ++/* dai driver */ ++#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ ++ SNDRV_PCM_FMTBIT_S24_LE |\ ++ SNDRV_PCM_FMTBIT_S32_LE) ++ ++static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = { ++ { ++ .name = "ETDM", ++ .id = AN7581_DAI_ETDM, ++ .capture = { ++ .stream_name = "ETDM Capture", ++ .channels_min = 1, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = MTK_ETDM_FORMATS, ++ }, ++ .playback = { ++ .stream_name = "ETDM Playback", ++ .channels_min = 1, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = MTK_ETDM_FORMATS, ++ }, ++ .ops = &mtk_dai_etdm_ops, ++ .symmetric_rate = 1, ++ .symmetric_sample_bits = 1, ++ }, ++}; ++ ++int an7581_dai_etdm_register(struct mtk_base_afe *afe) ++{ ++ struct mtk_base_afe_dai *dai; ++ ++ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); ++ if (!dai) ++ return -ENOMEM; ++ ++ list_add(&dai->list, &afe->sub_dais); ++ ++ dai->dai_drivers = mtk_dai_etdm_driver; ++ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver); ++ ++ dai->dapm_widgets = mtk_dai_etdm_widgets; ++ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets); ++ dai->dapm_routes = mtk_dai_etdm_routes; ++ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes); ++ ++ return 0; ++} +--- /dev/null ++++ b/sound/soc/mediatek/an7581/an7581-reg.h +@@ -0,0 +1,88 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * an7581-reg.h -- Airoha AN7581 audio driver reg definition ++ */ ++ ++#ifndef _AN7581_REG_H_ ++#define _AN7581_REG_H_ ++ ++#define AFE_DAC_CON0 0x0 ++#define AFE_DL1_ENABLE_SHIFT 17 ++#define AFE_UL1_ENABLE_SHIFT 1 ++ ++#define ETDM_COWORK_CON0 0x4c ++#define EDTM_IN1_SLAVE_SEL GENMASK(27, 24) ++#define EDTM_OUT1_SLAVE_SEL GENMASK(11, 8) ++#define ETDM_COWORK_CON1 0x50 ++#define EDTM_IN1_SDATA0_SEL GENMASK(3, 0) ++#define ETDM_IN1_CON0 0x5c ++#define EDTM_LRCK_AUTO_MODE BIT(29) ++#define ETDM_CH_NUM GENMASK(27, 23) ++#define ETDM_WRD_LEN GENMASK(20, 16) ++#define ETDM_BIT_LEN GENMASK(15, 11) ++#define ETDM_FMT GENMASK(8, 6) ++#define ETDM_MODE BIT(5) ++#define ETDM_SYNC BIT(1) ++#define ETDM_EN BIT(0) ++#define ETDM_IN1_CON1 0x60 ++#define ETDM_IN1_CON2 0x64 ++#define IN_CLK_SRC GENMASK(12, 10) ++#define ETDM_IN1_CON3 0x68 ++#define IN_SEL_FS GENMASK(30, 26) ++#define ETDM_IN1_CON4 0x6c ++#define IN_RELATCH GENMASK(24, 20) ++#define IN_CLK_INV BIT(18) ++#define ETDM_IN1_CON5 0x70 ++#define ETDM_IN1_CON6 0x74 ++#define ETDM_OUT1_CON0 0x7c ++#define ETDM_OUT1_CON1 0x80 ++#define EDTM_DIRECT_INPUT_MASTER_BCK BIT(30) ++#define EDTM_CKEN_SEL BIT(12) ++#define EDTM_LRCK_AUTO_OFF BIT(10) ++#define EDTM_INITIAL_POINT GENMASK(9, 5) ++#define EDTM_INITIAL_COUNT GENMASK(4, 0) ++#define ETDM_OUT1_CON2 0x84 ++#define ETDM_OUT1_CON3 0x88 ++#define ETDM_OUT1_CON4 0x8c ++#define OUT_RELATCH GENMASK(28, 24) ++#define OUT_CLK_SRC GENMASK(8, 6) ++#define OUT_SEL_FS GENMASK(4, 0) ++#define ETDM_OUT1_CON5 0x90 ++#define ETDM_CLK_DIV BIT(12) ++#define OUT_CLK_INV BIT(9) ++#define ETDM_OUT1_CON6 0x94 ++#define ETDM_OUT1_CON7 0x98 ++ ++#define AFE_DL1_BASE 0xa8 ++#define AFE_DL1_END 0xb0 ++#define AFE_DL1_CUR 0xac ++#define AFE_DL1_CON0 0xb4 ++#define AFE_PBUF_SIZE_SHIFT 16 ++#define AFE_PBUF_SIZE_MASK GENMASK(1, 0) ++#define AFE_MINLEN_SHIFT 8 ++#define AFE_MINLEN_MASK GENMASK(3, 0) ++#define AFE_HD_SHIFT 5 ++ ++#define AFE_UL1_BASE 0xc4 ++#define AFE_UL1_END 0xc8 ++#define AFE_UL1_CUR 0xcc ++#define AFE_UL1_CON0 0xd0 ++#define AFE_MSB_SHIFT 6 ++ ++#define AFE_IRQ_CON0 0xe4 ++#define AFE_IRQ_ON_SHIFT 0 ++#define AFE_IRQ_CLR_SHIFT 1 ++#define AFE_IRQ_CNT 0xe8 ++#define AFE_IRQ_CNT_SHIFT 0 ++#define AFE_IRQ_CNT_MASK GENMASK(31, 0) ++ ++#define AFE_IRQ_STS 0xf8 ++#define AFE_IRQ_STS_PLAY BIT(1) ++#define AFE_IRQ_STS_RECORD BIT(0) ++ ++#define AFE_IRQ1_CON0 0x100 ++#define AFE_IRQ1_CNT 0x104 ++ ++#define AFE_MAX_REGISTER AFE_IRQ1_CON0 ++ ++#endif +--- /dev/null ++++ b/sound/soc/mediatek/an7581/an7581-wm8960.c +@@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Airoha ALSA SoC I2S platform driver for AN7581 @@ -596,6 +1151,16 @@ Signed-off-by: Christian Marangi + +#include "an7581-afe-common.h" + ++static const struct snd_soc_dapm_widget an7581_wm8960_widgets[] = { ++ SND_SOC_DAPM_HP("Headphone", NULL), ++ SND_SOC_DAPM_MIC("AMIC", NULL), ++}; ++ ++static const struct snd_kcontrol_new an7581_wm8960_controls[] = { ++ SOC_DAPM_PIN_SWITCH("Headphone"), ++ SOC_DAPM_PIN_SWITCH("AMIC"), ++}; ++ +SND_SOC_DAILINK_DEFS(playback, + DAILINK_COMP_ARRAY(COMP_CPU("DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), @@ -606,10 +1171,16 @@ Signed-off-by: Christian Marangi + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + -+static struct snd_soc_dai_link an7581_i2s_dai_links[] = { ++SND_SOC_DAILINK_DEFS(codec, ++ DAILINK_COMP_ARRAY(COMP_CPU("ETDM")), ++ DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")), ++ DAILINK_COMP_ARRAY(COMP_EMPTY())); ++ ++static struct snd_soc_dai_link an7581_wm8960_dai_links[] = { ++ /* FE */ + { -+ .name = "an7581-i2s-playback", -+ .stream_name = "an7581-i2s-playback", ++ .name = "wm8960-playback", ++ .stream_name = "wm8960-playback", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .dynamic = 0, @@ -617,29 +1188,43 @@ Signed-off-by: Christian Marangi + SND_SOC_DAILINK_REG(playback), + }, + { -+ .name = "an7581-i2s-capture", -+ .stream_name = "an7581-i2s-capture", ++ .name = "wm8960-capture", ++ .stream_name = "wm8960-capture", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .dynamic = 0, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture), + }, ++ /* BE */ ++ { ++ .name = "wm8960-codec", ++ .no_pcm = 1, ++ .dai_fmt = SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBC_CFC | ++ SND_SOC_DAIFMT_GATED, ++ SND_SOC_DAILINK_REG(codec), ++ }, +}; + -+static struct snd_soc_card an7581_i2s_card = { -+ .name = "an7581-i2s", ++static struct snd_soc_card an7581_wm8960_card = { ++ .name = "an7581-wm8960", + .owner = THIS_MODULE, -+ .dai_link = an7581_i2s_dai_links, -+ .num_links = ARRAY_SIZE(an7581_i2s_dai_links), ++ .dai_link = an7581_wm8960_dai_links, ++ .num_links = ARRAY_SIZE(an7581_wm8960_dai_links), ++ .controls = an7581_wm8960_controls, ++ .num_controls = ARRAY_SIZE(an7581_wm8960_controls), ++ .dapm_widgets = an7581_wm8960_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(an7581_wm8960_widgets), +}; + -+static int an7581_i2s_machine_probe(struct platform_device *pdev) ++static int an7581_wm8960_machine_probe(struct platform_device *pdev) +{ -+ struct snd_soc_card *card = &an7581_i2s_card; -+ struct device_node *platform_dai_node; ++ struct device_node *platform_dai_node, *codec_dai_node; ++ struct snd_soc_card *card = &an7581_wm8960_card; ++ struct device_node *platform, *codec; + struct snd_soc_dai_link *dai_link; -+ struct device_node *platform; + int ret, i; + + card->dev = &pdev->dev; @@ -665,6 +1250,35 @@ Signed-off-by: Christian Marangi + dai_link->platforms->of_node = platform_dai_node; + } + ++ codec = of_get_child_by_name(pdev->dev.of_node, "codec"); ++ ++ if (codec) { ++ codec_dai_node = of_parse_phandle(codec, "sound-dai", 0); ++ of_node_put(codec); ++ ++ if (!codec_dai_node) { ++ of_node_put(platform_dai_node); ++ dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n"); ++ return -EINVAL; ++ } ++ } else { ++ of_node_put(platform_dai_node); ++ dev_err(&pdev->dev, "Property 'codec' missing or invalid\n"); ++ return -EINVAL; ++ } ++ ++ for_each_card_prelinks(card, i, dai_link) { ++ if (dai_link->codecs->name) ++ continue; ++ dai_link->codecs->of_node = codec_dai_node; ++ } ++ ++ ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to parse audio-routing: %d\n", ret); ++ goto err_of_node_put; ++ } ++ + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__); @@ -675,55 +1289,24 @@ Signed-off-by: Christian Marangi + +err_of_node_put: + of_node_put(platform_dai_node); ++ of_node_put(codec_dai_node); + return ret; +} + -+static const struct of_device_id an7581_i2s_machine_dt_match[] = { -+ { .compatible = "airoha,an7581-i2s" }, ++static const struct of_device_id an7581_wm8960_machine_dt_match[] = { ++ { .compatible = "airoha,an7581-wm8960-sound" }, + { /* sentinel */ } +}; -+MODULE_DEVICE_TABLE(of, an7581_i2s_machine_dt_match); ++MODULE_DEVICE_TABLE(of, an7581_wm8960_machine_dt_match); + -+static struct platform_driver an7581_i2s_driver = { ++static struct platform_driver an7581_wm8960_driver = { + .driver = { -+ .name = "an7581-i2s", -+ .of_match_table = an7581_i2s_machine_dt_match, ++ .name = "an7581-wm8960", ++ .of_match_table = an7581_wm8960_machine_dt_match, + }, -+ .probe = an7581_i2s_machine_probe, ++ .probe = an7581_wm8960_machine_probe, +}; -+module_platform_driver(an7581_i2s_driver); ++module_platform_driver(an7581_wm8960_driver); + +MODULE_DESCRIPTION("Airoha SoC I2S platform driver for ALSA AN7581"); +MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/sound/soc/airoha/an7581/an7581-reg.h -@@ -0,0 +1,29 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * an7581-reg.h -- Airoha AN7581 audio driver reg definition -+ */ -+ -+#ifndef _AN7581_REG_H_ -+#define _AN7581_REG_H_ -+ -+#define AFE_DAC_CON0 0x0 -+ -+#define AFE_DL1_BASE 0xa8 -+#define AFE_DL1_END 0xac -+#define AFE_DL1_CUR 0xb0 -+ -+#define AFE_UL1_BASE 0xc4 -+#define AFE_UL1_END 0xc8 -+#define AFE_UL1_CUR 0xcc -+ -+#define AFE_IRQ0_CON0 0xe4 -+ -+#define AFE_IRQ_STS 0xf8 -+#define AFE_IRQ_STS_PLAY BIT(1) -+#define AFE_IRQ_STS_RECORD BIT(0) -+ -+#define AFE_IRQ1_CON0 0x100 -+ -+#define AFE_MAX_REGISTER AFE_IRQ1_CON0 -+ -+#endif diff --git a/target/linux/bcm47xx/image/lzma-loader/src/LzmaDecode.c b/target/linux/bcm47xx/image/lzma-loader/src/LzmaDecode.c index a4aeda5f1f..900c7e7b49 100644 --- a/target/linux/bcm47xx/image/lzma-loader/src/LzmaDecode.c +++ b/target/linux/bcm47xx/image/lzma-loader/src/LzmaDecode.c @@ -185,6 +185,7 @@ int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder { int mi = 1; int i; + int symbol = 0; #ifdef _LZMA_LOC_OPT RC_INIT_VAR #endif @@ -202,7 +203,7 @@ int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder #ifdef _LZMA_LOC_OPT RC_FLUSH_VAR #endif - return 0; + return symbol; } Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) diff --git a/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch b/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch index abf19408a2..b1614eba44 100644 --- a/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch +++ b/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch @@ -58,7 +58,7 @@ Signed-off-by: Jonas Gorski + the phy interface, but actually requires internal delays enabled. --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c -@@ -1434,6 +1434,16 @@ static void b53_adjust_531x5_rgmii(struc +@@ -1444,6 +1444,16 @@ static void b53_adjust_531x5_rgmii(struc else off = B53_RGMII_CTRL_P(port); @@ -75,7 +75,7 @@ Signed-off-by: Jonas Gorski /* Configure the port RGMII clock delay by DLL disabled and * tx_clk aligned timing (restoring to reset defaults) */ -@@ -1445,19 +1455,24 @@ static void b53_adjust_531x5_rgmii(struc +@@ -1455,19 +1465,24 @@ static void b53_adjust_531x5_rgmii(struc * account for this internal delay that is inserted, otherwise * the switch won't be able to receive correctly. * diff --git a/target/linux/econet/dts/en751221.dtsi b/target/linux/econet/dts/en751221.dtsi index d512d0425a..0a2448cd1c 100644 --- a/target/linux/econet/dts/en751221.dtsi +++ b/target/linux/econet/dts/en751221.dtsi @@ -56,6 +56,93 @@ econet,shadow-interrupts = <7 2>, <8 3>, <13 12>, <30 29>; }; + ethernet: ethernet@1fb50000 { + compatible = "econet,en751221-eth"; + reg = <0x1fb50000 0x10000>; + + #address-cells = <1>; + #size-cells = <0>; + + interrupt-parent = <&intc>; + interrupts = <21>, <22>; + + gmac0: mac@0 { + compatible = "econet,eth-mac"; + reg = <0>; + phy-mode = "trgmii"; + status = "disabled"; + + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "econet,eth-mac"; + reg = <1>; + status = "disabled"; + phy-mode = "rgmii-rxid"; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch0: switch@1f { + compatible = "mediatek,mt7530"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1f>; + mediatek,mcm; + reset-names = "mcm"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + port@0 { + status = "disabled"; + reg = <0>; + label = "lan0"; + }; + + port@1 { + status = "disabled"; + reg = <1>; + label = "lan1"; + }; + + port@2 { + status = "disabled"; + reg = <2>; + label = "lan2"; + }; + + port@3 { + status = "disabled"; + reg = <3>; + label = "lan3"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + }; + }; + usb: usb@1fb90000 { compatible = "mediatek,mt8173-xhci", "mediatek,mtk-xhci"; reg = <0x1fb90000 0x4000>, diff --git a/target/linux/econet/dts/en751221_generic.dts b/target/linux/econet/dts/en751221_generic.dts index 375b9ebd3a..026f3e3739 100644 --- a/target/linux/econet/dts/en751221_generic.dts +++ b/target/linux/econet/dts/en751221_generic.dts @@ -50,3 +50,7 @@ }; }; }; + +&gmac0 { + status = "okay"; +}; diff --git a/target/linux/econet/dts/en751221_nokia_g240g-e.dts b/target/linux/econet/dts/en751221_nokia_g240g-e.dts index 7d82b566cc..68c314dbd9 100644 --- a/target/linux/econet/dts/en751221_nokia_g240g-e.dts +++ b/target/linux/econet/dts/en751221_nokia_g240g-e.dts @@ -29,95 +29,103 @@ partition@0 { label = "bootloader"; - reg = <0x00000000 0x00040000>; + reg = <0x0 0x40000>; read-only; }; partition@40000 { - // Unused label = "romfile"; - reg = <0x00040000 0x00040000>; + reg = <0x40000 0x40000>; }; partition@80000 { - // trx - OpenWRT kernel is 4MB, factory is 3MB - label = "kernel"; - reg = <0x00080000 0x00400000>; + label = "tclinux"; + reg = <0x80000 0x2200000>; + econet,enable-remap; }; - partition@380000 { - // squashfs + partition@480000 { label = "rootfs"; - reg = <0x00480000 0x01F00000>; + reg = <0x480000 0x1e00000>; linux,rootfs; }; partition@2280000 { - // trx label = "kernel_slave"; - reg = <0x02280000 0x00300000>; + reg = <0x2280000 0x300000>; }; partition@2580000 { - // squashfs label = "rootfs_slave"; - reg = <0x02580000 0x01F00000>; + reg = <0x2580000 0x1f00000>; }; partition@4480000 { - // trx label = "kernel_oflt"; - reg = <0x04480000 0x00300000>; + reg = <0x4480000 0x300000>; }; partition@4780000 { - // squashfs label = "rootfs_oflt"; - reg = <0x04780000 0x00C00000>; + reg = <0x4780000 0xc00000>; }; partition@5380000 { - // UBI label = "config"; - reg = <0x05380000 0x00800000>; + reg = <0x5380000 0x800000>; }; partition@5b80000 { - // UBI label = "log"; - reg = <0x05b80000 0x00C00000>; + reg = <0x5b80000 0xc00000>; }; partition@6780000 { - // UBI / unused label = "extfs"; - reg = <0x06780000 0x00600000>; + reg = <0x6780000 0x600000>; }; partition@6d80000 { - // binary label = "bosa"; - reg = <0x06d80000 0x00040000>; + reg = <0x6d80000 0x40000>; }; partition@6dc0000 { label = "flag"; - reg = <0x06dc0000 0x00040000>; + reg = <0x6dc0000 0x40000>; }; partition@6e00000 { label = "flagback"; - reg = <0x06e00000 0x00040000>; + reg = <0x6e00000 0x40000>; }; partition@6e40000 { label = "ri"; - reg = <0x06e40000 0x00040000>; + reg = <0x6e40000 0x40000>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_ri_3e: macaddr@3e { + compatible = "mac-base"; + reg = <0x3e 0x6>; + #nvmem-cell-cells = <1>; + }; + }; }; partition@6e80000 { label = "riback"; - reg = <0x06e80000 0x00040000>; + reg = <0x6e80000 0x40000>; }; }; }; + +&gmac0 { + status = "okay"; + nvmem-cells = <&macaddr_ri_3e 0>; + nvmem-cell-names = "mac-address"; +}; diff --git a/target/linux/econet/dts/en751221_smartfiber_xp8421-b.dts b/target/linux/econet/dts/en751221_smartfiber_xp8421-b.dts index 45654492a8..4599d34053 100644 --- a/target/linux/econet/dts/en751221_smartfiber_xp8421-b.dts +++ b/target/linux/econet/dts/en751221_smartfiber_xp8421-b.dts @@ -31,27 +31,35 @@ label = "bootloader"; reg = <0x0 0x40000>; read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_bootloader_ff48: macaddr@ff48 { + compatible = "mac-base"; + reg = <0xff48 0x6>; + #nvmem-cell-cells = <1>; + }; + }; }; partition@40000 { label = "romfile"; reg = <0x40000 0x40000>; - read-only; }; partition@80000 { label = "tclinux"; reg = <0x80000 0x1400000>; - read-only; econet,enable-remap; }; - /* Nested inside of tclinux */ partition@480000 { label = "rootfs"; reg = <0x480000 0xf80000>; linux,rootfs; - read-only; }; partition@1480000 { @@ -77,6 +85,28 @@ partition@de40000 { label = "reservearea"; reg = <0xde40000 0x1c0000>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_reserve_140000: eeprom@140000 { + /* MT7592 */ + reg = <0x140000 0x200>; + }; + + eeprom_reserve_180040: eeprom@180040 { + /* MT7612E */ + reg = <0x180040 0x600>; + }; + }; }; }; }; + +&gmac0 { + status = "okay"; + nvmem-cells = <&macaddr_bootloader_ff48 0>; + nvmem-cell-names = "mac-address"; +}; diff --git a/target/linux/econet/dts/en751221_tplink_archer-vr1200v-v2.dts b/target/linux/econet/dts/en751221_tplink_archer-vr1200v-v2.dts index 1866b446fd..2bc44d11cd 100644 --- a/target/linux/econet/dts/en751221_tplink_archer-vr1200v-v2.dts +++ b/target/linux/econet/dts/en751221_tplink_archer-vr1200v-v2.dts @@ -29,34 +29,63 @@ partition@0 { label = "bootloader"; - reg = <0x0 0x00080000>; + reg = <0x0 0x80000>; read-only; }; + partition@80000 { label = "misc"; - reg = <0x00080000 0x140000>; + reg = <0x80000 0x140000>; + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_misc_80000: eeprom@80000 { + /* MT7592 */ + reg = <0x80000 0x200>; + }; + + eeprom_misc_a0000: eeprom@a0000 { + /* MT7613BE */ + reg = <0xa0000 0x600>; + }; + + macaddr_misc_8f100: macaddr@8f100 { + compatible = "mac-base"; + reg = <0x4f100 0x6>; + #nvmem-cell-cells = <1>; + }; + }; }; - partition@1c0200 { - label = "kernel"; - reg = <0x001c0000 0x400000>; + + partition@1c0000 { + label = "tclinux"; + reg = <0x1c0000 0x1e40000>; + econet,enable-remap; }; + partition@5c0000 { label = "rootfs"; - reg = <0x005c0000 0x1a40000>; + reg = <0x5c0000 0x1a40000>; linux,rootfs; }; - partition@1c0000 { - label = "firmware"; - reg = <0x001c0000 0x1e40000>; - }; + partition@2000000 { label = "firmware_factory"; reg = <0x2000000 0x1e40000>; }; + + partition@3e40000 { + label = "unused"; + reg = <0x3e40000 0x1a0000>; + }; + partition@3fe0000 { label = "reserve"; reg = <0x3fe0000 0x20000>; }; + partition@4000000 { label = "openwrt_ubi"; /* From the factory this is unallocated space, so it's ours for the taking. @@ -67,3 +96,9 @@ }; }; }; + +&gmac0 { + status = "okay"; + nvmem-cells = <&macaddr_misc_8f100 0>; + nvmem-cell-names = "mac-address"; +}; diff --git a/target/linux/econet/en751221/config-6.12 b/target/linux/econet/en751221/config-6.12 index 653019f9c5..86991c3963 100644 --- a/target/linux/econet/en751221/config-6.12 +++ b/target/linux/econet/en751221/config-6.12 @@ -120,6 +120,9 @@ CONFIG_NET_INGRESS=y CONFIG_NET_XGRESS=y CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y CONFIG_NR_CPUS=2 +CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y +CONFIG_NVMEM_SYSFS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_EARLY_FLATTREE=y @@ -141,6 +144,7 @@ CONFIG_RANDSTRUCT_NONE=y CONFIG_RATIONAL=y CONFIG_RFS_ACCEL=y CONFIG_RPS=y +CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES=y CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SGL_ALLOC=y @@ -152,7 +156,6 @@ CONFIG_SPI=y CONFIG_SPI_AIROHA_EN7523=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y -CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_SYS_HAS_CPU_MIPS32_R1=y CONFIG_SYS_HAS_CPU_MIPS32_R2=y diff --git a/target/linux/generic/pending-6.12/750-01-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch b/target/linux/generic/backport-6.12/613-01-v6.19-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch similarity index 71% rename from target/linux/generic/pending-6.12/750-01-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch rename to target/linux/generic/backport-6.12/613-01-v6.19-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch index 6d5131d4b5..d953ea7545 100644 --- a/target/linux/generic/pending-6.12/750-01-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch +++ b/target/linux/generic/backport-6.12/613-01-v6.19-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch @@ -1,13 +1,20 @@ -From 36ee43df98b0ac16bb73e62fa8cffcdf710c37e4 Mon Sep 17 00:00:00 2001 +From 6f268e275c74dae0536e0b61982a8db25bcf4f16 Mon Sep 17 00:00:00 2001 From: Jonas Gorski -Date: Tue, 25 Nov 2025 08:51:44 +0100 +Date: Fri, 28 Nov 2025 09:06:19 +0100 Subject: [PATCH] net: dsa: b53: fix VLAN_ID_IDX write size for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Since BCM5325 and BCM5365 only support up to 256 VLANs, the VLAN_ID_IDX register is only 8 bit wide, not 16 bit, so use an appropriate accessor. Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-2-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski --- drivers/net/dsa/b53/b53_common.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/linux/generic/pending-6.12/750-02-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch b/target/linux/generic/backport-6.12/613-02-v6.19-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch similarity index 69% rename from target/linux/generic/pending-6.12/750-02-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch rename to target/linux/generic/backport-6.12/613-02-v6.19-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch index 54db56df21..72f81d020f 100644 --- a/target/linux/generic/pending-6.12/750-02-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch +++ b/target/linux/generic/backport-6.12/613-02-v6.19-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch @@ -1,7 +1,10 @@ -From 2bed2d0932c37d6cae9a745613c2e8f83649ed39 Mon Sep 17 00:00:00 2001 +From 9316012dd01952f75e37035360138ccc786ef727 Mon Sep 17 00:00:00 2001 From: Jonas Gorski -Date: Tue, 25 Nov 2025 08:51:45 +0100 +Date: Fri, 28 Nov 2025 09:06:20 +0100 Subject: [PATCH] net: dsa: b53: fix extracting VID from entry for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit BCM5325/65's Entry register uses the highest three bits for VALID/STATIC/AGE, so shifting by 53 only will add these to @@ -10,7 +13,11 @@ b53_arl_entry::vid. So make sure to mask the vid value as well, to not get invalid VIDs. Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-3-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski --- drivers/net/dsa/b53/b53_priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/generic/pending-6.12/750-03-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch b/target/linux/generic/backport-6.12/613-03-v6.19-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch similarity index 84% rename from target/linux/generic/pending-6.12/750-03-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch rename to target/linux/generic/backport-6.12/613-03-v6.19-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch index 8c4bb03cf0..4852df50be 100644 --- a/target/linux/generic/pending-6.12/750-03-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch +++ b/target/linux/generic/backport-6.12/613-03-v6.19-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch @@ -1,14 +1,21 @@ -From 8d2f3f0e87fe526686f7a2744bf965ce4e99ae41 Mon Sep 17 00:00:00 2001 +From 8e46aacea4264bcb8d4265fb07577afff58ae78d Mon Sep 17 00:00:00 2001 From: Jonas Gorski -Date: Tue, 25 Nov 2025 08:51:46 +0100 +Date: Fri, 28 Nov 2025 09:06:21 +0100 Subject: [PATCH] net: dsa: b53: use same ARL search result offset for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit BCM5365's search result is at the same offset as BCM5325's search result, and they (mostly) share the same format, so switch BCM5365 to BCM5325's arl ops. Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-4-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski --- drivers/net/dsa/b53/b53_common.c | 18 +----------------- drivers/net/dsa/b53/b53_regs.h | 4 +--- diff --git a/target/linux/generic/pending-6.12/750-04-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch b/target/linux/generic/backport-6.12/613-04-v6.19-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch similarity index 80% rename from target/linux/generic/pending-6.12/750-04-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch rename to target/linux/generic/backport-6.12/613-04-v6.19-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch index 47cfb01cc2..3748892ca8 100644 --- a/target/linux/generic/pending-6.12/750-04-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch +++ b/target/linux/generic/backport-6.12/613-04-v6.19-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch @@ -1,6 +1,6 @@ -From d0d7daf6e051f8795e4e1b759ff5055c80a85832 Mon Sep 17 00:00:00 2001 +From 85132103f700b1340fc17df8a981509d17bf4872 Mon Sep 17 00:00:00 2001 From: Jonas Gorski -Date: Tue, 25 Nov 2025 08:51:47 +0100 +Date: Fri, 28 Nov 2025 09:06:22 +0100 Subject: [PATCH] net: dsa: b53: fix CPU port unicast ARL entries for BCM5325/65 On BCM5325 and BCM5365, unicast ARL entries use 8 as the value for the @@ -9,6 +9,9 @@ at most other places. Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251128080625.27181-5-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski --- drivers/net/dsa/b53/b53_priv.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) @@ -27,7 +30,7 @@ Signed-off-by: Jonas Gorski u64_to_ether_addr(mac_vid, ent->mac); + ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & + ARLTBL_DATA_PORT_ID_MASK_25; -+ if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) ++ if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) + ent->port = B53_CPU_PORT_25; ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; } @@ -38,7 +41,7 @@ Signed-off-by: Jonas Gorski *mac_vid = ether_addr_to_u64(ent->mac); - *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << - ARLTBL_DATA_PORT_ID_S_25; -+ if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) ++ if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) + *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25; + else + *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << diff --git a/target/linux/generic/pending-6.12/750-05-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch b/target/linux/generic/backport-6.12/613-05-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch similarity index 91% rename from target/linux/generic/pending-6.12/750-05-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch rename to target/linux/generic/backport-6.12/613-05-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch index 59016c13f4..c0f5b5d600 100644 --- a/target/linux/generic/pending-6.12/750-05-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch +++ b/target/linux/generic/backport-6.12/613-05-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch @@ -1,6 +1,6 @@ -From 0a215e4d8da0c5e36ee29304879a111daff5b461 Mon Sep 17 00:00:00 2001 +From 3b08863469aa6028ac7c3120966f4e2f6051cf6b Mon Sep 17 00:00:00 2001 From: Jonas Gorski -Date: Tue, 25 Nov 2025 08:51:48 +0100 +Date: Fri, 28 Nov 2025 09:06:23 +0100 Subject: [PATCH] net: dsa: b53: fix BCM5325/65 ARL entry multicast port masks We currently use the mask 0xf for writing and reading b53_entry::port, @@ -20,7 +20,10 @@ contained in the Search Result Extension register. So create a separate search result parse function that properly handles this. Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-6-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski --- drivers/net/dsa/b53/b53_common.c | 4 +++- drivers/net/dsa/b53/b53_priv.h | 25 +++++++++++++++++++++---- @@ -53,11 +56,11 @@ Signed-off-by: Jonas Gorski - ARLTBL_DATA_PORT_ID_MASK_25; + ent->port = (mac_vid & ARLTBL_DATA_PORT_ID_MASK_25) >> + ARLTBL_DATA_PORT_ID_S_25; - if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) ent->port = B53_CPU_PORT_25; ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; @@ -388,8 +388,8 @@ static inline void b53_arl_from_entry_25 - if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25; else - *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << diff --git a/target/linux/generic/pending-6.12/750-06-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch b/target/linux/generic/backport-6.12/613-06-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch similarity index 93% rename from target/linux/generic/pending-6.12/750-06-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch rename to target/linux/generic/backport-6.12/613-06-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch index 8e579afda7..a2025f980c 100644 --- a/target/linux/generic/pending-6.12/750-06-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch +++ b/target/linux/generic/backport-6.12/613-06-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch @@ -1,6 +1,6 @@ -From d41f2d5f1c9c6d492ccd3ffdd09e064e70ebc934 Mon Sep 17 00:00:00 2001 +From d39514e6a2d14f57830d649e2bf03b49612c2f73 Mon Sep 17 00:00:00 2001 From: Jonas Gorski -Date: Tue, 25 Nov 2025 08:51:49 +0100 +Date: Fri, 28 Nov 2025 09:06:24 +0100 Subject: [PATCH] net: dsa: b53: fix BCM5325/65 ARL entry VIDs BCM5325/65's ARL entry registers do not contain the VID, only the search @@ -12,6 +12,9 @@ move the VLAN ID field definition to the search register definition. Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251128080625.27181-7-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski --- drivers/net/dsa/b53/b53_common.c | 9 +++++++-- drivers/net/dsa/b53/b53_priv.h | 12 ++++++------ @@ -60,7 +63,7 @@ Signed-off-by: Jonas Gorski ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); @@ -352,7 +352,7 @@ static inline void b53_arl_to_entry_25(s ARLTBL_DATA_PORT_ID_S_25; - if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) ent->port = B53_CPU_PORT_25; - ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; + ent->vid = vid_entry; diff --git a/target/linux/generic/backport-6.12/613-07-v6.19-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch b/target/linux/generic/backport-6.12/613-07-v6.19-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch new file mode 100644 index 0000000000..7c6a63fc91 --- /dev/null +++ b/target/linux/generic/backport-6.12/613-07-v6.19-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch @@ -0,0 +1,44 @@ +From 0b2b27058692d437b12d3f2a3bf0fa699af7376e Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Fri, 28 Nov 2025 09:06:25 +0100 +Subject: [PATCH] net: dsa: b53: allow VID 0 for BCM5325/65 + +Now that writing ARL entries works properly, we can actually use VID 0 +as the default untagged VLAN for BCM5325 and BCM5365 as well. + +So use 0 as default PVID for all chips and do not reject VLAN 0 anymore, +which we ignored since commit 45e9d59d3950 ("net: dsa: b53: do not allow +to configure VLAN 0") anyway. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251128080625.27181-8-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/b53/b53_common.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -852,10 +852,7 @@ static void b53_enable_stp(struct b53_de + + static u16 b53_default_pvid(struct b53_device *dev) + { +- if (is5325(dev) || is5365(dev)) +- return 1; +- else +- return 0; ++ return 0; + } + + static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port) +@@ -1679,9 +1676,6 @@ static int b53_vlan_prepare(struct dsa_s + { + struct b53_device *dev = ds->priv; + +- if ((is5325(dev) || is5365(dev)) && vlan->vid == 0) +- return -EOPNOTSUPP; +- + /* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of + * receiving VLAN tagged frames at all, we can still allow the port to + * be configured for egress untagged. diff --git a/target/linux/generic/pending-6.12/750-07-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch b/target/linux/generic/pending-6.12/750-07-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch deleted file mode 100644 index 9b255cc39f..0000000000 --- a/target/linux/generic/pending-6.12/750-07-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch +++ /dev/null @@ -1,175 +0,0 @@ -From b5a97c36457e4299afdb420603d39d1e30da843e Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Tue, 25 Nov 2025 08:51:50 +0100 -Subject: [PATCH] net: dsa: b53: allow VID 0 for BCM5325/65 - -Now that writing ARL entries works properly, we can actually use VID 0 -as the default untagged VLAN for BCM5325 and BCM5365 as well, so use 0 -as default PVID always. - -Signed-off-by: Jonas Gorski ---- - drivers/net/dsa/b53/b53_common.c | 49 +++++++++++--------------------- - 1 file changed, 17 insertions(+), 32 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -850,14 +850,6 @@ static void b53_enable_stp(struct b53_de - b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc); - } - --static u16 b53_default_pvid(struct b53_device *dev) --{ -- if (is5325(dev) || is5365(dev)) -- return 1; -- else -- return 0; --} -- - static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port) - { - struct b53_device *dev = ds->priv; -@@ -886,14 +878,12 @@ int b53_configure_vlan(struct dsa_switch - struct b53_device *dev = ds->priv; - struct b53_vlan vl = { 0 }; - struct b53_vlan *v; -- int i, def_vid; - u16 vid; -- -- def_vid = b53_default_pvid(dev); -+ int i; - - /* clear all vlan entries */ - if (is5325(dev) || is5365(dev)) { -- for (i = def_vid; i < dev->num_vlans; i++) -+ for (i = 0; i < dev->num_vlans; i++) - b53_set_vlan_entry(dev, i, &vl); - } else { - b53_do_vlan_op(dev, VTA_CMD_CLEAR); -@@ -907,7 +897,7 @@ int b53_configure_vlan(struct dsa_switch - * entry. Do this only when the tagging protocol is not - * DSA_TAG_PROTO_NONE - */ -- v = &dev->vlans[def_vid]; -+ v = &dev->vlans[0]; - b53_for_each_port(dev, i) { - if (!b53_vlan_port_may_join_untagged(ds, i)) - continue; -@@ -915,16 +905,15 @@ int b53_configure_vlan(struct dsa_switch - vl.members |= BIT(i); - if (!b53_vlan_port_needs_forced_tagged(ds, i)) - vl.untag = vl.members; -- b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(i), -- def_vid); -+ b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(i), 0); - } -- b53_set_vlan_entry(dev, def_vid, &vl); -+ b53_set_vlan_entry(dev, 0, &vl); - - if (dev->vlan_filtering) { - /* Upon initial call we have not set-up any VLANs, but upon - * system resume, we need to restore all VLAN entries. - */ -- for (vid = def_vid + 1; vid < dev->num_vlans; vid++) { -+ for (vid = 1; vid < dev->num_vlans; vid++) { - v = &dev->vlans[vid]; - - if (!v->members) -@@ -1260,7 +1249,6 @@ static int b53_setup(struct dsa_switch * - struct b53_device *dev = ds->priv; - struct b53_vlan *vl; - unsigned int port; -- u16 pvid; - int ret; - - /* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set -@@ -1290,8 +1278,7 @@ static int b53_setup(struct dsa_switch * - } - - /* setup default vlan for filtering mode */ -- pvid = b53_default_pvid(dev); -- vl = &dev->vlans[pvid]; -+ vl = &dev->vlans[0]; - b53_for_each_port(dev, port) { - vl->members |= BIT(port); - if (!b53_vlan_port_needs_forced_tagged(ds, port)) -@@ -1720,7 +1707,7 @@ int b53_vlan_add(struct dsa_switch *ds, - if (pvid) - new_pvid = vlan->vid; - else if (!pvid && vlan->vid == old_pvid) -- new_pvid = b53_default_pvid(dev); -+ new_pvid = 0; - else - new_pvid = old_pvid; - dev->ports[port].pvid = new_pvid; -@@ -1770,7 +1757,7 @@ int b53_vlan_del(struct dsa_switch *ds, - vl->members &= ~BIT(port); - - if (pvid == vlan->vid) -- pvid = b53_default_pvid(dev); -+ pvid = 0; - dev->ports[port].pvid = pvid; - - if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port)) -@@ -2249,7 +2236,7 @@ int b53_br_join(struct dsa_switch *ds, i - struct b53_device *dev = ds->priv; - struct b53_vlan *vl; - s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -- u16 pvlan, reg, pvid; -+ u16 pvlan, reg; - unsigned int i; - - /* On 7278, port 7 which connects to the ASP should only receive -@@ -2258,8 +2245,7 @@ int b53_br_join(struct dsa_switch *ds, i - if (dev->chip_id == BCM7278_DEVICE_ID && port == 7) - return -EINVAL; - -- pvid = b53_default_pvid(dev); -- vl = &dev->vlans[pvid]; -+ vl = &dev->vlans[0]; - - if (dev->vlan_filtering) { - /* Make this port leave the all VLANs join since we will have -@@ -2275,9 +2261,9 @@ int b53_br_join(struct dsa_switch *ds, i - reg); - } - -- b53_get_vlan_entry(dev, pvid, vl); -+ b53_get_vlan_entry(dev, 0, vl); - vl->members &= ~BIT(port); -- b53_set_vlan_entry(dev, pvid, vl); -+ b53_set_vlan_entry(dev, 0, vl); - } - - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); -@@ -2316,7 +2302,7 @@ void b53_br_leave(struct dsa_switch *ds, - struct b53_vlan *vl; - s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - unsigned int i; -- u16 pvlan, reg, pvid; -+ u16 pvlan, reg; - - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); - -@@ -2341,8 +2327,7 @@ void b53_br_leave(struct dsa_switch *ds, - b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); - dev->ports[port].vlan_ctl_mask = pvlan; - -- pvid = b53_default_pvid(dev); -- vl = &dev->vlans[pvid]; -+ vl = &dev->vlans[0]; - - if (dev->vlan_filtering) { - /* Make this port join all VLANs without VLAN entries */ -@@ -2354,9 +2339,9 @@ void b53_br_leave(struct dsa_switch *ds, - b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); - } - -- b53_get_vlan_entry(dev, pvid, vl); -+ b53_get_vlan_entry(dev, 0, vl); - vl->members |= BIT(port); -- b53_set_vlan_entry(dev, pvid, vl); -+ b53_set_vlan_entry(dev, 0, vl); - } - } - EXPORT_SYMBOL(b53_br_leave); diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c index 5b3f21c92f..3bf2c2e83c 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c @@ -1464,13 +1464,13 @@ int rt3050_esw_init(struct fe_priv *priv) const __be32 *rgmii; int ret; - if (!pdev) - return -ENODEV; - if (!of_device_is_compatible(np, ralink_esw_match->compatible)) return -EINVAL; pdev = of_find_device_by_node(np); + if (!pdev) + return -ENODEV; + esw = platform_get_drvdata(pdev); if (!esw) { put_device(&pdev->dev); diff --git a/target/linux/rockchip/patches-6.12/036-05-v6.19-mmc-sdhci-of-dwcmshc-Fix-command-queue-support-for-RK3576.patch b/target/linux/rockchip/patches-6.12/036-05-v6.19-mmc-sdhci-of-dwcmshc-Fix-command-queue-support-for-RK3576.patch new file mode 100644 index 0000000000..c4d9689507 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/036-05-v6.19-mmc-sdhci-of-dwcmshc-Fix-command-queue-support-for-RK3576.patch @@ -0,0 +1,55 @@ +From 69cc9d4075855661268327c38c9b0e71ac37eb1c Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 21 Nov 2025 17:26:59 +0100 +Subject: [PATCH] mmc: sdhci-of-dwcmshc: Fix command queue support for RK3576 + +When I added command queue engine (CQE) support for the Rockchip eMMC +controller, I missed that RK3576 has a separate platform data struct. +While things are working fine on RK3588 (I tested the ROCK 5B) and +the suspend issue is fixed on the RK3576 (I tested the Sige5), this +results in stability issues. By also adding the necessary hooks for +the RK3576 platform the following problems can be avoided: + +[ 15.606895] mmc0: running CQE recovery +[ 15.616189] mmc0: running CQE recovery +[...] +[ 25.911484] mmc0: running CQE recovery +[ 25.926305] mmc0: running CQE recovery +[ 25.927468] mmc0: running CQE recovery +[...] +[ 26.255719] mmc0: running CQE recovery +[ 26.257162] ------------[ cut here ]------------ +[ 26.257581] mmc0: cqhci: spurious TCN for tag 31 +[ 26.258034] WARNING: CPU: 0 PID: 0 at drivers/mmc/host/cqhci-core.c:796 cqhci_irq+0x440/0x68c +[ 26.263786] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.18.0-rc6-gd984ebbf0d15 #1 PREEMPT +[ 26.264561] Hardware name: ArmSoM Sige5 (DT) +[...] +[ 26.272748] Call trace: +[ 26.272964] cqhci_irq+0x440/0x68c (P) +[ 26.273296] dwcmshc_cqe_irq_handler+0x54/0x88 +[ 26.273689] sdhci_irq+0xbc/0x1200 +[ 26.273991] __handle_irq_event_percpu+0x54/0x1d0 +[...] + +Note that the above problems do not necessarily happen with every boot. + +Reported-by: Adrian Hunter +Closes: https://lore.kernel.org/linux-rockchip/01949bc9-4873-498b-ac7d-f008393ccc4c@intel.com/ +Fixes: fda1e0af7c28f ("mmc: sdhci-of-dwcmshc: Add command queue support for rockchip SOCs") +Signed-off-by: Sebastian Reichel +Reviewed-by: Shawn Lin +Signed-off-by: Ulf Hansson +--- + drivers/mmc/host/sdhci-of-dwcmshc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -1333,6 +1333,7 @@ static const struct dwcmshc_pltfm_data s + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, + }, ++ .cqhci_host_ops = &rk35xx_cqhci_ops, + .init = dwcmshc_rk35xx_init, + .postinit = dwcmshc_rk3576_postinit, + }; diff --git a/target/linux/rockchip/patches-6.12/036-06-v6.19-mmc-sdhci-of-dwcmshc-Disable-internal-clock-auto-gate-for.patch b/target/linux/rockchip/patches-6.12/036-06-v6.19-mmc-sdhci-of-dwcmshc-Disable-internal-clock-auto-gate-for.patch new file mode 100644 index 0000000000..d8a0ed8d14 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/036-06-v6.19-mmc-sdhci-of-dwcmshc-Disable-internal-clock-auto-gate-for.patch @@ -0,0 +1,42 @@ +From c7ce6453b769c45006ed4983762f81e130878171 Mon Sep 17 00:00:00 2001 +From: Shawn Lin +Date: Wed, 26 Nov 2025 07:26:39 +0800 +Subject: [PATCH] mmc: sdhci-of-dwcmshc: Disable internal clock auto gate for + Rockchip SOCs + +Enabling CMDQ support can lead to random occurrences of the error log when +there are RPMB access and data flush executed: + +"mmc2: Timeout waiting for hardware interrupt." + +Enabling CMDQ and then issuing a DCMD as the final command before disabling +it causes the eMMC controller to auto-gate its internal clock. Chip simulation +shows this results in a state machine mismatch after CMDQ mode exit, triggering +data-timeout errors for all subsequent read and write operations. + +Therefore, the auto-clock-gate function must be disabled whenever CMDQ is +enabled. + +Signed-off-by: Shawn Lin +Acked-by: Adrian Hunter +Fixes: fda1e0af7c28 ("mmc: sdhci-of-dwcmshc: Add command queue support for rockchip SOCs") +Signed-off-by: Ulf Hansson +--- + drivers/mmc/host/sdhci-of-dwcmshc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -696,10 +696,11 @@ static void dwcmshc_rk3568_set_clock(str + + sdhci_set_clock(host, clock); + +- /* Disable cmd conflict check */ ++ /* Disable cmd conflict check and internal clock gate */ + reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; + extra = sdhci_readl(host, reg); + extra &= ~BIT(0); ++ extra |= BIT(4); + sdhci_writel(host, extra, reg); + + if (clock <= 52000000) { diff --git a/target/linux/rockchip/patches-6.12/036-07-v6.19-mmc-sdhci-of-dwcmshc-reduce-CIT-for-better-performance.patch b/target/linux/rockchip/patches-6.12/036-07-v6.19-mmc-sdhci-of-dwcmshc-reduce-CIT-for-better-performance.patch new file mode 100644 index 0000000000..90647d96c3 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/036-07-v6.19-mmc-sdhci-of-dwcmshc-reduce-CIT-for-better-performance.patch @@ -0,0 +1,44 @@ +From 79cf71c0b177c0e23d411e2469435e2c2f83f563 Mon Sep 17 00:00:00 2001 +From: Shawn Lin +Date: Wed, 26 Nov 2025 07:26:40 +0800 +Subject: [PATCH] mmc: sdhci-of-dwcmshc: reduce CIT for better performance + +CQHCI_SSC1.CIT indicates to the CQE the polling period to use for +periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one +hardware queue, and CMD13 can only query one slot at a time for data +transmission, which cannot be processed in parallel. Modifying the +CMD13 query interval can increase the query frequency and improve +random write performance. + +Signed-off-by: Shawn Lin +Acked-by: Adrian Hunter +Signed-off-by: Ulf Hansson +--- + drivers/mmc/host/cqhci.h | 1 + + drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/drivers/mmc/host/cqhci.h ++++ b/drivers/mmc/host/cqhci.h +@@ -93,6 +93,7 @@ + /* send status config 1 */ + #define CQHCI_SSC1 0x40 + #define CQHCI_SSC1_CBC_MASK GENMASK(19, 16) ++#define CQHCI_SSC1_CIT_MASK GENMASK(15, 0) + + /* send status config 2 */ + #define CQHCI_SSC2 0x44 +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -614,6 +614,11 @@ static void rk35xx_sdhci_cqe_pre_enable( + struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host); + u32 reg; + ++ /* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */ ++ reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1); ++ reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100; ++ sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1); ++ + reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG); + reg |= CQHCI_ENABLE; + sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG); diff --git a/target/sdk/Makefile b/target/sdk/Makefile index 19096f9aea..9583064ed6 100644 --- a/target/sdk/Makefile +++ b/target/sdk/Makefile @@ -41,13 +41,13 @@ SDK_DIRS = \ GIT_URL:=$(shell git config --get remote.origin.url 2>/dev/null) GIT_URL:=$(if $(CONFIG_BUILDBOT),$(filter git://% http://% https://%,$(GIT_URL)),$(GIT_URL)) GIT_COMMIT:=$(shell git rev-parse HEAD 2>/dev/null) -GIT_BRANCH:=$(filter-out master HEAD,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)) +GIT_BRANCH:=$(filter-out master main HEAD,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)) GIT_TAGNAME:=$(shell git show-ref --tags --dereference 2>/dev/null | sed -ne '/^$(GIT_COMMIT) / { s|^.*/||; s|\^.*||; p }') -BASE_FEED:=$(if $(GIT_URL),src-git --root=package base $(GIT_URL)$(if $(GIT_BRANCH),;$(GIT_BRANCH),$(if $(GIT_TAGNAME),;$(GIT_TAGNAME)))) +BASE_FEED:=$(if $(GIT_URL),src-git --root=package base $(GIT_URL)$(if $(CONFIG_BUILDBOT),^$(GIT_COMMIT),$(if $(GIT_TAGNAME),;$(GIT_TAGNAME),$(if $(GIT_BRANCH),;$(GIT_BRANCH))))) BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),$(shell cd $(TOPDIR); LC_ALL=C git svn info 2>/dev/null | sed -ne 's/^URL: /src-gitsvn --root=package base /p')) BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),$(shell cd $(TOPDIR); LC_ALL=C svn info 2>/dev/null | sed -ne 's/^URL: /src-svn --root=package base /p')) -BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),src-git --root=package base https://github.com/immortalwrt/immortalwrt.git$(if $(GIT_BRANCH),;$(GIT_BRANCH),$(if $(GIT_TAGNAME),;$(GIT_TAGNAME)))) +BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),src-git --root=package base https://github.com/immortalwrt/immortalwrt.git$(if $(CONFIG_BUILDBOT),^$(GIT_COMMIT),$(if $(GIT_TAGNAME),;$(GIT_TAGNAME),$(if $(GIT_BRANCH),;$(GIT_BRANCH))))) KDIR_BASE = $(patsubst $(TOPDIR)/%,%,$(LINUX_DIR)) KDIR_ARCHES = $(LINUX_KARCH) diff --git a/tools/gnulib/Makefile b/tools/gnulib/Makefile index 018ff5db14..0b28d73d13 100644 --- a/tools/gnulib/Makefile +++ b/tools/gnulib/Makefile @@ -20,8 +20,10 @@ endef define Host/Install $(call Host/Uninstall) $(INSTALL_DIR) $(1)/share/aclocal - $(foreach m4,$(notdir $(wildcard $(HOST_BUILD_DIR)/m4/*.m4)), - $(INSTALL_DATA) $(HOST_BUILD_DIR)/m4/$(m4) $(1)/share/aclocal/gl_$(m4)) + for m4 in $(HOST_BUILD_DIR)/m4/*.m4; do \ + $(INSTALL_DATA) $(HOST_BUILD_DIR)/m4/$$$$(basename $$$$m4) \ + $(1)/share/aclocal/gl_$$$$(basename $$$$m4); \ + done $(CP) $(HOST_BUILD_DIR)/ $(1)/share/gnulib/ ln -sf ../share/gnulib/gnulib-tool $(STAGING_DIR_HOST)/bin/gnulib-tool endef