@@ -43,7 +43,9 @@ struct xe_res_cursor {
u64 remaining;
void *node;
u32 mem_type;
+ unsigned int order;
struct scatterlist *sgl;
+ const dma_addr_t *dma_addr;
struct drm_buddy *mm;
};
@@ -70,6 +72,7 @@ static inline void xe_res_first(struct ttm_resource *res,
struct xe_res_cursor *cur)
{
cur->sgl = NULL;
+ cur->dma_addr = NULL;
if (!res)
goto fallback;
@@ -160,11 +163,43 @@ static inline void xe_res_first_sg(const struct sg_table *sg,
cur->start = start;
cur->remaining = size;
cur->size = 0;
+ cur->dma_addr = NULL;
cur->sgl = sg->sgl;
cur->mem_type = XE_PL_TT;
__xe_res_sg_next(cur);
}
+/**
+ * xe_res_first_dma - initialize a xe_res_cursor with dma_addr array
+ *
+ * @dma_addr: dma_addr array to walk
+ * @start: Start of the range
+ * @size: Size of the range
+ * @order: Order of dma mapping. i.e. PAGE_SIZE << order is mapping size
+ * @cur: cursor object to initialize
+ *
+ * Start walking over the range of allocations between @start and @size.
+ */
+static inline void xe_res_first_dma(const dma_addr_t *dma_addr,
+ u64 start, u64 size,
+ unsigned int order,
+ struct xe_res_cursor *cur)
+{
+ XE_WARN_ON(start);
+ XE_WARN_ON(!dma_addr);
+ XE_WARN_ON(!IS_ALIGNED(start, PAGE_SIZE) ||
+ !IS_ALIGNED(size, PAGE_SIZE));
+
+ cur->node = NULL;
+ cur->start = start;
+ cur->remaining = size;
+ cur->size = PAGE_SIZE << order;
+ cur->dma_addr = dma_addr;
+ cur->order = order;
+ cur->sgl = NULL;
+ cur->mem_type = XE_PL_TT;
+}
+
/**
* xe_res_next - advance the cursor
*
@@ -191,6 +226,13 @@ static inline void xe_res_next(struct xe_res_cursor *cur, u64 size)
return;
}
+ if (cur->dma_addr) {
+ cur->size = (PAGE_SIZE << cur->order) -
+ (size - cur->size);
+ cur->start += size;
+ return;
+ }
+
if (cur->sgl) {
cur->start += size;
__xe_res_sg_next(cur);
@@ -232,6 +274,12 @@ static inline void xe_res_next(struct xe_res_cursor *cur, u64 size)
*/
static inline u64 xe_res_dma(const struct xe_res_cursor *cur)
{
- return cur->sgl ? sg_dma_address(cur->sgl) + cur->start : cur->start;
+ if (cur->dma_addr)
+ return cur->dma_addr[cur->start >> (PAGE_SHIFT + cur->order)] +
+ (cur->start & ((PAGE_SIZE << cur->order) - 1));
+ else if (cur->sgl)
+ return sg_dma_address(cur->sgl) + cur->start;
+ else
+ return cur->start;
}
#endif
Useful for SVM ranges in SRAM and programing page tables. Signed-off-by: Matthew Brost <matthew.brost@intel.com> --- drivers/gpu/drm/xe/xe_res_cursor.h | 50 +++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)