88//! information, and starting the GPU firmware coprocessor.
99
1010use crate :: hw;
11- use kernel:: { device , io_mem :: IoMem , platform, prelude:: * , types :: ARef } ;
11+ use kernel:: { c_str , devres :: Devres , io :: mem :: IoMem , platform, prelude:: * } ;
1212
1313/// Size of the ASC control MMIO region.
1414pub ( crate ) const ASC_CTL_SIZE : usize = 0x4000 ;
@@ -142,45 +142,57 @@ pub(crate) struct FaultInfo {
142142
143143/// Device resources for this GPU instance.
144144pub ( crate ) struct Resources {
145- dev : ARef < device :: Device > ,
146- asc : IoMem < ASC_CTL_SIZE > ,
147- sgx : IoMem < SGX_SIZE > ,
145+ dev : platform :: Device ,
146+ asc : Devres < IoMem < ASC_CTL_SIZE > > ,
147+ sgx : Devres < IoMem < SGX_SIZE > > ,
148148}
149149
150150impl Resources {
151151 /// Map the required resources given our platform device.
152152 pub ( crate ) fn new ( pdev : & mut platform:: Device ) -> Result < Resources > {
153- // TODO: add device abstraction to ioremap by name
154- // SAFETY: We do not trigger any DMA operations directly via ASC registers
155- let asc_res = unsafe { pdev . ioremap_resource ( 0 ) ? } ;
156- // SAFETY: We do not trigger any DMA operations directly via SGX registers
157- let sgx_res = unsafe { pdev. ioremap_resource ( 1 ) ? } ;
153+ let asc_res = pdev . resource_by_name ( c_str ! ( "asc" ) ) . ok_or ( EINVAL ) ? ;
154+ let asc_iomem = pdev . ioremap_resource_sized :: < ASC_CTL_SIZE > ( asc_res ) ? ;
155+
156+ let sgx_res = pdev . resource_by_name ( c_str ! ( "sgx" ) ) . ok_or ( EINVAL ) ? ;
157+ let sgx_iomem = pdev. ioremap_resource_sized :: < SGX_SIZE > ( sgx_res ) ? ;
158158
159159 Ok ( Resources {
160160 // SAFETY: This device does DMA via the UAT IOMMU.
161- dev : pdev. get_device ( ) ,
162- asc : asc_res ,
163- sgx : sgx_res ,
161+ dev : pdev. clone ( ) ,
162+ asc : asc_iomem ,
163+ sgx : sgx_iomem ,
164164 } )
165165 }
166166
167- fn sgx_read32 ( & self , off : usize ) -> u32 {
168- self . sgx . readl_relaxed ( off)
167+ fn sgx_read32 < const OFF : usize > ( & self ) -> u32 {
168+ if let Some ( sgx) = self . sgx . try_access ( ) {
169+ sgx. readl_relaxed ( OFF )
170+ } else {
171+ 0
172+ }
169173 }
170174
171175 /* Not yet used
172- fn sgx_write32(&self, off: usize, val: u32) {
173- self.sgx.writel_relaxed(val, off)
176+ fn sgx_write32<OFF: usize>(&self, val: u32) {
177+ if let Some(sgx) = self.sgx.try_access() {
178+ sgx.writel_relaxed(val, OFF)
179+ }
174180 }
175181 */
176182
177- fn sgx_read64 ( & self , off : usize ) -> u64 {
178- self . sgx . readq_relaxed ( off)
183+ fn sgx_read64 < const OFF : usize > ( & self ) -> u64 {
184+ if let Some ( sgx) = self . sgx . try_access ( ) {
185+ sgx. readq_relaxed ( OFF )
186+ } else {
187+ 0
188+ }
179189 }
180190
181191 /* Not yet used
182- fn sgx_write64(&self, off: usize, val: u64) {
183- self.sgx.writeq_relaxed(val, off)
192+ fn sgx_write64<OFF: usize>(&self, val: u64) {
193+ if let Some(sgx) = self.sgx.try_access() {
194+ sgx.writeq_relaxed(val, OFF)
195+ }
184196 }
185197 */
186198
@@ -193,9 +205,10 @@ impl Resources {
193205
194206 /// Start the ASC coprocessor CPU.
195207 pub ( crate ) fn start_cpu ( & self ) -> Result {
196- let val = self . asc . readl_relaxed ( CPU_CONTROL ) ;
208+ let res = self . asc . try_access ( ) . ok_or ( ENXIO ) ?;
209+ let val = res. readl_relaxed ( CPU_CONTROL ) ;
197210
198- self . asc . writel_relaxed ( val | CPU_RUN , CPU_CONTROL ) ;
211+ res . writel_relaxed ( val | CPU_RUN , CPU_CONTROL ) ;
199212
200213 Ok ( ( ) )
201214 }
@@ -204,12 +217,12 @@ impl Resources {
204217 ///
205218 /// See [`hw::GpuIdConfig`] for the result.
206219 pub ( crate ) fn get_gpu_id ( & self ) -> Result < hw:: GpuIdConfig > {
207- let id_version = self . sgx_read32 ( ID_VERSION ) ;
208- let id_unk08 = self . sgx_read32 ( ID_UNK08 ) ;
209- let id_counts_1 = self . sgx_read32 ( ID_COUNTS_1 ) ;
210- let id_counts_2 = self . sgx_read32 ( ID_COUNTS_2 ) ;
211- let id_unk18 = self . sgx_read32 ( ID_UNK18 ) ;
212- let id_clusters = self . sgx_read32 ( ID_CLUSTERS ) ;
220+ let id_version = self . sgx_read32 :: < ID_VERSION > ( ) ;
221+ let id_unk08 = self . sgx_read32 :: < ID_UNK08 > ( ) ;
222+ let id_counts_1 = self . sgx_read32 :: < ID_COUNTS_1 > ( ) ;
223+ let id_counts_2 = self . sgx_read32 :: < ID_COUNTS_2 > ( ) ;
224+ let id_unk18 = self . sgx_read32 :: < ID_UNK18 > ( ) ;
225+ let id_clusters = self . sgx_read32 :: < ID_CLUSTERS > ( ) ;
213226
214227 dev_info ! (
215228 self . dev. as_ref( ) ,
@@ -229,15 +242,15 @@ impl Resources {
229242 let num_clusters = match gpu_gen {
230243 4 | 5 => {
231244 // G13 | G14G
232- core_mask_regs. push ( self . sgx_read32 ( CORE_MASK_0 ) , GFP_KERNEL ) ?;
233- core_mask_regs. push ( self . sgx_read32 ( CORE_MASK_1 ) , GFP_KERNEL ) ?;
245+ core_mask_regs. push ( self . sgx_read32 :: < CORE_MASK_0 > ( ) , GFP_KERNEL ) ?;
246+ core_mask_regs. push ( self . sgx_read32 :: < CORE_MASK_1 > ( ) , GFP_KERNEL ) ?;
234247 ( id_clusters >> 12 ) & 0xff
235248 }
236249 6 => {
237250 // G14X
238- core_mask_regs. push ( self . sgx_read32 ( CORE_MASKS_G14X ) , GFP_KERNEL ) ?;
239- core_mask_regs. push ( self . sgx_read32 ( CORE_MASKS_G14X + 4 ) , GFP_KERNEL ) ?;
240- core_mask_regs. push ( self . sgx_read32 ( CORE_MASKS_G14X + 8 ) , GFP_KERNEL ) ?;
251+ core_mask_regs. push ( self . sgx_read32 :: < CORE_MASKS_G14X > ( ) , GFP_KERNEL ) ?;
252+ core_mask_regs. push ( self . sgx_read32 :: < { CORE_MASKS_G14X + 4 } > ( ) , GFP_KERNEL ) ?;
253+ core_mask_regs. push ( self . sgx_read32 :: < { CORE_MASKS_G14X + 8 } > ( ) , GFP_KERNEL ) ?;
241254 // Clusters per die * num dies
242255 ( ( id_counts_1 >> 8 ) & 0xff ) * ( ( id_counts_1 >> 16 ) & 0xf )
243256 }
@@ -355,17 +368,17 @@ impl Resources {
355368 let g14x = cfg. gpu_core as u32 >= hw:: GpuCore :: G14S as u32 ;
356369
357370 let fault_info = if g14x {
358- self . sgx_read64 ( FAULT_INFO_G14X )
371+ self . sgx_read64 :: < FAULT_INFO_G14X > ( )
359372 } else {
360- self . sgx_read64 ( FAULT_INFO )
373+ self . sgx_read64 :: < FAULT_INFO > ( )
361374 } ;
362375
363376 if fault_info & 1 == 0 {
364377 return None ;
365378 }
366379
367380 let fault_addr = if g14x {
368- self . sgx_read64 ( FAULT_ADDR_G14X )
381+ self . sgx_read64 :: < FAULT_ADDR_G14X > ( )
369382 } else {
370383 fault_info >> 30
371384 } ;
0 commit comments