From patchwork Fri Sep 30 12:43:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Subhransu S. Prusty" X-Patchwork-Id: 9358323 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 675A7600C8 for ; Fri, 30 Sep 2016 14:02:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 565892A044 for ; Fri, 30 Sep 2016 14:02:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B2B12A047; Fri, 30 Sep 2016 14:02:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05DBE2A044 for ; Fri, 30 Sep 2016 14:01:55 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 6CAC22666D7; Fri, 30 Sep 2016 16:01:54 +0200 (CEST) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 9C81C266686; Fri, 30 Sep 2016 15:59:27 +0200 (CEST) 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 96171261A1A; Fri, 30 Sep 2016 14:50:19 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by alsa0.perex.cz (Postfix) with ESMTP id C935826657F for ; Fri, 30 Sep 2016 14:50:16 +0200 (CEST) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP; 30 Sep 2016 05:50:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,272,1473145200"; d="scan'208";a="15394944" Received: from subhransu-desktop.iind.intel.com ([10.223.96.24]) by orsmga004.jf.intel.com with ESMTP; 30 Sep 2016 05:50:13 -0700 From: "Subhransu S. Prusty" To: alsa-devel@alsa-project.org Date: Fri, 30 Sep 2016 18:13:27 +0530 Message-Id: <1475239410-16548-5-git-send-email-subhransu.s.prusty@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1475239410-16548-1-git-send-email-subhransu.s.prusty@intel.com> References: <1475239410-16548-1-git-send-email-subhransu.s.prusty@intel.com> Cc: tiwai@suse.de, lgirdwood@gmail.com, Pierre-Louis Bossart , patches.audio@intel.com, broonie@kernel.org, "Subhransu S. Prusty" Subject: [alsa-devel] [PATCH 4/7] ALSA: core: add report of max inflight bytes 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 From: Pierre-Louis Bossart Report size of data burst before updating the hw_ptr, e.g. while DMA operations are on-going. This can help fix two issues with stale data discussed many times over on the alsa-devel mailing list (refilling/reading ring buffer too late during capture or rewinding too close to the hw_ptr during playback) This patch only reports the maximum burst of data and does not provide hooks to negotiate its size. This might be useful to lower power or reduce latency, but isn't typically supported by fixed-function DMA hardware. The use of IOCTL1 is not really required but keep for symmetry with existing code used to retried fifo_size Signed-off-by: Pierre-Louis Bossart Signed-off-by: Subhransu S. Prusty --- include/sound/pcm.h | 2 ++ include/uapi/sound/asound.h | 5 +++-- sound/core/pcm_lib.c | 20 ++++++++++++++++++++ sound/core/pcm_native.c | 7 +++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 1accb8b..8c9d80a 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -56,6 +56,7 @@ struct snd_pcm_hardware { unsigned int periods_min; /* min # of periods */ unsigned int periods_max; /* max # of periods */ size_t fifo_size; /* fifo size in bytes */ + unsigned int max_inflight_bytes;/* hw_ptr precision/fuzziness, e.g. due to DMA transfers */ }; struct snd_pcm_substream; @@ -105,6 +106,7 @@ struct snd_pcm_ops { #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 #define SNDRV_PCM_IOCTL1_GSTATE 3 #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4 +#define SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES 5 #define SNDRV_PCM_TRIGGER_STOP 0 #define SNDRV_PCM_TRIGGER_START 1 diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 6828ed2..5f539d7 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -392,8 +392,9 @@ struct snd_pcm_hw_params { unsigned int msbits; /* R: used most significant bits */ unsigned int rate_num; /* R: rate numerator */ unsigned int rate_den; /* R: rate denominator */ - snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */ - unsigned char reserved[64]; /* reserved for future */ + snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames, indicates buffering after hw_ptr updates */ + unsigned int max_inflight_bytes;/* R: typically DMA burst in bytes, indicates buffering before hw_ptr updates */ + unsigned char reserved[60]; /* reserved for future */ }; enum { diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 1656ca9..06b44ed 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1827,6 +1827,23 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream, return 0; } +static int snd_pcm_lib_ioctl_max_inflight_bytes( + struct snd_pcm_substream *substream, + void *arg) +{ + struct snd_pcm_hw_params *params = arg; + + params->max_inflight_bytes = substream->runtime->hw.max_inflight_bytes; + /* + * Sanity check that max_inflight_bytes isn't larger than buffer_size, + * couldn't think of any other checks + */ + if (params->max_inflight_bytes > substream->runtime->buffer_size) + params->max_inflight_bytes = substream->runtime->buffer_size; + + return 0; +} + /** * snd_pcm_lib_ioctl - a generic PCM ioctl callback * @substream: the pcm substream instance @@ -1850,6 +1867,9 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, return snd_pcm_lib_ioctl_channel_info(substream, arg); case SNDRV_PCM_IOCTL1_FIFO_SIZE: return snd_pcm_lib_ioctl_fifo_size(substream, arg); + case SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES: + return snd_pcm_lib_ioctl_max_inflight_bytes(substream, arg); + } return -ENXIO; } diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 1965d83..a29b5af 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -292,6 +292,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, params->info = 0; params->fifo_size = 0; + params->max_inflight_bytes = 0; if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) params->msbits = 0; if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) { @@ -449,6 +450,12 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, return changed; } } + if (!params->max_inflight_bytes) { + changed = substream->ops->ioctl(substream, + SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES, params); + if (changed < 0) + return changed; + } params->rmask = 0; return 0; }