Skip to content

Commit 9969562

Browse files
committed
arch: microblaze: CPU Idling/Power Management
Internal references: FWRIVERHD-4978 Signed-off-by: Alp Sayin <alpsayin@gmail.com>
1 parent b72e339 commit 9969562

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

arch/microblaze/core/cpu_idle.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2023 Advanced Micro Devices, Inc. (AMD)
3+
* Copyright (c) 2023 Alp Sayin <alpsayin@gmail.com>
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
9+
#include <zephyr/irq.h>
10+
#include <zephyr/tracing/tracing.h>
11+
12+
static ALWAYS_INLINE void microblaze_idle(unsigned int key)
13+
{
14+
sys_trace_idle();
15+
16+
/* wait for interrupt */
17+
#if defined(CONFIG_MICROBLAZE_IDLE_SLEEP)
18+
{
19+
__asm__ __volatile__("sleep\t");
20+
}
21+
#elif defined(CONFIG_MICROBLAZE_IDLE_HIBERNATE)
22+
{
23+
__asm__ __volatile__("hibernate\t");
24+
}
25+
#elif defined(CONFIG_MICROBLAZE_IDLE_SUSPEND)
26+
{
27+
__asm__ __volatile__("suspend\t");
28+
}
29+
#elif defined(CONFIG_MICROBLAZE_IDLE_NOP)
30+
{
31+
__asm__ __volatile__("nop\t");
32+
}
33+
#endif
34+
/* unlock interrupts */
35+
irq_unlock(key);
36+
}
37+
38+
void arch_cpu_idle(void)
39+
{
40+
microblaze_idle(1);
41+
}
42+
43+
void arch_cpu_atomic_idle(unsigned int key)
44+
{
45+
microblaze_idle(key);
46+
}
47+
48+
/**
49+
* @brief Defined weak so SoCs/Boards with timers can override.
50+
* This is an approximate busy wait implementation that executes
51+
* a number of NOPs to obtain an approximate of the desired delay.
52+
*
53+
* @param usec_to_wait
54+
*/
55+
static void ALWAYS_INLINE arch_busy_wait_1ms(void)
56+
{
57+
#define LOOP_LIMIT (427ULL * 200000000ULL / CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)
58+
for (uint64_t counter = 0; counter < LOOP_LIMIT; counter++) {
59+
arch_nop();
60+
}
61+
}
62+
63+
__weak void arch_busy_wait(uint32_t usec_to_wait)
64+
{
65+
for (uint32_t msecs = 0; msecs < usec_to_wait / USEC_PER_MSEC; msecs++) {
66+
arch_busy_wait_1ms();
67+
}
68+
}

0 commit comments

Comments
 (0)