Skip to content

Commit 10dcc3d

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: gpu: Implement mapping timestamp buffers
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent e4095f5 commit 10dcc3d

3 files changed

Lines changed: 62 additions & 5 deletions

File tree

drivers/gpu/drm/asahi/gem.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,26 @@ impl ObjectRef {
8484
if !self.gem.kernel {
8585
return Err(EINVAL);
8686
}
87-
vm.map_in_range(self.gem.size(), &self.gem, alignment, range, prot, guard)
87+
vm.map_in_range(&self.gem, 0..self.gem.size(), alignment, range, prot, guard)
88+
}
89+
90+
/// Maps a range within an object into a given `Vm` at any free address within a given range.
91+
pub(crate) fn map_range_into_range(
92+
&mut self,
93+
vm: &crate::mmu::Vm,
94+
obj_range: Range<usize>,
95+
range: Range<u64>,
96+
alignment: u64,
97+
prot: u32,
98+
guard: bool,
99+
) -> Result<crate::mmu::KernelMapping> {
100+
if obj_range.end > self.gem.size() {
101+
return Err(EINVAL);
102+
}
103+
if self.gem.flags & uapi::ASAHI_GEM_VM_PRIVATE != 0 && vm.is_extobj(&self.gem) {
104+
return Err(EINVAL);
105+
}
106+
vm.map_in_range(&self.gem, obj_range, alignment, range, prot, guard)
88107
}
89108

90109
/// Maps an object into a given `Vm` at a specific address.

drivers/gpu/drm/asahi/gpu.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ pub(crate) trait GpuManager: Send + Sync {
278278
fn free_context(&self, data: KBox<fw::types::GpuObject<fw::workqueue::GpuContextData>>);
279279
/// Check whether the GPU is crashed
280280
fn is_crashed(&self) -> bool;
281+
/// Map a BO as a timestamp buffer
282+
fn map_timestamp_buffer(
283+
&self,
284+
bo: gem::ObjectRef,
285+
range: Range<usize>,
286+
) -> Result<mmu::KernelMapping>;
281287
}
282288

283289
/// Private generic trait for functions that don't need to escape this module.
@@ -1488,6 +1494,21 @@ impl GpuManager for GpuManager::ver {
14881494
fn is_crashed(&self) -> bool {
14891495
self.crashed.load(Ordering::Relaxed)
14901496
}
1497+
1498+
fn map_timestamp_buffer(
1499+
&self,
1500+
mut bo: gem::ObjectRef,
1501+
range: Range<usize>,
1502+
) -> Result<mmu::KernelMapping> {
1503+
bo.map_range_into_range(
1504+
self.uat.kernel_vm(),
1505+
range,
1506+
IOVA_KERN_TIMESTAMP_RANGE,
1507+
mmu::UAT_PGSZ as u64,
1508+
mmu::PROT_FW_SHARED_RW,
1509+
false,
1510+
)
1511+
}
14911512
}
14921513

14931514
#[versions(AGX)]

drivers/gpu/drm/asahi/mmu.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,13 @@ impl VmInner {
488488
let mut iova = node.start();
489489
let guard = node.bo.as_ref().ok_or(EINVAL)?.inner().sgt.lock();
490490
let sgt = guard.as_ref().ok_or(EINVAL)?;
491+
let mut offset = node.offset;
491492

492493
for range in sgt.iter() {
493-
let addr = range.dma_address();
494-
let len = range.dma_len();
494+
let mut addr = range.dma_address();
495+
let mut len = range.dma_len();
495496

496-
if (addr | len | iova as usize) & UAT_PGMSK != 0 {
497+
if (offset | addr | len | iova as usize) & UAT_PGMSK != 0 {
497498
dev_err!(
498499
self.dev.as_ref(),
499500
"MMU: KernelMapping {:#x}:{:#x} -> {:#x} is not page-aligned\n",
@@ -504,6 +505,17 @@ impl VmInner {
504505
return Err(EINVAL);
505506
}
506507

508+
if offset > 0 {
509+
let skip = len.min(offset);
510+
addr += skip;
511+
len -= skip;
512+
offset -= skip;
513+
}
514+
515+
if len == 0 {
516+
continue;
517+
}
518+
507519
mod_dev_dbg!(
508520
self.dev,
509521
"MMU: map: {:#x}:{:#x} -> {:#x}\n",
@@ -592,6 +604,7 @@ pub(crate) struct KernelMappingInner {
592604
owner: ARef<gpuvm::GpuVm<VmInner>>,
593605
uat_inner: Arc<UatInner>,
594606
prot: u32,
607+
offset: usize,
595608
mapped_size: usize,
596609
}
597610

@@ -1084,13 +1097,14 @@ impl Vm {
10841097
#[allow(clippy::too_many_arguments)]
10851098
pub(crate) fn map_in_range(
10861099
&self,
1087-
size: usize,
10881100
gem: &gem::Object,
1101+
object_range: Range<usize>,
10891102
alignment: u64,
10901103
range: Range<u64>,
10911104
prot: u32,
10921105
guard: bool,
10931106
) -> Result<KernelMapping> {
1107+
let size = object_range.range();
10941108
let sgt = gem.sg_table()?;
10951109
let mut inner = self.inner.exec_lock(Some(gem))?;
10961110
let vm_bo = inner.obtain_bo()?;
@@ -1109,6 +1123,7 @@ impl Vm {
11091123
prot,
11101124
bo: Some(vm_bo),
11111125
_gem: Some(gem.reference()),
1126+
offset: object_range.start,
11121127
mapped_size: size,
11131128
},
11141129
(size + if guard { UAT_PGSZ } else { 0 }) as u64, // Add guard page
@@ -1152,6 +1167,7 @@ impl Vm {
11521167
prot,
11531168
bo: Some(vm_bo),
11541169
_gem: Some(gem.reference()),
1170+
offset: 0,
11551171
mapped_size: size,
11561172
},
11571173
addr,
@@ -1253,6 +1269,7 @@ impl Vm {
12531269
prot,
12541270
bo: None,
12551271
_gem: None,
1272+
offset: 0,
12561273
mapped_size: size,
12571274
},
12581275
iova,

0 commit comments

Comments
 (0)