From patchwork Thu Jan 14 16:29:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Caleb Crome X-Patchwork-Id: 8033981 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2F8B4BEEE5 for ; Thu, 14 Jan 2016 16:30:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1B3D6204AD for ; Thu, 14 Jan 2016 16:30:12 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 5750720497 for ; Thu, 14 Jan 2016 16:30:09 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id C06EE26059E; Thu, 14 Jan 2016 17:30:07 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id C2DD1260560; Thu, 14 Jan 2016 17:29:59 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 146CF260568; Thu, 14 Jan 2016 17:29:58 +0100 (CET) Received: from mail-pa0-f66.google.com (mail-pa0-f66.google.com [209.85.220.66]) by alsa0.perex.cz (Postfix) with ESMTP id 678E7260524 for ; Thu, 14 Jan 2016 17:29:52 +0100 (CET) Received: by mail-pa0-f66.google.com with SMTP id yy13so28468793pab.1 for ; Thu, 14 Jan 2016 08:29:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crome-org.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id; bh=h9uLF/tXnZSDgCeCKu5rSmeLN8WjtWATm1lP5rE57dY=; b=lNxbtxT6/1BRijpryTE+15cdSRq+YvMR2LjXzDlFy/kxh45O3iiCA/zoq8MepWGBPD 7FcRmIfeSAxuQiYRoHvBLy/R7agR4Lt/GuelHvra7gKkdjhkwPLRqYaQirHQGGCR+5rX Wi+VQWEwz5VjcDRjXlECD9nfMo9es6PuslTW5RTnsoUzk74Z2so5SvQt3saV6LeWDkjZ vd7sJ1XKlYCDXUJ/rPcAmjjXgwiGvkfOFRwWy7xOjuFG8EMAv8V1IMpYNG3uuMxfcIzE hxdMWT6ZysS2KTRk5OjR6D/RId3XlgSaj6s7RpdlxPh6st7N2y0d+l06Q0w6VX6MPoax TE1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=h9uLF/tXnZSDgCeCKu5rSmeLN8WjtWATm1lP5rE57dY=; b=HmRfw44fgheAnuLaKHoWkPOdLeFvkGK7fx0rYjE8aahrcPcks5Q4rWmlj8LQGp4G5k f4AagoVjyxF8yq3lHpLK+Uwj9tp45Xqfw7PnUL+ihAwj8YYl9HMv+W78x5za+Iso+Oex BtPorB7M6gd9LwsFZJ5AGLa51sUL7I+59K1eI9YgX7Ktix6eo55eQDgHybQynBOQtjfP KJUsp2X64drK0s7DE5/ruDqpod8zgicAYm5qLskfjagv1/et6gjulBcxi+LzygVVdQdE tfJlj0O2NXIKwyelGGs/2Vlsu5ALaGINoWL7OrkKVxoetPFYd67TbGXIPTHPTytmLnWl Q07Q== X-Gm-Message-State: ALoCoQlPmjcq8qgkcR/riuCeIPVnKJfLslQKZDoguiZlPQ8AUBRfbTmVx9hJDIZSGRG6XqpFIhE6Te7f6W83bAWquEouqGgz/A== X-Received: by 10.66.252.198 with SMTP id zu6mr7267146pac.107.1452788990814; Thu, 14 Jan 2016 08:29:50 -0800 (PST) Received: from caleb-physical-disk-vm.attlocal.net (99-113-34-250.lightspeed.sntcca.sbcglobal.net. [99.113.34.250]) by smtp.gmail.com with ESMTPSA id 73sm10425762pfm.10.2016.01.14.08.29.49 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 14 Jan 2016 08:29:50 -0800 (PST) From: Caleb Crome To: Timur Tabi , Nicolin Chen , Xiubo Li , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Caleb Crome , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org Date: Thu, 14 Jan 2016 08:29:42 -0800 Message-Id: <1452788982-11583-1-git-send-email-caleb@crome.org> X-Mailer: git-send-email 2.1.4 Subject: [alsa-devel] [PATCH RFC 1/1] ASoC: fsl_ssi: Make fifo watermark and maxburst settings device tree options X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Tuning the SSI fifo watermark & maxburst settings needs to be optimized differently depending on the demands on the system. The current default of 2 is too low for high data-rate systems. This patch maintains exactly the same behavior by default (i.e defaults to 2), but adds device tree options to set maxburst & fifo depth from the device tree. This is necessary because a setting of 2 simply doesn't work at higher data rates. Signed-off-by: Caleb Crome --- .../devicetree/bindings/sound/fsl,ssi.txt | 10 +++ sound/soc/fsl/fsl_ssi.c | 87 ++++++++++++++-------- 2 files changed, 68 insertions(+), 29 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt index 5b76be4..7af62b9 100644 --- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt +++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt @@ -61,6 +61,16 @@ Optional properties: - fsl,mode: The operating mode for the AC97 interface only. "ac97-slave" - AC97 mode, SSI is clock slave "ac97-master" - AC97 mode, SSI is clock master +- fsl,fifo-watermark: Sets the fifo watermark. The default is + fifo_depth-2 words, meaning 'initiate dma transfer + when 2 words are left in the fifo'. At higher + data rates (48kHz, 16-channels for example), this + causes silent but deadly DMA xruns and channel + slips. For 15 word FIFOs (like on MX5, MX6) 8 is + a good value when running at high data rates +- fsl,dma-maxburst: sets the max number of words to transfer in DMA. + This defaults to the same value as + fsl,fifo-watermark. Child 'codec' node required properties: - compatible: Compatible list, contains the name of the codec diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5cfc540..94d8b5d7 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -221,6 +221,12 @@ struct fsl_ssi_soc_data { * @dbg_stats: Debugging statistics * * @soc: SoC specific data + * + * @fifo_watermark: the FIFO watermark setting. Notifies DMA when + * there are @fifo_watermark or fewer words in TX fifo or + * @fifo_watermark or more empty words in RX fifo. + * @dma_maxburst: max number of words to transfer in one go. So far, + * this is always the same as fifo_watermark. */ struct fsl_ssi_private { struct regmap *regs; @@ -259,6 +265,9 @@ struct fsl_ssi_private { const struct fsl_ssi_soc_data *soc; struct device *dev; + + u32 fifo_watermark; + u32 dma_maxburst; }; /* @@ -1037,21 +1046,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, regmap_write(regs, CCSR_SSI_SRCR, srcr); regmap_write(regs, CCSR_SSI_SCR, scr); - /* - * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't - * use FIFO 1. We program the transmit water to signal a DMA transfer - * if there are only two (or fewer) elements left in the FIFO. Two - * elements equals one frame (left channel, right channel). This value, - * however, depends on the depth of the transmit buffer. - * - * We set the watermark on the same level as the DMA burstsize. For - * fiq it is probably better to use the biggest possible watermark - * size. - */ - if (ssi_private->use_dma) - wm = ssi_private->fifo_depth - 2; - else - wm = ssi_private->fifo_depth; + wm = ssi_private->fifo_watermark; regmap_write(regs, CCSR_SSI_SFCSR, CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | @@ -1359,12 +1354,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", PTR_ERR(ssi_private->baudclk)); - /* - * We have burstsize be "fifo_depth - 2" to match the SSI - * watermark setting in fsl_ssi_startup(). - */ - ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2; - ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2; + ssi_private->dma_params_tx.maxburst = ssi_private->dma_maxburst; + ssi_private->dma_params_rx.maxburst = ssi_private->dma_maxburst; ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; @@ -1421,6 +1412,51 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev, clk_disable_unprepare(ssi_private->clk); } +static void fsl_ssi_set_fifo_settings( + struct device_node *np, + struct fsl_ssi_private *ssi_private) +{ + const uint32_t *iprop; + /* + * Determine the FIFO depth. & watermark + * + * Set the watermark for transmit FIFO 0/1 and receive FIFO + * 0/1. We program the transmit water to signal a DMA transfer + * when this many words are left to be transmitted (or + * received). Previous setting was 2 elements, which was + * assumed to be one frame. Such a small value causes silent + * DMA xruns at high data rates. 8 seems to be a good + * tradeoff between xruns & number of DMA transfers. + * + * We set the watermark on the same level as the DMA burstsize. For + * fiq it is probably better to use the biggest possible watermark + * size. + */ + iprop = of_get_property(np, "fsl,fifo-depth", NULL); + if (iprop) + ssi_private->fifo_depth = be32_to_cpup(iprop); + else + /* Older 8610 DTs didn't have the fifo-depth property */ + ssi_private->fifo_depth = 8; + + iprop = of_get_property(np, "fsl,fifo-watermark", NULL); + if (iprop) + ssi_private->fifo_watermark = be32_to_cpup(iprop); + else + /* Default to old value of 2, which is too + * small at high data rates, but it's the + * default that's been there for years. + */ + ssi_private->fifo_watermark = ssi_private->fifo_depth - 2; + + iprop = of_get_property(np, "fsl,dma-maxburst", NULL); + + if (iprop) + ssi_private->dma_maxburst = be32_to_cpup(iprop); + else + ssi_private->dma_maxburst = ssi_private->fifo_watermark; +} + static int fsl_ssi_probe(struct platform_device *pdev) { struct fsl_ssi_private *ssi_private; @@ -1428,7 +1464,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; const struct of_device_id *of_id; const char *p, *sprop; - const uint32_t *iprop; struct resource *res; void __iomem *iomem; char name[64]; @@ -1510,13 +1545,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private->cpu_dai_drv.symmetric_samplebits = 1; } - /* Determine the FIFO depth. */ - iprop = of_get_property(np, "fsl,fifo-depth", NULL); - if (iprop) - ssi_private->fifo_depth = be32_to_cpup(iprop); - else - /* Older 8610 DTs didn't have the fifo-depth property */ - ssi_private->fifo_depth = 8; + fsl_ssi_set_fifo_settings(np, ssi_private); dev_set_drvdata(&pdev->dev, ssi_private);