13 #include "pwrmgr_regs.h"
28 (1u << (PWRMGR_CONTROL_CORE_CLK_EN_BIT -
29 PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
30 "Layout of control register changed.");
33 (1u << (PWRMGR_CONTROL_IO_CLK_EN_BIT -
34 PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
35 "Layout of control register changed.");
37 #if defined(OPENTITAN_IS_EARLGREY)
38 static_assert(kDifPwrmgrDomainOptionUsbClockInLowPower ==
39 (1u << (PWRMGR_CONTROL_USB_CLK_EN_LP_BIT -
40 PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
41 "Layout of control register changed.");
43 static_assert(kDifPwrmgrDomainOptionUsbClockInActivePower ==
44 (1u << (PWRMGR_CONTROL_USB_CLK_EN_ACTIVE_BIT -
45 PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
46 "Layout of control register changed.");
49 static_assert(kDifPwrmgrDomainOptionMainPowerInLowPower ==
50 (1u << (PWRMGR_CONTROL_MAIN_PD_N_BIT -
51 PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
52 "Layout of control register changed.");
61 #if defined(OPENTITAN_IS_EARLGREY)
62 kDifPwrmgrDomainOptionUsbClockInLowPower |
63 kDifPwrmgrDomainOptionUsbClockInActivePower |
64 #elif defined(OPENTITAN_IS_DARJEELING)
67 #error "dif_pwrmgr does not support this top"
69 kDifPwrmgrDomainOptionMainPowerInLowPower,
70 .index = PWRMGR_CONTROL_CORE_CLK_EN_BIT,
77 #if defined(OPENTITAN_IS_EARLGREY)
78 static_assert(kDifPwrmgrWakeupRequestSourceOne ==
79 (1u << PWRMGR_WAKEUP_EN_EN_0_BIT),
80 "Layout of WAKEUP_EN register changed.");
81 static_assert(kDifPwrmgrWakeupRequestSourceOne ==
82 (1u << PWRMGR_PARAM_SYSRST_CTRL_AON_WKUP_REQ_IDX),
83 "Layout of WAKE_INFO register changed.");
84 static_assert(kDifPwrmgrWakeupRequestSourceTwo ==
85 (1u << PWRMGR_PARAM_ADC_CTRL_AON_WKUP_REQ_IDX),
86 "Layout of WAKE_INFO register changed.");
87 static_assert(kDifPwrmgrWakeupRequestSourceThree ==
88 (1u << PWRMGR_PARAM_PINMUX_AON_PIN_WKUP_REQ_IDX),
89 "Layout of WAKE_INFO register changed.");
90 static_assert(kDifPwrmgrWakeupRequestSourceFour ==
91 (1u << PWRMGR_PARAM_PINMUX_AON_USB_WKUP_REQ_IDX),
92 "Layout of WAKE_INFO register changed.");
93 static_assert(kDifPwrmgrWakeupRequestSourceFive ==
94 (1u << PWRMGR_PARAM_AON_TIMER_AON_WKUP_REQ_IDX),
95 "Layout of WAKE_INFO register changed.");
96 static_assert(kDifPwrmgrWakeupRequestSourceSix ==
97 (1u << PWRMGR_PARAM_SENSOR_CTRL_AON_WKUP_REQ_IDX),
98 "Layout of WAKE_INFO register changed.");
99 #elif defined(OPENTITAN_IS_DARJEELING)
100 static_assert(kDifPwrmgrWakeupRequestSourceOne ==
101 (1u << PWRMGR_PARAM_PINMUX_AON_PIN_WKUP_REQ_IDX),
102 "Layout of WAKE_INFO register changed.");
103 static_assert(kDifPwrmgrWakeupRequestSourceTwo ==
104 (1u << PWRMGR_PARAM_AON_TIMER_AON_WKUP_REQ_IDX),
105 "Layout of WAKE_INFO register changed.");
106 static_assert(kDifPwrmgrWakeupRequestSourceThree ==
107 (1u << PWRMGR_PARAM_SOC_PROXY_WKUP_INTERNAL_REQ_IDX),
108 "Layout of WAKE_INFO register changed.");
109 static_assert(kDifPwrmgrWakeupRequestSourceFour ==
110 (1u << PWRMGR_PARAM_SOC_PROXY_WKUP_EXTERNAL_REQ_IDX),
111 "Layout of WAKE_INFO register changed.");
113 #error "dif_pwrmgr does not support this top"
120 static_assert(kDifPwrmgrResetRequestSourceOne ==
121 (1u << PWRMGR_RESET_EN_EN_0_BIT),
122 "Layout of RESET_EN register changed.");
123 static_assert(kDifPwrmgrResetRequestSourceTwo ==
124 (1u << PWRMGR_RESET_EN_EN_1_BIT),
125 "Layout of RESET_EN register changed.");
130 static_assert(kDifPwrmgrIrqWakeup == PWRMGR_INTR_COMMON_WAKEUP_BIT,
131 "Layout of interrupt registers changed.");
137 ptrdiff_t write_enable_reg_offset;
139 ptrdiff_t sources_enable_reg_offset;
140 ptrdiff_t cur_req_sources_reg_offset;
154 .write_enable_reg_offset = PWRMGR_WAKEUP_EN_REGWEN_REG_OFFSET,
155 .write_enable_bit_index = PWRMGR_WAKEUP_EN_REGWEN_EN_BIT,
156 .sources_enable_reg_offset = PWRMGR_WAKEUP_EN_REG_OFFSET,
157 .cur_req_sources_reg_offset = PWRMGR_WAKE_STATUS_REG_OFFSET,
160 .mask = kDifPwrmgrWakeupRequestSourceOne |
161 kDifPwrmgrWakeupRequestSourceTwo |
162 kDifPwrmgrWakeupRequestSourceThree |
163 #if defined(OPENTITAN_IS_EARLGREY)
164 kDifPwrmgrWakeupRequestSourceFour |
165 kDifPwrmgrWakeupRequestSourceFive |
166 kDifPwrmgrWakeupRequestSourceSix,
167 #elif defined(OPENTITAN_IS_DARJEELING)
168 kDifPwrmgrWakeupRequestSourceFour,
170 #error "dif_pwrmgr does not support this top"
177 .write_enable_reg_offset = PWRMGR_RESET_EN_REGWEN_REG_OFFSET,
178 .write_enable_bit_index = PWRMGR_RESET_EN_REGWEN_EN_BIT,
179 .sources_enable_reg_offset = PWRMGR_RESET_EN_REG_OFFSET,
180 .cur_req_sources_reg_offset = PWRMGR_RESET_STATUS_REG_OFFSET,
183 .mask = kDifPwrmgrResetRequestSourceOne |
184 kDifPwrmgrResetRequestSourceTwo,
192 dt_instance_id_t inst_id,
size_t sig_idx,
194 if (pwrmgr == NULL || sources == NULL) {
204 for (
size_t i = 0; i < dt_pwrmgr_wakeup_src_count(dt); i++) {
205 dt_pwrmgr_wakeup_src_t src = dt_pwrmgr_wakeup_src(dt, i);
206 if (src.inst_id == inst_id && src.wakeup == sig_idx) {
213 for (
size_t i = 0; i < dt_pwrmgr_reset_request_src_count(dt); i++) {
214 dt_pwrmgr_reset_req_src_t src = dt_pwrmgr_reset_request_src(dt, i);
215 if (src.inst_id == inst_id && src.reset_req == sig_idx) {
240 return (val & bitfield.
mask) == val;
250 static bool control_register_is_locked(
const dif_pwrmgr_t *pwrmgr) {
253 mmio_region_read32(pwrmgr->base_addr, PWRMGR_CTRL_CFG_REGWEN_REG_OFFSET),
254 PWRMGR_CTRL_CFG_REGWEN_EN_BIT);
263 static void sync_slow_clock_domain_polled(
const dif_pwrmgr_t *pwrmgr) {
266 pwrmgr->base_addr, PWRMGR_CFG_CDC_SYNC_REG_OFFSET,
269 mmio_region_read32(pwrmgr->base_addr, PWRMGR_CFG_CDC_SYNC_REG_OFFSET),
270 PWRMGR_CFG_CDC_SYNC_SYNC_BIT)) {
278 static bool request_sources_is_locked(
const dif_pwrmgr_t *pwrmgr,
282 mmio_region_read32(pwrmgr->base_addr, reg_info.write_enable_reg_offset);
295 if (control_register_is_locked(pwrmgr)) {
300 mmio_region_read32(pwrmgr->base_addr, PWRMGR_CONTROL_REG_OFFSET);
303 mmio_region_write32(pwrmgr->base_addr, PWRMGR_CONTROL_REG_OFFSET, reg_val);
307 sync_slow_clock_domain_polled(pwrmgr);
314 if (pwrmgr == NULL || cur_state == NULL) {
319 mmio_region_read32(pwrmgr->base_addr, PWRMGR_CONTROL_REG_OFFSET);
329 if (pwrmgr == NULL || !is_valid_for_bitfield(config, kDomainConfigBitfield) ||
334 if (control_register_is_locked(pwrmgr)) {
339 mmio_region_read32(pwrmgr->base_addr, PWRMGR_CONTROL_REG_OFFSET);
341 mmio_region_write32(pwrmgr->base_addr, PWRMGR_CONTROL_REG_OFFSET, reg_val);
345 sync_slow_clock_domain_polled(pwrmgr);
352 if (pwrmgr == NULL || config == NULL) {
357 mmio_region_read32(pwrmgr->base_addr, PWRMGR_CONTROL_REG_OFFSET);
359 reg_val, kDomainConfigBitfield);
367 if (pwrmgr == NULL || !is_valid_req_type(req_type) ||
374 if (!is_valid_for_bitfield(sources, reg_info.bitfield)) {
379 if (request_sources_is_locked(pwrmgr, req_type)) {
385 mmio_region_write32(pwrmgr->base_addr, reg_info.sources_enable_reg_offset,
389 sync_slow_clock_domain_polled(pwrmgr);
397 if (pwrmgr == NULL || !is_valid_req_type(req_type) || sources == NULL) {
403 mmio_region_read32(pwrmgr->base_addr, reg_info.sources_enable_reg_offset);
412 if (pwrmgr == NULL || !is_valid_req_type(req_type) || sources == NULL) {
417 uint32_t reg_val = mmio_region_read32(pwrmgr->base_addr,
418 reg_info.cur_req_sources_reg_offset);
426 if (pwrmgr == NULL || !is_valid_req_type(req_type)) {
432 mmio_region_write32(pwrmgr->base_addr,
433 request_reg_infos[req_type].write_enable_reg_offset, 0);
441 if (pwrmgr == NULL || !is_valid_req_type(req_type) || is_locked == NULL) {
445 *is_locked = request_sources_is_locked(pwrmgr, req_type);
460 mmio_region_write32(pwrmgr->base_addr,
461 PWRMGR_WAKE_INFO_CAPTURE_DIS_REG_OFFSET, reg_val);
468 if (pwrmgr == NULL || cur_state == NULL) {
472 uint32_t reg_val = mmio_region_read32(
473 pwrmgr->base_addr, PWRMGR_WAKE_INFO_CAPTURE_DIS_REG_OFFSET);
483 if (pwrmgr == NULL || reason == NULL) {
488 mmio_region_read32(pwrmgr->base_addr, PWRMGR_WAKE_INFO_REG_OFFSET);
500 if (request_sources != 0) {
506 .request_sources = request_sources,
513 if (pwrmgr == NULL) {
517 mmio_region_write32(pwrmgr->base_addr, PWRMGR_WAKE_INFO_REG_OFFSET,
525 if (pwrmgr == NULL || codes == NULL) {
529 mmio_region_read32(pwrmgr->base_addr, PWRMGR_FAULT_STATUS_REG_OFFSET);