xref: /linux/drivers/gpu/nova-core/firmware.rs (revision 07dad44aa9a93b16af19e8609a10b241c352b440)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Contains structures and functions dedicated to the parsing, building and patching of firmwares
4 //! to be loaded into a given execution unit.
5 
6 use kernel::device;
7 use kernel::firmware;
8 use kernel::prelude::*;
9 use kernel::str::CString;
10 
11 use crate::gpu;
12 use crate::gpu::Chipset;
13 
14 pub(crate) const FIRMWARE_VERSION: &str = "535.113.01";
15 
16 /// Structure encapsulating the firmware blobs required for the GPU to operate.
17 #[expect(dead_code)]
18 pub(crate) struct Firmware {
19     booter_load: firmware::Firmware,
20     booter_unload: firmware::Firmware,
21     bootloader: firmware::Firmware,
22     gsp: firmware::Firmware,
23 }
24 
25 impl Firmware {
26     pub(crate) fn new(dev: &device::Device, chipset: Chipset, ver: &str) -> Result<Firmware> {
27         let mut chip_name = CString::try_from_fmt(fmt!("{chipset}"))?;
28         chip_name.make_ascii_lowercase();
29         let chip_name = &*chip_name;
30 
31         let request = |name_| {
32             CString::try_from_fmt(fmt!("nvidia/{chip_name}/gsp/{name_}-{ver}.bin"))
33                 .and_then(|path| firmware::Firmware::request(&path, dev))
34         };
35 
36         Ok(Firmware {
37             booter_load: request("booter_load")?,
38             booter_unload: request("booter_unload")?,
39             bootloader: request("bootloader")?,
40             gsp: request("gsp")?,
41         })
42     }
43 }
44 
45 pub(crate) struct ModInfoBuilder<const N: usize>(firmware::ModInfoBuilder<N>);
46 
47 impl<const N: usize> ModInfoBuilder<N> {
48     const fn make_entry_file(self, chipset: &str, fw: &str) -> Self {
49         ModInfoBuilder(
50             self.0
51                 .new_entry()
52                 .push("nvidia/")
53                 .push(chipset)
54                 .push("/gsp/")
55                 .push(fw)
56                 .push("-")
57                 .push(FIRMWARE_VERSION)
58                 .push(".bin"),
59         )
60     }
61 
62     const fn make_entry_chipset(self, chipset: &str) -> Self {
63         self.make_entry_file(chipset, "booter_load")
64             .make_entry_file(chipset, "booter_unload")
65             .make_entry_file(chipset, "bootloader")
66             .make_entry_file(chipset, "gsp")
67     }
68 
69     pub(crate) const fn create(
70         module_name: &'static kernel::str::CStr,
71     ) -> firmware::ModInfoBuilder<N> {
72         let mut this = Self(firmware::ModInfoBuilder::new(module_name));
73         let mut i = 0;
74 
75         while i < gpu::Chipset::NAMES.len() {
76             this = this.make_entry_chipset(gpu::Chipset::NAMES[i]);
77             i += 1;
78         }
79 
80         this.0
81     }
82 }
83