mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 01:31:30 +03:00
- The issue was happening because dapm core was not deallocating
the hw contraints rules memory.
Memory leak backtrace from cat /sys/kernel/debug/kmemleak:
[<0000000046fdaf4f>] slab_post_alloc_hook+0x6c/0x3e0
[<00000000989dfc0e>] __kmalloc_track_caller+0x1b8/0x400
[<00000000505e39ec>] krealloc+0xe8/0x160
[<000000009cc82a21>] snd_pcm_hw_rule_add+0x164/0x1a0
[<00000000aa77851e>] snd_pcm_hw_constraint_list+0x28/0x30
[<000000009b2cd5c6>] tegra210_ahub_write_ram+0xa8/0xb60
[<00000000a61d7069>] snd_soc_dai_startup+0x40/0xa0
[<00000000a7452879>] snd_soc_dai_link_event+0x334/0x600
[<000000008c5771de>] dapm_seq_check_event+0x120/0x330
[<00000000be740a3d>] dapm_seq_run_coalesced+0xb0/0x250
[<0000000003732007>] dapm_seq_run+0xf0/0x510
[<00000000cbb85eb0>] dapm_power_widgets+0x58c/0xac0
[<00000000b96c5548>] snd_soc_dapm_stream_event+0x128/0x170
[<0000000027bb14bc>] soc_pcm_prepare+0x70/0x110
[<00000000d44b9075>] snd_pcm_do_prepare+0x34/0x50
[<000000005664d4d5>] snd_pcm_action_single+0x4c/0xa0
- For BE dais HW constraints won't take any impact and only for FE
dais it is required. So added it in component driver open callback.
Bug 200773796
Signed-off-by: Sheetal <sheetal@nvidia.com>
Change-Id: Ic4c1bf881b914bda03bda8e97816cf1c6dee4052
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.10/+/2596443
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Mohan Kumar D <mkumard@nvidia.com>
Reviewed-by: Viswanath L <viswanathl@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Sharad Gupta <sharadg@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
146 lines
4.8 KiB
C
146 lines
4.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* tegra210_ahub.h - TEGRA210 AHUB
|
|
*
|
|
* Copyright (c) 2020-2021 NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#ifndef __TEGRA210_AHUB__H__
|
|
#define __TEGRA210_AHUB__H__
|
|
|
|
/* Tegra210 specific */
|
|
#define TEGRA210_XBAR_PART1_RX 0x200
|
|
#define TEGRA210_XBAR_PART2_RX 0x400
|
|
#define TEGRA210_XBAR_RX_STRIDE 0x4
|
|
#define TEGRA210_XBAR_AUDIO_RX_COUNT 90
|
|
#define TEGRA210_XBAR_REG_MASK_0 0xf1f03ff
|
|
#define TEGRA210_XBAR_REG_MASK_1 0x3f30031f
|
|
#define TEGRA210_XBAR_REG_MASK_2 0xff1cf313
|
|
#define TEGRA210_XBAR_REG_MASK_3 0x0
|
|
#define TEGRA210_XBAR_UPDATE_MAX_REG 3
|
|
/* Tegra186 specific */
|
|
#define TEGRA186_XBAR_PART3_RX 0x600
|
|
#define TEGRA186_XBAR_AUDIO_RX_COUNT 115
|
|
#define TEGRA186_XBAR_REG_MASK_0 0xf3fffff
|
|
#define TEGRA186_XBAR_REG_MASK_1 0x3f310f1f
|
|
#define TEGRA186_XBAR_REG_MASK_2 0xff3cf311
|
|
#define TEGRA186_XBAR_REG_MASK_3 0x3f0f00ff
|
|
#define TEGRA186_XBAR_UPDATE_MAX_REG 4
|
|
|
|
/* Fields in *AHUBRAMCTL_CTRL; used by different AHUB modules */
|
|
#define TEGRA210_AHUBRAMCTL_CTRL_RW_READ 0
|
|
#define TEGRA210_AHUBRAMCTL_CTRL_RW_WRITE (1 << 14)
|
|
#define TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN (1 << 13)
|
|
#define TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN (1 << 12)
|
|
#define TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_MASK 0x1ff
|
|
|
|
#define TEGRA_XBAR_UPDATE_MAX_REG (TEGRA186_XBAR_UPDATE_MAX_REG)
|
|
|
|
#define TEGRA186_MAX_REGISTER_ADDR (TEGRA186_XBAR_PART3_RX + \
|
|
(TEGRA210_XBAR_RX_STRIDE * (TEGRA186_XBAR_AUDIO_RX_COUNT - 1)))
|
|
|
|
#define TEGRA210_MAX_REGISTER_ADDR (TEGRA210_XBAR_PART2_RX + \
|
|
(TEGRA210_XBAR_RX_STRIDE * (TEGRA210_XBAR_AUDIO_RX_COUNT - 1)))
|
|
|
|
#define MUX_REG(id) (TEGRA210_XBAR_RX_STRIDE * (id))
|
|
|
|
#define MUX_VALUE(npart, nbit) (1 + (nbit) + (npart) * 32)
|
|
|
|
#define SOC_VALUE_ENUM_WIDE(xreg, shift, xmax, xtexts, xvalues) \
|
|
{ \
|
|
.reg = xreg, \
|
|
.shift_l = shift, \
|
|
.shift_r = shift, \
|
|
.items = xmax, \
|
|
.texts = xtexts, \
|
|
.values = xvalues, \
|
|
.mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0 \
|
|
}
|
|
|
|
#define SOC_VALUE_ENUM_WIDE_DECL(name, xreg, shift, xtexts, xvalues) \
|
|
static struct soc_enum name = \
|
|
SOC_VALUE_ENUM_WIDE(xreg, shift, ARRAY_SIZE(xtexts), \
|
|
xtexts, xvalues)
|
|
|
|
#define MUX_ENUM_CTRL_DECL(ename, id) \
|
|
SOC_VALUE_ENUM_WIDE_DECL(ename##_enum, MUX_REG(id), 0, \
|
|
tegra210_ahub_mux_texts, \
|
|
tegra210_ahub_mux_values); \
|
|
static const struct snd_kcontrol_new ename##_control = \
|
|
SOC_DAPM_ENUM_EXT("Route", ename##_enum, \
|
|
tegra_ahub_get_value_enum, \
|
|
tegra_ahub_put_value_enum)
|
|
|
|
#define MUX_ENUM_CTRL_DECL_186(ename, id) \
|
|
SOC_VALUE_ENUM_WIDE_DECL(ename##_enum, MUX_REG(id), 0, \
|
|
tegra186_ahub_mux_texts, \
|
|
tegra186_ahub_mux_values); \
|
|
static const struct snd_kcontrol_new ename##_control = \
|
|
SOC_DAPM_ENUM_EXT("Route", ename##_enum, \
|
|
tegra_ahub_get_value_enum, \
|
|
tegra_ahub_put_value_enum)
|
|
|
|
#define IN_OUT_ROUTES(name) \
|
|
{ name " XBAR-RX", NULL, name " XBAR-Playback" }, \
|
|
{ name " XBAR-Capture", NULL, name " XBAR-TX" },
|
|
|
|
#define WIDGETS(sname, ename) \
|
|
SND_SOC_DAPM_AIF_IN(sname " XBAR-RX", NULL, 0, SND_SOC_NOPM, 0, 0), \
|
|
SND_SOC_DAPM_AIF_OUT(sname " XBAR-TX", NULL, 0, SND_SOC_NOPM, 0, 0), \
|
|
SND_SOC_DAPM_MUX(sname " Mux", SND_SOC_NOPM, 0, 0, \
|
|
&ename##_control)
|
|
|
|
#define TX_WIDGETS(sname) \
|
|
SND_SOC_DAPM_AIF_IN(sname " XBAR-RX", NULL, 0, SND_SOC_NOPM, 0, 0), \
|
|
SND_SOC_DAPM_AIF_OUT(sname " XBAR-TX", NULL, 0, SND_SOC_NOPM, 0, 0)
|
|
|
|
#define DAI(sname) \
|
|
{ \
|
|
.name = "XBAR-" #sname, \
|
|
.playback = { \
|
|
.stream_name = #sname " XBAR-Playback", \
|
|
.channels_min = 1, \
|
|
.channels_max = 16, \
|
|
.rates = SNDRV_PCM_RATE_KNOT, \
|
|
.formats = SNDRV_PCM_FMTBIT_S8 | \
|
|
SNDRV_PCM_FMTBIT_S16_LE | \
|
|
SNDRV_PCM_FMTBIT_S24_LE | \
|
|
SNDRV_PCM_FMTBIT_S32_LE, \
|
|
}, \
|
|
.capture = { \
|
|
.stream_name = #sname " XBAR-Capture", \
|
|
.channels_min = 1, \
|
|
.channels_max = 16, \
|
|
.rates = SNDRV_PCM_RATE_KNOT, \
|
|
.formats = SNDRV_PCM_FMTBIT_S8 | \
|
|
SNDRV_PCM_FMTBIT_S16_LE | \
|
|
SNDRV_PCM_FMTBIT_S24_LE | \
|
|
SNDRV_PCM_FMTBIT_S32_LE, \
|
|
}, \
|
|
}
|
|
|
|
struct tegra_ahub_soc_data {
|
|
const struct regmap_config *regmap_config;
|
|
const struct snd_soc_component_driver *cmpnt_drv;
|
|
struct snd_soc_dai_driver *dai_drv;
|
|
unsigned int mask[4];
|
|
unsigned int reg_count;
|
|
unsigned int num_dais;
|
|
};
|
|
|
|
struct tegra_ahub {
|
|
const struct tegra_ahub_soc_data *soc_data;
|
|
struct regmap *regmap;
|
|
struct clk *clk;
|
|
};
|
|
|
|
void tegra210_ahub_write_ram(struct regmap *regmap, unsigned int reg_ctrl,
|
|
unsigned int reg_data, unsigned int ram_offset,
|
|
unsigned int *data, size_t size);
|
|
void tegra210_ahub_read_ram(struct regmap *regmap, unsigned int reg_ctrl,
|
|
unsigned int reg_data, unsigned int ram_offset,
|
|
unsigned int *data, size_t size);
|
|
|
|
#endif
|