xref: /linux/drivers/gpu/nova-core/driver.rs (revision 0242623384c767b1156b61b67894b4ecf6682b8b)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 use kernel::{
4     auxiliary, c_str,
5     device::Core,
6     pci,
7     pci::{Class, ClassMask, Vendor},
8     prelude::*,
9     sizes::SZ_16M,
10     sync::Arc,
11 };
12 
13 use crate::gpu::Gpu;
14 
15 #[pin_data]
16 pub(crate) struct NovaCore {
17     #[pin]
18     pub(crate) gpu: Gpu,
19     _reg: auxiliary::Registration,
20 }
21 
22 const BAR0_SIZE: usize = SZ_16M;
23 pub(crate) type Bar0 = pci::Bar<BAR0_SIZE>;
24 
25 kernel::pci_device_table!(
26     PCI_TABLE,
27     MODULE_PCI_TABLE,
28     <NovaCore as pci::Driver>::IdInfo,
29     [
30         // Modern NVIDIA GPUs will show up as either VGA or 3D controllers.
31         (
32             pci::DeviceId::from_class_and_vendor(
33                 Class::DISPLAY_VGA,
34                 ClassMask::ClassSubclass,
35                 Vendor::NVIDIA
36             ),
37             ()
38         ),
39         (
40             pci::DeviceId::from_class_and_vendor(
41                 Class::DISPLAY_3D,
42                 ClassMask::ClassSubclass,
43                 Vendor::NVIDIA
44             ),
45             ()
46         ),
47     ]
48 );
49 
50 impl pci::Driver for NovaCore {
51     type IdInfo = ();
52     const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
53 
54     fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
55         pin_init::pin_init_scope(move || {
56             dev_dbg!(pdev.as_ref(), "Probe Nova Core GPU driver.\n");
57 
58             pdev.enable_device_mem()?;
59             pdev.set_master();
60 
61             let bar = Arc::pin_init(
62                 pdev.iomap_region_sized::<BAR0_SIZE>(0, c_str!("nova-core/bar0")),
63                 GFP_KERNEL,
64             )?;
65 
66             Ok(try_pin_init!(Self {
67                 gpu <- Gpu::new(pdev, bar.clone(), bar.access(pdev.as_ref())?),
68                 _reg: auxiliary::Registration::new(
69                     pdev.as_ref(),
70                     c_str!("nova-drm"),
71                     0, // TODO[XARR]: Once it lands, use XArray; for now we don't use the ID.
72                     crate::MODULE_NAME
73                 )?,
74             }))
75         })
76     }
77 
78     fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
79         this.gpu.unbind(pdev.as_ref());
80     }
81 }
82