1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
use kernel::{
error::Result,
io_mem::IoMem,
pci,
prelude::*,
};
use crate::bios::*;
use crate::gsp::*;
use crate::driver::BAR_SIZE;
#[derive(PartialEq)]
pub(crate) enum CardType {
TU100 = 0x160,
GA100 = 0x170,
AD100 = 0x190,
}
pub(crate) struct Gpu {
vidmem_size: u64,
vga_workspace_addr: u64,
vga_workspace_size: u64,
card_type: CardType,
bar: IoMem<BAR_SIZE>,
bios: Bios,
gsp: Gsp,
}
impl Gpu {
pub(crate) fn new(card_type: CardType, bar: IoMem<BAR_SIZE>) -> Self
{
Self {
card_type: card_type,
bar: bar,
vidmem_size: 0,
vga_workspace_addr: 0,
vga_workspace_size : 0,
bios: Bios::new(),
gsp: Gsp::new(),
}
}
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;
}
addr = (addr & 0xffffff00) << 8;
if addr < base {
return self.vidmem_size - 0x20000;
}
addr
}
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(())
}
}
|