From patchwork Thu Dec 14 17:33:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 121995 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp7105376qgn; Thu, 14 Dec 2017 09:36:35 -0800 (PST) X-Google-Smtp-Source: ACJfBov+EEXurpjbI569dL/IKpask4JBbyeASMRrf1aA2A3dmMAkrq6Ijnc9GmCK7a1d4DV0daqa X-Received: by 10.84.128.197 with SMTP id a63mr10240541pla.210.1513272995591; Thu, 14 Dec 2017 09:36:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513272995; cv=none; d=google.com; s=arc-20160816; b=XgG5iw9KTUaEukaplazyTvAW7UXK0zMoODKSwylGqSlCOy6YucqIruH/e9t6+IBJkw sv4P2RxeMTw7XNWyykX7HF0OWiTU0W/UvEK61ExsnqQkoPnDzfzRxGfLxFAf9h8EJcvO X1Db8XJAmTPGek5VEn4Ft1gSIu00Uzrj+EhdfF11tue54E37w5UibK0yeLqb7HT+YM2z YlkZPNjxzpgTbZF2+KDzB4Flh+RhGW2KNes9mAwvyeLrDbnIlVSdpzRk4ujC1Jkgdo4k 9U7mi19TlL5OCWi+f81WhNx4HHA306B/sRUcnixesp50WZIJr0x36DLKfYkSU0NqDzvK LNXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=h9FbwvOQTnX/y8WClzwphGe7ASQGbyJxPzBMZomec0A=; b=LELMZQ9kjO7NPdNQD80Ke8JYZWgiaCyH/v2B1+fyspgjnuE5+AIUMeEDZtADwPD6H3 eZeILVlfKrfmtyfFW/oplwOMlIAUkxSgQrnu0NB2b/gVC2sPq2t5IuyLjWmx7mlnZDex sfdPcfnLfokzYSGWVlwNi89k9qNefEpe9/c5VMZB25/LynfMXK4uyoglSomOavkhWrKs TyIjiqTM4GsaLXmsoNqpl/pQgfEC3gayPYgEvAOcrMtCvqOhlWzc5aQK4r+qLkLR5nAO a8kxqbp2HJlJWDKoeoHvE1ORpIKZ/iBI3YJ1pbTbR6C8UCOZmWPPaSh+Et3Oor994xoc Xo7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=aNnwIxcb; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a16si3181496pgn.797.2017.12.14.09.36.35; Thu, 14 Dec 2017 09:36:35 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=aNnwIxcb; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753810AbdLNRgd (ORCPT + 10 others); Thu, 14 Dec 2017 12:36:33 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:41868 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753697AbdLNRga (ORCPT ); Thu, 14 Dec 2017 12:36:30 -0500 Received: by mail-wm0-f65.google.com with SMTP id g75so12943680wme.0 for ; Thu, 14 Dec 2017 09:36:29 -0800 (PST) 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; bh=DILw6oPt1qTQjGuLHiux0h6k6/S2gF5gM0/EvigMs9E=; b=aNnwIxcbnwOaq4Utc/82FXsBljCn7YVVNm2e+CQKnSGYGt1fwmet8r+YUjPnWVIOwj fBea/fnSb4pL8Q9kglzbf0HqKpdYXt3QoUCuX6MZGLuiZS/2PfctoCSVNpmtQjah/clo pkTp/UK3vKrK0vQBuSvkGeVNl7oYaWDEOHuD4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DILw6oPt1qTQjGuLHiux0h6k6/S2gF5gM0/EvigMs9E=; b=g1scT2gNwS2Krpd4q1hopMnl91NTTqDDgMR4+5AmJRvm71mLH3aYc7gTndPVJB9Uq7 PbQKLbduBSAklFw9R+/ZzAUdCkwreJ9KqENzWv0BDXIIFlhO8msZUUNH8tQLhoqQF1BV vhGbZW1yzygB9S990SVnSmccatBUdF7lj4DZfBoqLMyWpVdmYy0PRTywllREnWc9oSWB sZo+j2LAEZPQAWnFt9drt7WRiXiIURGSKyuf+2jTOhRa/1wDk8oxoAYxXPAD8tFYtdNp JA5TmR+ykxTHg9H8dB5tlvMrcWBurEh+WZ7BgpadnDCt9EB/lIYFQffOdg8IBKFUFB7Z EEXg== X-Gm-Message-State: AKGB3mLBvLOB4Wtk75haBgniGmRVtoqdpyDCVllp99kwyawIJOxkAPrl ib7S1SdrSbPLm7KzuRGaowHrWQ== X-Received: by 10.28.167.86 with SMTP id q83mr2737029wme.102.1513272988655; Thu, 14 Dec 2017 09:36:28 -0800 (PST) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id r82sm1741757wme.31.2017.12.14.09.36.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Dec 2017 09:36:28 -0800 (PST) From: srinivas.kandagatla@linaro.org To: Andy Gross , Mark Brown , linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org Cc: David Brown , Rob Herring , Mark Rutland , Liam Girdwood , Patrick Lai , Banajit Goswami , Jaroslav Kysela , Takashi Iwai , linux-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, sboyd@codeaurora.org, Srinivas Kandagatla Subject: [RESEND PATCH v2 02/15] soc: qcom: add support to APR bus driver Date: Thu, 14 Dec 2017 17:33:49 +0000 Message-Id: <20171214173402.19074-3-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> References: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Srinivas Kandagatla This patch adds support toi APR bus (Asynchronous Packet Router) driver. ARP driver is made as a bus driver so that the apr devices can added removed more dynamically depending on the state of the services on the dsp. APR is used for communication between application processor and QDSP to use services on QDSP like Audio and others. Signed-off-by: Srinivas Kandagatla --- drivers/soc/qcom/Kconfig | 8 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/apr.c | 395 ++++++++++++++++++++++++++++++++++++++++ include/linux/mod_devicetable.h | 13 ++ include/linux/soc/qcom/apr.h | 174 ++++++++++++++++++ 5 files changed, 591 insertions(+) create mode 100644 drivers/soc/qcom/apr.c create mode 100644 include/linux/soc/qcom/apr.h -- 2.15.0 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index b81374bb6713..1daa39925dd4 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -97,4 +97,12 @@ config QCOM_WCNSS_CTRL Client driver for the WCNSS_CTRL SMD channel, used to download nv firmware to a newly booted WCNSS chip. +config QCOM_APR + tristate "Qualcomm APR Bus (Asynchronous Packet Router)" + depends on (RPMSG_QCOM_SMD || RPMSG_QCOM_GLINK_RPM) + help + Enable APR IPC protocol support between + application processor and QDSP6. APR is + used by audio driver to configure QDSP6 + ASM, ADM and AFE modules. endmenu diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 40c56f67e94a..9daba7e6d20f 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o obj-$(CONFIG_QCOM_SMP2P) += smp2p.o obj-$(CONFIG_QCOM_SMSM) += smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o +obj-$(CONFIG_QCOM_APR) += apr.o diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c new file mode 100644 index 000000000000..c6f3aa7a375b --- /dev/null +++ b/drivers/soc/qcom/apr.c @@ -0,0 +1,395 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Copyright (c) 2011-2016, The Linux Foundation +* Copyright (c) 2017, Linaro Limited +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct apr_data { + int (*get_data_src)(struct apr_hdr *hdr); + int dest_id; +}; + +struct apr { + struct rpmsg_endpoint *ch; + struct device *dev; + spinlock_t svcs_lock; + struct list_head svcs; + int dest_id; + const struct apr_data *data; +}; + +/* Static CORE service on the ADSP */ +static const struct apr_device_id core_svc_device_id = + ADSP_AUDIO_APR_DEV("CORE", APR_SVC_ADSP_CORE); + +/** + * apr_send_pkt() - Send a apr message from apr device + * + * @adev: Pointer to previously registered apr device. + * @buf: Pointer to buffer to send + * + * Return: Will be an negative on packet size on success. + */ +int apr_send_pkt(struct apr_device *adev, uint32_t *buf) +{ + struct apr *apr = dev_get_drvdata(adev->dev.parent); + struct apr_hdr *hdr; + unsigned long flags; + int ret; + + spin_lock_irqsave(&adev->lock, flags); + + hdr = (struct apr_hdr *)buf; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->src_svc = adev->svc_id; + hdr->dest_domain = adev->domain_id; + hdr->dest_svc = adev->svc_id; + + ret = rpmsg_send(apr->ch, buf, hdr->pkt_size); + if (ret) { + dev_err(&adev->dev, "Unable to send APR pkt %d\n", + hdr->pkt_size); + } else { + ret = hdr->pkt_size; + } + + spin_unlock_irqrestore(&adev->lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(apr_send_pkt); + +static void apr_dev_release(struct device *dev) +{ + struct apr_device *adev = to_apr_device(dev); + + kfree(adev); +} + +static int qcom_rpmsg_q6_callback(struct rpmsg_device *rpdev, void *buf, + int len, void *priv, u32 addr) +{ + struct apr *apr = dev_get_drvdata(&rpdev->dev); + struct apr_client_data data; + struct apr_device *p, *c_svc = NULL; + struct apr_driver *adrv = NULL; + struct apr_hdr *hdr; + uint16_t hdr_size; + uint16_t msg_type; + uint16_t ver; + uint16_t src; + uint16_t svc; + + if (!buf || len <= APR_HDR_SIZE) { + dev_err(apr->dev, "APR: Improper apr pkt received:%p %d\n", + buf, len); + return -EINVAL; + } + + hdr = buf; + ver = APR_HDR_FIELD_VER(hdr->hdr_field); + if (ver > APR_PKT_VER + 1) + return -EINVAL; + + hdr_size = APR_HDR_FIELD_SIZE_BYTES(hdr->hdr_field); + if (hdr_size < APR_HDR_SIZE) { + dev_err(apr->dev, "APR: Wrong hdr size:%d\n", hdr_size); + return -EINVAL; + } + + if (hdr->pkt_size < APR_HDR_SIZE) { + dev_err(apr->dev, "APR: Wrong paket size\n"); + return -EINVAL; + } + + msg_type = APR_HDR_FIELD_MT(hdr->hdr_field); + if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) { + dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type); + return -EINVAL; + } + + if (hdr->src_domain >= APR_DOMAIN_MAX || + hdr->dest_domain >= APR_DOMAIN_MAX || + hdr->src_svc >= APR_SVC_MAX || + hdr->dest_svc >= APR_SVC_MAX) { + dev_err(apr->dev, "APR: Wrong APR header\n"); + return -EINVAL; + } + + svc = hdr->dest_svc; + src = apr->data->get_data_src(hdr); + if (src == APR_DEST_MAX) + return -EINVAL; + + spin_lock(&apr->svcs_lock); + list_for_each_entry(p, &apr->svcs, node) { + if (svc == p->svc_id) { + c_svc = p; + if (c_svc->dev.driver) + adrv = to_apr_driver(c_svc->dev.driver); + break; + } + } + spin_unlock(&apr->svcs_lock); + + if (!adrv) { + dev_err(apr->dev, "APR: service is not registered\n"); + return -EINVAL; + } + + data.payload_size = hdr->pkt_size - hdr_size; + data.opcode = hdr->opcode; + data.src = src; + data.src_port = hdr->src_port; + data.dest_port = hdr->dest_port; + data.token = hdr->token; + data.msg_type = msg_type; + + if (data.payload_size > 0) + data.payload = (char *)hdr + hdr_size; + + adrv->callback(c_svc, &data); + + return 0; +} + +static const struct apr_device_id *apr_match(const struct apr_device_id *id, + const struct apr_device *adev) +{ + while (id->domain_id != 0 || id->svc_id != 0) { + if (id->domain_id == adev->domain_id && + id->svc_id == adev->svc_id && + id->client_id == adev->client_id) + return id; + id++; + } + return NULL; +} + +static int apr_device_match(struct device *dev, struct device_driver *drv) +{ + struct apr_device *adev = to_apr_device(dev); + struct apr_driver *adrv = to_apr_driver(drv); + + return !!apr_match(adrv->id_table, adev); +} + +static int apr_device_probe(struct device *dev) +{ + struct apr_device *adev; + struct apr_driver *adrv; + int ret = 0; + + adev = to_apr_device(dev); + adrv = to_apr_driver(dev->driver); + + ret = adrv->probe(adev); + + return ret; +} + +static int apr_device_remove(struct device *dev) +{ + struct apr_device *adev = to_apr_device(dev); + struct apr_driver *adrv; + struct apr *apr = dev_get_drvdata(adev->dev.parent); + + if (dev->driver) { + adrv = to_apr_driver(dev->driver); + if (adrv->remove) + adrv->remove(adev); + spin_lock(&apr->svcs_lock); + list_del(&adev->node); + spin_unlock(&apr->svcs_lock); + } + + return 0; +} + +struct bus_type aprbus_type = { + .name = "aprbus", + .match = apr_device_match, + .probe = apr_device_probe, + .remove = apr_device_remove, +}; +EXPORT_SYMBOL_GPL(aprbus_type); + +/** + * apr_add_device() - Add a new apr device + * + * @dev: Pointer to apr device. + * @id: Pointer to apr device id to add. + * + * Return: Will be an negative on error or a zero on success. + */ +int apr_add_device(struct device *dev, const struct apr_device_id *id) +{ + struct apr *apr = dev_get_drvdata(dev); + struct apr_device *adev = NULL; + + if (!apr) + return -EINVAL; + + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + spin_lock_init(&adev->lock); + + adev->svc_id = id->svc_id; + adev->dest_id = apr->dest_id; + adev->client_id = id->client_id; + adev->domain_id = id->domain_id; + adev->version = id->svc_version; + + adev->dev.bus = &aprbus_type; + adev->dev.parent = dev; + adev->dev.release = apr_dev_release; + adev->dev.driver = NULL; + + dev_set_name(&adev->dev, "apr:%s:%x:%x:%x", id->name, id->domain_id, + id->svc_id, id->client_id); + + spin_lock(&apr->svcs_lock); + list_add_tail(&adev->node, &apr->svcs); + spin_unlock(&apr->svcs_lock); + + return device_register(&adev->dev); +} +EXPORT_SYMBOL_GPL(apr_add_device); + +static int qcom_rpmsg_q6_probe(struct rpmsg_device *rpdev) +{ + struct device *dev = &rpdev->dev; + struct apr *apr; + + apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL); + if (!apr) + return -ENOMEM; + + apr->data = of_device_get_match_data(dev); + if (!apr->data) + return -ENODEV; + + apr->dest_id = apr->data->dest_id; + dev_set_drvdata(dev, apr); + apr->ch = rpdev->ept; + apr->dev = dev; + INIT_LIST_HEAD(&apr->svcs); + + /* register core service */ + apr_add_device(dev, &core_svc_device_id); + + return 0; +} + +static int apr_remove_device(struct device *dev, void *null) +{ + struct apr_device *adev = to_apr_device(dev); + + device_unregister(&adev->dev); + + return 0; +} + +static void qcom_rpmsg_q6_remove(struct rpmsg_device *rpdev) +{ + device_for_each_child(&rpdev->dev, NULL, apr_remove_device); +} + +static int apr_v2_get_data_src(struct apr_hdr *hdr) +{ + if (hdr->src_domain == APR_DOMAIN_MODEM) + return APR_DEST_MODEM; + else if (hdr->src_domain == APR_DOMAIN_ADSP) + return APR_DEST_QDSP6; + + return APR_DEST_MAX; +} + +/* + * __apr_driver_register() - Client driver registration with aprbus + * + * @drv:Client driver to be associated with client-device. + * @owner: owning module/driver + * + * This API will register the client driver with the aprbus + * It is called from the driver's module-init function. + */ +int __apr_driver_register(struct apr_driver *drv, struct module *owner) +{ + /* ID table is mandatory to match the devices to probe */ + if (!drv->id_table) + return -EINVAL; + + drv->driver.bus = &aprbus_type; + drv->driver.owner = owner; + + return driver_register(&drv->driver); +} +EXPORT_SYMBOL_GPL(__apr_driver_register); + +/* + * apr_driver_unregister() - Undo effect of apr_driver_register + * + * @drv: Client driver to be unregistered + */ +void apr_driver_unregister(struct apr_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL_GPL(apr_driver_unregister); + +static const struct apr_data apr_v2_data = { + .get_data_src = apr_v2_get_data_src, + .dest_id = APR_DEST_QDSP6, +}; + +static const struct of_device_id qcom_rpmsg_q6_of_match[] = { + { .compatible = "qcom,apr-msm8996", .data = &apr_v2_data}, + {} +}; + +static struct rpmsg_driver qcom_rpmsg_q6_driver = { + .probe = qcom_rpmsg_q6_probe, + .remove = qcom_rpmsg_q6_remove, + .callback = qcom_rpmsg_q6_callback, + .drv = { + .name = "qcom_rpmsg_q6", + .owner = THIS_MODULE, + .of_match_table = qcom_rpmsg_q6_of_match, + }, +}; + +static int __init apr_init(void) +{ + int ret; + + ret = register_rpmsg_driver(&qcom_rpmsg_q6_driver); + if (!ret) + return bus_register(&aprbus_type); + + return ret; +} + +static void __exit apr_exit(void) +{ + bus_unregister(&aprbus_type); + unregister_rpmsg_driver(&qcom_rpmsg_q6_driver); +} + +subsys_initcall(apr_init); +module_exit(apr_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Qualcomm APR Bus"); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index abb6dc2ebbf8..068d215c3be6 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -452,6 +452,19 @@ struct spi_device_id { kernel_ulong_t driver_data; /* Data private to the driver */ }; + +#define APR_NAME_SIZE 32 +#define APR_MODULE_PREFIX "apr:" + +struct apr_device_id { + char name[APR_NAME_SIZE]; + __u32 domain_id; + __u32 svc_id; + __u32 client_id; + __u32 svc_version; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + #define SPMI_NAME_SIZE 32 #define SPMI_MODULE_PREFIX "spmi:" diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h new file mode 100644 index 000000000000..8620289c34ab --- /dev/null +++ b/include/linux/soc/qcom/apr.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Copyright (c) 2011-2016, The Linux Foundation +* Copyright (c) 2017, Linaro Limited +*/ + +#ifndef __APR_H_ +#define __APR_H_ + +#include +#include +#include +/* APR Client IDs */ +#define APR_CLIENT_AUDIO 0x0 +#define APR_CLIENT_VOICE 0x1 +#define APR_CLIENT_MAX 0x2 + +#define APR_DL_SMD 0 +#define APR_DL_MAX 1 + +#define APR_DEST_MODEM 0 +#define APR_DEST_QDSP6 1 +#define APR_DEST_MAX 2 +#define APR_MAX_BUF 8192 + +#define APR_HDR_LEN(hdr_len) ((hdr_len)/4) +#define APR_PKT_SIZE(hdr_len, payload_len) ((hdr_len) + (payload_len)) +#define APR_HDR_FIELD(msg_type, hdr_len, ver)\ + (((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF)) + +#define APR_HDR_SIZE sizeof(struct apr_hdr) +#define APR_SEQ_CMD_HDR_FIELD APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \ + APR_HDR_LEN(APR_HDR_SIZE), \ + APR_PKT_VER) + +/* Version */ +#define APR_PKT_VER 0x0 + +/* Command and Response Types */ +#define APR_MSG_TYPE_EVENT 0x0 +#define APR_MSG_TYPE_CMD_RSP 0x1 +#define APR_MSG_TYPE_SEQ_CMD 0x2 +#define APR_MSG_TYPE_NSEQ_CMD 0x3 +#define APR_MSG_TYPE_MAX 0x04 + +/* APR Basic Response Message */ +#define APR_BASIC_RSP_RESULT 0x000110E8 +#define APR_RSP_ACCEPTED 0x000100BE + +/* Domain IDs */ +#define APR_DOMAIN_SIM 0x1 +#define APR_DOMAIN_PC 0x2 +#define APR_DOMAIN_MODEM 0x3 +#define APR_DOMAIN_ADSP 0x4 +#define APR_DOMAIN_APPS 0x5 +#define APR_DOMAIN_MAX 0x6 + +/* ADSP service IDs */ +#define APR_SVC_TEST_CLIENT 0x2 +#define APR_SVC_ADSP_CORE 0x3 +#define APR_SVC_AFE 0x4 +#define APR_SVC_VSM 0x5 +#define APR_SVC_VPM 0x6 +#define APR_SVC_ASM 0x7 +#define APR_SVC_ADM 0x8 +#define APR_SVC_ADSP_MVM 0x09 +#define APR_SVC_ADSP_CVS 0x0A +#define APR_SVC_ADSP_CVP 0x0B +#define APR_SVC_USM 0x0C +#define APR_SVC_LSM 0x0D +#define APR_SVC_VIDC 0x16 +#define APR_SVC_MAX 0x17 + +/* Modem Service IDs */ +#define APR_SVC_MVS 0x3 +#define APR_SVC_MVM 0x4 +#define APR_SVC_CVS 0x5 +#define APR_SVC_CVP 0x6 +#define APR_SVC_SRD 0x7 + +/* APR Port IDs */ +#define APR_MAX_PORTS 0x80 +#define APR_NAME_MAX 0x40 +#define RESET_EVENTS 0x000130D7 + +/* hdr field Ver [0:3], Size [4:7], Message type [8:10] */ +#define APR_HDR_FIELD_VER(h) (h & 0x000F) +#define APR_HDR_FIELD_SIZE(h) ((h & 0x00F0) >> 4) +#define APR_HDR_FIELD_SIZE_BYTES(h) (((h & 0x00F0) >> 4) * 4) +#define APR_HDR_FIELD_MT(h) ((h & 0x0300) >> 8) + +struct apr_hdr { + uint16_t hdr_field; + uint16_t pkt_size; + uint8_t src_svc; + uint8_t src_domain; + uint16_t src_port; + uint8_t dest_svc; + uint8_t dest_domain; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; +}; + +struct apr_client_data { + uint16_t payload_size; + uint16_t hdr_len; + uint16_t msg_type; + uint16_t src; + uint16_t dest_svc; + uint16_t src_port; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; + void *payload; +}; + +#define ADSP_AUDIO_APR_DEV(name, id) \ + {name, APR_DOMAIN_ADSP, id, APR_CLIENT_AUDIO} + +/* Bits 0 to 15 -- Minor version, Bits 16 to 31 -- Major version */ + +#define APR_SVC_MAJOR_VERSION(v) ((v >> 16) & 0xFF) +#define APR_SVC_MINOR_VERSION(v) (v & 0xFF) + +struct apr_device { + struct device dev; + uint16_t svc_id; + uint16_t dest_id; + uint16_t client_id; + uint16_t domain_id; + uint16_t version; + + spinlock_t lock; + struct list_head node; +}; + + +#define to_apr_device(d) container_of(d, struct apr_device, dev) + +struct apr_driver { + int (*probe)(struct apr_device *sl); + int (*remove)(struct apr_device *sl); + int (*callback)(struct apr_device *a, struct apr_client_data *d); + struct device_driver driver; + const struct apr_device_id *id_table; +}; + +#define to_apr_driver(d) container_of(d, struct apr_driver, driver) + +/* + * use a macro to avoid include chaining to get THIS_MODULE + */ +#define apr_driver_register(drv) __apr_driver_register(drv, THIS_MODULE) + +int __apr_driver_register(struct apr_driver *drv, struct module *owner); +void apr_driver_unregister(struct apr_driver *drv); +int apr_add_device(struct device *dev, const struct apr_device_id *id); + +/** + * module_apr_driver() - Helper macro for registering a aprbus driver + * @__aprbus_driver: aprbus_driver struct + * + * Helper macro for aprbus drivers which do not do anything special in + * module init/exit. This eliminates a lot of boilerplate. Each module + * may only use this macro once, and calling it replaces module_init() + * and module_exit() + */ +#define module_apr_driver(__apr_driver) \ + module_driver(__apr_driver, apr_driver_register, \ + apr_driver_unregister) + +int apr_send_pkt(struct apr_device *adev, uint32_t *buf); + +#endif /* __APR_H_ */ From patchwork Thu Dec 14 17:33:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 121996 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp7105504qgn; Thu, 14 Dec 2017 09:36:43 -0800 (PST) X-Google-Smtp-Source: ACJfBosIZcGE6Q1fuoSOjb2+nNcqy5Qdn3R+eN7u36Le9GCm2kSLy9Bwv/Zc5YaIFxkD3sex6Dju X-Received: by 10.84.128.197 with SMTP id a63mr10240861pla.210.1513273003053; Thu, 14 Dec 2017 09:36:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513273003; cv=none; d=google.com; s=arc-20160816; b=HFaXAzgh76hbAh2bphzgfH27fY0lojVnHoABmTokqJ6cOlad6Msn9aYd4UTQGS5lPy o5AQsySgIj+uCq0KokivY57QVZQPYz3GkmsqTsQayGwbL2OAYfukljfiO8mvJeYS+KtV kA2R9UFWY3qrPXV5SbVEQ+H/8iipCWDrhqnYTMBZOMv2bhvwawJAKTr5wgS/2AzgxSLY ZGWFkflZA29FCmGlhPE3QonKbbKxzLfD5PL0mY1wmygfDesBFl3NZgOPlnxQdKweAWSn vpGpDWdBP9gdM8Pyz10LpkPwoCLLntd7JcuojDsPQSEeIDYBPsa2UnLgS3JWFkDxH/J9 wHug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=L0wUD3GRQLNMh0w4UmxcKxRo7xNWEnTUcqCGo+ohIFY=; b=qMRZscJL3QZ2cqvVxlF4YnuDFz9jZriE36yHGXkiCUZ6iMNZ/GnzCcH6kHgP0VoS+E uxKovZoBtpI9XwJLp+2G8X4wjH08UBqzOkWinL7BKfKrPM9wND2Vs2GIj0V1ltGWVIwJ 0VtHU7+K2so3+RsNIHUidLDTyMPUU05Svk3UO4xbjDqZro+JbmGRXEp/emRcqWrv+9v3 qS9AgThWNuGf/UkDqn6rNMu552tXZ99RFv7rl4/zJHJ3TKpJH4nvqcKU6K4n28WIR7uT GaFutTbZUlxNP3eG4UijicZ3kjT9ZLzSOuiDKTz5fx6NNM6gb7mTg9Wh7uVhFm7wtpd7 vT0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=QdMB7fE5; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a16si3181496pgn.797.2017.12.14.09.36.42; Thu, 14 Dec 2017 09:36:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=QdMB7fE5; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753848AbdLNRgk (ORCPT + 10 others); Thu, 14 Dec 2017 12:36:40 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:41893 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753624AbdLNRgg (ORCPT ); Thu, 14 Dec 2017 12:36:36 -0500 Received: by mail-wm0-f67.google.com with SMTP id g75so12944232wme.0 for ; Thu, 14 Dec 2017 09:36:35 -0800 (PST) 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; bh=f/zRsj0OzIeNS0Xd92+bTvAMHKx0Cw4B89d9H8CWiWQ=; b=QdMB7fE5aLWDxVivNJBvfKq+XoAcGwbgiC4RR/8VpmqdCy3sueM/+eQ2K8F5mI/Q2l NnRL8/9foxQlYXiG1F8FAGX16Eq345Yt6KC4wjXBivD/SSe4Fb9egDEv4KbdkWKuI1gm Ly7rkRx2yRkwMbPBDZNxUop+kFi/Kwox3RA7s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=f/zRsj0OzIeNS0Xd92+bTvAMHKx0Cw4B89d9H8CWiWQ=; b=Ym/VF01DBQvqKzzBKqQG2t2o25QIUokQ4JA8rqBmzc++SLC1I55XGnvG/l8rgvBIXo R01SJSFtv4LIoSgCO963MjbpifEmL2Z5+/9SYbuXF71hnQZ7vEEU45ONx6k7yQxwikKD Hxnh+EsZQZjvHRTc2dO6XyEoyjnQGEPJBoloN6aE3neNzF3IjCpKgN1fRF40vj8br++3 u/J03F5V4+z5ERkN9pxvwBnjc6ayiP5nZlTyZkb4R2+Pa6OVycNnV1Dtnxzz+zTTZTh0 SfK00hkL9MfuiEKjAwcPoUEKNwoH4WEFJh/inE2iu0A3nH2M1KnFdhMSIrKaUDHyEDNF 3gQA== X-Gm-Message-State: AKGB3mJLVKmp/gyaa0/p84IsaS8geORKDd8YpM2gobTev+3cvmZxqH1w DGeC12ONbzY7QfYbp1W1Y9Ka/A== X-Received: by 10.28.128.214 with SMTP id b205mr3140049wmd.82.1513272994720; Thu, 14 Dec 2017 09:36:34 -0800 (PST) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id r82sm1741757wme.31.2017.12.14.09.36.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Dec 2017 09:36:34 -0800 (PST) From: srinivas.kandagatla@linaro.org To: Andy Gross , Mark Brown , linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org Cc: David Brown , Rob Herring , Mark Rutland , Liam Girdwood , Patrick Lai , Banajit Goswami , Jaroslav Kysela , Takashi Iwai , linux-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, sboyd@codeaurora.org, Srinivas Kandagatla Subject: [RESEND PATCH v2 05/15] ASoC: qcom: qdsp6: Add support to Q6ADM Date: Thu, 14 Dec 2017 17:33:52 +0000 Message-Id: <20171214173402.19074-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> References: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Srinivas Kandagatla This patch adds support to q6 ADM (Audio Device Manager) module in q6dsp. ADM performs routing between audio streams and AFE ports. It does Rate matching for streams going to devices driven by different clocks, it handles volume ramping, Mixing with channel and bit-width. ADM creates and destroys dynamic COPP services for device-related audio processing as needed. This patch adds basic support to ADM. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 5 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6adm.c | 602 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6adm.h | 24 ++ 4 files changed, 632 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6adm.c create mode 100644 sound/soc/qcom/qdsp6/q6adm.h -- 2.15.0 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 1db92069a6a0..a307880dc992 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -48,9 +48,14 @@ config SND_SOC_QDSP6_AFE tristate default n +config SND_SOC_QDSP6_ADM + tristate + default n + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" select SND_SOC_QDSP6_AFE + select SND_SOC_QDSP6_ADM 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 313e65f571db..052813ea7062 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o +obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c new file mode 100644 index 000000000000..b9f79a198ea4 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6adm.c @@ -0,0 +1,602 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Copyright (c) 2011-2016, The Linux Foundation +* Copyright (c) 2017, Linaro Limited +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6adm.h" +#include "q6afe.h" +#include "common.h" + +#define ADM_CMD_DEVICE_OPEN_V5 0x00010326 +#define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329 +#define ADM_CMD_DEVICE_CLOSE_V5 0x00010327 +#define ADM_CMD_MATRIX_MAP_ROUTINGS_V5 0x00010325 + +#define TIMEOUT_MS 1000 +#define RESET_COPP_ID 99 +#define INVALID_COPP_ID 0xFF +/* Definition for a legacy device session. */ +#define ADM_LEGACY_DEVICE_SESSION 0 +#define ADM_MATRIX_ID_AUDIO_RX 0 + +struct copp { + int afe_port; + int copp_idx; + int id; + int cnt; + int topology; + int mode; + int stat; + int rate; + int bit_width; + int channels; + int app_type; + int acdb_id; + wait_queue_head_t wait; + struct list_head node; + struct q6adm *adm; +}; + +struct q6adm { + struct apr_device *apr; + struct device *dev; + unsigned long copp_bitmap[AFE_MAX_PORTS]; + struct list_head copps_list; + spinlock_t copps_list_lock; + int matrix_map_stat; + struct platform_device *routing_dev; + + wait_queue_head_t matrix_map_wait; +}; + +static struct copp *adm_find_copp(struct q6adm *adm, int port_idx, int copp_idx) +{ + struct copp *c; + + spin_lock(&adm->copps_list_lock); + list_for_each_entry(c, &adm->copps_list, node) { + if ((port_idx == c->afe_port) && (copp_idx == c->copp_idx)) { + spin_unlock(&adm->copps_list_lock); + return c; + } + } + + spin_unlock(&adm->copps_list_lock); + return NULL; + +} + +static struct copp *adm_find_matching_copp(struct q6adm *adm, + int port_idx, int topology, + int mode, int rate, + int bit_width, int app_type) +{ + struct copp *c; + + spin_lock(&adm->copps_list_lock); + + list_for_each_entry(c, &adm->copps_list, node) { + if ((port_idx == c->afe_port) && (topology == c->topology) && + (mode == c->mode) && (rate == c->rate) && + (bit_width == c->bit_width) && (app_type == c->app_type)) { + spin_unlock(&adm->copps_list_lock); + return c; + } + } + spin_unlock(&adm->copps_list_lock); + + return NULL; + +} + +static int adm_callback(struct apr_device *adev, struct apr_client_data *data) +{ + uint32_t *payload; + int port_idx, copp_idx; + struct copp *copp; + struct q6adm *adm = dev_get_drvdata(&adev->dev); + + payload = data->payload; + + if (data->payload_size) { + copp_idx = (data->token) & 0XFF; + port_idx = ((data->token) >> 16) & 0xFF; + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + dev_err(&adev->dev, "Invalid port idx %d token %d\n", + port_idx, data->token); + return 0; + } + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + dev_err(&adev->dev, "Invalid copp idx %d token %d\n", + copp_idx, data->token); + return 0; + } + + if (data->opcode == APR_BASIC_RSP_RESULT) { + if (payload[1] != 0) { + dev_err(&adev->dev, "cmd = 0x%x returned error = 0x%x\n", + payload[0], payload[1]); + } + switch (payload[0]) { + case ADM_CMD_DEVICE_OPEN_V5: + case ADM_CMD_DEVICE_CLOSE_V5: + copp = adm_find_copp(adm, port_idx, copp_idx); + if (IS_ERR_OR_NULL(copp)) + return 0; + + copp->stat = payload[1]; + wake_up(&copp->wait); + break; + case ADM_CMD_MATRIX_MAP_ROUTINGS_V5: + adm->matrix_map_stat = payload[1]; + wake_up(&adm->matrix_map_wait); + break; + + default: + dev_err(&adev->dev, "Unknown Cmd: 0x%x\n", + payload[0]); + break; + } + return 0; + } + + switch (data->opcode) { + case ADM_CMDRSP_DEVICE_OPEN_V5:{ + struct adm_cmd_rsp_device_open_v5 { + u32 status; + u16 copp_id; + u16 reserved; + } __packed * open = data->payload; + + open = data->payload; + copp = adm_find_copp(adm, port_idx, copp_idx); + if (IS_ERR_OR_NULL(copp)) + return 0; + + if (open->copp_id == INVALID_COPP_ID) { + dev_err(&adev->dev, "Invalid coppid rxed %d\n", + open->copp_id); + copp->stat = ADSP_EBADPARAM; + wake_up(&copp->wait); + break; + } + copp->stat = payload[0]; + copp->id = open->copp_id; + pr_debug("%s: coppid rxed=%d\n", __func__, + open->copp_id); + wake_up(&copp->wait); + + } + break; + default: + dev_err(&adev->dev, "Unknown cmd:0x%x\n", + data->opcode); + break; + } + } + return 0; +} + +static struct copp *adm_alloc_copp(struct q6adm *adm, int port_idx) +{ + struct copp *c; + int idx; + + idx = find_first_zero_bit(&adm->copp_bitmap[port_idx], + MAX_COPPS_PER_PORT); + + if (idx > MAX_COPPS_PER_PORT) + return ERR_PTR(-EBUSY); + + set_bit(idx, &adm->copp_bitmap[port_idx]); + + c = devm_kzalloc(adm->dev, sizeof(*c), GFP_KERNEL); + if (!c) + return ERR_PTR(-ENOMEM); + c->copp_idx = idx; + c->afe_port = port_idx; + c->adm = adm; + + init_waitqueue_head(&c->wait); + + spin_lock(&adm->copps_list_lock); + list_add_tail(&c->node, &adm->copps_list); + spin_unlock(&adm->copps_list_lock); + + return c; +} + +static void adm_free_copp(struct q6adm *adm, struct copp *c, int port_idx) +{ + clear_bit(c->copp_idx, &adm->copp_bitmap[port_idx]); + spin_lock(&adm->copps_list_lock); + list_del(&c->node); + spin_unlock(&adm->copps_list_lock); +} +/** + * q6adm_open() - open adm to get hold of free copp + * + * @dev: Pointer to adm child device. + * @port_id: port id + * @path: playback or capture path. + * @rate: rate at which copp is required. + * @channel_mode: channel mode + * @topology: adm topology id + * @perf_mode: performace mode. + * @bit_width: audio sample bit width + * @app_type: Application type. + * @acdb_id: ACDB id + * + * Return: Will be an negative on error or a valid copp index on success. + */ +int q6adm_open(struct device *dev, int port_id, int path, int rate, + int channel_mode, int topology, int perf_mode, + uint16_t bit_width, int app_type, int acdb_id) +{ + struct adm_cmd_device_open_v5 { + struct apr_hdr hdr; + u16 flags; + u16 mode_of_operation; + u16 endpoint_id_1; + u16 endpoint_id_2; + u32 topology_id; + u16 dev_num_channel; + u16 bit_width; + u32 sample_rate; + u8 dev_channel_mapping[8]; + } __packed open; + int ret = 0; + int port_idx, flags; + int tmp_port = q6afe_get_port_id(port_id); + struct copp *copp; + struct q6adm *adm = dev_get_drvdata(dev->parent); + + port_idx = port_id; + if (port_idx < 0) { + dev_err(dev, "Invalid port_id 0x%x\n", port_id); + return -EINVAL; + } + + flags = ADM_LEGACY_DEVICE_SESSION; + copp = adm_find_matching_copp(adm, port_idx, topology, perf_mode, + rate, bit_width, app_type); + + if (!copp) { + copp = adm_alloc_copp(adm, port_idx); + if (IS_ERR_OR_NULL(copp)) + return PTR_ERR(copp); + + copp->cnt = 0; + copp->topology = topology; + copp->mode = perf_mode; + copp->rate = rate; + copp->channels = channel_mode; + copp->bit_width = bit_width; + copp->app_type = app_type; + } + + /* Create a COPP if port id are not enabled */ + if (copp->cnt == 0) { + + open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + open.hdr.pkt_size = sizeof(open); + open.hdr.src_svc = APR_SVC_ADM; + open.hdr.src_domain = APR_DOMAIN_APPS; + open.hdr.src_port = tmp_port; + open.hdr.dest_svc = APR_SVC_ADM; + open.hdr.dest_domain = APR_DOMAIN_ADSP; + open.hdr.dest_port = tmp_port; + open.hdr.token = port_idx << 16 | copp->copp_idx; + open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5; + open.flags = flags; + open.mode_of_operation = path; + open.endpoint_id_1 = tmp_port; + open.topology_id = topology; + open.dev_num_channel = channel_mode & 0x00FF; + open.bit_width = bit_width; + open.sample_rate = rate; + + ret = q6dsp_map_channels(&open.dev_channel_mapping[0], + channel_mode); + + if (ret) + return ret; + + copp->stat = -1; + ret = apr_send_pkt(adm->apr, (uint32_t *)&open); + if (ret < 0) { + dev_err(dev, "port_id: 0x%x for[0x%x] failed %d\n", + tmp_port, port_id, ret); + return -EINVAL; + } + /* Wait for the callback with copp id */ + ret = + wait_event_timeout(copp->wait, copp->stat >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + dev_err(dev, "ADM timedout port_id: 0x%x for [0x%x]\n", + tmp_port, port_id); + return -EINVAL; + } else if (copp->stat > 0) { + dev_err(dev, "DSP returned error[%s]\n", + adsp_err_get_err_str(copp->stat)); + return adsp_err_get_lnx_err_code(copp->stat); + } + } + copp->cnt++; + return copp->copp_idx; +} +EXPORT_SYMBOL_GPL(q6adm_open); +/** + * q6adm_matrix_map() - Map asm streams and afe ports using payload + * + * @dev: Pointer to adm child device. + * @path: playback or capture path. + * @payload_map: map between session id and afe ports. + * @perf_mode: Performace mode. + * + * Return: Will be an negative on error or a zero on success. + */ +int q6adm_matrix_map(struct device *dev, int path, + struct route_payload payload_map, int perf_mode) +{ + struct adm_cmd_matrix_map_routings_v5 { + struct apr_hdr hdr; + u32 matrix_id; + u32 num_sessions; + } __packed * route; + + struct adm_session_map_node_v5 { + u16 session_id; + u16 num_copps; + } __packed * node; + struct q6adm *adm = dev_get_drvdata(dev->parent); + uint16_t *copps_list; + int cmd_size = 0; + int ret = 0, i = 0; + void *payload = NULL; + void *matrix_map = NULL; + int port_idx, copp_idx; + struct copp *copp; + + /* Assumes port_ids have already been validated during adm_open */ + cmd_size = (sizeof(*route) + + sizeof(*node) + + (sizeof(uint32_t) * payload_map.num_copps)); + matrix_map = kzalloc(cmd_size, GFP_KERNEL); + if (!matrix_map) + return -ENOMEM; + + route = (struct adm_cmd_matrix_map_routings_v5 *)matrix_map; + route->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + route->hdr.pkt_size = cmd_size; + route->hdr.src_svc = 0; + route->hdr.src_domain = APR_DOMAIN_APPS; + route->hdr.src_port = 0; /* Ignored */ + route->hdr.dest_svc = APR_SVC_ADM; + route->hdr.dest_domain = APR_DOMAIN_ADSP; + route->hdr.dest_port = 0; /* Ignored */ + route->hdr.token = 0; + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->num_sessions = 1; + + switch (path) { + case ADM_PATH_PLAYBACK: + route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; + break; + default: + dev_err(dev, "Wrong path set[%d]\n", path); + + break; + } + + payload = ((u8 *) matrix_map + sizeof(*route)); + node = (struct adm_session_map_node_v5 *)payload; + + node->session_id = payload_map.session_id; + node->num_copps = payload_map.num_copps; + payload = (u8 *) node + sizeof(*node); + copps_list = (uint16_t *) payload; + + for (i = 0; i < payload_map.num_copps; i++) { + port_idx = payload_map.port_id[i]; + if (port_idx < 0) { + dev_err(dev, "Invalid port_id 0x%x\n", + payload_map.port_id[i]); + return -EINVAL; + } + copp_idx = payload_map.copp_idx[i]; + + copp = adm_find_copp(adm, port_idx, copp_idx); + if (IS_ERR_OR_NULL(copp)) + return -EINVAL; + + copps_list[i] = copp->id; + } + + adm->matrix_map_stat = -1; + + ret = apr_send_pkt(adm->apr, (uint32_t *) matrix_map); + if (ret < 0) { + dev_err(dev, "routing for syream %d failed ret %d\n", + payload_map.session_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + ret = wait_event_timeout(adm->matrix_map_wait, + adm->matrix_map_stat >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + dev_err(dev, "routing for syream %d failed\n", + payload_map.session_id); + ret = -EINVAL; + goto fail_cmd; + } else if (adm->matrix_map_stat > 0) { + dev_err(dev, "DSP returned error[%s]\n", + adsp_err_get_err_str(adm->matrix_map_stat)); + ret = adsp_err_get_lnx_err_code(adm->matrix_map_stat); + goto fail_cmd; + } + +fail_cmd: + kfree(matrix_map); + return ret; +} +EXPORT_SYMBOL_GPL(q6adm_matrix_map); + +static void adm_reset_copp(struct copp *c) +{ + c->id = RESET_COPP_ID; + c->cnt = 0; + c->topology = 0; + c->mode = 0; + c->stat = -1; + c->rate = 0; + c->channels = 0; + c->bit_width = 0; + c->app_type = 0; +} +/** + * q6adm_close() - Close adm copp + * + * @dev: Pointer to adm child device. + * @port_id: afe port id. + * @perf_mode: perf_mode mode + * @copp_idx: copp index to close + * + * Return: Will be an negative on error or a zero on success. + */ +int q6adm_close(struct device *dev, int port_id, int perf_mode, int copp_idx) +{ + struct apr_hdr close; + struct copp *copp; + + int ret = 0, port_idx; + int copp_id = RESET_COPP_ID; + struct q6adm *adm = dev_get_drvdata(dev->parent); + + port_idx = port_id; + if (port_idx < 0) { + dev_err(dev, "Invalid port_id 0x%x\n", port_id); + return -EINVAL; + } + + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + dev_err(dev, "Invalid copp idx: %d\n", copp_idx); + return -EINVAL; + } + + copp = adm_find_copp(adm, port_id, copp_idx); + if (IS_ERR_OR_NULL(copp)) + return -EINVAL; + + copp->cnt--; + if (!copp->cnt) { + copp_id = copp->id; + + close.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + close.pkt_size = sizeof(close); + close.src_svc = APR_SVC_ADM; + close.src_domain = APR_DOMAIN_APPS; + close.src_port = port_id; + close.dest_svc = APR_SVC_ADM; + close.dest_domain = APR_DOMAIN_ADSP; + close.dest_port = copp_id; + close.token = port_idx << 16 | copp_idx; + close.opcode = ADM_CMD_DEVICE_CLOSE_V5; + + ret = apr_send_pkt(adm->apr, (uint32_t *) &close); + if (ret < 0) { + dev_err(dev, "ADM close failed %d\n", ret); + return -EINVAL; + } + + ret = wait_event_timeout(copp->wait, copp->stat >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + dev_err(dev, "ADM cmd Route timedout for port 0x%x\n", + port_id); + return -EINVAL; + } else if (copp->stat > 0) { + dev_err(dev, "DSP returned error[%s]\n", + adsp_err_get_err_str(copp->stat)); + return adsp_err_get_lnx_err_code(copp->stat); + } + + adm_reset_copp(copp); + adm_free_copp(adm, copp, port_id); + } + + return 0; +} +EXPORT_SYMBOL_GPL(q6adm_close); + +static int q6adm_probe(struct apr_device *adev) +{ + struct q6adm *adm; + + adm = devm_kzalloc(&adev->dev, sizeof(*adm), GFP_KERNEL); + if (!adm) + return -ENOMEM; + + adm->apr = adev; + dev_set_drvdata(&adev->dev, adm); + adm->dev = &adev->dev; + adm->matrix_map_stat = 0; + init_waitqueue_head(&adm->matrix_map_wait); + + INIT_LIST_HEAD(&adm->copps_list); + spin_lock_init(&adm->copps_list_lock); + + adm->routing_dev = platform_device_register_data(&adev->dev, + "q6routing", + -1, NULL, 0); + + + return 0; +} + +static int q6adm_exit(struct apr_device *adev) +{ + struct q6adm *adm = dev_get_drvdata(&adev->dev); + + platform_device_unregister(adm->routing_dev); + + return 0; +} + +static const struct apr_device_id adm_id[] = { + {"Q6ADM", APR_DOMAIN_ADSP, APR_SVC_ADM, APR_CLIENT_AUDIO}, + {} +}; + +static struct apr_driver qcom_q6adm_driver = { + .probe = q6adm_probe, + .remove = q6adm_exit, + .callback = adm_callback, + .id_table = adm_id, + .driver = { + .name = "qcom-q6adm", + }, +}; + +module_apr_driver(qcom_q6adm_driver); +MODULE_DESCRIPTION("Q6 Audio Device Manager"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6adm.h b/sound/soc/qcom/qdsp6/q6adm.h new file mode 100644 index 000000000000..aa7b3ba4360b --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6adm.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __Q6_ADM_V2_H__ +#define __Q6_ADM_V2_H__ + +#define ADM_PATH_PLAYBACK 0x1 +#define MAX_COPPS_PER_PORT 8 +#define NULL_COPP_TOPOLOGY 0x00010312 + +/* multiple copp per stream. */ +struct route_payload { + int num_copps; + int session_id; + int copp_idx[MAX_COPPS_PER_PORT]; + int port_id[MAX_COPPS_PER_PORT]; +}; + +int q6adm_open(struct device *dev, int port_id, int path, int rate, + int channel_mode, int topology, int perf_mode, + uint16_t bit_width, int app_type, int acdb_id); +int q6adm_close(struct device *dev, int port, int topology, int perf_mode); +int q6adm_matrix_map(struct device *dev, int path, + struct route_payload payload_map, int perf_mode); + +#endif /* __Q6_ADM_V2_H__ */ From patchwork Thu Dec 14 17:34:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 122008 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp7107747qgn; Thu, 14 Dec 2017 09:38:58 -0800 (PST) X-Google-Smtp-Source: ACJfBosCriF8qGNGuOxz1JVETAeQp/LX2xk5L/g8d5tWBXjhRQ4U2zIzItZshDh1g2CAh5eknWZ6 X-Received: by 10.84.246.137 with SMTP id m9mr10306010pll.130.1513273138123; Thu, 14 Dec 2017 09:38:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513273138; cv=none; d=google.com; s=arc-20160816; b=R0SIAduVaT7cp7OEcmWpw/LkezyTFJjBw94ryetvyKLu1agdI7SgT5oR9LwAn3Dd7n Imu6WveITPKqLkd/EYEkKapwfEzCZPIBtYrFRXeg96aS7n+hQkg41dD/6eI7IDcEA4Fg 1t0DNroRLsb+dzv3yR3MuZaD/7q0vLM/IQNgq9v0MABDe8ZDaRyl+R5FBO8enSE3DHWi jc+7KIo5Kmm+Y8w8DRnX19zarxM6Dl8drlv+tTR6QZ5qP9B1ZFkaREUZ7kxjA2aX6jKQ SvvTXFYcFzBpPETlWoIu99HBSsSKeysk761Xg4Ck+tYigHO5lQnEQd63v1F+b2znlOrz /VMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=kP6W0p110awRV75hctOzMMq1qzFnApTc19eYy1kDQ+4=; b=LeA5jKzwxMG9gSs92mMgC42Z/vXUTbgY8W/FOaamV1s0RqUNPf3uOrq+AmPYcCKRed G0FwxkPghCd+dKceel2d9mHjpDZHZK/3iOioDP0cZ7XkbOqeBxLMOf2fy5y/cHrwRNxK VhM3Cr9YaTqQaxoLE9mDIoZCc7MC3moluC7DIsxcXEepFN36nwY1SvLDH2cBO+6amH73 o0dic4kJz1QellAecfiUahfaDrEa/p2obncwRbna+L5yiF86vBTsdOS46N0vwxojWNU2 Kt7EgfIOOA1k04g0btAdpKZa1emIvWXDfDSzwIozCCIgthwW1lKnrFqUUko5UilWEWor WB3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=bBEEv9tS; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q23si3191795pgc.47.2017.12.14.09.38.57; Thu, 14 Dec 2017 09:38:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=bBEEv9tS; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753877AbdLNRi4 (ORCPT + 10 others); Thu, 14 Dec 2017 12:38:56 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:37195 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753897AbdLNRgu (ORCPT ); Thu, 14 Dec 2017 12:36:50 -0500 Received: by mail-wm0-f68.google.com with SMTP id f140so12927219wmd.2 for ; Thu, 14 Dec 2017 09:36:49 -0800 (PST) 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; bh=CIxce/4lZ4m40iDYENrTsK72n8ByRc9vBTJqwEy+D6c=; b=bBEEv9tSTWk96TzI9WQwIbqXAfrpJkav1y+l+aWS5WUfX3wuBa4ioM54jT2TFygBTk CMHSruABRZo57MWKz98wtQPLxo90sAIa3kFIcJS4aA1DYdZlawgE7L0WFtw1VTWZw6VH OWpHMziKIhLWXUVmeqT82zINZ2+SPekMGOrDA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CIxce/4lZ4m40iDYENrTsK72n8ByRc9vBTJqwEy+D6c=; b=PUwNVVrJ2ts7ZYMwRzLnAu5juJQTLi6h8/s/mL8cTruKGGH0gEHySIIZN4erauPL2u 6f7Yk+mvpaKoBEpjl8+hI1I5LYWmZFHedS2PCl+9KmLFWlbCr2YkTkLLETH/F+qlk6F/ Y0xRWnvZFuW3ITLGvlRb+d4KTB4PqpjB+WyRxKRPM9wyVylRWSFhKKLjYP3gSgBX1Sbo pW0kbqGCKaFxx4pKZS3K7NbniwE7dPms9TsMVXJYLdohBy4aceT5FXdfewsu7H4D7S0g J70p+SXuvo0Vmy3m/DgO9yx6isnkJJIFMtXMdtv/guyTaD+dhYYAZdusfF9Gvo6RQYV9 k6OQ== X-Gm-Message-State: AKGB3mKRsqg3qOuQerOhUGIwBwQX/agOrZLe3s4Y3FOQQiaGbgi2H7Kh vXPpkI3kPTkFMjpXhRhOPnXw8Q== X-Received: by 10.28.198.75 with SMTP id w72mr3110633wmf.2.1513273009031; Thu, 14 Dec 2017 09:36:49 -0800 (PST) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id r82sm1741757wme.31.2017.12.14.09.36.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Dec 2017 09:36:48 -0800 (PST) From: srinivas.kandagatla@linaro.org To: Andy Gross , Mark Brown , linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org Cc: David Brown , Rob Herring , Mark Rutland , Liam Girdwood , Patrick Lai , Banajit Goswami , Jaroslav Kysela , Takashi Iwai , linux-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, sboyd@codeaurora.org, Srinivas Kandagatla Subject: [RESEND PATCH v2 13/15] dt-bindings: sound: qcom: Add devicetree bindings for apq8096 Date: Thu, 14 Dec 2017 17:34:00 +0000 Message-Id: <20171214173402.19074-14-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> References: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Srinivas Kandagatla Add devicetree bindings documentation file for Qualcomm apq8096 sound card. Signed-off-by: Srinivas Kandagatla --- .../devicetree/bindings/sound/qcom,apq8096.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,apq8096.txt -- 2.15.0 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8096.txt b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt new file mode 100644 index 000000000000..27b511dab533 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt @@ -0,0 +1,22 @@ +* Qualcomm Technologies APQ8096 ASoC sound card driver + +This binding describes the APQ8096 sound card, which uses qdsp for audio. + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,apq8096-sndcard" + +- qcom,audio-routing: + Usage: Optional + Value type: + Definition: A list of the connections between audio components. + Each entry is a pair of strings, the first being the + connection's sink, the second being the connection's + source. Valid names could be power supplies, MicBias + of codec and the jacks on the board: +Example: + sound { + compatible = "qcom,snd-apq8096"; + qcom,model = "DB820c"; + }; From patchwork Thu Dec 14 17:34:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 122003 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp7106047qgn; Thu, 14 Dec 2017 09:37:14 -0800 (PST) X-Google-Smtp-Source: ACJfBot0fXFG58U96zMMiRuByHqvwR40HSGfOMzyWjxyXgEOTRu+8FY0oruh4Ivh+wNEctuytIds X-Received: by 10.159.205.135 with SMTP id v7mr10178067plo.371.1513273034133; Thu, 14 Dec 2017 09:37:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513273034; cv=none; d=google.com; s=arc-20160816; b=Ebk6zmSV3Lv9+DBAR18OOhIQem8y2sNpdUNX3gZsMNPg0lUiF3SFRx+EYwmKQP/12j RVdCtn4B7dEGlE7O1DR0e6SDyqE3K9/54n6bmSVTFmfUiker9YlWT/oUsxgBMKN5AZRj k0/TlryC8wlVqt1UWOwGAD5qt8xqNVSXuxYbPHkzaXhh5d1OEfkZdNSXmp2rXi6pkCd7 LorUK4eLxfjMRQk1JRSN4byBjLlfDpzUcHXmCXDux4iX10yTx7lQ3UfTXG+/gYllr5Ql bOBe6EZnIcHQKo2ktldQdnik2LaJD1uQGy9iH6ISfjmX1mgwDlCdPMWn9Gf/hYI3HQVl XDHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=H3bx529xSFwNzdqVoDcBl51CNujrgek+CIRuGnCh0Sc=; b=P4cbV8/ChWLN2cjcy/t6uKHvsI7Jlu2DixsuICjHwlZLM/N43dc8YAn7jzch0KwkXO uKwDJh7pRoWnJ9haqR9UYgdwCQxyYZIGnPpl+orv8Waz7/vApp3PRmXhuJyb7LFse+ax NKjFRT5ul5wOKMfzrS+uRU7zZT4Upx5KkWSvuQsn9UBA3qipSb+DfVVVOoY5YfScPWHV OrXIfGs46ZOUEknST/CuhxIs30uKR3TwvR1/G/aT8DzVxP8FgZoKMtctH1C1bvNbt39H amqmGsUXDcKId7GjeCrktmIN/IDSxf0Kq/AwHmTzgA6Bnab7nOVdDxByh9Ln+R+Rr3Le 1VZw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=OwFZ4T7S; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r59si3420215plb.830.2017.12.14.09.37.13; Thu, 14 Dec 2017 09:37:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=OwFZ4T7S; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753920AbdLNRhL (ORCPT + 10 others); Thu, 14 Dec 2017 12:37:11 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:41937 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753880AbdLNRgx (ORCPT ); Thu, 14 Dec 2017 12:36:53 -0500 Received: by mail-wm0-f67.google.com with SMTP id g75so12945692wme.0 for ; Thu, 14 Dec 2017 09:36:53 -0800 (PST) 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; bh=ULUUZ5WmFHLaZcT68KslFCqjJW9uzV3bA4f/Y48ULGw=; b=OwFZ4T7Svs/peiij7t9w/KNBBR38sMGFlD+v1DMZhWHi1aKxqJWlZ/AcK2Wk1+mS3G 0nrVVbYU8pqaiJ2EG/axXQ6a3kCsunu9I/j9x6KUq3eI5e9pWQ4IEpyHwvj54X1LR6hv OeadT7HnAyqsGAZgDWzfxt91x/nPxWRbqzQwU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ULUUZ5WmFHLaZcT68KslFCqjJW9uzV3bA4f/Y48ULGw=; b=WU2wi6yEMMURPIfGFjcu0ZLO/JiL1Vuo0JhNLy36+/9wBCcpM+/4DA5X68FJGqUv6F RWZG13C7YYQ0G8nemqpTTDwnNEdEDU5rKBSKiceEdOnDL0O38HXLjgy8Co/nbrFwQ56A xI4Yqo3lvF7EoIO0zs0NURFapWIlNeQdEDv8yNk68kI3Fx+SBSd4rdjYmNkE5OI8RTTc 8wA9ouh3aDOMG6+R1tqgg3HJURXuxw9qeqJxf3K1LLLpFkSS5HeHseK82vvtUv+6hvmI PkrPnVI07VM2m4rNdR1yYPI+1Y1gJcMG7Nkq0975MIy0beUNaEGDiUvqvYHsQqsxAMW5 8+hA== X-Gm-Message-State: AKGB3mLqzWHAZQLKjC9sjy5DyOtQAYZ7o3LP/s0MB/sE7eXD1NeIVckQ CnmuoYJBZtNSYMwuMepWvbIxnQ== X-Received: by 10.28.150.12 with SMTP id y12mr3080161wmd.95.1513273012475; Thu, 14 Dec 2017 09:36:52 -0800 (PST) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id r82sm1741757wme.31.2017.12.14.09.36.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Dec 2017 09:36:51 -0800 (PST) From: srinivas.kandagatla@linaro.org To: Andy Gross , Mark Brown , linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org Cc: David Brown , Rob Herring , Mark Rutland , Liam Girdwood , Patrick Lai , Banajit Goswami , Jaroslav Kysela , Takashi Iwai , linux-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, sboyd@codeaurora.org, Srinivas Kandagatla Subject: [RESEND PATCH v2 15/15] arm64: dts: msm8996: db820c: Add sound card support Date: Thu, 14 Dec 2017 17:34:02 +0000 Message-Id: <20171214173402.19074-16-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> References: <20171214173402.19074-1-srinivas.kandagatla@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Srinivas Kandagatla This patch adds hdmi sound card support to db820c via qdsp. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 5 +++++ arch/arm64/boot/dts/qcom/msm8996.dtsi | 33 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) -- 2.15.0 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi index 9769053957af..b955769b100d 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi @@ -190,6 +190,11 @@ }; }; + snd { + compatible = "qcom,apq8096-sndcard"; + qcom,model = "DB820c"; + iommus = <&lpass_q6_smmu 1>; + }; gpio_keys { compatible = "gpio-keys"; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index a144cec7bb71..25c43fb8ab49 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1262,6 +1262,7 @@ phys = <&hdmi_phy>; phy-names = "hdmi_phy"; + #sound-dai-cells = <0>; ports { #address-cells = <1>; @@ -1297,6 +1298,33 @@ "ref_clk"; }; }; + + lpass_q6_smmu: arm,smmu-lpass_q6@1600000 { + compatible = "qcom,msm8996-smmu-v2"; + reg = <0x1600000 0x20000>; + #iommu-cells = <1>; + power-domains = <&gcc HLOS1_VOTE_LPASS_CORE_GDSC>; + + #global-interrupts = <1>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + ; + + clocks = <&gcc GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK>, + <&gcc GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK>; + clock-names = "iface", "bus"; + status = "okay"; + }; }; adsp-pil { @@ -1325,6 +1353,11 @@ qcom,ipc = <&apcs 16 8>; qcom,smd-edge = <1>; qcom,remote-pid = <2>; + + apr { + compatible = "qcom,apr-msm8996"; + qcom,smd-channels = "apr_audio_svc"; + }; }; };