xref: /linux/drivers/gpu/nova-core/api.rs (revision 5b0764a53235d3c77e1ed674e836e1b3fe1a4b1f)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Nova-core auxbus data. Contains all the methods used by the auxbus drivers
4 //! to interact with nova-core.
5 
6 use core::pin::Pin;
7 
8 use kernel::{
9     auxiliary,
10     device::Bound,
11     pci,
12     prelude::*,
13     types::ForLt, //
14 };
15 
16 pub use crate::gpu::Spec;
17 
18 use crate::{
19     driver,
20     gpu::Gpu,
21     gsp::commands::GetGspStaticInfoReply, //
22 };
23 
24 /// API handle for the auxiliary bus child drivers to interact with nova-core.
25 pub struct NovaCoreApi<'bound> {
26     pub(crate) gpu: Pin<&'bound Gpu<'bound>>,
27     pub(crate) pdev: &'bound pci::Device<Bound>,
28 }
29 
30 impl NovaCoreApi<'_> {
31     /// Obtain a [`NovaCoreApi`] handle from an auxiliary device registered
32     /// by nova-core.
33     pub fn of(adev: &auxiliary::Device<Bound>) -> Result<NovaCoreApiHandle<'_>> {
34         NovaCoreApiHandle::of(adev)
35     }
36 
37     /// Returns the GPU [`GetGspStaticInfoReply`].
38     pub fn gsp_static_info(&self) -> &GetGspStaticInfoReply {
39         &self.gpu.gsp_static_info
40     }
41 
42     /// Returns the GPU [`Spec`].
43     pub fn spec(&self) -> &Spec {
44         &self.gpu.spec
45     }
46 
47     /// Returns the size of the PCIe BAR used for accessing VRAM, typically
48     /// BAR1.
49     pub fn bar1_size(&self) -> Result<u64> {
50         let bar1 = driver::bar1_resource_index(self.pdev)?;
51 
52         self.pdev.resource_len(bar1)
53     }
54 }
55 
56 /// Expose a handle to nova-core API
57 pub struct NovaCoreApiHandle<'a> {
58     adev: &'a auxiliary::Device<Bound>,
59 }
60 
61 impl<'a> NovaCoreApiHandle<'a> {
62     fn of(adev: &'a auxiliary::Device<Bound>) -> Result<Self> {
63         adev.registration_data_with::<ForLt!(NovaCoreApi<'_>), ()>(|_| ())?;
64         Ok(Self { adev })
65     }
66 
67     /// Access the [`NovaCoreApi`] through a closure.
68     pub fn with<R>(&self, f: impl for<'b> FnOnce(Pin<&'a NovaCoreApi<'b>>) -> R) -> R {
69         self.adev
70             .registration_data_with::<ForLt!(NovaCoreApi<'_>), R>(f)
71             .expect("TypeId was validated in NovaCoreApiHandle::of()")
72     }
73 }
74