From patchwork Tue Jul 19 10:46:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinod Koul X-Patchwork-Id: 9238269 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EB074600CB for ; Tue, 19 Jul 2016 20:23:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DAE6026D19 for ; Tue, 19 Jul 2016 20:23:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CEEE12756B; Tue, 19 Jul 2016 20:23:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D005426D19 for ; Tue, 19 Jul 2016 20:23:19 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 8FB5E266052; Tue, 19 Jul 2016 22:23:18 +0200 (CEST) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 5C9BC265FF5; Tue, 19 Jul 2016 18:21:07 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 58F5B265D6C; Tue, 19 Jul 2016 18:21:04 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by alsa0.perex.cz (Postfix) with ESMTP id 31B4D265FF5 for ; Tue, 19 Jul 2016 12:39:36 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP; 19 Jul 2016 03:39:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.28,389,1464678000"; d="scan'208"; a="1019685666" Received: from vkoul-udesk7.iind.intel.com ([10.223.84.143]) by orsmga002.jf.intel.com with ESMTP; 19 Jul 2016 03:39:32 -0700 From: Vinod Koul To: alsa-devel@alsa-project.org Date: Tue, 19 Jul 2016 16:16:41 +0530 Message-Id: <1468925202-29445-2-git-send-email-vinod.koul@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1468925202-29445-1-git-send-email-vinod.koul@intel.com> References: <1468925202-29445-1-git-send-email-vinod.koul@intel.com> Cc: tiwai@suse.de, Hardik T Shah , Guneshwor Singh , liam.r.girdwood@linux.intel.com, patches.audio@intel.com, broonie@kernel.org, Vinod Koul Subject: [alsa-devel] [PATCH v2 1/2] ALSA - hda: Add support for parsing new HDA capabilities X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Guneshwor Singh Skylake onwards HDA controller supports new capabilities like Global Time Stamping (GTS) capability. So add support to parse these new capabilities. Signed-off-by: Guneshwor Singh Signed-off-by: Hardik T Shah Signed-off-by: Vinod Koul --- include/sound/hda_register.h | 23 ++++++++++++++++++++ sound/pci/hda/hda_controller.c | 49 ++++++++++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_controller.h | 27 +++++++++++++++++++++++ sound/pci/hda/hda_intel.c | 12 +++++++++++ 4 files changed, 111 insertions(+) diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h index ff1aecf325e8..e4178328e8c8 100644 --- a/include/sound/hda_register.h +++ b/include/sound/hda_register.h @@ -242,6 +242,29 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; /* Interval used to calculate the iterating register offset */ #define AZX_DRSM_INTERVAL 0x08 +/* Global time synchronization registers */ +#define GTSCC_TSCCD_MASK 0x80000000 +#define GTSCC_TSCCD_SHIFT 31 +#define GTSCC_TSCCI_MASK 0x20 +#define GTSCC_CDMAS_DMA_DIR_SHIFT 4 + +#define WALFCC_CIF_MASK 0x1FF +#define WALFCC_FN_SHIFT 9 +#define HDA_CLK_CYCLES_PER_FRAME 512 + +/* + * An error occurs near frame "rollover". The clocks in frame value indicates + * whether this error may have occurred. Here we use the value of 10. Please + * see the errata for the right number [<10] + */ +#define HDA_MAX_CYCLE_VALUE 499 +#define HDA_MAX_CYCLE_OFFSET 10 +#define HDA_MAX_CYCLE_READ_RETRY 10 + +#define TSCCU_CCU_SHIFT 32 +#define LLPC_CCU_SHIFT 32 + + /* * helpers to read the stream position */ diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 27de8015717d..7e5e4c261e51 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -393,6 +393,50 @@ static struct snd_pcm_hardware azx_pcm_hw = { .fifo_size = 0, }; +#define AZX_MAX_CAPS 10 + +/** + * azx_parse_capabilities - parse the additional HDA capabilities for HDA + * controller. HDA controller defines capabilities as link list which can be + * parsed to find the controller support. + * + * @chip: azx controller + */ +void azx_parse_capabilities(struct azx *chip) +{ + unsigned int cur_cap; + unsigned int offset; unsigned int counter = 0; + + offset = azx_readl(chip, LLCH); + + /* Lets walk the linked capabilities list */ + do { + cur_cap = _snd_hdac_chip_read(l, azx_bus(chip), offset); + + switch ((cur_cap & CAP_HDR_ID_MASK) >> CAP_HDR_ID_OFF) { + case GTS_CAP_ID: + dev_dbg(chip->card->dev, "Found GTS capability"); + chip->gts_present = 1; + break; + + default: + break; + } + + counter++; + + if (counter > AZX_MAX_CAPS) { + dev_err(chip->card->dev, "We exceeded azx capabilities!!!\n"); + break; + } + + /* read the offset of next capabiity */ + offset = cur_cap & CAP_HDR_NXT_PTR_MASK; + + } while (offset); +} +EXPORT_SYMBOL_GPL(azx_parse_capabilities); + static int azx_pcm_open(struct snd_pcm_substream *substream) { struct azx_pcm *apcm = snd_pcm_substream_chip(substream); @@ -412,6 +456,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) goto unlock; } runtime->private_data = azx_dev; + + if (chip->gts_present) + azx_pcm_hw.info = azx_pcm_hw.info | + SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME; + runtime->hw = azx_pcm_hw; runtime->hw.channels_min = hinfo->channels_min; runtime->hw.channels_max = hinfo->channels_max; diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index ec63bbf1ec6d..fc57eef9fd88 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -159,9 +159,14 @@ struct azx { unsigned int region_requested:1; unsigned int disabled:1; /* disabled by vga_switcheroo */ + /* GTS present */ + unsigned int gts_present:1; + #ifdef CONFIG_SND_HDA_DSP_LOADER struct azx_dev saved_azx_dev; #endif + unsigned int link_count; + unsigned int mlcap_offset; }; #define azx_bus(chip) (&(chip)->bus.core) @@ -173,6 +178,27 @@ struct azx { #define azx_snoop(chip) true #endif +#define AZX_REG_LLCH 0x14 + +#define AZX_REG_GTS_BASE 0x520 + +#define AZX_REG_GTSCC (AZX_REG_GTS_BASE + 0x00) +#define AZX_REG_WALFCC (AZX_REG_GTS_BASE + 0x04) +#define AZX_REG_TSCCL (AZX_REG_GTS_BASE + 0x08) +#define AZX_REG_TSCCU (AZX_REG_GTS_BASE + 0x0C) +#define AZX_REG_LLPFOC (AZX_REG_GTS_BASE + 0x14) +#define AZX_REG_LLPCL (AZX_REG_GTS_BASE + 0x18) +#define AZX_REG_LLPCU (AZX_REG_GTS_BASE + 0x1C) + +#define CAP_HDR_VER_OFF 28 +#define CAP_HDR_VER_MASK (0xF << CAP_HDR_VER_OFF) + +#define CAP_HDR_ID_OFF 16 +#define CAP_HDR_ID_MASK (0xFFF << CAP_HDR_ID_OFF) + +#define GTS_CAP_ID 0x1 +#define CAP_HDR_NXT_PTR_MASK 0xFFFF + /* * macros for easy use */ @@ -201,6 +227,7 @@ static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream) unsigned int azx_get_position(struct azx *chip, struct azx_dev *azx_dev); unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev); unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev); +void azx_parse_capabilities(struct azx *chip); /* Stream control. */ void azx_stop_all_streams(struct azx *chip); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 6f8ea13323c1..bd392183fbc1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1655,6 +1655,18 @@ static int azx_first_init(struct azx *chip) return -ENXIO; } + if (IS_SKL_PLUS(pci)) + azx_parse_capabilities(chip); + + /* + * Some Intel CPUs has always running timer (ART) feature and + * controller may have Global time sync reporting capability, so + * check both of these before declaring synchronized time reporting + * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME + */ + if (!(chip->gts_present && boot_cpu_has(X86_FEATURE_ART))) + chip->gts_present = false; + if (chip->msi) { if (chip->driver_caps & AZX_DCAPS_NO_MSI64) { dev_dbg(card->dev, "Disabling 64bit MSI\n");