2 * Copyright 2012 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
25 #include <core/object.h>
26 #include <core/enum.h>
28 #include <subdev/fb.h>
29 #include <subdev/bios.h>
32 struct nouveau_fb base
;
33 struct page
*r100c08_page
;
37 static int types
[0x80] = {
38 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
40 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
43 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
45 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
49 nv50_fb_memtype_valid(struct nouveau_fb
*pfb
, u32 memtype
)
51 return types
[(memtype
& 0xff00) >> 8] != 0;
55 nv50_fb_vram_new(struct nouveau_fb
*pfb
, u64 size
, u32 align
, u32 ncmin
,
56 u32 memtype
, struct nouveau_mem
**pmem
)
58 struct nv50_fb_priv
*priv
= (void *)pfb
;
59 struct nouveau_mm
*heap
= &priv
->base
.vram
;
60 struct nouveau_mm
*tags
= &priv
->base
.tags
;
61 struct nouveau_mm_node
*r
;
62 struct nouveau_mem
*mem
;
63 int comp
= (memtype
& 0x300) >> 8;
64 int type
= (memtype
& 0x07f);
65 int back
= (memtype
& 0x800);
69 min
= ncmin
? (ncmin
>> 12) : max
;
72 mem
= kzalloc(sizeof(*mem
), GFP_KERNEL
);
76 mutex_lock(&pfb
->base
.mutex
);
79 int n
= (max
>> 4) * comp
;
81 ret
= nouveau_mm_head(tags
, 1, n
, n
, 1, &mem
->tag
);
86 if (unlikely(!mem
->tag
))
90 INIT_LIST_HEAD(&mem
->regions
);
91 mem
->memtype
= (comp
<< 7) | type
;
97 ret
= nouveau_mm_tail(heap
, type
, max
, min
, align
, &r
);
99 ret
= nouveau_mm_head(heap
, type
, max
, min
, align
, &r
);
101 mutex_unlock(&pfb
->base
.mutex
);
102 pfb
->ram
.put(pfb
, &mem
);
106 list_add_tail(&r
->rl_entry
, &mem
->regions
);
109 mutex_unlock(&pfb
->base
.mutex
);
111 r
= list_first_entry(&mem
->regions
, struct nouveau_mm_node
, rl_entry
);
112 mem
->offset
= (u64
)r
->offset
<< 12;
118 nv50_fb_vram_del(struct nouveau_fb
*pfb
, struct nouveau_mem
**pmem
)
120 struct nv50_fb_priv
*priv
= (void *)pfb
;
121 struct nouveau_mm_node
*this;
122 struct nouveau_mem
*mem
;
126 if (unlikely(mem
== NULL
))
129 mutex_lock(&pfb
->base
.mutex
);
130 while (!list_empty(&mem
->regions
)) {
131 this = list_first_entry(&mem
->regions
, typeof(*this), rl_entry
);
133 list_del(&this->rl_entry
);
134 nouveau_mm_free(&priv
->base
.vram
, &this);
137 nouveau_mm_free(&priv
->base
.tags
, &mem
->tag
);
138 mutex_unlock(&pfb
->base
.mutex
);
144 nv50_vram_rblock(struct nv50_fb_priv
*priv
)
146 int i
, parts
, colbits
, rowbitsa
, rowbitsb
, banks
;
147 u64 rowsize
, predicted
;
148 u32 r0
, r4
, rt
, ru
, rblock_size
;
150 r0
= nv_rd32(priv
, 0x100200);
151 r4
= nv_rd32(priv
, 0x100204);
152 rt
= nv_rd32(priv
, 0x100250);
153 ru
= nv_rd32(priv
, 0x001540);
154 nv_debug(priv
, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0
, r4
, rt
, ru
);
156 for (i
= 0, parts
= 0; i
< 8; i
++) {
157 if (ru
& (0x00010000 << i
))
161 colbits
= (r4
& 0x0000f000) >> 12;
162 rowbitsa
= ((r4
& 0x000f0000) >> 16) + 8;
163 rowbitsb
= ((r4
& 0x00f00000) >> 20) + 8;
164 banks
= 1 << (((r4
& 0x03000000) >> 24) + 2);
166 rowsize
= parts
* banks
* (1 << colbits
) * 8;
167 predicted
= rowsize
<< rowbitsa
;
169 predicted
+= rowsize
<< rowbitsb
;
171 if (predicted
!= priv
->base
.ram
.size
) {
172 nv_warn(priv
, "memory controller reports %d MiB VRAM\n",
173 (u32
)(priv
->base
.ram
.size
>> 20));
176 rblock_size
= rowsize
;
180 nv_debug(priv
, "rblock %d bytes\n", rblock_size
);
185 nv50_fb_ctor(struct nouveau_object
*parent
, struct nouveau_object
*engine
,
186 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
187 struct nouveau_object
**pobject
)
189 struct nouveau_device
*device
= nv_device(parent
);
190 struct nouveau_bios
*bios
= nouveau_bios(device
);
191 const u32 rsvd_head
= ( 256 * 1024) >> 12; /* vga memory */
192 const u32 rsvd_tail
= (1024 * 1024) >> 12; /* vbios etc */
193 struct nv50_fb_priv
*priv
;
197 ret
= nouveau_fb_create(parent
, engine
, oclass
, &priv
);
198 *pobject
= nv_object(priv
);
202 switch (nv_rd32(priv
, 0x100714) & 0x00000007) {
203 case 0: priv
->base
.ram
.type
= NV_MEM_TYPE_DDR1
; break;
205 if (nouveau_fb_bios_memtype(bios
) == NV_MEM_TYPE_DDR3
)
206 priv
->base
.ram
.type
= NV_MEM_TYPE_DDR3
;
208 priv
->base
.ram
.type
= NV_MEM_TYPE_DDR2
;
210 case 2: priv
->base
.ram
.type
= NV_MEM_TYPE_GDDR3
; break;
211 case 3: priv
->base
.ram
.type
= NV_MEM_TYPE_GDDR4
; break;
212 case 4: priv
->base
.ram
.type
= NV_MEM_TYPE_GDDR5
; break;
217 priv
->base
.ram
.size
= nv_rd32(priv
, 0x10020c);
218 priv
->base
.ram
.size
= (priv
->base
.ram
.size
& 0xffffff00) |
219 ((priv
->base
.ram
.size
& 0x000000ff) << 32);
221 tags
= nv_rd32(priv
, 0x100320);
223 ret
= nouveau_mm_init(&priv
->base
.tags
, 0, tags
, 1);
227 nv_debug(priv
, "%d compression tags\n", tags
);
230 size
= (priv
->base
.ram
.size
>> 12) - rsvd_head
- rsvd_tail
;
231 switch (device
->chipset
) {
234 case 0xaf: /* IGPs, no reordering, no real VRAM */
235 ret
= nouveau_mm_init(&priv
->base
.vram
, rsvd_head
, size
, 1);
239 priv
->base
.ram
.stolen
= (u64
)nv_rd32(priv
, 0x100e10) << 12;
242 ret
= nouveau_mm_init(&priv
->base
.vram
, rsvd_head
, size
,
243 nv50_vram_rblock(priv
) >> 12);
247 priv
->base
.ram
.ranks
= (nv_rd32(priv
, 0x100200) & 0x4) ? 2 : 1;
251 priv
->r100c08_page
= alloc_page(GFP_KERNEL
| __GFP_ZERO
);
252 if (priv
->r100c08_page
) {
253 priv
->r100c08
= pci_map_page(device
->pdev
, priv
->r100c08_page
,
255 PCI_DMA_BIDIRECTIONAL
);
256 if (pci_dma_mapping_error(device
->pdev
, priv
->r100c08
))
257 nv_warn(priv
, "failed 0x100c08 page map\n");
259 nv_warn(priv
, "failed 0x100c08 page alloc\n");
262 priv
->base
.memtype_valid
= nv50_fb_memtype_valid
;
263 priv
->base
.ram
.get
= nv50_fb_vram_new
;
264 priv
->base
.ram
.put
= nv50_fb_vram_del
;
265 return nouveau_fb_created(&priv
->base
);
269 nv50_fb_dtor(struct nouveau_object
*object
)
271 struct nouveau_device
*device
= nv_device(object
);
272 struct nv50_fb_priv
*priv
= (void *)object
;
274 if (priv
->r100c08_page
) {
275 pci_unmap_page(device
->pdev
, priv
->r100c08
, PAGE_SIZE
,
276 PCI_DMA_BIDIRECTIONAL
);
277 __free_page(priv
->r100c08_page
);
280 nouveau_mm_fini(&priv
->base
.vram
);
281 nouveau_fb_destroy(&priv
->base
);
285 nv50_fb_init(struct nouveau_object
*object
)
287 struct nouveau_device
*device
= nv_device(object
);
288 struct nv50_fb_priv
*priv
= (void *)object
;
291 ret
= nouveau_fb_init(&priv
->base
);
295 /* Not a clue what this is exactly. Without pointing it at a
296 * scratch page, VRAM->GART blits with M2MF (as in DDX DFS)
297 * cause IOMMU "read from address 0" errors (rh#561267)
299 nv_wr32(priv
, 0x100c08, priv
->r100c08
>> 8);
301 /* This is needed to get meaningful information from 100c90
302 * on traps. No idea what these values mean exactly. */
303 switch (device
->chipset
) {
305 nv_wr32(priv
, 0x100c90, 0x000707ff);
310 nv_wr32(priv
, 0x100c90, 0x000d0fff);
313 nv_wr32(priv
, 0x100c90, 0x089d1fff);
316 nv_wr32(priv
, 0x100c90, 0x001d07ff);
323 struct nouveau_oclass
325 .handle
= NV_SUBDEV(FB
, 0x50),
326 .ofuncs
= &(struct nouveau_ofuncs
) {
327 .ctor
= nv50_fb_ctor
,
328 .dtor
= nv50_fb_dtor
,
329 .init
= nv50_fb_init
,
330 .fini
= _nouveau_fb_fini
,
334 static const struct nouveau_enum vm_dispatch_subclients
[] = {
335 { 0x00000000, "GRCTX", NULL
},
336 { 0x00000001, "NOTIFY", NULL
},
337 { 0x00000002, "QUERY", NULL
},
338 { 0x00000003, "COND", NULL
},
339 { 0x00000004, "M2M_IN", NULL
},
340 { 0x00000005, "M2M_OUT", NULL
},
341 { 0x00000006, "M2M_NOTIFY", NULL
},
345 static const struct nouveau_enum vm_ccache_subclients
[] = {
346 { 0x00000000, "CB", NULL
},
347 { 0x00000001, "TIC", NULL
},
348 { 0x00000002, "TSC", NULL
},
352 static const struct nouveau_enum vm_prop_subclients
[] = {
353 { 0x00000000, "RT0", NULL
},
354 { 0x00000001, "RT1", NULL
},
355 { 0x00000002, "RT2", NULL
},
356 { 0x00000003, "RT3", NULL
},
357 { 0x00000004, "RT4", NULL
},
358 { 0x00000005, "RT5", NULL
},
359 { 0x00000006, "RT6", NULL
},
360 { 0x00000007, "RT7", NULL
},
361 { 0x00000008, "ZETA", NULL
},
362 { 0x00000009, "LOCAL", NULL
},
363 { 0x0000000a, "GLOBAL", NULL
},
364 { 0x0000000b, "STACK", NULL
},
365 { 0x0000000c, "DST2D", NULL
},
369 static const struct nouveau_enum vm_pfifo_subclients
[] = {
370 { 0x00000000, "PUSHBUF", NULL
},
371 { 0x00000001, "SEMAPHORE", NULL
},
375 static const struct nouveau_enum vm_bar_subclients
[] = {
376 { 0x00000000, "FB", NULL
},
377 { 0x00000001, "IN", NULL
},
381 static const struct nouveau_enum vm_client
[] = {
382 { 0x00000000, "STRMOUT", NULL
},
383 { 0x00000003, "DISPATCH", vm_dispatch_subclients
},
384 { 0x00000004, "PFIFO_WRITE", NULL
},
385 { 0x00000005, "CCACHE", vm_ccache_subclients
},
386 { 0x00000006, "PPPP", NULL
},
387 { 0x00000007, "CLIPID", NULL
},
388 { 0x00000008, "PFIFO_READ", NULL
},
389 { 0x00000009, "VFETCH", NULL
},
390 { 0x0000000a, "TEXTURE", NULL
},
391 { 0x0000000b, "PROP", vm_prop_subclients
},
392 { 0x0000000c, "PVP", NULL
},
393 { 0x0000000d, "PBSP", NULL
},
394 { 0x0000000e, "PCRYPT", NULL
},
395 { 0x0000000f, "PCOUNTER", NULL
},
396 { 0x00000011, "PDAEMON", NULL
},
400 static const struct nouveau_enum vm_engine
[] = {
401 { 0x00000000, "PGRAPH", NULL
},
402 { 0x00000001, "PVP", NULL
},
403 { 0x00000004, "PEEPHOLE", NULL
},
404 { 0x00000005, "PFIFO", vm_pfifo_subclients
},
405 { 0x00000006, "BAR", vm_bar_subclients
},
406 { 0x00000008, "PPPP", NULL
},
407 { 0x00000009, "PBSP", NULL
},
408 { 0x0000000a, "PCRYPT", NULL
},
409 { 0x0000000b, "PCOUNTER", NULL
},
410 { 0x0000000c, "SEMAPHORE_BG", NULL
},
411 { 0x0000000d, "PCOPY", NULL
},
412 { 0x0000000e, "PDAEMON", NULL
},
416 static const struct nouveau_enum vm_fault
[] = {
417 { 0x00000000, "PT_NOT_PRESENT", NULL
},
418 { 0x00000001, "PT_TOO_SHORT", NULL
},
419 { 0x00000002, "PAGE_NOT_PRESENT", NULL
},
420 { 0x00000003, "PAGE_SYSTEM_ONLY", NULL
},
421 { 0x00000004, "PAGE_READ_ONLY", NULL
},
422 { 0x00000006, "NULL_DMAOBJ", NULL
},
423 { 0x00000007, "WRONG_MEMTYPE", NULL
},
424 { 0x0000000b, "VRAM_LIMIT", NULL
},
425 { 0x0000000f, "DMAOBJ_LIMIT", NULL
},
430 nv50_fb_trap(struct nouveau_fb
*pfb
, int display
)
432 struct nouveau_device
*device
= nv_device(pfb
);
433 struct nv50_fb_priv
*priv
= (void *)pfb
;
434 const struct nouveau_enum
*en
, *cl
;
435 u32 trap
[6], idx
, chan
;
436 u8 st0
, st1
, st2
, st3
;
439 idx
= nv_rd32(priv
, 0x100c90);
440 if (!(idx
& 0x80000000))
444 for (i
= 0; i
< 6; i
++) {
445 nv_wr32(priv
, 0x100c90, idx
| i
<< 24);
446 trap
[i
] = nv_rd32(priv
, 0x100c94);
448 nv_wr32(priv
, 0x100c90, idx
| 0x80000000);
453 /* decode status bits into something more useful */
454 if (device
->chipset
< 0xa3 ||
455 device
->chipset
== 0xaa || device
->chipset
== 0xac) {
456 st0
= (trap
[0] & 0x0000000f) >> 0;
457 st1
= (trap
[0] & 0x000000f0) >> 4;
458 st2
= (trap
[0] & 0x00000f00) >> 8;
459 st3
= (trap
[0] & 0x0000f000) >> 12;
461 st0
= (trap
[0] & 0x000000ff) >> 0;
462 st1
= (trap
[0] & 0x0000ff00) >> 8;
463 st2
= (trap
[0] & 0x00ff0000) >> 16;
464 st3
= (trap
[0] & 0xff000000) >> 24;
466 chan
= (trap
[2] << 16) | trap
[1];
468 nv_error(priv
, "trapped %s at 0x%02x%04x%04x on channel 0x%08x ",
469 (trap
[5] & 0x00000100) ? "read" : "write",
470 trap
[5] & 0xff, trap
[4] & 0xffff, trap
[3] & 0xffff, chan
);
472 en
= nouveau_enum_find(vm_engine
, st0
);
474 printk("%s/", en
->name
);
476 printk("%02x/", st0
);
478 cl
= nouveau_enum_find(vm_client
, st2
);
480 printk("%s/", cl
->name
);
482 printk("%02x/", st2
);
484 if (cl
&& cl
->data
) cl
= nouveau_enum_find(cl
->data
, st3
);
485 else if (en
&& en
->data
) cl
= nouveau_enum_find(en
->data
, st3
);
488 printk("%s", cl
->name
);
493 en
= nouveau_enum_find(vm_fault
, st1
);
495 printk("%s\n", en
->name
);
497 printk("0x%08x\n", st1
);