diff options
Diffstat (limited to 'sound/soc/intel/sst-haswell-ipc.c')
-rw-r--r-- | sound/soc/intel/sst-haswell-ipc.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 434236343ddf..b6291516dbbf 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c | |||
@@ -183,7 +183,7 @@ struct sst_hsw_ipc_fw_ready { | |||
183 | u32 inbox_size; | 183 | u32 inbox_size; |
184 | u32 outbox_size; | 184 | u32 outbox_size; |
185 | u32 fw_info_size; | 185 | u32 fw_info_size; |
186 | u8 fw_info[1]; | 186 | u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)]; |
187 | } __attribute__((packed)); | 187 | } __attribute__((packed)); |
188 | 188 | ||
189 | struct ipc_message { | 189 | struct ipc_message { |
@@ -457,9 +457,10 @@ static void ipc_tx_msgs(struct kthread_work *work) | |||
457 | return; | 457 | return; |
458 | } | 458 | } |
459 | 459 | ||
460 | /* if the DSP is busy we will TX messages after IRQ */ | 460 | /* if the DSP is busy, we will TX messages after IRQ. |
461 | * also postpone if we are in the middle of procesing completion irq*/ | ||
461 | ipcx = sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX); | 462 | ipcx = sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX); |
462 | if (ipcx & SST_IPCX_BUSY) { | 463 | if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) { |
463 | spin_unlock_irqrestore(&hsw->dsp->spinlock, flags); | 464 | spin_unlock_irqrestore(&hsw->dsp->spinlock, flags); |
464 | return; | 465 | return; |
465 | } | 466 | } |
@@ -502,6 +503,7 @@ static int tx_wait_done(struct sst_hsw *hsw, struct ipc_message *msg, | |||
502 | ipc_shim_dbg(hsw, "message timeout"); | 503 | ipc_shim_dbg(hsw, "message timeout"); |
503 | 504 | ||
504 | trace_ipc_error("error message timeout for", msg->header); | 505 | trace_ipc_error("error message timeout for", msg->header); |
506 | list_del(&msg->list); | ||
505 | ret = -ETIMEDOUT; | 507 | ret = -ETIMEDOUT; |
506 | } else { | 508 | } else { |
507 | 509 | ||
@@ -569,6 +571,9 @@ static void hsw_fw_ready(struct sst_hsw *hsw, u32 header) | |||
569 | { | 571 | { |
570 | struct sst_hsw_ipc_fw_ready fw_ready; | 572 | struct sst_hsw_ipc_fw_ready fw_ready; |
571 | u32 offset; | 573 | u32 offset; |
574 | u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)]; | ||
575 | char *tmp[5], *pinfo; | ||
576 | int i = 0; | ||
572 | 577 | ||
573 | offset = (header & 0x1FFFFFFF) << 3; | 578 | offset = (header & 0x1FFFFFFF) << 3; |
574 | 579 | ||
@@ -589,6 +594,19 @@ static void hsw_fw_ready(struct sst_hsw *hsw, u32 header) | |||
589 | fw_ready.inbox_offset, fw_ready.inbox_size); | 594 | fw_ready.inbox_offset, fw_ready.inbox_size); |
590 | dev_dbg(hsw->dev, " mailbox downstream 0x%x - size 0x%x\n", | 595 | dev_dbg(hsw->dev, " mailbox downstream 0x%x - size 0x%x\n", |
591 | fw_ready.outbox_offset, fw_ready.outbox_size); | 596 | fw_ready.outbox_offset, fw_ready.outbox_size); |
597 | if (fw_ready.fw_info_size < sizeof(fw_ready.fw_info)) { | ||
598 | fw_ready.fw_info[fw_ready.fw_info_size] = 0; | ||
599 | dev_dbg(hsw->dev, " Firmware info: %s \n", fw_ready.fw_info); | ||
600 | |||
601 | /* log the FW version info got from the mailbox here. */ | ||
602 | memcpy(fw_info, fw_ready.fw_info, fw_ready.fw_info_size); | ||
603 | pinfo = &fw_info[0]; | ||
604 | for (i = 0; i < sizeof(tmp) / sizeof(char *); i++) | ||
605 | tmp[i] = strsep(&pinfo, " "); | ||
606 | dev_info(hsw->dev, "FW loaded, mailbox readback FW info: type %s, - " | ||
607 | "version: %s.%s, build %s, source commit id: %s\n", | ||
608 | tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]); | ||
609 | } | ||
592 | } | 610 | } |
593 | 611 | ||
594 | static void hsw_notification_work(struct work_struct *work) | 612 | static void hsw_notification_work(struct work_struct *work) |
@@ -671,7 +689,9 @@ static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) | |||
671 | switch (stream_msg) { | 689 | switch (stream_msg) { |
672 | case IPC_STR_STAGE_MESSAGE: | 690 | case IPC_STR_STAGE_MESSAGE: |
673 | case IPC_STR_NOTIFICATION: | 691 | case IPC_STR_NOTIFICATION: |
692 | break; | ||
674 | case IPC_STR_RESET: | 693 | case IPC_STR_RESET: |
694 | trace_ipc_notification("stream reset", stream->reply.stream_hw_id); | ||
675 | break; | 695 | break; |
676 | case IPC_STR_PAUSE: | 696 | case IPC_STR_PAUSE: |
677 | stream->running = false; | 697 | stream->running = false; |
@@ -762,7 +782,8 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header) | |||
762 | } | 782 | } |
763 | 783 | ||
764 | /* update any stream states */ | 784 | /* update any stream states */ |
765 | hsw_stream_update(hsw, msg); | 785 | if (msg_get_global_type(header) == IPC_GLB_STREAM_MESSAGE) |
786 | hsw_stream_update(hsw, msg); | ||
766 | 787 | ||
767 | /* wake up and return the error if we have waiters on this message ? */ | 788 | /* wake up and return the error if we have waiters on this message ? */ |
768 | list_del(&msg->list); | 789 | list_del(&msg->list); |
@@ -1628,7 +1649,7 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw, | |||
1628 | enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx) | 1649 | enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx) |
1629 | { | 1650 | { |
1630 | u32 header, state_; | 1651 | u32 header, state_; |
1631 | int ret; | 1652 | int ret, item; |
1632 | 1653 | ||
1633 | header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE); | 1654 | header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE); |
1634 | state_ = state; | 1655 | state_ = state; |
@@ -1642,6 +1663,13 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw, | |||
1642 | return ret; | 1663 | return ret; |
1643 | } | 1664 | } |
1644 | 1665 | ||
1666 | for (item = 0; item < dx->entries_no; item++) { | ||
1667 | dev_dbg(hsw->dev, | ||
1668 | "Item[%d] offset[%x] - size[%x] - source[%x]\n", | ||
1669 | item, dx->mem_info[item].offset, | ||
1670 | dx->mem_info[item].size, | ||
1671 | dx->mem_info[item].source); | ||
1672 | } | ||
1645 | dev_dbg(hsw->dev, "ipc: got %d entry numbers for state %d\n", | 1673 | dev_dbg(hsw->dev, "ipc: got %d entry numbers for state %d\n", |
1646 | dx->entries_no, state); | 1674 | dx->entries_no, state); |
1647 | 1675 | ||
@@ -1775,8 +1803,6 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) | |||
1775 | 1803 | ||
1776 | /* get the FW version */ | 1804 | /* get the FW version */ |
1777 | sst_hsw_fw_get_version(hsw, &version); | 1805 | sst_hsw_fw_get_version(hsw, &version); |
1778 | dev_info(hsw->dev, "FW loaded: type %d - version: %d.%d build %d\n", | ||
1779 | version.type, version.major, version.minor, version.build); | ||
1780 | 1806 | ||
1781 | /* get the globalmixer */ | 1807 | /* get the globalmixer */ |
1782 | ret = sst_hsw_mixer_get_info(hsw); | 1808 | ret = sst_hsw_mixer_get_info(hsw); |