Software APIs
sysrst_ctrl_testutils.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/lib/testing/sysrst_ctrl_testutils.h"
6 
9 #include "sw/device/lib/testing/test_framework/check.h"
10 
12 
13 void sysrst_ctrl_testutils_setup_dio(dif_pinmux_t *pinmux) {
14  // Make sure that the DIO pins EC reset and flash WP are configured correctly
15  // https://opentitan.org/book/hw/ip/sysrst_ctrl/doc/theory_of_operation.html#ec-and-power-on-reset
16  // https://opentitan.org/book/hw/ip/sysrst_ctrl/doc/theory_of_operation.html#flash-write-protect-output
17  //
18  // The documentation says that they should be configured as open drain.
19  dif_pinmux_pad_attr_t out_attr;
20  dif_pinmux_pad_attr_t in_attr = {
21  .slew_rate = 0,
22  .drive_strength = 0,
23  .flags = kDifPinmuxPadAttrOpenDrain,
24  };
26  pinmux, kTopEarlgreyDirectPadsSysrstCtrlAonEcRstL, kDifPinmuxPadKindDio,
27  in_attr, &out_attr);
28  // The FPGA does not support open drain but instead has virtual open drain.
29  // Try to use that if open drain did not work.
30  if (res == kDifError && out_attr.flags != kDifPinmuxPadAttrOpenDrain) {
31  LOG_INFO(
32  "cannot use open drain for sysrst pins, trying virtual open drain");
33  in_attr.flags = kDifPinmuxPadAttrVirtualOpenDrain;
34  CHECK_DIF_OK(dif_pinmux_pad_write_attrs(
35  pinmux, kTopEarlgreyDirectPadsSysrstCtrlAonEcRstL, kDifPinmuxPadKindDio,
36  in_attr, &out_attr));
37  // Note: fallthrough with the modified `in_attr` so that the same attributes
38  // are used for both pads.
39  }
40  CHECK_DIF_OK(dif_pinmux_pad_write_attrs(
41  pinmux, kTopEarlgreyDirectPadsSysrstCtrlAonFlashWpL, kDifPinmuxPadKindDio,
42  in_attr, &out_attr));
43 }
44 
45 void sysrst_ctrl_testutils_release_dio(dif_sysrst_ctrl_t *sysrst_ctrl,
46  bool release_ec, bool release_flash) {
47  // Make sure that the DIO pins EC reset and flash WP are released according to
48  // the documentation:
49  // https://opentitan.org/book/hw/ip/sysrst_ctrl/doc/theory_of_operation.html#ec-and-power-on-reset
50  // https://opentitan.org/book/hw/ip/sysrst_ctrl/doc/theory_of_operation.html#flash-write-protect-output
51  // We also need to disable the output override mecanism (i.e. "release the
52  // pin").
53  if (release_ec) {
54  dif_sysrst_ctrl_pin_config_t cfg_ec_reset = {
56  .allow_zero = true,
57  .allow_one = true,
58  .override_value = false,
59  };
61  sysrst_ctrl, kDifSysrstCtrlPinEcResetInOut, cfg_ec_reset));
62  }
63  // Confusingly, the flash WP is different: the value of flash_wp_l_o defaults
64  // to logic 0 when it is not explicitly driven via the override function.
65  // Therefore to disable the driver we need to *enable* the override and set
66  // to 1.
67  if (release_flash) {
68  dif_sysrst_ctrl_pin_config_t cfg_flash_wp = {
70  .allow_zero = false,
71  .allow_one = true,
72  .override_value = true,
73  };
75  sysrst_ctrl, kDifSysrstCtrlPinFlashWriteProtectInOut, cfg_flash_wp));
76  }
77 }
78 
79 void sysrst_ctrl_testutils_set_ec_rst_pulse_width(
80  dif_sysrst_ctrl_t *sysrst_ctrl, uint32_t pulse_us) {
81  // The register field counts in aon_clock ticks.
82  uint64_t ticks =
83  udiv64_slow((uint64_t)pulse_us * kClockFreqAonHz, 1000 * 1000, NULL);
84  // The register field is 16-bit wide.
85  OT_ASSERT_ENUM_VALUE(SYSRST_CTRL_EC_RST_CTL_EC_RST_PULSE_OFFSET, 0);
86  CHECK(ticks <= SYSRST_CTRL_EC_RST_CTL_EC_RST_PULSE_MASK);
87  mmio_region_write32(sysrst_ctrl->base_addr, SYSRST_CTRL_EC_RST_CTL_REG_OFFSET,
88  (uint16_t)ticks);
89 }