diff options
author | Dave Airlie <airlied@redhat.com> | 2024-01-16 11:49:46 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2024-01-16 11:49:46 +1000 |
commit | f6efb996a97abea2954b3bad38f2617712015844 (patch) | |
tree | 8f652a005c05797efbcb52e8bb15c22f530bf403 /drivers/gpu/drm/nova/gsp.rs | |
parent | b6214aa6152cc7adf23f14d3c12bbd03ae2829d4 (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.rs | 85 |
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(()) + } +} |