Skip to content

arch/risc-v/eic7700x: Add the CRG reset controller. - #20062

Open
Fishwaldo wants to merge 4 commits into
apache:masterfrom
Fishwaldo:eic7700x-feature-reset-pr
Open

arch/risc-v/eic7700x: Add the CRG reset controller.#20062
Fishwaldo wants to merge 4 commits into
apache:masterfrom
Fishwaldo:eic7700x-feature-reset-pr

Conversation

@Fishwaldo

Copy link
Copy Markdown
Contributor

Summary

The Clock and Reset Generator holds the reset line for every block on the SoC,
and nothing in this port could see or move one. This registers all 324 lines
with the NuttX reset framework and lists them in /proc/reset.

  • arch: Add the CRG reset controller.assert, deassert, reset,
    status over 61 control registers
  • boards: Report the reset lines at startup. — one line of boot output
  • arch: Name the reset lines through procfs.get_line, so the listing
    carries names
  • boards: Enable the reset procfs entry. — the two board configurations

Design notes

Addressing. A line is its register index times thirty two plus its bit, so
decoding needs no table. The ids are sparse: 324 lines in a space of 1952.

Three masks per register. valid names the bits that are lines, rdonly
those the hardware will not let software drive, and critical those whose
assertion takes down the system asserting them: interconnect, DDR path, U84
cluster, and the configuration path back to this block. Critical lines are
still readable and releasable; only assert and reset refuse, with -EPERM.

The lines are active low, which the manual never states. Inferred from the
field naming (_rstn, _arstn, _prstn, _hrstn), the reset defaults, and
both vendor Linux drivers. Get it wrong and deassert asserts, so the evidence
is written out beside the table. It matches the hardware: uart0 reads
released while the console is printing.

Lines the manual omits are described rather than skipped: the GPIO resets
at 0x438, which the register table jumps straight past, and the translation
buffer and NPU E31 lines given only as reserved. Where an instance mapping is
missing, the assumption is recorded at the table row.

Registration writes nothing to the hardware.

Output

[CPU0] clk: registered 264 clocks, 0 failed
[CPU0] reset: 324 lines, 117 held

/proc/reset, abridged from 324 rows:

eic7700x-crg:
0    noc_nsp                  state:released reg:0x400 bit:0
224  hsp_axi                  state:released reg:0x41c bit:0
243  hsp_emmc_p               state:released reg:0x41c bit:19
288  i2c0                     state:asserted reg:0x424 bit:0
416  uart0                    state:released reg:0x434 bit:0
448  gpio0                    state:asserted reg:0x438 bit:0
1921 spi_slv                  state:released reg:0x4f0 bit:1

Ids naming no line return -ENODEV and the framework skips them, which is what
keeps the listing dense. The name table costs about 8 KiB and is built only
when CONFIG_RESET_PROCFS is.

Testing

Booted on the ESWIN EIC7700 EVB, TFTP loaded from U-Boot.

Compiled with -Wno-cpp -Werror in three configurations, the reset code being
option gated:

configuration result
RESET_PROCFS=y clean
RESET_PROCFS=n clean
DEBUG_RESET=n, RESET_PROCFS=y clean

tools/checkpatch.sh -c -u -m -g master..HEAD passes.

CONFIG_RESET_PROCFS depends on FS_PROCFS_REGISTER, so both board
configurations enable it; without it the symbol is dropped when the
configuration is regenerated and the entry never appears.

@Fishwaldo
Fishwaldo requested a review from lupyuen as a code owner September 6, 2026 10:46
@github-actions github-actions Bot added Arch: risc-v Issues related to the RISC-V (32-bit or 64-bit) architecture Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. Board: risc-v labels Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

xiaoxiang781216
xiaoxiang781216 previously approved these changes Sep 6, 2026
@acassis

acassis commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

@Fishwaldo please fix the conflicts

The Clock and Reset Generator holds the reset line for every block on
the SoC.  This registers all 324 of them with the NuttX reset framework
as a provider implementing assert, deassert, reset and status.

A line is addressed as its control register index times thirty two plus
its bit, across 61 registers, so the ids are sparse in a space of 1952
and decoding one is arithmetic rather than a lookup.

Each register carries three masks over the same bits: which bits are
lines at all, which the hardware will not let software drive, and which
would take down the system that asserted them.  The last are still
registered and can be read and released; only assert and reset refuse
them.  Where each line falls, and why, is recorded beside the table.

The lines are active low, which the manual never states.  It is inferred
from the field naming, the reset defaults and both vendor Linux drivers.
If that inference is wrong then deassert asserts, so the evidence for it
is written out in full rather than left as a convention.

Several lines are absent from the manual, the GPIO resets at offset
0x438 among them.  They were recovered from the vendor device tree and
confirmed by asserting each one and watching the block stop responding.

Registration writes nothing to the hardware.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
A peripheral held in reset reads like one that is absent, and the boot
loader does not leave the same lines released on every board or every
boot.  One line at startup says how much is held:

  reset: 324 lines, 117 held

Beside the clock tree's line and for the same reason: the summary is
worth seeing on every boot, and the detail belongs in /proc where it can
be read when it is wanted.

The driver's error output is enabled, matching the clock driver.  Info
level is not, since nothing at that level prints on a healthy boot.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
Implements get_line, so /proc/reset names all 324 lines and gives the
register and bit each lives in.  The framework asks status() for the
asserted state.

The names do not survive compilation: they live in the enumeration, so
without a table a listing gives only numbers, and working back from one
to a peripheral means counting through the header.  The table costs
about 8 KiB and is built only when the procfs entry is.

The ids are sparse, 324 lines across a space of 1952, so the table is
sorted by id and searched rather than indexed, and an id naming no line
returns -ENODEV.  The framework skips those, which is what leaves the
listing dense.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
Makes /proc/reset available, so which peripherals are held can be read
while the board is running rather than only for the eight lines the
startup report names.

RESET_PROCFS depends on FS_PROCFS_REGISTER, which neither board set.
Without it the symbol is dropped when the configuration is regenerated
and the entry never appears, which is silent: the defconfig still reads
as though the feature were on.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
@Fishwaldo

Copy link
Copy Markdown
Contributor Author

I'll have to rebase this one after my other open PR lands as this will conflict as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: risc-v Issues related to the RISC-V (32-bit or 64-bit) architecture Board: risc-v Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants