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