Skip to content

Commit 90d736c

Browse files
authored
Merge pull request #220 from tlauda/topic/idc_send_blocking
idc: allow to send blocking messages to cores
2 parents a1af7ff + 332aac8 commit 90d736c

7 files changed

Lines changed: 46 additions & 10 deletions

File tree

  • src
    • arch/xtensa
    • platform
      • apollolake/include/platform
      • baytrail/include/platform
      • cannonlake/include/platform
      • haswell/include/platform

src/arch/xtensa/smp/cpu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ void arch_cpu_enable_core(int id)
6262
idc_enable_interrupts(id, arch_cpu_get_id());
6363

6464
/* send IDC power up message */
65-
arch_idc_send_msg(&power_up);
65+
arch_idc_send_msg(&power_up, IDC_NON_BLOCKING);
6666

6767
active_cores_mask |= (1 << id);
6868
}
@@ -78,7 +78,7 @@ void arch_cpu_disable_core(int id)
7878
spin_lock_irq(&lock, flags);
7979

8080
if (active_cores_mask & (1 << id)) {
81-
arch_idc_send_msg(&power_down);
81+
arch_idc_send_msg(&power_down, IDC_NON_BLOCKING);
8282

8383
active_cores_mask ^= (1 << id);
8484
}

src/arch/xtensa/smp/include/arch/idc.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@
5555
#define trace_idc_error(__e) trace_error(TRACE_CLASS_IDC, __e)
5656

5757

58+
/** \brief IDC send blocking flag. */
59+
#define IDC_BLOCKING 0
60+
61+
/** \brief IDC send non-blocking flag. */
62+
#define IDC_NON_BLOCKING 1
63+
64+
/** \brief IDC send timeout in cycles. */
65+
#define IDC_TIMEOUT 800000
66+
5867
/** \brief ROM wake version parsed by ROM during core wake up. */
5968
#define IDC_ROM_WAKE_VERSION 0x2
6069

@@ -165,11 +174,16 @@ static void idc_irq_handler(void *arg)
165174
/**
166175
* \brief Sends IDC message.
167176
* \param[in,out] msg Pointer to IDC message.
177+
* \param[in] mode Is message blocking or not.
178+
* \return Error code.
168179
*/
169-
static inline void arch_idc_send_msg(struct idc_msg *msg)
180+
static inline int arch_idc_send_msg(struct idc_msg *msg, uint32_t mode)
170181
{
171182
struct idc *idc = *idc_get();
172183
int core = arch_cpu_get_id();
184+
int ret = 0;
185+
uint32_t timeout = 0;
186+
uint32_t idcietc;
173187
uint32_t flags;
174188

175189
tracev_idc("Msg");
@@ -179,7 +193,23 @@ static inline void arch_idc_send_msg(struct idc_msg *msg)
179193
idc_write(IPC_IDCIETC(msg->core), core, msg->extension);
180194
idc_write(IPC_IDCITC(msg->core), core, msg->header | IPC_IDCITC_BUSY);
181195

196+
if (mode == IDC_BLOCKING) {
197+
do {
198+
idelay(PLATFORM_DEFAULT_DELAY);
199+
timeout += PLATFORM_DEFAULT_DELAY;
200+
idcietc = idc_read(IPC_IDCIETC(msg->core), core);
201+
} while (!(idcietc & IPC_IDCIETC_DONE) &&
202+
timeout < IDC_TIMEOUT);
203+
204+
if (timeout >= IDC_TIMEOUT) {
205+
trace_idc_error("eS0");
206+
ret = -ETIME;
207+
}
208+
}
209+
182210
spin_unlock_irq(&idc->lock, flags);
211+
212+
return ret;
183213
}
184214

185215
/**

src/arch/xtensa/up/include/arch/idc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ struct idc_msg;
4141

4242
/**
4343
* \brief Sends IDC message.
44+
* \param[in,out] msg Pointer to IDC message.
45+
* \param[in] mode Is message blocking or not.
46+
* \return Error code.
4447
*/
45-
static inline void arch_idc_send_msg(struct idc_msg *msg) { }
48+
static inline int arch_idc_send_msg(struct idc_msg *msg,
49+
uint32_t mode) { return 0; }
4650

4751
/**
4852
* \brief Checks for pending IDC messages.

src/platform/apollolake/include/platform/idc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333

3434
#include <arch/idc.h>
3535

36-
static inline void idc_send_msg(struct idc_msg *msg)
36+
static inline int idc_send_msg(struct idc_msg *msg, uint32_t mode)
3737
{
38-
arch_idc_send_msg(msg);
38+
return arch_idc_send_msg(msg, mode);
3939
}
4040

4141
static inline void idc_process_msg_queue(void)

src/platform/baytrail/include/platform/idc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333

3434
struct idc_msg;
3535

36-
static inline void idc_send_msg(struct idc_msg *msg) { }
36+
static inline int idc_send_msg(struct idc_msg *msg,
37+
uint32_t mode) { return 0; }
3738

3839
static inline void idc_process_msg_queue(void) { }
3940

src/platform/cannonlake/include/platform/idc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333

3434
#include <arch/idc.h>
3535

36-
static inline void idc_send_msg(struct idc_msg *msg)
36+
static inline int idc_send_msg(struct idc_msg *msg, uint32_t mode)
3737
{
38-
arch_idc_send_msg(msg);
38+
return arch_idc_send_msg(msg, mode);
3939
}
4040

4141
static inline void idc_process_msg_queue(void)

src/platform/haswell/include/platform/idc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333

3434
struct idc_msg;
3535

36-
static inline void idc_send_msg(struct idc_msg *msg) { }
36+
static inline int idc_send_msg(struct idc_msg *msg,
37+
uint32_t mode) { return 0; }
3738

3839
static inline void idc_process_msg_queue(void) { }
3940

0 commit comments

Comments
 (0)