From 95579ce46deb17f103b1f99c79bfd239aa25b41c Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 26 Sep 2025 15:10:07 +0800 Subject: [PATCH 1/4] i2c_passthru: Use single byte address if enough Double byte address if the address is low causes issues on some devices (PS8835). Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/i2c_passthrough.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/framework_lib/src/chromium_ec/i2c_passthrough.rs b/framework_lib/src/chromium_ec/i2c_passthrough.rs index 03cb974e..d01aee86 100644 --- a/framework_lib/src/chromium_ec/i2c_passthrough.rs +++ b/framework_lib/src/chromium_ec/i2c_passthrough.rs @@ -79,7 +79,11 @@ pub fn i2c_read( len ))); } - let addr_bytes = u16::to_le_bytes(addr); + let addr_bytes = if addr < 0xFF { + vec![addr as u8] + } else { + u16::to_le_bytes(addr).to_vec() + }; let messages = vec![ EcParamsI2cPassthruMsg { addr_and_flags: i2c_addr, From ad54b0090ab0357fed019770ecf31e723f8a046e Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 23 Sep 2025 20:36:46 +0800 Subject: [PATCH 2/4] GpuVendor: Derive PartialEq Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index d9155bdc..b2c07068 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -1419,7 +1419,7 @@ pub enum GpuPcieConfig { } #[repr(u8)] -#[derive(Debug, FromPrimitive)] +#[derive(Debug, FromPrimitive, PartialEq)] pub enum GpuVendor { Initializing = 0x00, FanOnly = 0x01, From d7cce0c02d1dd15e3c2a62a3f30ff9232b76be8e Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 23 Sep 2025 20:37:04 +0800 Subject: [PATCH 3/4] parade_retimer: Allow reading firmware version Signed-off-by: Daniel Schaefer --- framework_lib/src/lib.rs | 1 + framework_lib/src/parade_retimer.rs | 44 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 framework_lib/src/parade_retimer.rs diff --git a/framework_lib/src/lib.rs b/framework_lib/src/lib.rs index f205403e..9bb1de7f 100644 --- a/framework_lib/src/lib.rs +++ b/framework_lib/src/lib.rs @@ -41,6 +41,7 @@ pub mod csme; pub mod ec_binary; pub mod esrt; mod os_specific; +pub mod parade_retimer; pub mod power; pub mod smbios; #[cfg(feature = "uefi")] diff --git a/framework_lib/src/parade_retimer.rs b/framework_lib/src/parade_retimer.rs new file mode 100644 index 00000000..f5d3b1f7 --- /dev/null +++ b/framework_lib/src/parade_retimer.rs @@ -0,0 +1,44 @@ +use alloc::vec::Vec; +use num_traits::FromPrimitive; + +use crate::chromium_ec::command::EcRequestRaw; +use crate::chromium_ec::commands::{EcRequestGetGpuPcie, GpuVendor}; +use crate::chromium_ec::i2c_passthrough::*; +use crate::chromium_ec::{CrosEc, EcResult}; +use crate::os_specific; + +pub fn get_version(ec: &CrosEc) -> EcResult>> { + let res = EcRequestGetGpuPcie {}.send_command(ec)?; + let vendor: Option = FromPrimitive::from_u8(res.gpu_vendor); + if vendor != Some(GpuVendor::NvidiaGn22) { + debug!("No compatible retimer present"); + return Ok(None); + }; + + // I2C Port on the EC + let i2c_port = 5; + // 8-bit I2C address of the retimer + // EC passthrough needs 7-bit, so shift one over before sending to EC + let i2c_addr = 0x10; + + // Check safe mode + let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x00, 0x01)?; + if i2c_response.data[0] == 0 { + // Safe mode not enabled, enable it + i2c_write(ec, i2c_port, i2c_addr >> 1, 0x00, &[0x01])?; + } + + // Wake up from low power mode + for _ in 0..3 { + let i2c_response = i2c_read(ec, i2c_port, (i2c_addr + 2) >> 1, 0x70, 0x01)?; + if i2c_response.data[0] != 0 { + i2c_write(ec, i2c_port, (i2c_addr + 2) >> 1, 0x70, &[0x00])?; + os_specific::sleep(50_000); + } + } + + // Read version + let i2c_response = i2c_read(ec, i2c_port, (i2c_addr + 18) >> 1, 0x01, 0x04)?; + + Ok(Some(i2c_response.data)) +} From 0b40a67c49b254c13e1152459034b1e3c2f97305 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 23 Sep 2025 22:11:19 +0800 Subject: [PATCH 4/4] commandline: Print Parade retimer ver in --versions Signed-off-by: Daniel Schaefer --- framework_lib/src/commandline/mod.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index e56d348d..b787d2c1 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -50,6 +50,7 @@ use crate::esrt; #[cfg(feature = "rusb")] use crate::inputmodule::check_inputmodule_version; use crate::os_specific; +use crate::parade_retimer; use crate::power; use crate::smbios; use crate::smbios::ConfigDigit0; @@ -677,7 +678,7 @@ fn print_versions(ec: &CrosEc) { } } if has_retimer { - println!("Retimers"); + println!("Intel Retimers"); if let Some(fw_version) = left_retimer { println!(" Left: 0x{:X} ({})", fw_version, fw_version); } @@ -689,6 +690,21 @@ fn print_versions(ec: &CrosEc) { println!(" Unknown"); } } + match parade_retimer::get_version(ec) { + // Does not exist + Ok(None) => {} + Ok(Some(ver)) => { + println!("Parade Retimers"); + println!( + " dGPU: {:X}.{:X}.{:X}.{:X}", + ver[0], ver[1], ver[2], ver[3] + ); + } + _err => { + println!("Parade Retimers"); + println!(" Unknown"); + } + } #[cfg(target_os = "linux")] if smbios::get_platform().and_then(Platform::which_cpu_vendor) != Some(util::CpuVendor::Amd) {