aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>2013-03-27 17:16:53 -0400
committerBen Skeggs <bskeggs@redhat.com>2013-04-26 01:37:40 -0400
commite30441adb91b020044f257c5c8e41022f3406ba1 (patch)
treeed9aaaa9a0aeb74eeaef783b4fd531269d3396ae
parentde7b7d59d54852c9544a9e4fa7af719511fb5366 (diff)
drm/nvc0-/ltcg: implement VRAM compression
Signed-off-by: Christoph Bumiller <e0425955@student.tuwien.ac.at> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c55
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c129
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c58
4 files changed, 220 insertions, 29 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
index f351f63bc654..a1985ed3d58d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
@@ -4,8 +4,15 @@
4#include <core/subdev.h> 4#include <core/subdev.h>
5#include <core/device.h> 5#include <core/device.h>
6 6
7struct nouveau_mm_node;
8
7struct nouveau_ltcg { 9struct nouveau_ltcg {
8 struct nouveau_subdev base; 10 struct nouveau_subdev base;
11
12 int (*tags_alloc)(struct nouveau_ltcg *, u32 count,
13 struct nouveau_mm_node **);
14 void (*tags_free)(struct nouveau_ltcg *, struct nouveau_mm_node **);
15 void (*tags_clear)(struct nouveau_ltcg *, u32 first, u32 count);
9}; 16};
10 17
11static inline struct nouveau_ltcg * 18static inline struct nouveau_ltcg *
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index 3b2ddc65bd48..86ad59203c8b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <subdev/fb.h> 25#include <subdev/fb.h>
26#include <subdev/ltcg.h>
26#include <subdev/bios.h> 27#include <subdev/bios.h>
27 28
28struct nvc0_fb_priv { 29struct nvc0_fb_priv {
@@ -31,34 +32,14 @@ struct nvc0_fb_priv {
31 dma_addr_t r100c10; 32 dma_addr_t r100c10;
32}; 33};
33 34
34/* 0 = unsupported 35extern const u8 nvc0_pte_storage_type_map[256];
35 * 1 = non-compressed 36
36 * 3 = compressed
37 */
38static const u8 types[256] = {
39 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
40 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
43 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
51 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
52 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
53 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
54 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
55};
56 37
57static bool 38static bool
58nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags) 39nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
59{ 40{
60 u8 memtype = (tile_flags & 0x0000ff00) >> 8; 41 u8 memtype = (tile_flags & 0x0000ff00) >> 8;
61 return likely((types[memtype] == 1)); 42 return likely((nvc0_pte_storage_type_map[memtype] != 0xff));
62} 43}
63 44
64static int 45static int
@@ -130,6 +111,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
130 int type = (memtype & 0x0ff); 111 int type = (memtype & 0x0ff);
131 int back = (memtype & 0x800); 112 int back = (memtype & 0x800);
132 int ret; 113 int ret;
114 const bool comp = nvc0_pte_storage_type_map[type] != type;
133 115
134 size >>= 12; 116 size >>= 12;
135 align >>= 12; 117 align >>= 12;
@@ -142,10 +124,22 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
142 return -ENOMEM; 124 return -ENOMEM;
143 125
144 INIT_LIST_HEAD(&mem->regions); 126 INIT_LIST_HEAD(&mem->regions);
145 mem->memtype = type;
146 mem->size = size; 127 mem->size = size;
147 128
148 mutex_lock(&pfb->base.mutex); 129 mutex_lock(&pfb->base.mutex);
130 if (comp) {
131 struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
132
133 /* compression only works with lpages */
134 if (align == (1 << (17 - 12))) {
135 int n = size >> 5;
136 ltcg->tags_alloc(ltcg, n, &mem->tag);
137 }
138 if (unlikely(!mem->tag))
139 type = nvc0_pte_storage_type_map[type];
140 }
141 mem->memtype = type;
142
149 do { 143 do {
150 if (back) 144 if (back)
151 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r); 145 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
@@ -168,6 +162,17 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
168 return 0; 162 return 0;
169} 163}
170 164
165static void
166nvc0_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
167{
168 struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
169
170 if ((*pmem)->tag)
171 ltcg->tags_free(ltcg, &(*pmem)->tag);
172
173 nv50_fb_vram_del(pfb, pmem);
174}
175
171static int 176static int
172nvc0_fb_init(struct nouveau_object *object) 177nvc0_fb_init(struct nouveau_object *object)
173{ 178{
@@ -215,7 +220,7 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
215 priv->base.memtype_valid = nvc0_fb_memtype_valid; 220 priv->base.memtype_valid = nvc0_fb_memtype_valid;
216 priv->base.ram.init = nvc0_fb_vram_init; 221 priv->base.ram.init = nvc0_fb_vram_init;
217 priv->base.ram.get = nvc0_fb_vram_new; 222 priv->base.ram.get = nvc0_fb_vram_new;
218 priv->base.ram.put = nv50_fb_vram_del; 223 priv->base.ram.put = nvc0_fb_vram_del;
219 224
220 priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); 225 priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
221 if (priv->r100c10_page) { 226 if (priv->r100c10_page) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
index 078a2b9d6bd6..a529563b5f8c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
@@ -23,10 +23,17 @@
23 */ 23 */
24 24
25#include <subdev/ltcg.h> 25#include <subdev/ltcg.h>
26#include <subdev/fb.h>
27#include <subdev/timer.h>
26 28
27struct nvc0_ltcg_priv { 29struct nvc0_ltcg_priv {
28 struct nouveau_ltcg base; 30 struct nouveau_ltcg base;
31 u32 part_nr;
32 u32 part_mask;
29 u32 subp_nr; 33 u32 subp_nr;
34 struct nouveau_mm tags;
35 u32 num_tags;
36 struct nouveau_mm_node *tag_ram;
30}; 37};
31 38
32static void 39static void
@@ -62,11 +69,104 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev)
62} 69}
63 70
64static int 71static int
72nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n,
73 struct nouveau_mm_node **pnode)
74{
75 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
76 int ret;
77
78 ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode);
79 if (ret)
80 *pnode = NULL;
81
82 return ret;
83}
84
85static void
86nvc0_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode)
87{
88 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
89
90 nouveau_mm_free(&priv->tags, pnode);
91}
92
93static void
94nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count)
95{
96 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
97 u32 last = first + count - 1;
98 int p, i;
99
100 BUG_ON((first > last) || (last >= priv->num_tags));
101
102 nv_wr32(priv, 0x17e8cc, first);
103 nv_wr32(priv, 0x17e8d0, last);
104 nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */
105
106 /* wait until it's finished with clearing */
107 for (p = 0; p < priv->part_nr; ++p) {
108 if (!(priv->part_mask & (1 << p)))
109 continue;
110 for (i = 0; i < priv->subp_nr; ++i)
111 nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0);
112 }
113}
114
115/* TODO: Figure out tag memory details and drop the over-cautious allocation.
116 */
117static int
118nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
119{
120 u32 tag_size, tag_margin, tag_align;
121 int ret;
122
123 nv_wr32(priv, 0x17e8d8, priv->part_nr);
124
125 /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
126 priv->num_tags = (pfb->ram.size >> 17) / 4;
127 if (priv->num_tags > (1 << 17))
128 priv->num_tags = 1 << 17; /* we have 17 bits in PTE */
129 priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */
130
131 tag_align = priv->part_nr * 0x800;
132 tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align;
133
134 /* 4 part 4 sub: 0x2000 bytes for 56 tags */
135 /* 3 part 4 sub: 0x6000 bytes for 168 tags */
136 /*
137 * About 147 bytes per tag. Let's be safe and allocate x2, which makes
138 * 0x4980 bytes for 64 tags, and round up to 0x6000 bytes for 64 tags.
139 *
140 * For 4 GiB of memory we'll have 8192 tags which makes 3 MiB, < 0.1 %.
141 */
142 tag_size = (priv->num_tags / 64) * 0x6000 + tag_margin;
143 tag_size += tag_align;
144 tag_size = (tag_size + 0xfff) >> 12; /* round up */
145
146 ret = nouveau_mm_tail(&pfb->vram, 0, tag_size, tag_size, 1,
147 &priv->tag_ram);
148 if (ret) {
149 priv->num_tags = 0;
150 } else {
151 u64 tag_base = (priv->tag_ram->offset << 12) + tag_margin;
152
153 tag_base += tag_align - 1;
154 tag_base /= tag_align;
155
156 nv_wr32(priv, 0x17e8d4, tag_base);
157 }
158 ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
159
160 return ret;
161}
162
163static int
65nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 164nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
66 struct nouveau_oclass *oclass, void *data, u32 size, 165 struct nouveau_oclass *oclass, void *data, u32 size,
67 struct nouveau_object **pobject) 166 struct nouveau_object **pobject)
68{ 167{
69 struct nvc0_ltcg_priv *priv; 168 struct nvc0_ltcg_priv *priv;
169 struct nouveau_fb *pfb = nouveau_fb(parent);
70 int ret; 170 int ret;
71 171
72 ret = nouveau_ltcg_create(parent, engine, oclass, &priv); 172 ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
@@ -74,19 +174,44 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
74 if (ret) 174 if (ret)
75 return ret; 175 return ret;
76 176
77 priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 24; 177 priv->part_nr = nv_rd32(priv, 0x022438);
178 priv->part_mask = nv_rd32(priv, 0x022554);
179
180 priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
181
78 nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ 182 nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
79 183
184 ret = nvc0_ltcg_init_tag_ram(pfb, priv);
185 if (ret)
186 return ret;
187
188 priv->base.tags_alloc = nvc0_ltcg_tags_alloc;
189 priv->base.tags_free = nvc0_ltcg_tags_free;
190 priv->base.tags_clear = nvc0_ltcg_tags_clear;
191
80 nv_subdev(priv)->intr = nvc0_ltcg_intr; 192 nv_subdev(priv)->intr = nvc0_ltcg_intr;
81 return 0; 193 return 0;
82} 194}
83 195
196static void
197nvc0_ltcg_dtor(struct nouveau_object *object)
198{
199 struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
200 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
201 struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent);
202
203 nouveau_mm_fini(&priv->tags);
204 nouveau_mm_free(&pfb->vram, &priv->tag_ram);
205
206 nouveau_ltcg_destroy(ltcg);
207}
208
84struct nouveau_oclass 209struct nouveau_oclass
85nvc0_ltcg_oclass = { 210nvc0_ltcg_oclass = {
86 .handle = NV_SUBDEV(LTCG, 0xc0), 211 .handle = NV_SUBDEV(LTCG, 0xc0),
87 .ofuncs = &(struct nouveau_ofuncs) { 212 .ofuncs = &(struct nouveau_ofuncs) {
88 .ctor = nvc0_ltcg_ctor, 213 .ctor = nvc0_ltcg_ctor,
89 .dtor = _nouveau_ltcg_dtor, 214 .dtor = nvc0_ltcg_dtor,
90 .init = _nouveau_ltcg_init, 215 .init = _nouveau_ltcg_init,
91 .fini = _nouveau_ltcg_fini, 216 .fini = _nouveau_ltcg_fini,
92 }, 217 },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
index 30c61e6c2017..4c3b0a23b9d6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
@@ -28,12 +28,54 @@
28#include <subdev/timer.h> 28#include <subdev/timer.h>
29#include <subdev/fb.h> 29#include <subdev/fb.h>
30#include <subdev/vm.h> 30#include <subdev/vm.h>
31#include <subdev/ltcg.h>
31 32
32struct nvc0_vmmgr_priv { 33struct nvc0_vmmgr_priv {
33 struct nouveau_vmmgr base; 34 struct nouveau_vmmgr base;
34 spinlock_t lock; 35 spinlock_t lock;
35}; 36};
36 37
38
39/* Map from compressed to corresponding uncompressed storage type.
40 * The value 0xff represents an invalid storage type.
41 */
42const u8 nvc0_pte_storage_type_map[256] =
43{
44 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, /* 0x00 */
45 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
46 0xff, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, /* 0x10 */
47 0x11, 0x11, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff,
48 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x27, /* 0x20 */
49 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
50 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 */
51 0xff, 0xff, 0x26, 0x27, 0x28, 0x29, 0x26, 0x27,
52 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0x46, 0xff, /* 0x40 */
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
54 0xff, 0x46, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, /* 0x50 */
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x60 */
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */
59 0xff, 0xff, 0xff, 0x7b, 0xff, 0xff, 0xff, 0xff,
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x7b, /* 0x80 */
61 0x7b, 0x7b, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xff,
62 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */
63 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
64 0xff, 0xff, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xa7, /* 0xa0 */
65 0xa8, 0xa9, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff,
66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7,
68 0xa8, 0xa9, 0xaa, 0xc3, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */
69 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xc3, 0xc3,
70 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */
71 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe,
72 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, /* 0xe0 */
73 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff,
74 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xf0 */
75 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff
76};
77
78
37static void 79static void
38nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index, 80nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index,
39 struct nouveau_gpuobj *pgt[2]) 81 struct nouveau_gpuobj *pgt[2])
@@ -68,10 +110,20 @@ static void
68nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, 110nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
69 struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) 111 struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
70{ 112{
71 u32 next = 1 << (vma->node->type - 8); 113 u64 next = 1 << (vma->node->type - 8);
72 114
73 phys = nvc0_vm_addr(vma, phys, mem->memtype, 0); 115 phys = nvc0_vm_addr(vma, phys, mem->memtype, 0);
74 pte <<= 3; 116 pte <<= 3;
117
118 if (mem->tag) {
119 struct nouveau_ltcg *ltcg =
120 nouveau_ltcg(vma->vm->vmm->base.base.parent);
121 u32 tag = mem->tag->offset + (delta >> 17);
122 phys |= (u64)tag << (32 + 12);
123 next |= (u64)1 << (32 + 12);
124 ltcg->tags_clear(ltcg, tag, cnt);
125 }
126
75 while (cnt--) { 127 while (cnt--) {
76 nv_wo32(pgt, pte + 0, lower_32_bits(phys)); 128 nv_wo32(pgt, pte + 0, lower_32_bits(phys));
77 nv_wo32(pgt, pte + 4, upper_32_bits(phys)); 129 nv_wo32(pgt, pte + 4, upper_32_bits(phys));
@@ -85,10 +137,12 @@ nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
85 struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) 137 struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
86{ 138{
87 u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5; 139 u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5;
140 /* compressed storage types are invalid for system memory */
141 u32 memtype = nvc0_pte_storage_type_map[mem->memtype & 0xff];
88 142
89 pte <<= 3; 143 pte <<= 3;
90 while (cnt--) { 144 while (cnt--) {
91 u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, target); 145 u64 phys = nvc0_vm_addr(vma, *list++, memtype, target);
92 nv_wo32(pgt, pte + 0, lower_32_bits(phys)); 146 nv_wo32(pgt, pte + 0, lower_32_bits(phys));
93 nv_wo32(pgt, pte + 4, upper_32_bits(phys)); 147 nv_wo32(pgt, pte + 4, upper_32_bits(phys));
94 pte += 8; 148 pte += 8;