From mboxrd@z Thu Jan 1 00:00:00 1970 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 4F3E5C433F5 for ; Fri, 4 Mar 2022 15:00:54 +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 9272D1B27; Fri, 4 Mar 2022 16:00:02 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9272D1B27 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1646406052; bh=N0Jahiz7vhPI3oW+M+kPlgXIhzUb0ctUA9JilxbRT6s=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=aNvvPUW5nhZ8+Orbz5WjE2/aZViqh1lDWd++CtaTHJmhxoIGmreGnQnS4huO88HZ4 h7IVIzFlRaxztLZpon1TXYf84sdSgMjJpqK28VXJ/SIyVMNlKTAnH/abyOUtUqehVZ Kd5os6gp+jHcQwFqJ58uEzQdcmSwDHgZb4587ZBU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 79423F80587; Fri, 4 Mar 2022 15:56:36 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id D3FFBF80588; Fri, 4 Mar 2022 15:56:34 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 46EDCF80571 for ; Fri, 4 Mar 2022 15:56:28 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 46EDCF80571 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="NPJqS6Zm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1646405789; x=1677941789; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=N0Jahiz7vhPI3oW+M+kPlgXIhzUb0ctUA9JilxbRT6s=; b=NPJqS6ZmLQ4EEp29yZCa+NvLbDpfAO7a5zbg/x8pDAjS6AgKbtV5PHSv x9u80oK1I/LPYhUoHmNg/zVkDesyWiHbcf9FHt+2HBjylaoWhkzcsTVSx BNOzmNcBWrMLmMepBKuPft3QLpFt3vKAbSLCUtcFW1DXEeD0oDipitmnw hTZTFJb85K3rRqQAUOeVkuXerrGWUX7puUUoy9aZmW+rNEKe50lo+U/6E YhjPc/xl+oqREtc4Lbm5NTbl7KG+p0CO0B2dDvmm1sH7kCL3oTK6eZCvl fDljnd5kEaI+gcCLP5yD562Ib0b5gxugrqyIiY5fFoQNvDoJWpWraijJH w==; X-IronPort-AV: E=McAfee;i="6200,9189,10276"; a="233949222" X-IronPort-AV: E=Sophos;i="5.90,155,1643702400"; d="scan'208";a="233949222" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2022 06:56:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,155,1643702400"; d="scan'208";a="609963530" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga004.fm.intel.com with ESMTP; 04 Mar 2022 06:56:24 -0800 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v3 13/17] ASoC: Intel: avs: Dynamic firmware resources management Date: Fri, 4 Mar 2022 15:57:51 +0100 Message-Id: <20220304145755.2844173-14-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220304145755.2844173-1-cezary.rojewski@intel.com> References: <20220304145755.2844173-1-cezary.rojewski@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Cezary Rojewski , rad@semihalf.com, upstream@semihalf.com, harshapriya.n@intel.com, tiwai@suse.com, pierre-louis.bossart@linux.intel.com, hdegoede@redhat.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, cujomalainey@chromium.org, lma@semihalf.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" Wrap elementary DSP-core operations and resource control into more complex handlers. This is done to reduce the number of invocations of wrapped operations throughout the driver as order of operations matters - most flows involve register manipulation and IPCs combined. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski --- sound/soc/intel/avs/avs.h | 10 +++ sound/soc/intel/avs/dsp.c | 170 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 02d7591d0eac..0034c075fa64 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -89,6 +89,7 @@ struct avs_dev { struct mutex modres_mutex; struct ida ppl_ida; struct list_head fw_list; + int *core_refs; struct completion fw_ready; }; @@ -205,4 +206,13 @@ int avs_request_firmware(struct avs_dev *adev, const struct firmware **fw_p, con void avs_release_last_firmware(struct avs_dev *adev); void avs_release_firmwares(struct avs_dev *adev); +int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id, + u8 core_id, u8 domain, void *param, u32 param_size, + u16 *instance_id); +void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u16 instance_id, + u8 ppl_instance_id, u8 core_id); +int avs_dsp_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority, + bool lp, u16 attributes, u8 *instance_id); +int avs_dsp_delete_pipeline(struct avs_dev *adev, u8 instance_id); + #endif /* __SOUND_SOC_INTEL_AVS_H */ diff --git a/sound/soc/intel/avs/dsp.c b/sound/soc/intel/avs/dsp.c index eb9d941fe6cf..5994d64d2468 100644 --- a/sound/soc/intel/avs/dsp.c +++ b/sound/soc/intel/avs/dsp.c @@ -104,4 +104,174 @@ int avs_dsp_core_disable(struct avs_dev *adev, u32 core_mask) return avs_dsp_op(adev, power, core_mask, false); } +static int avs_dsp_enable(struct avs_dev *adev, u32 core_mask) +{ + u32 mask; + int ret; + + ret = avs_dsp_core_enable(adev, core_mask); + if (ret < 0) + return ret; + + mask = core_mask & ~AVS_MAIN_CORE_MASK; + if (!mask) + /* + * without main core, fw is dead anyway + * so setting D0 for it is futile. + */ + return 0; + + ret = avs_ipc_set_dx(adev, mask, true); + return AVS_IPC_RET(ret); +} + +static int avs_dsp_disable(struct avs_dev *adev, u32 core_mask) +{ + int ret; + + ret = avs_ipc_set_dx(adev, core_mask, false); + if (ret) + return AVS_IPC_RET(ret); + + return avs_dsp_core_disable(adev, core_mask); +} + +static int avs_dsp_get_core(struct avs_dev *adev, u32 core_id) +{ + u32 mask; + int ret; + + mask = BIT_MASK(core_id); + if (mask == AVS_MAIN_CORE_MASK) + /* nothing to do for main core */ + return 0; + if (core_id >= adev->hw_cfg.dsp_cores) { + ret = -EINVAL; + goto err; + } + + adev->core_refs[core_id]++; + if (adev->core_refs[core_id] == 1) { + ret = avs_dsp_enable(adev, mask); + if (ret) + goto err_enable_dsp; + } + + return 0; + +err_enable_dsp: + adev->core_refs[core_id]--; +err: + dev_err(adev->dev, "get core %d failed: %d\n", core_id, ret); + return ret; +} + +static int avs_dsp_put_core(struct avs_dev *adev, u32 core_id) +{ + u32 mask; + int ret; + + mask = BIT_MASK(core_id); + if (mask == AVS_MAIN_CORE_MASK) + /* nothing to do for main core */ + return 0; + if (core_id >= adev->hw_cfg.dsp_cores) { + ret = -EINVAL; + goto err; + } + + adev->core_refs[core_id]--; + if (!adev->core_refs[core_id]) { + ret = avs_dsp_disable(adev, mask); + if (ret) + goto err; + } + + return 0; +err: + dev_err(adev->dev, "put core %d failed: %d\n", core_id, ret); + return ret; +} + +int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id, + u8 core_id, u8 domain, void *param, u32 param_size, + u16 *instance_id) +{ + struct avs_module_entry mentry; + int ret, id; + + id = avs_module_id_alloc(adev, module_id); + if (id < 0) + return id; + + ret = avs_get_module_id_entry(adev, module_id, &mentry); + if (ret) + goto err_mod_entry; + + ret = avs_dsp_get_core(adev, core_id); + if (ret) + goto err_mod_entry; + + ret = avs_ipc_init_instance(adev, module_id, id, ppl_instance_id, + core_id, domain, param, param_size); + if (ret) { + ret = AVS_IPC_RET(ret); + goto err_ipc; + } + + *instance_id = id; + return 0; + +err_ipc: + avs_dsp_put_core(adev, core_id); +err_mod_entry: + avs_module_id_free(adev, module_id, id); + return ret; +} + +void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u16 instance_id, + u8 ppl_instance_id, u8 core_id) +{ + /* Modules not owned by any pipeline need to be freed explicitly. */ + if (ppl_instance_id == INVALID_PIPELINE_ID) + avs_ipc_delete_instance(adev, module_id, instance_id); + + avs_module_id_free(adev, module_id, instance_id); + + avs_dsp_put_core(adev, core_id); +} + +int avs_dsp_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority, + bool lp, u16 attributes, u8 *instance_id) +{ + struct avs_fw_cfg *fw_cfg = &adev->fw_cfg; + int ret, id; + + id = ida_alloc_max(&adev->ppl_ida, fw_cfg->max_ppl_count - 1, GFP_KERNEL); + if (id < 0) + return id; + + ret = avs_ipc_create_pipeline(adev, req_size, priority, id, lp, + attributes); + if (ret) { + ida_free(&adev->ppl_ida, id); + return AVS_IPC_RET(ret); + } + + *instance_id = id; + return 0; +} + +int avs_dsp_delete_pipeline(struct avs_dev *adev, u8 instance_id) +{ + int ret; + + ret = avs_ipc_delete_pipeline(adev, instance_id); + if (ret) + ret = AVS_IPC_RET(ret); + + ida_free(&adev->ppl_ida, instance_id); + return ret; +} + MODULE_LICENSE("GPL"); -- 2.25.1