From patchwork Tue Jan 28 10:43:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193740 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.8 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, 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 A847BC33C9E for ; Tue, 28 Jan 2020 10:46:48 +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 2A69F2467E for ; Tue, 28 Jan 2020 10:46:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="vpeC8+kd" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2A69F2467E 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 446C51657; Tue, 28 Jan 2020 11:45:55 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 446C51657 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580208405; bh=Jh6yLhX2YhQQVZadbcudojWBtR2ZfotW772O22PFz94=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=vpeC8+kd0fEbuyDbbHiQ4WpdFZfoSSYqFHOCEix4ESShKAPcikMuH6cqoEQKz+Iaa k/auD9zDfiEOlXXbX8Ly+nMTO6zcf9j14k+70FkgaeWHXXUVz8IGhSW4J+ppFMV56/ rapDFInhlORE2evuwNFMYDb8eMBRMmyadftbvlac= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 6E88EF80259; Tue, 28 Jan 2020 11:44:20 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BB2C4F80228; Tue, 28 Jan 2020 11:44:14 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (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 BED88F80150 for ; Tue, 28 Jan 2020 11:44:10 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BED88F80150 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Jan 2020 02:44:09 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,373,1574150400"; d="scan'208";a="429292882" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga006.fm.intel.com with ESMTP; 28 Jan 2020 02:44:08 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Tue, 28 Jan 2020 11:43:47 +0100 Message-Id: <20200128104356.16570-3-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200128104356.16570-1-cezary.rojewski@intel.com> References: <20200128104356.16570-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 v3 02/11] ALSA: hda: Prepare for compress stream 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" Before introducing compress specific changes, adjust BDL and parameters setup functions so these are not tightly coupled with PCM streams. Signed-off-by: Cezary Rojewski --- sound/hda/hdac_stream.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 682ed39f79b0..5259cf366011 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -408,11 +408,15 @@ 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_pcm_runtime *runtime = substream->runtime; + 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); + /* reset BDL address */ snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0); snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0); @@ -426,7 +430,7 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) azx_dev->frags = 0; pos_adj = bus->bdl_pos_adj; - if (!azx_dev->no_period_wakeup && pos_adj > 0) { + if (runtime && !azx_dev->no_period_wakeup && pos_adj > 0) { pos_align = pos_adj; pos_adj = (pos_adj * runtime->rate + 47999) / 48000; if (!pos_adj) @@ -440,8 +444,7 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) pos_adj); pos_adj = 0; } else { - ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream), - azx_dev, + ofs = setup_bdle(bus, dmab, azx_dev, &bdl, ofs, pos_adj, true); if (ofs < 0) goto error; @@ -451,13 +454,11 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) for (i = 0; i < periods; i++) { if (i == periods - 1 && pos_adj) - ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream), - azx_dev, &bdl, ofs, - period_bytes - pos_adj, 0); + ofs = setup_bdle(bus, dmab, azx_dev, + &bdl, ofs, period_bytes - pos_adj, 0); else - ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream), - azx_dev, &bdl, ofs, - period_bytes, + ofs = setup_bdle(bus, dmab, azx_dev, + &bdl, ofs, period_bytes, !azx_dev->no_period_wakeup); if (ofs < 0) goto error; @@ -482,26 +483,25 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_setup_periods); int snd_hdac_stream_set_params(struct hdac_stream *azx_dev, unsigned int format_val) { - - unsigned int bufsize, period_bytes; struct snd_pcm_substream *substream = azx_dev->substream; - struct snd_pcm_runtime *runtime; + unsigned int bufsize, period_bytes; + unsigned int no_period_wakeup; int err; if (!substream) return -EINVAL; - runtime = substream->runtime; 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 || format_val != azx_dev->format_val || - runtime->no_period_wakeup != azx_dev->no_period_wakeup) { + no_period_wakeup != azx_dev->no_period_wakeup) { azx_dev->bufsize = bufsize; azx_dev->period_bytes = period_bytes; azx_dev->format_val = format_val; - azx_dev->no_period_wakeup = runtime->no_period_wakeup; + azx_dev->no_period_wakeup = no_period_wakeup; err = snd_hdac_stream_setup_periods(azx_dev); if (err < 0) return err; From patchwork Tue Jan 28 10:43:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193739 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.8 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, 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 A17D7C33C9E for ; Tue, 28 Jan 2020 10:47:41 +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 2A8712467E for ; Tue, 28 Jan 2020 10:47:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="OjzDol4s" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2A8712467E 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 89DB51682; Tue, 28 Jan 2020 11:46:49 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 89DB51682 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580208459; 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=OjzDol4sXSoTvybi1xHt/808HwPfXVYvDYGJ9d14U3WGykJRp8T7lvGBx64m2HsdV cFm7Pgm22Xt0ZJ96pMLxEUlbbi+9HVB5gluoC3E5vhDIy2C0u/VNQKffo1z+7dO4re e4rWTQeSJQTfkzlmOcs5vkOYqhPsCF/Zs9RLstQI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 57BFAF8027D; Tue, 28 Jan 2020 11:44:26 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 26FE5F80273; Tue, 28 Jan 2020 11:44:18 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (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 A22EEF8014B for ; Tue, 28 Jan 2020 11:44:12 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz A22EEF8014B X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Jan 2020 02:44:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,373,1574150400"; d="scan'208";a="429292887" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga006.fm.intel.com with ESMTP; 28 Jan 2020 02:44:09 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Tue, 28 Jan 2020 11:43:48 +0100 Message-Id: <20200128104356.16570-4-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200128104356.16570-1-cezary.rojewski@intel.com> References: <20200128104356.16570-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 v3 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 Tue Jan 28 10:43:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193738 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.8 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, 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 F03BFC33C9E for ; Tue, 28 Jan 2020 10:49:05 +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 758B52467E for ; Tue, 28 Jan 2020 10:49:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="HA4ucu9k" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 758B52467E 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 A222C1677; Tue, 28 Jan 2020 11:48:13 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz A222C1677 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580208543; bh=52OeLapKGTpaIJmp151N0jvXDUiVkny96An3Iy+ee5A=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=HA4ucu9k89HbAxEBJ1wzjxO5u7kQArFI5O6A2a7mEJiB4Cfr0+EbtAa3XxWC8G2vl m6J+alJnhZWWsDl91fS7zqy0Ab12Qn53ErvGGt5MATTM3mrlE52TvUhL24f8q8J8Qu F65hL1fcw+/y5+m2ZBCuN3CgbuK4jw26/rwcwLCA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 28162F80290; Tue, 28 Jan 2020 11:44:30 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 69A0CF80273; Tue, 28 Jan 2020 11:44:20 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (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 2C3ABF8014B for ; Tue, 28 Jan 2020 11:44:16 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2C3ABF8014B X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Jan 2020 02:44:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,373,1574150400"; d="scan'208";a="429292903" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga006.fm.intel.com with ESMTP; 28 Jan 2020 02:44:15 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Tue, 28 Jan 2020 11:43:51 +0100 Message-Id: <20200128104356.16570-7-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200128104356.16570-1-cezary.rojewski@intel.com> References: <20200128104356.16570-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 v3 06/11] ASoC: SOF: Intel: Account for compress streams when servicing IRQs 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" Update stream irq handler definition to correctly set hdac_stream current position when servicing stream interrupts for compress streams. Signed-off-by: Cezary Rojewski --- include/sound/hdaudio.h | 1 + sound/soc/sof/intel/hda-stream.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 9a8bf1eb7d69..9a24d57f0cf2 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -496,6 +496,7 @@ struct hdac_stream { bool locked:1; bool stripe:1; /* apply stripe control */ + unsigned long curr_pos; /* timestamp */ unsigned long start_wallclk; /* start + minimum wallclk */ unsigned long period_wallclk; /* wallclk for period */ diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index c0ab9bb2a797..c8920a60e346 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -571,6 +571,23 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev) return ret; } +static void hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, + u64 buffer_size) +{ + unsigned int prev_pos; + int pos, num_bytes; + + div_u64_rem(hstream->curr_pos, buffer_size, &prev_pos); + pos = snd_hdac_stream_get_pos_posbuf(hstream); + + if (pos < prev_pos) + num_bytes = (buffer_size - prev_pos) + pos; + else + num_bytes = pos - prev_pos; + + hstream->curr_pos += num_bytes; +} + static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status) { struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus); @@ -588,14 +605,19 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status) snd_hdac_stream_writeb(s, SD_STS, sd_status); active = true; - if (!s->substream || + if ((!s->substream && !s->cstream) || !s->running || (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0) continue; /* Inform ALSA only in case not do that with IPC */ - if (sof_hda->no_ipc_position) + if (s->substream && sof_hda->no_ipc_position) { snd_sof_pcm_period_elapsed(s->substream); + } else if (s->cstream) { + hda_dsp_set_bytes_transferred(s, + s->cstream->runtime->buffer_size); + snd_compr_fragment_elapsed(s->cstream); + } } } From patchwork Tue Jan 28 10:43:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193737 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.8 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, 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 83A85C33C9E for ; Tue, 28 Jan 2020 10:50:10 +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 0E5872467E for ; Tue, 28 Jan 2020 10:50:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="iGAo0a/o" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0E5872467E 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 692531681; Tue, 28 Jan 2020 11:49:18 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 692531681 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580208608; bh=d0A2WGkUPAvzIJB0YvSpHPBrkMHR38YfXh3irf62UeQ=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=iGAo0a/oPipbaD+Ksmb0zDryzQRwNdXooFUY8082pldjBSiLEjnllLKzGU/6gc86u zCJwSuz3iz93LVPDbL/IpMK2D8lnqrYmxWJw3+72wwVsB5/EHoCNMZO2lAHHIE+K1V n13fWH55pDLpDwM0j694YWJOYQXC3J8PR6y/PHOU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 68039F802BE; Tue, 28 Jan 2020 11:44:34 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 20480F8028C; Tue, 28 Jan 2020 11:44:27 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (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 59A1EF80274 for ; Tue, 28 Jan 2020 11:44:20 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 59A1EF80274 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Jan 2020 02:44:18 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,373,1574150400"; d="scan'208";a="429292908" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga006.fm.intel.com with ESMTP; 28 Jan 2020 02:44:17 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Tue, 28 Jan 2020 11:43:52 +0100 Message-Id: <20200128104356.16570-8-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200128104356.16570-1-cezary.rojewski@intel.com> References: <20200128104356.16570-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 v3 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 v3: - fixed sparse and all doc related warnings as reported by Pierre - 'extractor' field has been renamed and its declaration relocated to patch: "[PATCH v3 08/11] ASoC: SOF: Generic probe compress operations" 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 | 286 ++++++++++++++++++++++++++++++++++ sound/soc/sof/probe.h | 85 ++++++++++ 5 files changed, 386 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..2b2f3dcfc7e9 --- /dev/null +++ b/sound/soc/sof/probe.c @@ -0,0 +1,286 @@ +// 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 + * @stream_tag: Extractor stream tag + * @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 + * @buffer_id: List of probe points to disconnect + * @num_buffer_id: 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..45daa5552834 --- /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_buffer_id); + +#endif From patchwork Tue Jan 28 10:43:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 193736 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.8 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, 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 ECF9DC33C9E for ; Tue, 28 Jan 2020 10:51:17 +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 775C42467B for ; Tue, 28 Jan 2020 10:51:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="huQkvfdv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 775C42467B 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 D22631677; Tue, 28 Jan 2020 11:50:25 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D22631677 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1580208675; 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=huQkvfdviWgNO8Ea1tuGa7tITeFuXl653o+Ty80tVbdNtI5tvRGmG1euMN2A+6Rcv fr1kLcK7bmb1lmbNIxg6FTvXppk5Lo9P9Uw5cevXakT3uZpogYKQ/OEOSSUCxPYbFk 7KR/h8usyj97f3B0u1VbJoTv9PhqSP77jHPBgWtQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id C4B62F802DD; Tue, 28 Jan 2020 11:44:36 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9A2CDF8029B; Tue, 28 Jan 2020 11:44:32 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (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 62835F8028A for ; Tue, 28 Jan 2020 11:44:27 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 62835F8028A X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Jan 2020 02:44:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,373,1574150400"; d="scan'208";a="429292932" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga006.fm.intel.com with ESMTP; 28 Jan 2020 02:44:22 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Tue, 28 Jan 2020 11:43:55 +0100 Message-Id: <20200128104356.16570-11-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200128104356.16570-1-cezary.rojewski@intel.com> References: <20200128104356.16570-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 v3 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,