From patchwork Mon Jan 27 12:12:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193756 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4C68C2D0DB for ; Mon, 27 Jan 2020 12:14:59 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 42B97207FD for ; Mon, 27 Jan 2020 12:14:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="dHqKqdB2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 42B97207FD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 84970836; Mon, 27 Jan 2020 13:14:07 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 84970836 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580127297; bh=J9ap4Jcmx061nbXdTRhevrEx9f0ynKBj0KD6k9KEzPY=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=dHqKqdB2mYa2DJYt21AAfzdKoh5diENQK+fAKldQ12nqEGzxAB0QAjfqSodixMl8U b6Gpt0s11wVaBVjRp5GvP3GtGg7wG8kWEG9BNw2KugoKbrpOULHOKpljfITk2x0i4x Sm3MEP/DdRHpxqsicdIWxCddY3BVeCZDnqtUFzFQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 90CD4F80254; Mon, 27 Jan 2020 13:13:32 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 35C4CF80085; Mon, 27 Jan 2020 13:13:30 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 5C28FF80085 for ; Mon, 27 Jan 2020 13:13:24 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5C28FF80085 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2020 04:13:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,369,1574150400"; d="scan'208";a="261029611" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga002.fm.intel.com with ESMTP; 27 Jan 2020 04:13:21 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Mon, 27 Jan 2020 13:12:33 +0100 Message-Id: <20200127121243.15813-2-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200127121243.15813-1-cezary.rojewski@intel.com> References: <20200127121243.15813-1-cezary.rojewski@intel.com> Cc: lgirdwood@gmail.com, Cezary Rojewski , broonie@kernel.org, tiwai@suse.com, pierre-louis.bossart@linux.intel.com Subject: [alsa-devel] [PATCH v2 01/11] ALSA: hda: Allow for compress stream to hdac_ext_stream assignment X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Currently only PCM streams can enlist hdac_stream for their data transfer. Add cstream field to hdac_ext_stream to expose possibility of compress stream assignment in place of PCM one. Limited to HOST-type only. Rather than copying entire hdac_ext_host_stream_assign, declare separate PCM and compress wrappers and reuse it for both cases. Signed-off-by: Cezary Rojewski --- include/sound/hdaudio.h | 1 + include/sound/hdaudio_ext.h | 2 ++ sound/hda/ext/hdac_ext_stream.c | 49 +++++++++++++++++++++++++++++---- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index e05b95e83d5a..9a8bf1eb7d69 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -481,6 +481,7 @@ struct hdac_stream { struct snd_pcm_substream *substream; /* assigned substream, * set in PCM open */ + struct snd_compr_stream *cstream; unsigned int format_val; /* format value to be set in the * controller and the codec */ diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index ef88b20c7b0a..ec01f2024f0b 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -84,6 +84,8 @@ int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx, int num_stream, int dir); void snd_hdac_stream_free_all(struct hdac_bus *bus); void snd_hdac_link_free_all(struct hdac_bus *bus); +struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus, + struct snd_compr_stream *cstream); struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream, int type); diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index 6b1b4b834bae..488a52570062 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -14,6 +14,7 @@ #include #include #include +#include /** * snd_hdac_ext_stream_init - initialize each stream (aka device) @@ -281,8 +282,7 @@ hdac_ext_link_stream_assign(struct hdac_bus *bus, } static struct hdac_ext_stream * -hdac_ext_host_stream_assign(struct hdac_bus *bus, - struct snd_pcm_substream *substream) +hdac_ext_host_stream_assign(struct hdac_bus *bus, int direction) { struct hdac_ext_stream *res = NULL; struct hdac_stream *stream = NULL; @@ -296,12 +296,13 @@ hdac_ext_host_stream_assign(struct hdac_bus *bus, struct hdac_ext_stream *hstream = container_of(stream, struct hdac_ext_stream, hstream); - if (stream->direction != substream->stream) + if (stream->direction != direction) continue; if (!stream->opened) { if (!hstream->decoupled) - snd_hdac_ext_stream_decouple(bus, hstream, true); + snd_hdac_ext_stream_decouple(bus, + hstream, true); res = hstream; break; } @@ -310,13 +311,49 @@ hdac_ext_host_stream_assign(struct hdac_bus *bus, spin_lock_irq(&bus->reg_lock); res->hstream.opened = 1; res->hstream.running = 0; - res->hstream.substream = substream; + res->hstream.substream = NULL; + res->hstream.cstream = NULL; spin_unlock_irq(&bus->reg_lock); } return res; } +static struct hdac_ext_stream * +hdac_ext_host_stream_pcm_assign(struct hdac_bus *bus, + struct snd_pcm_substream *substream) +{ + struct hdac_ext_stream *res; + + res = hdac_ext_host_stream_assign(bus, substream->stream); + if (res) + res->hstream.substream = substream; + + return res; +} + +/** + * snd_hdac_ext_cstream_assign - assign a host stream for compress + * @bus: HD-audio core bus + * @cstream: Compress stream to assign + * + * Assign an unused host stream for the given compress stream. + * If no stream is free, NULL is returned. Stream is decoupled + * before assignment. + */ +struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus, + struct snd_compr_stream *cstream) +{ + struct hdac_ext_stream *res; + + res = hdac_ext_host_stream_assign(bus, cstream->direction); + if (res) + res->hstream.cstream = cstream; + + return res; +} +EXPORT_SYMBOL_GPL(snd_hdac_ext_cstream_assign); + /** * snd_hdac_ext_stream_assign - assign a stream for the PCM * @bus: HD-audio core bus @@ -350,7 +387,7 @@ struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus, return hstream; case HDAC_EXT_STREAM_TYPE_HOST: - return hdac_ext_host_stream_assign(bus, substream); + return hdac_ext_host_stream_pcm_assign(bus, substream); case HDAC_EXT_STREAM_TYPE_LINK: return hdac_ext_link_stream_assign(bus, substream); From patchwork Mon Jan 27 12:12:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193755 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B030C2D0DB for ; Mon, 27 Jan 2020 12:16:25 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0671E2067C for ; Mon, 27 Jan 2020 12:16:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="Sadw/j0i" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0671E2067C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 4B994836; Mon, 27 Jan 2020 13:15:33 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 4B994836 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580127383; bh=4x9IZMrCR1dEKdfykWIVAHC3X5WtgjthUXOiPUVquKs=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Sadw/j0iHGdDaKnDAhKLiehWHA7X3fHyynCPvKZxWXFXcIZiLjZCJH6LLCdal3Wmi 31iy9/DEEelnyln4Qp/NtFXtW3ZVBDPejSO+0dMLNDqDQ/W+xxP/2BN0cP4MpZUZSy nuOlfRylFB2sAzcHKulR4QOgAbvSayaiurYl0zvY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id BE54FF8027B; Mon, 27 Jan 2020 13:13:38 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id D9B7CF8023F; Mon, 27 Jan 2020 13:13:32 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 1FFF7F8023F for ; Mon, 27 Jan 2020 13:13:27 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 1FFF7F8023F X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2020 04:13:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,369,1574150400"; d="scan'208";a="261029631" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga002.fm.intel.com with ESMTP; 27 Jan 2020 04:13:24 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Mon, 27 Jan 2020 13:12:35 +0100 Message-Id: <20200127121243.15813-4-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200127121243.15813-1-cezary.rojewski@intel.com> References: <20200127121243.15813-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , Divya Prakash , lgirdwood@gmail.com, tiwai@suse.com, broonie@kernel.org Subject: [alsa-devel] [PATCH v2 03/11] ALSA: hda: Interrupt servicing and BDL setup for compress streams X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Account for compress streams when receiving and servicing buffer completed interrupts. In case of compress stream enlisting hdac_stream for data transfer, setup BDL entries much like it is the case for PCM streams. Signed-off-by: Cezary Rojewski Signed-off-by: Divya Prakash --- sound/hda/hdac_controller.c | 4 ++-- sound/hda/hdac_stream.c | 26 ++++++++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index 7e7be8e4dcf9..585908f58028 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c @@ -553,8 +553,8 @@ int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status, sd_status = snd_hdac_stream_readb(azx_dev, SD_STS); snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); handled |= 1 << azx_dev->index; - if (!azx_dev->substream || !azx_dev->running || - !(sd_status & SD_INT_COMPLETE)) + if ((!azx_dev->substream && !azx_dev->cstream) || + !azx_dev->running || !(sd_status & SD_INT_COMPLETE)) continue; if (ack) ack(bus, azx_dev); diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 5259cf366011..1858b96fdb69 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -408,14 +409,20 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) { struct hdac_bus *bus = azx_dev->bus; struct snd_pcm_substream *substream = azx_dev->substream; + struct snd_compr_stream *cstream = azx_dev->cstream; struct snd_pcm_runtime *runtime; struct snd_dma_buffer *dmab; __le32 *bdl; int i, ofs, periods, period_bytes; int pos_adj, pos_align; - runtime = substream->runtime; - dmab = snd_pcm_get_dma_buf(substream); + if (substream) { + runtime = substream->runtime; + dmab = snd_pcm_get_dma_buf(substream); + } else { + runtime = NULL; + dmab = snd_pcm_get_dma_buf(cstream); + } /* reset BDL address */ snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0); @@ -484,15 +491,22 @@ int snd_hdac_stream_set_params(struct hdac_stream *azx_dev, unsigned int format_val) { struct snd_pcm_substream *substream = azx_dev->substream; + struct snd_compr_stream *cstream = azx_dev->cstream; unsigned int bufsize, period_bytes; unsigned int no_period_wakeup; int err; - if (!substream) + if (substream) { + bufsize = snd_pcm_lib_buffer_bytes(substream); + period_bytes = snd_pcm_lib_period_bytes(substream); + no_period_wakeup = substream->runtime->no_period_wakeup; + } else if (cstream) { + bufsize = cstream->runtime->buffer_size; + period_bytes = cstream->runtime->fragment_size; + no_period_wakeup = 0; + } else { return -EINVAL; - bufsize = snd_pcm_lib_buffer_bytes(substream); - period_bytes = snd_pcm_lib_period_bytes(substream); - no_period_wakeup = substream->runtime->no_period_wakeup; + } if (bufsize != azx_dev->bufsize || period_bytes != azx_dev->period_bytes || From patchwork Mon Jan 27 12:12:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193754 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98849C2D0DB for ; Mon, 27 Jan 2020 12:17:25 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 245FE2067C for ; Mon, 27 Jan 2020 12:17:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="SZIkE1gv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 245FE2067C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 811821612; Mon, 27 Jan 2020 13:16:33 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 811821612 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580127443; bh=KM7+a0G9ASW1enpJmogmnBtFW8hiYVmO+FKaEZMIYYI=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=SZIkE1gvcpPHPikD/XPCgHIyqGeqUtdZu/EOdeL9bZGyhg6yXEsLjaKbWQsTQGabs S2PWgiYtndKWHSOG1PqyXQ441xv8COWGyXgV5yE8ePOeaaS2Ezdi6FdBv/KL5Q2npL UNvx79rp+uxQvMUqkI54Tl/2a01CrNkVwbcuBbO4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 07D00F8028F; Mon, 27 Jan 2020 13:13:44 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4316CF80276; Mon, 27 Jan 2020 13:13:36 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id A14B4F80085 for ; Mon, 27 Jan 2020 13:13:30 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz A14B4F80085 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2020 04:13:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,369,1574150400"; d="scan'208";a="261029652" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga002.fm.intel.com with ESMTP; 27 Jan 2020 04:13:28 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Mon, 27 Jan 2020 13:12:37 +0100 Message-Id: <20200127121243.15813-6-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200127121243.15813-1-cezary.rojewski@intel.com> References: <20200127121243.15813-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , Divya Prakash , lgirdwood@gmail.com, tiwai@suse.com, broonie@kernel.org Subject: [alsa-devel] [PATCH v2 05/11] ALSA: core: Implement compress page allocation and free routines X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Add simple malloc and free methods for memory management for compress streams. Based on snd_pcm_lib_malloc_pages and snd_pcm_lib_free_pages implementation. Signed-off-by: Cezary Rojewski Signed-off-by: Divya Prakash --- include/sound/compress_driver.h | 5 ++++ sound/core/compress_offload.c | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index 00f633c0c3ba..6ce8effa0b12 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h @@ -67,6 +67,7 @@ struct snd_compr_runtime { * @metadata_set: metadata set flag, true when set * @next_track: has userspace signal next track transition, true when set * @private_data: pointer to DSP private data + * @dma_buffer: allocated buffer if any */ struct snd_compr_stream { const char *name; @@ -78,6 +79,7 @@ struct snd_compr_stream { bool metadata_set; bool next_track; void *private_data; + struct snd_dma_buffer dma_buffer; }; /** @@ -212,6 +214,9 @@ snd_compr_set_runtime_buffer(struct snd_compr_stream *stream, } } +int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size); +int snd_compr_free_pages(struct snd_compr_stream *stream); + int snd_compr_stop_error(struct snd_compr_stream *stream, snd_pcm_state_t state); diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index f34ce564d92c..638c9314284f 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -488,6 +488,48 @@ snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) } #endif /* !COMPR_CODEC_CAPS_OVERFLOW */ +int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size) +{ + struct snd_dma_buffer *dmab; + int ret; + + if (snd_BUG_ON(!(stream) || !(stream)->runtime)) + return -EINVAL; + dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); + if (!dmab) + return -ENOMEM; + dmab->dev = stream->dma_buffer.dev; + ret = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab); + if (ret < 0) { + kfree(dmab); + return ret; + } + + snd_compr_set_runtime_buffer(stream, dmab); + stream->runtime->dma_bytes = size; + return 1; +} +EXPORT_SYMBOL(snd_compr_malloc_pages); + +int snd_compr_free_pages(struct snd_compr_stream *stream) +{ + struct snd_compr_runtime *runtime = stream->runtime; + + if (snd_BUG_ON(!(stream) || !(stream)->runtime)) + return -EINVAL; + if (runtime->dma_area == NULL) + return 0; + if (runtime->dma_buffer_p != &stream->dma_buffer) { + /* It's a newly allocated buffer. Release it now. */ + snd_dma_free_pages(runtime->dma_buffer_p); + kfree(runtime->dma_buffer_p); + } + + snd_compr_set_runtime_buffer(stream, NULL); + return 0; +} +EXPORT_SYMBOL(snd_compr_free_pages); + /* revisit this with snd_pcm_preallocate_xxx */ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream, struct snd_compr_params *params) From patchwork Mon Jan 27 12:12:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193753 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E71DBC2D0DB for ; Mon, 27 Jan 2020 12:18:28 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 748312087F for ; Mon, 27 Jan 2020 12:18:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="AnBAVrys" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 748312087F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D5DF71612; Mon, 27 Jan 2020 13:17:36 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D5DF71612 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580127506; bh=OmJB24k3HXegc1IeFh9bz1B5fmkL/wrmkRMqHm1H2fM=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=AnBAVrys3+inhLeaSpdpBMKFuLm9IyzOoZ7n0TirI+STKgu+2GxHYq+CTV7yhGIyZ 2HizNAxPSTqfiyrfsWMNxXV+JHcKdTTuZXyFExA0gs7mRYWMEnopFAL7jKjZnKfkW/ Fc2qwP2W9aZMGUr/xophfTURoIeUuFpF+r9/XbVM= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 45A4BF802A7; Mon, 27 Jan 2020 13:13:50 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id DD8ADF80290; Mon, 27 Jan 2020 13:13:42 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 62EDBF80268 for ; Mon, 27 Jan 2020 13:13:33 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 62EDBF80268 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2020 04:13:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,369,1574150400"; d="scan'208";a="261029679" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga002.fm.intel.com with ESMTP; 27 Jan 2020 04:13:31 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Mon, 27 Jan 2020 13:12:39 +0100 Message-Id: <20200127121243.15813-8-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200127121243.15813-1-cezary.rojewski@intel.com> References: <20200127121243.15813-1-cezary.rojewski@intel.com> Cc: lgirdwood@gmail.com, Cezary Rojewski , broonie@kernel.org, tiwai@suse.com, pierre-louis.bossart@linux.intel.com Subject: [alsa-devel] [PATCH v2 07/11] ASoC: SOF: Implement Probe IPC API X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Add all required types and methods to support each and every request that driver could sent to firmware. Probe is one of SOF firmware features which allows for data extraction and injection directly from or to DMA stream. Exposes eight IPCs: - addition and removal of injection DMAs - addition and removal of probe points - info retrieval of injection DMAs and probe points - probe initialization and cleanup Signed-off-by: Cezary Rojewski --- Changes in v2: - probe IPC API has been updated to align with newest SOF FW & probe debug app (struct_size macro has been enlisted to make the size calculations transparent) include/sound/sof/header.h | 11 ++ sound/soc/sof/Makefile | 2 +- sound/soc/sof/intel/hda-ipc.c | 4 +- sound/soc/sof/probe.c | 285 ++++++++++++++++++++++++++++++++++ sound/soc/sof/probe.h | 85 ++++++++++ sound/soc/sof/sof-priv.h | 3 + 6 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 sound/soc/sof/probe.c create mode 100644 sound/soc/sof/probe.h diff --git a/include/sound/sof/header.h b/include/sound/sof/header.h index bf3edd9c08b4..b79479575cc8 100644 --- a/include/sound/sof/header.h +++ b/include/sound/sof/header.h @@ -51,6 +51,7 @@ #define SOF_IPC_GLB_TRACE_MSG SOF_GLB_TYPE(0x9U) #define SOF_IPC_GLB_GDB_DEBUG SOF_GLB_TYPE(0xAU) #define SOF_IPC_GLB_TEST_MSG SOF_GLB_TYPE(0xBU) +#define SOF_IPC_GLB_PROBE SOF_GLB_TYPE(0xCU) /* * DSP Command Message Types @@ -102,6 +103,16 @@ #define SOF_IPC_STREAM_VORBIS_PARAMS SOF_CMD_TYPE(0x010) #define SOF_IPC_STREAM_VORBIS_FREE SOF_CMD_TYPE(0x011) +/* probe */ +#define SOF_IPC_PROBE_INIT SOF_CMD_TYPE(0x001) +#define SOF_IPC_PROBE_DEINIT SOF_CMD_TYPE(0x002) +#define SOF_IPC_PROBE_DMA_ADD SOF_CMD_TYPE(0x003) +#define SOF_IPC_PROBE_DMA_INFO SOF_CMD_TYPE(0x004) +#define SOF_IPC_PROBE_DMA_REMOVE SOF_CMD_TYPE(0x005) +#define SOF_IPC_PROBE_POINT_ADD SOF_CMD_TYPE(0x006) +#define SOF_IPC_PROBE_POINT_INFO SOF_CMD_TYPE(0x007) +#define SOF_IPC_PROBE_POINT_REMOVE SOF_CMD_TYPE(0x008) + /* trace */ #define SOF_IPC_TRACE_DMA_PARAMS SOF_CMD_TYPE(0x001) #define SOF_IPC_TRACE_DMA_POSITION SOF_CMD_TYPE(0x002) diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 0a8bc72c28a5..99c26420d9e5 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ - control.o trace.o utils.o sof-audio.o + control.o probe.o trace.o utils.o sof-audio.o snd-sof-pci-objs := sof-pci-dev.o snd-sof-acpi-objs := sof-acpi-dev.o diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index 1837f66e361f..922052883b0a 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -106,7 +106,9 @@ void hda_dsp_ipc_get_reply(struct snd_sof_dev *sdev) ret = reply.error; } else { /* reply correct size ? */ - if (reply.hdr.size != msg->reply_size) { + if (reply.hdr.size != msg->reply_size && + /* getter payload is never known upfront */ + !(reply.hdr.cmd & SOF_IPC_GLB_PROBE)) { dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n", msg->reply_size, reply.hdr.size); ret = -EINVAL; diff --git a/sound/soc/sof/probe.c b/sound/soc/sof/probe.c new file mode 100644 index 000000000000..3b849becfe9c --- /dev/null +++ b/sound/soc/sof/probe.c @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2019-2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include "sof-priv.h" +#include "probe.h" + +/** + * sof_ipc_probe_init - initialize data probing + * @sdev: SOF sound device + * @buffer_size: DMA buffer size to set for extractor + * + * Host chooses whether extraction is supported or not by providing + * valid stream tag to DSP. Once specified, stream described by that + * tag will be tied to DSP for extraction for the entire lifetime of + * probe. + * + * Probing is initialized only once and each INIT request must be + * matched by DEINIT call. + */ +int sof_ipc_probe_init(struct snd_sof_dev *sdev, + u32 stream_tag, size_t buffer_size) +{ + struct sof_ipc_probe_dma_add_params *msg; + struct sof_ipc_reply reply; + size_t size = struct_size(msg, dma, 1); + int ret; + + msg = kmalloc(size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + msg->hdr.size = size; + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_INIT; + msg->num_elems = 1; + msg->dma[0].stream_tag = stream_tag; + msg->dma[0].dma_buffer_size = buffer_size; + + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, + &reply, sizeof(reply)); + kfree(msg); + return ret; +} +EXPORT_SYMBOL(sof_ipc_probe_init); + +/** + * sof_ipc_probe_deinit - cleanup after data probing + * @sdev: SOF sound device + * + * Host sends DEINIT request to free previously initialized probe + * on DSP side once it is no longer needed. DEINIT only when there + * are no probes connected and with all injectors detached. + */ +int sof_ipc_probe_deinit(struct snd_sof_dev *sdev) +{ + struct sof_ipc_cmd_hdr msg; + struct sof_ipc_reply reply; + + msg.size = sizeof(msg); + msg.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DEINIT; + + return sof_ipc_tx_message(sdev->ipc, msg.cmd, &msg, msg.size, + &reply, sizeof(reply)); +} +EXPORT_SYMBOL(sof_ipc_probe_deinit); + +static int sof_ipc_probe_info(struct snd_sof_dev *sdev, unsigned int cmd, + void **params, size_t *num_params) +{ + struct sof_ipc_probe_info_params msg = {0}; + struct sof_ipc_probe_info_params *reply; + size_t bytes; + int ret; + + *params = NULL; + *num_params = 0; + + reply = kzalloc(SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL); + if (!reply) + return -ENOMEM; + msg.rhdr.hdr.size = sizeof(msg); + msg.rhdr.hdr.cmd = SOF_IPC_GLB_PROBE | cmd; + + ret = sof_ipc_tx_message(sdev->ipc, msg.rhdr.hdr.cmd, &msg, + msg.rhdr.hdr.size, reply, SOF_IPC_MSG_MAX_SIZE); + if (ret < 0 || reply->rhdr.error < 0) + goto exit; + + if (!reply->num_elems) + goto exit; + + bytes = reply->num_elems * sizeof(reply->dma[0]); + *params = kmemdup(&reply->dma[0], bytes, GFP_KERNEL); + if (!*params) { + ret = -ENOMEM; + goto exit; + } + *num_params = msg.num_elems; + +exit: + kfree(reply); + return ret; +} + +/** + * sof_ipc_probe_dma_info - retrieve list of active injection dmas + * @sdev: SOF sound device + * @dma: Returned list of active dmas + * @num_dma: Returned count of active dmas + * + * Host sends DMA_INFO request to obtain list of injection dmas it + * can use to transfer data over with. + * + * Note that list contains only injection dmas as there is only one + * extractor (dma) and it is always assigned on probing init. + * DSP knows exactly where data from extraction probes is going to, + * which is not the case for injection where multiple streams + * could be engaged. + */ +int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev, + struct sof_probe_dma **dma, size_t *num_dma) +{ + return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_DMA_INFO, + (void **)dma, num_dma); +} +EXPORT_SYMBOL(sof_ipc_probe_dma_info); + +/** + * sof_ipc_probe_dma_add - attach to specified dmas + * @sdev: SOF sound device + * @dma: List of streams (dmas) to attach to + * @num_dma: Number of elements in @dma + * + * Contrary to extraction, injection streams are never assigned + * on init. Before attempting any data injection, host is responsible + * for specifying streams which will be later used to transfer data + * to connected probe points. + */ +int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev, + struct sof_probe_dma *dma, size_t num_dma) +{ + struct sof_ipc_probe_dma_add_params *msg; + struct sof_ipc_reply reply; + size_t size = struct_size(msg, dma, num_dma); + int ret; + + msg = kmalloc(size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + msg->hdr.size = size; + msg->num_elems = num_dma; + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_ADD; + memcpy(&msg->dma[0], dma, size - sizeof(*msg)); + + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, + &reply, sizeof(reply)); + kfree(msg); + return ret; +} +EXPORT_SYMBOL(sof_ipc_probe_dma_add); + +/** + * sof_ipc_probe_dma_remove - detach from specified dmas + * @sdev: SOF sound device + * @stream_tag: List of stream tags to detach from + * @num_stream_tag: Number of elements in @stream_tag + * + * Host sends DMA_REMOVE request to free previously attached stream + * from being occupied for injection. Each detach operation should + * match equivalent DMA_ADD. Detach only when all probes tied to + * given stream have been disconnected. + */ +int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev, + unsigned int *stream_tag, size_t num_stream_tag) +{ + struct sof_ipc_probe_dma_remove_params *msg; + struct sof_ipc_reply reply; + size_t size = struct_size(msg, stream_tag, num_stream_tag); + int ret; + + msg = kmalloc(size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + msg->hdr.size = size; + msg->num_elems = num_stream_tag; + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_REMOVE; + memcpy(&msg->stream_tag[0], stream_tag, size - sizeof(*msg)); + + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, + &reply, sizeof(reply)); + kfree(msg); + return ret; +} +EXPORT_SYMBOL(sof_ipc_probe_dma_remove); + +/** + * sof_ipc_probe_points_info - retrieve list of active probe points + * @sdev: SOF sound device + * @desc: Returned list of active probes + * @num_desc: Returned count of active probes + * + * Host sends PROBE_POINT_INFO request to obtain list of active probe + * points, valid for disconnection when given probe is no longer + * required. + */ +int sof_ipc_probe_points_info(struct snd_sof_dev *sdev, + struct sof_probe_point_desc **desc, size_t *num_desc) +{ + return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_POINT_INFO, + (void **)desc, num_desc); +} +EXPORT_SYMBOL(sof_ipc_probe_points_info); + +/** + * sof_ipc_probe_points_add - connect specified probes + * @sdev: SOF sound device + * @desc: List of probe points to connect + * @num_desc: Number of elements in @desc + * + * Dynamically connects to provided set of endpoints. Immediately + * after connection is established, host must be prepared to + * transfer data from or to target stream given the probing purpose. + * + * Each probe point should be removed using PROBE_POINT_REMOVE + * request when no longer needed. + */ +int sof_ipc_probe_points_add(struct snd_sof_dev *sdev, + struct sof_probe_point_desc *desc, size_t num_desc) +{ + struct sof_ipc_probe_point_add_params *msg; + struct sof_ipc_reply reply; + size_t size = struct_size(msg, desc, num_desc); + int ret; + + msg = kmalloc(size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + msg->hdr.size = size; + msg->num_elems = num_desc; + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_POINT_ADD; + memcpy(&msg->desc[0], desc, size - sizeof(*msg)); + + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, + &reply, sizeof(reply)); + kfree(msg); + return ret; +} +EXPORT_SYMBOL(sof_ipc_probe_points_add); + +/** + * sof_ipc_probe_points_remove - disconnect specified probes + * @sdev: SOF sound device + * @desc: List of probe points to disconnect + * @num_desc: Number of elements in @desc + * + * Removes previously connected probes from list of active probe + * points and frees all resources on DSP side. + */ +int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, + unsigned int *buffer_id, size_t num_buffer_id) +{ + struct sof_ipc_probe_point_remove_params *msg; + struct sof_ipc_reply reply; + size_t size = struct_size(msg, buffer_id, num_buffer_id); + int ret; + + msg = kmalloc(size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + msg->hdr.size = size; + msg->num_elems = num_buffer_id; + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_POINT_REMOVE; + memcpy(&msg->buffer_id[0], buffer_id, size - sizeof(*msg)); + + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, + &reply, sizeof(reply)); + kfree(msg); + return ret; +} +EXPORT_SYMBOL(sof_ipc_probe_points_remove); diff --git a/sound/soc/sof/probe.h b/sound/soc/sof/probe.h new file mode 100644 index 000000000000..281a786519b2 --- /dev/null +++ b/sound/soc/sof/probe.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2019-2020 Intel Corporation. All rights reserved. + * + * Author: Cezary Rojewski + */ + +#ifndef __SOF_PROBE_H +#define __SOF_PROBE_H + +#include + +struct snd_sof_dev; + +#define SOF_PROBE_INVALID_NODE_ID UINT_MAX + +struct sof_probe_dma { + unsigned int stream_tag; + unsigned int dma_buffer_size; +} __packed; + +enum sof_connection_purpose { + SOF_CONNECTION_PURPOSE_EXTRACT = 1, + SOF_CONNECTION_PURPOSE_INJECT, +}; + +struct sof_probe_point_desc { + unsigned int buffer_id; + unsigned int purpose; + unsigned int stream_tag; +} __packed; + +struct sof_ipc_probe_dma_add_params { + struct sof_ipc_cmd_hdr hdr; + unsigned int num_elems; + struct sof_probe_dma dma[0]; +} __packed; + +struct sof_ipc_probe_info_params { + struct sof_ipc_reply rhdr; + unsigned int num_elems; + union { + struct sof_probe_dma dma[0]; + struct sof_probe_point_desc desc[0]; + }; +} __packed; + +struct sof_ipc_probe_dma_remove_params { + struct sof_ipc_cmd_hdr hdr; + unsigned int num_elems; + unsigned int stream_tag[0]; +} __packed; + +struct sof_ipc_probe_point_add_params { + struct sof_ipc_cmd_hdr hdr; + unsigned int num_elems; + struct sof_probe_point_desc desc[0]; +} __packed; + +struct sof_ipc_probe_point_remove_params { + struct sof_ipc_cmd_hdr hdr; + unsigned int num_elems; + unsigned int buffer_id[0]; +} __packed; + +int sof_ipc_probe_init(struct snd_sof_dev *sdev, + u32 stream_tag, size_t buffer_size); +int sof_ipc_probe_deinit(struct snd_sof_dev *sdev); +int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev, + struct sof_probe_dma **dma, size_t *num_dma); +int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev, + struct sof_probe_dma *dma, size_t num_dma); +int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev, + unsigned int *stream_tag, size_t num_stream_tag); +int sof_ipc_probe_points_info(struct snd_sof_dev *sdev, + struct sof_probe_point_desc **desc, size_t *num_desc); +int sof_ipc_probe_points_add(struct snd_sof_dev *sdev, + struct sof_probe_point_desc *desc, size_t num_desc); +int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, + unsigned int *buffer_id, size_t num_id); + +#endif diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index bc2337cf1142..9fa6fb6c7b93 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -387,6 +387,9 @@ struct snd_sof_dev { wait_queue_head_t waitq; int code_loading; + /* probes */ + unsigned int extractor; + /* DMA for Trace */ struct snd_dma_buffer dmatb; struct snd_dma_buffer dmatp; From patchwork Mon Jan 27 12:12:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193752 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72502C2D0DB for ; Mon, 27 Jan 2020 12:19:58 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F29F22067C for ; Mon, 27 Jan 2020 12:19:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="ESRrmLiA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F29F22067C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 640A11677; Mon, 27 Jan 2020 13:19:06 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 640A11677 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580127596; bh=R0gxYwXup/jFoQrgoY2SDqqpi/KjgAFsoSVRSpq92nI=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ESRrmLiA9SXDMqJjwBVnYuTXj268JVazkwRp33t5sWiBQ7cnsgPZEXvktWqFqGDuK s1f2gJaJgsdHX122VAr1xPMCAzKEfq6nbPJ3bOJFuj4jAEpLMYgb2FzTvEh5D6WUNo emWITCHOeluMCQZDLY+uCQIyaB+97pIrNC0GUYPU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 93E8DF802E0; Mon, 27 Jan 2020 13:13:54 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 93448F802A8; Mon, 27 Jan 2020 13:13:47 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 9170CF80277 for ; Mon, 27 Jan 2020 13:13:36 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 9170CF80277 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2020 04:13:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,369,1574150400"; d="scan'208";a="261029693" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga002.fm.intel.com with ESMTP; 27 Jan 2020 04:13:34 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Mon, 27 Jan 2020 13:12:41 +0100 Message-Id: <20200127121243.15813-10-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200127121243.15813-1-cezary.rojewski@intel.com> References: <20200127121243.15813-1-cezary.rojewski@intel.com> Cc: lgirdwood@gmail.com, Cezary Rojewski , broonie@kernel.org, tiwai@suse.com, pierre-louis.bossart@linux.intel.com Subject: [alsa-devel] [PATCH v2 09/11] ASoC: SOF: Intel: Probe compress operations X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Add HDA handlers for soc_compr_ops and snd_compr_ops which cover probe related operations. Implementation supports both connection purposes. These merely define stream setups as core flow is covered by SOF compress core. Signed-off-by: Cezary Rojewski --- Changes in v2: - probes over HDA no longer require SND_SOC_SOF_HDA_LINK enabled sound/soc/sof/intel/Kconfig | 9 ++ sound/soc/sof/intel/Makefile | 1 + sound/soc/sof/intel/apl.c | 9 ++ sound/soc/sof/intel/cnl.c | 9 ++ sound/soc/sof/intel/hda-compress.c | 132 +++++++++++++++++++++++++++++ sound/soc/sof/intel/hda.h | 24 ++++++ 6 files changed, 184 insertions(+) create mode 100644 sound/soc/sof/intel/hda-compress.c diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index 56a837d2cb95..3bc64dee7c39 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -305,6 +305,15 @@ config SND_SOC_SOF_HDA_AUDIO_CODEC Say Y if you want to enable HDAudio codecs with SOF. If unsure select "N". +config SND_SOC_SOF_HDA_PROBES + bool "SOF enable probes over HDA" + depends on SND_SOC_SOF_DEBUG_PROBES + help + This option enables the data probing for Intel(R). + Intel(R) Skylake and newer platforms. + Say Y if you want to enable probes. + If unsure, select "N". + config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 bool "SOF enable DMI Link L1" help diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index b8f58e006e29..cee02a2e00f4 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -9,6 +9,7 @@ snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \ hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \ hda-dai.o hda-bus.o \ apl.o cnl.o +snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o snd-sof-intel-hda-objs := hda-codec.o diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 2483b15699e7..02218d22e51f 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -73,6 +73,15 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .pcm_trigger = hda_dsp_pcm_trigger, .pcm_pointer = hda_dsp_pcm_pointer, +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) + /* probe callbacks */ + .probe_assign = hda_probe_compr_assign, + .probe_free = hda_probe_compr_free, + .probe_set_params = hda_probe_compr_set_params, + .probe_trigger = hda_probe_compr_trigger, + .probe_pointer = hda_probe_compr_pointer, +#endif + /* firmware loading */ .load_firmware = snd_sof_load_firmware_raw, diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 9e2d8afe0535..74d07a7b5e34 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -259,6 +259,15 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .pcm_trigger = hda_dsp_pcm_trigger, .pcm_pointer = hda_dsp_pcm_pointer, +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) + /* probe callbacks */ + .probe_assign = hda_probe_compr_assign, + .probe_free = hda_probe_compr_free, + .probe_set_params = hda_probe_compr_set_params, + .probe_trigger = hda_probe_compr_trigger, + .probe_pointer = hda_probe_compr_pointer, +#endif + /* firmware loading */ .load_firmware = snd_sof_load_firmware_raw, diff --git a/sound/soc/sof/intel/hda-compress.c b/sound/soc/sof/intel/hda-compress.c new file mode 100644 index 000000000000..da7de867d0af --- /dev/null +++ b/sound/soc/sof/intel/hda-compress.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2019-2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include +#include "../sof-priv.h" +#include "hda.h" + +static inline struct hdac_ext_stream * +hda_compr_get_stream(struct snd_compr_stream *cstream) +{ + return cstream->runtime->private_data; +} + +int hda_probe_compr_assign(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *stream; + struct hdac_bus *bus = sof_to_bus(sdev); + + stream = snd_hdac_ext_cstream_assign(bus, cstream); + if (!stream) + return -EBUSY; + + hdac_stream(stream)->curr_pos = 0; + cstream->runtime->private_data = stream; + + return hdac_stream(stream)->stream_tag; +} + +int hda_probe_compr_free(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); + + snd_hdac_stream_cleanup(hdac_stream(stream)); + hdac_stream(stream)->prepared = 0; + snd_hdac_ext_stream_release(stream, HDAC_EXT_STREAM_TYPE_HOST); + + return 0; +} + +int hda_probe_compr_set_params(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_compr_params *params, + struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); + unsigned int format_val; + int bps, ret; + /* compr params do not store bit depth, default to S32_LE */ + snd_pcm_format_t format = SNDRV_PCM_FORMAT_S32_LE; + + hdac_stream(stream)->bufsize = 0; + hdac_stream(stream)->period_bytes = 0; + hdac_stream(stream)->format_val = 0; + + bps = snd_pcm_format_physical_width(format); + if (bps < 0) + return bps; + format_val = snd_hdac_calc_stream_format(params->codec.sample_rate, + params->codec.ch_out, format, bps, 0); + ret = snd_hdac_stream_set_params(hdac_stream(stream), format_val); + if (ret < 0) + return ret; + ret = snd_hdac_stream_setup(hdac_stream(stream)); + if (ret < 0) + return ret; + + hdac_stream(stream)->prepared = 1; + + return 0; +} + +int hda_probe_compr_trigger(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, int cmd, + struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); + struct hdac_bus *bus = sof_to_bus(sdev); + unsigned long cookie; + + if (!hdac_stream(stream)->prepared) + return -EPIPE; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: + spin_lock_irqsave(&bus->reg_lock, cookie); + snd_hdac_stream_start(hdac_stream(stream), true); + spin_unlock_irqrestore(&bus->reg_lock, cookie); + break; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + spin_lock_irqsave(&bus->reg_lock, cookie); + snd_hdac_stream_stop(hdac_stream(stream)); + spin_unlock_irqrestore(&bus->reg_lock, cookie); + break; + + default: + return -EINVAL; + } + + return 0; +} + +int hda_probe_compr_pointer(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp, + struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); + struct snd_soc_pcm_stream *pstream; + + pstream = &dai->driver->capture; + tstamp->copied_total = hdac_stream(stream)->curr_pos; + tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates); + + return 0; +} diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index a4d030bfeee1..80aaf4172e34 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -11,6 +11,7 @@ #ifndef __SOF_INTEL_HDA_H #define __SOF_INTEL_HDA_H +#include #include #include #include "shim.h" @@ -533,6 +534,29 @@ int hda_ipc_pcm_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, const struct sof_ipc_pcm_params_reply *reply); +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) +/* + * Probe Compress Operations. + */ +int hda_probe_compr_assign(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_soc_dai *dai); +int hda_probe_compr_free(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_soc_dai *dai); +int hda_probe_compr_set_params(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_compr_params *params, + struct snd_soc_dai *dai); +int hda_probe_compr_trigger(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, int cmd, + struct snd_soc_dai *dai); +int hda_probe_compr_pointer(struct snd_sof_dev *sdev, + struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp, + struct snd_soc_dai *dai); +#endif + /* * DSP IPC Operations. */ From patchwork Mon Jan 27 12:12:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193751 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7348C2D0DB for ; Mon, 27 Jan 2020 12:20:54 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 52A3F2067C for ; Mon, 27 Jan 2020 12:20:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="cHS4g3bm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 52A3F2067C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B718C82E; Mon, 27 Jan 2020 13:20:02 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B718C82E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580127652; bh=e0bUUhWx8l4rk4iWjbbfhBpcxR+X7TtamBS4fH+Wk2s=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=cHS4g3bm3hnhaRuESDeB9cshJohqieLf8GTFcyKdwX7Nk0ShLdI3qFQTRzw3cK3Pg DGi1oYreOcR83kxilnUrLnRkmQJjDvAjMpXfLM24wGruOlpT4qb7TZOTie4vXJKi8f aMG2B20Wai2rqBrMhgaq9igCagIrprWYPHvPykcQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id E90DBF802EB; Mon, 27 Jan 2020 13:13:56 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 94AD6F802A8; Mon, 27 Jan 2020 13:13:48 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 2EE3AF8027D for ; Mon, 27 Jan 2020 13:13:38 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2EE3AF8027D X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2020 04:13:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,369,1574150400"; d="scan'208";a="261029701" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga002.fm.intel.com with ESMTP; 27 Jan 2020 04:13:36 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Mon, 27 Jan 2020 13:12:42 +0100 Message-Id: <20200127121243.15813-11-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200127121243.15813-1-cezary.rojewski@intel.com> References: <20200127121243.15813-1-cezary.rojewski@intel.com> Cc: lgirdwood@gmail.com, Cezary Rojewski , broonie@kernel.org, tiwai@suse.com, pierre-louis.bossart@linux.intel.com Subject: [alsa-devel] [PATCH v2 10/11] ASoC: SOF: Provide probe debugfs support X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Define debugfs subdirectory delegated for IPC communication with DSP. Input format: uint,uint,(...) which are later translated into DWORDS sequence and further into instances of struct of interest given the IPC type. For Extractor probes, following have been enabled: - PROBE_POINT_ADD (echo <..> probe_points) - PROBE_POINT_REMOVE (echo <..> probe_points_remove) - PROBE_POINT_INFO (cat probe_points) Signed-off-by: Cezary Rojewski --- Changes in v2: - renamed debugfs probe functions as requested by Pierre sound/soc/sof/debug.c | 208 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index d2b3b99d3a20..d38ab59e9a98 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -17,6 +17,203 @@ #include "sof-priv.h" #include "ops.h" +#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) +#include "probe.h" + +/** + * strsplit_u32 - Split string into sequence of u32 tokens + * @buf: String to split into tokens. + * @delim: String containing delimiter characters. + * @tkns: Returned u32 sequence pointer. + * @num_tkns: Returned number of tokens obtained. + */ +static int +strsplit_u32(char **buf, const char *delim, u32 **tkns, size_t *num_tkns) +{ + char *s; + u32 *data, *tmp; + size_t count = 0; + size_t cap = 32; + int ret = 0; + + *tkns = NULL; + *num_tkns = 0; + data = kcalloc(cap, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + while ((s = strsep(buf, delim)) != NULL) { + ret = kstrtouint(s, 0, data + count); + if (ret) + goto exit; + if (++count >= cap) { + cap *= 2; + tmp = krealloc(data, cap * sizeof(*data), GFP_KERNEL); + if (!tmp) { + ret = -ENOMEM; + goto exit; + } + data = tmp; + } + } + + if (!count) + goto exit; + *tkns = kmemdup(data, count * sizeof(*data), GFP_KERNEL); + if (*tkns == NULL) { + ret = -ENOMEM; + goto exit; + } + *num_tkns = count; + +exit: + kfree(data); + return ret; +} + +static int tokenize_input(const char __user *from, size_t count, + loff_t *ppos, u32 **tkns, size_t *num_tkns) +{ + char *buf; + int ret; + + buf = kmalloc(count + 1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = simple_write_to_buffer(buf, count, ppos, from, count); + if (ret != count) { + ret = ret >= 0 ? -EIO : ret; + goto exit; + } + + buf[count] = '\0'; + ret = strsplit_u32((char **)&buf, ",", tkns, num_tkns); +exit: + kfree(buf); + return ret; +} + +static ssize_t probe_points_read(struct file *file, + char __user *to, size_t count, loff_t *ppos) +{ + struct snd_sof_dfsentry *dfse = file->private_data; + struct sof_probe_point_desc *desc; + size_t num_desc, len = 0; + char *buf; + int i, ret; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = sof_ipc_probe_points_info(dfse->sdev, &desc, &num_desc); + if (ret < 0) + goto exit; + + for (i = 0; i < num_desc; i++) { + ret = snprintf(buf + len, PAGE_SIZE - len, + "Id: %#010x Purpose: %d Node id: %#x\n", + desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag); + if (ret < 0) + goto free_desc; + len += ret; + } + + ret = simple_read_from_buffer(to, count, ppos, buf, len); +free_desc: + kfree(desc); +exit: + kfree(buf); + return ret; +} + +static ssize_t probe_points_write(struct file *file, + const char __user *from, size_t count, loff_t *ppos) +{ + struct snd_sof_dfsentry *dfse = file->private_data; + struct sof_probe_point_desc *desc; + size_t num_tkns, bytes; + u32 *tkns; + int ret; + + ret = tokenize_input(from, count, ppos, &tkns, &num_tkns); + if (ret < 0) + return ret; + bytes = sizeof(*tkns) * num_tkns; + if (!num_tkns || (bytes % sizeof(*desc))) { + ret = -EINVAL; + goto exit; + } + + desc = (struct sof_probe_point_desc *)tkns; + ret = sof_ipc_probe_points_add(dfse->sdev, + desc, bytes / sizeof(*desc)); + if (!ret) + ret = count; +exit: + kfree(tkns); + return ret; +} + +static const struct file_operations probe_points_fops = { + .open = simple_open, + .read = probe_points_read, + .write = probe_points_write, + .llseek = default_llseek, +}; + +static ssize_t probe_points_remove_write(struct file *file, + const char __user *from, size_t count, loff_t *ppos) +{ + struct snd_sof_dfsentry *dfse = file->private_data; + size_t num_tkns; + u32 *tkns; + int ret; + + ret = tokenize_input(from, count, ppos, &tkns, &num_tkns); + if (ret < 0) + return ret; + if (!num_tkns) { + ret = -EINVAL; + goto exit; + } + + ret = sof_ipc_probe_points_remove(dfse->sdev, tkns, num_tkns); + if (!ret) + ret = count; +exit: + kfree(tkns); + return ret; +} + +static const struct file_operations probe_points_remove_fops = { + .open = simple_open, + .write = probe_points_remove_write, + .llseek = default_llseek, +}; + +static int snd_sof_debugfs_probe_item(struct snd_sof_dev *sdev, + const char *name, mode_t mode, + const struct file_operations *fops) +{ + struct snd_sof_dfsentry *dfse; + + dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); + if (!dfse) + return -ENOMEM; + + dfse->type = SOF_DFSENTRY_TYPE_BUF; + dfse->sdev = sdev; + + debugfs_create_file(name, mode, sdev->debugfs_root, dfse, fops); + /* add to dfsentry list */ + list_add(&dfse->list, &sdev->dfsentry_list); + + return 0; +} +#endif + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) #define MAX_IPC_FLOOD_DURATION_MS 1000 #define MAX_IPC_FLOOD_COUNT 10000 @@ -436,6 +633,17 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev) return err; } +#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) + err = snd_sof_debugfs_probe_item(sdev, "probe_points", + 0644, &probe_points_fops); + if (err < 0) + return err; + err = snd_sof_debugfs_probe_item(sdev, "probe_points_remove", + 0200, &probe_points_remove_fops); + if (err < 0) + return err; +#endif + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) /* create read-write ipc_flood_count debugfs entry */ err = snd_sof_debugfs_buf_item(sdev, NULL, 0,