mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	 e7c96980ea
			
		
	
	
		e7c96980ea
		
	
	
	
	
		
			
			Right now the GSP boot code is very incomplete and limited to running FRTS, so having it in `Gpu::new` is not a big constraint. However, this will change as we add more steps of the GSP boot process, and not all GPU families follow the same procedure, so having these steps in a dedicated method is the logical construct. There is also the fact the GSP will require its own runtime data, and while it won't immediately need to be pinned, we want to be ready for the time where it will - most likely when it starts using mutexes. Thus, add an empty `Gsp` type that is pinned inside `Gpu` and initialized using a pin initializer. This sets the constraint we need to observe from the start, and could spare us some costly refactoring down the road. Then, move the code related to GSP boot to the `gsp::boot` module, as part of the `Gsp` implementation. Doing so allows us to make `Gpu::new` return a fallible `impl PinInit` instead of a `Result.` This is more idiomatic when working with pinned objects, and sets up the pinned initialization pattern we want to preserve as the code grows more complex. Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20250913-nova_firmware-v6-2-9007079548b0@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
		
			
				
	
	
		
			66 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| 
 | |
| use kernel::{auxiliary, bindings, c_str, device::Core, pci, prelude::*, sizes::SZ_16M, sync::Arc};
 | |
| 
 | |
| use crate::gpu::Gpu;
 | |
| 
 | |
| #[pin_data]
 | |
| pub(crate) struct NovaCore {
 | |
|     #[pin]
 | |
|     pub(crate) gpu: Gpu,
 | |
|     _reg: auxiliary::Registration,
 | |
| }
 | |
| 
 | |
| const BAR0_SIZE: usize = SZ_16M;
 | |
| pub(crate) type Bar0 = pci::Bar<BAR0_SIZE>;
 | |
| 
 | |
| kernel::pci_device_table!(
 | |
|     PCI_TABLE,
 | |
|     MODULE_PCI_TABLE,
 | |
|     <NovaCore as pci::Driver>::IdInfo,
 | |
|     [(
 | |
|         pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_NVIDIA, bindings::PCI_ANY_ID as u32),
 | |
|         ()
 | |
|     )]
 | |
| );
 | |
| 
 | |
| impl pci::Driver for NovaCore {
 | |
|     type IdInfo = ();
 | |
|     const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
 | |
| 
 | |
|     fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
 | |
|         dev_dbg!(pdev.as_ref(), "Probe Nova Core GPU driver.\n");
 | |
| 
 | |
|         pdev.enable_device_mem()?;
 | |
|         pdev.set_master();
 | |
| 
 | |
|         let devres_bar = Arc::pin_init(
 | |
|             pdev.iomap_region_sized::<BAR0_SIZE>(0, c_str!("nova-core/bar0")),
 | |
|             GFP_KERNEL,
 | |
|         )?;
 | |
| 
 | |
|         // Used to provided a `&Bar0` to `Gpu::new` without tying it to the lifetime of
 | |
|         // `devres_bar`.
 | |
|         let bar_clone = Arc::clone(&devres_bar);
 | |
|         let bar = bar_clone.access(pdev.as_ref())?;
 | |
| 
 | |
|         let this = KBox::pin_init(
 | |
|             try_pin_init!(Self {
 | |
|                 gpu <- Gpu::new(pdev, devres_bar, bar),
 | |
|                 _reg: auxiliary::Registration::new(
 | |
|                     pdev.as_ref(),
 | |
|                     c_str!("nova-drm"),
 | |
|                     0, // TODO[XARR]: Once it lands, use XArray; for now we don't use the ID.
 | |
|                     crate::MODULE_NAME
 | |
|                 )?,
 | |
|             }),
 | |
|             GFP_KERNEL,
 | |
|         )?;
 | |
| 
 | |
|         Ok(this)
 | |
|     }
 | |
| 
 | |
|     fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
 | |
|         this.gpu.unbind(pdev.as_ref());
 | |
|     }
 | |
| }
 |