diff --git a/src/drivers/intel/baytrail/ipc.c b/src/drivers/intel/baytrail/ipc.c index f4643f05a2fb..189555c44bba 100644 --- a/src/drivers/intel/baytrail/ipc.c +++ b/src/drivers/intel/baytrail/ipc.c @@ -55,9 +55,6 @@ static void do_notify(void) /* clear DONE bit - tell Host we have completed */ shim_write(SHIM_IPCDH, shim_read(SHIM_IPCDH) & ~SHIM_IPCDH_DONE); - - /* unmask Done interrupt */ - shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DONE); } static void irq_handler(void *arg) @@ -150,6 +147,9 @@ void ipc_platform_send_msg(struct ipc *ipc) ipc->shared_ctx->dsp_msg = msg; tracev_ipc("ipc: msg tx -> 0x%x", msg->header); + /* Unmask Done interrupts first to receive ack */ + shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DONE); + /* now interrupt host to tell it we have message sent */ shim_write(SHIM_IPCDL, msg->header); shim_write(SHIM_IPCDH, SHIM_IPCDH_BUSY); @@ -202,9 +202,10 @@ int platform_ipc_init(struct ipc *ipc) interrupt_register(PLATFORM_IPC_INTERRUPT, irq_handler, ipc); interrupt_enable(PLATFORM_IPC_INTERRUPT, ipc); - /* Unmask Busy and Done interrupts */ + /* Unmask Busy and mask Done interrupts */ imrd = shim_read(SHIM_IMRD); - imrd &= ~(SHIM_IMRD_BUSY | SHIM_IMRD_DONE); + imrd &= ~SHIM_IMRD_BUSY; + imrd |= SHIM_IMRD_DONE; shim_write(SHIM_IMRD, imrd); return 0; diff --git a/src/drivers/intel/haswell/ipc.c b/src/drivers/intel/haswell/ipc.c index 97365a9233b9..8b590a662c38 100644 --- a/src/drivers/intel/haswell/ipc.c +++ b/src/drivers/intel/haswell/ipc.c @@ -55,9 +55,6 @@ static void do_notify(void) /* clear DONE bit - tell Host we have completed */ shim_write(SHIM_IPCD, 0); - - /* unmask Done interrupt */ - shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DONE); } static void irq_handler(void *arg) @@ -70,7 +67,7 @@ static void irq_handler(void *arg) tracev_ipc("ipc: irq isr 0x%x", isr); - if (isr & SHIM_ISRD_DONE) { + if (isr & SHIM_ISRD_DONE && !(imrd & SHIM_IMRD_DONE)) { /* Mask Done interrupt before return */ shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) | SHIM_IMRD_DONE); @@ -141,6 +138,9 @@ void ipc_platform_send_msg(struct ipc *ipc) ipc->shared_ctx->dsp_msg = msg; tracev_ipc("ipc: msg tx -> 0x%x", msg->header); + /* Unmask Done interrupts first to receive ack */ + shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DONE); + /* now interrupt host to tell it we have message sent */ shim_write(SHIM_IPCD, SHIM_IPCD_BUSY); @@ -192,9 +192,10 @@ int platform_ipc_init(struct ipc *ipc) interrupt_register(PLATFORM_IPC_INTERRUPT, irq_handler, ipc); interrupt_enable(PLATFORM_IPC_INTERRUPT, ipc); - /* Unmask Busy and Done interrupts */ + /* Unmask Busy and mask Done interrupts */ imrd = shim_read(SHIM_IMRD); - imrd &= ~(SHIM_IMRD_BUSY | SHIM_IMRD_DONE); + imrd &= ~SHIM_IMRD_BUSY; + imrd |= SHIM_IMRD_DONE; shim_write(SHIM_IMRD, imrd); return 0; diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index d14072bd79c0..66eefd6ae170 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -135,6 +135,9 @@ int platform_boot_complete(uint32_t boot_message) mailbox_dspbox_write(sizeof(ready), &sram_window, sram_window.ext_hdr.hdr.size); + /* Unmask Done interrupts first to receive ack */ + shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DONE); + /* now interrupt host to tell it we are done booting */ shim_write(SHIM_IPCDL, SOF_IPC_FW_READY | outbox); shim_write(SHIM_IPCDH, SHIM_IPCDH_BUSY); diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c index 0fcf3d08fc55..d700d2ebc8b5 100644 --- a/src/platform/haswell/platform.c +++ b/src/platform/haswell/platform.c @@ -131,6 +131,9 @@ int platform_boot_complete(uint32_t boot_message) mailbox_dspbox_write(sizeof(ready), &sram_window, sram_window.ext_hdr.hdr.size); + /* Unmask Done interrupts first to receive ack */ + shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DONE); + /* now interrupt host to tell it we are done booting */ shim_write(SHIM_IPCD, outbox | SHIM_IPCD_BUSY);