From 654b7ce4a10f51f0ba0691fba2e0c3ad3f4279a7 Mon Sep 17 00:00:00 2001 From: Mohan Kumar Date: Wed, 10 May 2017 12:29:49 +0530 Subject: [PATCH] ASoC: tegra-alt: Dump APE register for debugging Add support with a mixer control using which APE register status can be dumped from userspace during an error or while debugging. Bug 200307023 Change-Id: I489bdaeeec16975a872b9b145a1672f3f4ef1928 Signed-off-by: Mohan Kumar Reviewed-on: http://git-master/r/1478879 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Viswanath L GVS: Gerrit_Virtual_Submit Reviewed-by: Dipesh Gandhi Reviewed-by: Ravindra Lokhande --- sound/soc/tegra-alt/tegra210_admaif_alt.c | 73 +++++++++++++++++++++++ sound/soc/tegra-alt/tegra210_admaif_alt.h | 5 ++ 2 files changed, 78 insertions(+) diff --git a/sound/soc/tegra-alt/tegra210_admaif_alt.c b/sound/soc/tegra-alt/tegra210_admaif_alt.c index 0ece9345134f..0e3c45680bd6 100644 --- a/sound/soc/tegra-alt/tegra210_admaif_alt.c +++ b/sound/soc/tegra-alt/tegra210_admaif_alt.c @@ -575,6 +575,75 @@ static int tegra210_admaif_put_format(struct snd_kcontrol *kcontrol, return 0; } +static void tegra_admaif_reg_dump(struct tegra210_admaif *admaif) +{ + int i, stride; + int ret; + + ret = pm_runtime_get_sync(admaif->dev->parent); + if (ret < 0) { + dev_err(admaif->dev, "parent get_sync failed: %d\n", ret); + return; + } + + pr_info("=========ADMAIF reg dump=========\n"); + + for (i = 0; i < admaif->soc_data->num_ch; i++) { + stride = (i * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE); + pr_info("RX%d_Enable = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_XBAR_RX_ENABLE + stride)); + pr_info("RX%d_STATUS = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_XBAR_RX_STATUS + stride)); + pr_info("RX%d_CIF_CTRL = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_CHAN_ACIF_RX_CTRL + stride)); + pr_info("RX%d_FIFO_CTRL = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_XBAR_RX_FIFO_CTRL + stride)); + pr_info("TX%d_Enable = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_XBAR_TX_ENABLE + stride)); + pr_info("TX%d_STATUS = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_XBAR_TX_STATUS + stride)); + pr_info("TX%d_CIF_CTRL = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_CHAN_ACIF_TX_CTRL + stride)); + pr_info("TX%d_FIFO_CTRL = %#x\n", i+1, + readl(admaif->base_addr + + TEGRA210_ADMAIF_XBAR_TX_FIFO_CTRL + stride)); + } + pm_runtime_put_sync(admaif->dev->parent); +} +static int tegra210_ape_dump_reg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tegra210_admaif *admaif = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = admaif->reg_dump_flag; + + return 0; +} + +static int tegra210_ape_dump_reg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tegra210_admaif *admaif = snd_soc_codec_get_drvdata(codec); + + admaif->reg_dump_flag = ucontrol->value.integer.value[0]; + + if (admaif->reg_dump_flag) { + tegra_adma_dump_ch_reg(); + tegra_admaif_reg_dump(admaif); + } + + return 0; +} + static int tegra210_admaif_dai_probe(struct snd_soc_dai *dai) { struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai); @@ -896,6 +965,8 @@ static struct snd_kcontrol_new tegra210_admaif_controls[] = { TEGRA210_ADMAIF_TX_CIF_CTRL(19), TEGRA210_ADMAIF_TX_CIF_CTRL(20), #endif + SOC_SINGLE_EXT("APE Reg Dump", SND_SOC_NOPM, 0, 1, 0, + tegra210_ape_dump_reg_get, tegra210_ape_dump_reg_put), }; static int tegra210_admaif_codec_probe(struct snd_soc_codec *codec) @@ -962,6 +1033,7 @@ static int tegra210_admaif_probe(struct platform_device *pdev) admaif->soc_data = soc_data; admaif->is_shutdown = false; + admaif->dev = &pdev->dev; admaif->capture_dma_data = devm_kzalloc(&pdev->dev, sizeof(struct tegra_alt_pcm_dma_params) * @@ -997,6 +1069,7 @@ static int tegra210_admaif_probe(struct platform_device *pdev) goto err; } + admaif->base_addr = regs; admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &tegra210_admaif_regmap_config); if (IS_ERR(admaif->regmap)) { diff --git a/sound/soc/tegra-alt/tegra210_admaif_alt.h b/sound/soc/tegra-alt/tegra210_admaif_alt.h index 2d55edc4492d..80b340b5e5c7 100644 --- a/sound/soc/tegra-alt/tegra210_admaif_alt.h +++ b/sound/soc/tegra-alt/tegra210_admaif_alt.h @@ -153,6 +153,7 @@ struct tegra210_admaif_soc_data { struct tegra210_admaif { /* regmap for admaif */ struct regmap *regmap; + struct device *dev; int refcnt; struct tegra_alt_pcm_dma_params *capture_dma_data; struct tegra_alt_pcm_dma_params *playback_dma_data; @@ -161,6 +162,10 @@ struct tegra210_admaif { int tx_mono_to_stereo[TEGRA210_ADMAIF_CHANNEL_COUNT]; int rx_stereo_to_mono[TEGRA210_ADMAIF_CHANNEL_COUNT]; bool is_shutdown; + int reg_dump_flag; + void __iomem *base_addr; }; +extern void tegra_adma_dump_ch_reg(void); + #endif -- 2.39.2