summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nova/gsp.rs
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2024-01-16 11:49:46 +1000
committerDave Airlie <airlied@redhat.com>2024-01-16 11:49:46 +1000
commitf6efb996a97abea2954b3bad38f2617712015844 (patch)
tree8f652a005c05797efbcb52e8bb15c22f530bf403 /drivers/gpu/drm/nova/gsp.rs
parentb6214aa6152cc7adf23f14d3c12bbd03ae2829d4 (diff)
nova: add a gsp object with fw / radix3wip/fw-loader
The radix3 impl in this needs some scatterlist bindings I expect. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nova/gsp.rs')
-rw-r--r--drivers/gpu/drm/nova/gsp.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nova/gsp.rs b/drivers/gpu/drm/nova/gsp.rs
new file mode 100644
index 000000000000..53367aba2210
--- /dev/null
+++ b/drivers/gpu/drm/nova/gsp.rs
@@ -0,0 +1,85 @@
+use kernel::{
+ error::Result,
+ c_str,
+ firmware::{Firmware},
+ pci,
+ dma::{CoherentAllocation, CoherentAllocator,try_alloc_coherent},
+};
+
+use alloc::vec::Vec;
+use crate::driver::align;
+
+const GSP_PAGE_SHIFT: u32 = 12;
+const GSP_PAGE_SIZE: u32 = 1 << GSP_PAGE_SHIFT;
+
+#[derive(Default)]
+pub(crate) struct GspRadix3 {
+ pub(crate) mem: Vec<CoherentAllocation<u64, CoherentAllocator>>,
+}
+
+impl GspRadix3 {
+
+ pub (crate) fn try_new(size: usize, dev: &mut pci::Device) -> Result<GspRadix3>
+ {
+ let mut gsp_radix3: GspRadix3 = Default::default();
+ let mut lvl_size = size;
+ let addr = 0;
+ for i in (0..2).rev() {
+ let tbl_size: usize = align::<usize>((lvl_size as usize / 4096) * 8 as usize, GSP_PAGE_SIZE as usize);
+
+ gsp_radix3.mem.try_push(try_alloc_coherent(dev, tbl_size as usize, false)?)?;
+
+ if i == 2 {
+ // TODO this is the main piece
+ } else {
+ for j in 0..size / GSP_PAGE_SIZE as usize {
+ let entry: u64 = (addr + GSP_PAGE_SIZE as usize * j) as u64;
+ gsp_radix3.mem[i].write(j, &entry);
+ }
+ }
+
+ lvl_size = tbl_size;
+ }
+ Ok(gsp_radix3)
+ }
+
+}
+
+pub(crate) struct Gsp {
+ booter_load_fw: Firmware,
+ booter_unload_fw: Firmware,
+ gsp_fw: Firmware,
+ radix3: Option<GspRadix3>,
+}
+
+impl Gsp {
+ pub(crate) fn new() -> Self
+ {
+ Self {
+ booter_load_fw: Firmware::new(),
+ booter_unload_fw: Firmware::new(),
+ gsp_fw: Firmware::new(),
+ radix3: None,
+ }
+ }
+
+ pub(crate) fn init(&mut self, dev: &mut pci::Device) -> Result {
+ match self.booter_load_fw.request(c_str!("nvidia/ad102/gsp/booter_load-535.113.01.bin"), dev) {
+ Err(e) => return Err(e),
+ Ok(_) => ()
+ }
+
+ match self.booter_unload_fw.request(c_str!("nvidia/ad102/gsp/booter_unload-535.113.01.bin"), dev) {
+ Err(e) => return Err(e),
+ Ok(_) => ()
+ }
+
+ match self.gsp_fw.request(c_str!("nvidia/ad102/gsp/gsp-535.113.01.bin"), dev) {
+ Err(e) => return Err(e),
+ Ok(_) => (),
+ }
+
+ self.radix3 = Some(GspRadix3::try_new(1024, dev)?);
+ Ok(())
+ }
+}