From patchwork Wed Sep 23 12:24:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 291592 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 636E9C2D0A8 for ; Wed, 23 Sep 2020 12:27:04 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7F5602137B for ; Wed, 23 Sep 2020 12:27:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="hhDbm2yz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7F5602137B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 AA64A167A; Wed, 23 Sep 2020 14:26:10 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AA64A167A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864020; bh=u/dcVqeoRamitRJ3tkz1GqWY63PSw3mi7ptIbxp0fS8=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=hhDbm2yzbhGLGi7aJwF/DgkTP0zMxIoFoQLtpozknumASLbltDq7EUtuaz2o7kEjp bpAiVKKXCldOFqDQbf1mqIdtS2W2wUJ+q/Tq5Gi32YXcAOLkRMXPQREq6fJIbNa+yw R1STL28sxPJdQJ9xeuvt7LdS26cNs2oE+sBPO56Q= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 24484F80171; Wed, 23 Sep 2020 14:26:10 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 18741F800B4; Wed, 23 Sep 2020 14:26:07 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 757A3F800B4 for ; Wed, 23 Sep 2020 14:26:00 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 757A3F800B4 IronPort-SDR: lULcxl6k0VhrNTtt+2EphteiqcR9ZYOjYQU+9TyRh+Uvi2Jso7DdBZz3cl14D7GEcD53vS7/sA Q+cWVDIJ3PVw== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948204" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948204" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:25:58 -0700 IronPort-SDR: 0YbrTRjfNJDXJjmjIn0hrygWpieBl0ga+CATo5G3SIC/JTm9i0nIhCHy3LlRLDVQRMRCC6U4W7 +gtZV3ApWptg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338123" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:25:54 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 01/14] ASoC: Intel: Add catpt base members Date: Wed, 23 Sep 2020 14:24:55 +0200 Message-Id: <20200923122508.3360-2-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Declare base structures, registers and extension routines for the catpt solution. Signed-off-by: Cezary Rojewski --- sound/soc/intel/catpt/core.h | 86 ++++++++++++++ sound/soc/intel/catpt/dsp.c | 138 +++++++++++++++++++++++ sound/soc/intel/catpt/loader.c | 46 ++++++++ sound/soc/intel/catpt/registers.h | 179 ++++++++++++++++++++++++++++++ 4 files changed, 449 insertions(+) create mode 100644 sound/soc/intel/catpt/core.h create mode 100644 sound/soc/intel/catpt/dsp.c create mode 100644 sound/soc/intel/catpt/loader.c create mode 100644 sound/soc/intel/catpt/registers.h diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h new file mode 100644 index 000000000000..48952e93d86f --- /dev/null +++ b/sound/soc/intel/catpt/core.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Cezary Rojewski + */ + +#ifndef __SND_SOC_INTEL_CATPT_CORE_H +#define __SND_SOC_INTEL_CATPT_CORE_H + +#include +#include "registers.h" + +struct catpt_dev; + +void catpt_sram_init(struct resource *sram, u32 start, u32 size); +void catpt_sram_free(struct resource *sram); +struct resource * +catpt_request_region(struct resource *root, resource_size_t size); + +static inline bool catpt_resource_overlapping(struct resource *r1, + struct resource *r2, + struct resource *ret) +{ + if (!resource_overlaps(r1, r2)) + return false; + ret->start = max(r1->start, r2->start); + ret->end = min(r1->end, r2->end); + return true; +} + +struct catpt_module_type { + bool loaded; + u32 entry_point; + u32 persistent_size; + u32 scratch_size; + /* DRAM, initial module state */ + u32 state_offset; + u32 state_size; + + struct list_head node; +}; + +struct catpt_spec { + struct snd_soc_acpi_mach *machines; + u8 core_id; + u32 host_dram_offset; + u32 host_iram_offset; + u32 host_shim_offset; + u32 host_dma_offset[CATPT_DMA_COUNT]; + u32 host_ssp_offset[CATPT_SSP_COUNT]; + u32 dram_mask; + u32 iram_mask; + void (*pll_shutdown)(struct catpt_dev *cdev, bool enable); + int (*power_up)(struct catpt_dev *cdev); + int (*power_down)(struct catpt_dev *cdev); +}; + +struct catpt_dev { + struct device *dev; + struct dw_dma_chip *dmac; + + void __iomem *pci_ba; + void __iomem *lpe_ba; + u32 lpe_base; + int irq; + + const struct catpt_spec *spec; + struct completion fw_ready; + + struct resource dram; + struct resource iram; + struct resource *scratch; +}; + +int catpt_dmac_probe(struct catpt_dev *cdev); +void catpt_dmac_remove(struct catpt_dev *cdev); +struct dma_chan *catpt_dma_request_config_chan(struct catpt_dev *cdev); +int catpt_dma_memcpy_todsp(struct catpt_dev *cdev, struct dma_chan *chan, + dma_addr_t dst_addr, dma_addr_t src_addr, + size_t size); +int catpt_dma_memcpy_fromdsp(struct catpt_dev *cdev, struct dma_chan *chan, + dma_addr_t dst_addr, dma_addr_t src_addr, + size_t size); + +#endif diff --git a/sound/soc/intel/catpt/dsp.c b/sound/soc/intel/catpt/dsp.c new file mode 100644 index 000000000000..b0a61fcca50c --- /dev/null +++ b/sound/soc/intel/catpt/dsp.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include +#include "core.h" +#include "registers.h" + +static bool catpt_dma_filter(struct dma_chan *chan, void *param) +{ + return param == chan->device->dev; +} + +/* + * Either engine 0 or 1 can be used for image loading. + * Align with Windows driver equivalent and stick to engine 1. + */ +#define CATPT_DMA_DEVID 1 +#define CATPT_DMA_DSP_ADDR_MASK GENMASK(31, 20) + +struct dma_chan *catpt_dma_request_config_chan(struct catpt_dev *cdev) +{ + struct dma_slave_config config; + struct dma_chan *chan; + dma_cap_mask_t mask; + int ret; + + dma_cap_zero(mask); + dma_cap_set(DMA_MEMCPY, mask); + + chan = dma_request_channel(mask, catpt_dma_filter, cdev->dev); + if (!chan) { + dev_err(cdev->dev, "request channel failed\n"); + return ERR_PTR(-EPROBE_DEFER); + } + + memset(&config, 0, sizeof(config)); + config.direction = DMA_MEM_TO_DEV; + config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + config.src_maxburst = 16; + config.dst_maxburst = 16; + + ret = dmaengine_slave_config(chan, &config); + if (ret) { + dev_err(cdev->dev, "slave config failed: %d\n", ret); + dma_release_channel(chan); + return ERR_PTR(ret); + } + + return chan; +} + +static int catpt_dma_memcpy(struct catpt_dev *cdev, struct dma_chan *chan, + dma_addr_t dst_addr, dma_addr_t src_addr, + size_t size) +{ + struct dma_async_tx_descriptor *desc; + enum dma_status status; + + desc = dmaengine_prep_dma_memcpy(chan, dst_addr, src_addr, size, + DMA_CTRL_ACK); + if (!desc) { + dev_err(cdev->dev, "prep dma memcpy failed\n"); + return -EIO; + } + + /* enable demand mode for dma channel */ + catpt_updatel_shim(cdev, HMDC, + CATPT_HMDC_HDDA(CATPT_DMA_DEVID, chan->chan_id), + CATPT_HMDC_HDDA(CATPT_DMA_DEVID, chan->chan_id)); + dmaengine_submit(desc); + status = dma_wait_for_async_tx(desc); + /* regardless of status, disable access to HOST memory in demand mode */ + catpt_updatel_shim(cdev, HMDC, + CATPT_HMDC_HDDA(CATPT_DMA_DEVID, chan->chan_id), 0); + + return (status == DMA_COMPLETE) ? 0 : -EPROTO; +} + +int catpt_dma_memcpy_todsp(struct catpt_dev *cdev, struct dma_chan *chan, + dma_addr_t dst_addr, dma_addr_t src_addr, + size_t size) +{ + return catpt_dma_memcpy(cdev, chan, dst_addr | CATPT_DMA_DSP_ADDR_MASK, + src_addr, size); +} + +int catpt_dma_memcpy_fromdsp(struct catpt_dev *cdev, struct dma_chan *chan, + dma_addr_t dst_addr, dma_addr_t src_addr, + size_t size) +{ + return catpt_dma_memcpy(cdev, chan, dst_addr, + src_addr | CATPT_DMA_DSP_ADDR_MASK, size); +} + +int catpt_dmac_probe(struct catpt_dev *cdev) +{ + struct dw_dma_chip *dmac; + int ret; + + dmac = devm_kzalloc(cdev->dev, sizeof(*dmac), GFP_KERNEL); + if (!dmac) + return -ENOMEM; + + dmac->regs = cdev->lpe_ba + cdev->spec->host_dma_offset[CATPT_DMA_DEVID]; + dmac->dev = cdev->dev; + dmac->irq = cdev->irq; + + ret = dma_coerce_mask_and_coherent(cdev->dev, DMA_BIT_MASK(31)); + if (ret) + return ret; + /* + * Caller is responsible for putting device in D0 to allow + * for I/O and memory access before probing DW. + */ + ret = dw_dma_probe(dmac); + if (ret) + return ret; + + cdev->dmac = dmac; + return 0; +} + +void catpt_dmac_remove(struct catpt_dev *cdev) +{ + /* + * As do_dma_remove() juggles with pm_runtime_get_xxx() and + * pm_runtime_put_xxx() while both ADSP and DW 'devices' are part of + * the same module, caller makes sure pm_runtime_disable() is invoked + * before removing DW to prevent postmortem resume and suspend. + */ + dw_dma_remove(cdev->dmac); +} diff --git a/sound/soc/intel/catpt/loader.c b/sound/soc/intel/catpt/loader.c new file mode 100644 index 000000000000..3a7e5b396a86 --- /dev/null +++ b/sound/soc/intel/catpt/loader.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include +#include "core.h" + +void catpt_sram_init(struct resource *sram, u32 start, u32 size) +{ + sram->start = start; + sram->end = start + size - 1; +} + +void catpt_sram_free(struct resource *sram) +{ + struct resource *res, *save; + + for (res = sram->child; res;) { + save = res->sibling; + release_resource(res); + kfree(res); + res = save; + } +} + +struct resource * +catpt_request_region(struct resource *root, resource_size_t size) +{ + struct resource *res = root->child; + resource_size_t addr = root->start; + + for (;;) { + if (res->start - addr >= size) + break; + addr = res->end + 1; + res = res->sibling; + if (!res) + return NULL; + } + + return __request_region(root, addr, size, NULL, 0); +} diff --git a/sound/soc/intel/catpt/registers.h b/sound/soc/intel/catpt/registers.h new file mode 100644 index 000000000000..a051d8b36d88 --- /dev/null +++ b/sound/soc/intel/catpt/registers.h @@ -0,0 +1,179 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Cezary Rojewski + */ + +#ifndef __SND_SOC_INTEL_CATPT_REGS_H +#define __SND_SOC_INTEL_CATPT_REGS_H + +#include +#include +#include + +#define CATPT_SHIM_REGS_SIZE 4096 +#define CATPT_DMA_REGS_SIZE 1024 +#define CATPT_DMA_COUNT 2 +#define CATPT_SSP_COUNT 2 +#define CATPT_SSP_REGS_SIZE 512 + +/* DSP Shim registers */ + +#define CATPT_SHIM_CS1 0x00 +#define CATPT_SHIM_ISC 0x18 +#define CATPT_SHIM_ISD 0x20 +#define CATPT_SHIM_IMC 0x28 +#define CATPT_SHIM_IMD 0x30 +#define CATPT_SHIM_IPCC 0x38 +#define CATPT_SHIM_IPCD 0x40 +#define CATPT_SHIM_CLKCTL 0x78 +#define CATPT_SHIM_CS2 0x80 +#define CATPT_SHIM_LTRC 0xE0 +#define CATPT_SHIM_HMDC 0xE8 + +#define CATPT_CS_LPCS BIT(31) +#define CATPT_CS_SFCR(ssp) BIT(27 + (ssp)) +#define CATPT_CS_S1IOCS BIT(23) +#define CATPT_CS_S0IOCS BIT(21) +#define CATPT_CS_PCE BIT(15) +#define CATPT_CS_SDPM(ssp) BIT(11 + (ssp)) +#define CATPT_CS_STALL BIT(10) +#define CATPT_CS_DCS GENMASK(6, 4) +/* b100 DSP core & audio fabric high clock */ +#define CATPT_CS_DCS_HIGH (0x4 << 4) +#define CATPT_CS_SBCS(ssp) BIT(2 + (ssp)) +#define CATPT_CS_RST BIT(1) + +#define CATPT_ISC_IPCDB BIT(1) +#define CATPT_ISC_IPCCD BIT(0) +#define CATPT_ISD_DCPWM BIT(31) +#define CATPT_ISD_IPCCB BIT(1) +#define CATPT_ISD_IPCDD BIT(0) + +#define CATPT_IMC_IPCDB BIT(1) +#define CATPT_IMC_IPCCD BIT(0) +#define CATPT_IMD_IPCCB BIT(1) +#define CATPT_IMD_IPCDD BIT(0) + +#define CATPT_IPCC_BUSY BIT(31) +#define CATPT_IPCC_DONE BIT(30) +#define CATPT_IPCD_BUSY BIT(31) +#define CATPT_IPCD_DONE BIT(30) + +#define CATPT_CLKCTL_CFCIP BIT(31) +#define CATPT_CLKCTL_SMOS GENMASK(25, 24) + +#define CATPT_HMDC_HDDA(e, ch) BIT(8 * (e) + (ch)) + +/* defaults to reset SHIM registers to after each power cycle */ +#define CATPT_CS_DEFAULT 0x8480040E +#define CATPT_ISC_DEFAULT 0x0 +#define CATPT_ISD_DEFAULT 0x0 +#define CATPT_IMC_DEFAULT 0x7FFF0003 +#define CATPT_IMD_DEFAULT 0x7FFF0003 +#define CATPT_IPCC_DEFAULT 0x0 +#define CATPT_IPCD_DEFAULT 0x0 +#define CATPT_CLKCTL_DEFAULT 0x7FF +#define CATPT_CS2_DEFAULT 0x0 +#define CATPT_LTRC_DEFAULT 0x0 +#define CATPT_HMDC_DEFAULT 0x0 + +/* PCI Configuration registers */ + +#define CATPT_PCI_PMCAPID 0x80 +#define CATPT_PCI_PMCS (CATPT_PCI_PMCAPID + PCI_PM_CTRL) +#define CATPT_PCI_VDRTCTL0 0xA0 +#define CATPT_PCI_VDRTCTL2 0xA8 + +#define CATPT_VDRTCTL2_DTCGE BIT(10) +#define CATPT_VDRTCTL2_DCLCGE BIT(1) +#define CATPT_VDRTCTL2_CGEALL 0xF7F + +/* LPT PCI Configuration bits */ + +#define LPT_VDRTCTL0_DSRAMPGE(b) BIT(16 + (b)) +#define LPT_VDRTCTL0_DSRAMPGE_MASK GENMASK(31, 16) +#define LPT_VDRTCTL0_ISRAMPGE(b) BIT(6 + (b)) +#define LPT_VDRTCTL0_ISRAMPGE_MASK GENMASK(15, 6) +#define LPT_VDRTCTL0_D3SRAMPGD BIT(2) +#define LPT_VDRTCTL0_D3PGD BIT(1) +#define LPT_VDRTCTL0_APLLSE BIT(0) + +/* WPT PCI Configuration bits */ + +#define WPT_VDRTCTL0_DSRAMPGE(b) BIT(12 + (b)) +#define WPT_VDRTCTL0_DSRAMPGE_MASK GENMASK(31, 12) +#define WPT_VDRTCTL0_ISRAMPGE(b) BIT(2 + (b)) +#define WPT_VDRTCTL0_ISRAMPGE_MASK GENMASK(11, 2) +#define WPT_VDRTCTL0_D3SRAMPGD BIT(1) +#define WPT_VDRTCTL0_D3PGD BIT(0) + +#define WPT_VDRTCTL2_APLLSE BIT(31) + +/* defaults to reset SSP registers to after each power cycle */ +#define CATPT_SSC0_DEFAULT 0x0 +#define CATPT_SSC1_DEFAULT 0x0 +#define CATPT_SSS_DEFAULT 0xF004 +#define CATPT_SSIT_DEFAULT 0x0 +#define CATPT_SSD_DEFAULT 0xC43893A3 +#define CATPT_SSTO_DEFAULT 0x0 +#define CATPT_SSPSP_DEFAULT 0x0 +#define CATPT_SSTSA_DEFAULT 0x0 +#define CATPT_SSRSA_DEFAULT 0x0 +#define CATPT_SSTSS_DEFAULT 0x0 +#define CATPT_SSCR2_DEFAULT 0x0 +#define CATPT_SSPSP2_DEFAULT 0x0 + +/* Physically the same block, access address differs between host and dsp */ +#define CATPT_DSP_DRAM_OFFSET 0x400000 +#define catpt_to_host_offset(offset) ((offset) & ~(CATPT_DSP_DRAM_OFFSET)) +#define catpt_to_dsp_offset(offset) ((offset) | CATPT_DSP_DRAM_OFFSET) + +#define CATPT_MEMBLOCK_SIZE 0x8000 +#define catpt_num_dram(cdev) (hweight_long((cdev)->spec->dram_mask)) +#define catpt_num_iram(cdev) (hweight_long((cdev)->spec->iram_mask)) +#define catpt_dram_size(cdev) (catpt_num_dram(cdev) * CATPT_MEMBLOCK_SIZE) +#define catpt_iram_size(cdev) (catpt_num_iram(cdev) * CATPT_MEMBLOCK_SIZE) + +/* registry I/O helpers */ + +#define catpt_shim_addr(cdev) \ + ((cdev)->lpe_ba + (cdev)->spec->host_shim_offset) +#define catpt_dma_addr(cdev, dma) \ + ((cdev)->lpe_ba + (cdev)->spec->host_dma_offset[dma]) +#define catpt_ssp_addr(cdev, ssp) \ + ((cdev)->lpe_ba + (cdev)->spec->host_ssp_offset[ssp]) +#define catpt_inbox_addr(cdev) \ + ((cdev)->lpe_ba + (cdev)->ipc.config.inbox_offset) +#define catpt_outbox_addr(cdev) \ + ((cdev)->lpe_ba + (cdev)->ipc.config.outbox_offset) + +#define catpt_writel_ssp(cdev, ssp, reg, val) \ + writel(val, catpt_ssp_addr(cdev, ssp) + (reg)) + +#define catpt_readl_shim(cdev, reg) \ + readl(catpt_shim_addr(cdev) + CATPT_SHIM_##reg) +#define catpt_writel_shim(cdev, reg, val) \ + writel(val, catpt_shim_addr(cdev) + CATPT_SHIM_##reg) +#define catpt_updatel_shim(cdev, reg, mask, val) \ + catpt_writel_shim(cdev, reg, \ + (catpt_readl_shim(cdev, reg) & ~(mask)) | (val)) + +#define catpt_readl_poll_shim(cdev, reg, val, cond, delay_us, timeout_us) \ + readl_poll_timeout(catpt_shim_addr(cdev) + CATPT_SHIM_##reg, \ + val, cond, delay_us, timeout_us) + +#define catpt_readl_pci(cdev, reg) \ + readl(cdev->pci_ba + CATPT_PCI_##reg) +#define catpt_writel_pci(cdev, reg, val) \ + writel(val, cdev->pci_ba + CATPT_PCI_##reg) +#define catpt_updatel_pci(cdev, reg, mask, val) \ + catpt_writel_pci(cdev, reg, \ + (catpt_readl_pci(cdev, reg) & ~(mask)) | (val)) + +#define catpt_readl_poll_pci(cdev, reg, val, cond, delay_us, timeout_us) \ + readl_poll_timeout((cdev)->pci_ba + CATPT_PCI_##reg, \ + val, cond, delay_us, timeout_us) + +#endif From patchwork Wed Sep 23 12:24:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 250910 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B13F8C2D0A8 for ; Wed, 23 Sep 2020 12:27:56 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 87A352137B for ; Wed, 23 Sep 2020 12:27:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="hX/02+4O" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 87A352137B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 9AF5D16CE; Wed, 23 Sep 2020 14:27:03 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9AF5D16CE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864073; bh=x0mCqoKab6BvTFrXiDHuiJJoDFV69Xukjh3XvtSyPEA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=hX/02+4O4LDEihRw7zRuS38NzIVZwcwZUxtRoH95/erZEHjFdCVM9z7di4Yzai4rp WNAtHDuFKOU7fXT5OTw7vGnc4qRpTLlee+T4FgyNRtsrpxLeK7luh/mY36imO/c7Th eJxN2wSG6CDKqJ29pgffS1FxsUO4TVu6mYTtuFg4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 60940F8028D; Wed, 23 Sep 2020 14:26:11 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 023B7F8021C; Wed, 23 Sep 2020 14:26:07 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 10001F8015F for ; Wed, 23 Sep 2020 14:26:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 10001F8015F IronPort-SDR: KZKTdyLTK4s7Gg9uKIXnYhR4zgghiYvBnu8pba3g8iH5r/iWbFZpRKLjxYFdNE6hJTaM5mt0fe MP3w8kvDMHCg== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948208" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948208" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:02 -0700 IronPort-SDR: ESWB3GZG5zY/Rhb4YkPWdiu1/vlnD5N3UKSG8yxvT2RoScWK6xjOii8zLn4iGc9L+rILiwncou GghgJM3CM3Ow== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338154" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:25:58 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 02/14] ASoC: Intel: catpt: Implement IPC protocol Date: Wed, 23 Sep 2020 14:24:56 +0200 Message-Id: <20200923122508.3360-3-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Implement IRQ handlers for immediate and delayed replies and notifications. Communication is synchronous and allows for serialization of maximum one message at a time. DSP may respond with ADSP_PENDING status for a request - known as delayed reply - and when situation occurs, framework keeps the lock and awaits upcoming response through IPCD channel which is handled in bottom-half. Immediate replies spawn no BH at all as their processing is very short. Signed-off-by: Cezary Rojewski --- sound/soc/intel/catpt/core.h | 44 ++++ sound/soc/intel/catpt/ipc.c | 246 ++++++++++++++++++ sound/soc/intel/catpt/messages.h | 401 ++++++++++++++++++++++++++++++ sound/soc/intel/catpt/registers.h | 1 - 4 files changed, 691 insertions(+), 1 deletion(-) create mode 100644 sound/soc/intel/catpt/ipc.c create mode 100644 sound/soc/intel/catpt/messages.h diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h index 48952e93d86f..8819d928e891 100644 --- a/sound/soc/intel/catpt/core.h +++ b/sound/soc/intel/catpt/core.h @@ -9,6 +9,8 @@ #define __SND_SOC_INTEL_CATPT_CORE_H #include +#include +#include "messages.h" #include "registers.h" struct catpt_dev; @@ -29,6 +31,31 @@ static inline bool catpt_resource_overlapping(struct resource *r1, return true; } +struct catpt_ipc_msg { + union { + u32 header; + union catpt_global_msg rsp; + }; + void *data; + size_t size; +}; + +struct catpt_ipc { + struct device *dev; + + struct catpt_ipc_msg rx; + struct catpt_fw_ready config; + u32 default_timeout; + bool ready; + + spinlock_t lock; + struct mutex mutex; + struct completion done_completion; + struct completion busy_completion; +}; + +void catpt_ipc_init(struct catpt_ipc *ipc, struct device *dev); + struct catpt_module_type { bool loaded; u32 entry_point; @@ -59,6 +86,7 @@ struct catpt_spec { struct catpt_dev { struct device *dev; struct dw_dma_chip *dmac; + struct catpt_ipc ipc; void __iomem *pci_ba; void __iomem *lpe_ba; @@ -83,4 +111,20 @@ int catpt_dma_memcpy_fromdsp(struct catpt_dev *cdev, struct dma_chan *chan, dma_addr_t dst_addr, dma_addr_t src_addr, size_t size); +irqreturn_t catpt_dsp_irq_handler(int irq, void *dev_id); +irqreturn_t catpt_dsp_irq_thread(int irq, void *dev_id); + +/* + * IPC handlers may return positive values which denote successful + * HOST <-> DSP communication yet failure to process specific request. + * Use below macro to convert returned non-zero values appropriately + */ +#define CATPT_IPC_ERROR(err) (((err) < 0) ? (err) : -EREMOTEIO) + +int catpt_dsp_send_msg_timeout(struct catpt_dev *cdev, + struct catpt_ipc_msg request, + struct catpt_ipc_msg *reply, int timeout); +int catpt_dsp_send_msg(struct catpt_dev *cdev, struct catpt_ipc_msg request, + struct catpt_ipc_msg *reply); + #endif diff --git a/sound/soc/intel/catpt/ipc.c b/sound/soc/intel/catpt/ipc.c new file mode 100644 index 000000000000..7474bc73c73a --- /dev/null +++ b/sound/soc/intel/catpt/ipc.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include "core.h" +#include "messages.h" +#include "registers.h" + +#define CATPT_IPC_TIMEOUT_MS 300 + +void catpt_ipc_init(struct catpt_ipc *ipc, struct device *dev) +{ + ipc->dev = dev; + ipc->ready = false; + ipc->default_timeout = CATPT_IPC_TIMEOUT_MS; + init_completion(&ipc->done_completion); + init_completion(&ipc->busy_completion); + spin_lock_init(&ipc->lock); + mutex_init(&ipc->mutex); +} + +static int catpt_ipc_arm(struct catpt_ipc *ipc, struct catpt_fw_ready *config) +{ + /* + * Both tx and rx are put into and received from outbox. Inbox is + * only used for notifications where payload size is known upfront, + * thus no separate buffer is allocated for it. + */ + ipc->rx.data = devm_kzalloc(ipc->dev, config->outbox_size, GFP_KERNEL); + if (!ipc->rx.data) + return -ENOMEM; + + memcpy(&ipc->config, config, sizeof(*config)); + ipc->ready = true; + + return 0; +} + +static void catpt_ipc_msg_init(struct catpt_ipc *ipc, + struct catpt_ipc_msg *reply) +{ + lockdep_assert_held(&ipc->lock); + + ipc->rx.header = 0; + ipc->rx.size = reply ? reply->size : 0; + reinit_completion(&ipc->done_completion); + reinit_completion(&ipc->busy_completion); +} + +static void catpt_dsp_send_tx(struct catpt_dev *cdev, + const struct catpt_ipc_msg *tx) +{ + u32 header = tx->header | CATPT_IPCC_BUSY; + + if (tx->size) + memcpy_toio(catpt_outbox_addr(cdev), tx->data, tx->size); + catpt_writel_shim(cdev, IPCC, header); +} + +static int catpt_wait_msg_completion(struct catpt_dev *cdev, int timeout) +{ + struct catpt_ipc *ipc = &cdev->ipc; + int ret; + + ret = wait_for_completion_timeout(&ipc->done_completion, + msecs_to_jiffies(timeout)); + if (!ret) + return -ETIMEDOUT; + if (ipc->rx.rsp.status != CATPT_REPLY_PENDING) + return 0; + + /* wait for delayed reply */ + ret = wait_for_completion_timeout(&ipc->busy_completion, + msecs_to_jiffies(timeout)); + return ret ? 0 : -ETIMEDOUT; +} + +static int catpt_dsp_do_send_msg(struct catpt_dev *cdev, + struct catpt_ipc_msg request, + struct catpt_ipc_msg *reply, int timeout) +{ + struct catpt_ipc *ipc = &cdev->ipc; + unsigned long flags; + int ret; + + if (!ipc->ready) + return -EPERM; + if (request.size > ipc->config.outbox_size || + (reply && reply->size > ipc->config.outbox_size)) + return -EINVAL; + + spin_lock_irqsave(&ipc->lock, flags); + catpt_ipc_msg_init(ipc, reply); + catpt_dsp_send_tx(cdev, &request); + spin_unlock_irqrestore(&ipc->lock, flags); + + ret = catpt_wait_msg_completion(cdev, timeout); + if (ret) { + dev_crit(cdev->dev, "communication severed: %d, rebooting dsp..\n", + ret); + ipc->ready = false; + /* TODO: attempt recovery */ + return ret; + } + + ret = ipc->rx.rsp.status; + if (reply) { + reply->header = ipc->rx.header; + if (!ret && reply->data && reply->size) + memcpy(reply->data, ipc->rx.data, ipc->rx.size); + } + + return ret; +} + +int catpt_dsp_send_msg_timeout(struct catpt_dev *cdev, + struct catpt_ipc_msg request, + struct catpt_ipc_msg *reply, int timeout) +{ + struct catpt_ipc *ipc = &cdev->ipc; + int ret; + + mutex_lock(&ipc->mutex); + ret = catpt_dsp_do_send_msg(cdev, request, reply, timeout); + mutex_unlock(&ipc->mutex); + + return ret; +} + +int catpt_dsp_send_msg(struct catpt_dev *cdev, struct catpt_ipc_msg request, + struct catpt_ipc_msg *reply) +{ + return catpt_dsp_send_msg_timeout(cdev, request, reply, + cdev->ipc.default_timeout); +} + +static void catpt_dsp_copy_rx(struct catpt_dev *cdev, u32 header) +{ + struct catpt_ipc *ipc = &cdev->ipc; + + ipc->rx.header = header; + if (ipc->rx.size && ipc->rx.rsp.status == CATPT_REPLY_SUCCESS) { + memcpy_fromio(ipc->rx.data, catpt_outbox_addr(cdev), + ipc->rx.size); + } +} + +static void catpt_dsp_process_response(struct catpt_dev *cdev, u32 header) +{ + union catpt_notify_msg msg = CATPT_MSG(header); + struct catpt_ipc *ipc = &cdev->ipc; + + if (msg.fw_ready) { + struct catpt_fw_ready config; + /* to fit 32b header original address is shifted right by 3 */ + u32 off = msg.mailbox_address << 3; + + memcpy_fromio(&config, cdev->lpe_ba + off, sizeof(config)); + + catpt_ipc_arm(ipc, &config); + complete(&cdev->fw_ready); + return; + } + + switch (msg.global_msg_type) { + case CATPT_GLB_REQUEST_CORE_DUMP: + break; + + case CATPT_GLB_STREAM_MESSAGE: + switch (msg.stream_msg_type) { + case CATPT_STRM_NOTIFICATION: + break; + default: + catpt_dsp_copy_rx(cdev, header); + /* signal completion of delayed reply */ + complete(&ipc->busy_completion); + break; + } + break; + + default: + dev_warn(cdev->dev, "unknown response: %d received\n", + msg.global_msg_type); + break; + } +} + +irqreturn_t catpt_dsp_irq_thread(int irq, void *dev_id) +{ + struct catpt_dev *cdev = dev_id; + u32 ipcd; + + ipcd = catpt_readl_shim(cdev, IPCD); + + /* ensure there is delayed reply or notification to process */ + if (!(ipcd & CATPT_IPCD_BUSY)) + return IRQ_NONE; + + catpt_dsp_process_response(cdev, ipcd); + + /* tell DSP processing is completed */ + catpt_updatel_shim(cdev, IPCD, CATPT_IPCD_BUSY | CATPT_IPCD_DONE, + CATPT_IPCD_DONE); + /* unmask dsp BUSY interrupt */ + catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCDB, 0); + + return IRQ_HANDLED; +} + +irqreturn_t catpt_dsp_irq_handler(int irq, void *dev_id) +{ + struct catpt_dev *cdev = dev_id; + irqreturn_t ret = IRQ_NONE; + u32 isc, ipcc; + + isc = catpt_readl_shim(cdev, ISC); + + /* immediate reply */ + if (isc & CATPT_ISC_IPCCD) { + /* mask host DONE interrupt */ + catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCCD, CATPT_IMC_IPCCD); + + ipcc = catpt_readl_shim(cdev, IPCC); + catpt_dsp_copy_rx(cdev, ipcc); + complete(&cdev->ipc.done_completion); + + /* tell DSP processing is completed */ + catpt_updatel_shim(cdev, IPCC, CATPT_IPCC_DONE, 0); + /* unmask host DONE interrupt */ + catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCCD, 0); + ret = IRQ_HANDLED; + } + + /* delayed reply or notification */ + if (isc & CATPT_ISC_IPCDB) { + /* mask dsp BUSY interrupt */ + catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCDB, CATPT_IMC_IPCDB); + ret = IRQ_WAKE_THREAD; + } + + return ret; +} diff --git a/sound/soc/intel/catpt/messages.h b/sound/soc/intel/catpt/messages.h new file mode 100644 index 000000000000..1c51d142c177 --- /dev/null +++ b/sound/soc/intel/catpt/messages.h @@ -0,0 +1,401 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Cezary Rojewski + */ + +#ifndef __SND_SOC_INTEL_CATPT_MSG_H +#define __SND_SOC_INTEL_CATPT_MSG_H + +struct catpt_dev; + +/* IPC messages base types */ + +enum catpt_reply_status { + CATPT_REPLY_SUCCESS = 0, + CATPT_REPLY_ERROR_INVALID_PARAM = 1, + CATPT_REPLY_UNKNOWN_MESSAGE_TYPE = 2, + CATPT_REPLY_OUT_OF_RESOURCES = 3, + CATPT_REPLY_BUSY = 4, + CATPT_REPLY_PENDING = 5, + CATPT_REPLY_FAILURE = 6, + CATPT_REPLY_INVALID_REQUEST = 7, + CATPT_REPLY_UNINITIALIZED = 8, + CATPT_REPLY_NOT_FOUND = 9, + CATPT_REPLY_SOURCE_NOT_STARTED = 10, +}; + +/* GLOBAL messages */ + +enum catpt_global_msg_type { + CATPT_GLB_GET_FW_VERSION = 0, + CATPT_GLB_ALLOCATE_STREAM = 3, + CATPT_GLB_FREE_STREAM = 4, + CATPT_GLB_STREAM_MESSAGE = 6, + CATPT_GLB_REQUEST_CORE_DUMP = 7, + CATPT_GLB_SET_DEVICE_FORMATS = 10, + CATPT_GLB_ENTER_DX_STATE = 12, + CATPT_GLB_GET_MIXER_STREAM_INFO = 13, +}; + +union catpt_global_msg { + u32 val; + struct { + u32 status:5; + u32 context:19; /* stream or module specific */ + u32 global_msg_type:5; + u32 fw_ready:1; + u32 done:1; + u32 busy:1; + }; +} __packed; + +#define CATPT_MSG(hdr) { .val = hdr } +#define CATPT_GLOBAL_MSG(msg_type) \ + { .global_msg_type = CATPT_GLB_##msg_type } + +#define BUILD_HASH_SIZE 40 + +struct catpt_fw_version { + u8 build; + u8 minor; + u8 major; + u8 type; + u8 build_hash[BUILD_HASH_SIZE]; + u32 log_providers_hash; +} __packed; + +int catpt_ipc_get_fw_version(struct catpt_dev *cdev, + struct catpt_fw_version *version); + +enum catpt_pin_id { + CATPT_PIN_ID_SYSTEM = 0, + CATPT_PIN_ID_REFERENCE = 1, + CATPT_PIN_ID_CAPTURE1 = 2, + CATPT_PIN_ID_CAPTURE2 = 3, + CATPT_PIN_ID_OFFLOAD1 = 4, + CATPT_PIN_ID_OFFLOAD2 = 5, + CATPT_PIN_ID_MIXER = 7, + CATPT_PIN_ID_BLUETOOTH_CAPTURE = 8, + CATPT_PIN_ID_BLUETOOTH_RENDER = 9, +}; + +enum catpt_path_id { + CATPT_PATH_SSP0_OUT = 0, + CATPT_PATH_SSP0_IN = 1, + CATPT_PATH_SSP1_OUT = 2, + CATPT_PATH_SSP1_IN = 3, + /* duplicated audio in capture path */ + CATPT_PATH_SSP0_IN_DUP = 4, +}; + +enum catpt_stream_type { + CATPT_STRM_TYPE_RENDER = 0, /* offload */ + CATPT_STRM_TYPE_SYSTEM = 1, + CATPT_STRM_TYPE_CAPTURE = 2, + CATPT_STRM_TYPE_LOOPBACK = 3, + CATPT_STRM_TYPE_BLUETOOTH_RENDER = 4, + CATPT_STRM_TYPE_BLUETOOTH_CAPTURE = 5, +}; + +enum catpt_format_id { + CATPT_FORMAT_PCM = 0, + CATPT_FORMAT_MP3 = 1, + CATPT_FORMAT_AAC = 2, + CATPT_FORMAT_WMA = 3, +}; + +enum catpt_channel_index { + CATPT_CHANNEL_LEFT = 0x0, + CATPT_CHANNEL_CENTER = 0x1, + CATPT_CHANNEL_RIGHT = 0x2, + CATPT_CHANNEL_LEFT_SURROUND = 0x3, + CATPT_CHANNEL_CENTER_SURROUND = 0x3, + CATPT_CHANNEL_RIGHT_SURROUND = 0x4, + CATPT_CHANNEL_LFE = 0x7, + CATPT_CHANNEL_INVALID = 0xF, +}; + +enum catpt_channel_config { + CATPT_CHANNEL_CONFIG_MONO = 0, /* One channel only */ + CATPT_CHANNEL_CONFIG_STEREO = 1, /* L & R */ + CATPT_CHANNEL_CONFIG_2_POINT_1 = 2, /* L, R & LFE; PCM only */ + CATPT_CHANNEL_CONFIG_3_POINT_0 = 3, /* L, C & R; MP3 & AAC only */ + CATPT_CHANNEL_CONFIG_3_POINT_1 = 4, /* L, C, R & LFE; PCM only */ + CATPT_CHANNEL_CONFIG_QUATRO = 5, /* L, R, Ls & Rs; PCM only */ + CATPT_CHANNEL_CONFIG_4_POINT_0 = 6, /* L, C, R & Cs; MP3 & AAC only */ + CATPT_CHANNEL_CONFIG_5_POINT_0 = 7, /* L, C, R, Ls & Rs */ + CATPT_CHANNEL_CONFIG_5_POINT_1 = 8, /* L, C, R, Ls, Rs & LFE */ + CATPT_CHANNEL_CONFIG_DUAL_MONO = 9, /* One channel replicated in two */ + CATPT_CHANNEL_CONFIG_INVALID = 10, +}; + +enum catpt_interleaving_style { + CATPT_INTERLEAVING_PER_CHANNEL = 0, + CATPT_INTERLEAVING_PER_SAMPLE = 1, +}; + +struct catpt_audio_format { + u32 sample_rate; + u32 bit_depth; + u32 channel_map; + u32 channel_config; + u32 interleaving; + u8 num_channels; + u8 valid_bit_depth; + u8 reserved[2]; +} __packed; + +struct catpt_ring_info { + u32 page_table_addr; + u32 num_pages; + u32 size; + u32 offset; + u32 ring_first_page_pfn; +} __packed; + +#define CATPT_MODULE_COUNT (CATPT_MODID_LAST + 1) + +enum catpt_module_id { + CATPT_MODID_BASE_FW = 0x0, + CATPT_MODID_MP3 = 0x1, + CATPT_MODID_AAC_5_1 = 0x2, + CATPT_MODID_AAC_2_0 = 0x3, + CATPT_MODID_SRC = 0x4, + CATPT_MODID_WAVES = 0x5, + CATPT_MODID_DOLBY = 0x6, + CATPT_MODID_BOOST = 0x7, + CATPT_MODID_LPAL = 0x8, + CATPT_MODID_DTS = 0x9, + CATPT_MODID_PCM_CAPTURE = 0xA, + CATPT_MODID_PCM_SYSTEM = 0xB, + CATPT_MODID_PCM_REFERENCE = 0xC, + CATPT_MODID_PCM = 0xD, /* offload */ + CATPT_MODID_BLUETOOTH_RENDER = 0xE, + CATPT_MODID_BLUETOOTH_CAPTURE = 0xF, + CATPT_MODID_LAST = CATPT_MODID_BLUETOOTH_CAPTURE, +}; + +struct catpt_module_entry { + u32 module_id; + u32 entry_point; +} __packed; + +struct catpt_module_map { + u8 num_entries; + struct catpt_module_entry entries[]; +} __packed; + +struct catpt_memory_info { + u32 offset; + u32 size; +} __packed; + +#define CATPT_CHANNELS_MAX 4 +#define CATPT_ALL_CHANNELS_MASK UINT_MAX + +struct catpt_stream_info { + u32 stream_hw_id; + u32 reserved; + u32 read_pos_regaddr; + u32 pres_pos_regaddr; + u32 peak_meter_regaddr[CATPT_CHANNELS_MAX]; + u32 volume_regaddr[CATPT_CHANNELS_MAX]; +} __packed; + +int catpt_ipc_alloc_stream(struct catpt_dev *cdev, + enum catpt_path_id path_id, + enum catpt_stream_type type, + struct catpt_audio_format *afmt, + struct catpt_ring_info *rinfo, + u8 num_modules, + struct catpt_module_entry *modules, + struct resource *persistent, + struct resource *scratch, + struct catpt_stream_info *sinfo); +int catpt_ipc_free_stream(struct catpt_dev *cdev, u8 stream_hw_id); + +enum catpt_ssp_iface { + CATPT_SSP_IFACE_0 = 0, + CATPT_SSP_IFACE_1 = 1, + CATPT_SSP_IFACE_LAST = CATPT_SSP_IFACE_1, +}; + +#define CATPT_SSP_COUNT (CATPT_SSP_IFACE_LAST + 1) + +enum catpt_mclk_frequency { + CATPT_MCLK_OFF = 0, + CATPT_MCLK_FREQ_6_MHZ = 1, + CATPT_MCLK_FREQ_21_MHZ = 2, + CATPT_MCLK_FREQ_24_MHZ = 3, +}; + +enum catpt_ssp_mode { + CATPT_SSP_MODE_I2S_CONSUMER = 0, + CATPT_SSP_MODE_I2S_PROVIDER = 1, + CATPT_SSP_MODE_TDM_PROVIDER = 2, +}; + +struct catpt_ssp_device_format { + u32 iface; + u32 mclk; + u32 mode; + u16 clock_divider; + u8 channels; +} __packed; + +int catpt_ipc_set_device_format(struct catpt_dev *cdev, + struct catpt_ssp_device_format *devfmt); + +enum catpt_dx_state { + CATPT_DX_STATE_D3 = 3, +}; + +enum catpt_dx_type { + CATPT_DX_TYPE_FW_IMAGE = 0, + CATPT_DX_TYPE_MEMORY_DUMP = 1, +}; + +struct catpt_save_meminfo { + u32 offset; + u32 size; + u32 source; +} __packed; + +#define SAVE_MEMINFO_MAX 14 + +struct catpt_dx_context { + u32 num_meminfo; + struct catpt_save_meminfo meminfo[SAVE_MEMINFO_MAX]; +} __packed; + +int catpt_ipc_enter_dxstate(struct catpt_dev *cdev, enum catpt_dx_state state, + struct catpt_dx_context *context); + +struct catpt_mixer_stream_info { + u32 mixer_hw_id; + u32 peak_meter_regaddr[CATPT_CHANNELS_MAX]; + u32 volume_regaddr[CATPT_CHANNELS_MAX]; +} __packed; + +int catpt_ipc_get_mixer_stream_info(struct catpt_dev *cdev, + struct catpt_mixer_stream_info *info); + +/* STREAM messages */ + +enum catpt_stream_msg_type { + CATPT_STRM_RESET_STREAM = 0, + CATPT_STRM_PAUSE_STREAM = 1, + CATPT_STRM_RESUME_STREAM = 2, + CATPT_STRM_STAGE_MESSAGE = 3, + CATPT_STRM_NOTIFICATION = 4, +}; + +enum catpt_stage_action { + CATPT_STG_SET_VOLUME = 1, + CATPT_STG_SET_WRITE_POSITION = 2, + CATPT_STG_MUTE_LOOPBACK = 3, +}; + +union catpt_stream_msg { + u32 val; + struct { + u32 status:5; + u32 reserved:7; + u32 stage_action:4; + u32 stream_hw_id:4; + u32 stream_msg_type:4; + u32 global_msg_type:5; + u32 fw_ready:1; + u32 done:1; + u32 busy:1; + }; +} __packed; + +#define CATPT_STREAM_MSG(msg_type) \ +{ \ + .stream_msg_type = CATPT_STRM_##msg_type, \ + .global_msg_type = CATPT_GLB_STREAM_MESSAGE } +#define CATPT_STAGE_MSG(msg_type) \ +{ \ + .stage_action = CATPT_STG_##msg_type, \ + .stream_msg_type = CATPT_STRM_STAGE_MESSAGE, \ + .global_msg_type = CATPT_GLB_STREAM_MESSAGE } + +int catpt_ipc_reset_stream(struct catpt_dev *cdev, u8 stream_hw_id); +int catpt_ipc_pause_stream(struct catpt_dev *cdev, u8 stream_hw_id); +int catpt_ipc_resume_stream(struct catpt_dev *cdev, u8 stream_hw_id); + +/* STREAM messages - STAGE subtype */ + +enum catpt_audio_curve_type { + CATPT_AUDIO_CURVE_NONE = 0, + CATPT_AUDIO_CURVE_WINDOWS_FADE = 1, +}; + +int catpt_ipc_set_volume(struct catpt_dev *cdev, u8 stream_hw_id, + u32 channel, u32 volume, + u32 curve_duration, + enum catpt_audio_curve_type curve_type); + +int catpt_ipc_set_write_pos(struct catpt_dev *cdev, u8 stream_hw_id, + u32 pos, bool eob, bool ll); + +int catpt_ipc_mute_loopback(struct catpt_dev *cdev, u8 stream_hw_id, bool mute); + +/* NOTIFICATION messages */ + +enum catpt_notify_reason { + CATPT_NOTIFY_POSITION_CHANGED = 0, + CATPT_NOTIFY_GLITCH_OCCURRED = 1, +}; + +union catpt_notify_msg { + u32 val; + struct { + u32 mailbox_address:29; + u32 fw_ready:1; + u32 done:1; + u32 busy:1; + }; + struct { + u32 status:5; + u32 reserved:7; + u32 notify_reason:4; + u32 stream_hw_id:4; + u32 stream_msg_type:4; + u32 global_msg_type:5; + u32 hdr:3; /* fw_ready, done, busy */ + }; +} __packed; + +#define FW_INFO_SIZE_MAX 100 + +struct catpt_fw_ready { + u32 inbox_offset; + u32 outbox_offset; + u32 inbox_size; + u32 outbox_size; + u32 fw_info_size; + char fw_info[FW_INFO_SIZE_MAX]; +} __packed; + +struct catpt_notify_position { + u32 stream_position; + u32 fw_cycle_count; +} __packed; + +enum catpt_glitch_type { + CATPT_GLITCH_UNDERRUN = 1, + CATPT_GLITCH_DECODER_ERROR = 2, + CATPT_GLITCH_DOUBLED_WRITE_POS = 3, +}; + +struct catpt_notify_glitch { + u32 type; + u64 presentation_pos; + u32 write_pos; +} __packed; + +#endif diff --git a/sound/soc/intel/catpt/registers.h b/sound/soc/intel/catpt/registers.h index a051d8b36d88..47280d82842e 100644 --- a/sound/soc/intel/catpt/registers.h +++ b/sound/soc/intel/catpt/registers.h @@ -15,7 +15,6 @@ #define CATPT_SHIM_REGS_SIZE 4096 #define CATPT_DMA_REGS_SIZE 1024 #define CATPT_DMA_COUNT 2 -#define CATPT_SSP_COUNT 2 #define CATPT_SSP_REGS_SIZE 512 /* DSP Shim registers */ From patchwork Wed Sep 23 12:24:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 250909 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FABAC2D0A8 for ; Wed, 23 Sep 2020 12:29:28 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id CC05B21BE5 for ; Wed, 23 Sep 2020 12:29:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="AKke8g+a" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CC05B21BE5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 3398E16C0; Wed, 23 Sep 2020 14:28:36 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 3398E16C0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864166; bh=93HNljzIbW7JvYf8NqdporRfr4bFNeJZTThgiTbAy+8=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=AKke8g+a5MSWZB2gU5doPHRh+EM0YdPkaXJQ4wfA8OKBUqLUUEFUd+4AzJhtW7WK9 puxGbDZeEM0XmQeBA3Fdu6MXH9EJ56n1hosSi6sNXhhnjoqGsaz2aZshQw0z9bSfEL gZV09njbV0Y5i6SBXUgtPoOkg6qAE1hEdrSO9JKU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7157DF802E3; Wed, 23 Sep 2020 14:26:20 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id A32BAF802E3; Wed, 23 Sep 2020 14:26:16 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 DA0EFF8015F for ; Wed, 23 Sep 2020 14:26:08 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz DA0EFF8015F IronPort-SDR: twfoXAlEEPWsoEgt1pzrvE81VEqRY/1nbRE00pKeM8mEfthsmaikqKE5nRw8oBxyobR0Dukplz T+gEbU1Qerag== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948214" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948214" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:06 -0700 IronPort-SDR: dlI+laRgc7JIBxyjZeDxbVOMZWSg1ihrSQQfThvAiPER7D0MyMUsHKEB47+7cMkH/xDWAHJQ5K PPp6oy52sbyg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338167" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:02 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 03/14] ASoC: Intel: catpt: Add IPC message handlers Date: Wed, 23 Sep 2020 14:24:57 +0200 Message-Id: <20200923122508.3360-4-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Declare global and stream IPC message handlers for all known message types. Signed-off-by: Cezary Rojewski --- sound/soc/intel/catpt/core.h | 2 + sound/soc/intel/catpt/dsp.c | 106 +++++++++++ sound/soc/intel/catpt/ipc.c | 4 + sound/soc/intel/catpt/messages.c | 313 +++++++++++++++++++++++++++++++ 4 files changed, 425 insertions(+) create mode 100644 sound/soc/intel/catpt/messages.c diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h index 8819d928e891..3c860c0645dc 100644 --- a/sound/soc/intel/catpt/core.h +++ b/sound/soc/intel/catpt/core.h @@ -127,4 +127,6 @@ int catpt_dsp_send_msg_timeout(struct catpt_dev *cdev, int catpt_dsp_send_msg(struct catpt_dev *cdev, struct catpt_ipc_msg request, struct catpt_ipc_msg *reply); +int catpt_coredump(struct catpt_dev *cdev); + #endif diff --git a/sound/soc/intel/catpt/dsp.c b/sound/soc/intel/catpt/dsp.c index b0a61fcca50c..9d988b05c8cf 100644 --- a/sound/soc/intel/catpt/dsp.c +++ b/sound/soc/intel/catpt/dsp.c @@ -5,6 +5,7 @@ // Author: Cezary Rojewski // +#include #include #include #include "core.h" @@ -136,3 +137,108 @@ void catpt_dmac_remove(struct catpt_dev *cdev) */ dw_dma_remove(cdev->dmac); } + +#define CATPT_DUMP_MAGIC 0xcd42 +#define CATPT_DUMP_SECTION_ID_FILE 0x00 +#define CATPT_DUMP_SECTION_ID_IRAM 0x01 +#define CATPT_DUMP_SECTION_ID_DRAM 0x02 +#define CATPT_DUMP_SECTION_ID_REGS 0x03 +#define CATPT_DUMP_HASH_SIZE 20 + +struct catpt_dump_section_hdr { + u16 magic; + u8 core_id; + u8 section_id; + u32 size; +}; + +int catpt_coredump(struct catpt_dev *cdev) +{ + struct catpt_dump_section_hdr *hdr; + size_t dump_size, regs_size; + u8 *dump, *pos; + const char *eof; + char *info; + int i; + + regs_size = CATPT_SHIM_REGS_SIZE; + regs_size += CATPT_DMA_COUNT * CATPT_DMA_REGS_SIZE; + regs_size += CATPT_SSP_COUNT * CATPT_SSP_REGS_SIZE; + dump_size = resource_size(&cdev->dram); + dump_size += resource_size(&cdev->iram); + dump_size += regs_size; + /* account for header of each section and hash chunk */ + dump_size += 4 * sizeof(*hdr) + CATPT_DUMP_HASH_SIZE; + + dump = vzalloc(dump_size); + if (!dump) + return -ENOMEM; + + pos = dump; + + hdr = (struct catpt_dump_section_hdr *)pos; + hdr->magic = CATPT_DUMP_MAGIC; + hdr->core_id = cdev->spec->core_id; + hdr->section_id = CATPT_DUMP_SECTION_ID_FILE; + hdr->size = dump_size - sizeof(*hdr); + pos += sizeof(*hdr); + + info = cdev->ipc.config.fw_info; + eof = info + FW_INFO_SIZE_MAX; + /* navigate to fifth info segment (fw hash) */ + for (i = 0; i < 4 && info < eof; i++, info++) { + /* info segments are separated by space each */ + info = strnchr(info, eof - info, ' '); + if (!info) + break; + } + + if (i == 4 && info) + memcpy(pos, info, min_t(u32, eof - info, CATPT_DUMP_HASH_SIZE)); + pos += CATPT_DUMP_HASH_SIZE; + + hdr = (struct catpt_dump_section_hdr *)pos; + hdr->magic = CATPT_DUMP_MAGIC; + hdr->core_id = cdev->spec->core_id; + hdr->section_id = CATPT_DUMP_SECTION_ID_IRAM; + hdr->size = resource_size(&cdev->iram); + pos += sizeof(*hdr); + + memcpy_fromio(pos, cdev->lpe_ba + cdev->iram.start, hdr->size); + pos += hdr->size; + + hdr = (struct catpt_dump_section_hdr *)pos; + hdr->magic = CATPT_DUMP_MAGIC; + hdr->core_id = cdev->spec->core_id; + hdr->section_id = CATPT_DUMP_SECTION_ID_DRAM; + hdr->size = resource_size(&cdev->dram); + pos += sizeof(*hdr); + + memcpy_fromio(pos, cdev->lpe_ba + cdev->dram.start, hdr->size); + pos += hdr->size; + + hdr = (struct catpt_dump_section_hdr *)pos; + hdr->magic = CATPT_DUMP_MAGIC; + hdr->core_id = cdev->spec->core_id; + hdr->section_id = CATPT_DUMP_SECTION_ID_REGS; + hdr->size = regs_size; + pos += sizeof(*hdr); + + memcpy_fromio(pos, catpt_shim_addr(cdev), CATPT_SHIM_REGS_SIZE); + pos += CATPT_SHIM_REGS_SIZE; + + for (i = 0; i < CATPT_SSP_COUNT; i++) { + memcpy_fromio(pos, catpt_ssp_addr(cdev, i), + CATPT_SSP_REGS_SIZE); + pos += CATPT_SSP_REGS_SIZE; + } + for (i = 0; i < CATPT_DMA_COUNT; i++) { + memcpy_fromio(pos, catpt_dma_addr(cdev, i), + CATPT_DMA_REGS_SIZE); + pos += CATPT_DMA_REGS_SIZE; + } + + dev_coredumpv(cdev->dev, dump, dump_size, GFP_KERNEL); + + return 0; +} diff --git a/sound/soc/intel/catpt/ipc.c b/sound/soc/intel/catpt/ipc.c index 7474bc73c73a..d5edf3eebdf8 100644 --- a/sound/soc/intel/catpt/ipc.c +++ b/sound/soc/intel/catpt/ipc.c @@ -168,6 +168,10 @@ static void catpt_dsp_process_response(struct catpt_dev *cdev, u32 header) switch (msg.global_msg_type) { case CATPT_GLB_REQUEST_CORE_DUMP: + dev_err(cdev->dev, "ADSP device coredump received\n"); + ipc->ready = false; + catpt_coredump(cdev); + /* TODO: attempt recovery */ break; case CATPT_GLB_STREAM_MESSAGE: diff --git a/sound/soc/intel/catpt/messages.c b/sound/soc/intel/catpt/messages.c new file mode 100644 index 000000000000..a793d114afa4 --- /dev/null +++ b/sound/soc/intel/catpt/messages.c @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include "core.h" +#include "messages.h" +#include "registers.h" + +int catpt_ipc_get_fw_version(struct catpt_dev *cdev, + struct catpt_fw_version *version) +{ + union catpt_global_msg msg = CATPT_GLOBAL_MSG(GET_FW_VERSION); + struct catpt_ipc_msg request = {{0}}, reply; + int ret; + + request.header = msg.val; + reply.size = sizeof(*version); + reply.data = version; + + ret = catpt_dsp_send_msg(cdev, request, &reply); + if (ret) + dev_err(cdev->dev, "get fw version failed: %d\n", ret); + + return ret; +} + +struct catpt_alloc_stream_input { + enum catpt_path_id path_id:8; + enum catpt_stream_type stream_type:8; + enum catpt_format_id format_id:8; + u8 reserved; + struct catpt_audio_format input_format; + struct catpt_ring_info ring_info; + u8 num_entries; + /* flex array with entries here */ + struct catpt_memory_info persistent_mem; + struct catpt_memory_info scratch_mem; + u32 num_notifications; /* obsolete */ +} __packed; + +int catpt_ipc_alloc_stream(struct catpt_dev *cdev, + enum catpt_path_id path_id, + enum catpt_stream_type type, + struct catpt_audio_format *afmt, + struct catpt_ring_info *rinfo, + u8 num_modules, + struct catpt_module_entry *modules, + struct resource *persistent, + struct resource *scratch, + struct catpt_stream_info *sinfo) +{ + union catpt_global_msg msg = CATPT_GLOBAL_MSG(ALLOCATE_STREAM); + struct catpt_alloc_stream_input input; + struct catpt_ipc_msg request, reply; + size_t size, arrsz; + u8 *payload; + off_t off; + int ret; + + off = offsetof(struct catpt_alloc_stream_input, persistent_mem); + arrsz = sizeof(*modules) * num_modules; + size = sizeof(input) + arrsz; + + payload = kzalloc(size, GFP_KERNEL); + if (!payload) + return -ENOMEM; + + memset(&input, 0, sizeof(input)); + input.path_id = path_id; + input.stream_type = type; + input.format_id = CATPT_FORMAT_PCM; + input.input_format = *afmt; + input.ring_info = *rinfo; + input.num_entries = num_modules; + input.persistent_mem.offset = catpt_to_dsp_offset(persistent->start); + input.persistent_mem.size = resource_size(persistent); + if (scratch) { + input.scratch_mem.offset = catpt_to_dsp_offset(scratch->start); + input.scratch_mem.size = resource_size(scratch); + } + + /* re-arrange the input: account for flex array 'entries' */ + memcpy(payload, &input, sizeof(input)); + memmove(payload + off + arrsz, payload + off, sizeof(input) - off); + memcpy(payload + off, modules, arrsz); + + request.header = msg.val; + request.size = size; + request.data = payload; + reply.size = sizeof(*sinfo); + reply.data = sinfo; + + ret = catpt_dsp_send_msg(cdev, request, &reply); + if (ret) + dev_err(cdev->dev, "alloc stream type %d failed: %d\n", + type, ret); + + kfree(payload); + return ret; +} + +int catpt_ipc_free_stream(struct catpt_dev *cdev, u8 stream_hw_id) +{ + union catpt_global_msg msg = CATPT_GLOBAL_MSG(FREE_STREAM); + struct catpt_ipc_msg request; + int ret; + + request.header = msg.val; + request.size = sizeof(stream_hw_id); + request.data = &stream_hw_id; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "free stream %d failed: %d\n", + stream_hw_id, ret); + + return ret; +} + +int catpt_ipc_set_device_format(struct catpt_dev *cdev, + struct catpt_ssp_device_format *devfmt) +{ + union catpt_global_msg msg = CATPT_GLOBAL_MSG(SET_DEVICE_FORMATS); + struct catpt_ipc_msg request; + int ret; + + request.header = msg.val; + request.size = sizeof(*devfmt); + request.data = devfmt; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "set device format failed: %d\n", ret); + + return ret; +} + +int catpt_ipc_enter_dxstate(struct catpt_dev *cdev, enum catpt_dx_state state, + struct catpt_dx_context *context) +{ + union catpt_global_msg msg = CATPT_GLOBAL_MSG(ENTER_DX_STATE); + struct catpt_ipc_msg request, reply; + int ret; + + request.header = msg.val; + request.size = sizeof(state); + request.data = &state; + reply.size = sizeof(*context); + reply.data = context; + + ret = catpt_dsp_send_msg(cdev, request, &reply); + if (ret) + dev_err(cdev->dev, "enter dx state failed: %d\n", ret); + + return ret; +} + +int catpt_ipc_get_mixer_stream_info(struct catpt_dev *cdev, + struct catpt_mixer_stream_info *info) +{ + union catpt_global_msg msg = CATPT_GLOBAL_MSG(GET_MIXER_STREAM_INFO); + struct catpt_ipc_msg request = {{0}}, reply; + int ret; + + request.header = msg.val; + reply.size = sizeof(*info); + reply.data = info; + + ret = catpt_dsp_send_msg(cdev, request, &reply); + if (ret) + dev_err(cdev->dev, "get mixer info failed: %d\n", ret); + + return ret; +} + +int catpt_ipc_reset_stream(struct catpt_dev *cdev, u8 stream_hw_id) +{ + union catpt_stream_msg msg = CATPT_STREAM_MSG(RESET_STREAM); + struct catpt_ipc_msg request = {{0}}; + int ret; + + msg.stream_hw_id = stream_hw_id; + request.header = msg.val; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "reset stream %d failed: %d\n", + stream_hw_id, ret); + + return ret; +} + +int catpt_ipc_pause_stream(struct catpt_dev *cdev, u8 stream_hw_id) +{ + union catpt_stream_msg msg = CATPT_STREAM_MSG(PAUSE_STREAM); + struct catpt_ipc_msg request = {{0}}; + int ret; + + msg.stream_hw_id = stream_hw_id; + request.header = msg.val; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "pause stream %d failed: %d\n", + stream_hw_id, ret); + + return ret; +} + +int catpt_ipc_resume_stream(struct catpt_dev *cdev, u8 stream_hw_id) +{ + union catpt_stream_msg msg = CATPT_STREAM_MSG(RESUME_STREAM); + struct catpt_ipc_msg request = {{0}}; + int ret; + + msg.stream_hw_id = stream_hw_id; + request.header = msg.val; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "resume stream %d failed: %d\n", + stream_hw_id, ret); + + return ret; +} + +struct catpt_set_volume_input { + u32 channel; + u32 target_volume; + u64 curve_duration; + u32 curve_type; +} __packed; + +int catpt_ipc_set_volume(struct catpt_dev *cdev, u8 stream_hw_id, + u32 channel, u32 volume, + u32 curve_duration, + enum catpt_audio_curve_type curve_type) +{ + union catpt_stream_msg msg = CATPT_STAGE_MSG(SET_VOLUME); + struct catpt_ipc_msg request; + struct catpt_set_volume_input input; + int ret; + + msg.stream_hw_id = stream_hw_id; + input.channel = channel; + input.target_volume = volume; + input.curve_duration = curve_duration; + input.curve_type = curve_type; + + request.header = msg.val; + request.size = sizeof(input); + request.data = &input; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "set stream %d volume failed: %d\n", + stream_hw_id, ret); + + return ret; +} + +struct catpt_set_write_pos_input { + u32 new_write_pos; + bool end_of_buffer; + bool low_latency; +} __packed; + +int catpt_ipc_set_write_pos(struct catpt_dev *cdev, u8 stream_hw_id, + u32 pos, bool eob, bool ll) +{ + union catpt_stream_msg msg = CATPT_STAGE_MSG(SET_WRITE_POSITION); + struct catpt_ipc_msg request; + struct catpt_set_write_pos_input input; + int ret; + + msg.stream_hw_id = stream_hw_id; + input.new_write_pos = pos; + input.end_of_buffer = eob; + input.low_latency = ll; + + request.header = msg.val; + request.size = sizeof(input); + request.data = &input; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "set stream %d write pos failed: %d\n", + stream_hw_id, ret); + + return ret; +} + +int catpt_ipc_mute_loopback(struct catpt_dev *cdev, u8 stream_hw_id, bool mute) +{ + union catpt_stream_msg msg = CATPT_STAGE_MSG(MUTE_LOOPBACK); + struct catpt_ipc_msg request; + int ret; + + msg.stream_hw_id = stream_hw_id; + request.header = msg.val; + request.size = sizeof(mute); + request.data = &mute; + + ret = catpt_dsp_send_msg(cdev, request, NULL); + if (ret) + dev_err(cdev->dev, "mute loopback failed: %d\n", ret); + + return ret; +} From patchwork Wed Sep 23 12:24:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 291590 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7ED69C2D0A8 for ; Wed, 23 Sep 2020 12:29:39 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id ADADE21BE5 for ; Wed, 23 Sep 2020 12:29:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="f7WFRJ9j" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ADADE21BE5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 F34A3167A; Wed, 23 Sep 2020 14:28:46 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz F34A3167A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864177; bh=ddXvwnFYtvwGRm8deDApjfZFqSDLdSVgwZJgsld5fgg=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=f7WFRJ9j7316NqdfaLF9dc5Poqham5C2V3zkJTldgaMaKnSxlZaOW3dBPfVViqrL+ mwHNU1y4t7eN3enAIcIFn3zWFCgWdVQQqxGWVi9L/GhXDO0UBaSlQ5s0MIcARZniZ3 NF84+dKfzmiB7dK+4qbzLalHojJBfTP+9Q2RFG4Y= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id CA192F802E8; Wed, 23 Sep 2020 14:26:21 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3C7B5F802E7; Wed, 23 Sep 2020 14:26:19 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 2D8CEF802A2 for ; Wed, 23 Sep 2020 14:26:12 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2D8CEF802A2 IronPort-SDR: 3+PqsIQzcefynxwk8lv3U+TwYRZBXsqvXrcxTdgVEx30U4JL4ggt8X7I0ctTTypRyQuGwd+ap7 d+O09NGSDlkA== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948220" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948220" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:11 -0700 IronPort-SDR: mne4YbeOtlgLgbMbj+bquC/NXaAlFKXewVXM7Nut3MATA3iuhKUjR+MRQ06596rGl9fvfH1wEY Ku6q9LRY5AiA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338180" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:06 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 04/14] ASoC: Intel: catpt: Define DSP operations Date: Wed, 23 Sep 2020 14:24:58 +0200 Message-Id: <20200923122508.3360-5-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Implement dsp lifecycle functions such as core RESET and STALL, SRAM power control and LP clock selection. This also adds functions for handling transport over DW DMA controller. Signed-off-by: Cezary Rojewski --- sound/soc/intel/catpt/core.h | 34 ++++ sound/soc/intel/catpt/dsp.c | 334 +++++++++++++++++++++++++++++++++++ 2 files changed, 368 insertions(+) diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h index 3c860c0645dc..9e9b3dceedce 100644 --- a/sound/soc/intel/catpt/core.h +++ b/sound/soc/intel/catpt/core.h @@ -99,6 +99,10 @@ struct catpt_dev { struct resource dram; struct resource iram; struct resource *scratch; + + struct list_head stream_list; + spinlock_t list_lock; + struct mutex clk_mutex; }; int catpt_dmac_probe(struct catpt_dev *cdev); @@ -111,6 +115,16 @@ int catpt_dma_memcpy_fromdsp(struct catpt_dev *cdev, struct dma_chan *chan, dma_addr_t dst_addr, dma_addr_t src_addr, size_t size); +void lpt_dsp_pll_shutdown(struct catpt_dev *cdev, bool enable); +void wpt_dsp_pll_shutdown(struct catpt_dev *cdev, bool enable); +int lpt_dsp_power_up(struct catpt_dev *cdev); +int lpt_dsp_power_down(struct catpt_dev *cdev); +int wpt_dsp_power_up(struct catpt_dev *cdev); +int wpt_dsp_power_down(struct catpt_dev *cdev); +int catpt_dsp_stall(struct catpt_dev *cdev, bool stall); +void catpt_dsp_update_srampge(struct catpt_dev *cdev, struct resource *sram, + unsigned long mask); +int catpt_dsp_update_lpclock(struct catpt_dev *cdev); irqreturn_t catpt_dsp_irq_handler(int irq, void *dev_id); irqreturn_t catpt_dsp_irq_thread(int irq, void *dev_id); @@ -129,4 +143,24 @@ int catpt_dsp_send_msg(struct catpt_dev *cdev, struct catpt_ipc_msg request, int catpt_coredump(struct catpt_dev *cdev); +#include +#include + +struct snd_pcm_substream; +struct catpt_stream_template; + +struct catpt_stream_runtime { + struct snd_pcm_substream *substream; + + struct catpt_stream_template *template; + struct catpt_stream_info info; + struct resource *persistent; + struct snd_dma_buffer pgtbl; + + bool allocated; + bool prepared; + + struct list_head node; +}; + #endif diff --git a/sound/soc/intel/catpt/dsp.c b/sound/soc/intel/catpt/dsp.c index 9d988b05c8cf..2a52d1bf4e00 100644 --- a/sound/soc/intel/catpt/dsp.c +++ b/sound/soc/intel/catpt/dsp.c @@ -8,7 +8,10 @@ #include #include #include +#include +#include #include "core.h" +#include "messages.h" #include "registers.h" static bool catpt_dma_filter(struct dma_chan *chan, void *param) @@ -138,6 +141,337 @@ void catpt_dmac_remove(struct catpt_dev *cdev) dw_dma_remove(cdev->dmac); } +static void catpt_dsp_set_srampge(struct catpt_dev *cdev, struct resource *sram, + unsigned long mask, unsigned long new) +{ + unsigned long old; + u32 off = sram->start; + u32 b = __ffs(mask); + + old = catpt_readl_pci(cdev, VDRTCTL0) & mask; + dev_dbg(cdev->dev, "SRAMPGE [0x%08lx] 0x%08lx -> 0x%08lx", + mask, old, new); + + if (old == new) + return; + + catpt_updatel_pci(cdev, VDRTCTL0, mask, new); + /* wait for SRAM power gating to propagate */ + udelay(60); + + /* + * Dummy read as the very first access after block enable + * to prevent byte loss in future operations. + */ + for_each_clear_bit_from(b, &new, fls_long(mask)) { + u8 buf[4]; + + /* newly enabled: new bit=0 while old bit=1 */ + if (test_bit(b, &old)) { + dev_dbg(cdev->dev, "sanitize block %ld: off 0x%08x\n", + b - __ffs(mask), off); + memcpy_fromio(buf, cdev->lpe_ba + off, sizeof(buf)); + } + off += CATPT_MEMBLOCK_SIZE; + } +} + +void catpt_dsp_update_srampge(struct catpt_dev *cdev, struct resource *sram, + unsigned long mask) +{ + struct resource *res; + unsigned long new = 0; + + /* flag all busy blocks */ + for (res = sram->child; res; res = res->sibling) { + u32 h, l; + + h = (res->end - sram->start) / CATPT_MEMBLOCK_SIZE; + l = (res->start - sram->start) / CATPT_MEMBLOCK_SIZE; + new |= GENMASK(h, l); + } + + /* offset value given mask's start and invert it as ON=b0 */ + new = ~(new << __ffs(mask)) & mask; + + /* disable core clock gating */ + catpt_updatel_pci(cdev, VDRTCTL2, CATPT_VDRTCTL2_DCLCGE, 0); + + catpt_dsp_set_srampge(cdev, sram, mask, new); + + /* enable core clock gating */ + catpt_updatel_pci(cdev, VDRTCTL2, CATPT_VDRTCTL2_DCLCGE, + CATPT_VDRTCTL2_DCLCGE); +} + +int catpt_dsp_stall(struct catpt_dev *cdev, bool stall) +{ + u32 reg, val; + + val = stall ? CATPT_CS_STALL : 0; + catpt_updatel_shim(cdev, CS1, CATPT_CS_STALL, val); + + return catpt_readl_poll_shim(cdev, CS1, + reg, (reg & CATPT_CS_STALL) == val, + 500, 10000); +} + +static int catpt_dsp_reset(struct catpt_dev *cdev, bool reset) +{ + u32 reg, val; + + val = reset ? CATPT_CS_RST : 0; + catpt_updatel_shim(cdev, CS1, CATPT_CS_RST, val); + + return catpt_readl_poll_shim(cdev, CS1, + reg, (reg & CATPT_CS_RST) == val, + 500, 10000); +} + +void lpt_dsp_pll_shutdown(struct catpt_dev *cdev, bool enable) +{ + u32 val; + + val = enable ? LPT_VDRTCTL0_APLLSE : 0; + catpt_updatel_pci(cdev, VDRTCTL0, LPT_VDRTCTL0_APLLSE, val); +} + +void wpt_dsp_pll_shutdown(struct catpt_dev *cdev, bool enable) +{ + u32 val; + + val = enable ? WPT_VDRTCTL2_APLLSE : 0; + catpt_updatel_pci(cdev, VDRTCTL2, WPT_VDRTCTL2_APLLSE, val); +} + +static int catpt_dsp_select_lpclock(struct catpt_dev *cdev, bool lp, bool waiti) +{ + u32 mask, reg, val; + int ret; + + mutex_lock(&cdev->clk_mutex); + + val = lp ? CATPT_CS_LPCS : 0; + reg = catpt_readl_shim(cdev, CS1) & CATPT_CS_LPCS; + dev_dbg(cdev->dev, "LPCS [0x%08lx] 0x%08x -> 0x%08x", + CATPT_CS_LPCS, reg, val); + + if (reg == val) { + mutex_unlock(&cdev->clk_mutex); + return 0; + } + + if (waiti) { + /* wait for DSP to signal WAIT state */ + ret = catpt_readl_poll_shim(cdev, ISD, + reg, (reg & CATPT_ISD_DCPWM), + 500, 10000); + if (ret) { + dev_err(cdev->dev, "await WAITI timeout\n"); + mutex_unlock(&cdev->clk_mutex); + return ret; + } + } + + ret = catpt_readl_poll_shim(cdev, CLKCTL, + reg, !(reg & CATPT_CLKCTL_CFCIP), + 500, 10000); + if (ret) + dev_warn(cdev->dev, "clock change still in progress\n"); + + /* default to DSP core & audio fabric high clock */ + val |= CATPT_CS_DCS_HIGH; + mask = CATPT_CS_LPCS | CATPT_CS_DCS; + catpt_updatel_shim(cdev, CS1, mask, val); + + ret = catpt_readl_poll_shim(cdev, CLKCTL, + reg, !(reg & CATPT_CLKCTL_CFCIP), + 500, 10000); + if (ret) + dev_warn(cdev->dev, "clock change still in progress\n"); + + /* update PLL accordingly */ + cdev->spec->pll_shutdown(cdev, lp); + + mutex_unlock(&cdev->clk_mutex); + return 0; +} + +int catpt_dsp_update_lpclock(struct catpt_dev *cdev) +{ + struct catpt_stream_runtime *stream; + + list_for_each_entry(stream, &cdev->stream_list, node) + if (stream->prepared) + return catpt_dsp_select_lpclock(cdev, false, true); + + return catpt_dsp_select_lpclock(cdev, true, true); +} + +/* bring registers to their defaults as HW won't reset itself */ +static void catpt_dsp_set_regs_defaults(struct catpt_dev *cdev) +{ + int i; + + catpt_writel_shim(cdev, CS1, CATPT_CS_DEFAULT); + catpt_writel_shim(cdev, ISC, CATPT_ISC_DEFAULT); + catpt_writel_shim(cdev, ISD, CATPT_ISD_DEFAULT); + catpt_writel_shim(cdev, IMC, CATPT_IMC_DEFAULT); + catpt_writel_shim(cdev, IMD, CATPT_IMD_DEFAULT); + catpt_writel_shim(cdev, IPCC, CATPT_IPCC_DEFAULT); + catpt_writel_shim(cdev, IPCD, CATPT_IPCD_DEFAULT); + catpt_writel_shim(cdev, CLKCTL, CATPT_CLKCTL_DEFAULT); + catpt_writel_shim(cdev, CS2, CATPT_CS2_DEFAULT); + catpt_writel_shim(cdev, LTRC, CATPT_LTRC_DEFAULT); + catpt_writel_shim(cdev, HMDC, CATPT_HMDC_DEFAULT); + + for (i = 0; i < CATPT_SSP_COUNT; i++) { + catpt_writel_ssp(cdev, i, SSCR0, CATPT_SSC0_DEFAULT); + catpt_writel_ssp(cdev, i, SSCR1, CATPT_SSC1_DEFAULT); + catpt_writel_ssp(cdev, i, SSSR, CATPT_SSS_DEFAULT); + catpt_writel_ssp(cdev, i, SSITR, CATPT_SSIT_DEFAULT); + catpt_writel_ssp(cdev, i, SSDR, CATPT_SSD_DEFAULT); + catpt_writel_ssp(cdev, i, SSTO, CATPT_SSTO_DEFAULT); + catpt_writel_ssp(cdev, i, SSPSP, CATPT_SSPSP_DEFAULT); + catpt_writel_ssp(cdev, i, SSTSA, CATPT_SSTSA_DEFAULT); + catpt_writel_ssp(cdev, i, SSRSA, CATPT_SSRSA_DEFAULT); + catpt_writel_ssp(cdev, i, SSTSS, CATPT_SSTSS_DEFAULT); + catpt_writel_ssp(cdev, i, SSCR2, CATPT_SSCR2_DEFAULT); + catpt_writel_ssp(cdev, i, SSPSP2, CATPT_SSPSP2_DEFAULT); + } +} + +int lpt_dsp_power_down(struct catpt_dev *cdev) +{ + catpt_dsp_reset(cdev, true); + + /* set 24Mhz clock for both SSPs */ + catpt_updatel_shim(cdev, CS1, CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1), + CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1)); + catpt_dsp_select_lpclock(cdev, true, false); + + /* DRAM power gating all */ + catpt_dsp_set_srampge(cdev, &cdev->dram, cdev->spec->dram_mask, + cdev->spec->dram_mask); + catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask, + cdev->spec->iram_mask); + + catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D3hot); + /* give hw time to drop off */ + udelay(50); + + return 0; +} + +int lpt_dsp_power_up(struct catpt_dev *cdev) +{ + /* SRAM power gating none */ + catpt_dsp_set_srampge(cdev, &cdev->dram, cdev->spec->dram_mask, 0); + catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask, 0); + + catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D0); + /* give hw time to wake up */ + udelay(100); + + catpt_dsp_select_lpclock(cdev, false, false); + catpt_updatel_shim(cdev, CS1, + CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1), + CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1)); + /* stagger DSP reset after clock selection */ + udelay(50); + + catpt_dsp_reset(cdev, false); + /* generate int deassert msg to fix inversed int logic */ + catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCDB | CATPT_IMC_IPCCD, 0); + + return 0; +} + +int wpt_dsp_power_down(struct catpt_dev *cdev) +{ + u32 mask, val; + + /* disable core clock gating */ + catpt_updatel_pci(cdev, VDRTCTL2, CATPT_VDRTCTL2_DCLCGE, 0); + + catpt_dsp_reset(cdev, true); + /* set 24Mhz clock for both SSPs */ + catpt_updatel_shim(cdev, CS1, CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1), + CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1)); + catpt_dsp_select_lpclock(cdev, true, false); + /* disable MCLK */ + catpt_updatel_shim(cdev, CLKCTL, CATPT_CLKCTL_SMOS, 0); + + catpt_dsp_set_regs_defaults(cdev); + + /* switch clock gating */ + mask = CATPT_VDRTCTL2_CGEALL & (~CATPT_VDRTCTL2_DCLCGE); + val = mask & (~CATPT_VDRTCTL2_DTCGE); + catpt_updatel_pci(cdev, VDRTCTL2, mask, val); + /* enable DTCGE separatelly */ + catpt_updatel_pci(cdev, VDRTCTL2, CATPT_VDRTCTL2_DTCGE, + CATPT_VDRTCTL2_DTCGE); + + /* SRAM power gating all */ + catpt_dsp_set_srampge(cdev, &cdev->dram, cdev->spec->dram_mask, + cdev->spec->dram_mask); + catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask, + cdev->spec->iram_mask); + mask = WPT_VDRTCTL0_D3SRAMPGD | WPT_VDRTCTL0_D3PGD; + catpt_updatel_pci(cdev, VDRTCTL0, mask, WPT_VDRTCTL0_D3PGD); + + catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D3hot); + /* give hw time to drop off */ + udelay(50); + + /* enable core clock gating */ + catpt_updatel_pci(cdev, VDRTCTL2, CATPT_VDRTCTL2_DCLCGE, + CATPT_VDRTCTL2_DCLCGE); + udelay(50); + + return 0; +} + +int wpt_dsp_power_up(struct catpt_dev *cdev) +{ + u32 mask, val; + + /* disable core clock gating */ + catpt_updatel_pci(cdev, VDRTCTL2, CATPT_VDRTCTL2_DCLCGE, 0); + + /* switch clock gating */ + mask = CATPT_VDRTCTL2_CGEALL & (~CATPT_VDRTCTL2_DCLCGE); + val = mask & (~CATPT_VDRTCTL2_DTCGE); + catpt_updatel_pci(cdev, VDRTCTL2, mask, val); + + catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D0); + + /* SRAM power gating none */ + mask = WPT_VDRTCTL0_D3SRAMPGD | WPT_VDRTCTL0_D3PGD; + catpt_updatel_pci(cdev, VDRTCTL0, mask, mask); + catpt_dsp_set_srampge(cdev, &cdev->dram, cdev->spec->dram_mask, 0); + catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask, 0); + + catpt_dsp_set_regs_defaults(cdev); + + /* restore MCLK */ + catpt_updatel_shim(cdev, CLKCTL, CATPT_CLKCTL_SMOS, CATPT_CLKCTL_SMOS); + catpt_dsp_select_lpclock(cdev, false, false); + /* set 24Mhz clock for both SSPs */ + catpt_updatel_shim(cdev, CS1, CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1), + CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1)); + catpt_dsp_reset(cdev, false); + + /* enable core clock gating */ + catpt_updatel_pci(cdev, VDRTCTL2, CATPT_VDRTCTL2_DCLCGE, + CATPT_VDRTCTL2_DCLCGE); + + /* generate int deassert msg to fix inversed int logic */ + catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCDB | CATPT_IMC_IPCCD, 0); + + return 0; +} + #define CATPT_DUMP_MAGIC 0xcd42 #define CATPT_DUMP_SECTION_ID_FILE 0x00 #define CATPT_DUMP_SECTION_ID_IRAM 0x01 From patchwork Wed Sep 23 12:24:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 250908 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 345E3C2D0A8 for ; Wed, 23 Sep 2020 12:30:24 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3E14421D92 for ; Wed, 23 Sep 2020 12:30:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="jeHBFknU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3E14421D92 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 9B9A816CE; Wed, 23 Sep 2020 14:29:31 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9B9A816CE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864221; bh=X8VFKAn7eawqzXyP+HgVL8oAiyo0sNGkwTbWawGISBY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=jeHBFknUGLKkgPpUvPlmStprmI1ijIV5tttHQD4gVPfOBGxJ90XwPKohCMzXKBil1 fMvYLhEJBKvTTVQhhUsEqJZW/u4Rm1jieHgj3dbMeSZMAWh6qWPAPJ1LsUVnyGNCrs ZSKwGJtwmJfQi1b73FjwTfn0pDRW+cfwxAxLShvI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 1950FF802F8; Wed, 23 Sep 2020 14:26:24 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EBEA8F802F9; Wed, 23 Sep 2020 14:26:22 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 203ACF802E0 for ; Wed, 23 Sep 2020 14:26:15 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 203ACF802E0 IronPort-SDR: hdcq2DegFri7EHAcDbTZtgxGrVu5BuC4vSjVdKcfQ99OvMY9yugZxTSxotWhViDbFsPMBHkyE9 e8Ep/3mdTgGg== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948228" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948228" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:15 -0700 IronPort-SDR: 5VvOk/RUaseS54TgWkKM1KYZievJ0iJxcIP82QOwX8FAufDfdq+i/F3lFnaBj1GtbSGwA455s8 tS/RQt86KL9Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338196" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:11 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 05/14] ASoC: Intel: catpt: Firmware loading and context restore Date: Wed, 23 Sep 2020 14:24:59 +0200 Message-Id: <20200923122508.3360-6-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" For Lynxpoint and Wildcat Point solution, is it host's responsibility to allocate SRAM regions and ensure those already taken are not overwritten with other data until released. Blocks are transferred to SRAM - either IRAM or DRAM - via DW DMA controller. Once basefw is booted, ownership of DMA transfer is lost in favour of DSP. Hosts reponsibilities don't end on initial block allocation and binary transfer. During Dx transitions host must store FW runtime context from DRAM before putting AudioDSP subsystem into lower power state. Said context gets flashed after D0 entry to bring DSP right where it was just before suspending. Load and restore procedures are finalized with SRAM power gating and adequate clock level selection. This power gates unused EBBs and clock speed effectively reducing power consumption. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko --- sound/soc/intel/catpt/core.h | 12 + sound/soc/intel/catpt/loader.c | 619 +++++++++++++++++++++++++++++++++ 2 files changed, 631 insertions(+) diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h index 9e9b3dceedce..260e5ae94a2c 100644 --- a/sound/soc/intel/catpt/core.h +++ b/sound/soc/intel/catpt/core.h @@ -100,9 +100,16 @@ struct catpt_dev { struct resource iram; struct resource *scratch; + struct catpt_mixer_stream_info mixer; + struct catpt_module_type modules[CATPT_MODULE_COUNT]; + struct catpt_ssp_device_format devfmt[CATPT_SSP_COUNT]; struct list_head stream_list; spinlock_t list_lock; struct mutex clk_mutex; + + struct catpt_dx_context dx_ctx; + void *dxbuf_vaddr; + dma_addr_t dxbuf_paddr; }; int catpt_dmac_probe(struct catpt_dev *cdev); @@ -141,6 +148,11 @@ int catpt_dsp_send_msg_timeout(struct catpt_dev *cdev, int catpt_dsp_send_msg(struct catpt_dev *cdev, struct catpt_ipc_msg request, struct catpt_ipc_msg *reply); +int catpt_first_boot_firmware(struct catpt_dev *cdev); +int catpt_boot_firmware(struct catpt_dev *cdev, bool restore); +int catpt_store_streams_context(struct catpt_dev *cdev, struct dma_chan *chan); +int catpt_store_module_states(struct catpt_dev *cdev, struct dma_chan *chan); +int catpt_store_memdumps(struct catpt_dev *cdev, struct dma_chan *chan); int catpt_coredump(struct catpt_dev *cdev); #include diff --git a/sound/soc/intel/catpt/loader.c b/sound/soc/intel/catpt/loader.c index 3a7e5b396a86..473e842e9901 100644 --- a/sound/soc/intel/catpt/loader.c +++ b/sound/soc/intel/catpt/loader.c @@ -6,8 +6,49 @@ // #include +#include #include #include "core.h" +#include "registers.h" + +/* FW load (200ms) plus operational delays */ +#define FW_READY_TIMEOUT_MS 250 + +#define FW_SIGNATURE "$SST" +#define FW_SIGNATURE_SIZE 4 + +struct catpt_fw_hdr { + char signature[FW_SIGNATURE_SIZE]; + u32 file_size; + u32 modules; + u32 file_format; + u32 reserved[4]; +} __packed; + +struct catpt_fw_mod_hdr { + char signature[FW_SIGNATURE_SIZE]; + u32 mod_size; + u32 blocks; + u16 slot; + u16 module_id; + u32 entry_point; + u32 persistent_size; + u32 scratch_size; +} __packed; + +enum catpt_ram_type { + CATPT_RAM_TYPE_IRAM = 1, + CATPT_RAM_TYPE_DRAM = 2, + /* DRAM with module's initial state */ + CATPT_RAM_TYPE_INSTANCE = 3, +}; + +struct catpt_fw_block_hdr { + u32 ram_type; + u32 size; + u32 ram_offset; + u32 rsvd; +} __packed; void catpt_sram_init(struct resource *sram, u32 start, u32 size) { @@ -44,3 +85,581 @@ catpt_request_region(struct resource *root, resource_size_t size) return __request_region(root, addr, size, NULL, 0); } + +int catpt_store_streams_context(struct catpt_dev *cdev, struct dma_chan *chan) +{ + struct catpt_stream_runtime *stream; + + list_for_each_entry(stream, &cdev->stream_list, node) { + u32 off, size; + int ret; + + off = stream->persistent->start; + size = resource_size(stream->persistent); + dev_dbg(cdev->dev, "storing stream %d ctx: off 0x%08x size %d\n", + stream->info.stream_hw_id, off, size); + + ret = catpt_dma_memcpy_fromdsp(cdev, chan, + cdev->dxbuf_paddr + off, + cdev->lpe_base + off, + ALIGN(size, 4)); + if (ret) { + dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret); + return ret; + } + } + + return 0; +} + +int catpt_store_module_states(struct catpt_dev *cdev, struct dma_chan *chan) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cdev->modules); i++) { + struct catpt_module_type *type; + u32 off; + int ret; + + type = &cdev->modules[i]; + if (!type->loaded || !type->state_size) + continue; + + off = type->state_offset; + dev_dbg(cdev->dev, "storing mod %d state: off 0x%08x size %d\n", + i, off, type->state_size); + + ret = catpt_dma_memcpy_fromdsp(cdev, chan, + cdev->dxbuf_paddr + off, + cdev->lpe_base + off, + ALIGN(type->state_size, 4)); + if (ret) { + dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret); + return ret; + } + } + + return 0; +} + +int catpt_store_memdumps(struct catpt_dev *cdev, struct dma_chan *chan) +{ + int i; + + for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) { + struct catpt_save_meminfo *info; + u32 off; + int ret; + + info = &cdev->dx_ctx.meminfo[i]; + if (info->source != CATPT_DX_TYPE_MEMORY_DUMP) + continue; + + off = catpt_to_host_offset(info->offset); + if (off < cdev->dram.start || off > cdev->dram.end) + continue; + + dev_dbg(cdev->dev, "storing memdump: off 0x%08x size %d\n", + off, info->size); + + ret = catpt_dma_memcpy_fromdsp(cdev, chan, + cdev->dxbuf_paddr + off, + cdev->lpe_base + off, + ALIGN(info->size, 4)); + if (ret) { + dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret); + return ret; + } + } + + return 0; +} + +static int +catpt_restore_streams_context(struct catpt_dev *cdev, struct dma_chan *chan) +{ + struct catpt_stream_runtime *stream; + + list_for_each_entry(stream, &cdev->stream_list, node) { + u32 off, size; + int ret; + + off = stream->persistent->start; + size = resource_size(stream->persistent); + dev_dbg(cdev->dev, "restoring stream %d ctx: off 0x%08x size %d\n", + stream->info.stream_hw_id, off, size); + + ret = catpt_dma_memcpy_todsp(cdev, chan, + cdev->lpe_base + off, + cdev->dxbuf_paddr + off, + ALIGN(size, 4)); + if (ret) { + dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret); + return ret; + } + } + + return 0; +} + +static int catpt_restore_memdumps(struct catpt_dev *cdev, struct dma_chan *chan) +{ + int i; + + for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) { + struct catpt_save_meminfo *info; + u32 off; + int ret; + + info = &cdev->dx_ctx.meminfo[i]; + if (info->source != CATPT_DX_TYPE_MEMORY_DUMP) + continue; + + off = catpt_to_host_offset(info->offset); + if (off < cdev->dram.start || off > cdev->dram.end) + continue; + + dev_dbg(cdev->dev, "restoring memdump: off 0x%08x size %d\n", + off, info->size); + + ret = catpt_dma_memcpy_todsp(cdev, chan, + cdev->lpe_base + off, + cdev->dxbuf_paddr + off, + ALIGN(info->size, 4)); + if (ret) { + dev_err(cdev->dev, "restore block failed: %d\n", ret); + return ret; + } + } + + return 0; +} + +static int catpt_restore_fwimage(struct catpt_dev *cdev, + struct dma_chan *chan, dma_addr_t paddr, + struct catpt_fw_block_hdr *blk) +{ + struct resource r1, r2, common; + int i; + + print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, + blk, sizeof(*blk), false); + + r1.start = cdev->dram.start + blk->ram_offset; + r1.end = r1.start + blk->size - 1; + /* advance to data area */ + paddr += sizeof(*blk); + + for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) { + struct catpt_save_meminfo *info; + u32 off; + int ret; + + info = &cdev->dx_ctx.meminfo[i]; + + if (info->source != CATPT_DX_TYPE_FW_IMAGE) + continue; + + off = catpt_to_host_offset(info->offset); + if (off < cdev->dram.start || off > cdev->dram.end) + continue; + + r2.start = off; + r2.end = r2.start + info->size - 1; + + if (!catpt_resource_overlapping(&r2, &r1, &common)) + continue; + /* calculate start offset of common data area */ + off = common.start - r1.start; + + dev_dbg(cdev->dev, "restoring fwimage: %pr\n", &common); + + ret = catpt_dma_memcpy_todsp(cdev, chan, common.start, + paddr + off, + resource_size(&common)); + if (ret) { + dev_err(cdev->dev, "memcpy todsp failed: %d\n", ret); + return ret; + } + } + + return 0; +} + +static int catpt_load_block(struct catpt_dev *cdev, + struct dma_chan *chan, dma_addr_t paddr, + struct catpt_fw_block_hdr *blk, bool alloc) +{ + struct resource *sram, *res; + dma_addr_t dst_addr; + int ret; + + print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, + blk, sizeof(*blk), false); + + switch (blk->ram_type) { + case CATPT_RAM_TYPE_IRAM: + sram = &cdev->iram; + break; + default: + sram = &cdev->dram; + break; + }; + + dst_addr = sram->start + blk->ram_offset; + if (alloc) { + res = __request_region(sram, dst_addr, blk->size, NULL, 0); + if (!res) + return -EBUSY; + } + + /* advance to data area */ + paddr += sizeof(*blk); + + ret = catpt_dma_memcpy_todsp(cdev, chan, dst_addr, paddr, blk->size); + if (ret) { + dev_err(cdev->dev, "memcpy error: %d\n", ret); + __release_region(sram, dst_addr, blk->size); + } + + return ret; +} + +static int catpt_restore_basefw(struct catpt_dev *cdev, + struct dma_chan *chan, dma_addr_t paddr, + struct catpt_fw_mod_hdr *basefw) +{ + u32 offset = sizeof(*basefw); + int ret, i; + + print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, + basefw, sizeof(*basefw), false); + + /* restore basefw image */ + for (i = 0; i < basefw->blocks; i++) { + struct catpt_fw_block_hdr *blk; + + blk = (struct catpt_fw_block_hdr *)((u8 *)basefw + offset); + + switch (blk->ram_type) { + case CATPT_RAM_TYPE_IRAM: + ret = catpt_load_block(cdev, chan, paddr + offset, + blk, false); + break; + default: + ret = catpt_restore_fwimage(cdev, chan, paddr + offset, + blk); + break; + } + + if (ret) { + dev_err(cdev->dev, "restore block failed: %d\n", ret); + return ret; + } + + offset += sizeof(*blk) + blk->size; + } + + /* then proceed with memory dumps */ + ret = catpt_restore_memdumps(cdev, chan); + if (ret) + dev_err(cdev->dev, "restore memdumps failed: %d\n", ret); + + return ret; +} + +static int catpt_restore_module(struct catpt_dev *cdev, + struct dma_chan *chan, dma_addr_t paddr, + struct catpt_fw_mod_hdr *mod) +{ + u32 offset = sizeof(*mod); + int i; + + print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, + mod, sizeof(*mod), false); + + for (i = 0; i < mod->blocks; i++) { + struct catpt_fw_block_hdr *blk; + int ret; + + blk = (struct catpt_fw_block_hdr *)((u8 *)mod + offset); + + switch (blk->ram_type) { + case CATPT_RAM_TYPE_INSTANCE: + /* restore module state */ + ret = catpt_dma_memcpy_todsp(cdev, chan, + cdev->lpe_base + blk->ram_offset, + cdev->dxbuf_paddr + blk->ram_offset, + ALIGN(blk->size, 4)); + break; + default: + ret = catpt_load_block(cdev, chan, paddr + offset, + blk, false); + break; + } + + if (ret) { + dev_err(cdev->dev, "restore block failed: %d\n", ret); + return ret; + } + + offset += sizeof(*blk) + blk->size; + } + + return 0; +} + +static int catpt_load_module(struct catpt_dev *cdev, + struct dma_chan *chan, dma_addr_t paddr, + struct catpt_fw_mod_hdr *mod) +{ + struct catpt_module_type *type; + u32 offset = sizeof(*mod); + int i; + + print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, + mod, sizeof(*mod), false); + + type = &cdev->modules[mod->module_id]; + + for (i = 0; i < mod->blocks; i++) { + struct catpt_fw_block_hdr *blk; + int ret; + + blk = (struct catpt_fw_block_hdr *)((u8 *)mod + offset); + + ret = catpt_load_block(cdev, chan, paddr + offset, blk, true); + if (ret) { + dev_err(cdev->dev, "load block failed: %d\n", ret); + return ret; + } + + /* + * Save state window coordinates - these will be + * used to capture module state on D0 exit. + */ + if (blk->ram_type == CATPT_RAM_TYPE_INSTANCE) { + type->state_offset = blk->ram_offset; + type->state_size = blk->size; + } + + offset += sizeof(*blk) + blk->size; + } + + /* init module type static info */ + type->loaded = true; + /* DSP expects address from module header substracted by 4 */ + type->entry_point = mod->entry_point - 4; + type->persistent_size = mod->persistent_size; + type->scratch_size = mod->scratch_size; + + return 0; +} + +static int catpt_restore_firmware(struct catpt_dev *cdev, + struct dma_chan *chan, dma_addr_t paddr, + struct catpt_fw_hdr *fw) +{ + u32 offset = sizeof(*fw); + int i; + + print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, + fw, sizeof(*fw), false); + + for (i = 0; i < fw->modules; i++) { + struct catpt_fw_mod_hdr *mod; + int ret; + + mod = (struct catpt_fw_mod_hdr *)((u8 *)fw + offset); + if (strncmp(fw->signature, mod->signature, + FW_SIGNATURE_SIZE)) { + dev_err(cdev->dev, "module signature mismatch\n"); + return -EINVAL; + } + + if (mod->module_id > CATPT_MODID_LAST) + return -EINVAL; + + switch (mod->module_id) { + case CATPT_MODID_BASE_FW: + ret = catpt_restore_basefw(cdev, chan, paddr + offset, + mod); + break; + default: + ret = catpt_restore_module(cdev, chan, paddr + offset, + mod); + break; + } + + if (ret) { + dev_err(cdev->dev, "restore module failed: %d\n", ret); + return ret; + } + + offset += sizeof(*mod) + mod->mod_size; + } + + return 0; +} + +static int catpt_load_firmware(struct catpt_dev *cdev, + struct dma_chan *chan, dma_addr_t paddr, + struct catpt_fw_hdr *fw) +{ + u32 offset = sizeof(*fw); + int i; + + print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, + fw, sizeof(*fw), false); + + for (i = 0; i < fw->modules; i++) { + struct catpt_fw_mod_hdr *mod; + int ret; + + mod = (struct catpt_fw_mod_hdr *)((u8 *)fw + offset); + if (strncmp(fw->signature, mod->signature, + FW_SIGNATURE_SIZE)) { + dev_err(cdev->dev, "module signature mismatch\n"); + return -EINVAL; + } + + if (mod->module_id > CATPT_MODID_LAST) + return -EINVAL; + + ret = catpt_load_module(cdev, chan, paddr + offset, mod); + if (ret) { + dev_err(cdev->dev, "load module failed: %d\n", ret); + return ret; + } + + offset += sizeof(*mod) + mod->mod_size; + } + + return 0; +} + +static int catpt_load_image(struct catpt_dev *cdev, struct dma_chan *chan, + const char *name, const char *signature, + bool restore) +{ + struct catpt_fw_hdr *fw; + struct firmware *img; + dma_addr_t paddr; + void *vaddr; + int ret; + + ret = request_firmware((const struct firmware **)&img, name, cdev->dev); + if (ret) + return ret; + + fw = (struct catpt_fw_hdr *)img->data; + if (strncmp(fw->signature, signature, FW_SIGNATURE_SIZE)) { + dev_err(cdev->dev, "firmware signature mismatch\n"); + ret = -EINVAL; + goto release_fw; + } + + vaddr = dma_alloc_coherent(cdev->dev, img->size, &paddr, GFP_KERNEL); + if (!vaddr) { + ret = -ENOMEM; + goto release_fw; + } + + memcpy(vaddr, img->data, img->size); + fw = (struct catpt_fw_hdr *)vaddr; + if (restore) + ret = catpt_restore_firmware(cdev, chan, paddr, fw); + else + ret = catpt_load_firmware(cdev, chan, paddr, fw); + + dma_free_coherent(cdev->dev, img->size, vaddr, paddr); +release_fw: + release_firmware(img); + return ret; +} + +static int catpt_load_images(struct catpt_dev *cdev, bool restore) +{ + static const char *const names[] = { + "intel/IntcSST1.bin", + "intel/IntcSST2.bin", + }; + struct dma_chan *chan; + int ret; + + chan = catpt_dma_request_config_chan(cdev); + if (IS_ERR(chan)) + return PTR_ERR(chan); + + ret = catpt_load_image(cdev, chan, names[cdev->spec->core_id - 1], + FW_SIGNATURE, restore); + if (ret) + goto release_dma_chan; + + if (!restore) + goto release_dma_chan; + ret = catpt_restore_streams_context(cdev, chan); + if (ret) + dev_err(cdev->dev, "restore streams ctx failed: %d\n", ret); +release_dma_chan: + dma_release_channel(chan); + return ret; +} + +int catpt_boot_firmware(struct catpt_dev *cdev, bool restore) +{ + int ret; + + catpt_dsp_stall(cdev, true); + + ret = catpt_load_images(cdev, restore); + if (ret) { + dev_err(cdev->dev, "load binaries failed: %d\n", ret); + return ret; + } + + reinit_completion(&cdev->fw_ready); + catpt_dsp_stall(cdev, false); + + ret = wait_for_completion_timeout(&cdev->fw_ready, + msecs_to_jiffies(FW_READY_TIMEOUT_MS)); + if (!ret) { + dev_err(cdev->dev, "firmware ready timeout\n"); + return -ETIMEDOUT; + } + + /* update sram pg & clock once done booting */ + catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask); + catpt_dsp_update_srampge(cdev, &cdev->iram, cdev->spec->iram_mask); + + return catpt_dsp_update_lpclock(cdev); +} + +int catpt_first_boot_firmware(struct catpt_dev *cdev) +{ + struct resource *res; + int ret; + + ret = catpt_boot_firmware(cdev, false); + if (ret) { + dev_err(cdev->dev, "basefw boot failed: %d\n", ret); + return ret; + } + + /* restrict FW Core dump area */ + __request_region(&cdev->dram, 0, 0x200, NULL, 0); + /* restrict entire area following BASE_FW - highest offset in DRAM */ + for (res = cdev->dram.child; res->sibling; res = res->sibling) + ; + __request_region(&cdev->dram, res->end + 1, + cdev->dram.end - res->end, NULL, 0); + + ret = catpt_ipc_get_mixer_stream_info(cdev, &cdev->mixer); + if (ret) + return CATPT_IPC_ERROR(ret); + + /* update dram pg for scratch and restricted regions */ + catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask); + + return 0; +} From patchwork Wed Sep 23 12:25:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 291589 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59EE2C2D0A8 for ; Wed, 23 Sep 2020 12:31:16 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 5F1CF206F7 for ; Wed, 23 Sep 2020 12:31:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="QcilXeep" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F1CF206F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 AFFC2827; Wed, 23 Sep 2020 14:30:23 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AFFC2827 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864273; bh=4A745Q4b/M/SR5Az/nhOlTAZCTgo0KIXdFzw4AGThok=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=QcilXeepBtGaHUSWCYaPrQf+UTQSEeA9MhEaXPauJemF2+rWQ3nsGazaFs6Shn4ca dykOVxuXejByKiFomxQxkfoMsYn74giGLd+ByAzXo+tnd1X14Y+4snnrJUx03iv+dZ tTCFxU1mZV23ZCltK1bUGh7b/sK8nH9qLJ9JHjwY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4E739F802FB; Wed, 23 Sep 2020 14:26:29 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0C973F80321; Wed, 23 Sep 2020 14:26:28 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 6FF2FF802E9 for ; Wed, 23 Sep 2020 14:26:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6FF2FF802E9 IronPort-SDR: DCjd/DoEngZnNwXAeDJEaO6xnpHjiBUoB4YXdd6A2aMlmpSTNaVXU0s3Ts8rToMSP+HO5Udq99 mTdiJhGA3RiA== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948235" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948235" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:19 -0700 IronPort-SDR: KIwz+jmkErsi2TspzDXDwqewRRKxCTpK2nTHP6rCaXrN61wX4ITcTbuQV2xslkqKzC+wErPEGu 0qtvfTy4dsMw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338210" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:15 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 06/14] ASoC: Intel: catpt: PCM operations Date: Wed, 23 Sep 2020 14:25:00 +0200 Message-Id: <20200923122508.3360-7-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" DSP designed for Lynxpoint and Wildcat Point offers no dynamic topology i.e. all pipelines are already defined within firmware and host is relegated to allocing stream for predefined pins. This is represented by 'catpt_topology' member. Implementation covers all available pin types: - system playback and capture - two offload streams - loopback (reference) - bluetooth playback and capture PCM DAI operations differentiate between those pins as some (mainly offload) are to be handled differently - DSP expects wp updates on each notify_position notification. System playback has no volume control capability as it is routed to mixer stream directly. Other primary streams - capture and two offloads - offer individual volume controls. Compared to sound/soc/intel/haswell this configures SSP device format automatically on pcm creation. Signed-off-by: Cezary Rojewski --- sound/soc/intel/catpt/core.h | 8 + sound/soc/intel/catpt/ipc.c | 37 + sound/soc/intel/catpt/loader.c | 6 + sound/soc/intel/catpt/pcm.c | 1211 ++++++++++++++++++++++++++++++++ 4 files changed, 1262 insertions(+) create mode 100644 sound/soc/intel/catpt/pcm.c diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h index 260e5ae94a2c..a29b4c0232cb 100644 --- a/sound/soc/intel/catpt/core.h +++ b/sound/soc/intel/catpt/core.h @@ -175,4 +175,12 @@ struct catpt_stream_runtime { struct list_head node; }; +int catpt_register_plat_component(struct catpt_dev *cdev); +void catpt_stream_update_position(struct catpt_dev *cdev, + struct catpt_stream_runtime *stream, + struct catpt_notify_position *pos); +struct catpt_stream_runtime * +catpt_stream_find(struct catpt_dev *cdev, u8 stream_hw_id); +int catpt_arm_stream_templates(struct catpt_dev *cdev); + #endif diff --git a/sound/soc/intel/catpt/ipc.c b/sound/soc/intel/catpt/ipc.c index d5edf3eebdf8..e4569be02bbc 100644 --- a/sound/soc/intel/catpt/ipc.c +++ b/sound/soc/intel/catpt/ipc.c @@ -138,6 +138,42 @@ int catpt_dsp_send_msg(struct catpt_dev *cdev, struct catpt_ipc_msg request, cdev->ipc.default_timeout); } +static void +catpt_dsp_notify_stream(struct catpt_dev *cdev, union catpt_notify_msg msg) +{ + struct catpt_stream_runtime *stream; + struct catpt_notify_position pos; + struct catpt_notify_glitch glitch; + + stream = catpt_stream_find(cdev, msg.stream_hw_id); + if (!stream) { + dev_warn(cdev->dev, "notify %d for non-existent stream %d\n", + msg.notify_reason, msg.stream_hw_id); + return; + } + + switch (msg.notify_reason) { + case CATPT_NOTIFY_POSITION_CHANGED: + memcpy_fromio(&pos, catpt_inbox_addr(cdev), sizeof(pos)); + + catpt_stream_update_position(cdev, stream, &pos); + break; + + case CATPT_NOTIFY_GLITCH_OCCURRED: + memcpy_fromio(&glitch, catpt_inbox_addr(cdev), sizeof(glitch)); + + dev_warn(cdev->dev, "glitch %d at pos: 0x%08llx, wp: 0x%08x\n", + glitch.type, glitch.presentation_pos, + glitch.write_pos); + break; + + default: + dev_warn(cdev->dev, "unknown notification: %d received\n", + msg.notify_reason); + break; + } +} + static void catpt_dsp_copy_rx(struct catpt_dev *cdev, u32 header) { struct catpt_ipc *ipc = &cdev->ipc; @@ -177,6 +213,7 @@ static void catpt_dsp_process_response(struct catpt_dev *cdev, u32 header) case CATPT_GLB_STREAM_MESSAGE: switch (msg.stream_msg_type) { case CATPT_STRM_NOTIFICATION: + catpt_dsp_notify_stream(cdev, msg); break; default: catpt_dsp_copy_rx(cdev, header); diff --git a/sound/soc/intel/catpt/loader.c b/sound/soc/intel/catpt/loader.c index 473e842e9901..8a5f20abcadb 100644 --- a/sound/soc/intel/catpt/loader.c +++ b/sound/soc/intel/catpt/loader.c @@ -658,6 +658,12 @@ int catpt_first_boot_firmware(struct catpt_dev *cdev) if (ret) return CATPT_IPC_ERROR(ret); + ret = catpt_arm_stream_templates(cdev); + if (ret) { + dev_err(cdev->dev, "arm templates failed: %d\n", ret); + return ret; + } + /* update dram pg for scratch and restricted regions */ catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask); diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c new file mode 100644 index 000000000000..bf8941ea0490 --- /dev/null +++ b/sound/soc/intel/catpt/pcm.c @@ -0,0 +1,1211 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include +#include +#include +#include "core.h" +#include "messages.h" + +struct catpt_stream_template { + enum catpt_path_id path_id; + enum catpt_stream_type type; + u32 persistent_size; + u8 num_entries; + struct catpt_module_entry entries[]; +}; + +static struct catpt_stream_template system_pb = { + .path_id = CATPT_PATH_SSP0_OUT, + .type = CATPT_STRM_TYPE_SYSTEM, + .num_entries = 1, + .entries = {{ CATPT_MODID_PCM_SYSTEM, 0 }}, +}; + +static struct catpt_stream_template system_cp = { + .path_id = CATPT_PATH_SSP0_IN, + .type = CATPT_STRM_TYPE_CAPTURE, + .num_entries = 1, + .entries = {{ CATPT_MODID_PCM_CAPTURE, 0 }}, +}; + +static struct catpt_stream_template offload_pb = { + .path_id = CATPT_PATH_SSP0_OUT, + .type = CATPT_STRM_TYPE_RENDER, + .num_entries = 1, + .entries = {{ CATPT_MODID_PCM, 0 }}, +}; + +static struct catpt_stream_template loopback_cp = { + .path_id = CATPT_PATH_SSP0_OUT, + .type = CATPT_STRM_TYPE_LOOPBACK, + .num_entries = 1, + .entries = {{ CATPT_MODID_PCM_REFERENCE, 0 }}, +}; + +static struct catpt_stream_template bluetooth_pb = { + .path_id = CATPT_PATH_SSP1_OUT, + .type = CATPT_STRM_TYPE_BLUETOOTH_RENDER, + .num_entries = 1, + .entries = {{ CATPT_MODID_BLUETOOTH_RENDER, 0 }}, +}; + +static struct catpt_stream_template bluetooth_cp = { + .path_id = CATPT_PATH_SSP1_IN, + .type = CATPT_STRM_TYPE_BLUETOOTH_CAPTURE, + .num_entries = 1, + .entries = {{ CATPT_MODID_BLUETOOTH_CAPTURE, 0 }}, +}; + +static struct catpt_stream_template *catpt_topology[] = { + [CATPT_STRM_TYPE_RENDER] = &offload_pb, + [CATPT_STRM_TYPE_SYSTEM] = &system_pb, + [CATPT_STRM_TYPE_CAPTURE] = &system_cp, + [CATPT_STRM_TYPE_LOOPBACK] = &loopback_cp, + [CATPT_STRM_TYPE_BLUETOOTH_RENDER] = &bluetooth_pb, + [CATPT_STRM_TYPE_BLUETOOTH_CAPTURE] = &bluetooth_cp, +}; + +static struct catpt_stream_template * +catpt_get_stream_template(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtm = substream->private_data; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtm, 0); + enum catpt_stream_type type; + + type = cpu_dai->driver->id; + + /* account for capture in bidirectional dais */ + switch (type) { + case CATPT_STRM_TYPE_SYSTEM: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + type = CATPT_STRM_TYPE_CAPTURE; + break; + case CATPT_STRM_TYPE_BLUETOOTH_RENDER: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + type = CATPT_STRM_TYPE_BLUETOOTH_CAPTURE; + break; + default: + break; + }; + + return catpt_topology[type]; +} + +struct catpt_stream_runtime * +catpt_stream_find(struct catpt_dev *cdev, u8 stream_hw_id) +{ + struct catpt_stream_runtime *pos, *result = NULL; + + spin_lock(&cdev->list_lock); + list_for_each_entry(pos, &cdev->stream_list, node) { + if (pos->info.stream_hw_id == stream_hw_id) { + result = pos; + break; + } + } + + spin_unlock(&cdev->list_lock); + return result; +} + +static u32 catpt_stream_read_position(struct catpt_dev *cdev, + struct catpt_stream_runtime *stream) +{ + u32 pos; + + memcpy_fromio(&pos, cdev->lpe_ba + stream->info.read_pos_regaddr, + sizeof(pos)); + return pos; +} + +static u32 catpt_stream_volume(struct catpt_dev *cdev, + struct catpt_stream_runtime *stream, u32 channel) +{ + u32 volume, offset; + + if (channel >= CATPT_CHANNELS_MAX) + channel = 0; + + offset = stream->info.volume_regaddr[channel]; + memcpy_fromio(&volume, cdev->lpe_ba + offset, sizeof(volume)); + return volume; +} + +static u32 catpt_mixer_volume(struct catpt_dev *cdev, + struct catpt_mixer_stream_info *info, u32 channel) +{ + u32 volume, offset; + + if (channel >= CATPT_CHANNELS_MAX) + channel = 0; + + offset = info->volume_regaddr[channel]; + memcpy_fromio(&volume, cdev->lpe_ba + offset, sizeof(volume)); + return volume; +} + +static void catpt_arrange_page_table(struct snd_pcm_substream *substream, + struct snd_dma_buffer *pgtbl) +{ + struct snd_pcm_runtime *rtm = substream->runtime; + struct snd_dma_buffer *databuf = snd_pcm_get_dma_buf(substream); + int i, pages; + + pages = snd_sgbuf_aligned_pages(rtm->dma_bytes); + + for (i = 0; i < pages; i++) { + u32 pfn, offset; + u32 *page_table; + + pfn = PFN_DOWN(snd_sgbuf_get_addr(databuf, i * PAGE_SIZE)); + /* incrementing by 2 on even and 3 on odd */ + offset = ((i << 2) + i) >> 1; + page_table = (u32 *)(pgtbl->area + offset); + + if (i & 1) + *page_table |= (pfn << 4); + else + *page_table |= pfn; + } +} + +static u32 catpt_get_channel_map(enum catpt_channel_config config) +{ + switch (config) { + case CATPT_CHANNEL_CONFIG_MONO: + return (GENMASK(31, 4) | CATPT_CHANNEL_CENTER); + + case CATPT_CHANNEL_CONFIG_STEREO: + return (GENMASK(31, 8) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_RIGHT << 4)); + + case CATPT_CHANNEL_CONFIG_2_POINT_1: + return (GENMASK(31, 12) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_RIGHT << 4) + | (CATPT_CHANNEL_LFE << 8)); + + case CATPT_CHANNEL_CONFIG_3_POINT_0: + return (GENMASK(31, 12) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_CENTER << 4) + | (CATPT_CHANNEL_RIGHT << 8)); + + case CATPT_CHANNEL_CONFIG_3_POINT_1: + return (GENMASK(31, 16) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_CENTER << 4) + | (CATPT_CHANNEL_RIGHT << 8) + | (CATPT_CHANNEL_LFE << 12)); + + case CATPT_CHANNEL_CONFIG_QUATRO: + return (GENMASK(31, 16) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_RIGHT << 4) + | (CATPT_CHANNEL_LEFT_SURROUND << 8) + | (CATPT_CHANNEL_RIGHT_SURROUND << 12)); + + case CATPT_CHANNEL_CONFIG_4_POINT_0: + return (GENMASK(31, 16) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_CENTER << 4) + | (CATPT_CHANNEL_RIGHT << 8) + | (CATPT_CHANNEL_CENTER_SURROUND << 12)); + + case CATPT_CHANNEL_CONFIG_5_POINT_0: + return (GENMASK(31, 20) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_CENTER << 4) + | (CATPT_CHANNEL_RIGHT << 8) + | (CATPT_CHANNEL_LEFT_SURROUND << 12) + | (CATPT_CHANNEL_RIGHT_SURROUND << 16)); + + case CATPT_CHANNEL_CONFIG_5_POINT_1: + return (GENMASK(31, 24) | CATPT_CHANNEL_CENTER + | (CATPT_CHANNEL_LEFT << 4) + | (CATPT_CHANNEL_RIGHT << 8) + | (CATPT_CHANNEL_LEFT_SURROUND << 12) + | (CATPT_CHANNEL_RIGHT_SURROUND << 16) + | (CATPT_CHANNEL_LFE << 20)); + + case CATPT_CHANNEL_CONFIG_DUAL_MONO: + return (GENMASK(31, 8) | CATPT_CHANNEL_LEFT + | (CATPT_CHANNEL_LEFT << 4)); + + default: + return U32_MAX; + } +} + +static enum catpt_channel_config catpt_get_channel_config(u32 num_channels) +{ + switch (num_channels) { + case 6: + return CATPT_CHANNEL_CONFIG_5_POINT_1; + case 5: + return CATPT_CHANNEL_CONFIG_5_POINT_0; + case 4: + return CATPT_CHANNEL_CONFIG_QUATRO; + case 3: + return CATPT_CHANNEL_CONFIG_2_POINT_1; + case 1: + return CATPT_CHANNEL_CONFIG_MONO; + case 2: + default: + return CATPT_CHANNEL_CONFIG_STEREO; + } +} + +static int catpt_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct catpt_stream_template *template; + struct catpt_stream_runtime *stream; + struct resource *res; + int ret; + + template = catpt_get_stream_template(substream); + + stream = kzalloc(sizeof(*stream), GFP_KERNEL); + if (!stream) + return -ENOMEM; + + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, cdev->dev, PAGE_SIZE, + &stream->pgtbl); + if (ret) + goto err_pgtbl; + + res = catpt_request_region(&cdev->dram, template->persistent_size); + if (!res) { + ret = -EBUSY; + goto err_request; + } + + catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask); + + stream->template = template; + stream->persistent = res; + stream->substream = substream; + INIT_LIST_HEAD(&stream->node); + snd_soc_dai_set_dma_data(dai, substream, stream); + + spin_lock(&cdev->list_lock); + list_add_tail(&stream->node, &cdev->stream_list); + spin_unlock(&cdev->list_lock); + + return 0; + +err_request: + snd_dma_free_pages(&stream->pgtbl); +err_pgtbl: + kfree(stream); + return ret; +} + +static void catpt_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct catpt_stream_runtime *stream; + + stream = snd_soc_dai_get_dma_data(dai, substream); + + spin_lock(&cdev->list_lock); + list_del(&stream->node); + spin_unlock(&cdev->list_lock); + + release_resource(stream->persistent); + kfree(stream->persistent); + catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask); + + snd_dma_free_pages(&stream->pgtbl); + kfree(stream); + snd_soc_dai_set_dma_data(dai, substream, NULL); +} + +static int catpt_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct catpt_stream_runtime *stream; + struct catpt_audio_format afmt; + struct catpt_ring_info rinfo; + struct snd_pcm_runtime *rtm = substream->runtime; + struct snd_dma_buffer *dmab; + int ret; + + stream = snd_soc_dai_get_dma_data(dai, substream); + if (stream->allocated) + return 0; + + memset(&afmt, 0, sizeof(afmt)); + afmt.sample_rate = params_rate(params); + afmt.bit_depth = params_physical_width(params); + afmt.valid_bit_depth = params_width(params); + afmt.num_channels = params_channels(params); + afmt.channel_config = catpt_get_channel_config(afmt.num_channels); + afmt.channel_map = catpt_get_channel_map(afmt.channel_config); + afmt.interleaving = CATPT_INTERLEAVING_PER_CHANNEL; + + dmab = snd_pcm_get_dma_buf(substream); + catpt_arrange_page_table(substream, &stream->pgtbl); + + memset(&rinfo, 0, sizeof(rinfo)); + rinfo.page_table_addr = stream->pgtbl.addr; + rinfo.num_pages = DIV_ROUND_UP(rtm->dma_bytes, PAGE_SIZE); + rinfo.size = rtm->dma_bytes; + rinfo.offset = 0; + rinfo.ring_first_page_pfn = PFN_DOWN(snd_sgbuf_get_addr(dmab, 0)); + + ret = catpt_ipc_alloc_stream(cdev, stream->template->path_id, + stream->template->type, + &afmt, &rinfo, + stream->template->num_entries, + stream->template->entries, + stream->persistent, + cdev->scratch, + &stream->info); + if (ret) + return CATPT_IPC_ERROR(ret); + + stream->allocated = true; + return 0; +} + +static int catpt_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct catpt_stream_runtime *stream; + + stream = snd_soc_dai_get_dma_data(dai, substream); + if (!stream->allocated) + return 0; + + catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id); + catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); + + stream->allocated = false; + return 0; +} + +static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol); + +static int catpt_dai_apply_usettings(struct snd_soc_dai *dai, + struct catpt_stream_runtime *stream) +{ + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct snd_soc_component *component = dai->component; + struct snd_kcontrol *pos, *kctl = NULL; + const char *name; + int ret; + u32 id = stream->info.stream_hw_id; + + /* only selected streams have individual controls */ + switch (id) { + case CATPT_PIN_ID_OFFLOAD1: + name = "Media0 Playback Volume"; + break; + case CATPT_PIN_ID_OFFLOAD2: + name = "Media1 Playback Volume"; + break; + case CATPT_PIN_ID_CAPTURE1: + name = "Mic Capture Volume"; + break; + case CATPT_PIN_ID_REFERENCE: + name = "Loopback Mute"; + break; + default: + return 0; + }; + + list_for_each_entry(pos, &component->card->snd_card->controls, list) { + if (pos->private_data == component && + !strncmp(name, pos->id.name, sizeof(pos->id.name))) { + kctl = pos; + break; + } + } + if (!kctl) + return -ENOENT; + + if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK) + return catpt_set_dspvol(cdev, id, (long *)kctl->private_value); + ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)kctl->private_value); + if (ret) + return CATPT_IPC_ERROR(ret); + return 0; +} + +static int catpt_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct catpt_stream_runtime *stream; + int ret; + + stream = snd_soc_dai_get_dma_data(dai, substream); + if (stream->prepared) + return 0; + + ret = catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id); + if (ret) + return CATPT_IPC_ERROR(ret); + + ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id); + if (ret) + return CATPT_IPC_ERROR(ret); + + ret = catpt_dsp_update_lpclock(cdev); + if (ret) + return ret; + + ret = catpt_dai_apply_usettings(dai, stream); + if (ret) + return ret; + + stream->prepared = true; + return 0; +} + +static int catpt_dai_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct catpt_stream_runtime *stream; + struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_uframes_t pos; + int ret; + + stream = snd_soc_dai_get_dma_data(dai, substream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* only offload is set_write_pos driven */ + if (stream->template->type != CATPT_STRM_TYPE_RENDER) + goto resume_stream; + + pos = frames_to_bytes(runtime, runtime->start_threshold); + /* + * Dsp operates on buffer halves, thus max 2x set_write_pos + * (entire buffer filled) prior to stream start. + */ + ret = catpt_ipc_set_write_pos(cdev, stream->info.stream_hw_id, + pos, false, false); + if (ret) + return CATPT_IPC_ERROR(ret); + fallthrough; + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + resume_stream: + ret = catpt_ipc_resume_stream(cdev, stream->info.stream_hw_id); + if (ret) + return CATPT_IPC_ERROR(ret); + break; + + case SNDRV_PCM_TRIGGER_STOP: + stream->prepared = false; + catpt_dsp_update_lpclock(cdev); + fallthrough; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id); + if (ret) + return CATPT_IPC_ERROR(ret); + break; + + default: + break; + } + + return 0; +} + +void catpt_stream_update_position(struct catpt_dev *cdev, + struct catpt_stream_runtime *stream, + struct catpt_notify_position *pos) +{ + struct snd_pcm_substream *substream = stream->substream; + struct snd_pcm_runtime *r = substream->runtime; + snd_pcm_uframes_t dsppos, newpos; + int ret; + + dsppos = bytes_to_frames(r, pos->stream_position); + + /* only offload is set_write_pos driven */ + if (stream->template->type != CATPT_STRM_TYPE_RENDER) + goto exit; + + if (dsppos >= r->buffer_size / 2) + newpos = r->buffer_size / 2; + else + newpos = 0; + /* + * Dsp operates on buffer halves, thus on every notify position + * (buffer half consumed) update wp to allow stream progression. + */ + ret = catpt_ipc_set_write_pos(cdev, stream->info.stream_hw_id, + frames_to_bytes(r, newpos), + false, false); + if (ret) { + dev_err(cdev->dev, "update position for stream %d failed: %d\n", + stream->info.stream_hw_id, ret); + return; + } +exit: + snd_pcm_period_elapsed(substream); +} + +/* 200 ms for 2 32-bit channels at 48kHz (native format) */ +#define CATPT_BUFFER_MAX_SIZE 76800 +#define CATPT_PCM_PERIODS_MAX 4 +#define CATPT_PCM_PERIODS_MIN 2 + +static const struct snd_pcm_hardware catpt_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .period_bytes_min = PAGE_SIZE, + .period_bytes_max = CATPT_BUFFER_MAX_SIZE / CATPT_PCM_PERIODS_MIN, + .periods_min = CATPT_PCM_PERIODS_MIN, + .periods_max = CATPT_PCM_PERIODS_MAX, + .buffer_bytes_max = CATPT_BUFFER_MAX_SIZE, +}; + +static int catpt_component_pcm_construct(struct snd_soc_component *component, + struct snd_soc_pcm_runtime *rtd) +{ + struct catpt_dev *cdev = dev_get_drvdata(component->dev); + + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV_SG, + cdev->dev, + catpt_pcm_hardware.buffer_bytes_max, + catpt_pcm_hardware.buffer_bytes_max); + + return 0; +} + +static int catpt_component_open(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtm = substream->private_data; + + if (rtm->dai_link->no_pcm) + return 0; + snd_soc_set_runtime_hwparams(substream, &catpt_pcm_hardware); + return 0; +} + +static snd_pcm_uframes_t +catpt_component_pointer(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + struct catpt_dev *cdev = dev_get_drvdata(component->dev); + struct catpt_stream_runtime *stream; + struct snd_soc_pcm_runtime *rtm = substream->private_data; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtm, 0); + u32 pos; + + if (rtm->dai_link->no_pcm) + return 0; + + stream = snd_soc_dai_get_dma_data(cpu_dai, substream); + pos = catpt_stream_read_position(cdev, stream); + + return bytes_to_frames(substream->runtime, pos); +} + +static const struct snd_soc_dai_ops catpt_fe_dai_ops = { + .startup = catpt_dai_startup, + .shutdown = catpt_dai_shutdown, + .hw_params = catpt_dai_hw_params, + .hw_free = catpt_dai_hw_free, + .prepare = catpt_dai_prepare, + .trigger = catpt_dai_trigger, +}; + +static int catpt_dai_pcm_new(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_dai *dai) +{ + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct catpt_dev *cdev = dev_get_drvdata(dai->dev); + struct catpt_ssp_device_format devfmt; + int ret; + + devfmt.iface = dai->driver->id; + devfmt.channels = codec_dai->driver->capture.channels_max; + + switch (devfmt.iface) { + case CATPT_SSP_IFACE_0: + devfmt.mclk = CATPT_MCLK_FREQ_24_MHZ; + + switch (devfmt.channels) { + case 4: + devfmt.mode = CATPT_SSP_MODE_TDM_PROVIDER; + devfmt.clock_divider = 4; + break; + case 2: + default: + devfmt.mode = CATPT_SSP_MODE_I2S_PROVIDER; + devfmt.clock_divider = 9; + break; + } + break; + + case CATPT_SSP_IFACE_1: + devfmt.mclk = CATPT_MCLK_OFF; + devfmt.mode = CATPT_SSP_MODE_I2S_CONSUMER; + devfmt.clock_divider = 0; + break; + } + + ret = catpt_ipc_set_device_format(cdev, &devfmt); + if (ret) + return CATPT_IPC_ERROR(ret); + + /* store device format set for given SSP */ + memcpy(&cdev->devfmt[devfmt.iface], &devfmt, sizeof(devfmt)); + return 0; +} + +static struct snd_soc_dai_driver dai_drivers[] = { +/* FE DAIs */ +{ + .name = "System Pin", + .id = CATPT_STRM_TYPE_SYSTEM, + .ops = &catpt_fe_dai_ops, + .playback = { + .stream_name = "System Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + }, + .capture = { + .stream_name = "Analog Capture", + .channels_min = 2, + .channels_max = 4, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +{ + .name = "Offload0 Pin", + .id = CATPT_STRM_TYPE_RENDER, + .ops = &catpt_fe_dai_ops, + .playback = { + .stream_name = "Offload0 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +{ + .name = "Offload1 Pin", + .id = CATPT_STRM_TYPE_RENDER, + .ops = &catpt_fe_dai_ops, + .playback = { + .stream_name = "Offload1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +{ + .name = "Loopback Pin", + .id = CATPT_STRM_TYPE_LOOPBACK, + .ops = &catpt_fe_dai_ops, + .capture = { + .stream_name = "Loopback Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +{ + .name = "Bluetooth Pin", + .id = CATPT_STRM_TYPE_BLUETOOTH_RENDER, + .ops = &catpt_fe_dai_ops, + .playback = { + .stream_name = "Bluetooth Playback", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "Bluetooth Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}, +/* BE DAIs */ +{ + .name = "ssp0-port", + .id = CATPT_SSP_IFACE_0, + .pcm_new = catpt_dai_pcm_new, + .playback = { + .channels_min = 1, + .channels_max = 8, + }, + .capture = { + .channels_min = 1, + .channels_max = 8, + }, +}, +{ + .name = "ssp1-port", + .id = CATPT_SSP_IFACE_1, + .pcm_new = catpt_dai_pcm_new, + .playback = { + .channels_min = 1, + .channels_max = 8, + }, + .capture = { + .channels_min = 1, + .channels_max = 8, + }, +}, +}; + +#define DSP_VOLUME_MAX S32_MAX /* 0db */ + +static const u32 volume_map[] = { + DSP_VOLUME_MAX >> 30, + DSP_VOLUME_MAX >> 29, + DSP_VOLUME_MAX >> 28, + DSP_VOLUME_MAX >> 27, + DSP_VOLUME_MAX >> 26, + DSP_VOLUME_MAX >> 25, + DSP_VOLUME_MAX >> 24, + DSP_VOLUME_MAX >> 23, + DSP_VOLUME_MAX >> 22, + DSP_VOLUME_MAX >> 21, + DSP_VOLUME_MAX >> 20, + DSP_VOLUME_MAX >> 19, + DSP_VOLUME_MAX >> 18, + DSP_VOLUME_MAX >> 17, + DSP_VOLUME_MAX >> 16, + DSP_VOLUME_MAX >> 15, + DSP_VOLUME_MAX >> 14, + DSP_VOLUME_MAX >> 13, + DSP_VOLUME_MAX >> 12, + DSP_VOLUME_MAX >> 11, + DSP_VOLUME_MAX >> 10, + DSP_VOLUME_MAX >> 9, + DSP_VOLUME_MAX >> 8, + DSP_VOLUME_MAX >> 7, + DSP_VOLUME_MAX >> 6, + DSP_VOLUME_MAX >> 5, + DSP_VOLUME_MAX >> 4, + DSP_VOLUME_MAX >> 3, + DSP_VOLUME_MAX >> 2, + DSP_VOLUME_MAX >> 1, + DSP_VOLUME_MAX >> 0, +}; + +static u32 ctlvol_to_dspvol(u32 value) +{ + if (value >= ARRAY_SIZE(volume_map)) + value = 0; + return volume_map[value]; +} + +static u32 dspvol_to_ctlvol(u32 volume) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(volume_map); i++) + if (volume_map[i] >= volume) + return i; + return i - 1; +} + +static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol) +{ + u32 dspvol; + int ret, i; + + for (i = 1; i < CATPT_CHANNELS_MAX; i++) + if (ctlvol[i] == ctlvol[0]) + break; + + if (i == CATPT_CHANNELS_MAX) { + dspvol = ctlvol_to_dspvol(ctlvol[0]); + + ret = catpt_ipc_set_volume(cdev, stream_id, + CATPT_ALL_CHANNELS_MASK, dspvol, + 0, CATPT_AUDIO_CURVE_NONE); + } else { + for (i = 0; i < CATPT_CHANNELS_MAX; i++) { + dspvol = ctlvol_to_dspvol(ctlvol[i]); + + ret = catpt_ipc_set_volume(cdev, stream_id, + i, dspvol, + 0, CATPT_AUDIO_CURVE_NONE); + if (ret) + break; + } + } + + if (ret) + return CATPT_IPC_ERROR(ret); + return 0; +} + +static int catpt_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = CATPT_CHANNELS_MAX; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = ARRAY_SIZE(volume_map) - 1; + return 0; +} + +static int catpt_mixer_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct catpt_dev *cdev = dev_get_drvdata(component->dev); + u32 dspvol; + int i; + + pm_runtime_get_sync(cdev->dev); + + for (i = 0; i < CATPT_CHANNELS_MAX; i++) { + dspvol = catpt_mixer_volume(cdev, &cdev->mixer, i); + ucontrol->value.integer.value[i] = dspvol_to_ctlvol(dspvol); + } + + pm_runtime_mark_last_busy(cdev->dev); + pm_runtime_put_autosuspend(cdev->dev); + + return 0; +} + +static int catpt_mixer_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct catpt_dev *cdev = dev_get_drvdata(component->dev); + int ret; + + pm_runtime_get_sync(cdev->dev); + + ret = catpt_set_dspvol(cdev, cdev->mixer.mixer_hw_id, + ucontrol->value.integer.value); + + pm_runtime_mark_last_busy(cdev->dev); + pm_runtime_put_autosuspend(cdev->dev); + + return ret; +} + +static int catpt_stream_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, + enum catpt_pin_id pin_id) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct catpt_dev *cdev = dev_get_drvdata(component->dev); + struct catpt_stream_runtime *stream; + long *ctlvol = (long *)kcontrol->private_value; + u32 dspvol; + int i; + + stream = catpt_stream_find(cdev, pin_id); + if (!stream) { + for (i = 0; i < CATPT_CHANNELS_MAX; i++) + ucontrol->value.integer.value[i] = ctlvol[i]; + return 0; + } + + pm_runtime_get_sync(cdev->dev); + + for (i = 0; i < CATPT_CHANNELS_MAX; i++) { + dspvol = catpt_stream_volume(cdev, stream, i); + ucontrol->value.integer.value[i] = dspvol_to_ctlvol(dspvol); + } + + pm_runtime_mark_last_busy(cdev->dev); + pm_runtime_put_autosuspend(cdev->dev); + + return 0; +} + +static int catpt_stream_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, + enum catpt_pin_id pin_id) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct catpt_dev *cdev = dev_get_drvdata(component->dev); + struct catpt_stream_runtime *stream; + long *ctlvol = (long *)kcontrol->private_value; + int ret, i; + + stream = catpt_stream_find(cdev, pin_id); + if (!stream) { + for (i = 0; i < CATPT_CHANNELS_MAX; i++) + ctlvol[i] = ucontrol->value.integer.value[i]; + return 0; + } + + pm_runtime_get_sync(cdev->dev); + + ret = catpt_set_dspvol(cdev, stream->info.stream_hw_id, + ucontrol->value.integer.value); + + pm_runtime_mark_last_busy(cdev->dev); + pm_runtime_put_autosuspend(cdev->dev); + + if (ret) + return ret; + + for (i = 0; i < CATPT_CHANNELS_MAX; i++) + ctlvol[i] = ucontrol->value.integer.value[i]; + return 0; +} + +static int catpt_offload1_volume_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + return catpt_stream_volume_get(kctl, uctl, CATPT_PIN_ID_OFFLOAD1); +} + +static int catpt_offload1_volume_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + return catpt_stream_volume_put(kctl, uctl, CATPT_PIN_ID_OFFLOAD1); +} + +static int catpt_offload2_volume_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + return catpt_stream_volume_get(kctl, uctl, CATPT_PIN_ID_OFFLOAD2); +} + +static int catpt_offload2_volume_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + return catpt_stream_volume_put(kctl, uctl, CATPT_PIN_ID_OFFLOAD2); +} + +static int catpt_capture_volume_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + return catpt_stream_volume_get(kctl, uctl, CATPT_PIN_ID_CAPTURE1); +} + +static int catpt_capture_volume_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + return catpt_stream_volume_put(kctl, uctl, CATPT_PIN_ID_CAPTURE1); +} + +static int catpt_loopback_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = *(bool *)kcontrol->private_value; + return 0; +} + +static int catpt_loopback_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct catpt_dev *cdev = dev_get_drvdata(component->dev); + struct catpt_stream_runtime *stream; + bool mute; + int ret; + + mute = (bool)ucontrol->value.integer.value[0]; + stream = catpt_stream_find(cdev, CATPT_PIN_ID_REFERENCE); + if (!stream) { + *(bool *)kcontrol->private_value = mute; + return 0; + } + + pm_runtime_get_sync(cdev->dev); + + ret = catpt_ipc_mute_loopback(cdev, stream->info.stream_hw_id, mute); + + pm_runtime_mark_last_busy(cdev->dev); + pm_runtime_put_autosuspend(cdev->dev); + + if (ret) + return CATPT_IPC_ERROR(ret); + + *(bool *)kcontrol->private_value = mute; + return 0; +} + +static int catpt_waves_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int catpt_waves_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int catpt_waves_param_get(struct snd_kcontrol *kcontrol, + unsigned int __user *bytes, + unsigned int size) +{ + return 0; +} + +static int catpt_waves_param_put(struct snd_kcontrol *kcontrol, + const unsigned int __user *bytes, + unsigned int size) +{ + return 0; +} + +static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(catpt_volume_tlv, -9000, 300, 1); + +#define CATPT_VOLUME_CTL(kname, sname) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = (kname), \ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_READWRITE, \ + .info = catpt_volume_info, \ + .get = catpt_##sname##_volume_get, \ + .put = catpt_##sname##_volume_put, \ + .tlv.p = catpt_volume_tlv, \ + .private_value = (unsigned long) \ + &(long[CATPT_CHANNELS_MAX]) {0} } + +static const struct snd_kcontrol_new component_kcontrols[] = { +/* Master volume (mixer stream) */ +CATPT_VOLUME_CTL("Master Playback Volume", mixer), +/* Individual volume controls for offload and capture */ +CATPT_VOLUME_CTL("Media0 Playback Volume", offload1), +CATPT_VOLUME_CTL("Media1 Playback Volume", offload2), +CATPT_VOLUME_CTL("Mic Capture Volume", capture), +SOC_SINGLE_BOOL_EXT("Loopback Mute", (unsigned long)&(bool[1]) {0}, + catpt_loopback_switch_get, catpt_loopback_switch_put), +/* Enable or disable WAVES module */ +SOC_SINGLE_BOOL_EXT("Waves Switch", 0, + catpt_waves_switch_get, catpt_waves_switch_put), +/* WAVES module parameter control */ +SND_SOC_BYTES_TLV("Waves Set Param", 128, + catpt_waves_param_get, catpt_waves_param_put), +}; + +static const struct snd_soc_dapm_widget component_widgets[] = { + SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL, 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM, 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route component_routes[] = { + {"Playback VMixer", NULL, "System Playback"}, + {"Playback VMixer", NULL, "Offload0 Playback"}, + {"Playback VMixer", NULL, "Offload1 Playback"}, + + {"SSP0 CODEC OUT", NULL, "Playback VMixer"}, + + {"Analog Capture", NULL, "SSP0 CODEC IN"}, + {"Loopback Capture", NULL, "SSP0 CODEC IN"}, + + {"SSP1 BT OUT", NULL, "Bluetooth Playback"}, + {"Bluetooth Capture", NULL, "SSP1 BT IN"}, +}; + +static const struct snd_soc_component_driver catpt_comp_driver = { + .name = "catpt-platform", + + .pcm_construct = catpt_component_pcm_construct, + .open = catpt_component_open, + .pointer = catpt_component_pointer, + + .controls = component_kcontrols, + .num_controls = ARRAY_SIZE(component_kcontrols), + .dapm_widgets = component_widgets, + .num_dapm_widgets = ARRAY_SIZE(component_widgets), + .dapm_routes = component_routes, + .num_dapm_routes = ARRAY_SIZE(component_routes), +}; + +int catpt_arm_stream_templates(struct catpt_dev *cdev) +{ + struct resource *res; + u32 scratch_size = 0; + int i, j; + + for (i = 0; i < ARRAY_SIZE(catpt_topology); i++) { + struct catpt_stream_template *template; + struct catpt_module_entry *entry; + struct catpt_module_type *type; + + template = catpt_topology[i]; + template->persistent_size = 0; + + for (j = 0; j < template->num_entries; j++) { + entry = &template->entries[j]; + type = &cdev->modules[entry->module_id]; + + if (!type->loaded) + return -ENOENT; + + entry->entry_point = type->entry_point; + template->persistent_size += type->persistent_size; + if (type->scratch_size > scratch_size) + scratch_size = type->scratch_size; + } + } + + if (scratch_size) { + /* allocate single scratch area for all modules */ + res = catpt_request_region(&cdev->dram, scratch_size); + if (!res) + return -EBUSY; + cdev->scratch = res; + } + + return 0; +} + +int catpt_register_plat_component(struct catpt_dev *cdev) +{ + struct snd_soc_component *component; + int ret; + + component = devm_kzalloc(cdev->dev, sizeof(*component), GFP_KERNEL); + if (!component) + return -ENOMEM; + + ret = snd_soc_component_initialize(component, &catpt_comp_driver, + cdev->dev); + if (ret) + return ret; + + component->name = catpt_comp_driver.name; + return snd_soc_add_component(component, dai_drivers, + ARRAY_SIZE(dai_drivers)); +} From patchwork Wed Sep 23 12:25:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 250907 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67CACC2D0A8 for ; Wed, 23 Sep 2020 12:31:51 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 88EE82137B for ; Wed, 23 Sep 2020 12:31:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="euVky4Gr" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 88EE82137B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 287FC16C2; Wed, 23 Sep 2020 14:30:58 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 287FC16C2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864308; bh=dWCTzp7EyevJbepJXcWBg6RjbT85FDzoGjFm49svQak=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=euVky4Grog3D6i/CqQm3emgPwVIgHDq7wLXo4Xi95CcwYvJHBrmDn/T7KFMxUDLt2 qj0zMMnTjyyKIPLDs4/w0bRhw/UIMLW5Ga0Vx9r6C8qEx6TZctnw0pjbfdJvhA5kxB sEUJTb0K9O4uQbWvyARi6KgcNBjAjzo42dWcEwEM= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 9F6A9F80323; Wed, 23 Sep 2020 14:26:30 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 452C3F80322; Wed, 23 Sep 2020 14:26:28 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 31B4AF802FB for ; Wed, 23 Sep 2020 14:26:24 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 31B4AF802FB IronPort-SDR: KWc8A9nBCnFKM3g0lGujsuXZq1fSfUyr/tTB4ARlx14rLen+fblVBNljUQqOBg3UZrIJa9ZjPd bjuWsvSVEmPA== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948240" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948240" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:23 -0700 IronPort-SDR: +zqb1Lxb1fmlOKxOyrnPAwJSCe5wBRhf91AnJm6h3BMMBd6v4VhQyGt+qRfN6PbaTB2VwD0yBc SFKmS0OpeRgQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338229" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:19 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 07/14] ASoC: Intel: catpt: Device driver lifecycle Date: Wed, 23 Sep 2020 14:25:01 +0200 Message-Id: <20200923122508.3360-8-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Implement ACPI device probing and removal functions as well as handlers for its PM capabilities. Device probing also takes care of enumerating ADSP subsystem components. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko --- sound/soc/intel/catpt/device.c | 344 +++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 sound/soc/intel/catpt/device.c diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c new file mode 100644 index 000000000000..e7dc2fb69ea8 --- /dev/null +++ b/sound/soc/intel/catpt/device.c @@ -0,0 +1,344 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// +// Special thanks to: +// Marcin Barlik +// Piotr Papierkowski +// +// for sharing LPT-LP and WTP-LP AudioDSP architecture expertise and +// helping backtrack its historical background +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" +#include "registers.h" + +static int __maybe_unused catpt_suspend(struct device *dev) +{ + struct catpt_dev *cdev = dev_get_drvdata(dev); + struct dma_chan *chan; + int ret; + + chan = catpt_dma_request_config_chan(cdev); + if (IS_ERR(chan)) + return PTR_ERR(chan); + + memset(&cdev->dx_ctx, 0, sizeof(cdev->dx_ctx)); + ret = catpt_ipc_enter_dxstate(cdev, CATPT_DX_STATE_D3, &cdev->dx_ctx); + if (ret) { + ret = CATPT_IPC_ERROR(ret); + goto release_dma_chan; + } + + ret = catpt_dsp_stall(cdev, true); + if (ret) + goto release_dma_chan; + + ret = catpt_store_memdumps(cdev, chan); + if (ret) { + dev_err(cdev->dev, "store memdumps failed: %d\n", ret); + goto release_dma_chan; + } + + ret = catpt_store_module_states(cdev, chan); + if (ret) { + dev_err(cdev->dev, "store module states failed: %d\n", ret); + goto release_dma_chan; + } + + ret = catpt_store_streams_context(cdev, chan); + if (ret) + dev_err(cdev->dev, "store streams ctx failed: %d\n", ret); + +release_dma_chan: + dma_release_channel(chan); + if (ret) + return ret; + return cdev->spec->power_down(cdev); +} + +static int __maybe_unused catpt_resume(struct device *dev) +{ + struct catpt_dev *cdev = dev_get_drvdata(dev); + int ret, i; + + ret = cdev->spec->power_up(cdev); + if (ret) + return ret; + + if (!module_is_live(dev->driver->owner)) { + dev_info(dev, "module unloading, skipping fw boot\n"); + return 0; + } + + ret = catpt_boot_firmware(cdev, true); + if (ret) { + dev_err(cdev->dev, "boot firmware failed: %d\n", ret); + return ret; + } + + /* reconfigure SSP devices after Dx transition */ + for (i = 0; i < CATPT_SSP_COUNT; i++) { + if (cdev->devfmt[i].iface == UINT_MAX) + continue; + + ret = catpt_ipc_set_device_format(cdev, &cdev->devfmt[i]); + if (ret) + return CATPT_IPC_ERROR(ret); + } + + return 0; +} + +static int __maybe_unused catpt_runtime_suspend(struct device *dev) +{ + return catpt_suspend(dev); +} + +static int __maybe_unused catpt_runtime_resume(struct device *dev) +{ + return catpt_resume(dev); +} + +static const struct dev_pm_ops catpt_dev_pm = { + SET_SYSTEM_SLEEP_PM_OPS(catpt_suspend, catpt_resume) + SET_RUNTIME_PM_OPS(catpt_runtime_suspend, catpt_runtime_resume, NULL) +}; + +/* machine board owned by CATPT is removed with this hook */ +static void board_pdev_unregister(void *data) +{ + platform_device_unregister(data); +} + +static int catpt_register_board(struct catpt_dev *cdev) +{ + const struct catpt_spec *spec = cdev->spec; + struct snd_soc_acpi_mach *mach; + struct platform_device *board; + + mach = snd_soc_acpi_find_machine(spec->machines); + if (!mach) { + dev_info(cdev->dev, "no machines present\n"); + return 0; + } + + mach->mach_params.platform = "catpt-platform"; + board = platform_device_register_data(NULL, mach->drv_name, + PLATFORM_DEVID_NONE, + (const void *)mach, sizeof(*mach)); + if (IS_ERR(board)) { + dev_err(cdev->dev, "board register failed\n"); + return PTR_ERR(board); + } + + return devm_add_action_or_reset(cdev->dev, board_pdev_unregister, + board); +} + +static int catpt_probe_components(struct catpt_dev *cdev) +{ + int ret; + + ret = cdev->spec->power_up(cdev); + if (ret) + return ret; + + ret = catpt_dmac_probe(cdev); + if (ret) { + dev_err(cdev->dev, "DMAC probe failed: %d\n", ret); + goto err_dmac_probe; + } + + ret = catpt_first_boot_firmware(cdev); + if (ret) { + dev_err(cdev->dev, "first fw boot failed: %d\n", ret); + goto err_boot_fw; + } + + ret = catpt_register_plat_component(cdev); + if (ret) { + dev_err(cdev->dev, "register plat comp failed: %d\n", ret); + goto err_boot_fw; + } + + ret = catpt_register_board(cdev); + if (ret) { + dev_err(cdev->dev, "register board failed: %d\n", ret); + goto err_reg_board; + } + + /* reflect actual ADSP state in pm_runtime */ + pm_runtime_set_active(cdev->dev); + + pm_runtime_set_autosuspend_delay(cdev->dev, 2000); + pm_runtime_use_autosuspend(cdev->dev); + pm_runtime_mark_last_busy(cdev->dev); + pm_runtime_enable(cdev->dev); + return 0; + +err_reg_board: + snd_soc_unregister_component(cdev->dev); +err_boot_fw: + catpt_dmac_remove(cdev); +err_dmac_probe: + cdev->spec->power_down(cdev); + + return ret; +} + +static void catpt_dev_init(struct catpt_dev *cdev, struct device *dev, + const struct catpt_spec *spec) +{ + cdev->dev = dev; + cdev->spec = spec; + init_completion(&cdev->fw_ready); + INIT_LIST_HEAD(&cdev->stream_list); + spin_lock_init(&cdev->list_lock); + mutex_init(&cdev->clk_mutex); + + /* + * Mark both device formats as uninitialized. Once corresponding + * cpu_dai's pcm is created, proper values are assigned. + */ + cdev->devfmt[CATPT_SSP_IFACE_0].iface = UINT_MAX; + cdev->devfmt[CATPT_SSP_IFACE_1].iface = UINT_MAX; + + catpt_ipc_init(&cdev->ipc, dev); + + catpt_sram_init(&cdev->dram, spec->host_dram_offset, + catpt_dram_size(cdev)); + catpt_sram_init(&cdev->iram, spec->host_iram_offset, + catpt_iram_size(cdev)); +} + +static int catpt_acpi_probe(struct platform_device *pdev) +{ + const struct catpt_spec *spec; + struct catpt_dev *cdev; + struct device *dev = &pdev->dev; + struct resource *res; + int ret; + + spec = device_get_match_data(dev); + if (!spec) + return -ENODEV; + + cdev = devm_kzalloc(dev, sizeof(*cdev), GFP_KERNEL); + if (!cdev) + return -ENOMEM; + + catpt_dev_init(cdev, dev, spec); + + /* map DSP bar address */ + cdev->lpe_ba = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(cdev->lpe_ba)) + return PTR_ERR(cdev->lpe_ba); + cdev->lpe_base = res->start; + + /* map PCI bar address */ + cdev->pci_ba = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(cdev->pci_ba)) + return PTR_ERR(cdev->pci_ba); + + /* alloc buffer for storing DRAM context during dx transitions */ + cdev->dxbuf_vaddr = dmam_alloc_coherent(dev, catpt_dram_size(cdev), + &cdev->dxbuf_paddr, GFP_KERNEL); + if (!cdev->dxbuf_vaddr) + return -ENOMEM; + + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + cdev->irq = ret; + + platform_set_drvdata(pdev, cdev); + + ret = devm_request_threaded_irq(dev, cdev->irq, catpt_dsp_irq_handler, + catpt_dsp_irq_thread, + IRQF_SHARED, "AudioDSP", cdev); + if (ret) + return ret; + + return catpt_probe_components(cdev); +} + +static int catpt_acpi_remove(struct platform_device *pdev) +{ + struct catpt_dev *cdev = platform_get_drvdata(pdev); + + pm_runtime_disable(cdev->dev); + + snd_soc_unregister_component(cdev->dev); + catpt_dmac_remove(cdev); + cdev->spec->power_down(cdev); + + catpt_sram_free(&cdev->iram); + catpt_sram_free(&cdev->dram); + + return 0; +} + +static struct catpt_spec lpt_desc = { + .machines = snd_soc_acpi_intel_haswell_machines, + .core_id = 0x01, + .host_dram_offset = 0x000000, + .host_iram_offset = 0x080000, + .host_shim_offset = 0x0E7000, + .host_dma_offset = { 0x0F0000, 0x0F8000 }, + .host_ssp_offset = { 0x0E8000, 0x0E9000 }, + .dram_mask = LPT_VDRTCTL0_DSRAMPGE_MASK, + .iram_mask = LPT_VDRTCTL0_ISRAMPGE_MASK, + .pll_shutdown = lpt_dsp_pll_shutdown, + .power_up = lpt_dsp_power_up, + .power_down = lpt_dsp_power_down, +}; + +static struct catpt_spec wpt_desc = { + .machines = snd_soc_acpi_intel_broadwell_machines, + .core_id = 0x02, + .host_dram_offset = 0x000000, + .host_iram_offset = 0x0A0000, + .host_shim_offset = 0x0FB000, + .host_dma_offset = { 0x0FE000, 0x0FF000 }, + .host_ssp_offset = { 0x0FC000, 0x0FD000 }, + .dram_mask = WPT_VDRTCTL0_DSRAMPGE_MASK, + .iram_mask = WPT_VDRTCTL0_ISRAMPGE_MASK, + .pll_shutdown = wpt_dsp_pll_shutdown, + .power_up = wpt_dsp_power_up, + .power_down = wpt_dsp_power_down, +}; + +static const struct acpi_device_id catpt_ids[] = { + { "INT33C8", (unsigned long)&lpt_desc }, + { "INT3438", (unsigned long)&wpt_desc }, + { } +}; +MODULE_DEVICE_TABLE(acpi, catpt_ids); + +static struct platform_driver catpt_acpi_driver = { + .probe = catpt_acpi_probe, + .remove = catpt_acpi_remove, + .driver = { + .name = "intel_catpt", + .acpi_match_table = catpt_ids, + .pm = &catpt_dev_pm, + }, +}; +module_platform_driver(catpt_acpi_driver); + +MODULE_AUTHOR("Cezary Rojewski "); +MODULE_DESCRIPTION("Intel LPT/WPT AudioDSP driver"); +MODULE_LICENSE("GPL v2"); From patchwork Wed Sep 23 12:25:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 291588 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 68D6DC4727E for ; Wed, 23 Sep 2020 12:32:17 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id AA138206F7 for ; Wed, 23 Sep 2020 12:32:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="SoC6dztZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AA138206F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 1DBAD16E9; Wed, 23 Sep 2020 14:31:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 1DBAD16E9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864335; bh=nfrGfsvGAeNP25D2Ih3AQLUrDRWqaxpw+Q6TTJmULGI=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=SoC6dztZo8sZTuhv4He1R4yqkKwYuUcpwHp1uxJoKAOpgyqU5MvqtcYmndOvvyucE nZCiuIdToF8aCYNQ9sqQ0GP9rybHu170gCZ5AL4qS3hevDuIZoBaRdQ3jQJOJGiFGj FZzwy7DEEgnas8Eptxk/vLdSd8wXhHtVO+ugQOUc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 300AAF80339; Wed, 23 Sep 2020 14:26:36 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8B0EFF8033D; Wed, 23 Sep 2020 14:26:35 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 CDC5EF80316 for ; Wed, 23 Sep 2020 14:26:27 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CDC5EF80316 IronPort-SDR: nMwSlfXvo3sZAnz8zy7QNdnC1dyaCcMuuoSi5bvyWYSqbFCWsM1W9UcQfMkxhhVU7Y2abWRkbo 2nJ5O+0extsw== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948244" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948244" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:27 -0700 IronPort-SDR: qmMqVr9ybo9qCveHxfgFtFgyo1gEyj5urkK6holNGwnycrB5Rqq02Z1Pd2/yUaV63wBI3Zfh3J EyvNprY+LQ8Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338243" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:23 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 08/14] ASoC: Intel: catpt: Event tracing Date: Wed, 23 Sep 2020 14:25:02 +0200 Message-Id: <20200923122508.3360-9-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Define tracing macros for easy catpt debug. These cover all IPC message types: requests, replies and notifications. Signed-off-by: Cezary Rojewski --- Changes in v6: - trace usage now part of this patch instead of being separated from it Changes in v2: - trace.h events for updating registers have been removed and usages replaced by dev_dbg (SRAMPGE/ LPCS) - trace.h events for catpt_mbank and catpt_mregion have been removed sound/soc/intel/catpt/device.c | 3 ++ sound/soc/intel/catpt/ipc.c | 11 +++++ sound/soc/intel/catpt/trace.h | 83 ++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 sound/soc/intel/catpt/trace.h diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c index e7dc2fb69ea8..c02d46e5bc81 100644 --- a/sound/soc/intel/catpt/device.c +++ b/sound/soc/intel/catpt/device.c @@ -25,6 +25,9 @@ #include "core.h" #include "registers.h" +#define CREATE_TRACE_POINTS +#include "trace.h" + static int __maybe_unused catpt_suspend(struct device *dev) { struct catpt_dev *cdev = dev_get_drvdata(dev); diff --git a/sound/soc/intel/catpt/ipc.c b/sound/soc/intel/catpt/ipc.c index e4569be02bbc..925a193a9932 100644 --- a/sound/soc/intel/catpt/ipc.c +++ b/sound/soc/intel/catpt/ipc.c @@ -9,6 +9,7 @@ #include "core.h" #include "messages.h" #include "registers.h" +#include "trace.h" #define CATPT_IPC_TIMEOUT_MS 300 @@ -56,6 +57,9 @@ static void catpt_dsp_send_tx(struct catpt_dev *cdev, { u32 header = tx->header | CATPT_IPCC_BUSY; + trace_catpt_ipc_request(header); + trace_catpt_ipc_payload(tx->data, tx->size); + if (tx->size) memcpy_toio(catpt_outbox_addr(cdev), tx->data, tx->size); catpt_writel_shim(cdev, IPCC, header); @@ -155,12 +159,14 @@ catpt_dsp_notify_stream(struct catpt_dev *cdev, union catpt_notify_msg msg) switch (msg.notify_reason) { case CATPT_NOTIFY_POSITION_CHANGED: memcpy_fromio(&pos, catpt_inbox_addr(cdev), sizeof(pos)); + trace_catpt_ipc_payload((u8 *)&pos, sizeof(pos)); catpt_stream_update_position(cdev, stream, &pos); break; case CATPT_NOTIFY_GLITCH_OCCURRED: memcpy_fromio(&glitch, catpt_inbox_addr(cdev), sizeof(glitch)); + trace_catpt_ipc_payload((u8 *)&glitch, sizeof(glitch)); dev_warn(cdev->dev, "glitch %d at pos: 0x%08llx, wp: 0x%08x\n", glitch.type, glitch.presentation_pos, @@ -182,6 +188,7 @@ static void catpt_dsp_copy_rx(struct catpt_dev *cdev, u32 header) if (ipc->rx.size && ipc->rx.rsp.status == CATPT_REPLY_SUCCESS) { memcpy_fromio(ipc->rx.data, catpt_outbox_addr(cdev), ipc->rx.size); + trace_catpt_ipc_payload(ipc->rx.data, ipc->rx.size); } } @@ -196,6 +203,7 @@ static void catpt_dsp_process_response(struct catpt_dev *cdev, u32 header) u32 off = msg.mailbox_address << 3; memcpy_fromio(&config, cdev->lpe_ba + off, sizeof(config)); + trace_catpt_ipc_payload((u8 *)&config, sizeof(config)); catpt_ipc_arm(ipc, &config); complete(&cdev->fw_ready); @@ -236,6 +244,7 @@ irqreturn_t catpt_dsp_irq_thread(int irq, void *dev_id) u32 ipcd; ipcd = catpt_readl_shim(cdev, IPCD); + trace_catpt_ipc_notify(ipcd); /* ensure there is delayed reply or notification to process */ if (!(ipcd & CATPT_IPCD_BUSY)) @@ -259,6 +268,7 @@ irqreturn_t catpt_dsp_irq_handler(int irq, void *dev_id) u32 isc, ipcc; isc = catpt_readl_shim(cdev, ISC); + trace_catpt_irq(isc); /* immediate reply */ if (isc & CATPT_ISC_IPCCD) { @@ -266,6 +276,7 @@ irqreturn_t catpt_dsp_irq_handler(int irq, void *dev_id) catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCCD, CATPT_IMC_IPCCD); ipcc = catpt_readl_shim(cdev, IPCC); + trace_catpt_ipc_reply(ipcc); catpt_dsp_copy_rx(cdev, ipcc); complete(&cdev->ipc.done_completion); diff --git a/sound/soc/intel/catpt/trace.h b/sound/soc/intel/catpt/trace.h new file mode 100644 index 000000000000..bb3d627dbeaf --- /dev/null +++ b/sound/soc/intel/catpt/trace.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Cezary Rojewski + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM intel_catpt + +#if !defined(__SND_SOC_INTEL_CATPT_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __SND_SOC_INTEL_CATPT_TRACE_H + +#include +#include + +DECLARE_EVENT_CLASS(catpt_ipc_msg, + + TP_PROTO(u32 header), + + TP_ARGS(header), + + TP_STRUCT__entry( + __field(u32, header) + ), + + TP_fast_assign( + __entry->header = header; + ), + + TP_printk("0x%08x", __entry->header) +); + +DEFINE_EVENT(catpt_ipc_msg, catpt_irq, + TP_PROTO(u32 header), + TP_ARGS(header) +); + +DEFINE_EVENT(catpt_ipc_msg, catpt_ipc_request, + TP_PROTO(u32 header), + TP_ARGS(header) +); + +DEFINE_EVENT(catpt_ipc_msg, catpt_ipc_reply, + TP_PROTO(u32 header), + TP_ARGS(header) +); + +DEFINE_EVENT(catpt_ipc_msg, catpt_ipc_notify, + TP_PROTO(u32 header), + TP_ARGS(header) +); + +TRACE_EVENT_CONDITION(catpt_ipc_payload, + + TP_PROTO(const u8 *data, size_t size), + + TP_ARGS(data, size), + + TP_CONDITION(data && size), + + TP_STRUCT__entry( + __dynamic_array(u8, buf, size) + ), + + TP_fast_assign( + memcpy(__get_dynamic_array(buf), data, size); + ), + + TP_printk("%u byte(s)%s", + __get_dynamic_array_len(buf), + __print_hex_dump("", DUMP_PREFIX_NONE, 16, 4, + __get_dynamic_array(buf), + __get_dynamic_array_len(buf), false)) +); + +#endif /* __SND_SOC_INTEL_CATPT_TRACE_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace +#include From patchwork Wed Sep 23 12:25:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 250906 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7F96EC2D0A8 for ; Wed, 23 Sep 2020 12:32:54 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C03BB206F7 for ; Wed, 23 Sep 2020 12:32:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="tDXcVk1b" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C03BB206F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 3F4FF16C0; Wed, 23 Sep 2020 14:32:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 3F4FF16C0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864372; bh=DRas24z59DjblDBLS3ZJ82b4enyzadn5VUGQSf2VY4w=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=tDXcVk1bb8tECX5BSpvjgQItTueF92thqcuKHAP8jFDbydjlvI3I+xMGk0Bx4bmhk VEFxso1ikGRckyrqVwBB1Pk0gMuyVZICprtZkyTRZtjo7YMBtPqge79ryc1sQ/TsVK fgKz4sgxybv9gpo9qmVGy8XD5y85zaWvoi2P+mds= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 3FA61F80340; Wed, 23 Sep 2020 14:26:39 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 15B01F80341; Wed, 23 Sep 2020 14:26:38 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 CB47DF80337 for ; Wed, 23 Sep 2020 14:26:31 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CB47DF80337 IronPort-SDR: 2ptEtEqCKOYkSXvG4D3VMIBtVxx/gx1wTrKjxtHjG4zO1bl8TNqx9LkCBz/+cxiYbBVD9z4xIr hEaLZ92wfAAw== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948249" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948249" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:31 -0700 IronPort-SDR: 6/DoZbGZnGGor5dqxFtZPvuY+Odo/AbA/jh5oxhiW6IZ5HE5VtKXh80DKreUMa2wWRO8dqywDh KNCc0mJhDKmg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338264" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:27 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 09/14] ASoC: Intel: catpt: Simple sysfs attributes Date: Wed, 23 Sep 2020 14:25:03 +0200 Message-Id: <20200923122508.3360-10-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Add sysfs entries for displaying version of FW currently in use as well as dumping full FW information including build and log-providers hashes. Signed-off-by: Cezary Rojewski --- Changes in v7: - fixed licence header for fs.c - renamed fs.c to sysfs.c to better match its purpose - added documentation within Documentation/ABI/testing for entries exposed by catpt - bin_attribute fw_build replaced by attribute fw_info: fw_info contains full FW information and after successful handshake, it's always available (stored in driver data) so no need to invoke GET_FW_VERSION IPC again, just dump the stored information - rather than manually creating and removing sysfs files, now makes use of dev_groups member of struct device_driver Changes in v6: - functions declaration and usage now part of this patch instead of being separated from it Changes in v2: - fixed size provided to memcpy() in fw_build_read() as reported by Mark .../ABI/testing/sysfs-bus-pci-devices-catpt | 16 ++++++ sound/soc/intel/catpt/core.h | 1 + sound/soc/intel/catpt/device.c | 1 + sound/soc/intel/catpt/sysfs.c | 57 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-devices-catpt create mode 100644 sound/soc/intel/catpt/sysfs.c diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-catpt b/Documentation/ABI/testing/sysfs-bus-pci-devices-catpt new file mode 100644 index 000000000000..8a200f4eefbd --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-catpt @@ -0,0 +1,16 @@ +What: /sys/devices/pci0000:00//fw_version +Date: September 2020 +Contact: Cezary Rojewski +Description: + Version of AudioDSP firmware ASoC catpt driver is + communicating with. + Format: %d.%d.%d.%d, type:major:minor:build. + +What: /sys/devices/pci0000:00//fw_info +Date: September 2020 +Contact: Cezary Rojewski +Description: + Detailed AudioDSP firmware build information including + build hash and log-providers hash. This information is + obtained during initial handshake with firmware. + Format: %s. diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h index a29b4c0232cb..19eda125ee59 100644 --- a/sound/soc/intel/catpt/core.h +++ b/sound/soc/intel/catpt/core.h @@ -14,6 +14,7 @@ #include "registers.h" struct catpt_dev; +extern const struct attribute_group *catpt_attr_groups[]; void catpt_sram_init(struct resource *sram, u32 start, u32 size); void catpt_sram_free(struct resource *sram); diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c index c02d46e5bc81..2d53efa656b1 100644 --- a/sound/soc/intel/catpt/device.c +++ b/sound/soc/intel/catpt/device.c @@ -338,6 +338,7 @@ static struct platform_driver catpt_acpi_driver = { .name = "intel_catpt", .acpi_match_table = catpt_ids, .pm = &catpt_dev_pm, + .dev_groups = catpt_attr_groups, }, }; module_platform_driver(catpt_acpi_driver); diff --git a/sound/soc/intel/catpt/sysfs.c b/sound/soc/intel/catpt/sysfs.c new file mode 100644 index 000000000000..f38562071a04 --- /dev/null +++ b/sound/soc/intel/catpt/sysfs.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include "core.h" + +static ssize_t fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct catpt_dev *cdev = dev_get_drvdata(dev); + struct catpt_fw_version version; + int ret; + + pm_runtime_get_sync(cdev->dev); + + ret = catpt_ipc_get_fw_version(cdev, &version); + + pm_runtime_mark_last_busy(cdev->dev); + pm_runtime_put_autosuspend(cdev->dev); + + if (ret) + return CATPT_IPC_ERROR(ret); + + return sprintf(buf, "%d.%d.%d.%d\n", version.type, version.major, + version.minor, version.build); +} + +static DEVICE_ATTR_RO(fw_version); + +static ssize_t fw_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct catpt_dev *cdev = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", cdev->ipc.config.fw_info); +} + +static DEVICE_ATTR_RO(fw_info); + +static struct attribute *catpt_attrs[] = { + &dev_attr_fw_version.attr, + &dev_attr_fw_info.attr, + NULL +}; + +static const struct attribute_group catpt_attr_group = { + .attrs = catpt_attrs, +}; + +const struct attribute_group *catpt_attr_groups[] = { + &catpt_attr_group, + NULL +}; From patchwork Wed Sep 23 12:25:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 291587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25894C2D0A8 for ; Wed, 23 Sep 2020 12:33:34 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 22DCE206F7 for ; Wed, 23 Sep 2020 12:33:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="sZ9XwhFt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 22DCE206F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 8E4A816FB; Wed, 23 Sep 2020 14:32:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8E4A816FB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864411; bh=WaO5P2stU2cnjh7a4E/IbyN5yPKCR8s80+czcxNVdcA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=sZ9XwhFtEgEubOonQRcow3mZr1N8mmHyHHjPDuoHvkNSiu+7+N0+4JDwTfTQqS0uL VFvDpbDEeEhp45HWwOcHIh2Afy5svttjJPnt1YqbH4VSBkgz+RA0yjPp7Y8zJPPqQ+ yoJvlz7JrLdE41o25/tQ5PxXIDWDByvab6AvRNc4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 1ED2FF80345; Wed, 23 Sep 2020 14:26:44 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 089F2F80345; Wed, 23 Sep 2020 14:26:42 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 4E24BF8033E for ; Wed, 23 Sep 2020 14:26:35 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 4E24BF8033E IronPort-SDR: Wxf56/A4mlLDQLAk6zV4iXP/bzEtSD+ywpHXx7MMn+TPzB7zhc+T+74nBDHtjjnWI67RPxcL7/ DmvJbwLJoyRA== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948256" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948256" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:34 -0700 IronPort-SDR: 0yNcMSL+Y4ehQDgm31dGjeSd7awnbg+BU4HbcPI6TdoNg0TonSs2v/xCDcaYWGF/EDtjQOZtxH HWzBLKfiIa7g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338278" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:31 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 10/14] ASoC: Intel: haswell: Remove haswell-solution specific code Date: Wed, 23 Sep 2020 14:25:04 +0200 Message-Id: <20200923122508.3360-11-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Remove code specific to sound/soc/intel/haswell. Update BE dai_link definition to provide seamless transition to catpt solution. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko --- No changes since initial version. sound/soc/intel/boards/haswell.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c index 744b7b5b8106..c268405e5594 100644 --- a/sound/soc/intel/boards/haswell.c +++ b/sound/soc/intel/boards/haswell.c @@ -13,9 +13,6 @@ #include #include -#include "../common/sst-dsp.h" -#include "../haswell/sst-haswell-ipc.h" - #include "../../codecs/rt5640.h" /* Haswell ULT platforms have a Headphone and Mic jack */ @@ -77,25 +74,6 @@ static const struct snd_soc_ops haswell_rt5640_ops = { .hw_params = haswell_rt5640_hw_params, }; -static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); - struct sst_pdata *pdata = dev_get_platdata(component->dev); - struct sst_hsw *haswell = pdata->dsp; - int ret; - - /* Set ADSP SSP port settings */ - ret = sst_hsw_device_set_config(haswell, SST_HSW_DEVICE_SSP_0, - SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, - SST_HSW_DEVICE_CLOCK_MASTER, 9); - if (ret < 0) { - dev_err(rtd->dev, "failed to set device config\n"); - return ret; - } - - return 0; -} - SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); @@ -117,13 +95,15 @@ SND_SOC_DAILINK_DEF(codec, SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio"))); +SND_SOC_DAILINK_DEF(ssp0_port, + DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); + static struct snd_soc_dai_link haswell_rt5640_dais[] = { /* Front End DAI links */ { .name = "System", .stream_name = "System Playback/Capture", .dynamic = 1, - .init = haswell_rtd_init, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dpcm_playback = 1, .dpcm_capture = 1, @@ -167,7 +147,7 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = { .ops = &haswell_rt5640_ops, .dpcm_playback = 1, .dpcm_capture = 1, - SND_SOC_DAILINK_REG(dummy, codec, dummy), + SND_SOC_DAILINK_REG(ssp0_port, codec, platform), }, }; From patchwork Wed Sep 23 12:25:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 250905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1121C2D0A8 for ; Wed, 23 Sep 2020 12:34:06 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 1A1CB221E7 for ; Wed, 23 Sep 2020 12:34:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="tPQ0wq/E" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1A1CB221E7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 7556616C0; Wed, 23 Sep 2020 14:33:14 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 7556616C0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864444; bh=PecAKC6b4ISZuISCpI47SXILjMSAchREsntYK/RpfT4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=tPQ0wq/EkptHwxwcWkj3elj5e6LTr2+Tqj3gttBxy6st8QvPcJd30nMi2W7stKYZQ eahmOVg3SYE/czmbWGSKSSLVmmLMTGiaojdbTcnwScr6tm8ojjAeC7QqvTAvDAfW9M +/2HAzwEk0D3tlft3KO5XpuoUQqFHlbK/+40VFeU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id F3B85F8034D; Wed, 23 Sep 2020 14:26:46 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4D851F80348; Wed, 23 Sep 2020 14:26:45 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 02BB4F80343 for ; Wed, 23 Sep 2020 14:26:38 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 02BB4F80343 IronPort-SDR: Xl8Zc+tAnWz4Y6Ke0GCkdPN0YhIM1FBMx3FOlSvLz5gzDslEFjZtKvTLWEU5zwm+9QTJ6PSZgJ SrUv4G/sjxaw== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948261" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948261" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:38 -0700 IronPort-SDR: EumCLp3djF5STm+L83EtCxMBZGTXa8lcqOmqjPvixB5hlQs0pO9smrPxLW4d+gBK1BBg46d9nq N7kqG+9lbyaQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338296" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:35 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 11/14] ASoC: Intel: broadwell: Remove haswell-solution specific code Date: Wed, 23 Sep 2020 14:25:05 +0200 Message-Id: <20200923122508.3360-12-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Remove code specific to sound/soc/intel/haswell. Update BE dai_link definition to provide seamless transition to catpt solution. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko --- No changes since initial version. sound/soc/intel/boards/broadwell.c | 33 ------------------------------ 1 file changed, 33 deletions(-) diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c index 56972af13b6f..648b47190051 100644 --- a/sound/soc/intel/boards/broadwell.c +++ b/sound/soc/intel/boards/broadwell.c @@ -14,9 +14,6 @@ #include #include -#include "../common/sst-dsp.h" -#include "../haswell/sst-haswell-ipc.h" - #include "../../codecs/rt286.h" static struct snd_soc_jack broadwell_headset; @@ -122,27 +119,6 @@ static const struct snd_soc_ops broadwell_rt286_ops = { .hw_params = broadwell_rt286_hw_params, }; -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) -static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); - struct sst_pdata *pdata = dev_get_platdata(component->dev); - struct sst_hsw *broadwell = pdata->dsp; - int ret; - - /* Set ADSP SSP port settings */ - ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0, - SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, - SST_HSW_DEVICE_CLOCK_MASTER, 9); - if (ret < 0) { - dev_err(rtd->dev, "error: failed to set device config\n"); - return ret; - } - - return 0; -} -#endif - static const unsigned int channels[] = { 2, }; @@ -189,10 +165,8 @@ SND_SOC_DAILINK_DEF(platform, SND_SOC_DAILINK_DEF(codec, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1"))); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); -#endif /* broadwell digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link broadwell_rt286_dais[] = { @@ -201,9 +175,6 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { .name = "System PCM", .stream_name = "System Playback/Capture", .dynamic = 1, -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) - .init = broadwell_rtd_init, -#endif .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .ops = &broadwell_fe_ops, .dpcm_playback = 1, @@ -248,11 +219,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { .ops = &broadwell_rt286_ops, .dpcm_playback = 1, .dpcm_capture = 1, -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) - SND_SOC_DAILINK_REG(dummy, codec, dummy), -#else SND_SOC_DAILINK_REG(ssp0_port, codec, platform), -#endif }, }; From patchwork Wed Sep 23 12:25:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 291586 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0967EC2D0A8 for ; Wed, 23 Sep 2020 12:34:38 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3E261206F7 for ; Wed, 23 Sep 2020 12:34:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="NGRg2qFD" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3E261206F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 AD644170A; Wed, 23 Sep 2020 14:33:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AD644170A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864475; bh=dUteBxx+9AlSMIpxgevWBJwj7PpPeg6k7TvZl94d8dw=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=NGRg2qFD+aW96d8ObpWhzC239qEMzHwxOlSxWmW07gWO4U6eZdFXJyLccx9h1APNH jpN3GbFze1JqFmhaelGSwIrcgbNNev2n0H679/nqCc6U1FN86R5KE06Ahok3UmFa4u lEOEgKkQJPWO9oeAQzB4ioJ2H/65lMQYnxQ9Uq/o= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 2BE48F80351; Wed, 23 Sep 2020 14:26:48 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id A4346F80347; Wed, 23 Sep 2020 14:26:45 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 AB2B2F8033E for ; Wed, 23 Sep 2020 14:26:42 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz AB2B2F8033E IronPort-SDR: XlxFM8WHqQWJC3n5e8Asr3NfCC/UrQd+Qu3RkDRoOveKDN53NDtVMYHYm9TzD7Le/3ny/wGpy5 cKJuIsVhm8kg== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948274" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948274" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:42 -0700 IronPort-SDR: pCbLdx6E5YaBfRLTKLcrNEoJSdLLNss0Tq0oTxwz1Yr9ELEpqF64wMsavnXwm3/EwrWpivFixp rqwsKW5Ax8nQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338306" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:38 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 12/14] ASoC: Intel: bdw-5650: Remove haswell-solution specific code Date: Wed, 23 Sep 2020 14:25:06 +0200 Message-Id: <20200923122508.3360-13-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Remove code specific to sound/soc/intel/haswell. Update BE dai_link definition to provide seamless transition to catpt solution. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko --- No changes since initial version. sound/soc/intel/boards/bdw-rt5650.c | 36 ----------------------------- 1 file changed, 36 deletions(-) diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c index 1412a9941ed4..c44315af6a4c 100644 --- a/sound/soc/intel/boards/bdw-rt5650.c +++ b/sound/soc/intel/boards/bdw-rt5650.c @@ -16,9 +16,6 @@ #include #include -#include "../common/sst-dsp.h" -#include "../haswell/sst-haswell-ipc.h" - #include "../../codecs/rt5645.h" struct bdw_rt5650_priv { @@ -138,30 +135,6 @@ static struct snd_soc_ops bdw_rt5650_ops = { .hw_params = bdw_rt5650_hw_params, }; -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) -static int bdw_rt5650_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = - snd_soc_rtdcom_lookup(rtd, DRV_NAME); - struct sst_pdata *pdata = dev_get_platdata(component->dev); - struct sst_hsw *broadwell = pdata->dsp; - int ret; - - /* Set ADSP SSP port settings - * clock_divider = 4 means BCLK = MCLK/5 = 24MHz/5 = 4.8MHz - */ - ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0, - SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, - SST_HSW_DEVICE_TDM_CLOCK_MASTER, 4); - if (ret < 0) { - dev_err(rtd->dev, "error: failed to set device config\n"); - return ret; - } - - return 0; -} -#endif - static const unsigned int channels[] = { 2, 4, }; @@ -251,10 +224,8 @@ SND_SOC_DAILINK_DEF(platform, SND_SOC_DAILINK_DEF(be, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5650:00", "rt5645-aif1"))); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); -#endif static struct snd_soc_dai_link bdw_rt5650_dais[] = { /* Front End DAI links */ @@ -263,9 +234,6 @@ static struct snd_soc_dai_link bdw_rt5650_dais[] = { .stream_name = "System Playback", .dynamic = 1, .ops = &bdw_rt5650_fe_ops, -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) - .init = bdw_rt5650_rtd_init, -#endif .trigger = { SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST @@ -289,11 +257,7 @@ static struct snd_soc_dai_link bdw_rt5650_dais[] = { .dpcm_playback = 1, .dpcm_capture = 1, .init = bdw_rt5650_init, -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) - SND_SOC_DAILINK_REG(dummy, be, dummy), -#else SND_SOC_DAILINK_REG(ssp0_port, be, platform), -#endif }, }; From patchwork Wed Sep 23 12:25:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 250904 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 391B1C2D0A8 for ; Wed, 23 Sep 2020 12:35:17 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 860EE206F7 for ; Wed, 23 Sep 2020 12:35:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="dpx2ScGc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 860EE206F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 0F929170E; Wed, 23 Sep 2020 14:34:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 0F929170E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864515; bh=xE+miAfmKbvksPbmBi/TwTAbZ6QNKrzhP8Yd66aQhGQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=dpx2ScGctN9w7uxhoGKmAbBux8CpmSZ+/do6zU4Fv9pVxYJrE7X1oxb6rBlNa/AuM WzsxUVF/D4FfwyN+Kdclh079pymhS7W0Q1UxAt59ayZwklq7cmzZa8TgZkx0jnAP+3 BGH2uD/UU9JVsyd986b/WndBL/e8LFxyqiWqeUVA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B846DF80362; Wed, 23 Sep 2020 14:26:56 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2BDDEF80362; Wed, 23 Sep 2020 14:26:53 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 49192F8034F for ; Wed, 23 Sep 2020 14:26:46 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 49192F8034F IronPort-SDR: c4M7eXc9zzEEy/h6lkZvptThjjCWJZ8ks+cUWHI49CATyAQQhKnXFosLRPjAISW1jo2U86eV3K ZnTvh4au87vA== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948281" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948281" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:45 -0700 IronPort-SDR: X53GH6lTm6juYvhJyQMeVT1WCvk2NgOCNugQBMBsctT8GbMKvC3xchCJVbdRzK12ahZguhiklF yzCaVc9ktw2Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338316" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:42 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 13/14] ASoC: Intel: bdw-5677: Remove haswell-solution specific code Date: Wed, 23 Sep 2020 14:25:07 +0200 Message-Id: <20200923122508.3360-14-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Remove code specific to sound/soc/intel/haswell. Update BE dai_link definition to provide seamless transition to catpt solution. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko --- No changes since initial version. sound/soc/intel/boards/bdw-rt5677.c | 33 ----------------------------- 1 file changed, 33 deletions(-) diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index 297871bcaf5d..d6584768883b 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -17,9 +17,6 @@ #include #include -#include "../common/sst-dsp.h" -#include "../haswell/sst-haswell-ipc.h" - #include "../../codecs/rt5677.h" struct bdw_rt5677_priv { @@ -201,27 +198,6 @@ static const struct snd_soc_ops bdw_rt5677_dsp_ops = { .hw_params = bdw_rt5677_dsp_hw_params, }; -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) -static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); - struct sst_pdata *pdata = dev_get_platdata(component->dev); - struct sst_hsw *broadwell = pdata->dsp; - int ret; - - /* Set ADSP SSP port settings */ - ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0, - SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, - SST_HSW_DEVICE_CLOCK_MASTER, 9); - if (ret < 0) { - dev_err(rtd->dev, "error: failed to set device config\n"); - return ret; - } - - return 0; -} -#endif - static const unsigned int channels[] = { 2, }; @@ -333,10 +309,8 @@ SND_SOC_DAILINK_DEF(platform, SND_SOC_DAILINK_DEF(be, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-aif1"))); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); -#endif /* Wake on voice interface */ SND_SOC_DAILINK_DEFS(dsp, @@ -350,9 +324,6 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { .name = "System PCM", .stream_name = "System Playback/Capture", .dynamic = 1, -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) - .init = bdw_rt5677_rtd_init, -#endif .trigger = { SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST @@ -387,11 +358,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { .dpcm_capture = 1, .init = bdw_rt5677_init, .exit = bdw_rt5677_exit, -#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) - SND_SOC_DAILINK_REG(dummy, be, dummy), -#else SND_SOC_DAILINK_REG(ssp0_port, be, platform), -#endif }, }; From patchwork Wed Sep 23 12:25:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 291585 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4952AC2D0A8 for ; Wed, 23 Sep 2020 12:35:44 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 6E1E32137B for ; Wed, 23 Sep 2020 12:35:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="gGxPGNC9" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6E1E32137B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 D1516170C; Wed, 23 Sep 2020 14:34:51 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D1516170C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1600864541; bh=AA9eZtvjtvLyMhjI5WztkXpysF+nOXqQoEmmQCVIbF4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=gGxPGNC9GQ1fz0beTwVP4KLBZGu1Ae5/e21TrmcA7wxKUpuaRwjBl+2wTLFXlWaPZ MTdp0UrRt+rtSM2Ca6Xv7r7cngPxWNvx5PXxQthP0+S26jEIQrZb4GmEvMnL2D5W9F t2yZxPhvtjAK8V33MS8gv4M6b2S3LPKh+/PHdnDc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id BF42BF80367; Wed, 23 Sep 2020 14:26:58 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id F1C5AF80368; Wed, 23 Sep 2020 14:26:56 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (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 698B8F80360 for ; Wed, 23 Sep 2020 14:26:50 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 698B8F80360 IronPort-SDR: ZXoXYVyhsg0iGD8oecGk2SktRTounLSDY70gboCS7MmA3Fc7OoCpXPX4kL7ZUfIdDP9d/79jHR 1FnIQRLNeyKw== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="160948289" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="160948289" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 05:26:49 -0700 IronPort-SDR: nZNDt7mGiSipdQo8zwNfWihGENbI2yIoTndMXff5jkx/6VUfYuqWL+9jB3mo4C83K6uOW+YJxP XtwRrN3D7Z7Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="347338330" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by FMSMGA003.fm.intel.com with ESMTP; 23 Sep 2020 05:26:45 -0700 From: Cezary Rojewski To: alsa-devel@alsa-project.org Subject: [PATCH v8 14/14] ASoC: Intel: Select catpt and deprecate haswell Date: Wed, 23 Sep 2020 14:25:08 +0200 Message-Id: <20200923122508.3360-15-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923122508.3360-1-cezary.rojewski@intel.com> References: <20200923122508.3360-1-cezary.rojewski@intel.com> Cc: pierre-louis.bossart@linux.intel.com, Cezary Rojewski , andriy.shevchenko@linux.intel.com, filip.kaczmarski@intel.com, harshapriya.n@intel.com, gregkh@linuxfoundation.org, marcin.barlik@intel.com, zwisler@google.com, lgirdwood@gmail.com, tiwai@suse.com, filip.proborszcz@intel.com, broonie@kernel.org, amadeuszx.slawinski@linux.intel.com, michal.wasko@intel.com, cujomalainey@chromium.org, krzysztof.hejmowski@intel.com, ppapierkowski@habana.ai, vamshi.krishna.gopal@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Prevent sound/soc/intel/haswell code compile and select catpt instead as a recommended solution. Userspace-exposed members are compatible with what is exposed by deprecated solution thus no harm is done. The only visible difference is the newly added 'Loopback Mute' kcontrol. Signed-off-by: Cezary Rojewski --- Changes in v7: - patch: 10/14 'ASoC: Intel: Select catpt and deprecate haswell' has been moved to the back of the list: enable catpt after machine boards have been prepared for it first Changes in v5: - remove DMADEVICES depends on: DW_DMAC_CORE already covers that - add optional COMPILE_TEST depends on sound/soc/intel/Kconfig | 24 ++++++++++++------------ sound/soc/intel/Makefile | 2 +- sound/soc/intel/boards/Kconfig | 8 ++++---- sound/soc/intel/catpt/Makefile | 6 ++++++ 4 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 sound/soc/intel/catpt/Makefile diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 0e48c4f532ce..dfc20f2bb859 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -47,21 +47,21 @@ config SND_SOC_INTEL_SST_FIRMWARE # Haswell/Broadwell/Baytrail legacy and will be set # when these platforms are enabled -config SND_SOC_INTEL_HASWELL - tristate "Haswell/Broadwell Platforms" +config SND_SOC_INTEL_CATPT + tristate "Haswell and Broadwell" + depends on ACPI || COMPILE_TEST depends on SND_DMA_SGBUF - depends on DMADEVICES && ACPI - select SND_SOC_INTEL_SST - select SND_SOC_INTEL_SST_ACPI - select SND_SOC_INTEL_SST_FIRMWARE + select DW_DMAC_CORE select SND_SOC_ACPI_INTEL_MATCH help - If you have a Intel Haswell or Broadwell platform connected to - an I2S codec, then enable this option by saying Y or m. This is - typically used for Chromebooks. This is a recommended option. - This option is mutually exclusive with the SOF support on - Broadwell. If you want to enable SOF on Broadwell, you need to - deselect this option first. + Enable support for Intel(R) Haswell and Broadwell platforms + with I2S codec present. This is a recommended option. + Say Y or m if you have such device. + If unsure, say N. + +config SND_SOC_INTEL_HASWELL + tristate + select SND_SOC_INTEL_CATPT config SND_SOC_INTEL_BAYTRAIL tristate "Baytrail (legacy) Platforms" diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index 04ee48204fc9..c88c615f85f7 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -3,9 +3,9 @@ obj-$(CONFIG_SND_SOC) += common/ # Platform Support -obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/ obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM) += atom/ +obj-$(CONFIG_SND_SOC_INTEL_CATPT) += catpt/ obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += skylake/ obj-$(CONFIG_SND_SOC_INTEL_KEEMBAY) += keembay/ diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 12dd41796e82..6afdd9ac4478 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -26,7 +26,7 @@ config SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES interface. If unsure select N. -if SND_SOC_INTEL_HASWELL +if SND_SOC_INTEL_CATPT config SND_SOC_INTEL_HASWELL_MACH tristate "Haswell Lynxpoint" @@ -40,9 +40,9 @@ config SND_SOC_INTEL_HASWELL_MACH Say Y or m if you have such a device. If unsure select "N". -endif ## SND_SOC_INTEL_HASWELL +endif ## SND_SOC_INTEL_CATPT -if SND_SOC_INTEL_HASWELL || SND_SOC_SOF_BROADWELL +if SND_SOC_INTEL_CATPT || SND_SOC_SOF_BROADWELL config SND_SOC_INTEL_BDW_RT5650_MACH tristate "Broadwell with RT5650 codec" @@ -83,7 +83,7 @@ config SND_SOC_INTEL_BROADWELL_MACH Ultrabook platforms. Say Y or m if you have such a device. This is a recommended option. If unsure select "N". -endif ## SND_SOC_INTEL_HASWELL || SND_SOC_SOF_BROADWELL +endif ## SND_SOC_INTEL_CATPT || SND_SOC_SOF_BROADWELL if SND_SOC_INTEL_BAYTRAIL diff --git a/sound/soc/intel/catpt/Makefile b/sound/soc/intel/catpt/Makefile new file mode 100644 index 000000000000..c393a45795da --- /dev/null +++ b/sound/soc/intel/catpt/Makefile @@ -0,0 +1,6 @@ +snd-soc-catpt-objs := device.o dsp.o loader.o ipc.o messages.o pcm.o sysfs.o + +# tell define_trace.h where to find the trace header +CFLAGS_device.o := -I$(src) + +obj-$(CONFIG_SND_SOC_INTEL_CATPT) += snd-soc-catpt.o