.. | .. |
---|
3 | 3 | * Copyright (C) 2017-2018 Etnaviv Project |
---|
4 | 4 | */ |
---|
5 | 5 | |
---|
| 6 | +#include <linux/dma-mapping.h> |
---|
| 7 | + |
---|
6 | 8 | #include <drm/drm_mm.h> |
---|
7 | 9 | |
---|
8 | 10 | #include "etnaviv_cmdbuf.h" |
---|
| 11 | +#include "etnaviv_gem.h" |
---|
9 | 12 | #include "etnaviv_gpu.h" |
---|
10 | 13 | #include "etnaviv_mmu.h" |
---|
11 | 14 | #include "etnaviv_perfmon.h" |
---|
12 | 15 | |
---|
13 | | -#define SUBALLOC_SIZE SZ_256K |
---|
| 16 | +#define SUBALLOC_SIZE SZ_512K |
---|
14 | 17 | #define SUBALLOC_GRANULE SZ_4K |
---|
15 | 18 | #define SUBALLOC_GRANULES (SUBALLOC_SIZE / SUBALLOC_GRANULE) |
---|
16 | 19 | |
---|
17 | 20 | struct etnaviv_cmdbuf_suballoc { |
---|
18 | 21 | /* suballocated dma buffer properties */ |
---|
19 | | - struct etnaviv_gpu *gpu; |
---|
| 22 | + struct device *dev; |
---|
20 | 23 | void *vaddr; |
---|
21 | 24 | dma_addr_t paddr; |
---|
22 | | - |
---|
23 | | - /* GPU mapping */ |
---|
24 | | - u32 iova; |
---|
25 | | - struct drm_mm_node vram_node; /* only used on MMUv2 */ |
---|
26 | 25 | |
---|
27 | 26 | /* allocation management */ |
---|
28 | 27 | struct mutex lock; |
---|
.. | .. |
---|
32 | 31 | }; |
---|
33 | 32 | |
---|
34 | 33 | struct etnaviv_cmdbuf_suballoc * |
---|
35 | | -etnaviv_cmdbuf_suballoc_new(struct etnaviv_gpu * gpu) |
---|
| 34 | +etnaviv_cmdbuf_suballoc_new(struct device *dev) |
---|
36 | 35 | { |
---|
37 | 36 | struct etnaviv_cmdbuf_suballoc *suballoc; |
---|
38 | 37 | int ret; |
---|
.. | .. |
---|
41 | 40 | if (!suballoc) |
---|
42 | 41 | return ERR_PTR(-ENOMEM); |
---|
43 | 42 | |
---|
44 | | - suballoc->gpu = gpu; |
---|
| 43 | + suballoc->dev = dev; |
---|
45 | 44 | mutex_init(&suballoc->lock); |
---|
46 | 45 | init_waitqueue_head(&suballoc->free_event); |
---|
47 | 46 | |
---|
48 | | - suballoc->vaddr = dma_alloc_wc(gpu->dev, SUBALLOC_SIZE, |
---|
| 47 | + BUILD_BUG_ON(ETNAVIV_SOFTPIN_START_ADDRESS < SUBALLOC_SIZE); |
---|
| 48 | + suballoc->vaddr = dma_alloc_wc(dev, SUBALLOC_SIZE, |
---|
49 | 49 | &suballoc->paddr, GFP_KERNEL); |
---|
50 | | - if (!suballoc->vaddr) |
---|
| 50 | + if (!suballoc->vaddr) { |
---|
| 51 | + ret = -ENOMEM; |
---|
51 | 52 | goto free_suballoc; |
---|
52 | | - |
---|
53 | | - ret = etnaviv_iommu_get_suballoc_va(gpu, suballoc->paddr, |
---|
54 | | - &suballoc->vram_node, SUBALLOC_SIZE, |
---|
55 | | - &suballoc->iova); |
---|
56 | | - if (ret) |
---|
57 | | - goto free_dma; |
---|
| 53 | + } |
---|
58 | 54 | |
---|
59 | 55 | return suballoc; |
---|
60 | 56 | |
---|
61 | | -free_dma: |
---|
62 | | - dma_free_wc(gpu->dev, SUBALLOC_SIZE, suballoc->vaddr, suballoc->paddr); |
---|
63 | 57 | free_suballoc: |
---|
64 | 58 | kfree(suballoc); |
---|
65 | 59 | |
---|
66 | | - return NULL; |
---|
| 60 | + return ERR_PTR(ret); |
---|
| 61 | +} |
---|
| 62 | + |
---|
| 63 | +int etnaviv_cmdbuf_suballoc_map(struct etnaviv_cmdbuf_suballoc *suballoc, |
---|
| 64 | + struct etnaviv_iommu_context *context, |
---|
| 65 | + struct etnaviv_vram_mapping *mapping, |
---|
| 66 | + u32 memory_base) |
---|
| 67 | +{ |
---|
| 68 | + return etnaviv_iommu_get_suballoc_va(context, mapping, memory_base, |
---|
| 69 | + suballoc->paddr, SUBALLOC_SIZE); |
---|
| 70 | +} |
---|
| 71 | + |
---|
| 72 | +void etnaviv_cmdbuf_suballoc_unmap(struct etnaviv_iommu_context *context, |
---|
| 73 | + struct etnaviv_vram_mapping *mapping) |
---|
| 74 | +{ |
---|
| 75 | + etnaviv_iommu_put_suballoc_va(context, mapping); |
---|
67 | 76 | } |
---|
68 | 77 | |
---|
69 | 78 | void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc) |
---|
70 | 79 | { |
---|
71 | | - etnaviv_iommu_put_suballoc_va(suballoc->gpu, &suballoc->vram_node, |
---|
72 | | - SUBALLOC_SIZE, suballoc->iova); |
---|
73 | | - dma_free_wc(suballoc->gpu->dev, SUBALLOC_SIZE, suballoc->vaddr, |
---|
| 80 | + dma_free_wc(suballoc->dev, SUBALLOC_SIZE, suballoc->vaddr, |
---|
74 | 81 | suballoc->paddr); |
---|
75 | 82 | kfree(suballoc); |
---|
76 | 83 | } |
---|
.. | .. |
---|
95 | 102 | suballoc->free_space, |
---|
96 | 103 | msecs_to_jiffies(10 * 1000)); |
---|
97 | 104 | if (!ret) { |
---|
98 | | - dev_err(suballoc->gpu->dev, |
---|
| 105 | + dev_err(suballoc->dev, |
---|
99 | 106 | "Timeout waiting for cmdbuf space\n"); |
---|
100 | 107 | return -ETIMEDOUT; |
---|
101 | 108 | } |
---|
.. | .. |
---|
123 | 130 | wake_up_all(&suballoc->free_event); |
---|
124 | 131 | } |
---|
125 | 132 | |
---|
126 | | -u32 etnaviv_cmdbuf_get_va(struct etnaviv_cmdbuf *buf) |
---|
| 133 | +u32 etnaviv_cmdbuf_get_va(struct etnaviv_cmdbuf *buf, |
---|
| 134 | + struct etnaviv_vram_mapping *mapping) |
---|
127 | 135 | { |
---|
128 | | - return buf->suballoc->iova + buf->suballoc_offset; |
---|
| 136 | + return mapping->iova + buf->suballoc_offset; |
---|
129 | 137 | } |
---|
130 | 138 | |
---|
131 | 139 | dma_addr_t etnaviv_cmdbuf_get_pa(struct etnaviv_cmdbuf *buf) |
---|