On Fri, 27 Feb 2026 21:32:12 +0900 Eliot Courtney <[email protected]> wrote:
Tested-by: Zhi Wang <[email protected]> > Add `RmControl` which implements CommandToGsp for sending RM control > RPCs. > > Add `RmControlReply` which implements MessageFromGsp for getting the > reply back. > > Add `send_rm_control` which sends an RM control RPC via the command > queue using the above structures. > > This gives a generic way to send each RM control RPC. Each new RM > control RPC can be added by extending RmControlMsgFunction and adding > its bindings wrappers and writing a helper function to send it via > `send_rm_control`. > > Signed-off-by: Eliot Courtney <[email protected]> > --- > drivers/gpu/nova-core/gsp.rs | 1 + > drivers/gpu/nova-core/gsp/rm.rs | 3 + > drivers/gpu/nova-core/gsp/rm/commands.rs | 111 > +++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) > > diff --git a/drivers/gpu/nova-core/gsp.rs > b/drivers/gpu/nova-core/gsp.rs index a6f3918c20b1..1a1c4e9808ac 100644 > --- a/drivers/gpu/nova-core/gsp.rs > +++ b/drivers/gpu/nova-core/gsp.rs > @@ -17,6 +17,7 @@ > pub(crate) mod cmdq; > pub(crate) mod commands; > mod fw; > +pub(crate) mod rm; > mod sequencer; > > pub(crate) use fw::{ > diff --git a/drivers/gpu/nova-core/gsp/rm.rs > b/drivers/gpu/nova-core/gsp/rm.rs new file mode 100644 > index 000000000000..10e879a3e842 > --- /dev/null > +++ b/drivers/gpu/nova-core/gsp/rm.rs > @@ -0,0 +1,3 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +pub(crate) mod commands; > diff --git a/drivers/gpu/nova-core/gsp/rm/commands.rs > b/drivers/gpu/nova-core/gsp/rm/commands.rs new file mode 100644 > index 000000000000..16bcf88644db > --- /dev/null > +++ b/drivers/gpu/nova-core/gsp/rm/commands.rs > @@ -0,0 +1,111 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +use core::{ > + array, > + convert::Infallible, // > +}; > + > +use kernel::prelude::*; > + > +use crate::{ > + driver::Bar0, > + gsp::{ > + cmdq::{ > + Cmdq, > + CommandToGsp, > + MessageFromGsp, // > + }, > + fw::{ > + rm::*, > + MsgFunction, > + NvStatus, // > + }, > + }, > + sbuffer::SBufferIter, > +}; > + > +/// Command for sending an RM control message to the GSP. > +struct RmControl<'a> { > + h_client: u32, > + h_object: u32, > + cmd: RmControlMsgFunction, > + params: &'a [u8], > +} > + > +impl<'a> RmControl<'a> { > + /// Creates a new RM control command. > + fn new(h_client: u32, h_object: u32, cmd: RmControlMsgFunction, > params: &'a [u8]) -> Self { > + Self { > + h_client, > + h_object, > + cmd, > + params, > + } > + } > +} > + > +impl CommandToGsp for RmControl<'_> { > + const FUNCTION: MsgFunction = MsgFunction::GspRmControl; > + type Command = GspRmControl; > + type Reply = RmControlReply; > + type InitError = Infallible; > + > + fn init(&self) -> impl Init<Self::Command, Self::InitError> { > + GspRmControl::new( > + self.h_client, > + self.h_object, > + self.cmd, > + self.params.len() as u32, > + ) > + } > + > + fn variable_payload_len(&self) -> usize { > + self.params.len() > + } > + > + fn init_variable_payload( > + &self, > + dst: &mut SBufferIter<array::IntoIter<&mut [u8], 2>>, > + ) -> Result { > + dst.write_all(self.params) > + } > +} > + > +/// Response from an RM control message. > +pub(crate) struct RmControlReply { > + status: NvStatus, > + params: KVVec<u8>, > +} > + > +impl MessageFromGsp for RmControlReply { > + const FUNCTION: MsgFunction = MsgFunction::GspRmControl; > + type Message = GspRmControl; > + type InitError = Error; > + > + fn read( > + msg: &Self::Message, > + sbuffer: &mut SBufferIter<array::IntoIter<&[u8], 2>>, > + ) -> Result<Self, Self::InitError> { > + Ok(RmControlReply { > + status: msg.status(), > + params: sbuffer.flush_into_kvvec(GFP_KERNEL)?, > + }) > + } > +} > + > +/// Sends an RM control command, checks the reply status, and > returns the raw parameter bytes. +#[expect(dead_code)] > +fn send_rm_control( > + cmdq: &Cmdq, > + bar: &Bar0, > + h_client: u32, > + h_object: u32, > + cmd: RmControlMsgFunction, > + params: &[u8], > +) -> Result<KVVec<u8>> { > + let reply = cmdq.send_sync_command(bar, RmControl::new(h_client, > h_object, cmd, params))?; + > + Result::from(reply.status)?; > + > + Ok(reply.params) > +} >
