MCPcopy Index your code
hub / github.com/FrameworkComputer/framework-system / get_version

Function get_version

framework_lib/src/parade_retimer.rs:10–66  ·  view source on GitHub ↗
(ec: &CrosEc)

Source from the content-addressed store, hash-verified

8use crate::os_specific;
9
10pub fn get_version(ec: &CrosEc) -> EcResult<Option<Vec<u8>>> {
11 let res = EcRequestGetGpuPcie {}.send_command(ec)?;
12 let vendor: Option<GpuVendor> = FromPrimitive::from_u8(res.gpu_vendor);
13 info!("GPU vendor: {:?}", vendor);
14 if vendor != Some(GpuVendor::NvidiaGn22) {
15 info!("No compatible retimer present (vendor mismatch)");
16 return Ok(None);
17 };
18 info!("NVIDIA GPU detected, checking retimer...");
19
20 // I2C Port on the EC
21 let i2c_port = 5;
22 // 8-bit I2C address of the retimer
23 // EC passthrough needs 7-bit, so shift one over before sending to EC
24 let i2c_addr = 0x10;
25
26 // Check safe mode
27 info!(
28 "Reading retimer at I2C port {} addr 0x{:02X}",
29 i2c_port,
30 i2c_addr >> 1
31 );
32 let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x00, 0x01)?;
33 info!(
34 "I2C response: status=0x{:02X}, data_len={}",
35 i2c_response.i2c_status,
36 i2c_response.data.len()
37 );
38 if i2c_response.i2c_status == 0x01 {
39 // NAK
40 warn!("Unable to communicate with dGPU Retimer. Try to force it on by plugging a cable into the dGPU");
41 }
42 let Some(&safe_mode) = i2c_response.data.first() else {
43 info!("Failed to read retimer safe mode status (empty response)");
44 return Ok(None);
45 };
46 info!("Retimer safe mode status: {}", safe_mode);
47 if safe_mode == 0 {
48 // Safe mode not enabled, enable it
49 i2c_write(ec, i2c_port, i2c_addr >> 1, 0x00, &[0x01])?;
50 }
51
52 // Wake up from low power mode
53 for _ in 0..3 {
54 let i2c_response = i2c_read(ec, i2c_port, (i2c_addr + 2) >> 1, 0x70, 0x01)?;
55 if i2c_response.data.first() == Some(&0) {
56 continue;
57 }
58 i2c_write(ec, i2c_port, (i2c_addr + 2) >> 1, 0x70, &[0x00])?;
59 os_specific::sleep(50_000);
60 }
61
62 // Read version
63 let i2c_response = i2c_read(ec, i2c_port, (i2c_addr + 18) >> 1, 0x01, 0x04)?;
64
65 Ok(Some(i2c_response.data))
66}

Callers 1

print_versionsFunction · 0.85

Calls 4

i2c_readFunction · 0.85
i2c_writeFunction · 0.85
sleepFunction · 0.85
send_commandMethod · 0.45

Tested by

no test coverage detected