diff options
Diffstat (limited to 'drivers/gpu/drm/nova/gpu.rs')
-rw-r--r-- | drivers/gpu/drm/nova/gpu.rs | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nova/gpu.rs b/drivers/gpu/drm/nova/gpu.rs index d3f1890953b1..d8b80653bad8 100644 --- a/drivers/gpu/drm/nova/gpu.rs +++ b/drivers/gpu/drm/nova/gpu.rs @@ -2,15 +2,15 @@ use kernel::{ error::Result, io_mem::IoMem, - c_str, - firmware::{Firmware}, pci, + prelude::*, }; use crate::bios::*; - +use crate::gsp::*; use crate::driver::BAR_SIZE; +#[derive(PartialEq)] pub(crate) enum CardType { TU100 = 0x160, GA100 = 0x170, @@ -18,46 +18,65 @@ pub(crate) enum CardType { } pub(crate) struct Gpu { - booter_load_fw: Firmware, - booter_unload_fw: Firmware, - gsp_fw: Firmware, + vidmem_size: u64, + vga_workspace_addr: u64, + vga_workspace_size: u64, card_type: CardType, bar: IoMem<BAR_SIZE>, - bios: Bios + bios: Bios, + gsp: Gsp, } impl Gpu { pub(crate) fn new(card_type: CardType, bar: IoMem<BAR_SIZE>) -> Self { Self { - booter_load_fw: Firmware::new(), - booter_unload_fw: Firmware::new(), - gsp_fw: Firmware::new(), card_type: card_type, bar: bar, + vidmem_size: 0, + vga_workspace_addr: 0, + vga_workspace_size : 0, bios: Bios::new(), + gsp: Gsp::new(), } } - 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(_) => () + fn gsp_vga_workspace_addr(&self) -> u64 + { + let base: u64 = self.vidmem_size - 0x100000; + let mut addr: u64 = self.bar.readl(0x625f04) as u64; + + if (addr & 0x00000008) == 0 { + return base; } - match self.booter_unload_fw.request(c_str!("nvidia/ad102/gsp/booter_unload-535.113.01.bin"), dev) { - Err(e) => return Err(e), - Ok(_) => () + addr = (addr & 0xffffff00) << 8; + if addr < base { + return self.vidmem_size - 0x20000; } + addr + } - match self.gsp_fw.request(c_str!("nvidia/ad102/gsp/gsp-535.113.01.bin"), dev) { - Err(e) => return Err(e), - Ok(_) => (), + pub(crate) fn init(&mut self, dev: &mut pci::Device) -> Result { + // AD102 specific + + if self.card_type != CardType::AD100 { + return Err(ENOENT); } + self.vidmem_size = (self.bar.readl(0x1183a4) as u64) << 20; + + self.vga_workspace_addr = self.gsp_vga_workspace_addr(); + self.vga_workspace_size = self.vidmem_size - self.vga_workspace_addr; + + pr_info!("video memory size {:#x}: vga {:#x} {:#x}\n", self.vidmem_size, self.vga_workspace_addr, + self.vga_workspace_size); + self.bios.probe(&self.bar)?; self.bios.find_fwsec()?; + + self.gsp.init(dev)?; Ok(()) } } |