Switch all existing platform overrides to use the helper pattern instead
of the platform hooks. After this commit, only the .match_table and
.init members of struct platform_override are used.
There are two minor behavioral differences:
- For Allwinner D1, fdt_add_cpu_idle_states() is now called before the
body of generic_final_init(). This should have no functional impact.
- For StarFive JH7110, if the /chosen/starfive,boot-hart-id property is
missing, the code now falls back to using generic_coldboot_harts,
instead of accepting any hart.
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-7-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
The per-hart PLIC pointer is not really specific to FDT platforms. Move
it into the main driver and drop the extra wrapper functions.
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Move the PLIC save/restore functions inside the driver, so they can be
reused on any platform that needs them. The memory needed to store the
PLIC context is also allocated by the driver. The PM data cannot be
completely encapsulated, as some platforms (including Allwinner D1) need
to program the IRQ enable status to a sideband interrupt controller for
wakeup capability.
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Several of these override functions access the FDT blob. Explicitly
indicate which callbacks are allowed to modify the FDT blob by passing
the parameter as a possibly-const pointer. This also reduces code size
by deduplicating the call to fdt_get_address().
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
The address of the local scratch area is stored in each hart's mscratch
CSR. It is more efficient to read the CSR than to compute the address
from the hart ID.
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
All T-Head CSRs are already defined in thead/c9xx_encoding.h.
Let's reuse the values from there instead of redefining them with
a slightly different name.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Reviewed-by: Anup Patel <anup@brainfault.org>
Separate the implement of T-HEAD c9xx pmu to allow any platform with
c9xx cores can use it.
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
The CSR encoding for t-head c9xx cores is shared across all the
platforms with these cores. So move header thead_c9xx.h to the
thead subdir.
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Acked-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
T-HEAD c9xx pmu needs to clear OV bits of MCOUNTEROF in any condition
to avoid unnecessary OF interrupts.
In addition, the S-mode SCOUNTEROF only have OF bit set when the related
bits of MCOUNTERWEN is set, so also configure MCOUNTERWEN to allow kernel
to access valid SCOUNTEROF.
Signed-off-by: Haijiao Liu <haijiao.liu@sophgo.com>
Co-authored-by: Inochi Amaoto <inochiama@outlook.com>
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Samuel Holland <samuel@sholland.org>
The code calls various macros from riscv_asm.h and sbi_scratch.h
which are not directly included. Fix such dependency.
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Add D1's nonretentive suspend state to the devicetree so S-mode software
knows about it and can use it.
Latency and power measurements were taken on an Allwinner Nezha board:
- Entry latency was measured from the beginning of sbi_ecall_handler()
to before the call to wfi() in sun20i_d1_hart_suspend().
- Exit latency was measured from the beginning of sbi_init() to before
the call to sbi_hart_switch_mode() in init_warmboot().
- There was a 17.5 mW benefit from non-retentive suspend compared to
WFI, with a 170 mW cost during the 107 us entry/exit period. This
provides a break-even point around 1040 us. Residency includes entry
latency, so round this up to 1100 us.
- The hardware power sequence latency (after the WFI) is assumed to be
negligible, so set the wakeup latency to the exit latency.
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
The two referenced commits passed incorrect bounds to the PLIC save/
restore functions, causing out-of-bounds memory access. The functions
expect "num" to be the 1-based number of interrupt sources, equivalent
to the "riscv,ndev" devicetree property. Thus, "num" must be strictly
smaller than the 0-based size of the array storing the register values.
However, the referenced commits incorrectly passed in the unmodified
size of the array as "num". Fix this by reducing PLIC_SOURCES (matching
"riscv,ndev" on this platform), while keeping the same array sizes.
Addresses-Coverity-ID: 1530251 ("Out-of-bounds access")
Addresses-Coverity-ID: 1530252 ("Out-of-bounds access")
Fixes: 8509e46ca6 ("lib: utils/irqchip: plic: Ensure no out-of-bound access in priority save/restore helpers")
Fixes: 9a2eeb4aae ("lib: utils/irqchip: plic: Ensure no out-of-bound access in context save/restore helpers")
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Currently the context save/restore helpers writes/reads the provided
array using an index whose maximum value is determined by PLIC, which
potentially may disagree with the caller to these helpers.
Add a parameter to ask the caller to provide the size limit of the
array to ensure no out-of-bound access happens.
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Currently the priority save/restore helpers writes/reads the provided
array using an index whose maximum value is determined by PLIC, which
potentially may disagree with the caller to these helpers.
Add a parameter to ask the caller to provide the size limit of the
array to ensure no out-of-bound access happens.
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Corrected the same parameter of writel_relaxed in sun20i_d1_riscv_cfg_init
to be u32 for a while and u64 for a while.
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
With the T-HEAD C9XX cores being designed before or during ratification
of the SSCOFPMF extension, they implement a PMU extension that behaves
very similar but not equal to it by providing overflow interrupts though
in a slightly different registers format.
The sun20i-d1 is using this core. So implement the necessary overrides
to allow its pmu to be used via the standard sbi-pmu extension.
For now it's also the only soc using this core, so keep the additional
code in the d1-space for now.
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Allwinner D1 contains a "PPU" power domain controller which can
automatically power down/up the CPU power domain. This power domain
includes the C906 core along with its CLINT and PLIC.
This HSM implementation supports non-retentive hart suspend by:
1) Saving/restoring state that is lost during hart suspend,
2) Performing cache maintenance before/after hart suspend,
3) Configuring wakeup sources before hart suspend, and
4) Asking the PPU to power down the hart when it enters WFI.
Since this HSM implementation is for a single-core SoC, it does not need
to worry about concurrency or saving multiple instances of state.
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>