1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2018 Intel Corporation. All rights reserved. 4 * 5 * Author: Tomasz Lauda <tomasz.lauda@linux.intel.com> 6 */ 7 8 /** 9 * \file include/sof/drivers/idc.h 10 * \brief IDC header file 11 * \authors Tomasz Lauda <tomasz.lauda@linux.intel.com> 12 */ 13 14 #ifndef __SOF_DRIVERS_IDC_H__ 15 #define __SOF_DRIVERS_IDC_H__ 16 17 #include <arch/drivers/idc.h> 18 #include <platform/drivers/idc.h> 19 #include <sof/schedule/task.h> 20 #include <sof/trace/trace.h> 21 #include <user/trace.h> 22 #include <stdint.h> 23 24 /** \brief IDC send blocking flag. */ 25 #define IDC_BLOCKING 0 26 27 /** \brief IDC send non-blocking flag. */ 28 #define IDC_NON_BLOCKING 1 29 30 /** \brief IDC send core power up flag. */ 31 #define IDC_POWER_UP 2 32 33 /** \brief IDC send core power down flag. */ 34 #define IDC_POWER_DOWN 3 35 36 /** \brief IDC send timeout in microseconds. */ 37 #define IDC_TIMEOUT 10000 38 39 /** \brief IDC task deadline. */ 40 #define IDC_DEADLINE 100 41 42 /** \brief ROM wake version parsed by ROM during core wake up. */ 43 #define IDC_ROM_WAKE_VERSION 0x2 44 45 /** \brief IDC message type. */ 46 #define IDC_TYPE_SHIFT 24 47 #define IDC_TYPE_MASK 0x7f 48 #define IDC_TYPE(x) (((x) & IDC_TYPE_MASK) << IDC_TYPE_SHIFT) 49 50 /** \brief IDC message header. */ 51 #define IDC_HEADER_MASK 0xffffff 52 #define IDC_HEADER(x) ((x) & IDC_HEADER_MASK) 53 54 /** \brief IDC message extension. */ 55 #define IDC_EXTENSION_MASK 0x3fffffff 56 #define IDC_EXTENSION(x) ((x) & IDC_EXTENSION_MASK) 57 58 /** \brief IDC power up message. */ 59 #define IDC_MSG_POWER_UP (IDC_TYPE(0x1) | \ 60 IDC_HEADER(IDC_ROM_WAKE_VERSION)) 61 #define IDC_MSG_POWER_UP_EXT IDC_EXTENSION(SOF_TEXT_START >> 2) 62 63 /** \brief IDC power down message. */ 64 #define IDC_MSG_POWER_DOWN IDC_TYPE(0x2) 65 #define IDC_MSG_POWER_DOWN_EXT IDC_EXTENSION(0x0) 66 67 /** \brief IDC notify message. */ 68 #define IDC_MSG_NOTIFY IDC_TYPE(0x3) 69 #define IDC_MSG_NOTIFY_EXT IDC_EXTENSION(0x0) 70 71 /** \brief IDC IPC processing message. */ 72 #define IDC_MSG_IPC IDC_TYPE(0x4) 73 #define IDC_MSG_IPC_EXT IDC_EXTENSION(0x0) 74 75 /** \brief IDC component params message. */ 76 #define IDC_MSG_PARAMS IDC_TYPE(0x5) 77 #define IDC_MSG_PARAMS_EXT(x) IDC_EXTENSION(x) 78 79 /** \brief IDC component prepare message. */ 80 #define IDC_MSG_PREPARE IDC_TYPE(0x6) 81 #define IDC_MSG_PREPARE_EXT(x) IDC_EXTENSION(x) 82 83 /** \brief IDC component trigger message. */ 84 #define IDC_MSG_TRIGGER IDC_TYPE(0x7) 85 #define IDC_MSG_TRIGGER_EXT(x) IDC_EXTENSION(x) 86 87 /** \brief IDC component reset message. */ 88 #define IDC_MSG_RESET IDC_TYPE(0x8) 89 #define IDC_MSG_RESET_EXT(x) IDC_EXTENSION(x) 90 91 /** \brief Decodes IDC message type. */ 92 #define iTS(x) (((x) >> IDC_TYPE_SHIFT) & IDC_TYPE_MASK) 93 94 /** \brief Max IDC message payload size in bytes. */ 95 #define IDC_MAX_PAYLOAD_SIZE 96 96 97 /** \brief IDC message payload. */ 98 struct idc_payload { 99 uint8_t data[IDC_MAX_PAYLOAD_SIZE]; 100 }; 101 102 /** \brief IDC message. */ 103 struct idc_msg { 104 uint32_t header; /**< header value */ 105 uint32_t extension; /**< extension value */ 106 uint32_t core; /**< core id */ 107 uint32_t size; /**< payload size in bytes */ 108 void *payload; /**< pointer to payload data */ 109 }; 110 111 /** \brief IDC data. */ 112 struct idc { 113 uint32_t busy_bit_mask; /**< busy interrupt mask */ 114 struct idc_msg received_msg; /**< received message */ 115 struct task idc_task; /**< IDC processing task */ 116 struct idc_payload *payload; 117 int irq; 118 }; 119 120 /* idc trace context, used by multiple units */ 121 extern struct tr_ctx idc_tr; 122 idc_payload_get(struct idc * idc,uint32_t core)123static inline struct idc_payload *idc_payload_get(struct idc *idc, 124 uint32_t core) 125 { 126 return idc->payload + core; 127 } 128 129 void idc_enable_interrupts(int target_core, int source_core); 130 131 void idc_free(void); 132 133 int platform_idc_init(void); 134 135 enum task_state idc_do_cmd(void *data); 136 137 void idc_cmd(struct idc_msg *msg); 138 139 int idc_wait_in_blocking_mode(uint32_t target_core, bool (*cond)(int)); 140 141 int idc_msg_status_get(uint32_t core); 142 143 void idc_init_thread(void); 144 145 #endif /* __SOF_DRIVERS_IDC_H__ */ 146