Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions drv/cosmo-seq-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ drv-cpu-power-state = { path = "../cpu-power-state" }
counters = { path = "../../lib/counters" }
drv-cpu-seq-api = { path = "../cpu-seq-api" }
drv-hf-api = { path = "../hf-api" }
drv-i2c-api = { path = "../i2c-api" }
drv-i2c-devices = { path = "../i2c-devices" }
drv-ice40-spi-program = { path = "../ice40-spi-program" }
drv-packrat-vpd-loader = { path = "../packrat-vpd-loader" }
drv-spartan7-loader-api = { path = "../spartan7-loader-api" }
Expand All @@ -22,11 +24,13 @@ task-jefe-api = { path = "../../task/jefe-api" }
cfg-if = { workspace = true }
idol-runtime.workspace = true
num-traits = { workspace = true }
pmbus = { workspace = true }
zerocopy = { workspace = true }
zerocopy-derive = { workspace = true }

[build-dependencies]
build-fpga-regmap = { path = "../../build/fpga-regmap" }
build-i2c = { path = "../../build/i2c" }
build-util = { path = "../../build/util" }
build-stm32xx-sys = { path = "../../build/stm32xx-sys" }
idol = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions drv/cosmo-seq-server/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,11 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
)?;
}

let disposition = build_i2c::Disposition::Devices;
if let Err(e) = build_i2c::codegen(disposition) {
println!("cargo::error=I2C code generation failed: {e}",);
std::process::exit(1);
}

Ok(())
}
48 changes: 47 additions & 1 deletion drv/cosmo-seq-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ use userlib::{
use drv_hf_api::HostFlash;
use ringbuf::{counted_ringbuf, ringbuf_entry, Count};

include!(concat!(env!("OUT_DIR"), "/i2c_config.rs"));

mod vcore;
use vcore::VCore;

task_slot!(JEFE, jefe);
task_slot!(LOADER, spartan7_loader);
task_slot!(HF, hf);
Expand Down Expand Up @@ -369,6 +374,7 @@ struct ServerImpl {
sys: Sys,
hf: HostFlash,
seq: fmc_periph::Sequencer,
vcore: VCore,
}

impl ServerImpl {
Expand All @@ -393,6 +399,7 @@ impl ServerImpl {
sys: Sys::from(SYS.get_task_id()),
hf: HostFlash::from(HF.get_task_id()),
seq,
vcore: VCore::new(I2C.get_task_id()),
}
}

Expand Down Expand Up @@ -527,8 +534,9 @@ impl ServerImpl {
return Err(CpuSeqError::UnrecognizedCPU);
}
};

// Turn on the voltage regulator undervolt alerts.
self.enable_sequencer_interrupts();

// Flip the host flash mux so the CPU can read from it
// (this is secretly infallible on Cosmo, so we can unwrap it)
self.hf.set_mux(drv_hf_api::HfMuxState::HostCPU).unwrap();
Expand Down Expand Up @@ -633,6 +641,16 @@ impl ServerImpl {
notifications::SEQ_IRQ_MASK,
sys_api::IrqControl::Enable,
);
// Enable the undervoltage warning PMBus alert from the Vcore
// regulators.
//
// Yes, we just ignore the error here --- while that seems a bit
// sketchy, but what else can we do? It seems pretty bad to panic and
// say "nope, the computer won't turn on" because we weren't able to do
// an I2C transaction to turn on an interrupt that we only use for
// monitoring for faults. The initialize method will retry internally a
// few times, so we should power through any transient I2C messiness.
let _ = self.vcore.initialize_uv_warning();
self.seq.ier.modify(|m| {
m.set_fanfault(true);
m.set_thermtrip(true);
Expand All @@ -641,6 +659,9 @@ impl ServerImpl {
m.set_nicmapo(true);
m.set_amd_pwrok_fedge(true);
m.set_amd_rstn_fedge(true);
// PMBus alert bits for Renesas RAA229620A PWM controllers.
m.set_pwr_cont1_to_fpga1_alert(true);
m.set_pwr_cont2_to_fpga1_alert(true);
});
}

Expand All @@ -653,6 +674,9 @@ impl ServerImpl {
m.set_nicmapo(false);
m.set_amd_pwrok_fedge(false);
m.set_amd_rstn_fedge(false);

m.set_pwr_cont1_to_fpga1_alert(false);
m.set_pwr_cont2_to_fpga1_alert(false);
});
let _ = self.sys.gpio_irq_control(
notifications::SEQ_IRQ_MASK,
Expand Down Expand Up @@ -688,6 +712,28 @@ impl ServerImpl {

let mut action = InternalAction::None;

if ifr.pwr_cont1_to_fpga1_alert || ifr.pwr_cont2_to_fpga1_alert {
// We got a PMBus alert from one of the Vcore regulators.
let which_rails = vcore::Rails {
vddcr_cpu0: ifr.pwr_cont1_to_fpga1_alert,
vddcr_cpu1: ifr.pwr_cont2_to_fpga1_alert,
};
self.vcore.handle_pmalert(which_rails);
// The only way to make the pins deassert (and thus, the IRQ go
// away) is to tell the guys to clear the fault.
// N.B.: unlike other FPGA sequencer alerts, we need not clear the
// IFR bits for these; they are hot as long as the PMALERT pin from
// the RAA229620As is asserted. Clearing the fault in the regulator
// clears the IRQ.
let _ = self.vcore.clear_faults(which_rails);

// If *all* we saw was a PMBus alert, don't reset --- perhaps we're
// still fine, and we just got a warning from the regulator. If
// POWER_GOOD was deasserted, then the FPGA will MAPO us anyway,
// even though clearing the fault in the regulator might make
// POWER_GOOD come back.
}

if ifr.amd_pwrok_fedge || ifr.amd_rstn_fedge {
let rstn = self.seq.amd_reset_fedges.counts();
let pwrokn = self.seq.amd_pwrok_fedges.counts();
Expand Down
Loading
Loading