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
13void 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 };
25 dif_result_t res = dif_pinmux_pad_write_attrs(
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) {
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
45void 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 = {
55 .enabled = kDifToggleDisabled,
56 .allow_zero = true,
57 .allow_one = true,
58 .override_value = false,
59 };
60 CHECK_DIF_OK(dif_sysrst_ctrl_output_pin_override_configure(
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 = {
69 .enabled = kDifToggleEnabled,
70 .allow_zero = false,
71 .allow_one = true,
72 .override_value = true,
73 };
74 CHECK_DIF_OK(dif_sysrst_ctrl_output_pin_override_configure(
75 sysrst_ctrl, kDifSysrstCtrlPinFlashWriteProtectInOut, cfg_flash_wp));
76 }
77}
78
79void 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}