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)
38static_assert(kDifPwrmgrDomainOptionUsbClockInLowPower ==
39 (1u << (PWRMGR_CONTROL_USB_CLK_EN_LP_BIT -
40 PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
41 "Layout of control register changed.");
43static_assert(kDifPwrmgrDomainOptionUsbClockInActivePower ==
44 (1u << (PWRMGR_CONTROL_USB_CLK_EN_ACTIVE_BIT -
45 PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
46 "Layout of control register changed.");
49static_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 "Layout of interrupt registers changed.");
83 ptrdiff_t write_enable_reg_offset;
85 ptrdiff_t sources_enable_reg_offset;
86 ptrdiff_t cur_req_sources_reg_offset;
96static const request_reg_info_t request_reg_infos[2] = {
99 .write_enable_reg_offset = PWRMGR_WAKEUP_EN_REGWEN_REG_OFFSET,
100 .write_enable_bit_index = PWRMGR_WAKEUP_EN_REGWEN_EN_BIT,
101 .sources_enable_reg_offset = PWRMGR_WAKEUP_EN_REG_OFFSET,
102 .cur_req_sources_reg_offset = PWRMGR_WAKE_STATUS_REG_OFFSET,
106 .write_enable_reg_offset = PWRMGR_RESET_EN_REGWEN_REG_OFFSET,
107 .write_enable_bit_index = PWRMGR_RESET_EN_REGWEN_EN_BIT,
108 .sources_enable_reg_offset = PWRMGR_RESET_EN_REG_OFFSET,
109 .cur_req_sources_reg_offset = PWRMGR_RESET_STATUS_REG_OFFSET,
117 if (pwrmgr == NULL || sources == NULL) {
169 bitfield->
mask = (1 << count) - 1;
177 dif_result_t res = request_reg_bitfield(pwrmgr, req_type, &bitfield);
179 *sources = bitfield.
mask;
198 return (val & bitfield.
mask) == val;
208static bool control_register_is_locked(
const dif_pwrmgr_t *pwrmgr) {
210 return !bitfield_bit32_read(
211 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_CTRL_CFG_REGWEN_REG_OFFSET),
212 PWRMGR_CTRL_CFG_REGWEN_EN_BIT);
221static void sync_slow_clock_domain_polled(
const dif_pwrmgr_t *pwrmgr) {
224 pwrmgr->
base_addr, PWRMGR_CFG_CDC_SYNC_REG_OFFSET,
225 bitfield_bit32_write(0, PWRMGR_CFG_CDC_SYNC_SYNC_BIT,
true));
226 while (bitfield_bit32_read(
227 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_CFG_CDC_SYNC_REG_OFFSET),
228 PWRMGR_CFG_CDC_SYNC_SYNC_BIT)) {
236static bool request_sources_is_locked(
const dif_pwrmgr_t *pwrmgr,
238 request_reg_info_t reg_info = request_reg_infos[req_type];
240 mmio_region_read32(pwrmgr->
base_addr, reg_info.write_enable_reg_offset);
242 return !bitfield_bit32_read(reg_val, reg_info.write_enable_bit_index);
248 if (pwrmgr == NULL || !dif_is_valid_toggle(new_state) ||
249 !dif_is_valid_toggle(sync_state)) {
253 if (control_register_is_locked(pwrmgr)) {
258 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_CONTROL_REG_OFFSET);
259 reg_val = bitfield_bit32_write(reg_val, PWRMGR_CONTROL_LOW_POWER_HINT_BIT,
260 dif_toggle_to_bool(new_state));
261 mmio_region_write32(pwrmgr->
base_addr, PWRMGR_CONTROL_REG_OFFSET, reg_val);
265 sync_slow_clock_domain_polled(pwrmgr);
272 if (pwrmgr == NULL || cur_state == NULL) {
277 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_CONTROL_REG_OFFSET);
278 *cur_state = dif_bool_to_toggle(
279 bitfield_bit32_read(reg_val, PWRMGR_CONTROL_LOW_POWER_HINT_BIT));
287 if (pwrmgr == NULL || !is_valid_for_bitfield(config, kDomainConfigBitfield) ||
288 !dif_is_valid_toggle(sync_state)) {
292 if (control_register_is_locked(pwrmgr)) {
297 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_CONTROL_REG_OFFSET);
298 reg_val = bitfield_field32_write(reg_val, kDomainConfigBitfield, config);
299 mmio_region_write32(pwrmgr->
base_addr, PWRMGR_CONTROL_REG_OFFSET, reg_val);
303 sync_slow_clock_domain_polled(pwrmgr);
310 if (pwrmgr == NULL || config == NULL) {
315 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_CONTROL_REG_OFFSET);
317 reg_val, kDomainConfigBitfield);
325 if (pwrmgr == NULL || !is_valid_req_type(req_type) ||
326 !dif_is_valid_toggle(sync_state)) {
330 request_reg_info_t reg_info = request_reg_infos[req_type];
334 if (!is_valid_for_bitfield(sources, bitfield)) {
339 if (request_sources_is_locked(pwrmgr, req_type)) {
344 uint32_t reg_val = bitfield_field32_write(0, bitfield, sources);
345 mmio_region_write32(pwrmgr->
base_addr, reg_info.sources_enable_reg_offset,
349 sync_slow_clock_domain_polled(pwrmgr);
357 if (pwrmgr == NULL || !is_valid_req_type(req_type) || sources == NULL) {
361 request_reg_info_t reg_info = request_reg_infos[req_type];
363 dif_result_t res = request_reg_bitfield(pwrmgr, req_type, &bitfield);
368 mmio_region_read32(pwrmgr->
base_addr, reg_info.sources_enable_reg_offset);
369 *sources = bitfield_field32_read(reg_val, bitfield);
377 if (pwrmgr == NULL || !is_valid_req_type(req_type) || sources == NULL) {
381 request_reg_info_t reg_info = request_reg_infos[req_type];
383 dif_result_t res = request_reg_bitfield(pwrmgr, req_type, &bitfield);
387 uint32_t reg_val = mmio_region_read32(pwrmgr->
base_addr,
388 reg_info.cur_req_sources_reg_offset);
389 *sources = bitfield_field32_read(reg_val, bitfield);
396 if (pwrmgr == NULL || !is_valid_req_type(req_type)) {
403 request_reg_infos[req_type].write_enable_reg_offset, 0);
411 if (pwrmgr == NULL || !is_valid_req_type(req_type) || is_locked == NULL) {
415 *is_locked = request_sources_is_locked(pwrmgr, req_type);
422 if (pwrmgr == NULL || !dif_is_valid_toggle(new_state)) {
428 uint32_t reg_val = bitfield_bit32_write(
429 0, PWRMGR_WAKE_INFO_CAPTURE_DIS_VAL_BIT, !dif_toggle_to_bool(new_state));
431 PWRMGR_WAKE_INFO_CAPTURE_DIS_REG_OFFSET, reg_val);
438 if (pwrmgr == NULL || cur_state == NULL) {
442 uint32_t reg_val = mmio_region_read32(
443 pwrmgr->
base_addr, PWRMGR_WAKE_INFO_CAPTURE_DIS_REG_OFFSET);
445 *cur_state = dif_bool_to_toggle(
446 !bitfield_bit32_read(reg_val, PWRMGR_WAKE_INFO_CAPTURE_DIS_VAL_BIT));
453 if (pwrmgr == NULL || reason == NULL) {
458 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_WAKE_INFO_REG_OFFSET);
461 if (bitfield_bit32_read(reg_val, PWRMGR_WAKE_INFO_FALL_THROUGH_BIT)) {
464 if (bitfield_bit32_read(reg_val, PWRMGR_WAKE_INFO_ABORT_BIT)) {
474 uint32_t request_sources = bitfield_field32_read(reg_val, bitfield);
475 if (request_sources != 0) {
481 .request_sources = request_sources,
488 if (pwrmgr == NULL) {
492 mmio_region_write32(pwrmgr->
base_addr, PWRMGR_WAKE_INFO_REG_OFFSET,
500 if (pwrmgr == NULL || codes == NULL) {
504 mmio_region_read32(pwrmgr->
base_addr, PWRMGR_FAULT_STATUS_REG_OFFSET);