From nobody Tue Oct 7 08:35:49 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9DE37207DF3 for ; Fri, 11 Jul 2025 08:25:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222345; cv=none; b=VgsEelbgh7CIevPxzaEQBMRgQBETq2i7/YNKqCVnObIo4yIzeAQKBlFG5E/HZAlJ4lda5FKX5gHDAe17x+MDH0UVS5kgeZdLdXaxhApckdgAJ5Xuey9RYYmZqyrC8R+NYXDyr5Fa4njCIDqIDOWVhGNqRhTANa5jqqs9rSCFYak= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222345; c=relaxed/simple; bh=Nwai+69eO4bSfYsFbKUaWIDaRfGBfxzs5b4XP9/lYHQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=DNta7IcqzMCxlpVVE/+mRYizXIorNiT+ynD6QZO3QIY5J2g5YZPwXSnBpH86A4LPEdObi76OMC+Hqrfti//don9fUbZYjtXyPlk7A18C0lKleKaaVorkVE8SyD6W8UiQ++yC/HhyZmFGdEF/nhk7gEHeM5uYnhoFwWcH8l2sPoY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=MZkwYHmE; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="MZkwYHmE" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3a4f7ebfd00so844133f8f.2 for ; Fri, 11 Jul 2025 01:25:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752222342; x=1752827142; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=9LDW/NCXiu/dV0D7aUHjZFoEpgIFrqYJ9GeuMW0mLkU=; b=MZkwYHmEhkGOTKQjkodKVs5VNEcYW/0lxrPotNGwa2aJeZpoaLVrzwP1kfggjZm5tr tH9lr4TuZUTjQGKQvdM+madcced87onxOBFepHcvLePviLC1VKsVP+NjpgNu5uIsK01r N7eiCcrmWsY33MUWxSAq6n24LNnAGyUTfYKs3u7CYDu5Sv49j5iCcVslidsZyD4Y9yvV N7ViGw0MEY6TGLioS9Fa36p0b5oY0Z9DKJPqog0MdT5YRuXoH6wedNTcnfA6+XB8Oxe+ YCGuYZbKt6A6SKIEds//8PwnncikCSsABf5i4j/MmoDfe8k6v+QLN7KWKtQJWQy8hIeY 2rmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752222342; x=1752827142; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9LDW/NCXiu/dV0D7aUHjZFoEpgIFrqYJ9GeuMW0mLkU=; b=qHVRWh3WFXdRKXphk4c/ULhZEiHAtSHuUMs/AFELVphZTvKrgRbyZkCuDgaO6ty51T eIzw+h3TEC60V04Yyb5mSDjzFJKUwTJhwc/a0p/2d3ulDFM/CXLvaeLL2IDnMl59ktg7 GuBKmlSFpsuHUxgvjlQO+ei1r6ozvm5t1WLTTEG3V4nEEf9MPA6STbgaR3kXVSonJCes m+7MSZMZNocfyUBMNYzu4gKsziE5gLHtT8sRT09+EoUJTW7k1bydo2ImKYxAZEZuHfst oV4IGlTd1DlxyvAkKfgJtQp91O2cXS+QhmYylMiI9w+6OolPj7NXCeKh+e/FmGNEJabw UO9g== X-Forwarded-Encrypted: i=1; AJvYcCU9qUO1weaaLJxl43Cn2R32eO2nKGcw+i9dburvgfstGpDK2ZqFtnJpgpYKCwQSjwa1L6hX6GqF5QlGMdA=@vger.kernel.org X-Gm-Message-State: AOJu0YyNcezbvp/cYOCvVWN8pgCglloicIBuKLAwyjOO6/WrNHd4kw5h ZJKqfCx+5o21YJAf1v+3uMVT8f4zFHZuMm1zzE6/+WeYXN6zSrz+U+QnAYO/S5PHpWk9LuT/KQq gOVcSo1x8jOKEbdMa4w== X-Google-Smtp-Source: AGHT+IFAInUcpkRkmQUfzFtIt3PdeIZrLlceROtU5bN/fuj0D13u6vAJCEu6XtlsmoWgQdOBm0M/poWDkUUcUq4= X-Received: from wrpv18.prod.google.com ([2002:adf:f692:0:b0:3b5:e077:af45]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:5f52:0:b0:3a6:c923:bc5f with SMTP id ffacd0b85a97d-3b5f187ebaamr2416990f8f.17.1752222341901; Fri, 11 Jul 2025 01:25:41 -0700 (PDT) Date: Fri, 11 Jul 2025 09:24:33 +0100 In-Reply-To: <20250711082441.4193295-1-verhaegen@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250711082441.4193295-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711082441.4193295-2-verhaegen@google.com> Subject: [PATCH v1 1/4] ALSA: compress_offload: Add 64-bit safe timestamp infrastructure From: George Verhaegen To: Vinod Koul , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , Charles Keepax , Richard Fitzgerald , David Rhodes , Cezary Rojewski , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Srinivas Kandagatla , Daniel Baluta , Orson Zhai , Baolin Wang , Chunyan Zhang , Kunihiko Hayashi , Masami Hiramatsu Cc: Joris Verhaegen , kernel-team@android.com, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com, linux-arm-msm@vger.kernel.org, sound-open-firmware@alsa-project.org, linux-arm-kernel@lists.infradead.org, David Li , Miller Liang Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Joris Verhaegen The copied_total field in struct snd_compr_tstamp is a 32-bit value that can overflow on long-running high-bitrate streams, leading to incorrect calculations for buffer availablility. This patch adds a 64-bit safe timestamping mechanism. It introduces struct snd_compr_tstamp64 in the UAPI header which uses __u64 for cumulative counters. A new .pointer64 operation is added to the relevant ASoC and core compress ops structures. Corresponding ASoC wrapper functions are also added. The core timestamping logic is refactored to use u64 for its internal total_bytes_transferred counter, fixing the internal state overflow. The logic now attempts to use the new .pointer64 op first, falling back to the legacy 32-bit path if the new op is not implemented by a driver. Signed-off-by: Joris Verhaegen Tested-by: Joris Verhaegen Reviewed-by: David Li Reviewed-by: Miller Liang --- include/sound/compress_driver.h | 3 ++ include/sound/soc-component.h | 5 ++ include/sound/soc-dai.h | 6 +++ include/uapi/sound/compress_offload.h | 19 +++++++ sound/core/compress_offload.c | 78 +++++++++++++++++++++------ sound/soc/soc-component.c | 20 +++++++ sound/soc/soc-compress.c | 21 ++++++++ sound/soc/soc-dai.c | 14 +++++ 8 files changed, 150 insertions(+), 16 deletions(-) diff --git a/include/sound/compress_driver.h b/include/sound/compress_drive= r.h index b55c9eeb2b54..a047ff14a420 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h @@ -136,6 +136,7 @@ struct snd_compr_stream { * @trigger: Trigger operations like start, pause, resume, drain, stop. * This callback is mandatory * @pointer: Retrieve current h/w pointer information. Mandatory + * @pointer64: Retrieve current h/w pointer information in 64 bit. Optional * @copy: Copy the compressed data to/from userspace, Optional * Can't be implemented if DSP supports mmap * @mmap: DSP mmap method to mmap DSP memory @@ -162,6 +163,8 @@ struct snd_compr_ops { int (*trigger)(struct snd_compr_stream *stream, int cmd); int (*pointer)(struct snd_compr_stream *stream, struct snd_compr_tstamp *tstamp); + int (*pointer64)(struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp); int (*copy)(struct snd_compr_stream *stream, char __user *buf, size_t count); int (*mmap)(struct snd_compr_stream *stream, diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 61534ac0edd1..07d9f0ff7b1c 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -48,6 +48,9 @@ struct snd_compress_ops { int (*pointer)(struct snd_soc_component *component, struct snd_compr_stream *stream, struct snd_compr_tstamp *tstamp); + int (*pointer64)(struct snd_soc_component *component, + struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp); int (*copy)(struct snd_soc_component *component, struct snd_compr_stream *stream, char __user *buf, size_t count); @@ -500,6 +503,8 @@ int snd_soc_component_compr_get_codec_caps(struct snd_c= ompr_stream *cstream, int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t b= ytes); int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream, struct snd_compr_tstamp *tstamp); +int snd_soc_component_compr_pointer64(struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp); int snd_soc_component_compr_copy(struct snd_compr_stream *cstream, char __user *buf, size_t count); int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream, diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index d19ab5572d2b..8ecfa966e28a 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -257,6 +257,9 @@ int snd_soc_dai_compr_ack(struct snd_soc_dai *dai, int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai, struct snd_compr_stream *cstream, struct snd_compr_tstamp *tstamp); +int snd_soc_dai_compr_pointer64(struct snd_soc_dai *dai, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp); int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai, struct snd_compr_stream *cstream, struct snd_compr_metadata *metadata); @@ -385,6 +388,9 @@ struct snd_soc_cdai_ops { struct snd_soc_dai *); int (*pointer)(struct snd_compr_stream *, struct snd_compr_tstamp *, struct snd_soc_dai *); + int (*pointer64)(struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp, + struct snd_soc_dai *dai); int (*ack)(struct snd_compr_stream *, size_t, struct snd_soc_dai *); }; diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/com= press_offload.h index d62eb93af0ed..abd0ea3f86ee 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -56,6 +56,25 @@ struct snd_compr_tstamp { __u32 sampling_rate; } __attribute__((packed, aligned(4))); =20 +/** + * struct snd_compr_tstamp64 - timestamp descriptor with fields in 64 bit + * @byte_offset: Byte offset in ring buffer to DSP + * @copied_total: Total number of bytes copied from/to ring buffer to/by D= SP + * @pcm_frames: Frames decoded or encoded by DSP. This field will evolve by + * large steps and should only be used to monitor encoding/decoding + * progress. It shall not be used for timing estimates. + * @pcm_io_frames: Frames rendered or received by DSP into a mixer or an a= udio + * output/input. This field should be used for A/V sync or time estimates. + * @sampling_rate: sampling rate of audio + */ +struct snd_compr_tstamp64 { + __u32 byte_offset; + __u64 copied_total; + __u64 pcm_frames; + __u64 pcm_io_frames; + __u32 sampling_rate; +} __attribute__((packed, aligned(4))); + /** * struct snd_compr_avail - avail descriptor * @avail: Number of bytes available in ring buffer for writing/reading diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 840bb9cfe789..6a8873bd62ae 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -176,18 +176,65 @@ static int snd_compr_free(struct inode *inode, struct= file *f) return 0; } =20 +static int snd_compr_get_tstamp64(struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp) +{ + struct snd_compr_tstamp64 tstamp64_zero; + + memset(tstamp, 0, sizeof(*tstamp)); + memset(&tstamp64_zero, 0, sizeof(tstamp64_zero)); + + if (!stream->ops->pointer64) + return -EOPNOTSUPP; + stream->ops->pointer64(stream, tstamp); + + /** + * Even if pointer64 is non-null, the driver call may not have been imple= mented + * (due to indirection in soc-component.c). + * Check that the call was successful by verifying that tstamp is not all= zero. + */ + if (memcmp(tstamp, &tstamp64_zero, sizeof(*tstamp)) =3D=3D 0) { + pr_debug("no tstamp returned from pointer64\n"); + return -EOPNOTSUPP; + } + return 0; +} + +static void +snd_compr_tstamp32_from_64(struct snd_compr_tstamp *tstamp32, + const struct snd_compr_tstamp64 *tstamp64) +{ + tstamp32->byte_offset =3D tstamp64->byte_offset; + tstamp32->copied_total =3D (u32)tstamp64->copied_total; + tstamp32->pcm_frames =3D (u32)tstamp64->pcm_frames; + tstamp32->pcm_io_frames =3D (u32)tstamp64->pcm_io_frames; + tstamp32->sampling_rate =3D tstamp64->sampling_rate; +} + static int snd_compr_update_tstamp(struct snd_compr_stream *stream, struct snd_compr_tstamp *tstamp) { - if (!stream->ops->pointer) - return -ENOTSUPP; - stream->ops->pointer(stream, tstamp); - pr_debug("dsp consumed till %d total %d bytes\n", - tstamp->byte_offset, tstamp->copied_total); + u64 copied_total64; + struct snd_compr_tstamp64 tstamp64; + + /* Get 64 bit values if available. Otherwise, fallback to 32 bit. */ + if (snd_compr_get_tstamp64(stream, &tstamp64) =3D=3D 0) { + copied_total64 =3D tstamp64.copied_total; + snd_compr_tstamp32_from_64(tstamp, &tstamp64); + } else { + if (!stream->ops->pointer) + return -EOPNOTSUPP; + stream->ops->pointer(stream, tstamp); + copied_total64 =3D tstamp->copied_total; + } + + pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset, + copied_total64); + if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) - stream->runtime->total_bytes_transferred =3D tstamp->copied_total; + stream->runtime->total_bytes_transferred =3D copied_total64; else - stream->runtime->total_bytes_available =3D tstamp->copied_total; + stream->runtime->total_bytes_available =3D copied_total64; return 0; } =20 @@ -204,9 +251,9 @@ static size_t snd_compr_calc_avail(struct snd_compr_str= eam *stream, pr_debug("detected init and someone forgot to do a write\n"); return stream->runtime->buffer_size; } - pr_debug("app wrote %lld, DSP consumed %lld\n", - stream->runtime->total_bytes_available, - stream->runtime->total_bytes_transferred); + pr_debug("app wrote %llu, DSP consumed %llu\n", + stream->runtime->total_bytes_available, + stream->runtime->total_bytes_transferred); if (stream->runtime->total_bytes_available =3D=3D stream->runtime->total_bytes_transferred) { if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) { @@ -223,7 +270,7 @@ static size_t snd_compr_calc_avail(struct snd_compr_str= eam *stream, if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) avail->avail =3D stream->runtime->buffer_size - avail->avail; =20 - pr_debug("ret avail as %lld\n", avail->avail); + pr_debug("ret avail as %llu\n", avail->avail); return avail->avail; } =20 @@ -274,8 +321,7 @@ static int snd_compr_write_data(struct snd_compr_stream= *stream, (app_pointer * runtime->buffer_size); =20 dstn =3D runtime->buffer + app_pointer; - pr_debug("copying %ld at %lld\n", - (unsigned long)count, app_pointer); + pr_debug("copying %lu at %llu\n", (unsigned long)count, app_pointer); if (count < runtime->buffer_size - app_pointer) { if (copy_from_user(dstn, buf, count)) return -EFAULT; @@ -318,7 +364,7 @@ static ssize_t snd_compr_write(struct file *f, const ch= ar __user *buf, } =20 avail =3D snd_compr_get_avail(stream); - pr_debug("avail returned %ld\n", (unsigned long)avail); + pr_debug("avail returned %lu\n", (unsigned long)avail); /* calculate how much we can write to buffer */ if (avail > count) avail =3D count; @@ -374,7 +420,7 @@ static ssize_t snd_compr_read(struct file *f, char __us= er *buf, } =20 avail =3D snd_compr_get_avail(stream); - pr_debug("avail returned %ld\n", (unsigned long)avail); + pr_debug("avail returned %lu\n", (unsigned long)avail); /* calculate how much we can read from buffer */ if (avail > count) avail =3D count; @@ -443,7 +489,7 @@ static __poll_t snd_compr_poll(struct file *f, poll_tab= le *wait) #endif =20 avail =3D snd_compr_get_avail(stream); - pr_debug("avail is %ld\n", (unsigned long)avail); + pr_debug("avail is %lu\n", (unsigned long)avail); /* check if we have at least one fragment to fill */ switch (runtime->state) { case SNDRV_PCM_STATE_DRAINING: diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 25f5e543ae8d..7751f9fc2f1d 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -656,6 +656,26 @@ int snd_soc_component_compr_pointer(struct snd_compr_s= tream *cstream, } EXPORT_SYMBOL_GPL(snd_soc_component_compr_pointer); =20 +int snd_soc_component_compr_pointer64(struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp) +{ + struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; + struct snd_soc_component *component; + int i, ret; + + for_each_rtd_components(rtd, i, component) { + if (component->driver->compress_ops && + component->driver->compress_ops->pointer64) { + ret =3D component->driver->compress_ops->pointer64( + component, cstream, tstamp); + return soc_component_ret(component, ret); + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_component_compr_pointer64); + int snd_soc_component_compr_copy(struct snd_compr_stream *cstream, char __user *buf, size_t count) { diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 01d1d6bee28c..29a385d327be 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -475,6 +475,25 @@ static int soc_compr_pointer(struct snd_compr_stream *= cstream, return ret; } =20 +static int soc_compr_pointer64(struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp) +{ + struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; + int ret; + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(rtd, 0); + + snd_soc_dpcm_mutex_lock(rtd); + + ret =3D snd_soc_dai_compr_pointer64(cpu_dai, cstream, tstamp); + if (ret < 0) + goto out; + + ret =3D snd_soc_component_compr_pointer64(cstream, tstamp); +out: + snd_soc_dpcm_mutex_unlock(rtd); + return ret; +} + static int soc_compr_set_metadata(struct snd_compr_stream *cstream, struct snd_compr_metadata *metadata) { @@ -513,6 +532,7 @@ static struct snd_compr_ops soc_compr_ops =3D { .get_params =3D soc_compr_get_params, .trigger =3D soc_compr_trigger, .pointer =3D soc_compr_pointer, + .pointer64 =3D soc_compr_pointer64, .ack =3D soc_compr_ack, .get_caps =3D snd_soc_component_compr_get_caps, .get_codec_caps =3D snd_soc_component_compr_get_codec_caps, @@ -528,6 +548,7 @@ static struct snd_compr_ops soc_compr_dyn_ops =3D { .get_metadata =3D soc_compr_get_metadata, .trigger =3D soc_compr_trigger_fe, .pointer =3D soc_compr_pointer, + .pointer64 =3D soc_compr_pointer64, .ack =3D soc_compr_ack, .get_caps =3D snd_soc_component_compr_get_caps, .get_codec_caps =3D snd_soc_component_compr_get_codec_caps, diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index a210089747d0..5aadf661b65d 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -784,6 +784,20 @@ int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai, } EXPORT_SYMBOL_GPL(snd_soc_dai_compr_pointer); =20 +int snd_soc_dai_compr_pointer64(struct snd_soc_dai *dai, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp) +{ + int ret =3D 0; + + if (dai->driver->cops && + dai->driver->cops->pointer64) + ret =3D dai->driver->cops->pointer64(cstream, tstamp, dai); + + return soc_dai_ret(dai, ret); +} +EXPORT_SYMBOL_GPL(snd_soc_dai_compr_pointer64); + int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai, struct snd_compr_stream *cstream, struct snd_compr_metadata *metadata) --=20 2.50.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 08:35:49 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF1AC20298D for ; Fri, 11 Jul 2025 08:25:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222357; cv=none; b=DbZNmHX+t781MyMarkBrkiMGOrRKJwtWN0DK7J5u8SXllkcYhlzxuWiEaj8B7zbShr45FKH90lBIdBw5QJo6KgRTuDZ/4b2Bsy3quVEZXfGOGJlWgtTpLG+ToooBSUrkltye51FbLtFBty7N8pGguYDCw8xdMMaHXmBRgaomrQ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222357; c=relaxed/simple; bh=6a+4TCE/XMdBY8XCQGqf4jLOM9sFzs2NSof6bp+3vgQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HFQmmM2r8u69ZcNPI0a/lUBGDl4oJgvjCuOL3CEO1yEgNAgreuKbpiFgICrL5Pl8UnL29YSgBqyMgHHYBa4TvJdLM5uT0KyFH4Kc72Dj9YAVJ5xEBWqDbd3BgS4DD9EATsN9fb67ij05FzZsmNcFzk/+k45/+028cYo2Uq7aCRk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Q/jCYJrc; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Q/jCYJrc" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-455d95e711cso1194105e9.0 for ; Fri, 11 Jul 2025 01:25:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752222354; x=1752827154; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=8L1+KbxtaiQj6sn8lQLye+giidcKEKOPXNRznqTkxqk=; b=Q/jCYJrcpxR8y58eEanFNCTeYjhGS88FN0wkH9CC8U59cFx2BRTyCdpxMrTMjsS9tH Dp0GOvz03wFsRXHzdYd05RPzacnsCEnt6TQZp2G7cq//IakiI/zsHiqYWBLNKAe1PHIG N6TI9cVoYmWXim3/w9I2zo8CypWtBqQp2eYDTGxD1Wddq3Co+qHlNxaI/XsuGnBlRryY Pfu3Js7k3cTIBcKJxaiuqXp2OvW0cgz3NIR0mFako4vroeM/3Ab/62PC2rJivj2/LzYd UvY/6mx3IDPcwIMeWs43vYFQfonI2Ip9knPh3QD/Flq9sZmUKxiBNIFEs5OI648eGYud x64A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752222354; x=1752827154; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=8L1+KbxtaiQj6sn8lQLye+giidcKEKOPXNRznqTkxqk=; b=nbRevwGhU3VW4aqaSibXsMx8tfgOifiIpas/+2WUpPIt/sVUC7HcATjMyGtnebXgHU CmQjabKiFkh2AH44m1k0qxzaYEGpK8yL5KB4eu2+RpslplJBOexO1RGeyGL6nb3B6Dlh DI+Su7g9GyAAuVGPT+XAsQ7ABiZdAaC9XCgaXwPM3vW5RCSCdRWP0l+gH0YB7qZkZU04 p7XaNxstqY6H8OW57VVv2G6iLbdeR569kZkCXtyp04OWFoeXJyCsr8lQoDIW2+1DzOek Z0qaPYiyjzipxLp/9qV0htlCb7C9gvnLTmWbiQd/av6s75YeTXjSn+aBTz5PqvN3dkkz 4r+w== X-Forwarded-Encrypted: i=1; AJvYcCXyyfCNbX3tT1FbTEZaL+uqft7/D7l8KqrYI3wsENnX1Q+ijsBRyrugwRGdOqeJoVKfIhro6OOT8XuleuQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yzt4RL6PCUs6mHBN843K68Qq9Cp6VVx8ur0P9Au9w1iII35HIWj w7FyK4Wbm2v57CRb0AaYAVW83087P62i+j0/kIEy9bmzvn4qqZ4PZ0gY4/7RZuG1IvpEXcIUIRh fC4ix6EgyUasq3XTSZg== X-Google-Smtp-Source: AGHT+IEhhhO+Ek1toZERYmrZMeqyTAhmBuFzPDQDq9WLvA9pxxXLVvjyXL3kguu3RptTS4+kf0xbW/3oRFlCSYQ= X-Received: from wmbeq14.prod.google.com ([2002:a05:600c:848e:b0:453:6ee6:e62a]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3e83:b0:453:92e:a459 with SMTP id 5b1f17b1804b1-454db8d8d06mr65138905e9.16.1752222354317; Fri, 11 Jul 2025 01:25:54 -0700 (PDT) Date: Fri, 11 Jul 2025 09:24:34 +0100 In-Reply-To: <20250711082441.4193295-1-verhaegen@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250711082441.4193295-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711082441.4193295-3-verhaegen@google.com> Subject: [PATCH v1 2/4] ALSA: compress_offload: Add SNDRV_COMPRESS_TSTAMP64 ioctl From: George Verhaegen To: Vinod Koul , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , Charles Keepax , Richard Fitzgerald , David Rhodes , Cezary Rojewski , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Srinivas Kandagatla , Daniel Baluta , Orson Zhai , Baolin Wang , Chunyan Zhang , Kunihiko Hayashi , Masami Hiramatsu Cc: Joris Verhaegen , kernel-team@android.com, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com, linux-arm-msm@vger.kernel.org, sound-open-firmware@alsa-project.org, linux-arm-kernel@lists.infradead.org, David Li , Miller Liang Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Joris Verhaegen The previous patch introduced the internal infrastructure for handling 64-bit timestamps. This patch exposes this capability to user-space. Define the new ioctl command SNDRV_COMPRESS_TSTAMP64, which allows applications to fetch the overflow-safe struct snd_compr_tstamp64. The ioctl dispatch table is updated to handle the new command by calling a new snd_compr_tstamp64 handler, while the legacy path is renamed to snd_compr_tstamp32 for clarity. Signed-off-by: Joris Verhaegen Tested-by: Joris Verhaegen Reviewed-by: David Li Reviewed-by: Miller Liang --- include/uapi/sound/compress_offload.h | 2 ++ sound/core/compress_offload.c | 50 +++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/com= press_offload.h index abd0ea3f86ee..2758d9ee3d91 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -208,6 +208,7 @@ struct snd_compr_task_status { * Note: only codec params can be changed runtime and stream params cant be * SNDRV_COMPRESS_GET_PARAMS: Query codec params * SNDRV_COMPRESS_TSTAMP: get the current timestamp value + * SNDRV_COMPRESS_TSTAMP64: get the current timestamp value in 64 bit form= at * SNDRV_COMPRESS_AVAIL: get the current buffer avail value. * This also queries the tstamp properties * SNDRV_COMPRESS_PAUSE: Pause the running stream @@ -230,6 +231,7 @@ struct snd_compr_task_status { struct snd_compr_metadata) #define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x20, struct snd_compr_tstamp) #define SNDRV_COMPRESS_AVAIL _IOR('C', 0x21, struct snd_compr_avail) +#define SNDRV_COMPRESS_TSTAMP64 _IOR('C', 0x22, struct snd_compr_tstamp64) #define SNDRV_COMPRESS_PAUSE _IO('C', 0x30) #define SNDRV_COMPRESS_RESUME _IO('C', 0x31) #define SNDRV_COMPRESS_START _IO('C', 0x32) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 6a8873bd62ae..40c1e69961b7 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -211,8 +211,8 @@ snd_compr_tstamp32_from_64(struct snd_compr_tstamp *tst= amp32, tstamp32->sampling_rate =3D tstamp64->sampling_rate; } =20 -static int snd_compr_update_tstamp(struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp) +static int snd_compr_update_tstamp32(struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp) { u64 copied_total64; struct snd_compr_tstamp64 tstamp64; @@ -238,11 +238,30 @@ static int snd_compr_update_tstamp(struct snd_compr_s= tream *stream, return 0; } =20 +static int snd_compr_update_tstamp64(struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp) +{ + int retval =3D snd_compr_get_tstamp64(stream, tstamp); + + if (retval !=3D 0) + return retval; + + pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset, + tstamp->copied_total); + + if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) + stream->runtime->total_bytes_transferred =3D tstamp->copied_total; + else + stream->runtime->total_bytes_available =3D tstamp->copied_total; + + return 0; +} + static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, struct snd_compr_avail *avail) { memset(avail, 0, sizeof(*avail)); - snd_compr_update_tstamp(stream, &avail->tstamp); + snd_compr_update_tstamp32(stream, &avail->tstamp); /* Still need to return avail even if tstamp can't be filled in */ =20 if (stream->runtime->total_bytes_available =3D=3D 0 && @@ -769,19 +788,34 @@ snd_compr_set_metadata(struct snd_compr_stream *strea= m, unsigned long arg) return retval; } =20 -static inline int -snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) +static inline int snd_compr_tstamp32(struct snd_compr_stream *stream, + unsigned long arg) { struct snd_compr_tstamp tstamp =3D {0}; int ret; =20 - ret =3D snd_compr_update_tstamp(stream, &tstamp); + ret =3D snd_compr_update_tstamp32(stream, &tstamp); if (ret =3D=3D 0) ret =3D copy_to_user((struct snd_compr_tstamp __user *)arg, &tstamp, sizeof(tstamp)) ? -EFAULT : 0; return ret; } =20 +static inline int snd_compr_tstamp64(struct snd_compr_stream *stream, + unsigned long arg) +{ + struct snd_compr_tstamp64 tstamp =3D { 0 }; + int ret; + + ret =3D snd_compr_update_tstamp64(stream, &tstamp); + if (ret =3D=3D 0) + ret =3D copy_to_user((struct snd_compr_tstamp64 __user *)arg, + &tstamp, sizeof(tstamp)) ? + -EFAULT : + 0; + return ret; +} + static int snd_compr_pause(struct snd_compr_stream *stream) { int retval; @@ -1355,7 +1389,9 @@ static long snd_compr_ioctl(struct file *f, unsigned = int cmd, unsigned long arg) =20 switch (_IOC_NR(cmd)) { case _IOC_NR(SNDRV_COMPRESS_TSTAMP): - return snd_compr_tstamp(stream, arg); + return snd_compr_tstamp32(stream, arg); + case _IOC_NR(SNDRV_COMPRESS_TSTAMP64): + return snd_compr_tstamp64(stream, arg); case _IOC_NR(SNDRV_COMPRESS_AVAIL): return snd_compr_ioctl_avail(stream, arg); case _IOC_NR(SNDRV_COMPRESS_PAUSE): --=20 2.50.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 08:35:49 2025 Received: from mail-ed1-f74.google.com (mail-ed1-f74.google.com [209.85.208.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ABB0C212FAA for ; Fri, 11 Jul 2025 08:26:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222368; cv=none; b=kjyK88bzqO9r0PcDfBud0VViLRZvvZr1AvgcTDjiiJIo7yzsjHVTTA3NA34p/rNJV6bQUY+32f40Dvcq+F9HkSCdzGeJAzkN3uWtlvN6/vkIKzY9p0G/A4eTK9tVs6GEfq1JSIX0KCn26kAheCCXs+ra9o96yyNyCBxq6ZsJjG0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222368; c=relaxed/simple; bh=iUqDZ6dWJYus360rBT7JdCA1UZ5cAnvzIOD4c4yrCBw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=uRBRiqhEX1Rk4mQIMTWRjW31qKNazllagWjUobrKt6PFRvSPsgpJhnckdxD8WCSRR7cklhgwnSQjXrIH6TEdhqeIwfgdUjN0bXLZSGxL+LY39XqF/0SS8P1m0/qUePrCRIZIahmuLnhGlSXMu3VN73UyqzbOeuGXMqcAhdylyis= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=kvCUSic8; arc=none smtp.client-ip=209.85.208.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kvCUSic8" Received: by mail-ed1-f74.google.com with SMTP id 4fb4d7f45d1cf-60724177a1fso1956551a12.3 for ; Fri, 11 Jul 2025 01:26:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752222365; x=1752827165; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=OI8EJdj4iWn/1u1hrxV7gJL9a9iP26e/+tYZeBGEhqQ=; b=kvCUSic81zc9q861RSTTsima44l0XOS9iyAsCHHBYqJGtI2Hq73VitXwtAMGwAW8j+ +ScXQ5/Upuq/knPMRN+GrkH40PtUYZu6F6I08eBRr4YMTXzLfQH0VO45w9Lomaovkh79 5C2Wt2mKlV/b6DI+Man4t3si55OSsWvksHhi2sOhHkjlyFxEYTh4TzWZFcBrTYT0QkgJ TNFTk+IiGNbU8RiTReQmjot6610BvdH6W/qW8mwF4hLHrOLxRXUmZGbnpxVPrqz7zO5R copcDkhPOvLJHRTLLKSxyLj221AOfTmWZ6WG/oRW5Mjduz5buQqNpA4Y43yaUKyNp8k6 /Xcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752222365; x=1752827165; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=OI8EJdj4iWn/1u1hrxV7gJL9a9iP26e/+tYZeBGEhqQ=; b=uz7x/I3kTRqL4mDTVyf9gAmaWY0d/EsypyMKPeRvfJCwFRSVI3/yG6eYhYYFAMt4eU 7dSOgi7/QpabBkXve7IqcrpDsPisKSPOuITsqD+c9n/i/NFCigb8SM/y88aqNQzHGdV5 Zmu6VkDQqd3l+/gd2GOvYcP10wI+qwMVxJdLJ9R3WrA79RMVQL6mmZZp2x4bm/F16JYw LUaCPsZPI64zWSgHyc18P/GduIsOiR90Rd2MibetRV0Z6iLumXOGNUOwcimnhJWrjcGy KTM6H5tDc0y2kBio1o7HzbfSFNWiXVfXnR4eqQm4+3akgUcjGNWqs5bSTnZeMV0EnQgs DzNw== X-Forwarded-Encrypted: i=1; AJvYcCUZrgw0pfvdwigu/J07wCBVSf9A2gr2B8/YUe57htrCNCrDMvQ+uHoz1NLthAyLBS72wOz0MCoFtbziyZo=@vger.kernel.org X-Gm-Message-State: AOJu0Yx6A1I577G2/QplwnQ0xr5KGtFSpb+TGVxwr1n+uAx9/JywcV4B ZQatZ7o+TbjJaMafLSrHfm5REgnTRvPiFZ2+lR1dxj1tzYxaidSiEkLxNt0g3hmgIsctfIkFFWN SL1XaemkEnLLrU3zdJQ== X-Google-Smtp-Source: AGHT+IHI8PTrj97CrFmguJmIDyCYPUtRTqpUv31CiuHbIgrvImgMyuw2xI5mKz+ZrzTXQ83FPflouczIPb1Ff4c= X-Received: from edbdc17.prod.google.com ([2002:a05:6402:3111:b0:60e:395c:9cd1]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:13c1:b0:60b:9cf8:b218 with SMTP id 4fb4d7f45d1cf-611e7614a78mr1823302a12.7.1752222364829; Fri, 11 Jul 2025 01:26:04 -0700 (PDT) Date: Fri, 11 Jul 2025 09:24:35 +0100 In-Reply-To: <20250711082441.4193295-1-verhaegen@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250711082441.4193295-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711082441.4193295-4-verhaegen@google.com> Subject: [PATCH v1 3/4] ALSA: compress_offload: Add SNDRV_COMPRESS_AVAIL64 ioctl From: George Verhaegen To: Vinod Koul , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , Charles Keepax , Richard Fitzgerald , David Rhodes , Cezary Rojewski , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Srinivas Kandagatla , Daniel Baluta , Orson Zhai , Baolin Wang , Chunyan Zhang , Kunihiko Hayashi , Masami Hiramatsu Cc: Joris Verhaegen , kernel-team@android.com, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com, linux-arm-msm@vger.kernel.org, sound-open-firmware@alsa-project.org, linux-arm-kernel@lists.infradead.org, David Li , Miller Liang Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Joris Verhaegen Previous patches introduced ioctl for fetching a 64-bit timestamp via SNDRV_COMPRESS_TSTAMP64. To provide a consistent API, a 64-bit version of SNDRV_COMPRESS_AVAIL ioctl is required. Define a new struct snd_compr_avail64, which embeds the 64-bit timestamp struct, and define the corresponding SNDRV_COMPRESS_AVAIL64 ioctl command in the UAPI header. Signed-off-by: Joris Verhaegen Tested-by: Joris Verhaegen Reviewed-by: David Li Reviewed-by: Miller Liang --- include/uapi/sound/compress_offload.h | 11 ++++ sound/core/compress_offload.c | 88 +++++++++++++++++++++------ 2 files changed, 79 insertions(+), 20 deletions(-) diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/com= press_offload.h index 2758d9ee3d91..48525a87d98f 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -85,6 +85,16 @@ struct snd_compr_avail { struct snd_compr_tstamp tstamp; } __attribute__((packed, aligned(4))); =20 +/** + * struct snd_compr_avail64 - avail descriptor with tstamp in 64 bit format + * @avail: Number of bytes available in ring buffer for writing/reading + * @tstamp: timestamp information + */ +struct snd_compr_avail64 { + __u64 avail; + struct snd_compr_tstamp64 tstamp; +} __attribute__((packed, aligned(4))); + enum snd_compr_direction { SND_COMPRESS_PLAYBACK =3D 0, SND_COMPRESS_CAPTURE, @@ -232,6 +242,7 @@ struct snd_compr_task_status { #define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x20, struct snd_compr_tstamp) #define SNDRV_COMPRESS_AVAIL _IOR('C', 0x21, struct snd_compr_avail) #define SNDRV_COMPRESS_TSTAMP64 _IOR('C', 0x22, struct snd_compr_tstamp64) +#define SNDRV_COMPRESS_AVAIL64 _IOR('C', 0x23, struct snd_compr_avail64) #define SNDRV_COMPRESS_PAUSE _IO('C', 0x30) #define SNDRV_COMPRESS_RESUME _IO('C', 0x31) #define SNDRV_COMPRESS_START _IO('C', 0x32) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 40c1e69961b7..78ba86e0d74f 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -257,12 +257,11 @@ static int snd_compr_update_tstamp64(struct snd_compr= _stream *stream, return 0; } =20 -static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, - struct snd_compr_avail *avail) +static size_t snd_compr_calc_avail_internal(struct snd_compr_stream *strea= m, + struct snd_compr_avail *avail32, + struct snd_compr_avail64 *avail64) { - memset(avail, 0, sizeof(*avail)); - snd_compr_update_tstamp32(stream, &avail->tstamp); - /* Still need to return avail even if tstamp can't be filled in */ + u64 avail; =20 if (stream->runtime->total_bytes_available =3D=3D 0 && stream->runtime->state =3D=3D SNDRV_PCM_STATE_SETUP && @@ -284,33 +283,68 @@ static size_t snd_compr_calc_avail(struct snd_compr_s= tream *stream, } } =20 - avail->avail =3D stream->runtime->total_bytes_available - - stream->runtime->total_bytes_transferred; + avail =3D stream->runtime->total_bytes_available - + stream->runtime->total_bytes_transferred; if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) - avail->avail =3D stream->runtime->buffer_size - avail->avail; + avail =3D stream->runtime->buffer_size - avail; + + if (avail32) + avail32->avail =3D avail; + if (avail64) + avail64->avail =3D avail; + + pr_debug("ret avail %llu as %zu\n", avail, (size_t)avail); + return avail; +} + +static size_t snd_compr_calc_avail32(struct snd_compr_stream *stream, + struct snd_compr_avail *avail) +{ + memset(avail, 0, sizeof(*avail)); + snd_compr_update_tstamp32(stream, &avail->tstamp); + /* Still need to return avail even if tstamp can't be filled in */ =20 - pr_debug("ret avail as %llu\n", avail->avail); - return avail->avail; + return snd_compr_calc_avail_internal(stream, avail, NULL); +} + +static size_t snd_compr_calc_avail64(struct snd_compr_stream *stream, + struct snd_compr_avail64 *avail) +{ + memset(avail, 0, sizeof(*avail)); + snd_compr_update_tstamp64(stream, &avail->tstamp); + /* Still need to return avail even if tstamp can't be filled in */ + + return snd_compr_calc_avail_internal(stream, NULL, avail); } =20 static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) { struct snd_compr_avail avail; =20 - return snd_compr_calc_avail(stream, &avail); + return snd_compr_calc_avail32(stream, &avail); } =20 -static int -snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg) +static int snd_compr_ioctl_avail(struct snd_compr_stream *stream, + unsigned long arg, bool is_64bit) { - struct snd_compr_avail ioctl_avail; - size_t avail; + union { + struct snd_compr_avail avail32; + struct snd_compr_avail64 avail64; + } ioctrl_avail_u; + size_t avail, ioctrl_avail_size; =20 if (stream->direction =3D=3D SND_COMPRESS_ACCEL) return -EBADFD; =20 - avail =3D snd_compr_calc_avail(stream, &ioctl_avail); - ioctl_avail.avail =3D avail; + if (is_64bit) { + avail =3D snd_compr_calc_avail64(stream, &ioctrl_avail_u.avail64); + ioctrl_avail_u.avail64.avail =3D avail; + ioctrl_avail_size =3D sizeof(ioctrl_avail_u.avail64); + } else { + avail =3D snd_compr_calc_avail32(stream, &ioctrl_avail_u.avail32); + ioctrl_avail_u.avail32.avail =3D avail; + ioctrl_avail_size =3D sizeof(ioctrl_avail_u.avail32); + } =20 switch (stream->runtime->state) { case SNDRV_PCM_STATE_OPEN: @@ -321,12 +355,24 @@ snd_compr_ioctl_avail(struct snd_compr_stream *stream= , unsigned long arg) break; } =20 - if (copy_to_user((__u64 __user *)arg, - &ioctl_avail, sizeof(ioctl_avail))) + if (copy_to_user((__u64 __user *)arg, &ioctrl_avail_u, + ioctrl_avail_size)) return -EFAULT; return 0; } =20 +static int snd_compr_ioctl_avail32(struct snd_compr_stream *stream, + unsigned long arg) +{ + return snd_compr_ioctl_avail(stream, arg, false); +} + +static int snd_compr_ioctl_avail64(struct snd_compr_stream *stream, + unsigned long arg) +{ + return snd_compr_ioctl_avail(stream, arg, true); +} + static int snd_compr_write_data(struct snd_compr_stream *stream, const char __user *buf, size_t count) { @@ -1393,7 +1439,9 @@ static long snd_compr_ioctl(struct file *f, unsigned = int cmd, unsigned long arg) case _IOC_NR(SNDRV_COMPRESS_TSTAMP64): return snd_compr_tstamp64(stream, arg); case _IOC_NR(SNDRV_COMPRESS_AVAIL): - return snd_compr_ioctl_avail(stream, arg); + return snd_compr_ioctl_avail32(stream, arg); + case _IOC_NR(SNDRV_COMPRESS_AVAIL64): + return snd_compr_ioctl_avail64(stream, arg); case _IOC_NR(SNDRV_COMPRESS_PAUSE): return snd_compr_pause(stream); case _IOC_NR(SNDRV_COMPRESS_RESUME): --=20 2.50.0.727.gbf7dc18ff4-goog From nobody Tue Oct 7 08:35:49 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F5AA1E5206 for ; Fri, 11 Jul 2025 08:26:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222383; cv=none; b=AHERSCvJ5i2bRKctChOQd0DXk8XHjBOeRBBN4w50UOges0NRFmf0DNi7S5C2Z1sPA/xN4f3DNJTc/2gv7xLr5SiJQOswB0pHxtXU+OVR+4zCQukV0OvLaxjuzmQNLyuOHlkwqldg9J66xOu4pbJGiqMEfFkVFivkZRHZonVuWyQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752222383; c=relaxed/simple; bh=QNrvmanPsA6D02wDxkrZKNN2jYxE+wA4yv9qE0SK+r4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hGyb0YlIMrodji3Vvijy6fjn6nt/ZjGnWv1flZL4ZWEIAUPODevlx1NDZM4Y25MxaRFNiMR/Hr8fBWGY6lwFZPyYz07WLCzfFyFFYDc1Ulc5D0Nt9yNIalELhWFn+JuK8l5X9Xi0R1yZPvGZrjpbyvMsy8+5VA/NR9zgzNmA6JQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=1H+XF/Fh; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="1H+XF/Fh" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3a5281ba3a4so668347f8f.0 for ; Fri, 11 Jul 2025 01:26:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752222379; x=1752827179; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=kVOAmFl5zAXti6gLh+ZBvmTubm+lk5B/VHkbfciCopw=; b=1H+XF/Fh2hOAdUlmfWWojwu+paO4wB8QSfMyhSNFASS+FnN69OScBrJeotumNOuW0d /EuX2GXLBbZMwzvn1hZy7Zzyeq0eqrln7NAYz/2ctd4mfdXSYsbSaoFk+SQXvkitqnKn kX2tKqDpI2ckEjDAvMKty/EDDjB7F2GuyikJL4B01SOZitlweAUm+OXWLZd0r/CGWSlb 13Cjz5SPGUoLMxlxSCYyXLGQhSqgvRJD7Viw3Txe40PyC1Wxx9/broeXX4CvCuR+Lphe 0QKMb0LlwT0ALC0odJfx4CLNWjS2hwmMacZK4ooJXjTVnBMcgA4AWZemrgwkT3I+6U+T MdLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752222379; x=1752827179; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kVOAmFl5zAXti6gLh+ZBvmTubm+lk5B/VHkbfciCopw=; b=lJ1HmLh3/hW85dLtX3v4WfddoA1kipDGAvoitp2VsANtndX8bdBTHzyKxgI4p8Srl1 ZfbJVyg08lgChFsPWX1XcGWA91B1c5QVU3nixn6VmbRQhNtZjg3I3vnf6wWj+YbPGw6s oES7aGhRmrrmIkn7G8Qhw8el3BqxX3KbHehBFYU1HbexL9FMD5NFv0V7LoXEjzpyoerl 9bnKdvePRBjLGMmk9AbxEl1Em82PUsHCD/v9o+ERqt/zDcP2SN5ekwrie5Cs/XXybA37 ojRnrMxCYlRChMtGEd5acRx4IdjaGb3/GUufKmeWyZIJeWvv3Xpfx5pIJ7fqeXDJM/rZ by8Q== X-Forwarded-Encrypted: i=1; AJvYcCXF26L/b+shYxOe/fnqrl/9bPjlgSBHNZh3xdnEOA4nrRz402ZVI9ya5WuzSVOh6g25kHmxnKaRLdROBtM=@vger.kernel.org X-Gm-Message-State: AOJu0YxufzmQCA4AOgdUYchSPCgfG8F86T/X6OB+DN5clZ9yX62MYyum 56gYTX3X2/4bCcYtF4DuxRsG8Ir2r6XsBEN2OQJSTVTqmkbB33p1nOuWbw4OnQ4i7UfInWCeFle Xu0ZWqz/T/cqLweFHFQ== X-Google-Smtp-Source: AGHT+IEI8EkLH0hhCg4Fm9u33G3qmbru/qHXDL/egnit1i+ENrtOKNrNURybCKMiB1sHll+wQJz/7rhGRb7Sr8c= X-Received: from wrvr4.prod.google.com ([2002:a5d:52c4:0:b0:3b3:9c56:9547]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:adf:e19b:0:b0:3b5:dbd8:ad5f with SMTP id ffacd0b85a97d-3b5f18e8179mr2070870f8f.58.1752222378914; Fri, 11 Jul 2025 01:26:18 -0700 (PDT) Date: Fri, 11 Jul 2025 09:24:36 +0100 In-Reply-To: <20250711082441.4193295-1-verhaegen@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250711082441.4193295-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711082441.4193295-5-verhaegen@google.com> Subject: [PATCH v1 4/4] ASoC: codecs: Implement 64-bit pointer operation From: George Verhaegen To: Vinod Koul , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , Charles Keepax , Richard Fitzgerald , David Rhodes , Cezary Rojewski , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Srinivas Kandagatla , Daniel Baluta , Orson Zhai , Baolin Wang , Chunyan Zhang , Kunihiko Hayashi , Masami Hiramatsu Cc: Joris Verhaegen , kernel-team@android.com, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com, linux-arm-msm@vger.kernel.org, sound-open-firmware@alsa-project.org, linux-arm-kernel@lists.infradead.org, David Li , Miller Liang Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Joris Verhaegen Implement the new .pointer64 compress operation for the various ASoC drivers that support compress offload. For drivers with complex but similar 32-bit and 64-bit logic (wm_adsp, sof, uniphier), a shared internal function is used to handle both requests, minimizing code duplication and improving maintainability. For other drivers, internal counters and related variables are updated to u64 to ensure the source of the timestamp data is overflow-safe. The legacy .pointer operation is retained in all drivers to ensure full backward compatibility. Signed-off-by: Joris Verhaegen Tested-by: Joris Verhaegen Reviewed-by: David Li Reviewed-by: Miller Liang --- sound/soc/codecs/cs47l15.c | 1 + sound/soc/codecs/cs47l24.c | 1 + sound/soc/codecs/cs47l35.c | 1 + sound/soc/codecs/cs47l85.c | 1 + sound/soc/codecs/cs47l90.c | 1 + sound/soc/codecs/cs47l92.c | 1 + sound/soc/codecs/wm5102.c | 1 + sound/soc/codecs/wm5110.c | 1 + sound/soc/codecs/wm_adsp.c | 53 +++++++++++++++---- sound/soc/codecs/wm_adsp.h | 3 ++ .../intel/atom/sst-mfld-platform-compress.c | 17 +++++- sound/soc/intel/atom/sst-mfld-platform.h | 2 + sound/soc/intel/atom/sst/sst_drv_interface.c | 43 +++++++++++++-- sound/soc/qcom/qdsp6/q6asm-dai.c | 41 ++++++++++---- sound/soc/sof/compress.c | 44 +++++++++++---- sound/soc/sprd/sprd-pcm-compress.c | 28 +++++++--- sound/soc/sprd/sprd-pcm-dma.h | 2 +- sound/soc/uniphier/aio-compress.c | 40 +++++++++++--- 18 files changed, 232 insertions(+), 49 deletions(-) diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index 29a2bcfb3048..40e75af3367e 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -1342,6 +1342,7 @@ static const struct snd_compress_ops cs47l15_compress= _ops =3D { .get_caps =3D &wm_adsp_compr_get_caps, .trigger =3D &wm_adsp_compr_trigger, .pointer =3D &wm_adsp_compr_pointer, + .pointer64 =3D &wm_adsp_compr_pointer64, .copy =3D &wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index e2a839fae4fc..30c434a3fa53 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1189,6 +1189,7 @@ static const struct snd_compress_ops cs47l24_compress= _ops =3D { .get_caps =3D wm_adsp_compr_get_caps, .trigger =3D wm_adsp_compr_trigger, .pointer =3D wm_adsp_compr_pointer, + .pointer64 =3D wm_adsp_compr_pointer64, .copy =3D wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c index 85555c7a2e4b..8b416f452c45 100644 --- a/sound/soc/codecs/cs47l35.c +++ b/sound/soc/codecs/cs47l35.c @@ -1624,6 +1624,7 @@ static const struct snd_compress_ops cs47l35_compress= _ops =3D { .get_caps =3D &wm_adsp_compr_get_caps, .trigger =3D &wm_adsp_compr_trigger, .pointer =3D &wm_adsp_compr_pointer, + .pointer64 =3D &wm_adsp_compr_pointer64, .copy =3D &wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c index d34f4e8c26d3..b8ef0a69a2c5 100644 --- a/sound/soc/codecs/cs47l85.c +++ b/sound/soc/codecs/cs47l85.c @@ -2568,6 +2568,7 @@ static const struct snd_compress_ops cs47l85_compress= _ops =3D { .get_caps =3D &wm_adsp_compr_get_caps, .trigger =3D &wm_adsp_compr_trigger, .pointer =3D &wm_adsp_compr_pointer, + .pointer64 =3D &wm_adsp_compr_pointer64, .copy =3D &wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c index a9e703981f37..1ae44155e306 100644 --- a/sound/soc/codecs/cs47l90.c +++ b/sound/soc/codecs/cs47l90.c @@ -2483,6 +2483,7 @@ static const struct snd_compress_ops cs47l90_compress= _ops =3D { .get_caps =3D &wm_adsp_compr_get_caps, .trigger =3D &wm_adsp_compr_trigger, .pointer =3D &wm_adsp_compr_pointer, + .pointer64 =3D &wm_adsp_compr_pointer64, .copy =3D &wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c index 2c355c61acd8..0be338dabf25 100644 --- a/sound/soc/codecs/cs47l92.c +++ b/sound/soc/codecs/cs47l92.c @@ -1950,6 +1950,7 @@ static const struct snd_compress_ops cs47l92_compress= _ops =3D { .get_caps =3D &wm_adsp_compr_get_caps, .trigger =3D &wm_adsp_compr_trigger, .pointer =3D &wm_adsp_compr_pointer, + .pointer64 =3D &wm_adsp_compr_pointer64, .copy =3D &wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 9fc7a8325724..3f691f2f3269 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -2013,6 +2013,7 @@ static const struct snd_compress_ops wm5102_compress_= ops =3D { .get_caps =3D wm_adsp_compr_get_caps, .trigger =3D wm_adsp_compr_trigger, .pointer =3D wm_adsp_compr_pointer, + .pointer64 =3D wm_adsp_compr_pointer64, .copy =3D wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 212eca675f27..8470ade90bad 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2370,6 +2370,7 @@ static const struct snd_compress_ops wm5110_compress_= ops =3D { .get_caps =3D wm_adsp_compr_get_caps, .trigger =3D wm_adsp_compr_trigger, .pointer =3D wm_adsp_compr_pointer, + .pointer64 =3D wm_adsp_compr_pointer64, .copy =3D wm_adsp_compr_copy, }; =20 diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 8a1d5cc75d6c..0c3cc08aa3a8 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -173,7 +173,7 @@ struct wm_adsp_compr { struct snd_compressed_buffer size; =20 u32 *raw_buf; - unsigned int copied_total; + u64 copied_total; =20 unsigned int sample_rate; =20 @@ -1858,17 +1858,16 @@ static int wm_adsp_buffer_reenable_irq(struct wm_ad= sp_compr_buf *buf) buf->irq_count); } =20 -int wm_adsp_compr_pointer(struct snd_soc_component *component, - struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp) +static int wm_adsp_compr_pointer_internal(struct snd_soc_component *compon= ent, + struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp32, + struct snd_compr_tstamp64 *tstamp64) { struct wm_adsp_compr *compr =3D stream->runtime->private_data; struct wm_adsp *dsp =3D compr->dsp; struct wm_adsp_compr_buf *buf; int ret =3D 0; =20 - compr_dbg(compr, "Pointer request\n"); - mutex_lock(&dsp->cs_dsp.pwr_lock); =20 buf =3D compr->buf; @@ -1908,17 +1907,53 @@ int wm_adsp_compr_pointer(struct snd_soc_component = *component, } } =20 - tstamp->copied_total =3D compr->copied_total; - tstamp->copied_total +=3D buf->avail * CS_DSP_DATA_WORD_SIZE; - tstamp->sampling_rate =3D compr->sample_rate; + if (tstamp32) { + tstamp32->copied_total =3D (u32)compr->copied_total; + tstamp32->copied_total +=3D buf->avail * CS_DSP_DATA_WORD_SIZE; + tstamp32->sampling_rate =3D compr->sample_rate; + } + if (tstamp64) { + tstamp64->copied_total =3D compr->copied_total; + tstamp64->copied_total +=3D buf->avail * CS_DSP_DATA_WORD_SIZE; + tstamp64->sampling_rate =3D compr->sample_rate; + } =20 out: mutex_unlock(&dsp->cs_dsp.pwr_lock); =20 return ret; } + +int wm_adsp_compr_pointer(struct snd_soc_component *component, + struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp) +{ + struct wm_adsp_compr *compr =3D stream->runtime->private_data; + int ret =3D 0; + + compr_dbg(compr, "Pointer request\n"); + + ret =3D wm_adsp_compr_pointer_internal(component, stream, tstamp, NULL); + + return ret; +} EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer); =20 +int wm_adsp_compr_pointer64(struct snd_soc_component *component, + struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp) +{ + struct wm_adsp_compr *compr =3D stream->runtime->private_data; + int ret =3D 0; + + compr_dbg(compr, "Pointer64 request\n"); + + ret =3D wm_adsp_compr_pointer_internal(component, stream, NULL, tstamp); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer64); + static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int t= arget) { struct wm_adsp_compr_buf *buf =3D compr->buf; diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 25210d404bf1..5027236bb92e 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -132,6 +132,9 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp); int wm_adsp_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *stream, struct snd_compr_tstamp *tstamp); +int wm_adsp_compr_pointer64(struct snd_soc_component *component, + struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp); int wm_adsp_compr_copy(struct snd_soc_component *component, struct snd_compr_stream *stream, char __user *buf, size_t count); diff --git a/sound/soc/intel/atom/sst-mfld-platform-compress.c b/sound/soc/= intel/atom/sst-mfld-platform-compress.c index 89c9c5ad6b21..9fbd0d641059 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-compress.c +++ b/sound/soc/intel/atom/sst-mfld-platform-compress.c @@ -210,7 +210,21 @@ static int sst_platform_compr_pointer(struct snd_soc_c= omponent *component, stream->compr_ops->tstamp(sst->dev, stream->id, tstamp); tstamp->byte_offset =3D tstamp->copied_total % (u32)cstream->runtime->buffer_size; - pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); + pr_debug("calc bytes offset/copied bytes as %u\n", tstamp->byte_offset); + return 0; +} + +static int sst_platform_compr_pointer64(struct snd_soc_component *componen= t, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp) +{ + struct sst_runtime_stream *stream; + + stream =3D cstream->runtime->private_data; + stream->compr_ops->tstamp64(sst->dev, stream->id, tstamp); + tstamp->byte_offset =3D + tstamp->copied_total % cstream->runtime->buffer_size; + pr_debug("calc bytes offset/copied bytes as %u\n", tstamp->byte_offset); return 0; } =20 @@ -265,6 +279,7 @@ const struct snd_compress_ops sst_platform_compress_ops= =3D { .set_metadata =3D sst_platform_compr_set_metadata, .trigger =3D sst_platform_compr_trigger, .pointer =3D sst_platform_compr_pointer, + .pointer64 =3D sst_platform_compr_pointer64, .ack =3D sst_platform_compr_ack, .get_caps =3D sst_platform_compr_get_caps, .get_codec_caps =3D sst_platform_compr_get_codec_caps, diff --git a/sound/soc/intel/atom/sst-mfld-platform.h b/sound/soc/intel/ato= m/sst-mfld-platform.h index 8b5777d3229a..bc21a36a4cc0 100644 --- a/sound/soc/intel/atom/sst-mfld-platform.h +++ b/sound/soc/intel/atom/sst-mfld-platform.h @@ -106,6 +106,8 @@ struct compress_sst_ops { =20 int (*tstamp)(struct device *dev, unsigned int str_id, struct snd_compr_tstamp *tstamp); + int (*tstamp64)(struct device *dev, unsigned int str_id, + struct snd_compr_tstamp64 *tstamp); int (*ack)(struct device *dev, unsigned int str_id, unsigned long bytes); int (*close)(struct device *dev, unsigned int str_id); diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel= /atom/sst/sst_drv_interface.c index 8bb27f86eb65..f6472ad29e47 100644 --- a/sound/soc/intel/atom/sst/sst_drv_interface.c +++ b/sound/soc/intel/atom/sst/sst_drv_interface.c @@ -325,8 +325,8 @@ static int sst_cdev_stream_partial_drain(struct device = *dev, return sst_drain_stream(ctx, str_id, true); } =20 -static int sst_cdev_tstamp(struct device *dev, unsigned int str_id, - struct snd_compr_tstamp *tstamp) +static int sst_cdev_tstamp32(struct device *dev, unsigned int str_id, + struct snd_compr_tstamp *tstamp) { struct snd_sst_tstamp fw_tstamp =3D {0,}; struct stream_info *stream; @@ -350,9 +350,41 @@ static int sst_cdev_tstamp(struct device *dev, unsigne= d int str_id, tstamp->sampling_rate =3D fw_tstamp.sampling_frequency; =20 dev_dbg(dev, "PCM =3D %u\n", tstamp->pcm_io_frames); - dev_dbg(dev, "Ptr Query on strid =3D %d copied_total %d, decodec %d\n", + dev_dbg(dev, "Ptr Query on strid =3D %d copied_total %u, decodec %u\n", str_id, tstamp->copied_total, tstamp->pcm_frames); - dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames); + dev_dbg(dev, "rendered %u\n", tstamp->pcm_io_frames); + + return 0; +} + +static int sst_cdev_tstamp64(struct device *dev, unsigned int str_id, + struct snd_compr_tstamp64 *tstamp) +{ + struct snd_sst_tstamp fw_tstamp =3D {0,}; + struct stream_info *stream; + struct intel_sst_drv *ctx =3D dev_get_drvdata(dev); + void __iomem *addr; + + addr =3D (void __iomem *)(ctx->mailbox + ctx->tstamp) + + (str_id * sizeof(fw_tstamp)); + + memcpy_fromio(&fw_tstamp, addr, sizeof(fw_tstamp)); + + stream =3D get_stream_info(ctx, str_id); + if (!stream) + return -EINVAL; + dev_dbg(dev, "rb_counter %llu in bytes\n", fw_tstamp.ring_buffer_counter); + + tstamp->copied_total =3D fw_tstamp.ring_buffer_counter; + tstamp->pcm_frames =3D fw_tstamp.frames_decoded; + tstamp->pcm_io_frames =3D div_u64(fw_tstamp.hardware_counter, + (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24)); + tstamp->sampling_rate =3D fw_tstamp.sampling_frequency; + + dev_dbg(dev, "PCM =3D %llu\n", tstamp->pcm_io_frames); + dev_dbg(dev, "Ptr Query on strid =3D %d copied_total %llu, decodec %llu\= n", + str_id, tstamp->copied_total, tstamp->pcm_frames); + dev_dbg(dev, "rendered %llu\n", tstamp->pcm_io_frames); =20 return 0; } @@ -650,7 +682,8 @@ static struct compress_sst_ops compr_ops =3D { .stream_drop =3D sst_cdev_stream_drop, .stream_drain =3D sst_cdev_stream_drain, .stream_partial_drain =3D sst_cdev_stream_partial_drain, - .tstamp =3D sst_cdev_tstamp, + .tstamp =3D sst_cdev_tstamp32, + .tstamp64 =3D sst_cdev_tstamp64, .ack =3D sst_cdev_ack, .get_caps =3D sst_cdev_caps, .get_codec_caps =3D sst_cdev_codec_caps, diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-= dai.c index a400c9a31fea..d9917eca5f80 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -59,9 +59,9 @@ struct q6asm_dai_rtd { unsigned int pcm_count; unsigned int pcm_irq_pos; /* IRQ position */ unsigned int periods; - unsigned int bytes_sent; - unsigned int bytes_received; - unsigned int copied_total; + uint64_t bytes_sent; + uint64_t bytes_received; + uint64_t copied_total; uint16_t bits_per_sample; uint16_t source; /* Encoding source bit mask */ struct audio_client *audio_client; @@ -1024,9 +1024,27 @@ static int q6asm_dai_compr_trigger(struct snd_soc_co= mponent *component, return ret; } =20 -static int q6asm_dai_compr_pointer(struct snd_soc_component *component, - struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp) +static int q6asm_dai_compr_pointer32(struct snd_soc_component *component, + struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp) +{ + struct snd_compr_runtime *runtime =3D stream->runtime; + struct q6asm_dai_rtd *prtd =3D runtime->private_data; + unsigned long flags; + + spin_lock_irqsave(&prtd->lock, flags); + + tstamp->copied_total =3D (u32) prtd->copied_total; + tstamp->byte_offset =3D prtd->copied_total % prtd->pcm_size; + + spin_unlock_irqrestore(&prtd->lock, flags); + + return 0; +} + +static int q6asm_dai_compr_pointer64(struct snd_soc_component *component, + struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp) { struct snd_compr_runtime *runtime =3D stream->runtime; struct q6asm_dai_rtd *prtd =3D runtime->private_data; @@ -1050,11 +1068,12 @@ static int q6asm_compr_copy(struct snd_soc_componen= t *component, struct q6asm_dai_rtd *prtd =3D runtime->private_data; unsigned long flags; u32 wflags =3D 0; - int avail, bytes_in_flight =3D 0; + u64 avail =3D 0; + u64 bytes_in_flight =3D 0; void *dstn; size_t copy; u32 app_pointer; - u32 bytes_received; + u64 bytes_received; =20 bytes_received =3D prtd->bytes_received; =20 @@ -1065,8 +1084,7 @@ static int q6asm_compr_copy(struct snd_soc_component = *component, if (prtd->next_track) bytes_received =3D ALIGN(prtd->bytes_received, prtd->pcm_count); =20 - app_pointer =3D bytes_received/prtd->pcm_size; - app_pointer =3D bytes_received - (app_pointer * prtd->pcm_size); + app_pointer =3D bytes_received % prtd->pcm_size; dstn =3D prtd->dma_buffer.area + app_pointer; =20 if (count < prtd->pcm_size - app_pointer) { @@ -1164,7 +1182,8 @@ static const struct snd_compress_ops q6asm_dai_compre= ss_ops =3D { .free =3D q6asm_dai_compr_free, .set_params =3D q6asm_dai_compr_set_params, .set_metadata =3D q6asm_dai_compr_set_metadata, - .pointer =3D q6asm_dai_compr_pointer, + .pointer =3D q6asm_dai_compr_pointer32, + .pointer64 =3D q6asm_dai_compr_pointer64, .trigger =3D q6asm_dai_compr_trigger, .get_caps =3D q6asm_dai_compr_get_caps, .get_codec_caps =3D q6asm_dai_compr_get_codec_caps, diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index d7b044f33d79..6eb0ceccde37 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -359,33 +359,59 @@ static int sof_compr_copy(struct snd_soc_component *c= omponent, return sof_compr_copy_capture(rtd, buf, count); } =20 -static int sof_compr_pointer(struct snd_soc_component *component, - struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) +static int sof_compr_pointer_internal(struct snd_soc_component *component, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp32, + struct snd_compr_tstamp64 *tstamp64) { struct snd_sof_pcm *spcm; struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; struct sof_compr_stream *sstream =3D cstream->runtime->private_data; + u64 pcm_io_frames; =20 spcm =3D snd_sof_find_spcm_dai(component, rtd); if (!spcm) return -EINVAL; - - tstamp->sampling_rate =3D sstream->sampling_rate; - tstamp->copied_total =3D sstream->copied_total; - tstamp->pcm_io_frames =3D div_u64(spcm->stream[cstream->direction].posn.d= ai_posn, - sstream->channels * sstream->sample_container_bytes); + pcm_io_frames =3D + div_u64(spcm->stream[cstream->direction].posn.dai_posn, + sstream->channels * sstream->sample_container_bytes); + + if (tstamp32) { + tstamp32->sampling_rate =3D sstream->sampling_rate; + tstamp32->copied_total =3D (u32)sstream->copied_total; + tstamp32->pcm_io_frames =3D (u32)pcm_io_frames; + } + if (tstamp64) { + tstamp64->sampling_rate =3D sstream->sampling_rate; + tstamp64->copied_total =3D sstream->copied_total; + tstamp64->pcm_io_frames =3D pcm_io_frames; + } =20 return 0; } =20 +static int sof_compr_pointer32(struct snd_soc_component *component, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp) +{ + return sof_compr_pointer_internal(component, cstream, tstamp, NULL); +} + +static int sof_compr_pointer64(struct snd_soc_component *component, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp) +{ + return sof_compr_pointer_internal(component, cstream, NULL, tstamp); +} + struct snd_compress_ops sof_compressed_ops =3D { .open =3D sof_compr_open, .free =3D sof_compr_free, .set_params =3D sof_compr_set_params, .get_params =3D sof_compr_get_params, .trigger =3D sof_compr_trigger, - .pointer =3D sof_compr_pointer, + .pointer =3D sof_compr_pointer32, + .pointer64 =3D sof_compr_pointer64, .copy =3D sof_compr_copy, }; EXPORT_SYMBOL(sof_compressed_ops); diff --git a/sound/soc/sprd/sprd-pcm-compress.c b/sound/soc/sprd/sprd-pcm-c= ompress.c index 57bd1a0728ac..3dea3b00af77 100644 --- a/sound/soc/sprd/sprd-pcm-compress.c +++ b/sound/soc/sprd/sprd-pcm-compress.c @@ -85,9 +85,9 @@ struct sprd_compr_stream { int info_size; =20 /* Data size copied to IRAM buffer */ - int copied_total; + u64 copied_total; /* Total received data size from userspace */ - int received_total; + u64 received_total; /* Stage 0 IRAM buffer received data size */ int received_stage0; /* Stage 1 DDR buffer received data size */ @@ -511,9 +511,24 @@ static int sprd_platform_compr_trigger(struct snd_soc_= component *component, return ret; } =20 -static int sprd_platform_compr_pointer(struct snd_soc_component *component, - struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) +static int sprd_platform_compr_pointer32(struct snd_soc_component *compone= nt, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp) +{ + struct snd_compr_runtime *runtime =3D cstream->runtime; + struct sprd_compr_stream *stream =3D runtime->private_data; + struct sprd_compr_playinfo *info =3D + (struct sprd_compr_playinfo *)stream->info_area; + + tstamp->copied_total =3D (u32)stream->copied_total; + tstamp->pcm_io_frames =3D (u32)info->current_data_offset; + + return 0; +} + +static int sprd_platform_compr_pointer64(struct snd_soc_component *compone= nt, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp) { struct snd_compr_runtime *runtime =3D cstream->runtime; struct sprd_compr_stream *stream =3D runtime->private_data; @@ -660,7 +675,8 @@ const struct snd_compress_ops sprd_platform_compress_op= s =3D { .free =3D sprd_platform_compr_free, .set_params =3D sprd_platform_compr_set_params, .trigger =3D sprd_platform_compr_trigger, - .pointer =3D sprd_platform_compr_pointer, + .pointer =3D sprd_platform_compr_pointer32, + .pointer64 =3D sprd_platform_compr_pointer64, .copy =3D sprd_platform_compr_copy, .get_caps =3D sprd_platform_compr_get_caps, .get_codec_caps =3D sprd_platform_compr_get_codec_caps, diff --git a/sound/soc/sprd/sprd-pcm-dma.h b/sound/soc/sprd/sprd-pcm-dma.h index be5e385f5e42..31866a5df84b 100644 --- a/sound/soc/sprd/sprd-pcm-dma.h +++ b/sound/soc/sprd/sprd-pcm-dma.h @@ -46,7 +46,7 @@ struct sprd_compr_ops { int (*stop)(int str_id); int (*pause)(int str_id); int (*pause_release)(int str_id); - int (*drain)(int received_total); + int (*drain)(u64 received_total); int (*set_params)(int str_id, struct sprd_compr_params *params); }; =20 diff --git a/sound/soc/uniphier/aio-compress.c b/sound/soc/uniphier/aio-com= press.c index 4a19d4908ffd..d450f5432d02 100644 --- a/sound/soc/uniphier/aio-compress.c +++ b/sound/soc/uniphier/aio-compress.c @@ -247,9 +247,9 @@ static int uniphier_aio_compr_trigger(struct snd_soc_co= mponent *component, return ret; } =20 -static int uniphier_aio_compr_pointer(struct snd_soc_component *component, - struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) +static int uniphier_aio_compr_pointer_internal( + struct snd_soc_component *component, struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp32, struct snd_compr_tstamp64 *tstamp64) { struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; struct snd_compr_runtime *runtime =3D cstream->runtime; @@ -258,6 +258,7 @@ static int uniphier_aio_compr_pointer(struct snd_soc_co= mponent *component, int bytes =3D runtime->fragment_size; unsigned long flags; u32 pos; + u64 copied_total; =20 spin_lock_irqsave(&sub->lock, flags); =20 @@ -266,18 +267,42 @@ static int uniphier_aio_compr_pointer(struct snd_soc_= component *component, if (sub->swm->dir =3D=3D PORT_DIR_OUTPUT) { pos =3D sub->rd_offs; /* Size of AIO output format is double of IEC61937 */ - tstamp->copied_total =3D sub->rd_total / 2; + copied_total =3D sub->rd_total / 2; } else { pos =3D sub->wr_offs; - tstamp->copied_total =3D sub->rd_total; + copied_total =3D sub->rd_total; + } + + if (tstamp32) { + tstamp32->copied_total =3D (u32)copied_total; + tstamp32->byte_offset =3D pos; + } + if (tstamp64) { + tstamp64->copied_total =3D copied_total; + tstamp64->byte_offset =3D pos; } - tstamp->byte_offset =3D pos; =20 spin_unlock_irqrestore(&sub->lock, flags); =20 return 0; } =20 +static int uniphier_aio_compr_pointer32(struct snd_soc_component *componen= t, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp) +{ + return uniphier_aio_compr_pointer_internal(component, cstream, tstamp, + NULL); +} + +static int uniphier_aio_compr_pointer64(struct snd_soc_component *componen= t, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp64 *tstamp) +{ + return uniphier_aio_compr_pointer_internal(component, cstream, NULL, + tstamp); +} + static int aio_compr_send_to_hw(struct uniphier_aio_sub *sub, char __user *buf, size_t dstsize) { @@ -426,7 +451,8 @@ const struct snd_compress_ops uniphier_aio_compress_ops= =3D { .get_params =3D uniphier_aio_compr_get_params, .set_params =3D uniphier_aio_compr_set_params, .trigger =3D uniphier_aio_compr_trigger, - .pointer =3D uniphier_aio_compr_pointer, + .pointer =3D uniphier_aio_compr_pointer32, + .pointer64 =3D uniphier_aio_compr_pointer64, .copy =3D uniphier_aio_compr_copy, .get_caps =3D uniphier_aio_compr_get_caps, .get_codec_caps =3D uniphier_aio_compr_get_codec_caps, --=20 2.50.0.727.gbf7dc18ff4-goog