From patchwork Mon May 16 10:47:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 572994 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 8F1D4C433F5 for ; Mon, 16 May 2022 10:48:57 +0000 (UTC) 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 7AAC11683; Mon, 16 May 2022 12:48:05 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 7AAC11683 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698135; bh=slIqjPWW+Rd6+alkrS9Z+VVatgFw4UUPxCLZE+uVPtU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=a5iTa0KXUXNK4fcJ983nx9CKhLwHgid6/iedDwPubk/f6ai8CYpTU39L+bv0M6wTq 0F6eJ/bI3avHW7L99+wZ1tejzchoISS+wTzngmcEAW/wQ/TtbuymYGmw/e709VAqsA /OJTz+vO0Bog7QWFDZXpbvFwJ3BDNrnZwGycsUaA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 895F2F8051D; Mon, 16 May 2022 12:47:34 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7AC8EF802DF; Mon, 16 May 2022 12:47:30 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 D3CC9F8012F for ; Mon, 16 May 2022 12:47:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D3CC9F8012F Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BZ//2KvU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698045; x=1684234045; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=slIqjPWW+Rd6+alkrS9Z+VVatgFw4UUPxCLZE+uVPtU=; b=BZ//2KvU7RMqHSkdWbEuFVITqCongPvlvacze4OUfoXgR5dXaTCGa2kW VhWbvGdUrDoIYpRmb3OFCVJXvZqJ56zQ9GnZ9KWVAsy2qSvIlUYqKgdDa ZMcvwcUHHayjJEN309hwQsF/JrlKffLkZIU8WbmZUmGFOg/31DM3UUwPL AE2uAdVqrIIwxa2+vFfMQU9TCWMAjmNh4Mx/XloaptPWHThABCJl3+c03 RD5xZKHmBT7QcqQGKGWliWxdaTLrP0BUaImi4LtQmS7U5aTK4PlkQS1Vh f4/GeuRKnD9yTSWBEnMaCuW/M/gfAsXPwAEZWnmQ59+NkGELK9U1itvLM g==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853234" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853234" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:49 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459727" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:47 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 1/8] ASoC: SOF: Introduce IPC independent ops for firmware tracing support Date: Mon, 16 May 2022 13:47:04 +0300 Message-Id: <20220516104711.26115-2-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The current (dma-)trace is only supported with IPC3, it is not available when IPC4 is used. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/sof-priv.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 8ea196305e4b..a7ffb6ecf332 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -357,6 +357,22 @@ struct snd_sof_ipc_msg { bool ipc_complete; }; +/** + * struct sof_ipc_fw_tracing_ops - IPC-specific firmware tracing ops + * @init: Function pointer for initialization of the tracing + * @free: Optional function pointer for freeing of the tracing + * @fw_crashed: Optional function pointer to notify the tracing of a firmware crash + * @suspend: Function pointer for system/runtime suspend + * @resume: Function pointer for system/runtime resume + */ +struct sof_ipc_fw_tracing_ops { + int (*init)(struct snd_sof_dev *sdev); + void (*free)(struct snd_sof_dev *sdev); + void (*fw_crashed)(struct snd_sof_dev *sdev); + void (*suspend)(struct snd_sof_dev *sdev, pm_message_t pm_state); + int (*resume)(struct snd_sof_dev *sdev); +}; + /** * struct sof_ipc_pm_ops - IPC-specific PM ops * @ctx_save: Function pointer for context save @@ -395,6 +411,7 @@ struct sof_ipc_pcm_ops; * @pm: Pointer to PM ops * @pcm: Pointer to PCM ops * @fw_loader: Pointer to Firmware Loader ops + * @fw_tracing: Pointer to Firmware tracing ops * * @tx_msg: Function pointer for sending a 'short' IPC message * @set_get_data: Function pointer for set/get data ('large' IPC message). This @@ -415,6 +432,7 @@ struct sof_ipc_ops { const struct sof_ipc_pm_ops *pm; const struct sof_ipc_pcm_ops *pcm; const struct sof_ipc_fw_loader_ops *fw_loader; + const struct sof_ipc_fw_tracing_ops *fw_tracing; int (*tx_msg)(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes, void *reply_data, size_t reply_bytes, bool no_pm); From patchwork Mon May 16 10:47:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 573460 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id A33B5C433F5 for ; Mon, 16 May 2022 10:48:25 +0000 (UTC) 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 37C881677; Mon, 16 May 2022 12:47:33 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 37C881677 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698103; bh=UGwKRk4cWTNgwF2Wv+HiO1LYQNBjEmeVJ8ld7RI01FI=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=oii1wae5jWHYcUHwKM84/gYkPgehgSJcfhYjRKvGB4k9dkpiNByr+u6pkna55i027 Hxey9Xp3K+03voPvkAZBKUGI6yaJTgLDOfr4MR40iMkzQzk/17B+Db6f/2drGv4Yat gmTh6oZ9SXio0dBgU9Nzv4WzjlqSI/zkN7+EzEKE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 62A60F8051A; Mon, 16 May 2022 12:47:32 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 5D0A5F800D8; Mon, 16 May 2022 12:47:30 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 D6063F800D8 for ; Mon, 16 May 2022 12:47:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D6063F800D8 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BvlBNez6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698045; x=1684234045; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UGwKRk4cWTNgwF2Wv+HiO1LYQNBjEmeVJ8ld7RI01FI=; b=BvlBNez6Ajbf4U8KESKfEuac4g3MVAV+c1GkFSsvzk0ydN6KPUvh04wj MJaMg7BYr4YSh03PnXsi2CtEtCGS7xg3nu7V4CtRf5MSrof8ccfGkXRMM P5eCLVOTfotj54PAGIZEcu9FAf0j1istoHbiCgk+B9k8zDudeHKqBv+vE ZEwOpOeD2TlnCMdD9NP69ar+ORxdmtyVbyIS5JNfN3TroILziKiftlNsD RABYaDZEUkuRC9qsssSIrabmBiwp+Q8S6Mn2HqfEFmWou7SEQ7q2MscTK MzLLOGCxIFX+DNYE8P/l4ULQ6hUst3hx7EUu7Bagv3a9IpGhRmjmRaS5D A==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853239" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853239" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:52 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459785" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:50 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 2/8] ASoC: SOF: Rename dtrace_is_supported flag to fw_trace_is_supported Date: Mon, 16 May 2022 13:47:05 +0300 Message-Id: <20220516104711.26115-3-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Rename the internal flag to not limit it's use for dma-trace, but to be used for generic firmware tracing functionality. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/core.c | 2 +- sound/soc/sof/intel/hda-dsp.c | 2 +- sound/soc/sof/sof-priv.h | 4 +++- sound/soc/sof/trace.c | 14 +++++++------- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 2d12e8bab769..ff636f0e2435 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -250,7 +250,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) } if (sof_debug_check_flag(SOF_DBG_ENABLE_TRACE)) { - sdev->dtrace_is_supported = true; + sdev->fw_trace_is_supported = true; /* init DMA trace */ ret = snd_sof_init_trace(sdev); diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index c068a3f2f6df..000ea906670c 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -432,7 +432,7 @@ static int hda_dsp_set_D0_state(struct snd_sof_dev *sdev, * when the DSP enters D0I3 while the system is in S0 * for debug purpose. */ - if (!sdev->dtrace_is_supported || + if (!sdev->fw_trace_is_supported || !hda_enable_trace_D0I3_S0 || sdev->system_suspend_target != SOF_SUSPEND_NONE) flags = HDA_PM_NO_DMA_TRACE; diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index a7ffb6ecf332..f1cbd2b0d1c9 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -546,13 +546,15 @@ struct snd_sof_dev { int ipc_timeout; int boot_timeout; + /* firmwre tracing */ + bool fw_trace_is_supported; /* set with Kconfig or module parameter */ + /* DMA for Trace */ struct snd_dma_buffer dmatb; struct snd_dma_buffer dmatp; int dma_trace_pages; wait_queue_head_t trace_sleep; u32 host_offset; - bool dtrace_is_supported; /* set with Kconfig or module parameter */ bool dtrace_error; bool dtrace_draining; enum sof_dtrace_state dtrace_state; diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c index 5d171bf8a5ea..c5cc78c1958f 100644 --- a/sound/soc/sof/trace.c +++ b/sound/soc/sof/trace.c @@ -392,7 +392,7 @@ static int snd_sof_enable_trace(struct snd_sof_dev *sdev) struct sof_ipc_reply ipc_reply; int ret; - if (!sdev->dtrace_is_supported) + if (!sdev->fw_trace_is_supported) return 0; if (sdev->dtrace_state == SOF_DTRACE_ENABLED || !sdev->dma_trace_pages) @@ -459,9 +459,9 @@ int snd_sof_init_trace(struct snd_sof_dev *sdev) /* dtrace is only supported with SOF_IPC */ if (sdev->pdata->ipc_type != SOF_IPC) - sdev->dtrace_is_supported = false; + sdev->fw_trace_is_supported = false; - if (!sdev->dtrace_is_supported) + if (!sdev->fw_trace_is_supported) return 0; /* set false before start initialization */ @@ -521,7 +521,7 @@ EXPORT_SYMBOL(snd_sof_init_trace); int snd_sof_trace_update_pos(struct snd_sof_dev *sdev, struct sof_ipc_dma_trace_posn *posn) { - if (!sdev->dtrace_is_supported) + if (!sdev->fw_trace_is_supported) return 0; if (sdev->dtrace_state == SOF_DTRACE_ENABLED && @@ -541,7 +541,7 @@ int snd_sof_trace_update_pos(struct snd_sof_dev *sdev, /* an error has occurred within the DSP that prevents further trace */ void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev) { - if (!sdev->dtrace_is_supported) + if (!sdev->fw_trace_is_supported) return; if (sdev->dtrace_state == SOF_DTRACE_ENABLED) { @@ -559,7 +559,7 @@ static void snd_sof_release_trace(struct snd_sof_dev *sdev, bool only_stop) struct sof_ipc_reply ipc_reply; int ret; - if (!sdev->dtrace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED) + if (!sdev->fw_trace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED) return; ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_STOP); @@ -611,7 +611,7 @@ EXPORT_SYMBOL(snd_sof_trace_resume); void snd_sof_free_trace(struct snd_sof_dev *sdev) { - if (!sdev->dtrace_is_supported) + if (!sdev->fw_trace_is_supported) return; /* release trace */ From patchwork Mon May 16 10:47:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 572992 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 3303FC433FE for ; Mon, 16 May 2022 10:49:59 +0000 (UTC) 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 754EF1677; Mon, 16 May 2022 12:49:07 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 754EF1677 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698197; bh=1kNnH+7BxZ6e/P4QbUKV5n8cQdSuDxedzb5TjYetAAk=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=g4c973HqRzk/cUj3TIaZ5mnDdpHOShnS0Bk4nhuIVLX2w4nAHtRtXPx9PpjeLlPjb GrK0UBeIPFf+F7ToL4kCSs+BEP16uPqJ1BspKyrkZ2JtmZXXiUojlmt47oCunYYP95 9L70KTQXmN4DwK43gXCzeNTDCdgW2ILihJ2KJ9Fg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7F1E5F80529; Mon, 16 May 2022 12:47:41 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id C4D30F80525; Mon, 16 May 2022 12:47:37 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 E1996F8014B for ; Mon, 16 May 2022 12:47:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E1996F8014B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lFRCGT0n" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698047; x=1684234047; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1kNnH+7BxZ6e/P4QbUKV5n8cQdSuDxedzb5TjYetAAk=; b=lFRCGT0nAFKnxeMi4HMdA6ACj8imPXqH/Z+eumnJE3pq5p2gwn9RwKuY vII4viOtkRNDrzGerk9SPfvIlTWBSfi8EPufvyftOfNxjqJ/ZV2AcEYfe Wgncgrq7J5gJo81bl0U0hp2EWTyEXV1kNPHIqvCypOVwuSQ93KxDL163E SYjlutYN7BcDzc/y7LJNA4pUEqjrVSAuxH3NORlpXjCtQ82VXI5owVbRE /rowcB2ZdDYt17UXDy28zDaVsNqCuFDdsZ4AK9kXDJLGQcBS/W1opdw1x 4HABjRa3GxzTctAs+xsPMkU5Yw8WfbHoqCNKZuCfiyRe7GXcsO9pQHvEv Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853246" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853246" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:55 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459795" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:52 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 3/8] ASoC: SOF: Clone the trace code to ipc3-dtrace as fw_tracing implementation Date: Mon, 16 May 2022 13:47:06 +0300 Message-Id: <20220516104711.26115-4-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The existing trace.c file is implementing the IPC3 dma-trace support. Clone the existing code with prefix fixes as ipc3 fw_tracing implementation to be used when the core is converted to use generic ops for firmware tracing. Drop the dual licensing of the content as the implementation is based on debugfs. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/Makefile | 1 + sound/soc/sof/ipc3-dtrace.c | 605 ++++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc3-priv.h | 5 + sound/soc/sof/ipc3.c | 1 + 4 files changed, 612 insertions(+) create mode 100644 sound/soc/sof/ipc3-dtrace.c diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 8a79f03207fe..92b5e83601be 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -3,6 +3,7 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\ ipc3-topology.o ipc3-control.o ipc3.o ipc3-pcm.o ipc3-loader.o\ + ipc3-dtrace.o\ ipc4.o ipc4-loader.o ifneq ($(CONFIG_SND_SOC_SOF_CLIENT),) snd-sof-objs += sof-client.o diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c new file mode 100644 index 000000000000..0bc3ad586d23 --- /dev/null +++ b/sound/soc/sof/ipc3-dtrace.c @@ -0,0 +1,605 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +#include +#include +#include "sof-priv.h" +#include "sof-audio.h" +#include "ops.h" +#include "sof-utils.h" +#include "ipc3-priv.h" + +#define TRACE_FILTER_ELEMENTS_PER_ENTRY 4 +#define TRACE_FILTER_MAX_CONFIG_STRING_LENGTH 1024 + +static int trace_filter_append_elem(struct snd_sof_dev *sdev, u32 key, u32 value, + struct sof_ipc_trace_filter_elem *elem_list, + int capacity, int *counter) +{ + if (*counter >= capacity) + return -ENOMEM; + + elem_list[*counter].key = key; + elem_list[*counter].value = value; + ++*counter; + + return 0; +} + +static int trace_filter_parse_entry(struct snd_sof_dev *sdev, const char *line, + struct sof_ipc_trace_filter_elem *elem, + int capacity, int *counter) +{ + int log_level, pipe_id, comp_id, read, ret; + int len = strlen(line); + int cnt = *counter; + u32 uuid_id; + + /* ignore empty content */ + ret = sscanf(line, " %n", &read); + if (!ret && read == len) + return len; + + ret = sscanf(line, " %d %x %d %d %n", &log_level, &uuid_id, &pipe_id, &comp_id, &read); + if (ret != TRACE_FILTER_ELEMENTS_PER_ENTRY || read != len) { + dev_err(sdev->dev, "Invalid trace filter entry '%s'\n", line); + return -EINVAL; + } + + if (uuid_id > 0) { + ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_BY_UUID, + uuid_id, elem, capacity, &cnt); + if (ret) + return ret; + } + if (pipe_id >= 0) { + ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_BY_PIPE, + pipe_id, elem, capacity, &cnt); + if (ret) + return ret; + } + if (comp_id >= 0) { + ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_BY_COMP, + comp_id, elem, capacity, &cnt); + if (ret) + return ret; + } + + ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_SET_LEVEL | + SOF_IPC_TRACE_FILTER_ELEM_FIN, + log_level, elem, capacity, &cnt); + if (ret) + return ret; + + /* update counter only when parsing whole entry passed */ + *counter = cnt; + + return len; +} + +static int trace_filter_parse(struct snd_sof_dev *sdev, char *string, + int *out_elem_cnt, + struct sof_ipc_trace_filter_elem **out) +{ + static const char entry_delimiter[] = ";"; + char *entry = string; + int capacity = 0; + int entry_len; + int cnt = 0; + + /* + * Each entry contains at least 1, up to TRACE_FILTER_ELEMENTS_PER_ENTRY + * IPC elements, depending on content. Calculate IPC elements capacity + * for the input string where each element is set. + */ + while (entry) { + capacity += TRACE_FILTER_ELEMENTS_PER_ENTRY; + entry = strchr(entry + 1, entry_delimiter[0]); + } + *out = kmalloc(capacity * sizeof(**out), GFP_KERNEL); + if (!*out) + return -ENOMEM; + + /* split input string by ';', and parse each entry separately in trace_filter_parse_entry */ + while ((entry = strsep(&string, entry_delimiter))) { + entry_len = trace_filter_parse_entry(sdev, entry, *out, capacity, &cnt); + if (entry_len < 0) { + dev_err(sdev->dev, + "Parsing filter entry '%s' failed with %d\n", + entry, entry_len); + return -EINVAL; + } + } + + *out_elem_cnt = cnt; + + return 0; +} + +static int ipc3_trace_update_filter(struct snd_sof_dev *sdev, int num_elems, + struct sof_ipc_trace_filter_elem *elems) +{ + struct sof_ipc_trace_filter *msg; + struct sof_ipc_reply reply; + size_t size; + int ret; + + size = struct_size(msg, elems, num_elems); + if (size > SOF_IPC_MSG_MAX_SIZE) + return -EINVAL; + + msg = kmalloc(size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->hdr.size = size; + msg->hdr.cmd = SOF_IPC_GLB_TRACE_MSG | SOF_IPC_TRACE_FILTER_UPDATE; + msg->elem_cnt = num_elems; + memcpy(&msg->elems[0], elems, num_elems * sizeof(*elems)); + + ret = pm_runtime_get_sync(sdev->dev); + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_noidle(sdev->dev); + dev_err(sdev->dev, "enabling device failed: %d\n", ret); + goto error; + } + ret = sof_ipc_tx_message(sdev->ipc, msg, msg->hdr.size, &reply, sizeof(reply)); + pm_runtime_mark_last_busy(sdev->dev); + pm_runtime_put_autosuspend(sdev->dev); + +error: + kfree(msg); + return ret ? ret : reply.error; +} + +static ssize_t dfsentry_trace_filter_write(struct file *file, const char __user *from, + size_t count, loff_t *ppos) +{ + struct snd_sof_dfsentry *dfse = file->private_data; + struct sof_ipc_trace_filter_elem *elems = NULL; + struct snd_sof_dev *sdev = dfse->sdev; + loff_t pos = 0; + int num_elems; + char *string; + int ret; + + if (count > TRACE_FILTER_MAX_CONFIG_STRING_LENGTH) { + dev_err(sdev->dev, "%s too long input, %zu > %d\n", __func__, count, + TRACE_FILTER_MAX_CONFIG_STRING_LENGTH); + return -EINVAL; + } + + string = kmalloc(count + 1, GFP_KERNEL); + if (!string) + return -ENOMEM; + + /* assert null termination */ + string[count] = 0; + ret = simple_write_to_buffer(string, count, &pos, from, count); + if (ret < 0) + goto error; + + ret = trace_filter_parse(sdev, string, &num_elems, &elems); + if (ret < 0) + goto error; + + if (num_elems) { + ret = ipc3_trace_update_filter(sdev, num_elems, elems); + if (ret < 0) { + dev_err(sdev->dev, "Filter update failed: %d\n", ret); + goto error; + } + } + ret = count; +error: + kfree(string); + kfree(elems); + return ret; +} + +static const struct file_operations sof_dfs_trace_filter_fops = { + .open = simple_open, + .write = dfsentry_trace_filter_write, + .llseek = default_llseek, +}; + +static int debugfs_create_trace_filter(struct snd_sof_dev *sdev) +{ + struct snd_sof_dfsentry *dfse; + + dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); + if (!dfse) + return -ENOMEM; + + dfse->sdev = sdev; + dfse->type = SOF_DFSENTRY_TYPE_BUF; + + debugfs_create_file("filter", 0200, sdev->debugfs_root, dfse, + &sof_dfs_trace_filter_fops); + /* add to dfsentry list */ + list_add(&dfse->list, &sdev->dfsentry_list); + + return 0; +} + +static size_t sof_dtrace_avail(struct snd_sof_dev *sdev, + loff_t pos, size_t buffer_size) +{ + loff_t host_offset = READ_ONCE(sdev->host_offset); + + /* + * If host offset is less than local pos, it means write pointer of + * host DMA buffer has been wrapped. We should output the trace data + * at the end of host DMA buffer at first. + */ + if (host_offset < pos) + return buffer_size - pos; + + /* If there is available trace data now, it is unnecessary to wait. */ + if (host_offset > pos) + return host_offset - pos; + + return 0; +} + +static size_t sof_wait_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos, + size_t buffer_size) +{ + wait_queue_entry_t wait; + size_t ret = sof_dtrace_avail(sdev, pos, buffer_size); + + /* data immediately available */ + if (ret) + return ret; + + if (sdev->dtrace_state != SOF_DTRACE_ENABLED && sdev->dtrace_draining) { + /* + * tracing has ended and all traces have been + * read by client, return EOF + */ + sdev->dtrace_draining = false; + return 0; + } + + /* wait for available trace data from FW */ + init_waitqueue_entry(&wait, current); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&sdev->trace_sleep, &wait); + + if (!signal_pending(current)) { + /* set timeout to max value, no error code */ + schedule_timeout(MAX_SCHEDULE_TIMEOUT); + } + remove_wait_queue(&sdev->trace_sleep, &wait); + + return sof_dtrace_avail(sdev, pos, buffer_size); +} + +static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct snd_sof_dfsentry *dfse = file->private_data; + struct snd_sof_dev *sdev = dfse->sdev; + unsigned long rem; + loff_t lpos = *ppos; + size_t avail, buffer_size = dfse->size; + u64 lpos_64; + + /* make sure we know about any failures on the DSP side */ + sdev->dtrace_error = false; + + /* check pos and count */ + if (lpos < 0) + return -EINVAL; + if (!count) + return 0; + + /* check for buffer wrap and count overflow */ + lpos_64 = lpos; + lpos = do_div(lpos_64, buffer_size); + + /* get available count based on current host offset */ + avail = sof_wait_dtrace_avail(sdev, lpos, buffer_size); + if (sdev->dtrace_error) { + dev_err(sdev->dev, "trace IO error\n"); + return -EIO; + } + + /* make sure count is <= avail */ + if (count > avail) + count = avail; + + /* + * make sure that all trace data is available for the CPU as the trace + * data buffer might be allocated from non consistent memory. + * Note: snd_dma_buffer_sync() is called for normal audio playback and + * capture streams also. + */ + snd_dma_buffer_sync(&sdev->dmatb, SNDRV_DMA_SYNC_CPU); + /* copy available trace data to debugfs */ + rem = copy_to_user(buffer, ((u8 *)(dfse->buf) + lpos), count); + if (rem) + return -EFAULT; + + *ppos += count; + + /* move debugfs reading position */ + return count; +} + +static int dfsentry_dtrace_release(struct inode *inode, struct file *file) +{ + struct snd_sof_dfsentry *dfse = inode->i_private; + struct snd_sof_dev *sdev = dfse->sdev; + + /* avoid duplicate traces at next open */ + if (sdev->dtrace_state != SOF_DTRACE_ENABLED) + sdev->host_offset = 0; + + return 0; +} + +static const struct file_operations sof_dfs_dtrace_fops = { + .open = simple_open, + .read = dfsentry_dtrace_read, + .llseek = default_llseek, + .release = dfsentry_dtrace_release, +}; + +static int debugfs_create_dtrace(struct snd_sof_dev *sdev) +{ + struct snd_sof_dfsentry *dfse; + int ret; + + if (!sdev) + return -EINVAL; + + ret = debugfs_create_trace_filter(sdev); + if (ret < 0) + dev_warn(sdev->dev, "failed to create filter debugfs file: %d", ret); + + dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); + if (!dfse) + return -ENOMEM; + + dfse->type = SOF_DFSENTRY_TYPE_BUF; + dfse->buf = sdev->dmatb.area; + dfse->size = sdev->dmatb.bytes; + dfse->sdev = sdev; + + debugfs_create_file("trace", 0444, sdev->debugfs_root, dfse, + &sof_dfs_dtrace_fops); + + return 0; +} + +static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) +{ + struct sof_ipc_fw_ready *ready = &sdev->fw_ready; + struct sof_ipc_fw_version *v = &ready->version; + struct sof_ipc_dma_trace_params_ext params; + struct sof_ipc_reply ipc_reply; + int ret; + + if (!sdev->fw_trace_is_supported) + return 0; + + if (sdev->dtrace_state == SOF_DTRACE_ENABLED || !sdev->dma_trace_pages) + return -EINVAL; + + if (sdev->dtrace_state == SOF_DTRACE_STOPPED) + goto start; + + /* set IPC parameters */ + params.hdr.cmd = SOF_IPC_GLB_TRACE_MSG; + /* PARAMS_EXT is only supported from ABI 3.7.0 onwards */ + if (v->abi_version >= SOF_ABI_VER(3, 7, 0)) { + params.hdr.size = sizeof(struct sof_ipc_dma_trace_params_ext); + params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS_EXT; + params.timestamp_ns = ktime_get(); /* in nanosecond */ + } else { + params.hdr.size = sizeof(struct sof_ipc_dma_trace_params); + params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS; + } + params.buffer.phy_addr = sdev->dmatp.addr; + params.buffer.size = sdev->dmatb.bytes; + params.buffer.pages = sdev->dma_trace_pages; + params.stream_tag = 0; + + sdev->host_offset = 0; + sdev->dtrace_draining = false; + + ret = snd_sof_dma_trace_init(sdev, ¶ms); + if (ret < 0) { + dev_err(sdev->dev, "Host dtrace init failed: %d\n", ret); + return ret; + } + dev_dbg(sdev->dev, "%s: stream_tag: %d\n", __func__, params.stream_tag); + + /* send IPC to the DSP */ + ret = sof_ipc_tx_message(sdev->ipc, ¶ms, sizeof(params), &ipc_reply, sizeof(ipc_reply)); + if (ret < 0) { + dev_err(sdev->dev, "can't set params for DMA for trace %d\n", ret); + goto trace_release; + } + +start: + ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_START); + if (ret < 0) { + dev_err(sdev->dev, "Host dtrace trigger start failed: %d\n", ret); + goto trace_release; + } + + sdev->dtrace_state = SOF_DTRACE_ENABLED; + + return 0; + +trace_release: + snd_sof_dma_trace_release(sdev); + return ret; +} + +static int ipc3_dtrace_init(struct snd_sof_dev *sdev) +{ + int ret; + + /* dtrace is only supported with SOF_IPC */ + if (sdev->pdata->ipc_type != SOF_IPC) + return -EOPNOTSUPP; + + /* set false before start initialization */ + sdev->dtrace_state = SOF_DTRACE_DISABLED; + + /* allocate trace page table buffer */ + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, + PAGE_SIZE, &sdev->dmatp); + if (ret < 0) { + dev_err(sdev->dev, "can't alloc page table for trace %d\n", ret); + return ret; + } + + /* allocate trace data buffer */ + ret = snd_dma_alloc_dir_pages(SNDRV_DMA_TYPE_DEV_SG, sdev->dev, + DMA_FROM_DEVICE, DMA_BUF_SIZE_FOR_TRACE, + &sdev->dmatb); + if (ret < 0) { + dev_err(sdev->dev, "can't alloc buffer for trace %d\n", ret); + goto page_err; + } + + /* create compressed page table for audio firmware */ + ret = snd_sof_create_page_table(sdev->dev, &sdev->dmatb, + sdev->dmatp.area, sdev->dmatb.bytes); + if (ret < 0) + goto table_err; + + sdev->dma_trace_pages = ret; + dev_dbg(sdev->dev, "%s: dma_trace_pages: %d\n", __func__, + sdev->dma_trace_pages); + + if (sdev->first_boot) { + ret = debugfs_create_dtrace(sdev); + if (ret < 0) + goto table_err; + } + + init_waitqueue_head(&sdev->trace_sleep); + + ret = ipc3_dtrace_enable(sdev); + if (ret < 0) + goto table_err; + + return 0; +table_err: + sdev->dma_trace_pages = 0; + snd_dma_free_pages(&sdev->dmatb); +page_err: + snd_dma_free_pages(&sdev->dmatp); + return ret; +} + +int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, + struct sof_ipc_dma_trace_posn *posn) +{ + if (!sdev->fw_trace_is_supported) + return 0; + + if (sdev->dtrace_state == SOF_DTRACE_ENABLED && + sdev->host_offset != posn->host_offset) { + sdev->host_offset = posn->host_offset; + wake_up(&sdev->trace_sleep); + } + + if (posn->overflow != 0) + dev_err(sdev->dev, + "DSP trace buffer overflow %u bytes. Total messages %d\n", + posn->overflow, posn->messages); + + return 0; +} + +/* an error has occurred within the DSP that prevents further trace */ +static void ipc3_dtrace_fw_crashed(struct snd_sof_dev *sdev) +{ + if (sdev->dtrace_state == SOF_DTRACE_ENABLED) { + sdev->dtrace_error = true; + wake_up(&sdev->trace_sleep); + } +} + +static void ipc3_dtrace_release(struct snd_sof_dev *sdev, bool only_stop) +{ + struct sof_ipc_fw_ready *ready = &sdev->fw_ready; + struct sof_ipc_fw_version *v = &ready->version; + struct sof_ipc_cmd_hdr hdr; + struct sof_ipc_reply ipc_reply; + int ret; + + if (!sdev->fw_trace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED) + return; + + ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_STOP); + if (ret < 0) + dev_err(sdev->dev, "Host dtrace trigger stop failed: %d\n", ret); + sdev->dtrace_state = SOF_DTRACE_STOPPED; + + /* + * stop and free trace DMA in the DSP. TRACE_DMA_FREE is only supported from + * ABI 3.20.0 onwards + */ + if (v->abi_version >= SOF_ABI_VER(3, 20, 0)) { + hdr.size = sizeof(hdr); + hdr.cmd = SOF_IPC_GLB_TRACE_MSG | SOF_IPC_TRACE_DMA_FREE; + + ret = sof_ipc_tx_message(sdev->ipc, &hdr, hdr.size, + &ipc_reply, sizeof(ipc_reply)); + if (ret < 0) + dev_err(sdev->dev, "DMA_TRACE_FREE failed with error: %d\n", ret); + } + + if (only_stop) + goto out; + + ret = snd_sof_dma_trace_release(sdev); + if (ret < 0) + dev_err(sdev->dev, "Host dtrace release failed %d\n", ret); + + sdev->dtrace_state = SOF_DTRACE_DISABLED; + +out: + sdev->dtrace_draining = true; + wake_up(&sdev->trace_sleep); +} + +static void ipc3_dtrace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state) +{ + ipc3_dtrace_release(sdev, pm_state.event == SOF_DSP_PM_D0); +} + +static int ipc3_dtrace_resume(struct snd_sof_dev *sdev) +{ + return ipc3_dtrace_enable(sdev); +} + +static void ipc3_dtrace_free(struct snd_sof_dev *sdev) +{ + /* release trace */ + ipc3_dtrace_release(sdev, false); + + if (sdev->dma_trace_pages) { + snd_dma_free_pages(&sdev->dmatb); + snd_dma_free_pages(&sdev->dmatp); + sdev->dma_trace_pages = 0; + } +} + +const struct sof_ipc_fw_tracing_ops ipc3_dtrace_ops = { + .init = ipc3_dtrace_init, + .free = ipc3_dtrace_free, + .fw_crashed = ipc3_dtrace_fw_crashed, + .suspend = ipc3_dtrace_suspend, + .resume = ipc3_dtrace_resume, +}; diff --git a/sound/soc/sof/ipc3-priv.h b/sound/soc/sof/ipc3-priv.h index 82f9d0cbfb93..bb9cb0678686 100644 --- a/sound/soc/sof/ipc3-priv.h +++ b/sound/soc/sof/ipc3-priv.h @@ -16,6 +16,7 @@ extern const struct sof_ipc_pcm_ops ipc3_pcm_ops; extern const struct sof_ipc_tplg_ops ipc3_tplg_ops; extern const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops; extern const struct sof_ipc_fw_loader_ops ipc3_loader_ops; +extern const struct sof_ipc_fw_tracing_ops ipc3_dtrace_ops; /* helpers for fw_ready and ext_manifest parsing */ int sof_ipc3_get_ext_windows(struct snd_sof_dev *sdev, @@ -24,4 +25,8 @@ int sof_ipc3_get_cc_info(struct snd_sof_dev *sdev, const struct sof_ipc_ext_data_hdr *ext_hdr); int sof_ipc3_validate_fw_version(struct snd_sof_dev *sdev); +/* dtrace position update */ +int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, + struct sof_ipc_dma_trace_posn *posn); + #endif diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index a8ffc4f99565..124d4442c6c3 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -1070,6 +1070,7 @@ const struct sof_ipc_ops ipc3_ops = { .pm = &ipc3_pm_ops, .pcm = &ipc3_pcm_ops, .fw_loader = &ipc3_loader_ops, + .fw_tracing = &ipc3_dtrace_ops, .tx_msg = sof_ipc3_tx_msg, .rx_msg = sof_ipc3_rx_msg, From patchwork Mon May 16 10:47:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 572993 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 460A0C433EF for ; Mon, 16 May 2022 10:49:24 +0000 (UTC) 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 787A21695; Mon, 16 May 2022 12:48:32 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 787A21695 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698162; bh=ThEZB4wssOt00icRf3+xWcgiNcEl65wptgdwX61zNQY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uLpPMU08pVWsNaRsHTU3zjdF51Tf6RcnRlmxvA+4oGT9inwkcQWPV1TF0EeZ5WfFu UK+pWYIJA+LiyDQkN9MkDG1Ypz3eW1LyhY4g6WLgBdDHDY1xyy0CUo9wPfkKa60m9N u/lXsDRBufH8zc6I17LVBu1N5tEtKQ4wIqEWe+YI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 44348F8051F; Mon, 16 May 2022 12:47:40 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id F2EF0F80520; Mon, 16 May 2022 12:47:36 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 AD4D0F8025C for ; Mon, 16 May 2022 12:47:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz AD4D0F8025C Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="cHvpScPA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698047; x=1684234047; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ThEZB4wssOt00icRf3+xWcgiNcEl65wptgdwX61zNQY=; b=cHvpScPAM9YzZ4gS/YOcCzWGI6UnkKkxai+4wdRHJ7hD8n2vzHjOhxCW 7w4ycgDoeuGjmsxtiFFEV8fSrJs6iycpu+c2gsdlIdmWC7hWrMJcYzPuk Nc6AM0WnBB6/qBnzR+icGnpZoVhOq2095eIKDOCA5mIb0T1GjgEh2aCy0 tOW655YLzIk/TPQ2ySXrziwgzm7qbJ5SIHvZy9aWHOu2STrmRFgHGDmhM BR3CuZtgPvC0RAC2QhP6myemJ70C1cDGfwex0nD+WK4XtQ/94IpPDnHJ4 WGX6yiVkw6FHsiROIHlh733Cx5myz+S076QpEQoPeuCtQJ4oLJ012k8Dj w==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853250" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853250" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:58 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459810" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:55 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 4/8] ASoC: SOF: Switch to IPC generic firmware tracing Date: Mon, 16 May 2022 13:47:07 +0300 Message-Id: <20220516104711.26115-5-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Introduce new, generic API for firmware tracing with sof_fw_trace_ prefix and switch to use it. At the same time the old IPC3 code can be dropped from trace.c, which is now a generic wrapper for the firmware tracing ops. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/core.c | 11 +- sound/soc/sof/debug.c | 2 +- sound/soc/sof/ipc.c | 6 + sound/soc/sof/ipc3.c | 2 +- sound/soc/sof/ops.c | 2 +- sound/soc/sof/pm.c | 8 +- sound/soc/sof/sof-priv.h | 13 +- sound/soc/sof/trace.c | 615 ++------------------------------------- 8 files changed, 44 insertions(+), 615 deletions(-) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index ff636f0e2435..53719c04658f 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -252,12 +252,11 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) if (sof_debug_check_flag(SOF_DBG_ENABLE_TRACE)) { sdev->fw_trace_is_supported = true; - /* init DMA trace */ - ret = snd_sof_init_trace(sdev); + /* init firmware tracing */ + ret = sof_fw_trace_init(sdev); if (ret < 0) { /* non fatal */ - dev_warn(sdev->dev, - "warning: failed to initialize trace %d\n", + dev_warn(sdev->dev, "failed to initialize firmware tracing %d\n", ret); } } else { @@ -308,7 +307,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) sof_machine_err: snd_sof_machine_unregister(sdev, plat_data); fw_trace_err: - snd_sof_free_trace(sdev); + sof_fw_trace_free(sdev); fw_run_err: snd_sof_fw_unload(sdev); fw_load_err: @@ -447,7 +446,7 @@ int snd_sof_device_remove(struct device *dev) snd_sof_machine_unregister(sdev, pdata); if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { - snd_sof_free_trace(sdev); + sof_fw_trace_free(sdev); ret = snd_sof_dsp_power_down_notify(sdev); if (ret < 0) dev_warn(dev, "error: %d failed to prepare DSP for device removal", diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index 54d3643b46ad..cf1271eb29b2 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -443,6 +443,6 @@ void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev) snd_sof_ipc_dump(sdev); snd_sof_dsp_dbg_dump(sdev, "Firmware exception", SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX); - snd_sof_trace_notify_for_error(sdev); + sof_fw_trace_fw_crashed(sdev); } EXPORT_SYMBOL(snd_sof_handle_fw_exception); diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 41f3a217be5d..c5aef5fc056b 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -184,6 +184,12 @@ struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev) return NULL; } + if (ops->fw_tracing && (!ops->fw_tracing->init || !ops->fw_tracing->suspend || + !ops->fw_tracing->resume)) { + dev_err(sdev->dev, "Missing firmware tracing ops\n"); + return NULL; + } + return ipc; } EXPORT_SYMBOL(snd_sof_ipc_init); diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index 124d4442c6c3..dff5feaad370 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -946,7 +946,7 @@ static void ipc3_trace_message(struct snd_sof_dev *sdev, void *msg_buf) switch (msg_type) { case SOF_IPC_TRACE_DMA_POSITION: - snd_sof_trace_update_pos(sdev, msg_buf); + ipc3_dtrace_posn_update(sdev, msg_buf); break; default: dev_err(sdev->dev, "unhandled trace message %#x\n", msg_type); diff --git a/sound/soc/sof/ops.c b/sound/soc/sof/ops.c index 235e2ef72178..ff066de4ceb9 100644 --- a/sound/soc/sof/ops.c +++ b/sound/soc/sof/ops.c @@ -177,7 +177,7 @@ void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset, bool non_recoverabl snd_sof_dsp_dbg_dump(sdev, "DSP panic!", SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX); sof_set_fw_state(sdev, SOF_FW_CRASHED); - snd_sof_trace_notify_for_error(sdev); + sof_fw_trace_fw_crashed(sdev); } else { snd_sof_dsp_dbg_dump(sdev, "DSP panic (recovery will be attempted)", diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index fa3f5514c00f..18eb327a57f0 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -107,7 +107,7 @@ static int sof_resume(struct device *dev, bool runtime_resume) */ if (!runtime_resume && sof_ops(sdev)->set_power_state && old_state == SOF_DSP_PM_D0) { - ret = snd_sof_trace_resume(sdev); + ret = sof_fw_trace_resume(sdev); if (ret < 0) /* non fatal */ dev_warn(sdev->dev, @@ -143,7 +143,7 @@ static int sof_resume(struct device *dev, bool runtime_resume) } /* resume DMA trace */ - ret = snd_sof_trace_resume(sdev); + ret = sof_fw_trace_resume(sdev); if (ret < 0) { /* non fatal */ dev_warn(sdev->dev, @@ -208,7 +208,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) /* Skip to platform-specific suspend if DSP is entering D0 */ if (target_state == SOF_DSP_PM_D0) { - snd_sof_trace_suspend(sdev, pm_state); + sof_fw_trace_suspend(sdev, pm_state); /* Notify clients not managed by pm framework about core suspend */ sof_suspend_clients(sdev, pm_state); goto suspend; @@ -218,7 +218,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) tplg_ops->tear_down_all_pipelines(sdev, false); /* suspend DMA trace */ - snd_sof_trace_suspend(sdev, pm_state); + sof_fw_trace_suspend(sdev, pm_state); /* Notify clients not managed by pm framework about core suspend */ sof_suspend_clients(sdev, pm_state); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index f1cbd2b0d1c9..61ef739461f0 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -660,27 +660,26 @@ static inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_i /* * Trace/debug */ -int snd_sof_init_trace(struct snd_sof_dev *sdev); -void snd_sof_free_trace(struct snd_sof_dev *sdev); int snd_sof_dbg_init(struct snd_sof_dev *sdev); void snd_sof_free_debug(struct snd_sof_dev *sdev); int snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev, void *base, size_t size, const char *name, mode_t mode); -int snd_sof_trace_update_pos(struct snd_sof_dev *sdev, - struct sof_ipc_dma_trace_posn *posn); -void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev); void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level, u32 panic_code, u32 tracep_code, void *oops, struct sof_ipc_panic_info *panic_info, void *stack, size_t stack_words); -void snd_sof_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state); -int snd_sof_trace_resume(struct snd_sof_dev *sdev); void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev); int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev); int snd_sof_debugfs_add_region_item_iomem(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size, const char *name, enum sof_debugfs_access_type access_type); +/* Firmware tracing */ +int sof_fw_trace_init(struct snd_sof_dev *sdev); +void sof_fw_trace_free(struct snd_sof_dev *sdev); +void sof_fw_trace_fw_crashed(struct snd_sof_dev *sdev); +void sof_fw_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state); +int sof_fw_trace_resume(struct snd_sof_dev *sdev); /* * DSP Architectures. diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c index c5cc78c1958f..6f662642d611 100644 --- a/sound/soc/sof/trace.c +++ b/sound/soc/sof/trace.c @@ -1,626 +1,51 @@ -// SPDX-License-Identifier: (GPL-2.0-only 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) 2018 Intel Corporation. All rights reserved. -// -// Author: Liam Girdwood +// SPDX-License-Identifier: GPL-2.0-only // +// Copyright(c) 2022 Intel Corporation. All rights reserved. -#include -#include #include "sof-priv.h" -#include "sof-audio.h" -#include "ops.h" -#include "sof-utils.h" - -#define TRACE_FILTER_ELEMENTS_PER_ENTRY 4 -#define TRACE_FILTER_MAX_CONFIG_STRING_LENGTH 1024 - -static int trace_filter_append_elem(struct snd_sof_dev *sdev, uint32_t key, uint32_t value, - struct sof_ipc_trace_filter_elem *elem_list, - int capacity, int *counter) -{ - if (*counter >= capacity) - return -ENOMEM; - - elem_list[*counter].key = key; - elem_list[*counter].value = value; - ++*counter; - - return 0; -} - -static int trace_filter_parse_entry(struct snd_sof_dev *sdev, const char *line, - struct sof_ipc_trace_filter_elem *elem, - int capacity, int *counter) -{ - int len = strlen(line); - int cnt = *counter; - uint32_t uuid_id; - int log_level; - int pipe_id; - int comp_id; - int read; - int ret; - - /* ignore empty content */ - ret = sscanf(line, " %n", &read); - if (!ret && read == len) - return len; - - ret = sscanf(line, " %d %x %d %d %n", &log_level, &uuid_id, &pipe_id, &comp_id, &read); - if (ret != TRACE_FILTER_ELEMENTS_PER_ENTRY || read != len) { - dev_err(sdev->dev, "error: invalid trace filter entry '%s'\n", line); - return -EINVAL; - } - - if (uuid_id > 0) { - ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_BY_UUID, - uuid_id, elem, capacity, &cnt); - if (ret) - return ret; - } - if (pipe_id >= 0) { - ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_BY_PIPE, - pipe_id, elem, capacity, &cnt); - if (ret) - return ret; - } - if (comp_id >= 0) { - ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_BY_COMP, - comp_id, elem, capacity, &cnt); - if (ret) - return ret; - } - - ret = trace_filter_append_elem(sdev, SOF_IPC_TRACE_FILTER_ELEM_SET_LEVEL | - SOF_IPC_TRACE_FILTER_ELEM_FIN, - log_level, elem, capacity, &cnt); - if (ret) - return ret; - - /* update counter only when parsing whole entry passed */ - *counter = cnt; - - return len; -} - -static int trace_filter_parse(struct snd_sof_dev *sdev, char *string, - int *out_elem_cnt, - struct sof_ipc_trace_filter_elem **out) -{ - static const char entry_delimiter[] = ";"; - char *entry = string; - int capacity = 0; - int entry_len; - int cnt = 0; - - /* - * Each entry contains at least 1, up to TRACE_FILTER_ELEMENTS_PER_ENTRY - * IPC elements, depending on content. Calculate IPC elements capacity - * for the input string where each element is set. - */ - while (entry) { - capacity += TRACE_FILTER_ELEMENTS_PER_ENTRY; - entry = strchr(entry + 1, entry_delimiter[0]); - } - *out = kmalloc(capacity * sizeof(**out), GFP_KERNEL); - if (!*out) - return -ENOMEM; - - /* split input string by ';', and parse each entry separately in trace_filter_parse_entry */ - while ((entry = strsep(&string, entry_delimiter))) { - entry_len = trace_filter_parse_entry(sdev, entry, *out, capacity, &cnt); - if (entry_len < 0) { - dev_err(sdev->dev, "error: %s failed for '%s', %d\n", __func__, entry, - entry_len); - return -EINVAL; - } - } - - *out_elem_cnt = cnt; - - return 0; -} - -static int sof_ipc_trace_update_filter(struct snd_sof_dev *sdev, int num_elems, - struct sof_ipc_trace_filter_elem *elems) -{ - struct sof_ipc_trace_filter *msg; - struct sof_ipc_reply reply; - size_t size; - int ret; - - size = struct_size(msg, elems, num_elems); - if (size > SOF_IPC_MSG_MAX_SIZE) - return -EINVAL; - - msg = kmalloc(size, GFP_KERNEL); - if (!msg) - return -ENOMEM; - - msg->hdr.size = size; - msg->hdr.cmd = SOF_IPC_GLB_TRACE_MSG | SOF_IPC_TRACE_FILTER_UPDATE; - msg->elem_cnt = num_elems; - memcpy(&msg->elems[0], elems, num_elems * sizeof(*elems)); - - ret = pm_runtime_get_sync(sdev->dev); - if (ret < 0 && ret != -EACCES) { - pm_runtime_put_noidle(sdev->dev); - dev_err(sdev->dev, "error: enabling device failed: %d\n", ret); - goto error; - } - ret = sof_ipc_tx_message(sdev->ipc, msg, msg->hdr.size, &reply, sizeof(reply)); - pm_runtime_mark_last_busy(sdev->dev); - pm_runtime_put_autosuspend(sdev->dev); - -error: - kfree(msg); - return ret ? ret : reply.error; -} - -static ssize_t sof_dfsentry_trace_filter_write(struct file *file, const char __user *from, - size_t count, loff_t *ppos) -{ - struct snd_sof_dfsentry *dfse = file->private_data; - struct sof_ipc_trace_filter_elem *elems = NULL; - struct snd_sof_dev *sdev = dfse->sdev; - loff_t pos = 0; - int num_elems; - char *string; - int ret; - - if (count > TRACE_FILTER_MAX_CONFIG_STRING_LENGTH) { - dev_err(sdev->dev, "%s too long input, %zu > %d\n", __func__, count, - TRACE_FILTER_MAX_CONFIG_STRING_LENGTH); - return -EINVAL; - } - - string = kmalloc(count + 1, GFP_KERNEL); - if (!string) - return -ENOMEM; - - /* assert null termination */ - string[count] = 0; - ret = simple_write_to_buffer(string, count, &pos, from, count); - if (ret < 0) - goto error; - - ret = trace_filter_parse(sdev, string, &num_elems, &elems); - if (ret < 0) { - dev_err(sdev->dev, "error: fail in trace_filter_parse, %d\n", ret); - goto error; - } - - if (num_elems) { - ret = sof_ipc_trace_update_filter(sdev, num_elems, elems); - if (ret < 0) { - dev_err(sdev->dev, "error: fail in sof_ipc_trace_update_filter %d\n", ret); - goto error; - } - } - ret = count; -error: - kfree(string); - kfree(elems); - return ret; -} - -static const struct file_operations sof_dfs_trace_filter_fops = { - .open = simple_open, - .write = sof_dfsentry_trace_filter_write, - .llseek = default_llseek, -}; - -static int trace_debugfs_filter_create(struct snd_sof_dev *sdev) -{ - struct snd_sof_dfsentry *dfse; - - dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); - if (!dfse) - return -ENOMEM; - - dfse->sdev = sdev; - dfse->type = SOF_DFSENTRY_TYPE_BUF; - - debugfs_create_file("filter", 0200, sdev->debugfs_root, dfse, - &sof_dfs_trace_filter_fops); - /* add to dfsentry list */ - list_add(&dfse->list, &sdev->dfsentry_list); - - return 0; -} - -static size_t sof_trace_avail(struct snd_sof_dev *sdev, - loff_t pos, size_t buffer_size) -{ - loff_t host_offset = READ_ONCE(sdev->host_offset); - - /* - * If host offset is less than local pos, it means write pointer of - * host DMA buffer has been wrapped. We should output the trace data - * at the end of host DMA buffer at first. - */ - if (host_offset < pos) - return buffer_size - pos; - - /* If there is available trace data now, it is unnecessary to wait. */ - if (host_offset > pos) - return host_offset - pos; - - return 0; -} - -static size_t sof_wait_trace_avail(struct snd_sof_dev *sdev, - loff_t pos, size_t buffer_size) -{ - wait_queue_entry_t wait; - size_t ret = sof_trace_avail(sdev, pos, buffer_size); - - /* data immediately available */ - if (ret) - return ret; - - if (sdev->dtrace_state != SOF_DTRACE_ENABLED && sdev->dtrace_draining) { - /* - * tracing has ended and all traces have been - * read by client, return EOF - */ - sdev->dtrace_draining = false; - return 0; - } - - /* wait for available trace data from FW */ - init_waitqueue_entry(&wait, current); - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&sdev->trace_sleep, &wait); - - if (!signal_pending(current)) { - /* set timeout to max value, no error code */ - schedule_timeout(MAX_SCHEDULE_TIMEOUT); - } - remove_wait_queue(&sdev->trace_sleep, &wait); - - return sof_trace_avail(sdev, pos, buffer_size); -} - -static ssize_t sof_dfsentry_trace_read(struct file *file, char __user *buffer, - size_t count, loff_t *ppos) -{ - struct snd_sof_dfsentry *dfse = file->private_data; - struct snd_sof_dev *sdev = dfse->sdev; - unsigned long rem; - loff_t lpos = *ppos; - size_t avail, buffer_size = dfse->size; - u64 lpos_64; - - /* make sure we know about any failures on the DSP side */ - sdev->dtrace_error = false; - - /* check pos and count */ - if (lpos < 0) - return -EINVAL; - if (!count) - return 0; - /* check for buffer wrap and count overflow */ - lpos_64 = lpos; - lpos = do_div(lpos_64, buffer_size); - - /* get available count based on current host offset */ - avail = sof_wait_trace_avail(sdev, lpos, buffer_size); - if (sdev->dtrace_error) { - dev_err(sdev->dev, "error: trace IO error\n"); - return -EIO; - } - - /* make sure count is <= avail */ - if (count > avail) - count = avail; - - /* - * make sure that all trace data is available for the CPU as the trace - * data buffer might be allocated from non consistent memory. - * Note: snd_dma_buffer_sync() is called for normal audio playback and - * capture streams also. - */ - snd_dma_buffer_sync(&sdev->dmatb, SNDRV_DMA_SYNC_CPU); - /* copy available trace data to debugfs */ - rem = copy_to_user(buffer, ((u8 *)(dfse->buf) + lpos), count); - if (rem) - return -EFAULT; - - *ppos += count; - - /* move debugfs reading position */ - return count; -} - -static int sof_dfsentry_trace_release(struct inode *inode, struct file *file) +int sof_fw_trace_init(struct snd_sof_dev *sdev) { - struct snd_sof_dfsentry *dfse = inode->i_private; - struct snd_sof_dev *sdev = dfse->sdev; - - /* avoid duplicate traces at next open */ - if (sdev->dtrace_state != SOF_DTRACE_ENABLED) - sdev->host_offset = 0; - - return 0; -} - -static const struct file_operations sof_dfs_trace_fops = { - .open = simple_open, - .read = sof_dfsentry_trace_read, - .llseek = default_llseek, - .release = sof_dfsentry_trace_release, -}; - -static int trace_debugfs_create(struct snd_sof_dev *sdev) -{ - struct snd_sof_dfsentry *dfse; - int ret; - - if (!sdev) - return -EINVAL; - - ret = trace_debugfs_filter_create(sdev); - if (ret < 0) - dev_err(sdev->dev, "error: fail in %s, %d", __func__, ret); - - dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); - if (!dfse) - return -ENOMEM; - - dfse->type = SOF_DFSENTRY_TYPE_BUF; - dfse->buf = sdev->dmatb.area; - dfse->size = sdev->dmatb.bytes; - dfse->sdev = sdev; - - debugfs_create_file("trace", 0444, sdev->debugfs_root, dfse, - &sof_dfs_trace_fops); - - return 0; -} - -static int snd_sof_enable_trace(struct snd_sof_dev *sdev) -{ - struct sof_ipc_fw_ready *ready = &sdev->fw_ready; - struct sof_ipc_fw_version *v = &ready->version; - struct sof_ipc_dma_trace_params_ext params; - struct sof_ipc_reply ipc_reply; - int ret; - - if (!sdev->fw_trace_is_supported) - return 0; - - if (sdev->dtrace_state == SOF_DTRACE_ENABLED || !sdev->dma_trace_pages) - return -EINVAL; - - if (sdev->dtrace_state == SOF_DTRACE_STOPPED) - goto start; - - /* set IPC parameters */ - params.hdr.cmd = SOF_IPC_GLB_TRACE_MSG; - /* PARAMS_EXT is only supported from ABI 3.7.0 onwards */ - if (v->abi_version >= SOF_ABI_VER(3, 7, 0)) { - params.hdr.size = sizeof(struct sof_ipc_dma_trace_params_ext); - params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS_EXT; - params.timestamp_ns = ktime_get(); /* in nanosecond */ - } else { - params.hdr.size = sizeof(struct sof_ipc_dma_trace_params); - params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS; - } - params.buffer.phy_addr = sdev->dmatp.addr; - params.buffer.size = sdev->dmatb.bytes; - params.buffer.pages = sdev->dma_trace_pages; - params.stream_tag = 0; - - sdev->host_offset = 0; - sdev->dtrace_draining = false; - - ret = snd_sof_dma_trace_init(sdev, ¶ms); - if (ret < 0) { - dev_err(sdev->dev, - "error: fail in snd_sof_dma_trace_init %d\n", ret); - return ret; - } - dev_dbg(sdev->dev, "%s: stream_tag: %d\n", __func__, params.stream_tag); - - /* send IPC to the DSP */ - ret = sof_ipc_tx_message(sdev->ipc, ¶ms, sizeof(params), &ipc_reply, sizeof(ipc_reply)); - if (ret < 0) { - dev_err(sdev->dev, - "error: can't set params for DMA for trace %d\n", ret); - goto trace_release; - } - -start: - ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_START); - if (ret < 0) { - dev_err(sdev->dev, - "error: snd_sof_dma_trace_trigger: start: %d\n", ret); - goto trace_release; - } - - sdev->dtrace_state = SOF_DTRACE_ENABLED; - - return 0; - -trace_release: - snd_sof_dma_trace_release(sdev); - return ret; -} - -int snd_sof_init_trace(struct snd_sof_dev *sdev) -{ - int ret; - - /* dtrace is only supported with SOF_IPC */ - if (sdev->pdata->ipc_type != SOF_IPC) + if (!sdev->ipc->ops->fw_tracing) { + dev_info(sdev->dev, "Firmware tracing is not available\n"); sdev->fw_trace_is_supported = false; - if (!sdev->fw_trace_is_supported) return 0; - - /* set false before start initialization */ - sdev->dtrace_state = SOF_DTRACE_DISABLED; - - /* allocate trace page table buffer */ - ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, - PAGE_SIZE, &sdev->dmatp); - if (ret < 0) { - dev_err(sdev->dev, - "error: can't alloc page table for trace %d\n", ret); - return ret; - } - - /* allocate trace data buffer */ - ret = snd_dma_alloc_dir_pages(SNDRV_DMA_TYPE_DEV_SG, sdev->dev, - DMA_FROM_DEVICE, DMA_BUF_SIZE_FOR_TRACE, - &sdev->dmatb); - if (ret < 0) { - dev_err(sdev->dev, - "error: can't alloc buffer for trace %d\n", ret); - goto page_err; - } - - /* create compressed page table for audio firmware */ - ret = snd_sof_create_page_table(sdev->dev, &sdev->dmatb, - sdev->dmatp.area, sdev->dmatb.bytes); - if (ret < 0) - goto table_err; - - sdev->dma_trace_pages = ret; - dev_dbg(sdev->dev, "%s: dma_trace_pages: %d\n", - __func__, sdev->dma_trace_pages); - - if (sdev->first_boot) { - ret = trace_debugfs_create(sdev); - if (ret < 0) - goto table_err; } - init_waitqueue_head(&sdev->trace_sleep); - - ret = snd_sof_enable_trace(sdev); - if (ret < 0) - goto table_err; - - return 0; -table_err: - sdev->dma_trace_pages = 0; - snd_dma_free_pages(&sdev->dmatb); -page_err: - snd_dma_free_pages(&sdev->dmatp); - return ret; + return sdev->ipc->ops->fw_tracing->init(sdev); } -EXPORT_SYMBOL(snd_sof_init_trace); -int snd_sof_trace_update_pos(struct snd_sof_dev *sdev, - struct sof_ipc_dma_trace_posn *posn) +void sof_fw_trace_free(struct snd_sof_dev *sdev) { - if (!sdev->fw_trace_is_supported) - return 0; - - if (sdev->dtrace_state == SOF_DTRACE_ENABLED && - sdev->host_offset != posn->host_offset) { - sdev->host_offset = posn->host_offset; - wake_up(&sdev->trace_sleep); - } - - if (posn->overflow != 0) - dev_err(sdev->dev, - "error: DSP trace buffer overflow %u bytes. Total messages %d\n", - posn->overflow, posn->messages); + if (!sdev->fw_trace_is_supported || !sdev->ipc->ops->fw_tracing) + return; - return 0; + if (sdev->ipc->ops->fw_tracing->free) + sdev->ipc->ops->fw_tracing->free(sdev); } -/* an error has occurred within the DSP that prevents further trace */ -void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev) +void sof_fw_trace_fw_crashed(struct snd_sof_dev *sdev) { if (!sdev->fw_trace_is_supported) return; - if (sdev->dtrace_state == SOF_DTRACE_ENABLED) { - sdev->dtrace_error = true; - wake_up(&sdev->trace_sleep); - } + if (sdev->ipc->ops->fw_tracing->fw_crashed) + sdev->ipc->ops->fw_tracing->fw_crashed(sdev); } -EXPORT_SYMBOL(snd_sof_trace_notify_for_error); -static void snd_sof_release_trace(struct snd_sof_dev *sdev, bool only_stop) +void sof_fw_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state) { - struct sof_ipc_fw_ready *ready = &sdev->fw_ready; - struct sof_ipc_fw_version *v = &ready->version; - struct sof_ipc_cmd_hdr hdr; - struct sof_ipc_reply ipc_reply; - int ret; - - if (!sdev->fw_trace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED) + if (!sdev->fw_trace_is_supported) return; - ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_STOP); - if (ret < 0) - dev_err(sdev->dev, - "error: snd_sof_dma_trace_trigger: stop: %d\n", ret); - sdev->dtrace_state = SOF_DTRACE_STOPPED; - - /* - * stop and free trace DMA in the DSP. TRACE_DMA_FREE is only supported from - * ABI 3.20.0 onwards - */ - if (v->abi_version >= SOF_ABI_VER(3, 20, 0)) { - hdr.size = sizeof(hdr); - hdr.cmd = SOF_IPC_GLB_TRACE_MSG | SOF_IPC_TRACE_DMA_FREE; - - ret = sof_ipc_tx_message(sdev->ipc, &hdr, hdr.size, - &ipc_reply, sizeof(ipc_reply)); - if (ret < 0) - dev_err(sdev->dev, "DMA_TRACE_FREE failed with error: %d\n", ret); - } - - if (only_stop) - goto out; - - ret = snd_sof_dma_trace_release(sdev); - if (ret < 0) - dev_err(sdev->dev, - "error: fail in snd_sof_dma_trace_release %d\n", ret); - - sdev->dtrace_state = SOF_DTRACE_DISABLED; - -out: - sdev->dtrace_draining = true; - wake_up(&sdev->trace_sleep); + sdev->ipc->ops->fw_tracing->suspend(sdev, pm_state); } -void snd_sof_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state) -{ - snd_sof_release_trace(sdev, pm_state.event == SOF_DSP_PM_D0); -} -EXPORT_SYMBOL(snd_sof_trace_suspend); - -int snd_sof_trace_resume(struct snd_sof_dev *sdev) -{ - return snd_sof_enable_trace(sdev); -} -EXPORT_SYMBOL(snd_sof_trace_resume); - -void snd_sof_free_trace(struct snd_sof_dev *sdev) +int sof_fw_trace_resume(struct snd_sof_dev *sdev) { if (!sdev->fw_trace_is_supported) - return; - - /* release trace */ - snd_sof_release_trace(sdev, false); + return 0; - if (sdev->dma_trace_pages) { - snd_dma_free_pages(&sdev->dmatb); - snd_dma_free_pages(&sdev->dmatp); - sdev->dma_trace_pages = 0; - } + return sdev->ipc->ops->fw_tracing->resume(sdev); } -EXPORT_SYMBOL(snd_sof_free_trace); From patchwork Mon May 16 10:47:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 573458 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 976C4C433EF for ; Mon, 16 May 2022 10:49:40 +0000 (UTC) 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 B409E16A4; Mon, 16 May 2022 12:48:48 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B409E16A4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698178; bh=Zwje4zxU2xeTBuAe3WDdJzhLGMj6TakhH0SrNvXIN/U=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=hrO4fqJVLMIxFlEw3F0vMxRQuJZni1tOLJ72AAnl4fqRgWHA77vDTCrbXYbj0rRq+ FlIKdIiwFFG+MawbRyibS7nqhGys9mcMVHPFJg7NNDS/yt2Azjm5zDlUVb7KfNtJaw fpMzOmw+VXGPXtqGxYv/0IVk92AkIieSdb9YOuPw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id DE113F80525; Mon, 16 May 2022 12:47:40 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 49A49F8051F; Mon, 16 May 2022 12:47:37 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 89AD0F801D5 for ; Mon, 16 May 2022 12:47:26 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 89AD0F801D5 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="nmGByThb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698047; x=1684234047; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Zwje4zxU2xeTBuAe3WDdJzhLGMj6TakhH0SrNvXIN/U=; b=nmGByThbHY62ybpJJLXULJRbenm1koTnhDow8uo4yNCREsBUyUFH79TJ 0LEupQpQVDqv6+IT5obbTarSZWxfBbW3sLzVinK3sOdxCePxDcDCqggPx wjrjC1dJuI14tpkHi0YnxMv5L7D6PpdOnM5fRvPqJMMsLdFH/8HpgrcoE s7aM5nbAmX5PCtkVX8CqL1xm38HGUemcaGbTsSpSG0hwPHXH8bIEKnqYV TLMXvMhQUl8h8fQ9Ih9DT2vCk/8aQ9Iv2x05QR2qED6JfmO4E1ytMVf7Z ojgBEUx53tArsTFokWBL5Lle9jajIvPX0pDEMIw1zpJJRUDNNbmWlkSVk Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853253" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853253" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:47:01 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459818" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:46:58 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 5/8] ASoC: SOF: ipc3-dtrace: Move host ops wrappers from generic header to private Date: Mon, 16 May 2022 13:47:08 +0300 Message-Id: <20220516104711.26115-6-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Move the snd_sof_dma_trace_* ops wrappers from ops.h to ipc3-priv.h since they are not used outside of IPC3 code. While moving, rename them to sof_dtrace_host_* Signed-off-by: Peter Ujfalusi Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan --- sound/soc/sof/ipc3-dtrace.c | 10 +++++----- sound/soc/sof/ipc3-priv.h | 32 ++++++++++++++++++++++++++++++++ sound/soc/sof/ops.h | 26 -------------------------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 0bc3ad586d23..63132baaaa5a 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -412,7 +412,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) sdev->host_offset = 0; sdev->dtrace_draining = false; - ret = snd_sof_dma_trace_init(sdev, ¶ms); + ret = sof_dtrace_host_init(sdev, ¶ms); if (ret < 0) { dev_err(sdev->dev, "Host dtrace init failed: %d\n", ret); return ret; @@ -427,7 +427,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) } start: - ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_START); + ret = sof_dtrace_host_trigger(sdev, SNDRV_PCM_TRIGGER_START); if (ret < 0) { dev_err(sdev->dev, "Host dtrace trigger start failed: %d\n", ret); goto trace_release; @@ -438,7 +438,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) return 0; trace_release: - snd_sof_dma_trace_release(sdev); + sof_dtrace_host_release(sdev); return ret; } @@ -541,7 +541,7 @@ static void ipc3_dtrace_release(struct snd_sof_dev *sdev, bool only_stop) if (!sdev->fw_trace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED) return; - ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_STOP); + ret = sof_dtrace_host_trigger(sdev, SNDRV_PCM_TRIGGER_STOP); if (ret < 0) dev_err(sdev->dev, "Host dtrace trigger stop failed: %d\n", ret); sdev->dtrace_state = SOF_DTRACE_STOPPED; @@ -563,7 +563,7 @@ static void ipc3_dtrace_release(struct snd_sof_dev *sdev, bool only_stop) if (only_stop) goto out; - ret = snd_sof_dma_trace_release(sdev); + ret = sof_dtrace_host_release(sdev); if (ret < 0) dev_err(sdev->dev, "Host dtrace release failed %d\n", ret); diff --git a/sound/soc/sof/ipc3-priv.h b/sound/soc/sof/ipc3-priv.h index bb9cb0678686..21f0bd20323f 100644 --- a/sound/soc/sof/ipc3-priv.h +++ b/sound/soc/sof/ipc3-priv.h @@ -29,4 +29,36 @@ int sof_ipc3_validate_fw_version(struct snd_sof_dev *sdev); int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, struct sof_ipc_dma_trace_posn *posn); +/* dtrace platform callback wrappers */ +static inline int sof_dtrace_host_init(struct snd_sof_dev *sdev, + struct sof_ipc_dma_trace_params_ext *dtrace_params) +{ + struct snd_sof_dsp_ops *dsp_ops = sdev->pdata->desc->ops; + + if (dsp_ops->trace_init) + return dsp_ops->trace_init(sdev, dtrace_params); + + return 0; +} + +static inline int sof_dtrace_host_release(struct snd_sof_dev *sdev) +{ + struct snd_sof_dsp_ops *dsp_ops = sdev->pdata->desc->ops; + + if (dsp_ops->trace_release) + return dsp_ops->trace_release(sdev); + + return 0; +} + +static inline int sof_dtrace_host_trigger(struct snd_sof_dev *sdev, int cmd) +{ + struct snd_sof_dsp_ops *dsp_ops = sdev->pdata->desc->ops; + + if (dsp_ops->trace_trigger) + return dsp_ops->trace_trigger(sdev, cmd); + + return 0; +} + #endif diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index aa64e3bd645f..b79ae4f66eba 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -375,32 +375,6 @@ static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev, return sof_ops(sdev)->send_msg(sdev, msg); } -/* host DMA trace */ -static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev, - struct sof_ipc_dma_trace_params_ext *dtrace_params) -{ - if (sof_ops(sdev)->trace_init) - return sof_ops(sdev)->trace_init(sdev, dtrace_params); - - return 0; -} - -static inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev) -{ - if (sof_ops(sdev)->trace_release) - return sof_ops(sdev)->trace_release(sdev); - - return 0; -} - -static inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd) -{ - if (sof_ops(sdev)->trace_trigger) - return sof_ops(sdev)->trace_trigger(sdev, cmd); - - return 0; -} - /* host PCM ops */ static inline int snd_sof_pcm_platform_open(struct snd_sof_dev *sdev, From patchwork Mon May 16 10:47:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 573457 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 643F5C433EF for ; Mon, 16 May 2022 10:50:12 +0000 (UTC) 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 9870516B0; Mon, 16 May 2022 12:49:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9870516B0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698210; bh=oeLzRuEtYq7MBvwQOZoFG8mmvTfooDe2+nL6Z6Ba0nY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=fE6TEwTlr54mRSAwBuT7ltnSPVdr+hraFdOWmSmQ4kEuraXxf9ym77iWTmIyiKpDX YiRXa9QeDJRk++DT6yhTn3gGGyKXI0rZCFwApUup6m1gXzKgl/wPJwjfl4iCV8Ov0S dQ4UbzcgXbuSso5wkBjU2YQiwb2mtoc8oT8FH3wE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 0941EF80533; Mon, 16 May 2022 12:47:42 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id CDF5EF80524; Mon, 16 May 2022 12:47:37 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 6CD4CF80171 for ; Mon, 16 May 2022 12:47:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6CD4CF80171 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ESdacAOn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698049; x=1684234049; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oeLzRuEtYq7MBvwQOZoFG8mmvTfooDe2+nL6Z6Ba0nY=; b=ESdacAOnpzjyr9AQnfUcQYk9aDcGLQJgjV0fPbwB9pVOt0Ts8Yf+KcoJ 5SvR82OsZo41C9zjkHu3YNvQmWtEVK6cVT6tEF4J9w3DM6+czS8F2JYIE EnPulL/mvPAxnL3nUHJKDyXonmn8x8Bd5d1zB1+kWNDVbvSjB0GGHQUrk XMXjfEfBPfGaiPsCAlAOL6NQJtJvf9FCz2j+Rg+mA/FsOd4rQ+kcCK5Lo M3rv4nuJ9vM/H34QjSskeYpkBawxIBZfDvjJmaEa393dM9Vj95719Rfx3 hX0NBuzSVFORlHxxVdHjM6AWBIdT+T8K2fm0bz7cjT5YvUbrrsESRBPkG Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853257" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853257" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:47:03 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459828" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:47:01 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 6/8] ASoC: SOF: Modify the host trace_init parameter list to include dmab Date: Mon, 16 May 2022 13:47:09 +0300 Message-Id: <20220516104711.26115-7-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Stop host code (AMD, Intel) to access sdev->dmatb directly. Modify the trace_init prototype to include the pointer to a struct snd_dma_buffer. The ipc3-dtrace passes for now the pointer to sdev->dmatb, but the aim is to move all tracing related runtime information local to a trace implementation. Signed-off-by: Peter Ujfalusi Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan --- sound/soc/sof/amd/acp-trace.c | 4 ++-- sound/soc/sof/amd/acp.h | 2 +- sound/soc/sof/intel/hda-trace.c | 4 ++-- sound/soc/sof/intel/hda.h | 2 +- sound/soc/sof/ipc3-dtrace.c | 2 +- sound/soc/sof/ipc3-priv.h | 3 ++- sound/soc/sof/sof-priv.h | 3 ++- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sound/soc/sof/amd/acp-trace.c b/sound/soc/sof/amd/acp-trace.c index 903b6cc3dda3..c9482b27cbe3 100644 --- a/sound/soc/sof/amd/acp-trace.c +++ b/sound/soc/sof/amd/acp-trace.c @@ -34,7 +34,7 @@ int acp_sof_trace_release(struct snd_sof_dev *sdev) } EXPORT_SYMBOL_NS(acp_sof_trace_release, SND_SOC_SOF_AMD_COMMON); -int acp_sof_trace_init(struct snd_sof_dev *sdev, +int acp_sof_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, struct sof_ipc_dma_trace_params_ext *dtrace_params) { struct acp_dsp_stream *stream; @@ -46,7 +46,7 @@ int acp_sof_trace_init(struct snd_sof_dev *sdev, if (!stream) return -ENODEV; - stream->dmab = &sdev->dmatb; + stream->dmab = dmab; stream->num_pages = NUM_PAGES; ret = acp_dsp_stream_config(sdev, stream); diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h index de526a1bce13..291b44c54bcc 100644 --- a/sound/soc/sof/amd/acp.h +++ b/sound/soc/sof/amd/acp.h @@ -212,7 +212,7 @@ extern struct snd_sof_dsp_ops sof_renoir_ops; int snd_amd_acp_find_config(struct pci_dev *pci); /* Trace */ -int acp_sof_trace_init(struct snd_sof_dev *sdev, +int acp_sof_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, struct sof_ipc_dma_trace_params_ext *dtrace_params); int acp_sof_trace_release(struct snd_sof_dev *sdev); diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index 755ef1d835e0..cbb9bd7770e6 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -36,7 +36,7 @@ static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev, struct snd_dma_buffer return ret; } -int hda_dsp_trace_init(struct snd_sof_dev *sdev, +int hda_dsp_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, struct sof_ipc_dma_trace_params_ext *dtrace_params) { struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; @@ -57,7 +57,7 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, * initialize capture stream, set BDL address and return corresponding * stream tag which will be sent to the firmware by IPC message. */ - ret = hda_dsp_trace_prepare(sdev, &sdev->dmatb); + ret = hda_dsp_trace_prepare(sdev, dmab); if (ret < 0) { dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret); hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 535791c7d187..3e0f7b0c586a 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -658,7 +658,7 @@ static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; } /* * Trace Control. */ -int hda_dsp_trace_init(struct snd_sof_dev *sdev, +int hda_dsp_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, struct sof_ipc_dma_trace_params_ext *dtrace_params); int hda_dsp_trace_release(struct snd_sof_dev *sdev); int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd); diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 63132baaaa5a..91a2792b9beb 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -412,7 +412,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) sdev->host_offset = 0; sdev->dtrace_draining = false; - ret = sof_dtrace_host_init(sdev, ¶ms); + ret = sof_dtrace_host_init(sdev, &sdev->dmatb, ¶ms); if (ret < 0) { dev_err(sdev->dev, "Host dtrace init failed: %d\n", ret); return ret; diff --git a/sound/soc/sof/ipc3-priv.h b/sound/soc/sof/ipc3-priv.h index 21f0bd20323f..f5044202f3c5 100644 --- a/sound/soc/sof/ipc3-priv.h +++ b/sound/soc/sof/ipc3-priv.h @@ -31,12 +31,13 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, /* dtrace platform callback wrappers */ static inline int sof_dtrace_host_init(struct snd_sof_dev *sdev, + struct snd_dma_buffer *dmatb, struct sof_ipc_dma_trace_params_ext *dtrace_params) { struct snd_sof_dsp_ops *dsp_ops = sdev->pdata->desc->ops; if (dsp_ops->trace_init) - return dsp_ops->trace_init(sdev, dtrace_params); + return dsp_ops->trace_init(sdev, dmatb, dtrace_params); return 0; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 61ef739461f0..b176fc7e346c 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -254,8 +254,9 @@ struct snd_sof_dsp_ops { size_t size, const char *name, enum sof_debugfs_access_type access_type); /* optional */ - /* host DMA trace initialization */ + /* host DMA trace (IPC3) */ int (*trace_init)(struct snd_sof_dev *sdev, + struct snd_dma_buffer *dmatb, struct sof_ipc_dma_trace_params_ext *dtrace_params); /* optional */ int (*trace_release)(struct snd_sof_dev *sdev); /* optional */ int (*trace_trigger)(struct snd_sof_dev *sdev, From patchwork Mon May 16 10:47:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 572991 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 103FCC433F5 for ; Mon, 16 May 2022 10:50:25 +0000 (UTC) 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 390AF1697; Mon, 16 May 2022 12:49:33 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 390AF1697 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698223; bh=6l3DLTM1fWF79oYbq6YMDLUQs3o2FQiFa3fJrn9touk=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=YN20JGeFQjV9EX4r5tT/+n7sxsJ3EcUGYtw79+6sefMNpmBp5PfO/BgrnMLicB0W3 xYc/fS2PrkmBM7WOAQirXthoCf3prWjyxxkvbJVmdPTMP5trY3YhG5Bbi7utcWxYbN 76DrtHijViM/mqugh1cxfES0550TrgkfWm2/SmXw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7F2CAF80537; Mon, 16 May 2022 12:47:42 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 80657F80520; Mon, 16 May 2022 12:47:39 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 03E71F800D8 for ; Mon, 16 May 2022 12:47:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 03E71F800D8 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="OQghTAyh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698051; x=1684234051; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6l3DLTM1fWF79oYbq6YMDLUQs3o2FQiFa3fJrn9touk=; b=OQghTAyhNRQdbtnhPfrULB1huyBYlA6c/w7b8l0KuJLJvgUFaHntaUqu VD7nRHHDKkvnSJtP1rBAADdm5Vxfv12IglBZVGqdodV/BpgRlUEVm+/aZ q3dXAWRyP/0DON6yjq9k4KjmxbE1b/r0I8fZAHRwMtCGIpQ+CyhaMMwz0 Qn5YfPBfNe9eCJpS0JJ/pmCCbU6JMg0ecOrUkZgH5TDOjiTZCbD49+3lq iVIMcWQOn/WpTBaxRgJxT50unCwW91aHhC7KToIHs2Km1h5VoXsdzlp4y /UoMEylSM32FQyFWY7K5N9OJJVBClcJLPalEyxYCiK5HOlpVuq+HVAPsV Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853260" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853260" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:47:06 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459845" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:47:03 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 7/8] ASoC: SOF: Introduce opaque storage of private data for firmware tracing Date: Mon, 16 May 2022 13:47:10 +0300 Message-Id: <20220516104711.26115-8-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Firmware tracing implementations can allocate and store their privately used data behind the fw_trace_pdata pointer instead of adding more members to struct snd_sof_dev. Signed-off-by: Peter Ujfalusi Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan --- sound/soc/sof/sof-priv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index b176fc7e346c..d8d81e1ec259 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -549,6 +549,7 @@ struct snd_sof_dev { /* firmwre tracing */ bool fw_trace_is_supported; /* set with Kconfig or module parameter */ + void *fw_trace_data; /* private data used by firmware tracing implementation */ /* DMA for Trace */ struct snd_dma_buffer dmatb; From patchwork Mon May 16 10:47:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 573456 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id E2CCCC433F5 for ; Mon, 16 May 2022 10:50:41 +0000 (UTC) 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 EA9BA1681; Mon, 16 May 2022 12:49:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EA9BA1681 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1652698240; bh=pxU/GCQ/1AXArwiD8r7gIVHtyJp8ogicckG6HqApsyQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=A8MZNniR9e8ZR0EBcZhkY/OZUha2ks9/Woa0xtun6ldiHlCTjEggsTjvSTr5preSd 5dpHehUE689BwSmUfH4NIPqiZ89EerCSjn17Mz7j1DJPES8ixu73SF2LqWI42rKWaD v+UesL8T1AsI/4qn8RHyXRL73PCKmnf9z6MeYsVk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 0D66DF8053B; Mon, 16 May 2022 12:47:43 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BE59AF80520; Mon, 16 May 2022 12:47:40 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 92EA9F8012F for ; Mon, 16 May 2022 12:47:29 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 92EA9F8012F Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ioBwNSDj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652698050; x=1684234050; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pxU/GCQ/1AXArwiD8r7gIVHtyJp8ogicckG6HqApsyQ=; b=ioBwNSDjg44QJb6ovU0zuYGfr0O49Q2tgYYJCZIih0XaScNKSDFBAUWY Ijfby5WVFKXflcCEeiIqarBRFgl1bye9/vlQ1xDOBoXDp9rlTKKOZcVP5 iEGc8IxY6L5VHmlWfPfsJZnTVSgI0xIPGV59NLETjWiNAr+s1xfdMRdoP 9T807xW18v2f7QPBj4RzqHMuOGyzdpY38C3fJ7vPM2WtL1btpjv0IcBLc cAD+IcWixh/LGP73wCGj00qjQC1yLDYB+tmP9LhVR7KoaCdweRFmorxx5 gqMULre3h+8nexZNQo6YTad8MPN+G27s7GmEMBkYt47G1NiSwH+shbV+m A==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="333853270" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="333853270" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:47:09 -0700 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="596459890" Received: from afialcko-mobl.ger.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.51.55]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 03:47:06 -0700 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org, pierre-louis.bossart@linux.intel.com, daniel.baluta@nxp.com, AjitKumar.Pandey@amd.com Subject: [PATCH 8/8] ASoC: SOF: ipc3-dtrace: Move dtrace related variables local from sof_dev Date: Mon, 16 May 2022 13:47:11 +0300 Message-Id: <20220516104711.26115-9-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> References: <20220516104711.26115-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ranjani.sridharan@linux.intel.com, kai.vehmanen@linux.intel.com 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The variables and structs for DMA trace can be moved local to ipc3-dtrace.c and the storage can be allocated dynamically, stored behind the fw_trace_data pointer. Signed-off-by: Peter Ujfalusi Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan --- sound/soc/sof/ipc3-dtrace.c | 142 +++++++++++++++++++++++------------- sound/soc/sof/sof-priv.h | 16 ---- 2 files changed, 93 insertions(+), 65 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 91a2792b9beb..b4e1343f9138 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -15,6 +15,23 @@ #define TRACE_FILTER_ELEMENTS_PER_ENTRY 4 #define TRACE_FILTER_MAX_CONFIG_STRING_LENGTH 1024 +enum sof_dtrace_state { + SOF_DTRACE_DISABLED, + SOF_DTRACE_STOPPED, + SOF_DTRACE_ENABLED, +}; + +struct sof_dtrace_priv { + struct snd_dma_buffer dmatb; + struct snd_dma_buffer dmatp; + int dma_trace_pages; + wait_queue_head_t trace_sleep; + u32 host_offset; + bool dtrace_error; + bool dtrace_draining; + enum sof_dtrace_state dtrace_state; +}; + static int trace_filter_append_elem(struct snd_sof_dev *sdev, u32 key, u32 value, struct sof_ipc_trace_filter_elem *elem_list, int capacity, int *counter) @@ -228,7 +245,8 @@ static int debugfs_create_trace_filter(struct snd_sof_dev *sdev) static size_t sof_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos, size_t buffer_size) { - loff_t host_offset = READ_ONCE(sdev->host_offset); + struct sof_dtrace_priv *priv = sdev->fw_trace_data; + loff_t host_offset = READ_ONCE(priv->host_offset); /* * If host offset is less than local pos, it means write pointer of @@ -248,32 +266,33 @@ static size_t sof_dtrace_avail(struct snd_sof_dev *sdev, static size_t sof_wait_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos, size_t buffer_size) { - wait_queue_entry_t wait; size_t ret = sof_dtrace_avail(sdev, pos, buffer_size); + struct sof_dtrace_priv *priv = sdev->fw_trace_data; + wait_queue_entry_t wait; /* data immediately available */ if (ret) return ret; - if (sdev->dtrace_state != SOF_DTRACE_ENABLED && sdev->dtrace_draining) { + if (priv->dtrace_state != SOF_DTRACE_ENABLED && priv->dtrace_draining) { /* * tracing has ended and all traces have been * read by client, return EOF */ - sdev->dtrace_draining = false; + priv->dtrace_draining = false; return 0; } /* wait for available trace data from FW */ init_waitqueue_entry(&wait, current); set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&sdev->trace_sleep, &wait); + add_wait_queue(&priv->trace_sleep, &wait); if (!signal_pending(current)) { /* set timeout to max value, no error code */ schedule_timeout(MAX_SCHEDULE_TIMEOUT); } - remove_wait_queue(&sdev->trace_sleep, &wait); + remove_wait_queue(&priv->trace_sleep, &wait); return sof_dtrace_avail(sdev, pos, buffer_size); } @@ -283,13 +302,14 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer, { struct snd_sof_dfsentry *dfse = file->private_data; struct snd_sof_dev *sdev = dfse->sdev; + struct sof_dtrace_priv *priv = sdev->fw_trace_data; unsigned long rem; loff_t lpos = *ppos; size_t avail, buffer_size = dfse->size; u64 lpos_64; /* make sure we know about any failures on the DSP side */ - sdev->dtrace_error = false; + priv->dtrace_error = false; /* check pos and count */ if (lpos < 0) @@ -303,7 +323,7 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer, /* get available count based on current host offset */ avail = sof_wait_dtrace_avail(sdev, lpos, buffer_size); - if (sdev->dtrace_error) { + if (priv->dtrace_error) { dev_err(sdev->dev, "trace IO error\n"); return -EIO; } @@ -318,7 +338,7 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer, * Note: snd_dma_buffer_sync() is called for normal audio playback and * capture streams also. */ - snd_dma_buffer_sync(&sdev->dmatb, SNDRV_DMA_SYNC_CPU); + snd_dma_buffer_sync(&priv->dmatb, SNDRV_DMA_SYNC_CPU); /* copy available trace data to debugfs */ rem = copy_to_user(buffer, ((u8 *)(dfse->buf) + lpos), count); if (rem) @@ -334,10 +354,11 @@ static int dfsentry_dtrace_release(struct inode *inode, struct file *file) { struct snd_sof_dfsentry *dfse = inode->i_private; struct snd_sof_dev *sdev = dfse->sdev; + struct sof_dtrace_priv *priv = sdev->fw_trace_data; /* avoid duplicate traces at next open */ - if (sdev->dtrace_state != SOF_DTRACE_ENABLED) - sdev->host_offset = 0; + if (priv->dtrace_state != SOF_DTRACE_ENABLED) + priv->host_offset = 0; return 0; } @@ -351,12 +372,15 @@ static const struct file_operations sof_dfs_dtrace_fops = { static int debugfs_create_dtrace(struct snd_sof_dev *sdev) { + struct sof_dtrace_priv *priv; struct snd_sof_dfsentry *dfse; int ret; if (!sdev) return -EINVAL; + priv = sdev->fw_trace_data; + ret = debugfs_create_trace_filter(sdev); if (ret < 0) dev_warn(sdev->dev, "failed to create filter debugfs file: %d", ret); @@ -366,8 +390,8 @@ static int debugfs_create_dtrace(struct snd_sof_dev *sdev) return -ENOMEM; dfse->type = SOF_DFSENTRY_TYPE_BUF; - dfse->buf = sdev->dmatb.area; - dfse->size = sdev->dmatb.bytes; + dfse->buf = priv->dmatb.area; + dfse->size = priv->dmatb.bytes; dfse->sdev = sdev; debugfs_create_file("trace", 0444, sdev->debugfs_root, dfse, @@ -378,6 +402,7 @@ static int debugfs_create_dtrace(struct snd_sof_dev *sdev) static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) { + struct sof_dtrace_priv *priv = sdev->fw_trace_data; struct sof_ipc_fw_ready *ready = &sdev->fw_ready; struct sof_ipc_fw_version *v = &ready->version; struct sof_ipc_dma_trace_params_ext params; @@ -387,10 +412,10 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) if (!sdev->fw_trace_is_supported) return 0; - if (sdev->dtrace_state == SOF_DTRACE_ENABLED || !sdev->dma_trace_pages) + if (priv->dtrace_state == SOF_DTRACE_ENABLED || !priv->dma_trace_pages) return -EINVAL; - if (sdev->dtrace_state == SOF_DTRACE_STOPPED) + if (priv->dtrace_state == SOF_DTRACE_STOPPED) goto start; /* set IPC parameters */ @@ -404,15 +429,15 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) params.hdr.size = sizeof(struct sof_ipc_dma_trace_params); params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS; } - params.buffer.phy_addr = sdev->dmatp.addr; - params.buffer.size = sdev->dmatb.bytes; - params.buffer.pages = sdev->dma_trace_pages; + params.buffer.phy_addr = priv->dmatp.addr; + params.buffer.size = priv->dmatb.bytes; + params.buffer.pages = priv->dma_trace_pages; params.stream_tag = 0; - sdev->host_offset = 0; - sdev->dtrace_draining = false; + priv->host_offset = 0; + priv->dtrace_draining = false; - ret = sof_dtrace_host_init(sdev, &sdev->dmatb, ¶ms); + ret = sof_dtrace_host_init(sdev, &priv->dmatb, ¶ms); if (ret < 0) { dev_err(sdev->dev, "Host dtrace init failed: %d\n", ret); return ret; @@ -433,7 +458,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) goto trace_release; } - sdev->dtrace_state = SOF_DTRACE_ENABLED; + priv->dtrace_state = SOF_DTRACE_ENABLED; return 0; @@ -444,18 +469,30 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) static int ipc3_dtrace_init(struct snd_sof_dev *sdev) { + struct sof_dtrace_priv *priv; int ret; /* dtrace is only supported with SOF_IPC */ if (sdev->pdata->ipc_type != SOF_IPC) return -EOPNOTSUPP; + if (sdev->fw_trace_data) { + dev_err(sdev->dev, "fw_trace_data has been already allocated\n"); + return -EBUSY; + } + + priv = devm_kzalloc(sdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + sdev->fw_trace_data = priv; + /* set false before start initialization */ - sdev->dtrace_state = SOF_DTRACE_DISABLED; + priv->dtrace_state = SOF_DTRACE_DISABLED; /* allocate trace page table buffer */ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, - PAGE_SIZE, &sdev->dmatp); + PAGE_SIZE, &priv->dmatp); if (ret < 0) { dev_err(sdev->dev, "can't alloc page table for trace %d\n", ret); return ret; @@ -464,21 +501,21 @@ static int ipc3_dtrace_init(struct snd_sof_dev *sdev) /* allocate trace data buffer */ ret = snd_dma_alloc_dir_pages(SNDRV_DMA_TYPE_DEV_SG, sdev->dev, DMA_FROM_DEVICE, DMA_BUF_SIZE_FOR_TRACE, - &sdev->dmatb); + &priv->dmatb); if (ret < 0) { dev_err(sdev->dev, "can't alloc buffer for trace %d\n", ret); goto page_err; } /* create compressed page table for audio firmware */ - ret = snd_sof_create_page_table(sdev->dev, &sdev->dmatb, - sdev->dmatp.area, sdev->dmatb.bytes); + ret = snd_sof_create_page_table(sdev->dev, &priv->dmatb, + priv->dmatp.area, priv->dmatb.bytes); if (ret < 0) goto table_err; - sdev->dma_trace_pages = ret; + priv->dma_trace_pages = ret; dev_dbg(sdev->dev, "%s: dma_trace_pages: %d\n", __func__, - sdev->dma_trace_pages); + priv->dma_trace_pages); if (sdev->first_boot) { ret = debugfs_create_dtrace(sdev); @@ -486,7 +523,7 @@ static int ipc3_dtrace_init(struct snd_sof_dev *sdev) goto table_err; } - init_waitqueue_head(&sdev->trace_sleep); + init_waitqueue_head(&priv->trace_sleep); ret = ipc3_dtrace_enable(sdev); if (ret < 0) @@ -494,23 +531,25 @@ static int ipc3_dtrace_init(struct snd_sof_dev *sdev) return 0; table_err: - sdev->dma_trace_pages = 0; - snd_dma_free_pages(&sdev->dmatb); + priv->dma_trace_pages = 0; + snd_dma_free_pages(&priv->dmatb); page_err: - snd_dma_free_pages(&sdev->dmatp); + snd_dma_free_pages(&priv->dmatp); return ret; } int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, struct sof_ipc_dma_trace_posn *posn) { + struct sof_dtrace_priv *priv = sdev->fw_trace_data; + if (!sdev->fw_trace_is_supported) return 0; - if (sdev->dtrace_state == SOF_DTRACE_ENABLED && - sdev->host_offset != posn->host_offset) { - sdev->host_offset = posn->host_offset; - wake_up(&sdev->trace_sleep); + if (priv->dtrace_state == SOF_DTRACE_ENABLED && + priv->host_offset != posn->host_offset) { + priv->host_offset = posn->host_offset; + wake_up(&priv->trace_sleep); } if (posn->overflow != 0) @@ -524,27 +563,30 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, /* an error has occurred within the DSP that prevents further trace */ static void ipc3_dtrace_fw_crashed(struct snd_sof_dev *sdev) { - if (sdev->dtrace_state == SOF_DTRACE_ENABLED) { - sdev->dtrace_error = true; - wake_up(&sdev->trace_sleep); + struct sof_dtrace_priv *priv = sdev->fw_trace_data; + + if (priv->dtrace_state == SOF_DTRACE_ENABLED) { + priv->dtrace_error = true; + wake_up(&priv->trace_sleep); } } static void ipc3_dtrace_release(struct snd_sof_dev *sdev, bool only_stop) { + struct sof_dtrace_priv *priv = sdev->fw_trace_data; struct sof_ipc_fw_ready *ready = &sdev->fw_ready; struct sof_ipc_fw_version *v = &ready->version; struct sof_ipc_cmd_hdr hdr; struct sof_ipc_reply ipc_reply; int ret; - if (!sdev->fw_trace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED) + if (!sdev->fw_trace_is_supported || priv->dtrace_state == SOF_DTRACE_DISABLED) return; ret = sof_dtrace_host_trigger(sdev, SNDRV_PCM_TRIGGER_STOP); if (ret < 0) dev_err(sdev->dev, "Host dtrace trigger stop failed: %d\n", ret); - sdev->dtrace_state = SOF_DTRACE_STOPPED; + priv->dtrace_state = SOF_DTRACE_STOPPED; /* * stop and free trace DMA in the DSP. TRACE_DMA_FREE is only supported from @@ -567,11 +609,11 @@ static void ipc3_dtrace_release(struct snd_sof_dev *sdev, bool only_stop) if (ret < 0) dev_err(sdev->dev, "Host dtrace release failed %d\n", ret); - sdev->dtrace_state = SOF_DTRACE_DISABLED; + priv->dtrace_state = SOF_DTRACE_DISABLED; out: - sdev->dtrace_draining = true; - wake_up(&sdev->trace_sleep); + priv->dtrace_draining = true; + wake_up(&priv->trace_sleep); } static void ipc3_dtrace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state) @@ -586,13 +628,15 @@ static int ipc3_dtrace_resume(struct snd_sof_dev *sdev) static void ipc3_dtrace_free(struct snd_sof_dev *sdev) { + struct sof_dtrace_priv *priv = sdev->fw_trace_data; + /* release trace */ ipc3_dtrace_release(sdev, false); - if (sdev->dma_trace_pages) { - snd_dma_free_pages(&sdev->dmatb); - snd_dma_free_pages(&sdev->dmatp); - sdev->dma_trace_pages = 0; + if (priv->dma_trace_pages) { + snd_dma_free_pages(&priv->dmatb); + snd_dma_free_pages(&priv->dmatp); + priv->dma_trace_pages = 0; } } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index d8d81e1ec259..9d7f53ff9c70 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -461,12 +461,6 @@ struct snd_sof_ipc { const struct sof_ipc_ops *ops; }; -enum sof_dtrace_state { - SOF_DTRACE_DISABLED, - SOF_DTRACE_STOPPED, - SOF_DTRACE_ENABLED, -}; - /* * SOF Device Level. */ @@ -551,16 +545,6 @@ struct snd_sof_dev { bool fw_trace_is_supported; /* set with Kconfig or module parameter */ void *fw_trace_data; /* private data used by firmware tracing implementation */ - /* DMA for Trace */ - struct snd_dma_buffer dmatb; - struct snd_dma_buffer dmatp; - int dma_trace_pages; - wait_queue_head_t trace_sleep; - u32 host_offset; - bool dtrace_error; - bool dtrace_draining; - enum sof_dtrace_state dtrace_state; - bool msi_enabled; /* DSP core context */