From patchwork Wed Oct 6 11:39:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 515321 Delivered-To: patch@linaro.org Received: by 2002:adf:fbc8:0:0:0:0:0 with SMTP id d8csp563279wrs; Wed, 6 Oct 2021 04:40:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyKo9mnnUyAD4nYooPriuzqUeoffL2M56iRi19Om2/UMIMK+4qRG6kzCdcNYt7hJ4mMmZ/4 X-Received: by 2002:a05:6a00:ac1:b0:44c:4dc6:b897 with SMTP id c1-20020a056a000ac100b0044c4dc6b897mr21050831pfl.25.1633520429006; Wed, 06 Oct 2021 04:40:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633520429; cv=none; d=google.com; s=arc-20160816; b=J7BaNIG6sak2hhN2PsIEQSWYsasoiGA3oSBPNZXVfIJldGXmj2U4Xypjs9kZo2IsWf YEAr+r02DL1TURXvaCq+SZRaxrZ2S/oFlOhq6evj56w5XT3uESMKJogFaLi4EAtBkyTz fectc+39W1z89gTbjLRwAb5KvP2Iu73MeB6zcLDTE8WpL2CcgA6q5lDF8V7qBsskvXpK 8//LpOrVuXdjxQvHBe6Zu0kVmWo/l3c50VIAkcYR8Benj6lLgNIBoeg1z/UbZdnh9mM4 ljhoqL2sDLamgLZPF9TXxGBkC/ZsG5SP3fRwoOXrydibX9B++6mEB0t5sh39v24Ywv0v nrnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=FYgv1eoGx9NFbm/uI8k2s23DY3/Vaao0ojhIbD31vzo=; b=i4DWyHjIrLskSPMZ7+boo+LO+pBKv2SX1lGzC+aAtGDhUlEwa40v878i6KnoWAoppd pvfElSitKVYZMki6k3ZQy/ZNdAZLg5VwW012bshKFNMg2YKswSKbq7iF3mS6u7fWYZLz rhXD8L5uqKp8p13AYiDCM6OImWbmPEmdBUlKA5jKeperNRWQuK3Aw9VIzAb4LtcBCUtm HSnUPoL9EkTSlV6/QPup0EWVZdTmngrzErM3epdbQzSlHURfhx4etpf80yUJDdJF4ggL X7Cfnla9qr5Jtyc7HVJ9hBIcq7LrWHzx5tfPbk5aMmT3lqH8zrel8fjk0d+/bOyXADl3 2WSQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WDV9NffK; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o22si32587717pfu.175.2021.10.06.04.40.28; Wed, 06 Oct 2021 04:40:28 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WDV9NffK; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238188AbhJFLmT (ORCPT + 7 others); Wed, 6 Oct 2021 07:42:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230461AbhJFLmT (ORCPT ); Wed, 6 Oct 2021 07:42:19 -0400 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 35BD0C061749 for ; Wed, 6 Oct 2021 04:40:27 -0700 (PDT) Received: by mail-wr1-x42e.google.com with SMTP id t2so7897181wrb.8 for ; Wed, 06 Oct 2021 04:40:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FYgv1eoGx9NFbm/uI8k2s23DY3/Vaao0ojhIbD31vzo=; b=WDV9NffKpdhPFk4HWBwotwWh0W6xGQgfjunXo6vEax054Yneh/O28QkOUQK7Oo1tUQ TwT0wV9/SguhPV1KGJDDA/J77qjYkw/DfZJTc94oZnqbNYvV7O0HBTraiUvRqAi4Nedo gpoJrFotLuwo5hefq6r1RdGRoUAaY1FaoJ6bmWnA611NHDX8mbYGtGLqe7Tf2NBc68IA wciZI6+J+JFi72SrcSbTDpMS6tTgsuyqkhOeg44uRE/+3Gf9mVlGt15no6VvOAym50UN jPXtNNWajwjmsswtim9tNCoHISYiIbc4SjrrRzzijXzNSZ2twQmO+g7naHyBn++ndUbs WBRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FYgv1eoGx9NFbm/uI8k2s23DY3/Vaao0ojhIbD31vzo=; b=F+HbIQcDbiOZ7eAkX0qqnSJjORth5FQoFZ9X96pcZ0V5Pn/+K6/d1O+lGCPDulnvN6 DkKiqFJtTBEFUwDt490/k7GE5CUUIXhp0lvcZMbScads+Th6/VoeHKavy92luqlx1vXw M7ZYbHCezLkgbTFAkt2SAqGygDJD3Evud9kOdWlvN9SWZD3u5CSHqH4FwVT87rHu+mU2 +k4iVcUYzVan9tFw7CZbRvoUzaZhvHkyCknibhXA9OEXHfO84mcI8a9ixeU6az6sKkSZ yKRyPdBuG2Ijb8M2j5u5EGSgxm5R/xrAankEb4UlszCJxwd/t2NCbiV0l0DEYcOdavjc wNSQ== X-Gm-Message-State: AOAM532QYMpWMAU9RnLx0kOtinMdaLZy6e1Nr8zxLY9QNhCum7v3AQng 6UEBy+l9xU7/xh7FszVow6eJfw== X-Received: by 2002:a05:600c:b41:: with SMTP id k1mr9429483wmr.4.1633520425816; Wed, 06 Oct 2021 04:40:25 -0700 (PDT) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id n11sm5540110wmq.19.2021.10.06.04.40.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Oct 2021 04:40:25 -0700 (PDT) From: Srinivas Kandagatla To: broonie@kernel.org, bjorn.andersson@linaro.org, robh@kernel.org Cc: plai@codeaurora.org, pierre-louis.bossart@linux.intel.com, tiwai@suse.de, devicetree@vger.kernel.org, perex@perex.cz, alsa-devel@alsa-project.org, lgirdwood@gmail.com, bgoswami@codeaurora.org, Srinivas Kandagatla Subject: [PATCH v9 16/17] ASoC: qdsp6: audioreach: add q6prm support Date: Wed, 6 Oct 2021 12:39:49 +0100 Message-Id: <20211006113950.10782-17-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20211006113950.10782-1-srinivas.kandagatla@linaro.org> References: <20211006113950.10782-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add support to q6prm (Proxy Resource Manager) module used for clock resources Signed-off-by: Srinivas Kandagatla Reviewed-by: Pierre-Louis Bossart --- sound/soc/qcom/Kconfig | 4 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6prm.c | 202 ++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6prm.h | 78 +++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6prm.c create mode 100644 sound/soc/qcom/qdsp6/q6prm.h -- 2.21.0 diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index d1132c4174db..465a2a603401 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -96,6 +96,9 @@ config SND_SOC_QDSP6_APM select SND_SOC_QDSP6_APM_DAI select SND_SOC_QDSP6_APM_LPASS_DAI +config SND_SOC_QDSP6_PRM + tristate + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" depends on QCOM_APR @@ -111,6 +114,7 @@ config SND_SOC_QDSP6 select SND_SOC_QDSP6_ASM_DAI select SND_SOC_TOPOLOGY select SND_SOC_QDSP6_APM + select SND_SOC_QDSP6_PRM help To add support for MSM QDSP6 Soc Audio. This will enable sound soc platform specific diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile index bdcbfdfa9bd0..c932f8e24b32 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_ASM_DAI) += q6asm-dai.o obj-$(CONFIG_SND_SOC_QDSP6_APM) += snd-q6apm.o obj-$(CONFIG_SND_SOC_QDSP6_APM_DAI) += q6apm-dai.o obj-$(CONFIG_SND_SOC_QDSP6_APM_LPASS_DAI) += q6apm-lpass-dais.o +obj-$(CONFIG_SND_SOC_QDSP6_PRM) += q6prm.o diff --git a/sound/soc/qcom/qdsp6/q6prm.c b/sound/soc/qcom/qdsp6/q6prm.c new file mode 100644 index 000000000000..82c40f2d4e1d --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6prm.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2021, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6prm.h" +#include "audioreach.h" + +struct q6prm { + struct device *dev; + gpr_device_t *gdev; + wait_queue_head_t wait; + struct gpr_ibasic_rsp_result_t result; + struct mutex lock; +}; + +#define PRM_CMD_REQUEST_HW_RSC 0x0100100F +#define PRM_CMD_RSP_REQUEST_HW_RSC 0x02001002 +#define PRM_CMD_RELEASE_HW_RSC 0x01001010 +#define PRM_CMD_RSP_RELEASE_HW_RSC 0x02001003 +#define PARAM_ID_RSC_HW_CORE 0x08001032 +#define PARAM_ID_RSC_LPASS_CORE 0x0800102B +#define PARAM_ID_RSC_AUDIO_HW_CLK 0x0800102C + +struct prm_cmd_request_hw_core { + struct apm_module_param_data param_data; + uint32_t hw_clk_id; +} __packed; + +struct prm_cmd_request_rsc { + struct apm_module_param_data param_data; + uint32_t num_clk_id; + struct audio_hw_clk_cfg clock_id; +} __packed; + +static int q6prm_send_cmd_sync(struct q6prm *prm, struct gpr_pkt *pkt, uint32_t rsp_opcode) +{ + return audioreach_send_cmd_sync(prm->dev, prm->gdev, &prm->result, &prm->lock, + NULL, &prm->wait, pkt, rsp_opcode); +} + +static int q6prm_set_hw_core_req(struct device *dev, uint32_t hw_block_id, bool enable) +{ + struct q6prm *prm = dev_get_drvdata(dev->parent); + struct apm_module_param_data *param_data; + struct prm_cmd_request_hw_core *req; + gpr_device_t *gdev = prm->gdev; + uint32_t opcode, rsp_opcode; + struct gpr_pkt *pkt; + int rc; + + if (enable) { + opcode = PRM_CMD_REQUEST_HW_RSC; + rsp_opcode = PRM_CMD_RSP_REQUEST_HW_RSC; + } else { + opcode = PRM_CMD_RELEASE_HW_RSC; + rsp_opcode = PRM_CMD_RSP_RELEASE_HW_RSC; + } + + pkt = audioreach_alloc_cmd_pkt(sizeof(*req), opcode, 0, gdev->svc.id, GPR_PRM_MODULE_IID); + if (IS_ERR(pkt)) + return PTR_ERR(pkt); + + req = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE; + + param_data = &req->param_data; + + param_data->module_instance_id = GPR_PRM_MODULE_IID; + param_data->error_code = 0; + param_data->param_id = PARAM_ID_RSC_HW_CORE; + param_data->param_size = sizeof(*req) - APM_MODULE_PARAM_DATA_SIZE; + + req->hw_clk_id = hw_block_id; + + rc = q6prm_send_cmd_sync(prm, pkt, rsp_opcode); + + kfree(pkt); + + return rc; +} + +int q6prm_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id, + const char *client_name, uint32_t *client_handle) +{ + return q6prm_set_hw_core_req(dev, hw_block_id, true); + +} +EXPORT_SYMBOL_GPL(q6prm_vote_lpass_core_hw); + +int q6prm_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id, uint32_t client_handle) +{ + return q6prm_set_hw_core_req(dev, hw_block_id, false); +} +EXPORT_SYMBOL_GPL(q6prm_unvote_lpass_core_hw); + +int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root, + unsigned int freq) +{ + struct q6prm *prm = dev_get_drvdata(dev->parent); + struct apm_module_param_data *param_data; + struct prm_cmd_request_rsc *req; + gpr_device_t *gdev = prm->gdev; + struct gpr_pkt *pkt; + int rc; + + pkt = audioreach_alloc_cmd_pkt(sizeof(*req), PRM_CMD_REQUEST_HW_RSC, 0, gdev->svc.id, + GPR_PRM_MODULE_IID); + if (IS_ERR(pkt)) + return PTR_ERR(pkt); + + req = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE; + + param_data = &req->param_data; + + param_data->module_instance_id = GPR_PRM_MODULE_IID; + param_data->error_code = 0; + param_data->param_id = PARAM_ID_RSC_AUDIO_HW_CLK; + param_data->param_size = sizeof(*req) - APM_MODULE_PARAM_DATA_SIZE; + + req->num_clk_id = 1; + req->clock_id.clock_id = clk_id; + req->clock_id.clock_freq = freq; + req->clock_id.clock_attri = clk_attr; + req->clock_id.clock_root = clk_root; + + rc = q6prm_send_cmd_sync(prm, pkt, PRM_CMD_RSP_REQUEST_HW_RSC); + + kfree(pkt); + + return rc; +} +EXPORT_SYMBOL_GPL(q6prm_set_lpass_clock); + +static int prm_callback(struct gpr_resp_pkt *data, void *priv, int op) +{ + gpr_device_t *gdev = priv; + struct q6prm *prm = dev_get_drvdata(&gdev->dev); + struct gpr_ibasic_rsp_result_t *result; + struct gpr_hdr *hdr = &data->hdr; + + switch (hdr->opcode) { + case PRM_CMD_RSP_REQUEST_HW_RSC: + case PRM_CMD_RSP_RELEASE_HW_RSC: + result = data->payload; + prm->result.opcode = hdr->opcode; + prm->result.status = result->status; + wake_up(&prm->wait); + break; + default: + break; + } + + return 0; +} + +static int prm_probe(gpr_device_t *gdev) +{ + struct device *dev = &gdev->dev; + struct q6prm *cc; + + cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL); + if (!cc) + return -ENOMEM; + + cc->dev = dev; + cc->gdev = gdev; + mutex_init(&cc->lock); + init_waitqueue_head(&cc->wait); + dev_set_drvdata(dev, cc); + + return devm_of_platform_populate(dev); +} + +#ifdef CONFIG_OF +static const struct of_device_id prm_device_id[] = { + { .compatible = "qcom,q6prm" }, + {}, +}; +MODULE_DEVICE_TABLE(of, prm_device_id); +#endif + +static gpr_driver_t prm_driver = { + .probe = prm_probe, + .gpr_callback = prm_callback, + .driver = { + .name = "qcom-prm", + .of_match_table = of_match_ptr(prm_device_id), + }, +}; + +module_gpr_driver(prm_driver); +MODULE_DESCRIPTION("Audio Process Manager"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h new file mode 100644 index 000000000000..fea4d1954bc1 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6prm.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __Q6PRM_H__ +#define __Q6PRM_H__ + +/* Clock ID for Primary I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100 +/* Clock ID for Primary I2S EBIT */ +#define Q6PRM_LPASS_CLK_ID_PRI_MI2S_EBIT 0x101 +/* Clock ID for Secondary I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_SEC_MI2S_IBIT 0x102 +/* Clock ID for Secondary I2S EBIT */ +#define Q6PRM_LPASS_CLK_ID_SEC_MI2S_EBIT 0x103 +/* Clock ID for Tertiary I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_TER_MI2S_IBIT 0x104 +/* Clock ID for Tertiary I2S EBIT */ +#define Q6PRM_LPASS_CLK_ID_TER_MI2S_EBIT 0x105 +/* Clock ID for Quartnery I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_QUAD_MI2S_IBIT 0x106 +/* Clock ID for Quartnery I2S EBIT */ +#define Q6PRM_LPASS_CLK_ID_QUAD_MI2S_EBIT 0x107 +/* Clock ID for Speaker I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_SPEAKER_I2S_IBIT 0x108 +/* Clock ID for Speaker I2S EBIT */ +#define Q6PRM_LPASS_CLK_ID_SPEAKER_I2S_EBIT 0x109 +/* Clock ID for Speaker I2S OSR */ +#define Q6PRM_LPASS_CLK_ID_SPEAKER_I2S_OSR 0x10A + +/* Clock ID for QUINARY I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_QUI_MI2S_IBIT 0x10B +/* Clock ID for QUINARY I2S EBIT */ +#define Q6PRM_LPASS_CLK_ID_QUI_MI2S_EBIT 0x10C +/* Clock ID for SENARY I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D +/* Clock ID for SENARY I2S EBIT */ +#define Q6PRM_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E +/* Clock ID for INT0 I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_INT0_MI2S_IBIT 0x10F +/* Clock ID for INT1 I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_INT1_MI2S_IBIT 0x110 +/* Clock ID for INT2 I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_INT2_MI2S_IBIT 0x111 +/* Clock ID for INT3 I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_INT3_MI2S_IBIT 0x112 +/* Clock ID for INT4 I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_INT4_MI2S_IBIT 0x113 +/* Clock ID for INT5 I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_INT5_MI2S_IBIT 0x114 +/* Clock ID for INT6 I2S IBIT */ +#define Q6PRM_LPASS_CLK_ID_INT6_MI2S_IBIT 0x115 + +/* Clock ID for QUINARY MI2S OSR CLK */ +#define Q6PRM_LPASS_CLK_ID_QUI_MI2S_OSR 0x116 + +#define Q6PRM_LPASS_CLK_ID_WSA_CORE_MCLK 0x305 +#define Q6PRM_LPASS_CLK_ID_WSA_CORE_NPL_MCLK 0x306 + +#define Q6PRM_LPASS_CLK_ID_VA_CORE_MCLK 0x307 +#define Q6PRM_LPASS_CLK_ID_VA_CORE_2X_MCLK 0x308 + +#define Q6PRM_LPASS_CLK_ID_TX_CORE_MCLK 0x30c +#define Q6PRM_LPASS_CLK_ID_TX_CORE_NPL_MCLK 0x30d + +#define Q6PRM_LPASS_CLK_ID_RX_CORE_MCLK 0x30e +#define Q6PRM_LPASS_CLK_ID_RX_CORE_NPL_MCLK 0x30f + +#define Q6PRM_LPASS_CLK_SRC_INTERNAL 1 +#define Q6PRM_LPASS_CLK_ROOT_DEFAULT 0 +#define Q6PRM_HW_CORE_ID_LPASS 1 +#define Q6PRM_HW_CORE_ID_DCODEC 2 + +int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, + int clk_root, unsigned int freq); +int q6prm_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id, + const char *client_name, uint32_t *client_handle); +int q6prm_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id, + uint32_t client_handle); +#endif /* __Q6PRM_H__ */