From patchwork Tue Nov 12 11:17:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Pargmann X-Patchwork-Id: 3171741 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5A920C045B for ; Tue, 12 Nov 2013 11:18:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 28474201F0 for ; Tue, 12 Nov 2013 11:18:52 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9E9E82041E for ; Tue, 12 Nov 2013 11:18:49 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VgBzP-0001Ew-NQ; Tue, 12 Nov 2013 11:18:35 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VgBzN-0002TR-9N; Tue, 12 Nov 2013 11:18:33 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VgBzJ-0002Sc-9a for linux-arm-kernel@lists.infradead.org; Tue, 12 Nov 2013 11:18:30 +0000 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1VgByr-0004tt-HG; Tue, 12 Nov 2013 12:18:01 +0100 Received: from mpa by dude.hi.pengutronix.de with local (Exim 4.80) (envelope-from ) id 1VgByp-00022x-PI; Tue, 12 Nov 2013 12:17:59 +0100 From: Markus Pargmann To: Timur Tabi , Mark Brown , Liam Girdwood Subject: [PATCH] ASoC: fsl-ssi: fix SDMA starvation Date: Tue, 12 Nov 2013 12:17:36 +0100 Message-Id: <1384255056-25673-1-git-send-email-mpa@pengutronix.de> X-Mailer: git-send-email 1.8.4.2 X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: mpa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131112_061829_737691_198EDE61 X-CRM114-Status: GOOD ( 18.10 ) X-Spam-Score: -1.9 (-) Cc: alsa-devel@alsa-project.org, stable@vger.kernel.org, kernel@pengutronix.de, Markus Pargmann , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Juergen Beisert In cases when capturing is already running and someone enables also playback, the SDMA unit of the i.MX SoC does not see an edge on its TX DMA request line. This is due to the TX FIFOs are empty, and this request line is active all the time, when the CCSR_SSI_SIER_TDMAE bit is set. In this case also the TX FIFO underrun interrupt will flood the system forever. To ensure the first edge happens after enabling the TX side of the SSI unit and to trigger the SDMA unit successfully enable the CCSR_SSI_SIER_TDMAE on demand only. To be sure, this patch does the same for the CCSR_SSI_SIER_RDMAE (RX side) bit. Signed-off-by: Juergen Beisert Cc: stable@vger.kernel.org Signed-off-by: Markus Pargmann --- Hi, The patch is based on Mark's "fix/fsl" branch. Regards, Markus Pargmann sound/soc/fsl/fsl_ssi.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 6b81d0c..8c94632 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -107,10 +107,9 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) #endif /* SIER bitflag of interrupts to enable */ -#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \ - CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \ - CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \ - CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \ +#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TIE | \ + CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TUE1_EN | \ + CCSR_SSI_SIER_RFRC_EN | CCSR_SSI_SIER_RIE | \ CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN) /** @@ -548,6 +547,9 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, * * The DMA channel is in external master start and pause mode, which * means the SSI completely controls the flow of data. + * + * To use the i.MX's SDMA unit it is important to create an edge on the + * corresponding request line. Otherwise the request will be ignored! */ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) @@ -580,20 +582,26 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); - else + write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TDMAE); + } else { write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); + write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RDMAE); + } break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); - else + write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TDMAE, 0); + } else { write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); + write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RDMAE, 0); + } if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0)