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