Useful for SVM ranges in SRAM and programing page tables.

Signed-off-by: Matthew Brost <matthew.br...@intel.com>
---
 drivers/gpu/drm/xe/xe_res_cursor.h | 50 +++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/xe_res_cursor.h 
b/drivers/gpu/drm/xe/xe_res_cursor.h
index dca374b6521c..3df630af9252 100644
--- a/drivers/gpu/drm/xe/xe_res_cursor.h
+++ b/drivers/gpu/drm/xe/xe_res_cursor.h
@@ -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
-- 
2.34.1

Reply via email to