Skip to content

Commit f47aa60

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

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
@@ -492,12 +492,13 @@ impl VmInner {
492492
let mut iova = node.start();
493493
let guard = node.bo.as_ref().ok_or(EINVAL)?.inner().sgt.lock();
494494
let sgt = guard.as_ref().ok_or(EINVAL)?;
495+
let mut offset = node.offset;
495496

496497
for range in sgt.iter() {
497-
let addr = range.dma_address();
498-
let len = range.dma_len();
498+
let mut addr = range.dma_address();
499+
let mut len = range.dma_len();
499500

500-
if (addr | len | iova as usize) & UAT_PGMSK != 0 {
501+
if (offset | addr | len | iova as usize) & UAT_PGMSK != 0 {
501502
dev_err!(
502503
self.dev.as_ref(),
503504
"MMU: KernelMapping {:#x}:{:#x} -> {:#x} is not page-aligned\n",
@@ -508,6 +509,17 @@ impl VmInner {
508509
return Err(EINVAL);
509510
}
510511

512+
if offset > 0 {
513+
let skip = len.min(offset);
514+
addr += skip;
515+
len -= skip;
516+
offset -= skip;
517+
}
518+
519+
if len == 0 {
520+
continue;
521+
}
522+
511523
mod_dev_dbg!(
512524
self.dev,
513525
"MMU: map: {:#x}:{:#x} -> {:#x}\n",
@@ -596,6 +608,7 @@ pub(crate) struct KernelMappingInner {
596608
owner: ARef<gpuvm::GpuVm<VmInner>>,
597609
uat_inner: Arc<UatInner>,
598610
prot: u32,
611+
offset: usize,
599612
mapped_size: usize,
600613
}
601614

@@ -1082,13 +1095,14 @@ impl Vm {
10821095
#[allow(clippy::too_many_arguments)]
10831096
pub(crate) fn map_in_range(
10841097
&self,
1085-
size: usize,
10861098
gem: &gem::Object,
1099+
object_range: Range<usize>,
10871100
alignment: u64,
10881101
range: Range<u64>,
10891102
prot: u32,
10901103
guard: bool,
10911104
) -> Result<KernelMapping> {
1105+
let size = object_range.range();
10921106
let sgt = gem.owned_sg_table()?;
10931107
let mut inner = self.inner.exec_lock(Some(gem))?;
10941108
let vm_bo = inner.obtain_bo()?;
@@ -1107,6 +1121,7 @@ impl Vm {
11071121
prot,
11081122
bo: Some(vm_bo),
11091123
_gem: Some(gem.into()),
1124+
offset: object_range.start,
11101125
mapped_size: size,
11111126
},
11121127
(size + if guard { UAT_PGSZ } else { 0 }) as u64, // Add guard page
@@ -1150,6 +1165,7 @@ impl Vm {
11501165
prot,
11511166
bo: Some(vm_bo),
11521167
_gem: Some(gem.into()),
1168+
offset: 0,
11531169
mapped_size: size,
11541170
},
11551171
addr,
@@ -1254,6 +1270,7 @@ impl Vm {
12541270
prot,
12551271
bo: None,
12561272
_gem: None,
1273+
offset: 0,
12571274
mapped_size: size,
12581275
},
12591276
iova,

0 commit comments

Comments
 (0)