xref: /linux/drivers/gpu/nova-core/falcon/hal/ga102.rs (revision 68a052239fc4b351e961f698b824f7654a346091)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 use core::marker::PhantomData;
4 
5 use kernel::device;
6 use kernel::prelude::*;
7 use kernel::time::Delta;
8 
9 use crate::driver::Bar0;
10 use crate::falcon::{
11     Falcon, FalconBromParams, FalconEngine, FalconModSelAlgo, PeregrineCoreSelect,
12 };
13 use crate::regs;
14 use crate::util;
15 
16 use super::FalconHal;
17 
18 fn select_core_ga102<E: FalconEngine>(bar: &Bar0) -> Result {
19     let bcr_ctrl = regs::NV_PRISCV_RISCV_BCR_CTRL::read(bar, &E::ID);
20     if bcr_ctrl.core_select() != PeregrineCoreSelect::Falcon {
21         regs::NV_PRISCV_RISCV_BCR_CTRL::default()
22             .set_core_select(PeregrineCoreSelect::Falcon)
23             .write(bar, &E::ID);
24 
25         // TIMEOUT: falcon core should take less than 10ms to report being enabled.
26         util::wait_on(Delta::from_millis(10), || {
27             let r = regs::NV_PRISCV_RISCV_BCR_CTRL::read(bar, &E::ID);
28             if r.valid() {
29                 Some(())
30             } else {
31                 None
32             }
33         })?;
34     }
35 
36     Ok(())
37 }
38 
39 fn signature_reg_fuse_version_ga102(
40     dev: &device::Device,
41     bar: &Bar0,
42     engine_id_mask: u16,
43     ucode_id: u8,
44 ) -> Result<u32> {
45     const NV_FUSE_OPT_FPF_SIZE: u8 = regs::NV_FUSE_OPT_FPF_SIZE as u8;
46 
47     // Each engine has 16 ucode version registers numbered from 1 to 16.
48     let ucode_idx = match ucode_id {
49         1..=NV_FUSE_OPT_FPF_SIZE => (ucode_id - 1) as usize,
50         _ => {
51             dev_err!(dev, "invalid ucode id {:#x}", ucode_id);
52             return Err(EINVAL);
53         }
54     };
55 
56     // `ucode_idx` is guaranteed to be in the range [0..15], making the `read` calls provable valid
57     // at build-time.
58     let reg_fuse_version = if engine_id_mask & 0x0001 != 0 {
59         regs::NV_FUSE_OPT_FPF_SEC2_UCODE1_VERSION::read(bar, ucode_idx).data()
60     } else if engine_id_mask & 0x0004 != 0 {
61         regs::NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION::read(bar, ucode_idx).data()
62     } else if engine_id_mask & 0x0400 != 0 {
63         regs::NV_FUSE_OPT_FPF_GSP_UCODE1_VERSION::read(bar, ucode_idx).data()
64     } else {
65         dev_err!(dev, "unexpected engine_id_mask {:#x}", engine_id_mask);
66         return Err(EINVAL);
67     };
68 
69     // TODO[NUMM]: replace with `last_set_bit` once it lands.
70     Ok(u16::BITS - reg_fuse_version.leading_zeros())
71 }
72 
73 fn program_brom_ga102<E: FalconEngine>(bar: &Bar0, params: &FalconBromParams) -> Result {
74     regs::NV_PFALCON2_FALCON_BROM_PARAADDR::default()
75         .set_value(params.pkc_data_offset)
76         .write(bar, &E::ID, 0);
77     regs::NV_PFALCON2_FALCON_BROM_ENGIDMASK::default()
78         .set_value(u32::from(params.engine_id_mask))
79         .write(bar, &E::ID);
80     regs::NV_PFALCON2_FALCON_BROM_CURR_UCODE_ID::default()
81         .set_ucode_id(params.ucode_id)
82         .write(bar, &E::ID);
83     regs::NV_PFALCON2_FALCON_MOD_SEL::default()
84         .set_algo(FalconModSelAlgo::Rsa3k)
85         .write(bar, &E::ID);
86 
87     Ok(())
88 }
89 
90 pub(super) struct Ga102<E: FalconEngine>(PhantomData<E>);
91 
92 impl<E: FalconEngine> Ga102<E> {
93     pub(super) fn new() -> Self {
94         Self(PhantomData)
95     }
96 }
97 
98 impl<E: FalconEngine> FalconHal<E> for Ga102<E> {
99     fn select_core(&self, _falcon: &Falcon<E>, bar: &Bar0) -> Result {
100         select_core_ga102::<E>(bar)
101     }
102 
103     fn signature_reg_fuse_version(
104         &self,
105         falcon: &Falcon<E>,
106         bar: &Bar0,
107         engine_id_mask: u16,
108         ucode_id: u8,
109     ) -> Result<u32> {
110         signature_reg_fuse_version_ga102(&falcon.dev, bar, engine_id_mask, ucode_id)
111     }
112 
113     fn program_brom(&self, _falcon: &Falcon<E>, bar: &Bar0, params: &FalconBromParams) -> Result {
114         program_brom_ga102::<E>(bar, params)
115     }
116 }
117