From nobody Thu Oct 2 09:16:52 2025 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 00BBA3F9FB; Thu, 18 Sep 2025 15:50:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.17.235.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210636; cv=none; b=OJkECFflX6x9g9tsmoNIUqIIa8DeWLE4L2ZPkXMgdHcQpjw1hQm3nc8j+OP0K+OsWeSrk0tQnmV+fUL6SA7BZU5S/YULW5L3UMQe8129Io3qz1+hvAgJQZCMzg0I1FCAPnA/+9RPEHVvAKWn1SdA+w4Pli8iJvO4tJ4Ah+E4DQs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210636; c=relaxed/simple; bh=3ueV0+TWEXT+lbHC1mnyBhAYLOCSJuYccHwKxxNUhFc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p7frbzkxylmwkxcUlsgd5HWA8teOd1r6NyPdQOFRAJ1Z1Cs9/rqs6G1SUiJ010Le6oVRaexYKaKUy40nhLIZjK7QiCq1FpAtSHFsj1cuCcqCGFjPolOWsi2q1HY0SHdPEkaAh0C60GMPi9KuazjhGK/lAQxEhOWNrKImqQHjD6k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu; spf=pass smtp.mailfrom=csgroup.eu; arc=none smtp.client-ip=93.17.235.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub4.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4cSKSQ3kppz9sg0; Thu, 18 Sep 2025 17:34:30 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HDEkcH1IVVyx; Thu, 18 Sep 2025 17:34:30 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4cSKSQ2bD1z9sfv; Thu, 18 Sep 2025 17:34:30 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 439198B776; Thu, 18 Sep 2025 17:34:30 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id LGlByoGo7Cr9; Thu, 18 Sep 2025 17:34:30 +0200 (CEST) Received: from PO20335.idsi0.si.c-s.fr (unknown [192.168.235.99]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 76C7A8B767; Thu, 18 Sep 2025 17:34:29 +0200 (CEST) From: Christophe Leroy To: Herve Codina , Qiang Zhao , Shengjiu Wang , Xiubo Li , Fabio Estevam , Nicolin Chen , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Christophe Leroy , linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH RESEND v3 1/4] soc: fsl: qmc: Only set completion interrupt when needed Date: Thu, 18 Sep 2025 17:34:08 +0200 Message-ID: <40b41b53a26e77a50b3a5f68fcecc6f9a40a84b4.1758209158.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1758209657; l=3349; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=3ueV0+TWEXT+lbHC1mnyBhAYLOCSJuYccHwKxxNUhFc=; b=7YoDVmchoSPIi4mkTR5smUVwENM9xsvOMPjROEZI9uTWYid5RyMwIeB5cXfTLUQ7gKIPzZfPK woyB7SkM8ZiCdywhXXs3gY5r5gykus9J3L5aR213Bh6Wb4klHtJd3sV X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When no post-completion processing is expected, don't waste time handling useless interrupts. Only set QMC_BD_[R/T]X_I when a completion function is passed in, and perform seamless completion on submit for interruptless buffers. Acked-by: Herve Codina Signed-off-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 44 ++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 36c0ccc06151..da5ea6d35618 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -461,9 +461,16 @@ int qmc_chan_write_submit(struct qmc_chan *chan, dma_a= ddr_t addr, size_t length, =20 ctrl =3D qmc_read16(&bd->cbd_sc); if (ctrl & (QMC_BD_TX_R | QMC_BD_TX_UB)) { - /* We are full ... */ - ret =3D -EBUSY; - goto end; + if (!(ctrl & (QMC_BD_TX_R | QMC_BD_TX_I)) && bd =3D=3D chan->txbd_done) { + if (ctrl & QMC_BD_TX_W) + chan->txbd_done =3D chan->txbds; + else + chan->txbd_done++; + } else { + /* We are full ... */ + ret =3D -EBUSY; + goto end; + } } =20 qmc_write16(&bd->cbd_datlen, length); @@ -475,6 +482,10 @@ int qmc_chan_write_submit(struct qmc_chan *chan, dma_a= ddr_t addr, size_t length, =20 /* Activate the descriptor */ ctrl |=3D (QMC_BD_TX_R | QMC_BD_TX_UB); + if (complete) + ctrl |=3D QMC_BD_TX_I; + else + ctrl &=3D ~QMC_BD_TX_I; wmb(); /* Be sure to flush the descriptor before control update */ qmc_write16(&bd->cbd_sc, ctrl); =20 @@ -569,9 +580,16 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_ad= dr_t addr, size_t length, =20 ctrl =3D qmc_read16(&bd->cbd_sc); if (ctrl & (QMC_BD_RX_E | QMC_BD_RX_UB)) { - /* We are full ... */ - ret =3D -EBUSY; - goto end; + if (!(ctrl & (QMC_BD_RX_E | QMC_BD_RX_I)) && bd =3D=3D chan->rxbd_done) { + if (ctrl & QMC_BD_RX_W) + chan->rxbd_done =3D chan->rxbds; + else + chan->rxbd_done++; + } else { + /* We are full ... */ + ret =3D -EBUSY; + goto end; + } } =20 qmc_write16(&bd->cbd_datlen, 0); /* data length is updated by the QMC */ @@ -587,6 +605,10 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_ad= dr_t addr, size_t length, =20 /* Activate the descriptor */ ctrl |=3D (QMC_BD_RX_E | QMC_BD_RX_UB); + if (complete) + ctrl |=3D QMC_BD_RX_I; + else + ctrl &=3D ~QMC_BD_RX_I; wmb(); /* Be sure to flush data before descriptor activation */ qmc_write16(&bd->cbd_sc, ctrl); =20 @@ -1482,19 +1504,19 @@ static int qmc_setup_chan(struct qmc *qmc, struct q= mc_chan *chan) =20 /* Init Rx BDs and set Wrap bit on last descriptor */ BUILD_BUG_ON(QMC_NB_RXBDS =3D=3D 0); - val =3D QMC_BD_RX_I; for (i =3D 0; i < QMC_NB_RXBDS; i++) { bd =3D chan->rxbds + i; - qmc_write16(&bd->cbd_sc, val); + qmc_write16(&bd->cbd_sc, 0); } bd =3D chan->rxbds + QMC_NB_RXBDS - 1; - qmc_write16(&bd->cbd_sc, val | QMC_BD_RX_W); + qmc_write16(&bd->cbd_sc, QMC_BD_RX_W); =20 /* Init Tx BDs and set Wrap bit on last descriptor */ BUILD_BUG_ON(QMC_NB_TXBDS =3D=3D 0); - val =3D QMC_BD_TX_I; if (chan->mode =3D=3D QMC_HDLC) - val |=3D QMC_BD_TX_L | QMC_BD_TX_TC; + val =3D QMC_BD_TX_L | QMC_BD_TX_TC; + else + val =3D 0; for (i =3D 0; i < QMC_NB_TXBDS; i++) { bd =3D chan->txbds + i; qmc_write16(&bd->cbd_sc, val); --=20 2.49.0 From nobody Thu Oct 2 09:16:52 2025 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4B466313540; Thu, 18 Sep 2025 15:50:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.17.235.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210646; cv=none; b=TYnafLZheP+m/aU67C7ktO+ae3sr3+Qokbi3KRrw0+Fb/PCMoED/XxUYVWvcBh5rCAVRzWRHCww6yoEl4a564v7yPzSLVcodthRYSwbUmDKrLASX9acDXuRRHK9bfyDTgbAdmXlJUnkZ+p/dNLMxknY3kcAckK7pYOXtKz0rJsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210646; c=relaxed/simple; bh=PhCdmcBJPdWMbFjoZdGBw3gyDb5r2JgdoYXKwih9mSw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VP+W8xMAZg4uGLwaOsWsH9PFGHaGANUVoHUmy1qA7Pz3vLKhFAhRZrMeLio7a5399N6o8tBNwwgW766Vfn+MzliP/BW5oMdIwEHQfQvbxhMCIdTaBk3dAn2942aYTMG4n3LajBOdsAJ20BWpuw7xazMiDwT7n+EXBoe4xpdI0zk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu; spf=pass smtp.mailfrom=csgroup.eu; arc=none smtp.client-ip=93.17.235.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub4.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4cSKSR28vLz9sg1; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Z7_lta6qXCna; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4cSKSR15xZz9sfv; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 15DCD8B767; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id dYGLOMvVr6vT; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) Received: from PO20335.idsi0.si.c-s.fr (unknown [192.168.235.99]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 40FA78B775; Thu, 18 Sep 2025 17:34:30 +0200 (CEST) From: Christophe Leroy To: Herve Codina , Qiang Zhao , Shengjiu Wang , Xiubo Li , Fabio Estevam , Nicolin Chen , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Christophe Leroy , linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH RESEND v3 2/4] ASoc: fsl: fsl_qmc_audio: Ensure audio channels are ordered in TDM bus Date: Thu, 18 Sep 2025 17:34:09 +0200 Message-ID: <4ff40afdf3d032b05dd4af6c0f777d4d4b445a76.1758209158.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1758209657; l=2268; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=PhCdmcBJPdWMbFjoZdGBw3gyDb5r2JgdoYXKwih9mSw=; b=ruBvohcdwTV13JzsoBOhlDufd3DsKpD4cOPOEYuGWSfm6Ozs7idM1/CNZLZUOMe9VBZP4mWZ2 thJrF3KAZaWDljbSlUr+XfoKg14q6ra/HyrJIPSjZZGr0vqZjORgflI X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To reduce complexity of interrupt handling in following patch, ensure audio channels are configured in the same order as timeslots on the TDM bus. If we need a given ordering of audio sources in the audio frame, it is possible to re-order codecs on the TDM bus, no need to mix up timeslots in channels. Acked-by: Herve Codina Signed-off-by: Christophe Leroy --- sound/soc/fsl/fsl_qmc_audio.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c index 5614a8b909ed..c0c7ef0a1511 100644 --- a/sound/soc/fsl/fsl_qmc_audio.c +++ b/sound/soc/fsl/fsl_qmc_audio.c @@ -791,12 +791,17 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_= audio, struct device_node * struct qmc_dai *qmc_dai, struct snd_soc_dai_driver *qmc_soc_dai_driver) { + struct qmc_chan_ts_info ts_info; struct qmc_chan_info info; unsigned long rx_fs_rate; unsigned long tx_fs_rate; + int prev_last_rx_ts =3D 0; + int prev_last_tx_ts =3D 0; unsigned int nb_tx_ts; unsigned int nb_rx_ts; unsigned int i; + int last_rx_ts; + int last_tx_ts; int count; u32 val; int ret; @@ -879,6 +884,30 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_a= udio, struct device_node * return -EINVAL; } } + + ret =3D qmc_chan_get_ts_info(qmc_dai->chans[i].qmc_chan, &ts_info); + if (ret) { + dev_err(qmc_audio->dev, "dai %d get QMC %d channel TS info failed %d\n", + qmc_dai->id, i, ret); + return ret; + } + + last_rx_ts =3D fls64(ts_info.rx_ts_mask); + last_tx_ts =3D fls64(ts_info.tx_ts_mask); + + if (prev_last_rx_ts > last_rx_ts) { + dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (RX time= slot %d before %d)\n", + qmc_dai->id, i, prev_last_rx_ts, last_rx_ts); + return -EINVAL; + } + if (prev_last_tx_ts > last_tx_ts) { + dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (TX time= slot %d before %d)\n", + qmc_dai->id, i, prev_last_tx_ts, last_tx_ts); + return -EINVAL; + } + + prev_last_rx_ts =3D last_rx_ts; + prev_last_tx_ts =3D last_tx_ts; } =20 qmc_dai->nb_chans_avail =3D count; --=20 2.49.0 From nobody Thu Oct 2 09:16:52 2025 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1F5AE3148C9; Thu, 18 Sep 2025 15:50:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.17.235.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210652; cv=none; b=dV+Su4n6r3UhMt9LEWkqfYIm58IFtE+NxecvX/jX1rkPQpt+suLNEDyp21u/LhvLL1E3a4x0vGmdcFZ2iKaXXN3wlruwCh2RuaY0CNjAMGJYuR3uX9qFM4R7wnRLokpA3S3rb4VPyof15pTvUbSX9L95FOJa/lSqtT39R/+HyeQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210652; c=relaxed/simple; bh=X4wuqoJpWXmIdrxYayEnw6eOSBXb//enGdJw05ySXnk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZgDQqwyX/5h68zrujTQNHRbpiAbqifO91X0v3mAN1OpogGWEIZ9MIMRTf/elbRbkFNuJAb0mVbzXYd/JZSQ0PkzbKAKx2A6q8BqJPHmI6TAfRveGVdJiyee5oyDZoSMwyTuoURJ0bilD5eKeXwEaOKQEcYZx2hxoA0nreP6nizI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu; spf=pass smtp.mailfrom=csgroup.eu; arc=none smtp.client-ip=93.17.235.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub4.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4cSKSS1qhmz9sg3; Thu, 18 Sep 2025 17:34:32 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Hva2kIU2-6vX; Thu, 18 Sep 2025 17:34:32 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4cSKSS0Z9jz9sg2; Thu, 18 Sep 2025 17:34:32 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id E8B178B767; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id QD_i62Bf5ayM; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) Received: from PO20335.idsi0.si.c-s.fr (unknown [192.168.235.99]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 212A18B775; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) From: Christophe Leroy To: Herve Codina , Qiang Zhao , Shengjiu Wang , Xiubo Li , Fabio Estevam , Nicolin Chen , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Christophe Leroy , linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH RESEND v3 3/4] ASoC: fsl: fsl_qmc_audio: Only request completion on last channel Date: Thu, 18 Sep 2025 17:34:10 +0200 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1758209657; l=4994; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=X4wuqoJpWXmIdrxYayEnw6eOSBXb//enGdJw05ySXnk=; b=5i6LXaaOIEGn520Ma2k6jL70nix73aVbzgnhaVpZ96giQjjDNoTQigsFLYRNulLzciRKhomQw T17+p9Jsyw+CV8tEilZBBmbOg7wVXk8HGtmOEUvRzIvM8IgLSuRMana X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In non-interleaved mode, several QMC channels are used in sync. More details can be found in commit 188d9cae5438 ("ASoC: fsl: fsl_qmc_audio: Add support for non-interleaved mode.") At the time being, an interrupt is requested on each channel to perform capture/playback completion, allthough the completion is really performed only once all channels have completed their work. This leads to a lot more interrupts than really needed. Looking at /proc/interrupts shows ~3800 interrupts per second when using 4 capture and 4 playback devices with 5ms periods while only 1600 (200 x 4 + 200 x 4) periods are processed during one second. The QMC channels work in sync, the one started first is the one finishing first and the one started last is the one finishing last, so when the last one finishes it is guaranteed that the other ones are finished as well. Therefore only request completion processing on the last QMC channel. On my board with the above exemple, on a kernel started with 'threadirqs' option, the QMC irq thread uses 16% CPU time with this patch while it uses 26% CPU time without this patch. Acked-by: Herve Codina Signed-off-by: Christophe Leroy --- sound/soc/fsl/fsl_qmc_audio.c | 46 +++++------------------------------ 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c index c0c7ef0a1511..2790953543c5 100644 --- a/sound/soc/fsl/fsl_qmc_audio.c +++ b/sound/soc/fsl/fsl_qmc_audio.c @@ -57,7 +57,6 @@ struct qmc_dai_prtd { size_t ch_dma_offset; =20 unsigned int channels; - DECLARE_BITMAP(chans_pending, 64); struct snd_pcm_substream *substream; }; =20 @@ -126,17 +125,14 @@ static int qmc_audio_pcm_write_submit(struct qmc_dai_= prtd *prtd) int ret; =20 for (i =3D 0; i < prtd->channels; i++) { - bitmap_set(prtd->chans_pending, i, 1); - ret =3D qmc_chan_write_submit(prtd->qmc_dai->chans[i].qmc_chan, prtd->ch_dma_addr_current + i * prtd->ch_dma_offset, prtd->ch_dma_size, - qmc_audio_pcm_write_complete, - &prtd->qmc_dai->chans[i]); + i =3D=3D prtd->channels - 1 ? qmc_audio_pcm_write_complete : + NULL, prtd); if (ret) { dev_err(prtd->qmc_dai->dev, "write_submit %u failed %d\n", i, ret); - bitmap_clear(prtd->chans_pending, i, 1); return ret; } } @@ -146,20 +142,7 @@ static int qmc_audio_pcm_write_submit(struct qmc_dai_p= rtd *prtd) =20 static void qmc_audio_pcm_write_complete(void *context) { - struct qmc_dai_chan *chan =3D context; - struct qmc_dai_prtd *prtd; - - prtd =3D chan->prtd_tx; - - /* Mark the current channel as completed */ - bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1); - - /* - * All QMC channels involved must have completed their transfer before - * submitting a new one. - */ - if (!bitmap_empty(prtd->chans_pending, 64)) - return; + struct qmc_dai_prtd *prtd =3D context; =20 prtd->buffer_ended +=3D prtd->period_size; if (prtd->buffer_ended >=3D prtd->buffer_size) @@ -182,17 +165,14 @@ static int qmc_audio_pcm_read_submit(struct qmc_dai_p= rtd *prtd) int ret; =20 for (i =3D 0; i < prtd->channels; i++) { - bitmap_set(prtd->chans_pending, i, 1); - ret =3D qmc_chan_read_submit(prtd->qmc_dai->chans[i].qmc_chan, prtd->ch_dma_addr_current + i * prtd->ch_dma_offset, prtd->ch_dma_size, - qmc_audio_pcm_read_complete, - &prtd->qmc_dai->chans[i]); + i =3D=3D prtd->channels - 1 ? qmc_audio_pcm_read_complete : + NULL, prtd); if (ret) { dev_err(prtd->qmc_dai->dev, "read_submit %u failed %d\n", i, ret); - bitmap_clear(prtd->chans_pending, i, 1); return ret; } } @@ -202,26 +182,13 @@ static int qmc_audio_pcm_read_submit(struct qmc_dai_p= rtd *prtd) =20 static void qmc_audio_pcm_read_complete(void *context, size_t length, unsi= gned int flags) { - struct qmc_dai_chan *chan =3D context; - struct qmc_dai_prtd *prtd; - - prtd =3D chan->prtd_rx; - - /* Mark the current channel as completed */ - bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1); + struct qmc_dai_prtd *prtd =3D context; =20 if (length !=3D prtd->ch_dma_size) { dev_err(prtd->qmc_dai->dev, "read complete length =3D %zu, exp %zu\n", length, prtd->ch_dma_size); } =20 - /* - * All QMC channels involved must have completed their transfer before - * submitting a new one. - */ - if (!bitmap_empty(prtd->chans_pending, 64)) - return; - prtd->buffer_ended +=3D prtd->period_size; if (prtd->buffer_ended >=3D prtd->buffer_size) prtd->buffer_ended =3D 0; @@ -249,7 +216,6 @@ static int qmc_audio_pcm_trigger(struct snd_soc_compone= nt *component, =20 switch (cmd) { case SNDRV_PCM_TRIGGER_START: - bitmap_zero(prtd->chans_pending, 64); prtd->buffer_ended =3D 0; prtd->ch_dma_addr_current =3D prtd->ch_dma_addr_start; =20 --=20 2.49.0 From nobody Thu Oct 2 09:16:52 2025 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EA3CE312801; Thu, 18 Sep 2025 15:50:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.17.235.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210656; cv=none; b=WL/lc9LVnRLrKsOXaaEsDjSyLQeajiiNec5bgClSoaGc30GxvqZK31si+Z7MbbYvQor45ymPLw4LyeGkXatCMd5KTUEI7WVX9MaX8lkelGXEokUC6dlgwvXF1YWG5aZEjzmwQ3RYdphbWmQrqYXE+LpNHsbCqn2u3aTLHXyUTdk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758210656; c=relaxed/simple; bh=hiFVvDsKhsZYm/v2+/bRrQVP0aSM357pzO7qX7bdClA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UtAoC1ki27+HYo86wY8Z/4rIiajd1mq5RwrWKdUJA36mBMSgmlgsLQSvUyicZHxdvjPhSHbr5t8TtKFHLHOmVrOwvMs8yXyP5nh7NUdlH7oJ5L+KubJ888uNKdnynNPfiTDMBshrokZzr7Djfgm289yTwNyBgD7zndN5pBiusnA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu; spf=pass smtp.mailfrom=csgroup.eu; arc=none smtp.client-ip=93.17.235.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub4.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4cSKST1lJVz9sg5; Thu, 18 Sep 2025 17:34:33 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oX_2heg6YaBY; Thu, 18 Sep 2025 17:34:33 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4cSKST04Rcz9sg4; Thu, 18 Sep 2025 17:34:33 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id C02FB8B767; Thu, 18 Sep 2025 17:34:32 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id XD6WzEdXVtAS; Thu, 18 Sep 2025 17:34:32 +0200 (CEST) Received: from PO20335.idsi0.si.c-s.fr (unknown [192.168.235.99]) by messagerie.si.c-s.fr (Postfix) with ESMTP id E966A8B776; Thu, 18 Sep 2025 17:34:31 +0200 (CEST) From: Christophe Leroy To: Herve Codina , Qiang Zhao , Shengjiu Wang , Xiubo Li , Fabio Estevam , Nicolin Chen , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Christophe Leroy , linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH RESEND v3 4/4] ASoc: fsl: fsl_qmc_audio: Drop struct qmc_dai_chan Date: Thu, 18 Sep 2025 17:34:11 +0200 Message-ID: <9c729bbd9f1b61120a09a87fb76176ef344c5153.1758209158.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1758209657; l=7036; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=hiFVvDsKhsZYm/v2+/bRrQVP0aSM357pzO7qX7bdClA=; b=oA3dKiOCZ31kqBYOQcNUMFTkOTmgYgQtxij9M8WvelR5/+bYlgZQBVItZWNy4YPLRccDMKo6Q dV61RhOSRLWAzLjZP/dUyAWPZSYf0HGD7vPtuOYVP9fwia3krRLHUdr X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" prtd_tx and prtd_rx members are not used anymore and only qmc_chan member remains so struct qmc_dai_chan has become pointless. Use qmc_chan directly and drop struct qmc_dai_chan. Acked-by: Herve Codina Signed-off-by: Christophe Leroy --- sound/soc/fsl/fsl_qmc_audio.c | 52 ++++++++++++++--------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c index 2790953543c5..3de448ef724c 100644 --- a/sound/soc/fsl/fsl_qmc_audio.c +++ b/sound/soc/fsl/fsl_qmc_audio.c @@ -17,12 +17,6 @@ #include #include =20 -struct qmc_dai_chan { - struct qmc_dai_prtd *prtd_tx; - struct qmc_dai_prtd *prtd_rx; - struct qmc_chan *qmc_chan; -}; - struct qmc_dai { char *name; int id; @@ -33,7 +27,7 @@ struct qmc_dai { unsigned int nb_chans_avail; unsigned int nb_chans_used_tx; unsigned int nb_chans_used_rx; - struct qmc_dai_chan *chans; + struct qmc_chan **qmc_chans; }; =20 struct qmc_audio { @@ -125,7 +119,7 @@ static int qmc_audio_pcm_write_submit(struct qmc_dai_pr= td *prtd) int ret; =20 for (i =3D 0; i < prtd->channels; i++) { - ret =3D qmc_chan_write_submit(prtd->qmc_dai->chans[i].qmc_chan, + ret =3D qmc_chan_write_submit(prtd->qmc_dai->qmc_chans[i], prtd->ch_dma_addr_current + i * prtd->ch_dma_offset, prtd->ch_dma_size, i =3D=3D prtd->channels - 1 ? qmc_audio_pcm_write_complete : @@ -165,7 +159,7 @@ static int qmc_audio_pcm_read_submit(struct qmc_dai_prt= d *prtd) int ret; =20 for (i =3D 0; i < prtd->channels; i++) { - ret =3D qmc_chan_read_submit(prtd->qmc_dai->chans[i].qmc_chan, + ret =3D qmc_chan_read_submit(prtd->qmc_dai->qmc_chans[i], prtd->ch_dma_addr_current + i * prtd->ch_dma_offset, prtd->ch_dma_size, i =3D=3D prtd->channels - 1 ? qmc_audio_pcm_read_complete : @@ -206,7 +200,6 @@ static int qmc_audio_pcm_trigger(struct snd_soc_compone= nt *component, struct snd_pcm_substream *substream, int cmd) { struct qmc_dai_prtd *prtd =3D substream->runtime->private_data; - unsigned int i; int ret; =20 if (!prtd->qmc_dai) { @@ -220,9 +213,6 @@ static int qmc_audio_pcm_trigger(struct snd_soc_compone= nt *component, prtd->ch_dma_addr_current =3D prtd->ch_dma_addr_start; =20 if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { - for (i =3D 0; i < prtd->channels; i++) - prtd->qmc_dai->chans[i].prtd_tx =3D prtd; - /* Submit first chunk ... */ ret =3D qmc_audio_pcm_write_submit(prtd); if (ret) @@ -238,9 +228,6 @@ static int qmc_audio_pcm_trigger(struct snd_soc_compone= nt *component, if (ret) return ret; } else { - for (i =3D 0; i < prtd->channels; i++) - prtd->qmc_dai->chans[i].prtd_rx =3D prtd; - /* Submit first chunk ... */ ret =3D qmc_audio_pcm_read_submit(prtd); if (ret) @@ -610,9 +597,9 @@ static int qmc_dai_hw_params(struct snd_pcm_substream *= substream, chan_param.mode =3D QMC_TRANSPARENT; chan_param.transp.max_rx_buf_size =3D params_period_bytes(params) / nb_c= hans_used; for (i =3D 0; i < nb_chans_used; i++) { - ret =3D qmc_chan_set_param(qmc_dai->chans[i].qmc_chan, &chan_param); + ret =3D qmc_chan_set_param(qmc_dai->qmc_chans[i], &chan_param); if (ret) { - dev_err(dai->dev, "chans[%u], set param failed %d\n", + dev_err(dai->dev, "qmc_chans[%u], set param failed %d\n", i, ret); return ret; } @@ -654,7 +641,7 @@ static int qmc_dai_trigger(struct snd_pcm_substream *su= bstream, int cmd, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: for (i =3D 0; i < nb_chans_used; i++) { - ret =3D qmc_chan_start(qmc_dai->chans[i].qmc_chan, direction); + ret =3D qmc_chan_start(qmc_dai->qmc_chans[i], direction); if (ret) goto err_stop; } @@ -663,13 +650,13 @@ static int qmc_dai_trigger(struct snd_pcm_substream *= substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: /* Stop and reset all QMC channels and return the first error encountere= d */ for (i =3D 0; i < nb_chans_used; i++) { - ret_tmp =3D qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction); + ret_tmp =3D qmc_chan_stop(qmc_dai->qmc_chans[i], direction); if (!ret) ret =3D ret_tmp; if (ret_tmp) continue; =20 - ret_tmp =3D qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction); + ret_tmp =3D qmc_chan_reset(qmc_dai->qmc_chans[i], direction); if (!ret) ret =3D ret_tmp; } @@ -681,7 +668,7 @@ static int qmc_dai_trigger(struct snd_pcm_substream *su= bstream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* Stop all QMC channels and return the first error encountered */ for (i =3D 0; i < nb_chans_used; i++) { - ret_tmp =3D qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction); + ret_tmp =3D qmc_chan_stop(qmc_dai->qmc_chans[i], direction); if (!ret) ret =3D ret_tmp; } @@ -697,8 +684,8 @@ static int qmc_dai_trigger(struct snd_pcm_substream *su= bstream, int cmd, =20 err_stop: while (i--) { - qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction); - qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction); + qmc_chan_stop(qmc_dai->qmc_chans[i], direction); + qmc_chan_reset(qmc_dai->qmc_chans[i], direction); } return ret; } @@ -794,19 +781,20 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_= audio, struct device_node * return dev_err_probe(qmc_audio->dev, -EINVAL, "dai %d no QMC channel defined\n", qmc_dai->id); =20 - qmc_dai->chans =3D devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_dai->c= hans), GFP_KERNEL); - if (!qmc_dai->chans) + qmc_dai->qmc_chans =3D devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_da= i->qmc_chans), + GFP_KERNEL); + if (!qmc_dai->qmc_chans) return -ENOMEM; =20 for (i =3D 0; i < count; i++) { - qmc_dai->chans[i].qmc_chan =3D devm_qmc_chan_get_byphandles_index(qmc_au= dio->dev, np, - "fsl,qmc-chan", i); - if (IS_ERR(qmc_dai->chans[i].qmc_chan)) { - return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->chans[i].qmc_chan= ), + qmc_dai->qmc_chans[i] =3D devm_qmc_chan_get_byphandles_index(qmc_audio->= dev, np, + "fsl,qmc-chan", i); + if (IS_ERR(qmc_dai->qmc_chans[i])) { + return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->qmc_chans[i]), "dai %d get QMC channel %d failed\n", qmc_dai->id, i); } =20 - ret =3D qmc_chan_get_info(qmc_dai->chans[i].qmc_chan, &info); + ret =3D qmc_chan_get_info(qmc_dai->qmc_chans[i], &info); if (ret) { dev_err(qmc_audio->dev, "dai %d get QMC %d channel info failed %d\n", qmc_dai->id, i, ret); @@ -851,7 +839,7 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_au= dio, struct device_node * } } =20 - ret =3D qmc_chan_get_ts_info(qmc_dai->chans[i].qmc_chan, &ts_info); + ret =3D qmc_chan_get_ts_info(qmc_dai->qmc_chans[i], &ts_info); if (ret) { dev_err(qmc_audio->dev, "dai %d get QMC %d channel TS info failed %d\n", qmc_dai->id, i, ret); --=20 2.49.0