Skip to content

Commit 36478a7

Browse files
crojewsk-intelbroonie
authored andcommitted
ASoC: Intel: avs: ICCMAX recommendations for ICL+ platforms
For ICL+ platforms to avoid DMI/OPIO L1 entry during the base firmware load procedure, HW recommends to set LTRP_GB to 95us and start an additional CAPTURE stream in the background. Once the load completes, original LTRP_GB value is restored and the additional stream is released. Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://msgid.link/r/20240220115035.770402-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 5acb19e commit 36478a7

4 files changed

Lines changed: 66 additions & 2 deletions

File tree

include/sound/hda_register.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
131131
#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
132132
#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
133133

134+
#define AZX_REG_VS_LTRP_GB_MASK GENMASK(6, 0)
135+
134136
/* PCI space */
135137
#define AZX_PCIREG_TCSEL 0x44
136138

sound/soc/intel/avs/avs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ int avs_hda_load_library(struct avs_dev *adev, struct firmware *lib, u32 id);
325325
int avs_hda_transfer_modules(struct avs_dev *adev, bool load,
326326
struct avs_module_entry *mods, u32 num_mods);
327327

328+
int avs_icl_load_basefw(struct avs_dev *adev, struct firmware *fw);
329+
328330
/* Soc component members */
329331

330332
struct avs_soc_component {

sound/soc/intel/avs/icl.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
//
88

99
#include <linux/slab.h>
10+
#include <sound/hdaudio.h>
11+
#include <sound/hdaudio_ext.h>
1012
#include "avs.h"
1113
#include "messages.h"
1214

15+
#define ICL_VS_LTRP_GB_ICCMAX 95
16+
1317
#ifdef CONFIG_DEBUG_FS
1418
int avs_icl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
1519
u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
@@ -118,14 +122,70 @@ int avs_icl_set_d0ix(struct avs_dev *adev, bool enable)
118122
return AVS_IPC_RET(ret);
119123
}
120124

125+
int avs_icl_load_basefw(struct avs_dev *adev, struct firmware *fw)
126+
{
127+
struct hdac_bus *bus = &adev->base.core;
128+
struct hdac_ext_stream *host_stream;
129+
struct snd_pcm_substream substream;
130+
struct snd_dma_buffer dmab;
131+
unsigned int sd_fmt;
132+
u8 ltrp_gb;
133+
int ret;
134+
135+
/*
136+
* ICCMAX:
137+
*
138+
* For ICL+ platforms, as per HW recommendation LTRP_GB is set to 95us
139+
* during FW load. Its original value shall be restored once load completes.
140+
*
141+
* To avoid DMI/OPIO L1 entry during the load procedure, additional CAPTURE
142+
* stream is allocated and set to run.
143+
*/
144+
145+
memset(&substream, 0, sizeof(substream));
146+
substream.stream = SNDRV_PCM_STREAM_CAPTURE;
147+
148+
host_stream = snd_hdac_ext_stream_assign(bus, &substream, HDAC_EXT_STREAM_TYPE_HOST);
149+
if (!host_stream)
150+
return -EBUSY;
151+
152+
ltrp_gb = snd_hdac_chip_readb(bus, VS_LTRP) & AZX_REG_VS_LTRP_GB_MASK;
153+
/* Carries no real data, use default format. */
154+
sd_fmt = snd_hdac_stream_format(1, 32, 48000);
155+
156+
ret = snd_hdac_dsp_prepare(hdac_stream(host_stream), sd_fmt, fw->size, &dmab);
157+
if (ret < 0)
158+
goto release_stream;
159+
160+
snd_hdac_chip_updateb(bus, VS_LTRP, AZX_REG_VS_LTRP_GB_MASK, ICL_VS_LTRP_GB_ICCMAX);
161+
162+
spin_lock(&bus->reg_lock);
163+
snd_hdac_stream_start(hdac_stream(host_stream));
164+
spin_unlock(&bus->reg_lock);
165+
166+
ret = avs_hda_load_basefw(adev, fw);
167+
168+
spin_lock(&bus->reg_lock);
169+
snd_hdac_stream_stop(hdac_stream(host_stream));
170+
spin_unlock(&bus->reg_lock);
171+
172+
snd_hdac_dsp_cleanup(hdac_stream(host_stream), &dmab);
173+
174+
release_stream:
175+
snd_hdac_ext_stream_release(host_stream, HDAC_EXT_STREAM_TYPE_HOST);
176+
snd_hdac_chip_updateb(bus, VS_LTRP, AZX_REG_VS_LTRP_GB_MASK, ltrp_gb);
177+
178+
return ret;
179+
}
180+
121181
const struct avs_dsp_ops avs_icl_dsp_ops = {
122182
.power = avs_dsp_core_power,
123183
.reset = avs_dsp_core_reset,
124184
.stall = avs_dsp_core_stall,
125185
.irq_handler = avs_irq_handler,
126186
.irq_thread = avs_cnl_irq_thread,
127187
.int_control = avs_dsp_interrupt_control,
128-
.load_basefw = avs_hda_load_basefw,
188+
.load_basefw = avs_icl_load_basefw,
129189
.load_lib = avs_hda_load_library,
130190
.transfer_mods = avs_hda_transfer_modules,
131191
.log_buffer_offset = avs_icl_log_buffer_offset,

sound/soc/intel/avs/tgl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const struct avs_dsp_ops avs_tgl_dsp_ops = {
4242
.irq_handler = avs_irq_handler,
4343
.irq_thread = avs_cnl_irq_thread,
4444
.int_control = avs_dsp_interrupt_control,
45-
.load_basefw = avs_hda_load_basefw,
45+
.load_basefw = avs_icl_load_basefw,
4646
.load_lib = avs_hda_load_library,
4747
.transfer_mods = avs_hda_transfer_modules,
4848
.log_buffer_offset = avs_icl_log_buffer_offset,

0 commit comments

Comments
 (0)