Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp3654077pxb; Mon, 24 Jan 2022 14:32:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJxYlXlExCy5BOuHUzWblrMOvSmUR6ML1QgD/kh1QdmnGI9kdrPk0NdAZ7v8ihrWCF+abtDc X-Received: by 2002:a17:903:32d2:b0:14b:612:7fae with SMTP id i18-20020a17090332d200b0014b06127faemr16236310plr.80.1643063523931; Mon, 24 Jan 2022 14:32:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643063523; cv=none; d=google.com; s=arc-20160816; b=TKoQeBayHTOBamgi375Em8QMlBy20C6Sv14paIFX6fSentBflQmukq4bbQBeS2H+Rz lfDu1tm/M45Pd76adeEImVqwytdIe4tF2gypRoRL0MyRIpBiNxZA8vqYeCIc7nkO7NMn xE+UVRThG4E4VvWmI8P5AcjvXZsBA44/Qmib1PObZsinrYfgrKBhtdJUS4dqtWzif4ov 0jwZw3XKVDDZevfvSmbiYpJcVFYO2ueZ/yOZUxT3V8yoAPinoF0Lf7xUo99c0ndUmmtk UF5zWwdEGcxKUnB2KCt4rEVYcCDlPMNR3W4WXOUK457SDvFHwxrpKa1gSF0YD0IjJmMy TnpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=3QkKNH+vLdXg0FHSpfI1/ettPZdVpQXrA4v+s8lRoQg=; b=ptovV0PkO/Q99qZeZWeI1mJCgPJWJAILOr113lIUFR5r+Qkw/tE2ZgD3e368OKH81I B7/ZTouoh3y3gaZ8FrIUqpVs8PeotYCIsFdmUrd2I2qjl5ukBrXJR2eCj30eTjujn2vT IUy6Q4B3wIHrxaoa7JXD0o7wSCoUVT6Ei5f+T/U82Uz4S6Otf1MVWVWwcYFxK+ic41iO AF+NLyyl9eFehvl54TWoo0VbgdGhUNDI8Y0D6ognTGKIoc5Nc64andrspkmQ8uWAFGKH 1ld+WQ0i52ps/Yhgntm6QaqdyIgvosdUJvZ9O7ldizF62G3Z8ivB741RJbWYDLIW9c4o /JvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ucSnbFTw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c11si12564812plh.322.2022.01.24.14.31.51; Mon, 24 Jan 2022 14:32:03 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ucSnbFTw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1586923AbiAXW1c (ORCPT + 99 others); Mon, 24 Jan 2022 17:27:32 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:52512 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1454400AbiAXVcb (ORCPT ); Mon, 24 Jan 2022 16:32:31 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 1B098614DC; Mon, 24 Jan 2022 21:32:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C92F2C340E4; Mon, 24 Jan 2022 21:32:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643059950; bh=7bcSEZLz3ee9hcPWYNTolYzG/C+UFjH9TlCAQp+r2gA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ucSnbFTwnjrIewUo2lXvrRW/xTPbkKpjno666YDfl525K6khJ+GLD4K9TJBdeKNyU IWkTUHRE2AdnXW5SZ3fojNdt/yx1BOvBKUEiQWL2PMZvQ9Er98XpJSnkKh33qYxk79 Te1GoTxatiQRMbeUMCcFa/2G8/3kxmy/2mAn9kiI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Pierre-Louis Bossart , Ranjani Sridharan , =?UTF-8?q?P=C3=A9ter=20Ujfalusi?= , Mark Brown , Sasha Levin Subject: [PATCH 5.16 0762/1039] ASoC: SOF: Intel: hda: add quirks for HDAudio DMA position information Date: Mon, 24 Jan 2022 19:42:31 +0100 Message-Id: <20220124184150.932229356@linuxfoundation.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220124184125.121143506@linuxfoundation.org> References: <20220124184125.121143506@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Pierre-Louis Bossart [ Upstream commit 288fad2f71fa0b989c075d4984879c26d47cfb06 ] The code inherited from the Skylake driver does not seem to follow any known hardware recommendations. The only two recommended options are a) use DPIB registers if VC1 traffic is not allowed b) use DPIB DDR update if VC1 traffic is used In all of SOF-based updated, VC1 is not supported so we can 'safely' move to using DPIB registers only. This patch keeps the legacy code, in case there was an undocumented issue lost to history, and adds the DPIB DDR update for additional debug. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20211207193947.71080-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/sof/intel/hda-pcm.c | 86 +++++++++++++++++++++++++---------- sound/soc/sof/intel/hda.c | 9 +++- sound/soc/sof/intel/hda.h | 6 +++ 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index cc8ddef37f37b..41cb60955f5c1 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -172,38 +172,74 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev, goto found; } - /* - * DPIB/posbuf position mode: - * For Playback, Use DPIB register from HDA space which - * reflects the actual data transferred. - * For Capture, Use the position buffer for pointer, as DPIB - * is not accurate enough, its update may be completed - * earlier than the data written to DDR. - */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (sof_hda_position_quirk) { + case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY: + /* + * This legacy code, inherited from the Skylake driver, + * mixes DPIB registers and DPIB DDR updates and + * does not seem to follow any known hardware recommendations. + * It's not clear e.g. why there is a different flow + * for capture and playback, the only information that matters is + * what traffic class is used, and on all SOF-enabled platforms + * only VC0 is supported so the work-around was likely not necessary + * and quite possibly wrong. + */ + + /* DPIB/posbuf position mode: + * For Playback, Use DPIB register from HDA space which + * reflects the actual data transferred. + * For Capture, Use the position buffer for pointer, as DPIB + * is not accurate enough, its update may be completed + * earlier than the data written to DDR. + */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + } else { + /* + * For capture stream, we need more workaround to fix the + * position incorrect issue: + * + * 1. Wait at least 20us before reading position buffer after + * the interrupt generated(IOC), to make sure position update + * happens on frame boundary i.e. 20.833uSec for 48KHz. + * 2. Perform a dummy Read to DPIB register to flush DMA + * position value. + * 3. Read the DMA Position from posbuf. Now the readback + * value should be >= period boundary. + */ + usleep_range(20, 21); + snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + pos = snd_hdac_stream_get_pos_posbuf(hstream); + } + break; + case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS: + /* + * In case VC1 traffic is disabled this is the recommended option + */ pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, AZX_REG_VS_SDXDPIB_XBASE + (AZX_REG_VS_SDXDPIB_XINTERVAL * hstream->index)); - } else { + break; + case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE: /* - * For capture stream, we need more workaround to fix the - * position incorrect issue: - * - * 1. Wait at least 20us before reading position buffer after - * the interrupt generated(IOC), to make sure position update - * happens on frame boundary i.e. 20.833uSec for 48KHz. - * 2. Perform a dummy Read to DPIB register to flush DMA - * position value. - * 3. Read the DMA Position from posbuf. Now the readback - * value should be >= period boundary. + * This is the recommended option when VC1 is enabled. + * While this isn't needed for SOF platforms it's added for + * consistency and debug. */ - usleep_range(20, 21); - snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - hstream->index)); pos = snd_hdac_stream_get_pos_posbuf(hstream); + break; + default: + dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n", + sof_hda_position_quirk); + pos = 0; + break; } if (pos >= hstream->bufsize) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 2c0d4d06ab364..25200a0e1dc9d 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -440,6 +440,10 @@ MODULE_PARM_DESC(use_msi, "SOF HDA use PCI MSI mode"); #define hda_use_msi (1) #endif +int sof_hda_position_quirk = SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS; +module_param_named(position_quirk, sof_hda_position_quirk, int, 0444); +MODULE_PARM_DESC(position_quirk, "SOF HDaudio position quirk"); + static char *hda_model; module_param(hda_model, charp, 0444); MODULE_PARM_DESC(hda_model, "Use the given HDA board model."); @@ -618,7 +622,10 @@ static int hda_init(struct snd_sof_dev *sdev) /* HDA bus init */ sof_hda_bus_init(bus, &pci->dev); - bus->use_posbuf = 1; + if (sof_hda_position_quirk == SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS) + bus->use_posbuf = 0; + else + bus->use_posbuf = 1; bus->bdl_pos_adj = 0; bus->sync_write = 1; diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 1195018a1f4f5..dba4733ccf9ae 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -738,4 +738,10 @@ struct sof_ipc_dai_config; int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w); int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w); +#define SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY (0) /* previous implementation */ +#define SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS (1) /* recommended if VC0 only */ +#define SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE (2) /* recommended with VC0 or VC1 */ + +extern int sof_hda_position_quirk; + #endif -- 2.34.1