embox

Форк
0
119 строк · 2.4 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @date 10.05.2020
6
 * @author Alexander Kalmuk
7
 */
8

9
#include <assert.h>
10
#include <hw_cache.h>
11
#include <hw_otpc.h>
12
#include <hw_rtc.h>
13
#include <hw_sys.h>
14
#include <hw_watchdog.h>
15
#include <string.h>
16
#include <sys_clock_mgr.h>
17
#include <sys_power_mgr.h>
18
#include <time.h>
19

20
#include <arm/fpu.h>
21
#include <framework/mod/options.h>
22
#include <hal/cpu_idle.h>
23
#include <hal/clock.h>
24
#include <hal/reg.h>
25
#include <kernel/irq.h>
26
#include <kernel/time/clock_source.h>
27
#include <kernel/time/time.h>
28
#include <util/log.h>
29

30
#include <config/custom_config_qspi.h>
31

32
extern const struct clock_source *cs_jiffies;
33

34
static void switch_jiffies_to(int freq) {
35
	struct clock_source *cs = (struct clock_source *)cs_jiffies;
36
	struct time_counter_device *cd = cs->counter_device;
37

38
	cd->cycle_hz = freq;
39

40
	clock_source_set_periodic(cs, clock_freq());
41
}
42

43
void clk_update_hook(void) {
44
	static uint16_t cur_clk = 1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Pos;
45
	uint16_t clk;
46

47
#define FREQ_MASK                                            \
48
	((1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Pos)       \
49
	    | (1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Pos)   \
50
	    | (1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Pos) \
51
	    | (1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Pos))
52

53
	clk = CRG_TOP->CLK_CTRL_REG & FREQ_MASK;
54

55
	switch (clk) {
56
	case (1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Pos):
57
		if (cur_clk != clk) {
58
			switch_jiffies_to(32000000);
59
		}
60
		break;
61
	case (1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Pos):
62
		if (cur_clk != clk) {
63
			switch_jiffies_to(96000000);
64
		}
65
		break;
66
	case (1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Pos):
67
	case (1 << CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Pos):
68
	default:
69
		break;
70
	}
71

72
	cur_clk = clk;
73

74
#undef FREQ_MASK
75
}
76

77
extern int deepsleep_enter(void);
78

79
static uint32_t arch_deepsleep_flags = 0;
80

81
void arch_deepsleep_disable(uint32_t mask) {
82
	ipl_t ipl;
83

84
	ipl = ipl_save();
85
	arch_deepsleep_flags |= mask;
86
	ipl_restore(ipl);
87
}
88

89
void arch_deepsleep_enable(uint32_t mask) {
90
	ipl_t ipl;
91

92
	ipl = ipl_save();
93
	{ arch_deepsleep_flags &= ~mask; }
94
	ipl_restore(ipl);
95
}
96

97
static uint32_t arch_deepsleep_start(ipl_t *ipl) {
98
	*ipl = ipl_save();
99

100
	return arch_deepsleep_flags;
101
}
102

103
static void arch_deepsleep_finish(ipl_t ipl) {
104
	ipl_restore(ipl);
105
}
106

107
void arch_cpu_idle(void) {
108
	ipl_t ipl;
109

110
	clk_update_hook();
111

112
	if (arch_deepsleep_start(&ipl)) {
113
		__asm__ __volatile__("wfi");
114
	}
115
	else {
116
		deepsleep_enter();
117
	}
118
	arch_deepsleep_finish(ipl);
119
}
120

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.