From 58d25d7a9634857d3c97a0b0c19759af1a79b27c Mon Sep 17 00:00:00 2001 From: Pirmin Vogel Date: Fri, 27 Sep 2024 23:20:12 +0200 Subject: [PATCH] [pinmux/dif] Document WARL semantics of pad attribute registers The MIO|DIO_PAD_ATTR registers are specified as WARL meaning certain bits written by software may get discarded by the hardware. For example the supported number of drive strength bits can depend on the hardware platform (simulation, FPGA, silicon). When configuring pad attributes, the DIF performs a readback of the written value and signals an error if they don't match. This commit doesn't alter the behavior of the DIF but it documents the behavior and in particular the expection that higher-level software needs to decide on how to resolve the situation. This is related to lowRISC/OpenTitan#24577. Signed-off-by: Pirmin Vogel --- sw/device/lib/dif/dif_pinmux.c | 6 ++++++ sw/device/lib/dif/dif_pinmux.h | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sw/device/lib/dif/dif_pinmux.c b/sw/device/lib/dif/dif_pinmux.c index cae7209ee68fc..3ce20bdb33031 100644 --- a/sw/device/lib/dif/dif_pinmux.c +++ b/sw/device/lib/dif/dif_pinmux.c @@ -304,6 +304,12 @@ dif_result_t dif_pinmux_pad_write_attrs(const dif_pinmux_t *pinmux, uint32_t read_value = mmio_region_read32(pinmux->base_addr, reg_offset); *attrs_out = dif_pinmux_reg_to_pad_attr(read_value); + // Not all pads implement all attributes and not all target platforms support + // all attribute values. The underlying hardware registers implement Write-Any + // Read-Legal (WARL) semantics. If the specified attribute values are not + // supported by the hardware, return `kDifError`. The caller then needs to + // decide on how to resolve the situation. Unsupported attribute values can be + // identified by comparing `attrs_in` to `attrs_out`. if (reg_value != read_value) { return kDifError; } diff --git a/sw/device/lib/dif/dif_pinmux.h b/sw/device/lib/dif/dif_pinmux.h index 2eae8afcf5ab2..4c1f960718e61 100644 --- a/sw/device/lib/dif/dif_pinmux.h +++ b/sw/device/lib/dif/dif_pinmux.h @@ -345,8 +345,13 @@ dif_result_t dif_pinmux_output_select(const dif_pinmux_t *pinmux, * Not all pads implement all attributes and some combinations cannot be * enabled together. This function returns a `kDifBadArg` error in case of * invalid `attrs_in`. - * Conflicting attributes will be discarded by the hardware, and can be - * identified by comparing `attrs_in` to `attrs_out`. + * Not all target platforms support all attribute values and the underlying + * hardware registers implement Write-Any Read-Legal (WARL) semantics. For + * example, the maximum supported slew rate and drive strength may vary between + * platforms. If the specified attribute values are valid but not supported by + * the hardware, this function returns `kDifError` and the caller needs to + * decide on how to resolve the situation. Unsupported or conflicting attribute + * values can be identified by comparing `attrs_in` to `attrs_out`. * * IMPORTANT: * See `dif_pinmux_pad_attr` for information on which attributes are compulsory