Software APIs
pwrmgr.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/drivers/pwrmgr.h"
6 
9 #include "sw/device/silicon_creator/lib/drivers/ibex.h"
10 
12 #include "pwrmgr_regs.h"
13 
14 enum {
16  kAllResetsEnable = (1 << kTopEarlgreyPowerManagerResetRequestsLast) - 1,
17  kSyncConfig = (1 << PWRMGR_CFG_CDC_SYNC_SYNC_BIT),
18 };
19 
20 static_assert(kAllResetsEnable == 0x1,
21  "Number of reset requests changed, update expectation if this is "
22  "intentional");
23 static_assert(
24  PWRMGR_RESET_EN_EN_FIELD_WIDTH == 1,
25  "RESET_EN field width changed, kAllResetsEnable may need to be updated");
26 
27 void pwrmgr_cdc_sync(uint32_t n) {
28  // We want to timeout if the CDC bit doesn't self clear. It should take
29  // approximately 4 AON ticks to complete. We wait 25% longer (5 ticks).
30  uint32_t cpu_cycle_timeout =
31  (uint32_t)kClockFreqCpuHz / (uint32_t)kClockFreqAonHz * 5;
32 
33  // Ensure the bit is clear before requesting another sync.
34  ibex_mcycle_zero();
35  while (abs_mmio_read32(kBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET)) {
36  if (ibex_mcycle32() > cpu_cycle_timeout) {
37  // If the sync bit isn't clear, we shouldn't set it again. Abort.
38  return;
39  }
40  }
41  // Perform the sync procedure the requested number of times.
42  while (n--) {
43  ibex_mcycle_zero();
44  abs_mmio_write32(kBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET, kSyncConfig);
45  while (abs_mmio_read32(kBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET)) {
46  if (ibex_mcycle32() > cpu_cycle_timeout)
47  // If the sync bit isn't clear, we shouldn't set it again. Abort.
48  return;
49  }
50  }
51 }
52 
53 void pwrmgr_all_resets_enable(void) {
54  SEC_MMIO_ASSERT_WRITE_INCREMENT(kPwrmgrSecMmioAllResetsEnable, 1);
55  // Enable all resets.
56  sec_mmio_write32(kBase + PWRMGR_RESET_EN_REG_OFFSET, kAllResetsEnable);
57  pwrmgr_cdc_sync(1);
58 }