From: Alistair Popple <apop...@nvidia.com> This adds the GSP init done command to wait for GSP initialisation to complete. Once this command has been received the GSP is fully operational and will respond properly to normal RPC commands.
Co-developed-by: Joel Fernandes <joelagn...@nvidia.com> Signed-off-by: Alistair Popple <apop...@nvidia.com> --- drivers/gpu/nova-core/gpu.rs | 3 +++ drivers/gpu/nova-core/gsp/commands.rs | 34 +++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index c2a9cb32837f..023bafc85f58 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -10,6 +10,7 @@ use crate::firmware::{Firmware, FIRMWARE_VERSION}; use crate::gfw; use crate::gsp; +use crate::gsp::commands::gsp_init_done; use crate::regs; use crate::util; use crate::vbios::Vbios; @@ -375,6 +376,8 @@ pub(crate) fn new( Delta::from_secs(10), )?; + gsp_init_done(&mut libos.cmdq, Delta::from_secs(10))?; + Ok(pin_init!(Self { spec, bar: devres_bar, diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs index 12ea8cdec21d..9f858aedf853 100644 --- a/drivers/gpu/nova-core/gsp/commands.rs +++ b/drivers/gpu/nova-core/gsp/commands.rs @@ -8,13 +8,15 @@ use kernel::device; use kernel::pci; use kernel::prelude::*; +use kernel::time::Delta; use kernel::transmute::{AsBytes, FromBytes}; use crate::driver::Bar0; -use crate::gsp::cmdq::GspCommandToGsp; -use crate::gsp::cmdq::GspCmdq; +use crate::gsp::cmdq::{GspCommandToGsp, GspMessageFromGsp}; +use crate::gsp::GspCmdq; use crate::gsp::GSP_PAGE_SIZE; use crate::nvfw::{ + NV_VGPU_MSG_EVENT_GSP_INIT_DONE, NV_VGPU_MSG_FUNCTION_SET_REGISTRY, NV_VGPU_MSG_FUNCTION_GSP_SET_SYSTEM_INFO, GspSystemInfo, @@ -32,6 +34,34 @@ unsafe impl AsBytes for GspSystemInfo {} // that is not a problem because they are not used outside the kernel. unsafe impl FromBytes for GspSystemInfo {} +struct GspInitDone {} +impl GspMessageFromGsp for GspInitDone { + const FUNCTION: u32 = NV_VGPU_MSG_EVENT_GSP_INIT_DONE; +} + +pub(crate) fn gsp_init_done(cmdq: &mut GspCmdq, timeout: Delta) -> Result { + loop { + cmdq.wait_for_msg_from_gsp(timeout)?; + let msg = loop { + match cmdq.receive_msg_from_gsp() { + Ok(x) => break Ok(x), + Err(EAGAIN) => continue, + Err(x) => break Err(x), + }; + }?; + + let init_done = msg.try_as::<GspInitDone>().map(|_| ()); + + msg.ack()?; + + match init_done { + Ok(()) => break Ok(()), + Err(ERANGE) => continue, + Err(e) => break Err(e), + }; + } +} + const GSP_REGISTRY_NUM_ENTRIES: usize = 2; struct RegistryEntry { key: &'static str, -- 2.34.1