diff --git a/src/drivers/intel/cavs/idc.c b/src/drivers/intel/cavs/idc.c index e34535d7b..72f7b0d65 100644 --- a/src/drivers/intel/cavs/idc.c +++ b/src/drivers/intel/cavs/idc.c @@ -243,6 +243,39 @@ int platform_idc_init(void) return 0; } +/** + * \brief Restores IDC interrupt. During D0->D0ix/D0ix->D0 flow primary core + * disables all secondary cores - this is not cold boot process, because + * memory has not been powered off. In that case, we should only enable + * idc interrupts, because all required structures alreade exist. + */ +int platform_idc_restore(void) +{ + struct idc *idc = *idc_get(); + int core = cpu_get_id(); + int ret; + + idc->irq = interrupt_get_irq(PLATFORM_IDC_INTERRUPT, + PLATFORM_IDC_INTERRUPT_NAME); + if (idc->irq < 0) { + tr_err(&idc_tr, "platform_idc_restore(): getting irq failed."); + return idc->irq; + } + + ret = interrupt_register(idc->irq, idc_irq_handler, idc); + if (ret < 0) { + tr_err(&idc_tr, "platform_idc_restore(): registering irq failed."); + return ret; + } + + interrupt_enable(idc->irq, idc); + + /* enable BUSY interrupt */ + idc_write(IPC_IDCCTL, core, idc->busy_bit_mask); + + return 0; +} + /** * \brief Frees IDC data and unregisters interrupt. */ diff --git a/src/idc/idc.c b/src/idc/idc.c index 3e266526b..70dff21d5 100644 --- a/src/idc/idc.c +++ b/src/idc/idc.c @@ -352,3 +352,23 @@ int idc_init(void) return 0; #endif } + +int idc_restore(void) +{ + struct idc **idc = idc_get(); + + tr_info(&idc_tr, "idc_restore()"); + + /* idc_restore() is invoked during D0->D0ix/D0ix->D0 flow. In that + * case basic core structures e.g. idc struct should be already + * allocated (in D0->D0ix primary core disables all secondary cores, but + * memory has not been powered off). + */ + assert(*idc); + +#ifndef __ZEPHYR__ + return platform_idc_restore(); +#endif + + return 0; +} diff --git a/src/include/sof/drivers/idc.h b/src/include/sof/drivers/idc.h index 2074a7049..a1481ac61 100644 --- a/src/include/sof/drivers/idc.h +++ b/src/include/sof/drivers/idc.h @@ -132,6 +132,8 @@ void idc_free(void); int platform_idc_init(void); +int platform_idc_restore(void); + enum task_state idc_do_cmd(void *data); void idc_cmd(struct idc_msg *msg); diff --git a/src/platform/intel/cavs/include/cavs/drivers/idc.h b/src/platform/intel/cavs/include/cavs/drivers/idc.h index 9242450bd..11d30d7f4 100644 --- a/src/platform/intel/cavs/include/cavs/drivers/idc.h +++ b/src/platform/intel/cavs/include/cavs/drivers/idc.h @@ -20,6 +20,8 @@ int idc_send_msg(struct idc_msg *msg, uint32_t mode); int idc_init(void); +int idc_restore(void); + #else static inline int idc_send_msg(struct idc_msg *msg, uint32_t mode) { return 0; } diff --git a/src/platform/library/include/platform/drivers/idc.h b/src/platform/library/include/platform/drivers/idc.h index 9732796cb..977b4c008 100644 --- a/src/platform/library/include/platform/drivers/idc.h +++ b/src/platform/library/include/platform/drivers/idc.h @@ -28,6 +28,11 @@ static inline int idc_init(void) return 0; } +static inline int idc_restore(void) +{ + return 0; +} + #endif /* __PLATFORM_DRIVERS_IDC_H__ */ #else