Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpu/nova-core/driver.rs
48985 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
use kernel::{
4
auxiliary,
5
c_str,
6
device::Core,
7
devres::Devres,
8
dma::Device,
9
dma::DmaMask,
10
pci,
11
pci::{
12
Class,
13
ClassMask,
14
Vendor, //
15
},
16
prelude::*,
17
sizes::SZ_16M,
18
sync::Arc, //
19
};
20
21
use crate::gpu::Gpu;
22
23
#[pin_data]
24
pub(crate) struct NovaCore {
25
#[pin]
26
pub(crate) gpu: Gpu,
27
#[pin]
28
_reg: Devres<auxiliary::Registration>,
29
}
30
31
const BAR0_SIZE: usize = SZ_16M;
32
33
// For now we only support Ampere which can use up to 47-bit DMA addresses.
34
//
35
// TODO: Add an abstraction for this to support newer GPUs which may support
36
// larger DMA addresses. Limiting these GPUs to smaller address widths won't
37
// have any adverse affects, unless installed on systems which require larger
38
// DMA addresses. These systems should be quite rare.
39
const GPU_DMA_BITS: u32 = 47;
40
41
pub(crate) type Bar0 = pci::Bar<BAR0_SIZE>;
42
43
kernel::pci_device_table!(
44
PCI_TABLE,
45
MODULE_PCI_TABLE,
46
<NovaCore as pci::Driver>::IdInfo,
47
[
48
// Modern NVIDIA GPUs will show up as either VGA or 3D controllers.
49
(
50
pci::DeviceId::from_class_and_vendor(
51
Class::DISPLAY_VGA,
52
ClassMask::ClassSubclass,
53
Vendor::NVIDIA
54
),
55
()
56
),
57
(
58
pci::DeviceId::from_class_and_vendor(
59
Class::DISPLAY_3D,
60
ClassMask::ClassSubclass,
61
Vendor::NVIDIA
62
),
63
()
64
),
65
]
66
);
67
68
impl pci::Driver for NovaCore {
69
type IdInfo = ();
70
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
71
72
fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
73
pin_init::pin_init_scope(move || {
74
dev_dbg!(pdev.as_ref(), "Probe Nova Core GPU driver.\n");
75
76
pdev.enable_device_mem()?;
77
pdev.set_master();
78
79
// SAFETY: No concurrent DMA allocations or mappings can be made because
80
// the device is still being probed and therefore isn't being used by
81
// other threads of execution.
82
unsafe { pdev.dma_set_mask_and_coherent(DmaMask::new::<GPU_DMA_BITS>())? };
83
84
let bar = Arc::pin_init(
85
pdev.iomap_region_sized::<BAR0_SIZE>(0, c_str!("nova-core/bar0")),
86
GFP_KERNEL,
87
)?;
88
89
Ok(try_pin_init!(Self {
90
gpu <- Gpu::new(pdev, bar.clone(), bar.access(pdev.as_ref())?),
91
_reg <- auxiliary::Registration::new(
92
pdev.as_ref(),
93
c_str!("nova-drm"),
94
0, // TODO[XARR]: Once it lands, use XArray; for now we don't use the ID.
95
crate::MODULE_NAME
96
),
97
}))
98
})
99
}
100
101
fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
102
this.gpu.unbind(pdev.as_ref());
103
}
104
}
105
106