From nobody Tue Oct 7 08:29:27 2025 Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.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 770B2279DB8 for ; Fri, 11 Jul 2025 09:37:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226636; cv=none; b=Oa+52vUXTWSU/l5+ep0Hi017A0kCe3IWZupaZ2HFd0lmKmOyi7mFuokzu4TxZSmf6aDAFKb7NVj+UhVGlyz5ftYHhBOxFAkqJWNcnoz5UAM9pjQEfMX1t6GTxE2lWnuKaQxfJa+WLDh2MzckJ0Tcef+TBDnCRyrj181FUxSHuC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226636; c=relaxed/simple; bh=BF4pLdBjpwXhp9214H0A3l/lQbnRhG7cLFEFj657yF8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PDtIKB+3KGziR+i+aQvZQV2udXZE5YF9VUHL+Y19eadS7Qmc9oObAdSUh7iVsBadagjjh/qKKmCnaSW/N7EvbaQRCP8LXnPC6anBfbV1KirebsvkWKHdAwM/6Fax8Ct4GzqN8NH566YfsYJzd38GeJgA9lTlHTKWeEBHTCaZGJ8= 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=ebuAlyLv; arc=none smtp.client-ip=209.85.218.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="ebuAlyLv" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-ae6d4c5f798so129196966b.0 for ; Fri, 11 Jul 2025 02:37:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752226633; x=1752831433; 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=wBhpozoKO994tZaJby3EUAdOYCx2fn320yq/NpQfjfg=; b=ebuAlyLvQ9/mByoP9sjoRlXpDJoFV4kSmZV/3z9BXaA0j4eiL5jRndcJus51Mtt4hu OvxFtceeJvwgvPIb8demYbc5kK7uupB5c5JrEww8joWjvNxFsVr/RXwMa6kfz9B+viNh URq6/X47FXCZEtOCROfAUMsLFyS/gIvMr2x1BVUkIXnni/M06+euaMyRzGbXvc1/DgrG 2fG847ARPT7gwqquCI/xVoh2IguMePkm/pZgPmHDVzfxRJBNUOCcipX5ZW+2zm12sMBQ 67v0KiBad+l0eZiTJwHK5zly6zC6YazNJAHY67MLqVrMzaNdutuqKosz1L/Esxbnmx+L DJOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752226633; x=1752831433; 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=wBhpozoKO994tZaJby3EUAdOYCx2fn320yq/NpQfjfg=; b=VBTHM0vOr53G2WWDIuMbXi3+PfJRGRl6/rJ8H9mz47lXIIqcmvGU7wQPiEhpoqYOYI kEDdXZ1rHmzTZHB2XretoExkH1bPyJduHcqGlF9Av4V1QRfd9cl6xNuWTIzL7khu5cGj 1SNoqZ/HdlwBQTowACi0zSHwL20OjdXAe6o8oen6FbLmNFoTgQwqv80PmWejq5L9NA5Q Y4ttufw79OLBaXbR15wiKr0nwCXP/OLBSOHv35+dWjUMqbYooY7OUfvaB7epReRv46ck umXesMKr4TLEINpb3xUsu+TC4hcIn6s+u7T6tgH11Q4ZuNzbQDH6iuJ/g4GdwC1gxWXP fvxg== X-Forwarded-Encrypted: i=1; AJvYcCVlugvwPVjqzKcrPg43vetJ7cNVXkqfKcFuRS/FDkghxUSkd3E9oLinlweobgLYG3CbFSFsfh4AZnCUUMk=@vger.kernel.org X-Gm-Message-State: AOJu0YyD6cx6W2/giU7Egx8W23RlFXy5pr+hY3RUCe8rVzq7e+8RD/mx uUGvwPLCS/riaJS6byjPLFQhZ2ONL17y74bGNuwu/sEMVUtn9xpKqkOeclODcVl82sJ0JNiwi2b QbqUI5FpZ1XTXZVfoLQ== X-Google-Smtp-Source: AGHT+IGIdc1uDMfWkRcYXH2QBFFa8MaZ4zaOUnOEybovNZBaLXnRsrqkGYBocqlyoisFxGvLN/JgmGhrEpyjbXY= X-Received: from ejaw15.prod.google.com ([2002:a17:906:33cf:b0:ae4:a43:f265]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:970f:b0:ae0:da2d:44b9 with SMTP id a640c23a62f3a-ae6fbc2654fmr271916766b.7.1752226632845; Fri, 11 Jul 2025 02:37:12 -0700 (PDT) Date: Fri, 11 Jul 2025 10:36:27 +0100 In-Reply-To: <20250711093636.28204-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: <20250711093636.28204-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711093636.28204-2-verhaegen@google.com> Subject: [PATCH v2 1/4] ALSA: compress_offload: Add 64-bit safe timestamp infrastructure From: Joris 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" 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:29:27 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.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 2695C27BF7C for ; Fri, 11 Jul 2025 09:37:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226643; cv=none; b=I78CaDUm2tcum33scfCDKSYP/SRUtXMqEQofstLEx5ZKh9B/vUs/V8VfFyK53k5RcVMAl1OGNAihVc3Uro7ChS90AeoDNpCsE073JkXDAj2mW/RhubBSNSf9jL+sWXZkFN2idxfXP3cYqENsjsojrVs6O2qzxgmkBk0VbIvhmQM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226643; c=relaxed/simple; bh=atnTHiewC1xCmy/qyvfr5dfWTSiO6aJ9sJe0l5ek+ro=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=FSBDZRsMqQ+z0/LHOX1VpeFp4gfOOEhatdsIGFLfpPsI2BpDxjhpyr5aQ0NXaM8Jr21QowRbIloyV1jcqWZr/qJurPWCD3fLjbPLJFMuMoLMBlW4HHnV70YS4O/yzJHzDl/84xbUzvys1QOUYfaLWzihZdjCXTzfJVhACL+2U9A= 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=kc9uqdnH; arc=none smtp.client-ip=209.85.128.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="kc9uqdnH" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-451ac1b43c4so10541005e9.0 for ; Fri, 11 Jul 2025 02:37:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752226640; x=1752831440; 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=MyMo9zKfU1sUBA0BOjzI2p8EGc7Cd9FXwBdhaBOmmwY=; b=kc9uqdnHdA2TWjwCvrJI/3gHSyLP2JqdO01j7n8tfiB1eFe85bXsXvCTxHOH5/jAgg pFTgsOgL9cZeDW58YMy0kBPzowK/T6QDd1dmLKhNW6a/aGAnx0+ougUstogenbPh3yth whOvzwkx5KZJFq+pyb2jnAeePxLAMF4cgD0ND1W55QxwxL9u1oWD5LcqzDouPH2xDem0 mw29uZUpB1JzRp4fvj1dRhNwC9vTDgqmNOU1e03M8hFss3BGWd+6NfSM5wo/vsJvOL1g 07yLU72l0uHN6EOiX1Ws27EUM6lReGLK75cRsLFKmuEQQpVnKQxLeZazGCJqAgY+n7TA Ss9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752226640; x=1752831440; 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=MyMo9zKfU1sUBA0BOjzI2p8EGc7Cd9FXwBdhaBOmmwY=; b=CaHlw+/0RJYCaXkT4oFTi8mlHaiE9VB/23UcphN/RnVYQnLlnznDsTXT68WkqwA8CR O77JArDFVIDxhma/ivj6QBQ/6hxsBiiCQxqrxZHCAD6bjRdh/cTOcYM8282nEEJsN9fX ct6KGH7YWLulyDZeUGlwkkFkyK2C23LCaLYEEXAWFWR+FB+FcfQqtSgbn3fEIQjOmAld DPn9LmNsk0CIq1DVv0nlGbEjSvrX2hdfN3WEWgRkUbwcMvIrqEkPYFOYtKY+DL5Zq0gA K9SrzYNAxTjFWLbf6UAHr5ym4vCVjQjE3gYX+ePqdnuVlxc8r2uRvMhN2OncFKj32yew Cj/Q== X-Forwarded-Encrypted: i=1; AJvYcCXFOl+u0q2fbJRg9rO/+S1etp5QR8gl4NYt0u1fKPP1IC+Tud55vZgCkrth/h5wkOge07NHGa5nic6Liq0=@vger.kernel.org X-Gm-Message-State: AOJu0YzNyeYodic3IYMtiPiOPKMqJrc1gGpcWslJCF0Rn6i3JbJ4Q6RQ V1Hzoa4gk4AyVako+hFm09yawl7B/AqaqLX7PZ4mzdW01qbN1Xc+XpBJttF+p2sOo7HjJxPH9yu nyn0lGRpFJyWS1ePU8w== X-Google-Smtp-Source: AGHT+IGkFa1awjG9LOYkbAB1rrv/t1xS4FURqpEoi3ZhrWLDYJ7bMjZ3iWrbqN63RoLLbaFSUEG6qVEShxpv5T8= X-Received: from wmth6.prod.google.com ([2002:a05:600c:8b66:b0:442:f4a3:b8f5]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:6305:b0:450:cfcb:5c9b with SMTP id 5b1f17b1804b1-454ec15a964mr20354655e9.1.1752226640523; Fri, 11 Jul 2025 02:37:20 -0700 (PDT) Date: Fri, 11 Jul 2025 10:36:28 +0100 In-Reply-To: <20250711093636.28204-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: <20250711093636.28204-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711093636.28204-3-verhaegen@google.com> Subject: [PATCH v2 2/4] ALSA: compress_offload: Add SNDRV_COMPRESS_TSTAMP64 ioctl From: Joris 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" 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:29:27 2025 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.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 11DB927CCEB for ; Fri, 11 Jul 2025 09:37:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226651; cv=none; b=jnkOtNCFmTp0PedyhL+RBii07KBrzTJePAhc1U6YNmXR3vbY+tsDztdtfNyCxWvs2+5fXI1H0iuHyIsQURAP/Bt+VMtptTHkSnz0ayP+W3BVSxO14co02DRudzfGEU9VgFao84fOj8jJiAQHr0h3f4wxo8bQ7En9sTaReoqBM3s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226651; c=relaxed/simple; bh=M1dujzqlrViBX5eAVMXNVdNoKPO5BUR0diMllLgPzjc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JsnBFjaQZpqv9RXZm+1xIGaqSAOwfOWFkCAGdHlxbw7pLSSJyzdTkdB+6lye3CTZ5cqfi4fiu1t/UiUPjlqZzTxV9Ob8qDFpZI3TFRlkqtYZdStiQ9KkY+ckT/0TLgEAxbdXRPn8Bm4q3g0xPXflol0hyn7WdH4YfupnI1zw6pw= 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=ncTRiXyH; arc=none smtp.client-ip=209.85.221.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="ncTRiXyH" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3a4eb6fcd88so1336237f8f.1 for ; Fri, 11 Jul 2025 02:37:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752226648; x=1752831448; 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=WywIvLAv4IB9b6g8T96e6Qsk8BIfajnf2gbyC1P4AZo=; b=ncTRiXyH73I23H8AxSM5gLuUsBLk5YgNBE9QIYBtHQOjs5Dbt5ya03CH/Pucbmcy2+ uTWjNXMTQFwUfkpI7wgUcLm0BUfhTpAHEpFH3ANNky4KbfTgs/P2Tkj1SLeiYRYX9/tM LgSU5fHoZwLaz6Vkk1foZ7Cbdh6iz5mPNeQLSHqCMFf5vX6RMuzMY1vtn1k1c5Yl1UBA Ith/8IS1KKCPjApt0t+7rifg0YoSbRa3NXQIA3YtTgcfaKpoRnNHkzGXjW97mfRGSLf8 KkQCfymQUhsaTAmbFFY0KUwKPDQWej8c8QCKCSIBm9N7ssdmtkBfqLtV7kVmQqP90seL MWTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752226648; x=1752831448; 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=WywIvLAv4IB9b6g8T96e6Qsk8BIfajnf2gbyC1P4AZo=; b=UNndNYujYjoqFd5Bwee5G99T2g8c1QqxZ9rmaXW/wOUXpUPzdFToohEybACbCNq3o1 wRvvQtPxVZIwFDk2rUQORQwslxGsZh5/l9qux5j3dmELymvSfzdRD+WbX/JHPMpznHlQ a0vINRIUqGjXYxymho3HexWiG9DO0KNwm8+kXuCeBSantJKGfscweuXekOXmUk771XZ+ XfA8PX1z5GR2xgCLzUSe3dlrhfcvaIdFZo+4J1AIIobgg5KrzsEzsDxItQq1lOhv3zwS k0ADWGjwdvXFB9+AofRzmRu6mXtEw6BBqErC6aMAKoihZWRMjD/UZnEOcpf5xhgnS/5w BNPQ== X-Forwarded-Encrypted: i=1; AJvYcCUM4tsfzo8LBn9M4H1lQpL4qa9uuRYtkehDNMfBbSOMnmbcCYagfnjI78aD7/73+QIEaJxbtHpL78+WuMg=@vger.kernel.org X-Gm-Message-State: AOJu0YxVIbvdjM0XQy9zAtyNronsd7I1zmq9pHSsf3QuhlVXzjt85jBT E+d6AZ2P7nuhmb8IX+YmnsFxKYs3h+G2tQEgBaFCsX2NkcIbP2L611J3WJRjLpDpnUlCnkFXFAD QMqW9QZhi6LhuTha+Ag== X-Google-Smtp-Source: AGHT+IEmEE9dNv4iiepa6OEju/MJzJFG2hiRPgxw7iu3SiyhF7OruOUvPAPmCsUrMtbUZ8nFQRE0HzcU37l0TXw= X-Received: from wmbea14.prod.google.com ([2002:a05:600c:674e:b0:43d:9035:df36]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:18a3:b0:3a8:6262:6ef5 with SMTP id ffacd0b85a97d-3b5f2db15bemr1466223f8f.10.1752226648115; Fri, 11 Jul 2025 02:37:28 -0700 (PDT) Date: Fri, 11 Jul 2025 10:36:29 +0100 In-Reply-To: <20250711093636.28204-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: <20250711093636.28204-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711093636.28204-4-verhaegen@google.com> Subject: [PATCH v2 3/4] ALSA: compress_offload: Add SNDRV_COMPRESS_AVAIL64 ioctl From: Joris 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" 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:29:27 2025 Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.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 B481D2309B5 for ; Fri, 11 Jul 2025 09:37:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226661; cv=none; b=FAvyNLFqyuJnOqpY6NkGJpPHNbMkynPySi6TYJ5wQRYfIiUIi4UTDVKJ91WRdv2NeriLa9ue6y3kYo+PVXB8wnAHiyuxdfavUbQkh20Q3YZ4vG+DccykvDbbicXLL7H4DGvAXK0+n8u9sryUpIjM+dRT8jqRuzn8MvrMHjDf4GQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752226661; c=relaxed/simple; bh=tmeaFPZiRFFkwMdVxW7c7jSqi1d+sDYCXhN2nCh2uZY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=l4PUdpwubvKMhRcdZiaRmN6fT+KdzfRn/Llsbxo4nUtVUDb8eMuwa65v6MQnwx+2g7La/in05oj9D4fX5yrR6w9iMcutxFqE8l7EsmxCGIpMPNfvVLMZ5XVV/4h/7Y/JK479xvkD4haV3Sc+ewRKFHTrvSYGBDTPnF0f65YgYMs= 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=qrBUEqhF; arc=none smtp.client-ip=209.85.218.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="qrBUEqhF" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-ae3c5ca46f2so155354366b.2 for ; Fri, 11 Jul 2025 02:37:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1752226656; x=1752831456; 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=s24zxkMRC1OeCsWQ5Jm+L322PE3ZBEn4WYJVkxJHa58=; b=qrBUEqhF4eMMy0ucZScLyGFxGLY79K7kwoXTlHl5aOcbqCL5DsjqvyZm8nxJ6x1z2Y 9u99Eda6Fjw2GmLOKwgxJjllCmqKod18SutedUJVYmBfPYJ9yXFzrPwP7mGIZrnBuG3L pSnHLq3xgIlo58ODp4Gp6E9RftFD8+lwInCh3hSLUndlFU5AWunoUG22Mhi/FnGRTTo2 g5e0z70ql7WNS0OZq1ACH5PP8VC3jzW0qZd2UvTYvWfKpBnWkA727XiJP+jgPuY9WrWh 6cquZItZ3iaAL2eIVYdS1VJEC6+3/ympJdThjh04a/yEAEzVmGZUyEO7eKL8mAvciD+w bAdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752226656; x=1752831456; 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=s24zxkMRC1OeCsWQ5Jm+L322PE3ZBEn4WYJVkxJHa58=; b=kNIj72yWWpeFnQ9/BIfrQm5RTPp8hpci+cIK9eo+2LCeSmKPxZrNzK7seJr9VcLQXi EfSgjJCsiyyoLVepOayAY7/hHghtkgxxv27aLMxAe9MbsheCfVHWkhsoig9xs011hQAC 52UCxvCrNWn19oklbmY/ZK/Jpe+aB0+uOW0k64kM6i9iKniULaH5+vV4wCqWYYE59rlK 3TTPrwC3/+Z3BzOjS8/KwraouYvknn69hjjAOiVQ59wg+d2gkaixMyH4HaRvut0g6ez5 fWvGU1SuQVphAZUWRQAFF9MFL1cR7P2iM9SEIOXrSSqAnQ0T+Rq68Tijm4CKMlM2/g5/ ReJw== X-Forwarded-Encrypted: i=1; AJvYcCXED5j4LG4mY1J8yJ2tvZ+7eg+MPPwrL61pjyG37SeFG0L9M+ltIP8IwXIUI7FnIOWlbvI1Zv1kVqJZ2v4=@vger.kernel.org X-Gm-Message-State: AOJu0YwpB4CgIfpWiEJRL2N8UD3p8Dr/ZlaEEXr0ZGMMcgS+QOyAr5j+ EdNgzamyTLgrN9Ff4ds7FuyovcvCmin2giOFyANBT5Ibqy6vhUk99G+Axyz1nnw0TYSVngKgVhg +3EX+tu4SS+tdpuUn9A== X-Google-Smtp-Source: AGHT+IEE+Iad30lp8vlVTMnoKWDJrzSh/Gl4mnzAn3kxLg1w2hmTp8NWUwAAAjRm4Pv+hBo2ock630z7qIlqeIc= X-Received: from edon10.prod.google.com ([2002:aa7:d04a:0:b0:5fc:3251:d24f]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a17:906:d7d4:b0:ad8:a512:a9fc with SMTP id a640c23a62f3a-ae6fc3662f6mr256255866b.42.1752226655971; Fri, 11 Jul 2025 02:37:35 -0700 (PDT) Date: Fri, 11 Jul 2025 10:36:30 +0100 In-Reply-To: <20250711093636.28204-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: <20250711093636.28204-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.0.727.gbf7dc18ff4-goog Message-ID: <20250711093636.28204-5-verhaegen@google.com> Subject: [PATCH v2 4/4] ASoC: codecs: Implement 64-bit pointer operation From: Joris 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" 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 Reviewed-by: Richard Fitzgerald --- 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