]>
Commit | Line | Data |
---|---|---|
304424e1 MK |
1 | #include "drmP.h" |
2 | #include "drm.h" | |
3 | #include "nouveau_drv.h" | |
4 | #include "nouveau_drm.h" | |
5 | ||
6 | int | |
7 | nv50_fb_init(struct drm_device *dev) | |
8 | { | |
304424e1 MK |
9 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
10 | ||
4eb3033c BS |
11 | /* Not a clue what this is exactly. Without pointing it at a |
12 | * scratch page, VRAM->GART blits with M2MF (as in DDX DFS) | |
13 | * cause IOMMU "read from address 0" errors (rh#561267) | |
14 | */ | |
15 | nv_wr32(dev, 0x100c08, dev_priv->gart_info.sg_dummy_bus >> 8); | |
16 | ||
17 | /* This is needed to get meaningful information from 100c90 | |
18 | * on traps. No idea what these values mean exactly. */ | |
304424e1 MK |
19 | switch (dev_priv->chipset) { |
20 | case 0x50: | |
21 | nv_wr32(dev, 0x100c90, 0x0707ff); | |
22 | break; | |
f9aafdd3 | 23 | case 0xa3: |
304424e1 MK |
24 | case 0xa5: |
25 | case 0xa8: | |
26 | nv_wr32(dev, 0x100c90, 0x0d0fff); | |
27 | break; | |
28 | default: | |
29 | nv_wr32(dev, 0x100c90, 0x1d07ff); | |
30 | break; | |
31 | } | |
32 | ||
33 | return 0; | |
34 | } | |
35 | ||
36 | void | |
37 | nv50_fb_takedown(struct drm_device *dev) | |
38 | { | |
39 | } | |
d96773e7 BS |
40 | |
41 | void | |
42 | nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) | |
43 | { | |
44 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
cff5c133 | 45 | unsigned long flags; |
d96773e7 BS |
46 | u32 trap[6], idx, chinst; |
47 | int i, ch; | |
48 | ||
49 | idx = nv_rd32(dev, 0x100c90); | |
50 | if (!(idx & 0x80000000)) | |
51 | return; | |
52 | idx &= 0x00ffffff; | |
53 | ||
54 | for (i = 0; i < 6; i++) { | |
55 | nv_wr32(dev, 0x100c90, idx | i << 24); | |
56 | trap[i] = nv_rd32(dev, 0x100c94); | |
57 | } | |
58 | nv_wr32(dev, 0x100c90, idx | 0x80000000); | |
59 | ||
60 | if (!display) | |
61 | return; | |
62 | ||
63 | chinst = (trap[2] << 16) | trap[1]; | |
cff5c133 BS |
64 | |
65 | spin_lock_irqsave(&dev_priv->channels.lock, flags); | |
d96773e7 | 66 | for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { |
cff5c133 | 67 | struct nouveau_channel *chan = dev_priv->channels.ptr[ch]; |
d96773e7 BS |
68 | |
69 | if (!chan || !chan->ramin) | |
70 | continue; | |
71 | ||
72 | if (chinst == chan->ramin->vinst >> 12) | |
73 | break; | |
74 | } | |
cff5c133 | 75 | spin_unlock_irqrestore(&dev_priv->channels.lock, flags); |
d96773e7 BS |
76 | |
77 | NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x " | |
78 | "channel %d (0x%08x)\n", | |
79 | name, (trap[5] & 0x100 ? "read" : "write"), | |
80 | trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, | |
81 | trap[0], ch, chinst); | |
82 | } |