Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp3699466ybv; Mon, 10 Feb 2020 04:57:28 -0800 (PST) X-Google-Smtp-Source: APXvYqzm4kS2NXLMM4Y5VrGjaYd0goRHebIAmvbDZ4ivPCBczIKspqxCVIPuoQTSBQDXZoDj/IeJ X-Received: by 2002:a05:6830:4cd:: with SMTP id s13mr916673otd.181.1581339448367; Mon, 10 Feb 2020 04:57:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581339448; cv=none; d=google.com; s=arc-20160816; b=T5gcsvNVMwNaeh1SroTPquD3eznaXEVlQMJ9VhGgGgzFXfzXUbJcbb9TDzX/99UDHw Bja8BhpjgJHe0YO9bxU1pet1LI4Q7Dbw3GeydeHgivZ6Fh6FQKLHEUc6NJPI8pTgWmHL 8jqNxUO85iD+frpShv52fyyAX8xNDrAFJmqIcpnGowNummw/ZB36AtpGaS5F7u6YkZr8 ZHqjn7xvp34YkcAif5gtwOC7iURr09AmXHIcqXgvPOEMFuyu1r/+PtpMAZEXPCfM2YBL GZ9u7U6ECjZqslTlVzDO8D1sy6bf2W+Cvm5d7t0HqB2jSkdt7SFLykrlt+Chfc3gW4Dd RGKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=JZMVAw7POEq2u8gy6WUIi8KCwWyAtr6eTzuM4HLq09M=; b=kdgBIWigjSH/s0ZPNvJRrCMSjJsWU+jwEai3s3kEZOvI2xtAN8JZktd4a6WrdwefTR HUZiW7gjFxkagBYIz1qKY7WIoqvajHIA3dslXe8hCCScqCTWnHSqXPhHaBAEmtoZvJyk weyTTq/7Fy32U1f1CgGl8xH6qi+7p0yyWRJWwFdsPngeSoAa10V/hM0K/RJ15IBb+DDv OjvCQyLPP33s7Dlq/BWNZUaJf642EaqgPRs2rQFLZQlGtYITZYIIBzNf41friJllchVh BSh7ZPoTh2c8BrICCZW5P0SBMe480g23iXU9E6rubTuL7M7ANfYAG9BbxW9eJs4xS4/Q am2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jk2EIccJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c14si148638otn.118.2020.02.10.04.57.16; Mon, 10 Feb 2020 04:57:28 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jk2EIccJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727447AbgBJM5F (ORCPT + 99 others); Mon, 10 Feb 2020 07:57:05 -0500 Received: from mail.kernel.org ([198.145.29.99]:44070 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730015AbgBJMld (ORCPT ); Mon, 10 Feb 2020 07:41:33 -0500 Received: from localhost (unknown [209.37.97.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E01B7208C3; Mon, 10 Feb 2020 12:41:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1581338493; bh=c8goGARwlj2NHOIqJVsSN1MB+B+hQCBbGJ2drc+zI+w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jk2EIccJTfVBRq7pNoYg98rEANJAXvO3Aj5RfWM4aWvuQ15FxVJVd1dthGzOmXjjL oECUL+fOSASb8SGU8b0ZWxlgbonYwXsZq7q3wmWd+otw+7i7GV6jNov+24rd3WwJC3 QNYO+VKz1bqMgLzVFyH1Uj5fm5bU9SzlotVUccA8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alden DSouza , Jerome Brunet , Mark Brown Subject: [PATCH 5.5 279/367] ASoC: meson: axg-fifo: fix fifo threshold setup Date: Mon, 10 Feb 2020 04:33:12 -0800 Message-Id: <20200210122449.837877741@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200210122423.695146547@linuxfoundation.org> References: <20200210122423.695146547@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jerome Brunet commit 864cee90d4bd870e5d5e5a0b1a6f055f4f951350 upstream. On TODDR sm1, the fifo threshold register field is slightly different compared to the other SoCs. This leads to the fifo A being flushed to memory every 8kB. If the period is smaller than that, several periods are pushed to memory and notified at once. This is not ideal. Fix the register field update. With this, the fifos are flushed every 128B. We could still do better, like adapt the threshold depending on the period size, but at least it consistent across the different SoC/fifos Fixes: 5ac825c3d85e ("ASoC: meson: axg-toddr: add sm1 support") Reported-by: Alden DSouza Signed-off-by: Jerome Brunet Link: https://lore.kernel.org/r/20191218172420.1199117-2-jbrunet@baylibre.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/meson/axg-fifo.c | 27 +++++++++++++++++++++++++-- sound/soc/meson/axg-fifo.h | 6 ++++-- sound/soc/meson/axg-frddr.c | 24 ++++++++++++------------ sound/soc/meson/axg-toddr.c | 21 +++++++++------------ 4 files changed, 50 insertions(+), 28 deletions(-) --- a/sound/soc/meson/axg-fifo.c +++ b/sound/soc/meson/axg-fifo.c @@ -113,10 +113,12 @@ int axg_fifo_pcm_hw_params(struct snd_so { struct snd_pcm_runtime *runtime = ss->runtime; struct axg_fifo *fifo = axg_fifo_data(ss); + unsigned int burst_num, period, threshold; dma_addr_t end_ptr; - unsigned int burst_num; int ret; + period = params_period_bytes(params); + ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(params)); if (ret < 0) return ret; @@ -127,9 +129,25 @@ int axg_fifo_pcm_hw_params(struct snd_so regmap_write(fifo->map, FIFO_FINISH_ADDR, end_ptr); /* Setup interrupt periodicity */ - burst_num = params_period_bytes(params) / AXG_FIFO_BURST; + burst_num = period / AXG_FIFO_BURST; regmap_write(fifo->map, FIFO_INT_ADDR, burst_num); + /* + * Start the fifo request on the smallest of the following: + * - Half the fifo size + * - Half the period size + */ + threshold = min(period / 2, + (unsigned int)AXG_FIFO_MIN_DEPTH / 2); + + /* + * With the threshold in bytes, register value is: + * V = (threshold / burst) - 1 + */ + threshold /= AXG_FIFO_BURST; + regmap_field_write(fifo->field_threshold, + threshold ? threshold - 1 : 0); + /* Enable block count irq */ regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), @@ -352,6 +370,11 @@ int axg_fifo_probe(struct platform_devic return fifo->irq; } + fifo->field_threshold = + devm_regmap_field_alloc(dev, fifo->map, data->field_threshold); + if (IS_ERR(fifo->field_threshold)) + return PTR_ERR(fifo->field_threshold); + return devm_snd_soc_register_component(dev, data->component_drv, data->dai_drv, 1); } --- a/sound/soc/meson/axg-fifo.h +++ b/sound/soc/meson/axg-fifo.h @@ -9,7 +9,9 @@ struct clk; struct platform_device; +struct reg_field; struct regmap; +struct regmap_field; struct reset_control; struct snd_soc_component_driver; @@ -50,8 +52,6 @@ struct snd_soc_pcm_runtime; #define CTRL1_STATUS2_SEL_MASK GENMASK(11, 8) #define CTRL1_STATUS2_SEL(x) ((x) << 8) #define STATUS2_SEL_DDR_READ 0 -#define CTRL1_THRESHOLD_MASK GENMASK(23, 16) -#define CTRL1_THRESHOLD(x) ((x) << 16) #define CTRL1_FRDDR_DEPTH_MASK GENMASK(31, 24) #define CTRL1_FRDDR_DEPTH(x) ((x) << 24) #define FIFO_START_ADDR 0x08 @@ -67,12 +67,14 @@ struct axg_fifo { struct regmap *map; struct clk *pclk; struct reset_control *arb; + struct regmap_field *field_threshold; int irq; }; struct axg_fifo_match_data { const struct snd_soc_component_driver *component_drv; struct snd_soc_dai_driver *dai_drv; + struct reg_field field_threshold; }; int axg_fifo_pcm_open(struct snd_soc_component *component, --- a/sound/soc/meson/axg-frddr.c +++ b/sound/soc/meson/axg-frddr.c @@ -50,7 +50,7 @@ static int axg_frddr_dai_startup(struct struct snd_soc_dai *dai) { struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); - unsigned int fifo_depth, fifo_threshold; + unsigned int fifo_depth; int ret; /* Enable pclk to access registers and clock the fifo ip */ @@ -68,11 +68,8 @@ static int axg_frddr_dai_startup(struct * Depth and threshold are zero based. */ fifo_depth = AXG_FIFO_MIN_CNT - 1; - fifo_threshold = (AXG_FIFO_MIN_CNT / 2) - 1; - regmap_update_bits(fifo->map, FIFO_CTRL1, - CTRL1_FRDDR_DEPTH_MASK | CTRL1_THRESHOLD_MASK, - CTRL1_FRDDR_DEPTH(fifo_depth) | - CTRL1_THRESHOLD(fifo_threshold)); + regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_FRDDR_DEPTH_MASK, + CTRL1_FRDDR_DEPTH(fifo_depth)); return 0; } @@ -159,8 +156,9 @@ static const struct snd_soc_component_dr }; static const struct axg_fifo_match_data axg_frddr_match_data = { - .component_drv = &axg_frddr_component_drv, - .dai_drv = &axg_frddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &axg_frddr_component_drv, + .dai_drv = &axg_frddr_dai_drv }; static const struct snd_soc_dai_ops g12a_frddr_ops = { @@ -283,8 +281,9 @@ static const struct snd_soc_component_dr }; static const struct axg_fifo_match_data g12a_frddr_match_data = { - .component_drv = &g12a_frddr_component_drv, - .dai_drv = &g12a_frddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &g12a_frddr_component_drv, + .dai_drv = &g12a_frddr_dai_drv }; /* On SM1, the output selection in on CTRL2 */ @@ -353,8 +352,9 @@ static const struct snd_soc_component_dr }; static const struct axg_fifo_match_data sm1_frddr_match_data = { - .component_drv = &sm1_frddr_component_drv, - .dai_drv = &g12a_frddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &sm1_frddr_component_drv, + .dai_drv = &g12a_frddr_dai_drv }; static const struct of_device_id axg_frddr_of_match[] = { --- a/sound/soc/meson/axg-toddr.c +++ b/sound/soc/meson/axg-toddr.c @@ -89,7 +89,6 @@ static int axg_toddr_dai_startup(struct struct snd_soc_dai *dai) { struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); - unsigned int fifo_threshold; int ret; /* Enable pclk to access registers and clock the fifo ip */ @@ -107,11 +106,6 @@ static int axg_toddr_dai_startup(struct /* Apply single buffer mode to the interface */ regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_PP_MODE, 0); - /* TODDR does not have a configurable fifo depth */ - fifo_threshold = AXG_FIFO_MIN_CNT - 1; - regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_THRESHOLD_MASK, - CTRL1_THRESHOLD(fifo_threshold)); - return 0; } @@ -191,8 +185,9 @@ static const struct snd_soc_component_dr }; static const struct axg_fifo_match_data axg_toddr_match_data = { - .component_drv = &axg_toddr_component_drv, - .dai_drv = &axg_toddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &axg_toddr_component_drv, + .dai_drv = &axg_toddr_dai_drv }; static const struct snd_soc_dai_ops g12a_toddr_ops = { @@ -230,8 +225,9 @@ static const struct snd_soc_component_dr }; static const struct axg_fifo_match_data g12a_toddr_match_data = { - .component_drv = &g12a_toddr_component_drv, - .dai_drv = &g12a_toddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &g12a_toddr_component_drv, + .dai_drv = &g12a_toddr_dai_drv }; static const char * const sm1_toddr_sel_texts[] = { @@ -300,8 +296,9 @@ static const struct snd_soc_component_dr }; static const struct axg_fifo_match_data sm1_toddr_match_data = { - .component_drv = &sm1_toddr_component_drv, - .dai_drv = &g12a_toddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 12, 23), + .component_drv = &sm1_toddr_component_drv, + .dai_drv = &g12a_toddr_dai_drv }; static const struct of_device_id axg_toddr_of_match[] = {