summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nova/gpu.rs
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nova/gpu.rs')
-rw-r--r--drivers/gpu/drm/nova/gpu.rs59
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(())
}
}