From patchwork Wed Aug 7 13:47:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 11082191 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3220A14E5 for ; Wed, 7 Aug 2019 13:49:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F0EF28A4C for ; Wed, 7 Aug 2019 13:49:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 135B028A51; Wed, 7 Aug 2019 13:49:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EECD828A4C for ; Wed, 7 Aug 2019 13:49:01 +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 1211784B; Wed, 7 Aug 2019 15:48:06 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 1211784B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1565185736; bh=pJLi/wJ/Om2azqmjM81dmHnSox/fYb+rW2A65Tt9dUo=; h=From:To:Date:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=JCOa5j0PeMulXouphcZuxrEqgl1IaSBeebPNIL2AntmmBkJzQmnopEgII0DwAF9Js NfbynVAxm5wV0EQ1bi4R8V8v3PiaZfOntHYPfU3mHgSXA8vZwvFJLU5oJkmtr82OCV zY7iRFLpXKI/x5GQnIBGCsLy9ru2ZgcU7+GEWqdI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 6F65BF800F3; Wed, 7 Aug 2019 15:48:04 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0B644F80290; Wed, 7 Aug 2019 15:48:03 +0200 (CEST) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (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 4F2D2F800F3 for ; Wed, 7 Aug 2019 15:47:57 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 4F2D2F800F3 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Aug 2019 06:47:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,357,1559545200"; d="scan'208";a="165325284" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by orsmga007.jf.intel.com with ESMTP; 07 Aug 2019 06:47:54 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Date: Wed, 7 Aug 2019 15:47:45 +0200 Message-Id: <20190807134745.1648-1-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 Cc: lgirdwood@gmail.com, Cezary Rojewski , broonie@kernel.org, tiwai@suse.com, pierre-louis.bossart@linux.intel.com Subject: [alsa-devel] [RESEND PATCH v3] ASoC: Intel: Skylake: large_config_get overhaul X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" X-Virus-Scanned: ClamAV using ClamSMTP LARGE_CONFIG_GET is among the most crucial IPCs. Host is expected to send single request first to obtain total payload size from received header's data_off_size. From then on, it loops for each frame exceeding inbox size until entire payload is read. If entire payload is contained within the very first frame, no looping is performed. LARGE_CONFIG_GET is a flexible IPC, it not only receives payload but may carry one with them to provide list of params DSP module should return info for. This behavior is usually reserved for vendors and IPC handler should not touch that content. To achieve that, simply pass provided payload and bytes to sst_ipc_tx_message_wait as a part of request. In current state, LARGE_CONFIG_GET message handler does nothing of that, in consequence making it dysfunctional. Overhaul said handler allowing rightful king of IPCs to return back on his throne - kingdom he shares with his twin brother: LARGE_CONFIG_SET. The looping has not been added in this update as payloads of such size do not exist in practice. Will need to create custom module specifically for that very case and test against it before that feature can be added. Signed-off-by: Cezary Rojewski --- sound/soc/intel/skylake/skl-messages.c | 3 +- sound/soc/intel/skylake/skl-sst-ipc.c | 54 +++++++++++--------------- sound/soc/intel/skylake/skl-sst-ipc.h | 3 +- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index e8cc710f092b..84f0e6f58eb5 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -1379,11 +1379,12 @@ int skl_get_module_params(struct skl_dev *skl, u32 *params, int size, u32 param_id, struct skl_module_cfg *mcfg) { struct skl_ipc_large_config_msg msg; + size_t bytes = size; msg.module_id = mcfg->id.module_id; msg.instance_id = mcfg->id.pvt_id; msg.param_data_size = size; msg.large_param_id = param_id; - return skl_ipc_get_large_config(&skl->ipc, &msg, params); + return skl_ipc_get_large_config(&skl->ipc, &msg, ¶ms, &bytes); } diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index a2b69a02aab2..9d269a5f8bd9 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c @@ -969,12 +969,17 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, - struct skl_ipc_large_config_msg *msg, u32 *param) + struct skl_ipc_large_config_msg *msg, + unsigned int **payload, size_t *bytes) { struct skl_ipc_header header = {0}; - struct sst_ipc_message request = {0}, reply = {0}; - int ret = 0; - size_t sz_remaining, rx_size, data_offset; + struct sst_ipc_message request, reply = {0}; + unsigned int *buf; + int ret; + + reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL); + if (!reply.data) + return -ENOMEM; header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); @@ -987,34 +992,21 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, header.extension |= IPC_FINAL_BLOCK(1); header.extension |= IPC_INITIAL_BLOCK(1); - sz_remaining = msg->param_data_size; - data_offset = 0; - - while (sz_remaining != 0) { - rx_size = sz_remaining > SKL_ADSP_W1_SZ - ? SKL_ADSP_W1_SZ : sz_remaining; - if (rx_size == sz_remaining) - header.extension |= IPC_FINAL_BLOCK(1); - - request.header = *(u64 *)(&header); - reply.data = ((char *)param) + data_offset; - reply.size = msg->param_data_size; - ret = sst_ipc_tx_message_wait(ipc, request, &reply); - if (ret < 0) { - dev_err(ipc->dev, - "ipc: get large config fail, err: %d\n", ret); - return ret; - } - sz_remaining -= rx_size; - data_offset = msg->param_data_size - sz_remaining; + request.header = *(u64 *)&header; + request.data = *payload; + request.size = *bytes; + reply.size = SKL_ADSP_W1_SZ; - /* clear the fields */ - header.extension &= IPC_INITIAL_BLOCK_CLEAR; - header.extension &= IPC_DATA_OFFSET_SZ_CLEAR; - /* fill the fields */ - header.extension |= IPC_INITIAL_BLOCK(1); - header.extension |= IPC_DATA_OFFSET_SZ(data_offset); - } + ret = sst_ipc_tx_message_wait(ipc, request, &reply); + if (ret < 0) + dev_err(ipc->dev, "ipc: get large config fail: %d\n", ret); + + reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK; + buf = krealloc(reply.data, reply.size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + *payload = buf; + *bytes = reply.size; return ret; } diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index 93af08cf41d2..a7ab2c589cc5 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h @@ -139,7 +139,8 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, struct skl_ipc_large_config_msg *msg, u32 *param); int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, - struct skl_ipc_large_config_msg *msg, u32 *param); + struct skl_ipc_large_config_msg *msg, + unsigned int **payload, size_t *bytes); int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, u8 dma_id, u8 table_id, bool wait);