mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
ASoC: tegra-alt: Fix SW reset for Tegra210 ADMAIF9/10
When using ADMAIF9/10 channels for audio playback/capture on Tegra210, the soft-reset of the ADMAIF is failing when playback finishes ... Playing WAVE 'rec.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo [ 260.094969] tegra210-ape-admaif tegra210-admaif: Failed at ADMAIF0_TX sw reset There are a couple issues here ... 1. The ADMAIF that fails is reported as 'ADMAIF0' although in the above test ADMAIF9 is being used. This is purely an error in the driver which is using 'dev-id' as the ADMAIF ID instead of 'dai->id'. Hence the above error message is misleading. 2. The soft reset fails because the regmap configuration for the ADMAIF registers on T210 is incorrect. In the function, tegra210_admaif_volatile_reg(), only the ADMAIF registers between offset 0x000 and 0x500 are considered volatile. The problem is that the ADMAIF channel registers for T210 actually span 0x000-0x280 (for RX) and 0x300-0x580 (for TX). This means that for TX, the ADMAIF9/10 channel registers are not considered volatile and hence, polling the soft reset register is failing. Fix the above two issues by correcting the ADMAIF ID reported for any soft reset failures, and correct the address range for ADMAIF volatile registers. Bug 2037162 Change-Id: If22eba754ab4bf2bf5acc3c9da51388b7208c749 Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1620448 (cherry picked from commit 1cd55ec115b7235343f09ec524a2c4cb2253ef33) Reviewed-on: https://git-master.nvidia.com/r/1642335 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -144,8 +144,8 @@ static bool tegra_admaif_volatile_reg(struct device *dev, unsigned int reg)
|
||||
struct tegra_admaif *admaif = dev_get_drvdata(dev);
|
||||
unsigned int offset_tx_enable = admaif->soc_data->reg_offsets.tx_enable;
|
||||
|
||||
if (reg > 0 && (reg < admaif->soc_data->num_ch *
|
||||
TEGRA_ADMAIF_CHANNEL_REG_STRIDE * 2))
|
||||
if (reg > 0 && (reg < (offset_tx_enable + (admaif->soc_data->num_ch *
|
||||
TEGRA_ADMAIF_CHANNEL_REG_STRIDE))))
|
||||
reg = reg % TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
|
||||
|
||||
if ((reg == TEGRA_ADMAIF_XBAR_RX_ENABLE) ||
|
||||
@@ -451,7 +451,7 @@ static void tegra_admaif_stop_playback(struct snd_soc_dai *dai)
|
||||
/* HW needs sw reset to make sure previous transaction be clean */
|
||||
ret = tegra_admaif_sw_reset(dai, SNDRV_PCM_STREAM_PLAYBACK, 0xffff);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed at ADMAIF%d_TX sw reset\n", dev->id);
|
||||
dev_err(dev, "Failed at ADMAIF%d_TX sw reset\n", dai->id);
|
||||
}
|
||||
|
||||
static void tegra_admaif_start_capture(struct snd_soc_dai *dai)
|
||||
@@ -487,7 +487,7 @@ static void tegra_admaif_stop_capture(struct snd_soc_dai *dai)
|
||||
/* HW needs sw reset to make sure previous transaction be clean */
|
||||
ret = tegra_admaif_sw_reset(dai, SNDRV_PCM_STREAM_CAPTURE, 0xffff);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed at ADMAIF%d_RX sw reset\n", dev->id);
|
||||
dev_err(dev, "Failed at ADMAIF%d_RX sw reset\n", dai->id);
|
||||
}
|
||||
|
||||
static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
|
||||
Reference in New Issue
Block a user