mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 23:59:33 -04:00
gpu: nova-core: wait for RISC-V HALTED on FSP unload
Currently the code waits for "not active" but this is not the same as
halted as there are more than two states. Match openrm here and wait for
halted instead.
Fixes: c7fea1f709 ("gpu: nova-core: add non-sec2 unload path")
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260703-blackwell-fixes-v2-10-8e3d8bc32bb9@nvidia.com
[acourbot: s/imply/guarantee.]
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
committed by
Alexandre Courbot
parent
5557c238eb
commit
71d4e7233f
@@ -749,11 +749,22 @@ pub(crate) fn signature_reg_fuse_version(
|
||||
|
||||
/// Check if the RISC-V core is active.
|
||||
///
|
||||
/// Note that this does not guarantee that the RISC-V core is halted if it returns `false`.
|
||||
///
|
||||
/// Returns `true` if the RISC-V core is active, `false` otherwise.
|
||||
pub(crate) fn is_riscv_active(&self) -> bool {
|
||||
self.hal.is_riscv_active(self)
|
||||
}
|
||||
|
||||
/// Checks whether the RISC-V core is halted.
|
||||
///
|
||||
/// Note that this does not guarantee that the RISC-V core is active if it returns `false`.
|
||||
///
|
||||
/// Returns [`ENOTSUPP`] if the status is not available.
|
||||
pub(crate) fn is_riscv_halted(&self) -> Result<bool> {
|
||||
self.hal.is_riscv_halted(self)
|
||||
}
|
||||
|
||||
/// Load a firmware image into Falcon memory, using the preferred method for the current
|
||||
/// chipset.
|
||||
pub(crate) fn load<F: FalconFirmware<Target = E> + FalconDmaLoadable>(&self, fw: &F) -> Result {
|
||||
|
||||
@@ -53,6 +53,11 @@ fn signature_reg_fuse_version(
|
||||
/// Returns `true` if the RISC-V core is active, `false` otherwise.
|
||||
fn is_riscv_active(&self, falcon: &Falcon<'_, E>) -> bool;
|
||||
|
||||
/// Checks whether the RISC-V core is halted.
|
||||
///
|
||||
/// Returns [`ENOTSUPP`] if the chipset does not expose RISC-V halt status.
|
||||
fn is_riscv_halted(&self, falcon: &Falcon<'_, E>) -> Result<bool>;
|
||||
|
||||
/// Wait for memory scrubbing to complete.
|
||||
fn reset_wait_mem_scrubbing(&self, falcon: &Falcon<'_, E>) -> Result;
|
||||
|
||||
|
||||
@@ -139,6 +139,13 @@ fn is_riscv_active(&self, falcon: &Falcon<'_, E>) -> bool {
|
||||
.active_stat()
|
||||
}
|
||||
|
||||
fn is_riscv_halted(&self, falcon: &Falcon<'_, E>) -> Result<bool> {
|
||||
Ok(falcon
|
||||
.bar
|
||||
.read(regs::NV_PRISCV_RISCV_CPUCTL::of::<E>())
|
||||
.halted())
|
||||
}
|
||||
|
||||
fn reset_wait_mem_scrubbing(&self, falcon: &Falcon<'_, E>) -> Result {
|
||||
// TIMEOUT: memory scrubbing should complete in less than 20ms.
|
||||
read_poll_timeout(
|
||||
|
||||
@@ -55,6 +55,10 @@ fn is_riscv_active(&self, falcon: &Falcon<'_, E>) -> bool {
|
||||
.active_stat()
|
||||
}
|
||||
|
||||
fn is_riscv_halted(&self, _falcon: &Falcon<'_, E>) -> Result<bool> {
|
||||
Err(ENOTSUPP)
|
||||
}
|
||||
|
||||
fn reset_wait_mem_scrubbing(&self, falcon: &Falcon<'_, E>) -> Result {
|
||||
// TIMEOUT: memory scrubbing should complete in less than 10ms.
|
||||
read_poll_timeout(
|
||||
|
||||
@@ -116,8 +116,15 @@ impl UnloadBundle for FspUnloadBundle {
|
||||
fn run(&self, ctx: &mut GspBootContext<'_, '_>) -> Result {
|
||||
// GSP falcon does most of the work of resetting, so just wait for it to finish.
|
||||
read_poll_timeout(
|
||||
|| Ok(ctx.gsp_falcon.is_riscv_active()),
|
||||
|&active| !active,
|
||||
|| {
|
||||
// GSP register reads are not meaningful until the PRIV target mask is released.
|
||||
if !ctx.gsp_falcon.priv_target_mask_released() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
ctx.gsp_falcon.is_riscv_halted()
|
||||
},
|
||||
|&halted| halted,
|
||||
Delta::from_millis(10),
|
||||
Delta::from_secs(5),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user