linux-loongson/sound/soc/mediatek/common/mtk-base-afe.h
Chen-Yu Tsai ec4a10ca4a
ASoC: mediatek: use reserved memory or enable buffer pre-allocation
In commit 32c9c06adb ("ASoC: mediatek: disable buffer pre-allocation")
buffer pre-allocation was disabled to accommodate newer platforms that
have a limited reserved memory region for the audio frontend.

Turns out disabling pre-allocation across the board impacts platforms
that don't have this reserved memory region. Buffer allocation failures
have been observed on MT8173 and MT8183 based Chromebooks under low
memory conditions, which results in no audio playback for the user.

Since some MediaTek platforms already have dedicated reserved memory
pools for the audio frontend, the plan is to enable this for all of
them. This requires device tree changes. As a fallback, reinstate the
original policy of pre-allocating audio buffers at probe time of the
reserved memory pool cannot be found or used.

This patch covers the MT8173, MT8183, MT8186 and MT8192 platforms for
now, the reason being that existing MediaTek platform drivers that
supported reserved memory were all platforms that mainly supported
ChromeOS, and is also the set of devices that I can verify.

Fixes: 32c9c06adb ("ASoC: mediatek: disable buffer pre-allocation")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Link: https://patch.msgid.link/20250612074901.4023253-7-wenst@chromium.org
Signed-off-by: Mark Brown <broonie@kernel.org>
2025-06-12 13:45:35 +01:00

174 lines
3.8 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* mtk-base-afe.h -- Mediatek base afe structure
*
* Copyright (c) 2016 MediaTek Inc.
* Author: Garlic Tseng <garlic.tseng@mediatek.com>
*/
#ifndef _MTK_BASE_AFE_H_
#define _MTK_BASE_AFE_H_
#include <linux/soc/mediatek/mtk_sip_svc.h>
#define MTK_STREAM_NUM (SNDRV_PCM_STREAM_LAST + 1)
#define MTK_SIP_AUDIO_CONTROL MTK_SIP_SMC_CMD(0x517)
/* SMC CALL Operations */
enum mtk_audio_smc_call_op {
MTK_AUDIO_SMC_OP_INIT = 0,
MTK_AUDIO_SMC_OP_DRAM_REQUEST,
MTK_AUDIO_SMC_OP_DRAM_RELEASE,
MTK_AUDIO_SMC_OP_SRAM_REQUEST,
MTK_AUDIO_SMC_OP_SRAM_RELEASE,
MTK_AUDIO_SMC_OP_ADSP_REQUEST,
MTK_AUDIO_SMC_OP_ADSP_RELEASE,
MTK_AUDIO_SMC_OP_DOMAIN_SIDEBANDS,
MTK_AUDIO_SMC_OP_BTCVSD_WRITE,
MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_CLEAR,
MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_UNDERFLOW,
MTK_AUDIO_SMC_OP_NUM
};
struct mtk_base_memif_data {
int id;
const char *name;
int reg_ofs_base;
int reg_ofs_cur;
int reg_ofs_end;
int reg_ofs_base_msb;
int reg_ofs_cur_msb;
int reg_ofs_end_msb;
int fs_reg;
int fs_shift;
int fs_maskbit;
int mono_reg;
int mono_shift;
int mono_invert;
int quad_ch_reg;
int quad_ch_mask;
int quad_ch_shift;
int int_odd_flag_reg;
int int_odd_flag_shift;
int enable_reg;
int enable_shift;
int hd_reg;
int hd_shift;
int hd_align_reg;
int hd_align_mshift;
int msb_reg;
int msb_shift;
int msb_end_reg;
int msb_end_shift;
int agent_disable_reg;
int agent_disable_shift;
int ch_num_reg;
int ch_num_shift;
int ch_num_maskbit;
/* playback memif only */
int pbuf_reg;
int pbuf_mask;
int pbuf_shift;
int minlen_reg;
int minlen_mask;
int minlen_shift;
};
struct mtk_base_irq_data {
int id;
int irq_cnt_reg;
int irq_cnt_shift;
int irq_cnt_maskbit;
int irq_fs_reg;
int irq_fs_shift;
int irq_fs_maskbit;
int irq_en_reg;
int irq_en_shift;
int irq_clr_reg;
int irq_clr_shift;
int irq_status_shift;
};
struct device;
struct list_head;
struct mtk_base_afe_memif;
struct mtk_base_afe_irq;
struct mtk_base_afe_dai;
struct regmap;
struct snd_pcm_substream;
struct snd_soc_dai;
struct mtk_base_afe {
void __iomem *base_addr;
struct device *dev;
struct regmap *regmap;
struct mutex irq_alloc_lock; /* dynamic alloc irq lock */
unsigned int const *reg_back_up_list;
unsigned int *reg_back_up;
unsigned int reg_back_up_list_num;
int (*runtime_suspend)(struct device *dev);
int (*runtime_resume)(struct device *dev);
bool suspended;
struct mtk_base_afe_memif *memif;
int memif_size;
struct mtk_base_afe_irq *irqs;
int irqs_size;
int memif_32bit_supported;
bool preallocate_buffers;
struct list_head sub_dais;
struct snd_soc_dai_driver *dai_drivers;
unsigned int num_dai_drivers;
const struct snd_pcm_hardware *mtk_afe_hardware;
int (*memif_fs)(struct snd_pcm_substream *substream,
unsigned int rate);
int (*irq_fs)(struct snd_pcm_substream *substream,
unsigned int rate);
int (*get_dai_fs)(struct mtk_base_afe *afe,
int dai_id, unsigned int rate);
int (*get_memif_pbuf_size)(struct snd_pcm_substream *substream);
int (*request_dram_resource)(struct device *dev);
int (*release_dram_resource)(struct device *dev);
void *platform_priv;
};
struct mtk_base_afe_memif {
unsigned int phys_buf_addr;
int buffer_size;
struct snd_pcm_substream *substream;
const struct mtk_base_memif_data *data;
int irq_usage;
int const_irq;
unsigned char *dma_area;
dma_addr_t dma_addr;
size_t dma_bytes;
};
struct mtk_base_afe_irq {
const struct mtk_base_irq_data *irq_data;
int irq_occupyed;
};
struct mtk_base_afe_dai {
struct snd_soc_dai_driver *dai_drivers;
unsigned int num_dai_drivers;
const struct snd_kcontrol_new *controls;
unsigned int num_controls;
const struct snd_soc_dapm_widget *dapm_widgets;
unsigned int num_dapm_widgets;
const struct snd_soc_dapm_route *dapm_routes;
unsigned int num_dapm_routes;
struct list_head list;
};
#endif