Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions sound/soc/sof/intel/hda-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,8 +760,15 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops)

if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4 && !hda_use_tplg_nhlt) {
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct snd_ipc4_nhlt *entry;

ipc4_data->nhlt = intel_nhlt_init(sdev->dev);
entry = devm_kzalloc(sdev->dev, sizeof(*entry), GFP_KERNEL);
if (!entry)
return;

entry->nhlt = intel_nhlt_init(sdev->dev);
Comment thread
lgirdwood marked this conversation as resolved.

list_add(&entry->list, &ipc4_data->nhlt_list);
}
}
EXPORT_SYMBOL_NS(hda_set_dai_drv_ops, "SND_SOC_SOF_INTEL_HDA_COMMON");
Expand All @@ -770,9 +777,14 @@ void hda_ops_free(struct snd_sof_dev *sdev)
{
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct snd_ipc4_nhlt *entry;

if (!hda_use_tplg_nhlt)
intel_nhlt_free(ipc4_data->nhlt);
if (!hda_use_tplg_nhlt) {
entry = list_first_entry(&ipc4_data->nhlt_list,
struct snd_ipc4_nhlt, list);
intel_nhlt_free(entry->nhlt);
list_del(&entry->list);
}

kfree(sdev->private);
sdev->private = NULL;
Expand Down
1 change: 1 addition & 0 deletions sound/soc/sof/ipc4-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ static size_t sof_ipc4_fw_parse_basefw_ext_man(struct snd_sof_dev *sdev)
ssize_t payload_offset;
int ret;

INIT_LIST_HEAD(&ipc4_data->nhlt_list);
if (sdev->dsp_test_mode_enabled)
fw_lib = devm_kzalloc(sdev->dev, sizeof(*fw_lib), GFP_KERNEL);
else
Expand Down
9 changes: 7 additions & 2 deletions sound/soc/sof/ipc4-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ struct sof_ipc4_fw_library {
struct sof_ipc4_fw_module *modules;
};

struct snd_ipc4_nhlt {
struct list_head list;
void *nhlt;
};

/**
* struct sof_ipc4_fw_data - IPC4-specific data
* @manifest_fw_hdr_offset: FW header offset in the manifest
* @fw_lib_xa: XArray for firmware libraries, including basefw (ID = 0)
* Used to store the FW libraries and to manage the unique IDs of the
* libraries.
* @nhlt: NHLT table either from the BIOS or the topology manifest
* @mtrace_type: mtrace type supported on the booted platform
* @mtrace_log_bytes: log bytes as reported by the firmware via fw_config reply
* @num_playback_streams: max number of playback DMAs, needed for CHAIN_DMA offset
Expand All @@ -74,14 +78,14 @@ struct sof_ipc4_fw_library {
* base firmware
* @fw_context_save: Firmware supports full context save and restore
* @libraries_restored: The libraries have been retained during firmware boot
* @nhlt_list: The NHLT tables from the BIOS and the topology manifest
*
* @load_library: Callback function for platform dependent library loading
* @pipeline_state_mutex: Mutex to protect pipeline triggers, ref counts, states and deletion
*/
struct sof_ipc4_fw_data {
u32 manifest_fw_hdr_offset;
struct xarray fw_lib_xa;
void *nhlt;
enum sof_ipc4_mtrace_type mtrace_type;
u32 mtrace_log_bytes;
int num_playback_streams;
Expand All @@ -90,6 +94,7 @@ struct sof_ipc4_fw_data {
u32 max_libs_count;
bool fw_context_save;
bool libraries_restored;
struct list_head nhlt_list;

int (*load_library)(struct snd_sof_dev *sdev,
struct sof_ipc4_fw_library *fw_lib, bool reload);
Expand Down
64 changes: 45 additions & 19 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -1752,6 +1752,7 @@ snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai
u32 linktype, u8 dir, u32 **dst, u32 *len)
{
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct snd_ipc4_nhlt *entry = NULL;
struct nhlt_specific_cfg *cfg;
int sample_rate, channel_count;
bool format_change = false;
Expand Down Expand Up @@ -1788,10 +1789,17 @@ snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai
* Query the type for the port and then pass that information back
* to the blob lookup function.
*/
dev_type = intel_nhlt_ssp_device_type(sdev->dev, ipc4_data->nhlt,
dai_index);
if (dev_type < 0)
list_for_each_entry(entry, &ipc4_data->nhlt_list, list) {
dev_type = intel_nhlt_ssp_device_type(sdev->dev, entry->nhlt,
dai_index);
if (dev_type >= 0)
break;
}
if (dev_type < 0) {
dev_err(sdev->dev, "%s: No match for SSP%d in NHLT table\n",
__func__, dai_index);
return dev_type;
}
break;
default:
return 0;
Expand All @@ -1801,9 +1809,20 @@ snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai
dai_index, nhlt_type, dir, dev_type);

/* find NHLT blob with matching params */
cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type,
bit_depth, bit_depth, channel_count, sample_rate,
dir, dev_type);
if (entry) {
cfg = intel_nhlt_get_endpoint_blob(sdev->dev, entry->nhlt, dai_index, nhlt_type,
bit_depth, bit_depth, channel_count,
sample_rate, dir, dev_type);
} else {
list_for_each_entry(entry, &ipc4_data->nhlt_list, list) {
cfg = intel_nhlt_get_endpoint_blob(sdev->dev, entry->nhlt, dai_index,
nhlt_type, bit_depth, bit_depth,
channel_count, sample_rate, dir,
dev_type);
Comment thread
ranj063 marked this conversation as resolved.
if (cfg)
break;
}
}

if (!cfg) {
bool get_new_blob = false;
Expand Down Expand Up @@ -1837,13 +1856,15 @@ snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai
}

if (get_new_blob) {
cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt,
dai_index, nhlt_type,
bit_depth, bit_depth,
channel_count, sample_rate,
dir, dev_type);
if (cfg)
goto out;
list_for_each_entry(entry, &ipc4_data->nhlt_list, list) {
cfg = intel_nhlt_get_endpoint_blob(sdev->dev, entry->nhlt,
dai_index, nhlt_type,
bit_depth, bit_depth,
channel_count, sample_rate,
dir, dev_type);
if (cfg)
goto out;
}
}

dev_err(sdev->dev,
Expand Down Expand Up @@ -3747,13 +3768,18 @@ static int sof_ipc4_parse_manifest(struct snd_soc_component *scomp, int index,

switch (le32_to_cpu(manifest_tlv->type)) {
case SOF_MANIFEST_DATA_TYPE_NHLT:
/* no NHLT in BIOS, so use the one from topology manifest */
if (ipc4_data->nhlt)
break;
ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data,
le32_to_cpu(manifest_tlv->size), GFP_KERNEL);
if (!ipc4_data->nhlt)
struct snd_ipc4_nhlt *tplg_nhlt;
Comment thread
ranj063 marked this conversation as resolved.

/* Get the nhlt from topology manifest*/
tplg_nhlt = devm_kzalloc(sdev->dev, sizeof(*tplg_nhlt), GFP_KERNEL);
if (!tplg_nhlt)
return -ENOMEM;

tplg_nhlt->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data,
le32_to_cpu(manifest_tlv->size), GFP_KERNEL);

list_add(&tplg_nhlt->list, &ipc4_data->nhlt_list);

break;
default:
dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n",
Expand Down