blob: 03914bb57e16840c556d9000d858a0848e9bd93e [file] [log] [blame] [view]
# System Reset Control Technical Specification
# Overview
This document specifies the functionality of the System Reset Controller (`sysrst_ctrl`) that provides programmable hardware-level responses to trusted IOs and basic board-level reset sequencing capabilities.
These capabilities include keyboard and button combination-triggered actions, reset stretching for system-level reset signals, and internal reset / wakeup requests that go to the OpenTitan reset and power manager blocks.
This module conforms to the [Comportable guideline for peripheral functionality](../../../doc/contributing/hw/comportability/README.md).
See that document for integration overview within the broader top level system.
## Features
The IP block implements the following features:
- Always-on: uses the always-on power and clock domain
- EC reset pulse duration control and stretching
- Keyboard and button combination (combo) triggered action
- AC_present can trigger interrupt
- Configuration registers can be set and locked until the next chip reset
- Pin output override
## Description
The `sysrst_ctrl` logic is very simple.
It looks up the configuration registers to decide how long the EC reset pulse duration and how long the key presses should be.
Also what actions to take (e.g. Interrupt, EC reset, OpenTitan reset request, disconnect the battery from the power tree).
## Compatibility
The configuration programming interface is not based on any existing interface.
# Theory of Operations
![`sysrst_ctrl` Block Diagram](./doc/sysrst_ctrl_blockdiagram.svg)
The block diagram above shows a conceptual view of the `sysrst_ctrl` block, which consists of 3 main modules:
The first is the configuration and status registers, the second is the keyboard combo debounce and detection logic, and the third is the pinout override logic.
The debounce logic does not implement a low-pass filter, instead it uses a simpler technique of sampling once when the timer starts and then again when the timer ends.
The detection logic does require the signal to stay active for the entire period, which can be used to detect any anomoulous signals that might elude the rudimentary debounce logic.
For the auto block, key interrupt and ultra-low-power features there is only a debounce timer so it is good to be aware of this behavior of sampling the signal only twice.
The `sysrst_ctrl` has four input pins (`pwrb_in_i`, `key[0,1,2]_in_i`) with corresponding output pins (`pwrb_out`, `key[0,1,2]_out`).
During normal operation the `sysrst_ctrl` will pass the pin information directly from the input pins to the output pins with optional inversion.
Combinations of the inputs being active for a specified time can be detected and used to trigger actions.
The override logic allows the output to be overridden (i.e. not follow the corresponding input) based either on trigger or software settings.
This allows the security chip to take over the inputs for its own use without disturbing the main user.
The `sysrst_ctrl` also controls two active-low open-drain I/Os named `flash_wp_l_i` / `flash_wp_l_o` and `ec_rst_l_i` / `ec_rst_l_o`.
The `ec_rst_l_i` / `ec_rst_l_o` signals are connected to the same bidirectional pin of the OpenTitan chip, and are used to either reset the embedded controller (EC), or to detect self-reset of the EC and stretch the reset pulse (hence the bidirectional nature of this pin).
This output is always asserted when `sysrst_ctrl` is reset (allowing its use as a power-on reset) and remains asserted until released by software.
The flash write-protect output `flash_wp_l_o` is typically connected to the BIOS flash chip in the system.
This output is always asserted when the `sysrst_ctrl` block is reset and remains asserted until released by software.
## Hardware Interfaces
{{< incGenFromIpDesc "../data/sysrst_ctrl.hjson" "hwcfg" >}}
## Combo detection
Software can program the `sysrst_ctrl` block to detect certain button combos and for how long they have to be asserted until they trigger a programmable action.
A combo is a combination of multiple keys that are pressed together for a programmable amount of time.
In order to detect a combo, the hardware first OR's the active-low key-pressed indications and debounces the combined trigger signal.
The hardware then detects a negative edge on the combined trigger signal and checks whether it stays asserted low for the programmed amount of cycles.
If the combined trigger signal fulfills the programmed timing constraint, a combo is detected.
Optionally, a combo detection channel may also specify a pre-condition.
Such a pre-condition is a set of keys that must remain pressed in order to activate the combo detection circuit.
The main difference with respect to the combo detection circuit is that the pre-condition checks for a low level of the combined key-pressed indications instead of checking for a negative edge.
The pre-condition debounce timing is the same as for combo detection, but the key-pressed timing can be configured independently.
Let's use the "Power button + Key0 + Key1" combo with pre-condition "Key2" as an example:
0. Software can define the key value `key2_in_i==0` as pre-condition in the {{< regref COM_PRE_SEL_CTL_0 >}} register.
1. The key-pressed time for the pre-condition (e.g. 2 seconds) can be configured via the {{< regref COM_DET_SEL_CTL_0 >}} register.
2. Software can define the three key values `pwrb_in_i==0`, `key0_in_i==0` and `key1_in_i==0` as trigger combination in the {{< regref COM_SEL_CTL_0 >}} register.
3. The combo duration for which the above combo should be pressed (e.g. 10 seconds) can be configured via the {{< regref COM_DET_CTL_0 >}} register.
4. Actions such as asserting `ec_rst_l_o` and raising an interrupt can be configured via the {{< regref COM_OUT_CTL_0 >}} register.
5. The pulse width of the `ec_rst_l_o` pulse can be set in the {{< regref EC_RST_CTL >}} register.
6. The software can optionally lock the `sysrst_ctrl` configuration via {{< regref REGWEN >}}
Once the above configuration is active, `sysrst_ctrl` will start the timer when the pre-condition is valid (logic 0 level on all pre-condition signals).
If the timing condition (2 seconds) is met, `systrst_ctrl` will enable combo detection, and wait for a high (logic 1) to low (logic 0) transition of the combined trigger signal.
If a transition is seen, and the timing condition is met (10 seconds), `sysrst_ctrl` will assert `ec_rst_l_o`, the interrupt request and set the interrupt status register {{< regref COMBO_INTR_STATUS >}} to indicate the interrupt cause.
The software interrupt handler should then read the {{< regref COMBO_INTR_STATUS >}} register and clear the interrupt via the {{< regref INTR_STATE >}} register.
Note that an interrupt will also issue a wakeup request to the OpenTitan power manager via `wkup_req_o`.
Software should therefore read and clear the {{< regref WKUP_STATUS >}} register as well.
### Combo actions
The following four combo actions can be triggered:
- Drive the `bat_disable` output high until the next reset.
- Issue an interrupt to the processor via `intr_event_detected_o`.
- Assert `ec_rst_l_o` for the amount of cycles configured in {{< regref EC_RST_CTL >}}.
- Issue a reset request via `rst_req_o` to the reset manager of the OpenTitan system. Note that once a reset request is issued, it will remain asserted until the next reset.
These actions can be configured via the {{< regref COM_OUT_CTL_0 >}} register for each of the combo blocks as described in the previous section.
### Hardwired reset stretching functionality
In addition to the combo action described above, `ec_rst_l_o` is automatically asserted for the amount of cycles defined in the {{< regref EC_RST_CTL >}} register whenever the `ec_rst_l_i` input is asserted (i.e., when it transitions from high to low).
## Auto-block key outputs
Software can program the `sysrst_ctrl` block to override the output value of specific passthrough signals, depending on whether certain input signals are asserted or not.
Let's use the "Power button + Esc + Refresh" combo as an example.
When `pwrb_in_i` is asserted, `key1_out_o` (row) should be overridden so that `sysrst_ctrl` can detect if `key0_in_i` (column) is Refresh.
1. The software enables the auto block feature and sets an appropriate debounce timer value in the {{< regref AUTO_BLOCK_DEBOUNCE_CTL >}} register.
2. The software then defines the key outputs to auto override and their override values in the {{< regref AUTO_BLOCK_OUT_CTL >}} register.
Once the above configuration is active, `sysrst_ctrl` will detect a high (logic 1) to low (logic 0) transition on `pwrb_in_i` and check whether the key `pwrb_in_i` stays low for the programmed duration.
If this condition is met, `sysrst_ctrl` will drive `key1_out_o` to the value programmed in {{< regref AUTO_BLOCK_OUT_CTL >}}.
## Keyboard and input triggered interrupt
Software can program the `sysrst_ctrl` block to detect edge transitions on the `pwrb_in_i`, `key0_in_i`, `key1_in_i`, `key2_in_i`, `ac_present_i`, `ec_rst_l_i` and `flash_wp_l_i` signals and trigger an interrupt:
1. Software first defines the input signal and the edge transition to detect (H->L or L->H) via the {{< regref KEY_INTR_CTL >}} register.
2. The software then programs an appropriate debounce timer value to the {{< regref KEY_INTR_DEBOUNCE_CTL >}} register.
For example, when the power button is pressed, `pwrb_in_i` goes from logic 1 to logic 0 which would amount to an H->L transition.
Likewise, when the power button is released, `pwrb_in_i` goes from logic 0 to logic 1 which would amount to an L->H transition.
When `sysrst_ctrl` detects a transition (H->L or L->H) as specified in {{< regref KEY_INTR_CTL >}} and it meets the debounce requirement in {{< regref KEY_INTR_DEBOUNCE_CTL >}}, `sysrst_ctrl` sets the {{< regref KEY_INTR_STATUS >}} register to indicate the interrupt cause and send out a consolidated interrupt to the PLIC.
The software interrupt handler should then read the {{< regref KEY_INTR_STATUS >}} register and clear the interrupt via the {{< regref INTR_STATE >}} register.
Note that an interrupt will also issue a wakeup request to the OpenTitan power manager via `wkup_req_o`.
Software should therefore read and clear the {{< regref WKUP_STATUS >}} register as well.
## Ultra-low-power Wakeup Feature
Software can program the `sysrst_ctrl` block to detect certain specific signal transitions on the (possibly inverted) `ac_present_i`, `pwrb_in_i` and `lid_open_i` inputs.
As opposed to the combo detection and general key interrupt features above, this is a fixed function feature with limited configurability.
In particular, the transitions that can be detected are fixed to the following:
- A high level on the `ac_present_i` signal
- A H -> L transition on the `pwrb_in_i` signal
- A L -> H transition on the `lid_open_i` signal
Note that the signals may be potentially inverted due to the [input inversion feature](#inversion).
In order to activate this feature, software should do the following:
1. Software can program the appropriate debounce times via the {{< regref ULP_AC_DEBOUNCE_CTL >}}, {{< regref ULP_LID_DEBOUNCE_CTL >}} and {{< regref ULP_PWRB_DEBOUNCE_CTL >}} registers.
2. Then, software can activate detection by setting the {{< regref ULP_CTL >}} register to 1.
Once the above configuration is active, `sysrst_ctrl` will start the timer when a transition is detected.
Once the timing condition is met, `sysrst_ctrl` will assert `z3_wakeup` output signal, the interrupt request and set the interrupt status register {{< regref ULP_STATUS >}} to indicate the interrupt cause.
The software interrupt handler should then read the {{< regref ULP_STATUS >}} register and clear the interrupt via the {{< regref INTR_STATE >}} register.
Note that an interrupt will also issue a wakeup request to the OpenTitan power manager via `wkup_req_o`.
Software should therefore read and clear the {{< regref WKUP_STATUS >}} register as well.
Also note that the detection status is sticky.
I.e., software needs to explicitly disable this feature by setting {{< regref ULP_CTL >}} to 0 in order to clear the FSM state.
If software wants to re-arm the mechanism right away, it should first read back {{< regref ULP_CTL >}} to make sure it has been cleared before setting that register to 1 again.
This is needed because this register has to be synchronized over to the AON clock domain.
## Pin input value accessibility
`sysrst_ctrl` allows the software to read the raw input pin values via the {{< regref PIN_IN_VALUE >}} register like GPIOs.
To this end, the hardware samples the raw input values of `pwrb_in_i`, `key[0,1,2]_in_i`, `ac_present_i`, `ec_rst_l_i`, `flash_wp_l_i` before they are being inverted, and synchronizes them onto the bus clock domain.
## Pin output and keyboard inversion control {#inversion}
Software can optionally override all output signals, and change the signal polarity of some of the input and output signals.
The output signal override feature always has higher priority than any of the combo pattern detection mechanisms described above.
The selection of output signals to override, and the override values are programmable and lockable via the {{< regref PIN_ALLOWED_CTL >}} register.
For example, {{< regref PIN_ALLOWED_CTL.EC_RST_L_0 >}} to 1 and {{< regref PIN_ALLOWED_CTL.EC_RST_L_1 >}} to 0 means that software allows `ec_rst_l_o` to be overridden with logic 0, but not with logic 1.
If the SW locks the configuration with {{< regref REGWEN >}}, {{< regref PIN_ALLOWED_CTL >}} cannot be modified until the next OpenTitan reset.
When the system is up and running, the software can modify {{< regref PIN_OUT_CTL >}} and {{< regref PIN_OUT_VALUE >}} to enable or disable the feature.
For example, to release `ec_rst_l_o` after OpenTitan completes the reset, software can set {{< regref PIN_OUT_CTL >}} to 0 to stop the hardware from driving `ec_rst_l_o` to 0.
The input / output signal inversions can be programmed via the {{< regref KEY_INVERT_CTL >}} register.
Input signals will be inverted before the combo detection logic, while output signals will be inverted after the output signal override logic.
## EC and Power-on-reset
OpenTitan and EC will be reset together during power-on.
When OpenTitan is in reset, `ec_rst_l_o` will be asserted (active low).
The power-on-reset value of {{< regref PIN_ALLOWED_CTL.EC_RST_L_1 >}} and {{< regref PIN_OUT_CTL.EC_RST_L >}} will guarantee that `ec_rst_l_o` remains asserted after OpenTitan reset is released.
The software can release `ec_rst_l_o` explicitly by setting {{< regref PIN_OUT_CTL.EC_RST_L >}} to 0 during boot in order to complete the OpenTitan and EC power-on-reset sequence.
Note that since the `sysrst_ctrl` does not have control over the pad open-drain settings, software should properly initialize the pad attributes of the corresponding pad in the [pinmux configuration](../pinmux/README.md) before releasing `ec_rst_l_o`.
## Flash Write Protect Output
Upon reset, the `flash_wp_l_o` signal will be asserted active low.
The software can release `flash_wp_l_o` explicitly by setting {{< regref PIN_OUT_CTL.FLASH_WP_L >}} to 0 when needed.
The `flash_wp_l_o` signal does have a corresponding input signal `flash_wp_l_i` - but that one is mainly intended for pad observability and does not have a bypass path to `flash_wp_l_o`.
Hence, the value of `flash_wp_l_o` defaults to logic 0 when it is not explicitly driven via the override function.
Note that since the `sysrst_ctrl` does not have control over the pad open-drain settings, software should properly initialize the pad attributes of the corresponding pad in the [pinmux configuration](../pinmux/README.md) before releasing `flash_wp_l_o`.
## Device Interface Functions (DIFs)
{{< dif_listing "sw/device/lib/dif/dif_sysrst_ctrl.h" >}}
## Registers
{{< incGenFromIpDesc "../data/sysrst_ctrl.hjson" "registers" >}}