Commit abf31fee authored by Cezary Rojewski's avatar Cezary Rojewski Committed by Mark Brown

ASoC: Intel: Update request-reply IPC model

struct ipc_message contains fields: header, tx_data and tx_size which
represent TX i.e. request while RX is represented by rx_data and rx_size
with reply's header equivalent missing.

Reply header may contain some vital information including, but not
limited to, received payload size. Some IPCs have entire payload found
within RX header instead. Content and value of said header is context
dependent and may vary between firmware versions and target platform.
Current model does not allow such IPCs to function at all.

Rather than appending yet another parameter to an already long list of
such for sst_ipc_tx_message_XXXs, declare message container in form of
struct sst_ipc_message and add them to parent's ipc_message declaration.

Align haswell, baytrail and skylake with updated request-reply model and
modify their reply processing functions to save RX header within message
container. Despite the range of changes, status quo is achieved.
Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20190723144341.21339-2-cezary.rojewski@intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent b8ba3b57
...@@ -211,7 +211,7 @@ static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt, ...@@ -211,7 +211,7 @@ static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg) static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
{ {
struct sst_byt_stream *stream; struct sst_byt_stream *stream;
u64 header = msg->header; u64 header = msg->tx.header;
u8 stream_id = sst_byt_header_str_id(header); u8 stream_id = sst_byt_header_str_id(header);
u8 stream_msg = sst_byt_header_msg_id(header); u8 stream_msg = sst_byt_header_msg_id(header);
...@@ -240,9 +240,10 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header) ...@@ -240,9 +240,10 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
if (msg == NULL) if (msg == NULL)
return 1; return 1;
msg->rx.header = header;
if (header & IPC_HEADER_LARGE(true)) { if (header & IPC_HEADER_LARGE(true)) {
msg->rx_size = sst_byt_header_data(header); msg->rx.size = sst_byt_header_data(header);
sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size); sst_dsp_inbox_read(byt->dsp, msg->rx.data, msg->rx.size);
} }
/* update any stream states */ /* update any stream states */
...@@ -407,17 +408,18 @@ int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream, ...@@ -407,17 +408,18 @@ int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream) int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
{ {
struct sst_byt_alloc_params *str_req = &stream->request; struct sst_ipc_message request, reply = {0};
struct sst_byt_alloc_response *reply = &stream->reply;
u64 header;
int ret; int ret;
header = sst_byt_header(IPC_IA_ALLOC_STREAM, request.header = sst_byt_header(IPC_IA_ALLOC_STREAM,
sizeof(*str_req) + sizeof(u32), sizeof(stream->request) + sizeof(u32),
true, stream->str_id); true, stream->str_id);
ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req, request.data = &stream->request;
sizeof(*str_req), request.size = sizeof(stream->request);
reply, sizeof(*reply)); reply.data = &stream->reply;
reply.size = sizeof(stream->reply);
ret = sst_ipc_tx_message_wait(&byt->ipc, request, &reply);
if (ret < 0) { if (ret < 0) {
dev_err(byt->dev, "ipc: error stream commit failed\n"); dev_err(byt->dev, "ipc: error stream commit failed\n");
return ret; return ret;
...@@ -430,7 +432,7 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream) ...@@ -430,7 +432,7 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
{ {
u64 header; struct sst_ipc_message request = {0};
int ret = 0; int ret = 0;
struct sst_dsp *sst = byt->dsp; struct sst_dsp *sst = byt->dsp;
unsigned long flags; unsigned long flags;
...@@ -438,8 +440,9 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) ...@@ -438,8 +440,9 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
if (!stream->commited) if (!stream->commited)
goto out; goto out;
header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id); request.header = sst_byt_header(IPC_IA_FREE_STREAM,
ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0); 0, false, stream->str_id);
ret = sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(byt->dev, "ipc: free stream %d failed\n", dev_err(byt->dev, "ipc: free stream %d failed\n",
stream->str_id); stream->str_id);
...@@ -459,15 +462,13 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) ...@@ -459,15 +462,13 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
static int sst_byt_stream_operations(struct sst_byt *byt, int type, static int sst_byt_stream_operations(struct sst_byt *byt, int type,
int stream_id, int wait) int stream_id, int wait)
{ {
u64 header; struct sst_ipc_message request = {0};
header = sst_byt_header(type, 0, false, stream_id); request.header = sst_byt_header(type, 0, false, stream_id);
if (wait) if (wait)
return sst_ipc_tx_message_wait(&byt->ipc, header, NULL, return sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
0, NULL, 0);
else else
return sst_ipc_tx_message_nowait(&byt->ipc, header, return sst_ipc_tx_message_nowait(&byt->ipc, request);
NULL, 0);
} }
/* stream ALSA trigger operations */ /* stream ALSA trigger operations */
...@@ -475,19 +476,17 @@ int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream, ...@@ -475,19 +476,17 @@ int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
u32 start_offset) u32 start_offset)
{ {
struct sst_byt_start_stream_params start_stream; struct sst_byt_start_stream_params start_stream;
void *tx_msg; struct sst_ipc_message request;
size_t size;
u64 header;
int ret; int ret;
start_stream.byte_offset = start_offset; start_stream.byte_offset = start_offset;
header = sst_byt_header(IPC_IA_START_STREAM, request.header = sst_byt_header(IPC_IA_START_STREAM,
sizeof(start_stream) + sizeof(u32), sizeof(start_stream) + sizeof(u32),
true, stream->str_id); true, stream->str_id);
tx_msg = &start_stream; request.data = &start_stream;
size = sizeof(start_stream); request.size = sizeof(start_stream);
ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size); ret = sst_ipc_tx_message_nowait(&byt->ipc, request);
if (ret < 0) if (ret < 0)
dev_err(byt->dev, "ipc: error failed to start stream %d\n", dev_err(byt->dev, "ipc: error failed to start stream %d\n",
stream->str_id); stream->str_id);
...@@ -623,10 +622,10 @@ EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready); ...@@ -623,10 +622,10 @@ EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready);
static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{ {
if (msg->header & IPC_HEADER_LARGE(true)) if (msg->tx.header & IPC_HEADER_LARGE(true))
sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header); sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->tx.header);
} }
static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text) static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
...@@ -648,9 +647,9 @@ static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data, ...@@ -648,9 +647,9 @@ static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size) size_t tx_size)
{ {
/* msg content = lower 32-bit of the header + data */ /* msg content = lower 32-bit of the header + data */
*(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1); *(u32 *)msg->tx.data = (u32)(msg->tx.header & (u32)-1);
memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size); memcpy(msg->tx.data + sizeof(u32), tx_data, tx_size);
msg->tx_size += sizeof(u32); msg->tx.size += sizeof(u32);
} }
static u64 byt_reply_msg_match(u64 header, u64 *mask) static u64 byt_reply_msg_match(u64 header, u64 *mask)
......
...@@ -43,7 +43,7 @@ static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc) ...@@ -43,7 +43,7 @@ static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc)
} }
static int tx_wait_done(struct sst_generic_ipc *ipc, static int tx_wait_done(struct sst_generic_ipc *ipc,
struct ipc_message *msg, void *rx_data) struct ipc_message *msg, struct sst_ipc_message *reply)
{ {
unsigned long flags; unsigned long flags;
int ret; int ret;
...@@ -62,8 +62,11 @@ static int tx_wait_done(struct sst_generic_ipc *ipc, ...@@ -62,8 +62,11 @@ static int tx_wait_done(struct sst_generic_ipc *ipc,
} else { } else {
/* copy the data returned from DSP */ /* copy the data returned from DSP */
if (rx_data) if (reply) {
memcpy(rx_data, msg->rx_data, msg->rx_size); reply->header = msg->rx.header;
if (reply->data)
memcpy(reply->data, msg->rx.data, msg->rx.size);
}
ret = msg->errno; ret = msg->errno;
} }
...@@ -72,9 +75,9 @@ static int tx_wait_done(struct sst_generic_ipc *ipc, ...@@ -72,9 +75,9 @@ static int tx_wait_done(struct sst_generic_ipc *ipc,
return ret; return ret;
} }
static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, static int ipc_tx_message(struct sst_generic_ipc *ipc,
void *tx_data, size_t tx_bytes, void *rx_data, struct sst_ipc_message request,
size_t rx_bytes, int wait) struct sst_ipc_message *reply, int wait)
{ {
struct ipc_message *msg; struct ipc_message *msg;
unsigned long flags; unsigned long flags;
...@@ -87,23 +90,24 @@ static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, ...@@ -87,23 +90,24 @@ static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
return -EBUSY; return -EBUSY;
} }
msg->header = header; msg->tx.header = request.header;
msg->tx_size = tx_bytes; msg->tx.size = request.size;
msg->rx_size = rx_bytes; msg->rx.header = 0;
msg->rx.size = reply ? reply->size : 0;
msg->wait = wait; msg->wait = wait;
msg->errno = 0; msg->errno = 0;
msg->pending = false; msg->pending = false;
msg->complete = false; msg->complete = false;
if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL)) if ((request.size) && (ipc->ops.tx_data_copy != NULL))
ipc->ops.tx_data_copy(msg, tx_data, tx_bytes); ipc->ops.tx_data_copy(msg, request.data, request.size);
list_add_tail(&msg->list, &ipc->tx_list); list_add_tail(&msg->list, &ipc->tx_list);
schedule_work(&ipc->kwork); schedule_work(&ipc->kwork);
spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
if (wait) if (wait)
return tx_wait_done(ipc, msg, rx_data); return tx_wait_done(ipc, msg, reply);
else else
return 0; return 0;
} }
...@@ -118,13 +122,13 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) ...@@ -118,13 +122,13 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL);
if (ipc->msg[i].tx_data == NULL) if (ipc->msg[i].tx.data == NULL)
goto free_mem; goto free_mem;
ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL);
if (ipc->msg[i].rx_data == NULL) { if (ipc->msg[i].rx.data == NULL) {
kfree(ipc->msg[i].tx_data); kfree(ipc->msg[i].tx.data);
goto free_mem; goto free_mem;
} }
...@@ -136,8 +140,8 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) ...@@ -136,8 +140,8 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc)
free_mem: free_mem:
while (i > 0) { while (i > 0) {
kfree(ipc->msg[i-1].tx_data); kfree(ipc->msg[i-1].tx.data);
kfree(ipc->msg[i-1].rx_data); kfree(ipc->msg[i-1].rx.data);
--i; --i;
} }
kfree(ipc->msg); kfree(ipc->msg);
...@@ -173,8 +177,8 @@ static void ipc_tx_msgs(struct work_struct *work) ...@@ -173,8 +177,8 @@ static void ipc_tx_msgs(struct work_struct *work)
spin_unlock_irq(&ipc->dsp->spinlock); spin_unlock_irq(&ipc->dsp->spinlock);
} }
int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) struct sst_ipc_message request, struct sst_ipc_message *reply)
{ {
int ret; int ret;
...@@ -187,8 +191,7 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, ...@@ -187,8 +191,7 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) if (ipc->ops.check_dsp_lp_on(ipc->dsp, true))
return -EIO; return -EIO;
ret = ipc_tx_message(ipc, header, tx_data, tx_bytes, ret = ipc_tx_message(ipc, request, reply, 1);
rx_data, rx_bytes, 1);
if (ipc->ops.check_dsp_lp_on) if (ipc->ops.check_dsp_lp_on)
if (ipc->ops.check_dsp_lp_on(ipc->dsp, false)) if (ipc->ops.check_dsp_lp_on(ipc->dsp, false))
...@@ -198,19 +201,17 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, ...@@ -198,19 +201,17 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
} }
EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait); EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait);
int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
void *tx_data, size_t tx_bytes) struct sst_ipc_message request)
{ {
return ipc_tx_message(ipc, header, tx_data, tx_bytes, return ipc_tx_message(ipc, request, NULL, 0);
NULL, 0, 0);
} }
EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait); EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait);
int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header, int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) struct sst_ipc_message request, struct sst_ipc_message *reply)
{ {
return ipc_tx_message(ipc, header, tx_data, tx_bytes, return ipc_tx_message(ipc, request, reply, 1);
rx_data, rx_bytes, 1);
} }
EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm); EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm);
...@@ -230,7 +231,7 @@ struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, ...@@ -230,7 +231,7 @@ struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
} }
list_for_each_entry(msg, &ipc->rx_list, list) { list_for_each_entry(msg, &ipc->rx_list, list) {
if ((msg->header & mask) == header) if ((msg->tx.header & mask) == header)
return msg; return msg;
} }
...@@ -304,8 +305,8 @@ void sst_ipc_fini(struct sst_generic_ipc *ipc) ...@@ -304,8 +305,8 @@ void sst_ipc_fini(struct sst_generic_ipc *ipc)
if (ipc->msg) { if (ipc->msg) {
for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
kfree(ipc->msg[i].tx_data); kfree(ipc->msg[i].tx.data);
kfree(ipc->msg[i].rx_data); kfree(ipc->msg[i].rx.data);
} }
kfree(ipc->msg); kfree(ipc->msg);
} }
......
...@@ -17,15 +17,16 @@ ...@@ -17,15 +17,16 @@
#define IPC_MAX_MAILBOX_BYTES 256 #define IPC_MAX_MAILBOX_BYTES 256
struct ipc_message { struct sst_ipc_message {
struct list_head list;
u64 header; u64 header;
void *data;
size_t size;
};
/* direction wrt host CPU */ struct ipc_message {
char *tx_data; struct list_head list;
size_t tx_size; struct sst_ipc_message tx;
char *rx_data; struct sst_ipc_message rx;
size_t rx_size;
wait_queue_head_t waitq; wait_queue_head_t waitq;
bool pending; bool pending;
...@@ -66,14 +67,14 @@ struct sst_generic_ipc { ...@@ -66,14 +67,14 @@ struct sst_generic_ipc {
struct sst_plat_ipc_ops ops; struct sst_plat_ipc_ops ops;
}; };
int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); struct sst_ipc_message request, struct sst_ipc_message *reply);
int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
void *tx_data, size_t tx_bytes); struct sst_ipc_message request);
int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header, int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); struct sst_ipc_message request, struct sst_ipc_message *reply);
struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
u64 header); u64 header);
......
...@@ -511,7 +511,7 @@ static void hsw_notification_work(struct work_struct *work) ...@@ -511,7 +511,7 @@ static void hsw_notification_work(struct work_struct *work)
static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
{ {
struct sst_hsw_stream *stream; struct sst_hsw_stream *stream;
u32 header = msg->header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK); u32 header = msg->tx.header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
u32 stream_id = msg_get_stream_id(header); u32 stream_id = msg_get_stream_id(header);
u32 stream_msg = msg_get_stream_type(header); u32 stream_msg = msg_get_stream_type(header);
...@@ -552,6 +552,7 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header) ...@@ -552,6 +552,7 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
return -EIO; return -EIO;
} }
msg->rx.header = header;
/* first process the header */ /* first process the header */
switch (reply) { switch (reply) {
case IPC_GLB_REPLY_PENDING: case IPC_GLB_REPLY_PENDING:
...@@ -562,13 +563,13 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header) ...@@ -562,13 +563,13 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
case IPC_GLB_REPLY_SUCCESS: case IPC_GLB_REPLY_SUCCESS:
if (msg->pending) { if (msg->pending) {
trace_ipc_pending_reply("completed", header); trace_ipc_pending_reply("completed", header);
sst_dsp_inbox_read(hsw->dsp, msg->rx_data, sst_dsp_inbox_read(hsw->dsp, msg->rx.data,
msg->rx_size); msg->rx.size);
hsw->ipc.pending = false; hsw->ipc.pending = false;
} else { } else {
/* copy data from the DSP */ /* copy data from the DSP */
sst_dsp_outbox_read(hsw->dsp, msg->rx_data, sst_dsp_outbox_read(hsw->dsp, msg->rx.data,
msg->rx_size); msg->rx.size);
} }
break; break;
/* these will be rare - but useful for debug */ /* these will be rare - but useful for debug */
...@@ -810,11 +811,13 @@ static irqreturn_t hsw_irq_thread(int irq, void *context) ...@@ -810,11 +811,13 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
int sst_hsw_fw_get_version(struct sst_hsw *hsw, int sst_hsw_fw_get_version(struct sst_hsw *hsw,
struct sst_hsw_ipc_fw_version *version) struct sst_hsw_ipc_fw_version *version)
{ {
struct sst_ipc_message request = {0}, reply = {0};
int ret; int ret;
ret = sst_ipc_tx_message_wait(&hsw->ipc, request.header = IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION);
IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION), reply.data = version;
NULL, 0, version, sizeof(*version)); reply.size = sizeof(*version);
ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
if (ret < 0) if (ret < 0)
dev_err(hsw->dev, "error: get version failed\n"); dev_err(hsw->dev, "error: get version failed\n");
...@@ -840,7 +843,7 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, ...@@ -840,7 +843,7 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume)
{ {
struct sst_hsw_ipc_volume_req *req; struct sst_hsw_ipc_volume_req *req;
u32 header; struct sst_ipc_message request;
int ret; int ret;
trace_ipc_request("set stream volume", stream->reply.stream_hw_id); trace_ipc_request("set stream volume", stream->reply.stream_hw_id);
...@@ -848,11 +851,11 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, ...@@ -848,11 +851,11 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL) if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL)
return -EINVAL; return -EINVAL;
header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); request.header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
header |= (stage_id << IPC_STG_ID_SHIFT); request.header |= (stage_id << IPC_STG_ID_SHIFT);
req = &stream->vol_req; req = &stream->vol_req;
req->target_volume = volume; req->target_volume = volume;
...@@ -877,8 +880,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, ...@@ -877,8 +880,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
req->channel = channel; req->channel = channel;
} }
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req, request.data = req;
sizeof(*req), NULL, 0); request.size = sizeof(*req);
ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(hsw->dev, "error: set stream volume failed\n"); dev_err(hsw->dev, "error: set stream volume failed\n");
return ret; return ret;
...@@ -905,7 +909,7 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, ...@@ -905,7 +909,7 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
u32 volume) u32 volume)
{ {
struct sst_hsw_ipc_volume_req req; struct sst_hsw_ipc_volume_req req;
u32 header; struct sst_ipc_message request;
int ret; int ret;
trace_ipc_request("set mixer volume", volume); trace_ipc_request("set mixer volume", volume);
...@@ -933,18 +937,19 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, ...@@ -933,18 +937,19 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
req.channel = channel; req.channel = channel;
} }
header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT); request.header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT);
header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
header |= (stage_id << IPC_STG_ID_SHIFT); request.header |= (stage_id << IPC_STG_ID_SHIFT);
req.curve_duration = hsw->curve_duration; req.curve_duration = hsw->curve_duration;
req.curve_type = hsw->curve_type; req.curve_type = hsw->curve_type;
req.target_volume = volume; req.target_volume = volume;
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req, request.data = &req;
sizeof(req), NULL, 0); request.size = sizeof(req);
ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(hsw->dev, "error: set mixer volume failed\n"); dev_err(hsw->dev, "error: set mixer volume failed\n");
return ret; return ret;
...@@ -983,7 +988,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, ...@@ -983,7 +988,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
{ {
u32 header; struct sst_ipc_message request;
int ret = 0; int ret = 0;
struct sst_dsp *sst = hsw->dsp; struct sst_dsp *sst = hsw->dsp;
unsigned long flags; unsigned long flags;
...@@ -1000,10 +1005,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) ...@@ -1000,10 +1005,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
trace_ipc_request("stream free", stream->host_id); trace_ipc_request("stream free", stream->host_id);
stream->free_req.stream_id = stream->reply.stream_hw_id; stream->free_req.stream_id = stream->reply.stream_hw_id;
header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM); request.header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
request.data = &stream->free_req;
request.size = sizeof(stream->free_req);
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &stream->free_req, ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
sizeof(stream->free_req), NULL, 0);
if (ret < 0) { if (ret < 0) {
dev_err(hsw->dev, "error: free stream %d failed\n", dev_err(hsw->dev, "error: free stream %d failed\n",
stream->free_req.stream_id); stream->free_req.stream_id);
...@@ -1175,9 +1181,7 @@ int sst_hsw_stream_set_module_info(struct sst_hsw *hsw, ...@@ -1175,9 +1181,7 @@ int sst_hsw_stream_set_module_info(struct sst_hsw *hsw,
int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
{ {
struct sst_hsw_ipc_stream_alloc_req *str_req = &stream->request; struct sst_ipc_message request, reply = {0};
struct sst_hsw_ipc_stream_alloc_reply *reply = &stream->reply;
u32 header;
int ret; int ret;
if (!stream) { if (!stream) {
...@@ -1192,10 +1196,13 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) ...@@ -1192,10 +1196,13 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
trace_ipc_request("stream alloc", stream->host_id); trace_ipc_request("stream alloc", stream->host_id);
header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); request.header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
request.data = &stream->request;
request.size = sizeof(stream->request);
reply.data = &stream->reply;
reply.size = sizeof(stream->reply);
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, str_req, ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
sizeof(*str_req), reply, sizeof(*reply));
if (ret < 0) { if (ret < 0) {
dev_err(hsw->dev, "error: stream commit failed\n"); dev_err(hsw->dev, "error: stream commit failed\n");
return ret; return ret;
...@@ -1235,23 +1242,22 @@ void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw, ...@@ -1235,23 +1242,22 @@ void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw,
ABI to be opaque to client PCM drivers to cope with any future ABI changes */ ABI to be opaque to client PCM drivers to cope with any future ABI changes */
int sst_hsw_mixer_get_info(struct sst_hsw *hsw) int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
{ {
struct sst_hsw_ipc_stream_info_reply *reply; struct sst_ipc_message request = {0}, reply = {0};
u32 header;
int ret; int ret;
reply = &hsw->mixer_info; request.header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO);
header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO); reply.data = &hsw->mixer_info;
reply.size = sizeof(hsw->mixer_info);
trace_ipc_request("get global mixer info", 0); trace_ipc_request("get global mixer info", 0);
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
reply, sizeof(*reply));
if (ret < 0) { if (ret < 0) {
dev_err(hsw->dev, "error: get stream info failed\n"); dev_err(hsw->dev, "error: get stream info failed\n");
return ret; return ret;
} }
trace_hsw_mixer_info_reply(reply); trace_hsw_mixer_info_reply(&hsw->mixer_info);
return 0; return 0;
} }
...@@ -1260,16 +1266,15 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw) ...@@ -1260,16 +1266,15 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type, static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type,
int stream_id, int wait) int stream_id, int wait)
{ {
u32 header; struct sst_ipc_message request = {0};
header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | IPC_STR_TYPE(type); request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE);
header |= (stream_id << IPC_STR_ID_SHIFT); request.header |= IPC_STR_TYPE(type) | (stream_id << IPC_STR_ID_SHIFT);
if (wait) if (wait)
return sst_ipc_tx_message_wait(&hsw->ipc, header, return sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
NULL, 0, NULL, 0);
else else
return sst_ipc_tx_message_nowait(&hsw->ipc, header, NULL, 0); return sst_ipc_tx_message_nowait(&hsw->ipc, request);
} }
/* Stream ALSA trigger operations */ /* Stream ALSA trigger operations */
...@@ -1377,8 +1382,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw, ...@@ -1377,8 +1382,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
enum sst_hsw_device_mode mode, u32 clock_divider) enum sst_hsw_device_mode mode, u32 clock_divider)
{ {
struct sst_ipc_message request;
struct sst_hsw_ipc_device_config_req config; struct sst_hsw_ipc_device_config_req config;
u32 header;
int ret; int ret;
trace_ipc_request("set device config", dev); trace_ipc_request("set device config", dev);
...@@ -1394,10 +1399,11 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw, ...@@ -1394,10 +1399,11 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
trace_hsw_device_config_req(&config); trace_hsw_device_config_req(&config);
header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS); request.header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
request.data = &config;
request.size = sizeof(config);
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &config, ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
sizeof(config), NULL, 0);
if (ret < 0) if (ret < 0)
dev_err(hsw->dev, "error: set device formats failed\n"); dev_err(hsw->dev, "error: set device formats failed\n");
...@@ -1409,16 +1415,20 @@ EXPORT_SYMBOL_GPL(sst_hsw_device_set_config); ...@@ -1409,16 +1415,20 @@ EXPORT_SYMBOL_GPL(sst_hsw_device_set_config);
int sst_hsw_dx_set_state(struct sst_hsw *hsw, int sst_hsw_dx_set_state(struct sst_hsw *hsw,
enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx) enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx)
{ {
u32 header, state_; struct sst_ipc_message request, reply = {0};
u32 state_;
int ret, item; int ret, item;
header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
state_ = state; state_ = state;
request.header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
request.data = &state_;
request.size = sizeof(state_);
reply.data = dx;
reply.size = sizeof(*dx);
trace_ipc_request("PM enter Dx state", state); trace_ipc_request("PM enter Dx state", state);
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_, ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
sizeof(state_), dx, sizeof(*dx));
if (ret < 0) { if (ret < 0) {
dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
return ret; return ret;
...@@ -1878,7 +1888,7 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, ...@@ -1878,7 +1888,7 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
u32 module_id, u32 instance_id) u32 module_id, u32 instance_id)
{ {
int ret; int ret;
u32 header = 0; struct sst_ipc_message request;
struct sst_hsw_ipc_module_config config; struct sst_hsw_ipc_module_config config;
struct sst_module *module; struct sst_module *module;
struct sst_module_runtime *runtime; struct sst_module_runtime *runtime;
...@@ -1907,10 +1917,10 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, ...@@ -1907,10 +1917,10 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
return -ENXIO; return -ENXIO;
} }
header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) | IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) |
IPC_MODULE_ID(module_id); IPC_MODULE_ID(module_id);
dev_dbg(dev, "module enable header: %x\n", header); dev_dbg(dev, "module enable header: %x\n", (u32)request.header);
config.map.module_entries_count = 1; config.map.module_entries_count = 1;
config.map.module_entries[0].module_id = module->id; config.map.module_entries[0].module_id = module->id;
...@@ -1932,8 +1942,9 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, ...@@ -1932,8 +1942,9 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
config.scratch_mem.size, config.scratch_mem.offset, config.scratch_mem.size, config.scratch_mem.offset,
config.map.module_entries[0].entry_point); config.map.module_entries[0].entry_point);
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, request.data = &config;
&config, sizeof(config), NULL, 0); request.size = sizeof(config);
ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0) if (ret < 0)
dev_err(dev, "ipc: module enable failed - %d\n", ret); dev_err(dev, "ipc: module enable failed - %d\n", ret);
else else
...@@ -1946,7 +1957,7 @@ int sst_hsw_module_disable(struct sst_hsw *hsw, ...@@ -1946,7 +1957,7 @@ int sst_hsw_module_disable(struct sst_hsw *hsw,
u32 module_id, u32 instance_id) u32 module_id, u32 instance_id)
{ {
int ret; int ret;
u32 header; struct sst_ipc_message request = {0};
struct sst_module *module; struct sst_module *module;
struct device *dev = hsw->dev; struct device *dev = hsw->dev;
struct sst_dsp *dsp = hsw->dsp; struct sst_dsp *dsp = hsw->dsp;
...@@ -1967,11 +1978,11 @@ int sst_hsw_module_disable(struct sst_hsw *hsw, ...@@ -1967,11 +1978,11 @@ int sst_hsw_module_disable(struct sst_hsw *hsw,
return -ENXIO; return -ENXIO;
} }
header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) | IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) |
IPC_MODULE_ID(module_id); IPC_MODULE_ID(module_id);
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0) if (ret < 0)
dev_err(dev, "module disable failed - %d\n", ret); dev_err(dev, "module disable failed - %d\n", ret);
else else
...@@ -1985,15 +1996,16 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw, ...@@ -1985,15 +1996,16 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
u32 param_size, char *param) u32 param_size, char *param)
{ {
int ret; int ret;
u32 header = 0; struct sst_ipc_message request = {0};
u32 payload_size = 0, transfer_parameter_size = 0; u32 payload_size = 0;
struct sst_hsw_transfer_parameter *parameter; struct sst_hsw_transfer_parameter *parameter;
struct device *dev = hsw->dev; struct device *dev = hsw->dev;
header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) | IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) |
IPC_MODULE_ID(module_id); IPC_MODULE_ID(module_id);
dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", header); dev_dbg(dev, "sst_hsw_module_set_param header=%x\n",
(u32)request.header);
payload_size = param_size + payload_size = param_size +
sizeof(struct sst_hsw_transfer_parameter) - sizeof(struct sst_hsw_transfer_parameter) -
...@@ -2003,14 +2015,14 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw, ...@@ -2003,14 +2015,14 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) { if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) {
/* short parameter, mailbox can contain data */ /* short parameter, mailbox can contain data */
dev_dbg(dev, "transfer parameter size : %d\n", dev_dbg(dev, "transfer parameter size : %lu\n",
transfer_parameter_size); request.size);
transfer_parameter_size = ALIGN(payload_size, 4); request.size = ALIGN(payload_size, 4);
dev_dbg(dev, "transfer parameter aligned size : %d\n", dev_dbg(dev, "transfer parameter aligned size : %lu\n",
transfer_parameter_size); request.size);
parameter = kzalloc(transfer_parameter_size, GFP_KERNEL); parameter = kzalloc(request.size, GFP_KERNEL);
if (parameter == NULL) if (parameter == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -2022,9 +2034,9 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw, ...@@ -2022,9 +2034,9 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
parameter->parameter_id = parameter_id; parameter->parameter_id = parameter_id;
parameter->data_size = param_size; parameter->data_size = param_size;
request.data = parameter;
ret = sst_ipc_tx_message_wait(&hsw->ipc, header, ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
parameter, transfer_parameter_size , NULL, 0);
if (ret < 0) if (ret < 0)
dev_err(dev, "ipc: module set parameter failed - %d\n", ret); dev_err(dev, "ipc: module set parameter failed - %d\n", ret);
...@@ -2041,8 +2053,8 @@ static struct sst_dsp_device hsw_dev = { ...@@ -2041,8 +2053,8 @@ static struct sst_dsp_device hsw_dev = {
static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{ {
/* send the message */ /* send the message */
sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
sst_dsp_ipc_msg_tx(ipc->dsp, msg->header); sst_dsp_ipc_msg_tx(ipc->dsp, msg->tx.header);
} }
static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text) static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
...@@ -2063,7 +2075,7 @@ static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text) ...@@ -2063,7 +2075,7 @@ static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data, static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size) size_t tx_size)
{ {
memcpy(msg->tx_data, tx_data, tx_size); memcpy(msg->tx.data, tx_data, tx_size);
} }
static u64 hsw_reply_msg_match(u64 header, u64 *mask) static u64 hsw_reply_msg_match(u64 header, u64 *mask)
......
...@@ -366,10 +366,10 @@ static struct sst_dsp_device cnl_dev = { ...@@ -366,10 +366,10 @@ static struct sst_dsp_device cnl_dev = {
static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{ {
struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
if (msg->tx_size) if (msg->tx.size)
sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD,
header->extension); header->extension);
sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR,
......
...@@ -281,7 +281,7 @@ void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, ...@@ -281,7 +281,7 @@ void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size) size_t tx_size)
{ {
if (tx_size) if (tx_size)
memcpy(msg->tx_data, tx_data, tx_size); memcpy(msg->tx.data, tx_data, tx_size);
} }
static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp) static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
...@@ -295,10 +295,10 @@ static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp) ...@@ -295,10 +295,10 @@ static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
/* Lock to be held by caller */ /* Lock to be held by caller */
static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{ {
struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
if (msg->tx_size) if (msg->tx.size)
sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE, sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE,
header->extension); header->extension);
sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI, sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI,
...@@ -447,11 +447,12 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc, ...@@ -447,11 +447,12 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
return; return;
} }
msg->rx.header = *ipc_header;
/* first process the header */ /* first process the header */
if (reply == IPC_GLB_REPLY_SUCCESS) { if (reply == IPC_GLB_REPLY_SUCCESS) {
dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
/* copy the rx data from the mailbox */ /* copy the rx data from the mailbox */
sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size);
switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
case IPC_GLB_LOAD_MULTIPLE_MODS: case IPC_GLB_LOAD_MULTIPLE_MODS:
case IPC_GLB_LOAD_LIBRARY: case IPC_GLB_LOAD_LIBRARY:
...@@ -635,7 +636,7 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc, ...@@ -635,7 +636,7 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode) u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
...@@ -646,9 +647,10 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc, ...@@ -646,9 +647,10 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size); header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
header.extension = IPC_PPL_LP_MODE(lp_mode); header.extension = IPC_PPL_LP_MODE(lp_mode);
request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret); dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
return ret; return ret;
...@@ -661,16 +663,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline); ...@@ -661,16 +663,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline);
int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL); header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
header.primary |= IPC_INSTANCE_ID(instance_id); header.primary |= IPC_INSTANCE_ID(instance_id);
request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret); dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
return ret; return ret;
...@@ -684,7 +687,7 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc, ...@@ -684,7 +687,7 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
u8 instance_id, enum skl_ipc_pipeline_state state) u8 instance_id, enum skl_ipc_pipeline_state state)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
...@@ -692,9 +695,10 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc, ...@@ -692,9 +695,10 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE); header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
header.primary |= IPC_INSTANCE_ID(instance_id); header.primary |= IPC_INSTANCE_ID(instance_id);
header.primary |= IPC_PPL_STATE(state); header.primary |= IPC_PPL_STATE(state);
request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret); dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
return ret; return ret;
...@@ -707,7 +711,7 @@ int ...@@ -707,7 +711,7 @@ int
skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
...@@ -716,8 +720,10 @@ skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) ...@@ -716,8 +720,10 @@ skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
header.primary |= IPC_INSTANCE_ID(instance_id); header.primary |= IPC_INSTANCE_ID(instance_id);
header.extension = IPC_DMA_ID(dma_id); header.extension = IPC_DMA_ID(dma_id);
request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret); dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
return ret; return ret;
...@@ -730,16 +736,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline); ...@@ -730,16 +736,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline);
int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL); header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
header.primary |= IPC_INSTANCE_ID(instance_id); header.primary |= IPC_INSTANCE_ID(instance_id);
request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret); dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret);
return ret; return ret;
...@@ -753,7 +760,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id, ...@@ -753,7 +760,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
u16 module_id, struct skl_ipc_dxstate_info *dx) u16 module_id, struct skl_ipc_dxstate_info *dx)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request;
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
...@@ -762,10 +769,13 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id, ...@@ -762,10 +769,13 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
header.primary |= IPC_MOD_INSTANCE_ID(instance_id); header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
header.primary |= IPC_MOD_ID(module_id); header.primary |= IPC_MOD_ID(module_id);
request.header = *(u64 *)(&header);
request.data = dx;
request.size = sizeof(*dx);
dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
header.primary, header.extension); header.primary, header.extension);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, ret = sst_ipc_tx_message_wait(ipc, request, NULL);
dx, sizeof(*dx), NULL, 0);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
return ret; return ret;
...@@ -779,7 +789,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc, ...@@ -779,7 +789,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
struct skl_ipc_init_instance_msg *msg, void *param_data) struct skl_ipc_init_instance_msg *msg, void *param_data)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request;
int ret; int ret;
u32 *buffer = (u32 *)param_data; u32 *buffer = (u32 *)param_data;
/* param_block_size must be in dwords */ /* param_block_size must be in dwords */
...@@ -799,10 +809,13 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc, ...@@ -799,10 +809,13 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
header.extension |= IPC_DOMAIN(msg->domain); header.extension |= IPC_DOMAIN(msg->domain);
request.header = *(u64 *)(&header);
request.data = param_data;
request.size = msg->param_data_size;
dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
header.primary, header.extension); header.primary, header.extension);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data, ret = sst_ipc_tx_message_wait(ipc, request, NULL);
msg->param_data_size, NULL, 0);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: init instance failed\n"); dev_err(ipc->dev, "ipc: init instance failed\n");
...@@ -817,7 +830,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, ...@@ -817,7 +830,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
struct skl_ipc_bind_unbind_msg *msg) struct skl_ipc_bind_unbind_msg *msg)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND; u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
int ret; int ret;
...@@ -831,10 +844,11 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, ...@@ -831,10 +844,11 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id); header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
header.extension |= IPC_DST_QUEUE(msg->dst_queue); header.extension |= IPC_DST_QUEUE(msg->dst_queue);
header.extension |= IPC_SRC_QUEUE(msg->src_queue); header.extension |= IPC_SRC_QUEUE(msg->src_queue);
request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary, dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
header.extension); header.extension);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, "ipc: bind/unbind failed\n"); dev_err(ipc->dev, "ipc: bind/unbind failed\n");
return ret; return ret;
...@@ -854,7 +868,7 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc, ...@@ -854,7 +868,7 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
u8 module_cnt, void *data) u8 module_cnt, void *data)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request;
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
...@@ -862,8 +876,11 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc, ...@@ -862,8 +876,11 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS); header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data, request.header = *(u64 *)(&header);
(sizeof(u16) * module_cnt)); request.data = data;
request.size = sizeof(u16) * module_cnt;
ret = sst_ipc_tx_message_nowait(ipc, request);
if (ret < 0) if (ret < 0)
dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret); dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
...@@ -875,7 +892,7 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt, ...@@ -875,7 +892,7 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
void *data) void *data)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request;
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
...@@ -883,8 +900,11 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt, ...@@ -883,8 +900,11 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS); header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data, request.header = *(u64 *)(&header);
(sizeof(u16) * module_cnt), NULL, 0); request.data = data;
request.size = sizeof(u16) * module_cnt;
ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) if (ret < 0)
dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret); dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
...@@ -896,7 +916,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, ...@@ -896,7 +916,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
struct skl_ipc_large_config_msg *msg, u32 *param) struct skl_ipc_large_config_msg *msg, u32 *param)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request;
int ret = 0; int ret = 0;
size_t sz_remaining, tx_size, data_offset; size_t sz_remaining, tx_size, data_offset;
...@@ -923,9 +943,11 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, ...@@ -923,9 +943,11 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
header.primary, header.extension); header.primary, header.extension);
dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n", dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
(unsigned)data_offset, (unsigned)tx_size); (unsigned)data_offset, (unsigned)tx_size);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
((char *)param) + data_offset, request.header = *(u64 *)(&header);
tx_size, NULL, 0); request.data = ((char *)param) + data_offset;
request.size = tx_size;
ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, dev_err(ipc->dev,
"ipc: set large config fail, err: %d\n", ret); "ipc: set large config fail, err: %d\n", ret);
...@@ -950,7 +972,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, ...@@ -950,7 +972,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
struct skl_ipc_large_config_msg *msg, u32 *param) struct skl_ipc_large_config_msg *msg, u32 *param)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0}, reply = {0};
int ret = 0; int ret = 0;
size_t sz_remaining, rx_size, data_offset; size_t sz_remaining, rx_size, data_offset;
...@@ -974,9 +996,10 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, ...@@ -974,9 +996,10 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
if (rx_size == sz_remaining) if (rx_size == sz_remaining)
header.extension |= IPC_FINAL_BLOCK(1); header.extension |= IPC_FINAL_BLOCK(1);
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, request.header = *(u64 *)(&header);
((char *)param) + data_offset, reply.data = ((char *)param) + data_offset;
msg->param_data_size); reply.size = msg->param_data_size;
ret = sst_ipc_tx_message_wait(ipc, request, &reply);
if (ret < 0) { if (ret < 0) {
dev_err(ipc->dev, dev_err(ipc->dev,
"ipc: get large config fail, err: %d\n", ret); "ipc: get large config fail, err: %d\n", ret);
...@@ -1001,7 +1024,7 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, ...@@ -1001,7 +1024,7 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
u8 dma_id, u8 table_id, bool wait) u8 dma_id, u8 table_id, bool wait)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
int ret = 0; int ret = 0;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
...@@ -1009,12 +1032,12 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, ...@@ -1009,12 +1032,12 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY); header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
header.primary |= IPC_MOD_INSTANCE_ID(table_id); header.primary |= IPC_MOD_INSTANCE_ID(table_id);
header.primary |= IPC_MOD_ID(dma_id); header.primary |= IPC_MOD_ID(dma_id);
request.header = *(u64 *)(&header);
if (wait) if (wait)
ret = sst_ipc_tx_message_wait(ipc, *ipc_header, ret = sst_ipc_tx_message_wait(ipc, request, NULL);
NULL, 0, NULL, 0);
else else
ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0); ret = sst_ipc_tx_message_nowait(ipc, request);
if (ret < 0) if (ret < 0)
dev_err(ipc->dev, "ipc: load lib failed\n"); dev_err(ipc->dev, "ipc: load lib failed\n");
...@@ -1026,7 +1049,7 @@ EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library); ...@@ -1026,7 +1049,7 @@ EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
{ {
struct skl_ipc_header header = {0}; struct skl_ipc_header header = {0};
u64 *ipc_header = (u64 *)(&header); struct sst_ipc_message request = {0};
int ret; int ret;
header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
...@@ -1037,6 +1060,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) ...@@ -1037,6 +1060,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
header.extension = IPC_D0IX_WAKE(msg->wake); header.extension = IPC_D0IX_WAKE(msg->wake);
header.extension |= IPC_D0IX_STREAMING(msg->streaming); header.extension |= IPC_D0IX_STREAMING(msg->streaming);
request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__, dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
header.primary, header.extension); header.primary, header.extension);
...@@ -1044,7 +1068,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) ...@@ -1044,7 +1068,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
/* /*
* Use the nopm IPC here as we dont want it checking for D0iX * Use the nopm IPC here as we dont want it checking for D0iX
*/ */
ret = sst_ipc_tx_message_nopm(ipc, *ipc_header, NULL, 0, NULL, 0); ret = sst_ipc_tx_message_nopm(ipc, request, NULL);
if (ret < 0) if (ret < 0)
dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret); dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment