Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
58 changes: 46 additions & 12 deletions src/audio/module_adapter/module/dolby/dax.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ SOF_DEFINE_REG_UUID(dolby_dax_audio_processing);
#define DAX_CP_MASK 0x8
#define DAX_VOLUME_MASK 0x10
#define DAX_CTC_MASK 0x20
#define DAX_TUNING_FILE_MASK 0x40
#define DAX_PROCESSING_MASK 0x10000
#define DAX_RESET_MASK 0x20000
#define DAX_FREE_MASK 0x40000
Expand Down Expand Up @@ -241,24 +242,27 @@ static bool is_enabled(struct processing_module *mod)
return dax_ctx->enable && dax_ctx->p_dax;
}

static int set_tuning_file(struct processing_module *mod, void *value, uint32_t size)
static int set_tuning_file(struct processing_module *mod)
{
int ret = 0;
int ret = -EINVAL;
struct comp_dev *dev = mod->dev;
struct dax_adapter_data *adapter_data = module_get_private_data(mod);
struct sof_dax *dax_ctx = &adapter_data->dax_ctx;
struct dax_buffer old_tuning_buf = {0};
k_spinlock_key_t key;

if (dax_buffer_alloc(mod, &dax_ctx->tuning_file_buffer, size) != 0) {
comp_err(dev, "allocate %u bytes failed for tuning file", size);
ret = -ENOMEM;
} else {
memcpy_s(dax_ctx->tuning_file_buffer.addr,
dax_ctx->tuning_file_buffer.free,
value,
size);
key = k_spin_lock(&adapter_data->lock);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you're implicitly using the fact, that this function only runs in IPC context, when its priority is lower than the processing function? Although IIRC you also support running in DP mode, not sure this priority promise will also always hold for that case. So I suppose you'd need to take the lock in the critical part of the processing function too - where this tuning buffer is used there.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, and I agree we should not rely on an IPC-priority assumption, especially with DP mode in mind.

Also, the active buffer (dax_ctx->tuning_file_buffer) is only switched from the processing path (check_and_update_settings() -> set_tuning_file()), so we do not need to lock the other parts of the processing function.

I think I should add a lock in dax_set_param_wrapper as well to prevent access to same tuning buffer object.

if (adapter_data->cache_tuning_buf.addr && adapter_data->cache_tuning_buf.size > 0) {
old_tuning_buf = dax_ctx->tuning_file_buffer;
dax_ctx->tuning_file_buffer = adapter_data->cache_tuning_buf;
adapter_data->cache_tuning_buf = (struct dax_buffer){0};
ret = 0;
}
k_spin_unlock(&adapter_data->lock, key);

dax_buffer_release(mod, &old_tuning_buf);

comp_info(dev, "allocated: tuning %u, ret %d", dax_ctx->tuning_file_buffer.size, ret);
comp_info(dev, "apply tuning %p, ret %d", dax_ctx->tuning_file_buffer.addr, ret);
return ret;
}

Expand Down Expand Up @@ -363,11 +367,33 @@ static int dax_set_param_wrapper(struct processing_module *mod,
struct comp_dev *dev = mod->dev;
struct dax_adapter_data *adapter_data = module_get_private_data(mod);
struct sof_dax *dax_ctx = &adapter_data->dax_ctx;
struct dax_buffer new_tuning_buf = { 0 };
struct dax_buffer old_tuning_buf = { 0 };
k_spinlock_key_t key;
int32_t tmp_val;

switch (id) {
case DAX_PARAM_ID_TUNING_FILE:
set_tuning_file(mod, value, size);
ret = dax_buffer_alloc(mod, &new_tuning_buf, size);
if (ret != 0) {
comp_err(dev, "allocate %u bytes failed for tuning file, ret %d", size,
ret);
break;
}
ret = memcpy_s(new_tuning_buf.addr, new_tuning_buf.free, value, size);
if (ret != 0) {
comp_err(dev, "copy tuning file failed, ret %d", ret);
dax_buffer_release(mod, &new_tuning_buf);
break;
}
key = k_spin_lock(&adapter_data->lock);
old_tuning_buf = adapter_data->cache_tuning_buf;
adapter_data->cache_tuning_buf = new_tuning_buf;
k_spin_unlock(&adapter_data->lock, key);
dax_buffer_release(mod, &old_tuning_buf);
flag_process(adapter_data, DAX_TUNING_FILE_MASK, DAX_FLAG_SET);
comp_info(dev, "allocated: tuning %p, size %u", new_tuning_buf.addr,
new_tuning_buf.size);
break;
case DAX_PARAM_ID_ENABLE:
tmp_val = *((int32_t *)value);
Expand Down Expand Up @@ -488,6 +514,12 @@ static void check_and_update_settings(struct processing_module *mod)
if (!is_enabled(mod))
return;

if (flag_process(adapter_data, DAX_TUNING_FILE_MASK, DAX_FLAG_READ_AND_CLEAR)) {
set_tuning_file(mod);
flag_process(adapter_data, DAX_DEVICE_MASK, DAX_FLAG_SET);
flag_process(adapter_data, DAX_VOLUME_MASK, DAX_FLAG_SET);
}

if (flag_process(adapter_data, DAX_DEVICE_MASK, DAX_FLAG_READ_AND_CLEAR)) {
set_device(mod, dax_ctx->out_device);
set_tuning_device(mod, dax_ctx->tuning_device);
Expand Down Expand Up @@ -547,6 +579,7 @@ static int sof_dax_free(struct processing_module *mod)
dax_buffer_release(mod, &dax_ctx->tuning_file_buffer);
mod_data_blob_handler_free(mod, dax_ctx->blob_handler);
dax_ctx->blob_handler = NULL;
dax_buffer_release(mod, &adapter_data->cache_tuning_buf);
mod_free(mod, adapter_data);
module_set_private_data(mod, NULL);
}
Expand Down Expand Up @@ -584,6 +617,7 @@ static int sof_dax_init(struct processing_module *mod)
adapter_data = module_get_private_data(mod);
adapter_data->comp_id = dev->ipc_config.id;
adapter_data->priority = DAX_USER_PRIORITY_DEFAULT;
k_spinlock_init(&adapter_data->lock);
dax_ctx = &adapter_data->dax_ctx;
dax_ctx->enable = 0;
dax_ctx->profile = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/audio/module_adapter/module/dolby/dax.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Author: Jun Lai <jun.lai@dolby.com>
*/

#include <rtos/spinlock.h>
#include <sof/audio/module_adapter/module/generic.h>
#include <dax_inf.h>

Expand All @@ -24,6 +25,8 @@ struct dax_adapter_data {
atomic_t proc_flags;
uint32_t comp_id;
int32_t priority;
struct dax_buffer cache_tuning_buf;
struct k_spinlock lock;
};

/**
Expand Down
4 changes: 3 additions & 1 deletion src/audio/module_adapter/module/dolby/dax_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ uint32_t dax_query_period_frames(struct sof_dax *dax_ctx)

int dax_free(struct sof_dax *dax_ctx)
{
dax_ctx->p_dax = NULL;
return 0;
}

int dax_init(struct sof_dax *dax_ctx)
{
dax_ctx->p_dax = dax_ctx->persist_buffer.addr;
return 0;
}

Expand Down Expand Up @@ -81,7 +83,7 @@ int dax_set_ctc_enable(int32_t enable, struct sof_dax *dax_ctx)

const char *dax_get_version(void)
{
return "";
return "mock_version";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does C guarantee that this string is allocated in some permanent section and not on stack?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, string literals are guaranteed to have static storage duration in C.

}

void *dax_find_params(uint32_t query_id,
Expand Down
Loading