drivers/gpu/nova-core/gsp/hal/tu102.rs

Source file repositories/reference/linux-study-clean/drivers/gpu/nova-core/gsp/hal/tu102.rs

File Facts

System
Linux kernel
Corpus path
drivers/gpu/nova-core/gsp/hal/tu102.rs
Extension
.rs
Size
10285 bytes
Lines
350
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct Sec2UnloadBundle {
    fwsec_sb: FwsecUnloadFirmware,
    booter_unloader: BooterFirmware,
}

impl Sec2UnloadBundle {
    /// Load and prepare the resources required to properly reset the GSP after it has been stopped.
    fn build(
        dev: &device::Device<device::Bound>,
        bar: Bar0<'_>,
        chipset: Chipset,
        bios: &Vbios,
        gsp_falcon: &Falcon<GspEngine>,
        sec2_falcon: &Falcon<Sec2>,
    ) -> Result<KBox<dyn UnloadBundle>> {
        KBox::new(
            Self {
                fwsec_sb: FwsecUnloadFirmware::new(dev, bar, chipset, bios, gsp_falcon)?,
                booter_unloader: BooterFirmware::new(
                    dev,
                    BooterKind::Unloader,
                    chipset,
                    FIRMWARE_VERSION,
                    sec2_falcon,
                    bar,
                )?,
            },
            GFP_KERNEL,
        )
        .map(|b| b as KBox<dyn UnloadBundle>)
        .map_err(Into::into)
    }
}

impl UnloadBundle for Sec2UnloadBundle {
    fn run(
        &self,
        dev: &device::Device<device::Bound>,
        bar: Bar0<'_>,
        gsp_falcon: &Falcon<GspEngine>,
        sec2_falcon: &Falcon<Sec2>,
    ) -> Result {
        // Run FWSEC-SB to reset the GSP falcon to its pre-libos state.
        self.fwsec_sb.run(dev, bar, gsp_falcon)?;

        // Remove WPR2 region if set.
        let wpr2_hi = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
        if wpr2_hi.is_wpr2_set() {
            sec2_falcon.reset(bar)?;
            sec2_falcon.load(dev, bar, &self.booter_unloader)?;

            // Sentinel value to confirm that Booter Unloader has run.
            const MAILBOX_SENTINEL: u32 = 0xff;
            let (mbox0, _) =
                sec2_falcon.boot(bar, Some(MAILBOX_SENTINEL), Some(MAILBOX_SENTINEL))?;
            if mbox0 != 0 {
                dev_err!(dev, "Booter Unloader returned error 0x{:x}\n", mbox0);
                return Err(EINVAL);
            }

            // Confirm that the WPR2 region has been removed.
            let wpr2_hi = bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI);
            if wpr2_hi.is_wpr2_set() {
                dev_err!(
                    dev,
                    "WPR2 region still set after Booter Unloader returned\n"
                );
                return Err(EBUSY);
            }
        }

        Ok(())
    }
}

/// Helper function to load and run the FWSEC-FRTS firmware and confirm that it has properly
/// created the WPR2 region.
fn run_fwsec_frts(
    dev: &device::Device<device::Bound>,
    chipset: Chipset,
    falcon: &Falcon<GspEngine>,
    bar: Bar0<'_>,
    bios: &Vbios,
    fb_layout: &FbLayout,
) -> Result {
    // Check that the WPR2 region does not already exist - if it does, we cannot run
    // FWSEC-FRTS until the GPU is reset.
    if bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound() != 0 {
        dev_err!(
            dev,

Annotation

Implementation Notes