Merge remote branch 'nouveau/drm-nouveau-next' of ../drm-nouveau-next into drm-core-next
* 'nouveau/drm-nouveau-next' of ../drm-nouveau-next: drm/nouveau: fix __nouveau_fence_wait performance drm/nv40: attempt to reserve just enough vram for all 32 channels drm/nv50: check for vm traps on every gr irq drm/nv50: decode vm faults some more drm/nouveau: add nouveau_enum_find() util function drm/nouveau: properly handle pushbuffer check failures drm/nvc0: remove vm hack forcing large/small pages to not share a PDE
This commit is contained in:
@@ -1076,7 +1076,7 @@ extern void nv40_fb_set_tile_region(struct drm_device *dev, int i);
|
|||||||
/* nv50_fb.c */
|
/* nv50_fb.c */
|
||||||
extern int nv50_fb_init(struct drm_device *);
|
extern int nv50_fb_init(struct drm_device *);
|
||||||
extern void nv50_fb_takedown(struct drm_device *);
|
extern void nv50_fb_takedown(struct drm_device *);
|
||||||
extern void nv50_fb_vm_trap(struct drm_device *, int display, const char *);
|
extern void nv50_fb_vm_trap(struct drm_device *, int display);
|
||||||
|
|
||||||
/* nvc0_fb.c */
|
/* nvc0_fb.c */
|
||||||
extern int nvc0_fb_init(struct drm_device *);
|
extern int nvc0_fb_init(struct drm_device *);
|
||||||
|
|||||||
@@ -27,6 +27,9 @@
|
|||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
|
||||||
|
#include <linux/ktime.h>
|
||||||
|
#include <linux/hrtimer.h>
|
||||||
|
|
||||||
#include "nouveau_drv.h"
|
#include "nouveau_drv.h"
|
||||||
#include "nouveau_ramht.h"
|
#include "nouveau_ramht.h"
|
||||||
#include "nouveau_dma.h"
|
#include "nouveau_dma.h"
|
||||||
@@ -229,7 +232,8 @@ int
|
|||||||
__nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
|
__nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
|
||||||
{
|
{
|
||||||
unsigned long timeout = jiffies + (3 * DRM_HZ);
|
unsigned long timeout = jiffies + (3 * DRM_HZ);
|
||||||
unsigned long sleep_time = jiffies + 1;
|
unsigned long sleep_time = NSEC_PER_MSEC / 1000;
|
||||||
|
ktime_t t;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -243,8 +247,13 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
|
|||||||
|
|
||||||
__set_current_state(intr ? TASK_INTERRUPTIBLE
|
__set_current_state(intr ? TASK_INTERRUPTIBLE
|
||||||
: TASK_UNINTERRUPTIBLE);
|
: TASK_UNINTERRUPTIBLE);
|
||||||
if (lazy && time_after_eq(jiffies, sleep_time))
|
if (lazy) {
|
||||||
schedule_timeout(1);
|
t = ktime_set(0, sleep_time);
|
||||||
|
schedule_hrtimeout(&t, HRTIMER_MODE_REL);
|
||||||
|
sleep_time *= 2;
|
||||||
|
if (sleep_time > NSEC_PER_MSEC)
|
||||||
|
sleep_time = NSEC_PER_MSEC;
|
||||||
|
}
|
||||||
|
|
||||||
if (intr && signal_pending(current)) {
|
if (intr && signal_pending(current)) {
|
||||||
ret = -ERESTARTSYS;
|
ret = -ERESTARTSYS;
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
|
|||||||
if (push[i].bo_index >= req->nr_buffers) {
|
if (push[i].bo_index >= req->nr_buffers) {
|
||||||
NV_ERROR(dev, "push %d buffer not in list\n", i);
|
NV_ERROR(dev, "push %d buffer not in list\n", i);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out_prevalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bo[push[i].bo_index].read_domains |= (1 << 31);
|
bo[push[i].bo_index].read_domains |= (1 << 31);
|
||||||
@@ -612,7 +612,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret != -ERESTARTSYS)
|
if (ret != -ERESTARTSYS)
|
||||||
NV_ERROR(dev, "validate: %d\n", ret);
|
NV_ERROR(dev, "validate: %d\n", ret);
|
||||||
goto out;
|
goto out_prevalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply any relocations that are required */
|
/* Apply any relocations that are required */
|
||||||
@@ -705,6 +705,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
|
|||||||
out:
|
out:
|
||||||
validate_fini(&op, fence);
|
validate_fini(&op, fence);
|
||||||
nouveau_fence_unref(&fence);
|
nouveau_fence_unref(&fence);
|
||||||
|
|
||||||
|
out_prevalid:
|
||||||
kfree(bo);
|
kfree(bo);
|
||||||
kfree(push);
|
kfree(push);
|
||||||
|
|
||||||
|
|||||||
@@ -424,14 +424,32 @@ nouveau_mem_vram_init(struct drm_device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* reserve space at end of VRAM for PRAMIN */
|
/* reserve space at end of VRAM for PRAMIN */
|
||||||
if (dev_priv->chipset == 0x40 || dev_priv->chipset == 0x47 ||
|
if (dev_priv->card_type >= NV_50) {
|
||||||
dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b)
|
dev_priv->ramin_rsvd_vram = 1 * 1024 * 1024;
|
||||||
dev_priv->ramin_rsvd_vram = (2 * 1024 * 1024);
|
} else
|
||||||
else
|
if (dev_priv->card_type >= NV_40) {
|
||||||
if (dev_priv->card_type >= NV_40)
|
u32 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8);
|
||||||
dev_priv->ramin_rsvd_vram = (1 * 1024 * 1024);
|
u32 rsvd;
|
||||||
else
|
|
||||||
dev_priv->ramin_rsvd_vram = (512 * 1024);
|
/* estimate grctx size, the magics come from nv40_grctx.c */
|
||||||
|
if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs;
|
||||||
|
else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs;
|
||||||
|
else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs;
|
||||||
|
else rsvd = 0x4a40 * vs;
|
||||||
|
rsvd += 16 * 1024;
|
||||||
|
rsvd *= dev_priv->engine.fifo.channels;
|
||||||
|
|
||||||
|
/* pciegart table */
|
||||||
|
if (drm_pci_device_is_pcie(dev))
|
||||||
|
rsvd += 512 * 1024;
|
||||||
|
|
||||||
|
/* object storage */
|
||||||
|
rsvd += 512 * 1024;
|
||||||
|
|
||||||
|
dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096);
|
||||||
|
} else {
|
||||||
|
dev_priv->ramin_rsvd_vram = 512 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
ret = dev_priv->engine.vram.init(dev);
|
ret = dev_priv->engine.vram.init(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|||||||
@@ -427,8 +427,7 @@ nouveau_sgdma_init(struct drm_device *dev)
|
|||||||
u32 aper_size, align;
|
u32 aper_size, align;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (dev_priv->card_type >= NV_50 ||
|
if (dev_priv->card_type >= NV_50 || drm_pci_device_is_pcie(dev))
|
||||||
dev_priv->ramin_rsvd_vram >= 2 * 1024 * 1024)
|
|
||||||
aper_size = 512 * 1024 * 1024;
|
aper_size = 512 * 1024 * 1024;
|
||||||
else
|
else
|
||||||
aper_size = 64 * 1024 * 1024;
|
aper_size = 64 * 1024 * 1024;
|
||||||
|
|||||||
@@ -47,16 +47,25 @@ nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
|
|||||||
printk(" (unknown bits 0x%08x)", value);
|
printk(" (unknown bits 0x%08x)", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct nouveau_enum *
|
||||||
|
nouveau_enum_find(const struct nouveau_enum *en, u32 value)
|
||||||
|
{
|
||||||
|
while (en->name) {
|
||||||
|
if (en->value == value)
|
||||||
|
return en;
|
||||||
|
en++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nouveau_enum_print(const struct nouveau_enum *en, u32 value)
|
nouveau_enum_print(const struct nouveau_enum *en, u32 value)
|
||||||
{
|
{
|
||||||
while (en->name) {
|
en = nouveau_enum_find(en, value);
|
||||||
if (value == en->value) {
|
if (en) {
|
||||||
printk("%s", en->name);
|
printk("%s", en->name);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
en++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("(unknown enum 0x%08x)", value);
|
printk("(unknown enum 0x%08x)", value);
|
||||||
|
|||||||
@@ -36,10 +36,14 @@ struct nouveau_bitfield {
|
|||||||
struct nouveau_enum {
|
struct nouveau_enum {
|
||||||
u32 value;
|
u32 value;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
|
void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
|
||||||
void nouveau_enum_print(const struct nouveau_enum *, u32 value);
|
void nouveau_enum_print(const struct nouveau_enum *, u32 value);
|
||||||
|
const struct nouveau_enum *
|
||||||
|
nouveau_enum_find(const struct nouveau_enum *, u32 value);
|
||||||
|
|
||||||
int nouveau_ratelimit(void);
|
int nouveau_ratelimit(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -314,18 +314,7 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset,
|
|||||||
vm->spg_shift = 12;
|
vm->spg_shift = 12;
|
||||||
vm->lpg_shift = 17;
|
vm->lpg_shift = 17;
|
||||||
pgt_bits = 27;
|
pgt_bits = 27;
|
||||||
|
block = 4096;
|
||||||
/* Should be 4096 everywhere, this is a hack that's
|
|
||||||
* currently necessary to avoid an elusive bug that
|
|
||||||
* causes corruption when mixing small/large pages
|
|
||||||
*/
|
|
||||||
if (length < (1ULL << 40))
|
|
||||||
block = 4096;
|
|
||||||
else {
|
|
||||||
block = (1 << pgt_bits);
|
|
||||||
if (length < block)
|
|
||||||
block = length;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
kfree(vm);
|
kfree(vm);
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|||||||
@@ -516,7 +516,7 @@ nv04_fifo_isr(struct drm_device *dev)
|
|||||||
|
|
||||||
if (dev_priv->card_type == NV_50) {
|
if (dev_priv->card_type == NV_50) {
|
||||||
if (status & 0x00000010) {
|
if (status & 0x00000010) {
|
||||||
nv50_fb_vm_trap(dev, 1, "PFIFO_BAR_FAULT");
|
nv50_fb_vm_trap(dev, nouveau_ratelimit());
|
||||||
status &= ~0x00000010;
|
status &= ~0x00000010;
|
||||||
nv_wr32(dev, 0x002100, 0x00000010);
|
nv_wr32(dev, 0x002100, 0x00000010);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,12 +114,109 @@ nv50_fb_takedown(struct drm_device *dev)
|
|||||||
nv50_fb_destroy(dev);
|
nv50_fb_destroy(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_dispatch_subclients[] = {
|
||||||
|
{ 0x00000000, "GRCTX", NULL },
|
||||||
|
{ 0x00000001, "NOTIFY", NULL },
|
||||||
|
{ 0x00000002, "QUERY", NULL },
|
||||||
|
{ 0x00000003, "COND", NULL },
|
||||||
|
{ 0x00000004, "M2M_IN", NULL },
|
||||||
|
{ 0x00000005, "M2M_OUT", NULL },
|
||||||
|
{ 0x00000006, "M2M_NOTIFY", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_ccache_subclients[] = {
|
||||||
|
{ 0x00000000, "CB", NULL },
|
||||||
|
{ 0x00000001, "TIC", NULL },
|
||||||
|
{ 0x00000002, "TSC", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_prop_subclients[] = {
|
||||||
|
{ 0x00000000, "RT0", NULL },
|
||||||
|
{ 0x00000001, "RT1", NULL },
|
||||||
|
{ 0x00000002, "RT2", NULL },
|
||||||
|
{ 0x00000003, "RT3", NULL },
|
||||||
|
{ 0x00000004, "RT4", NULL },
|
||||||
|
{ 0x00000005, "RT5", NULL },
|
||||||
|
{ 0x00000006, "RT6", NULL },
|
||||||
|
{ 0x00000007, "RT7", NULL },
|
||||||
|
{ 0x00000008, "ZETA", NULL },
|
||||||
|
{ 0x00000009, "LOCAL", NULL },
|
||||||
|
{ 0x0000000a, "GLOBAL", NULL },
|
||||||
|
{ 0x0000000b, "STACK", NULL },
|
||||||
|
{ 0x0000000c, "DST2D", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_pfifo_subclients[] = {
|
||||||
|
{ 0x00000000, "PUSHBUF", NULL },
|
||||||
|
{ 0x00000001, "SEMAPHORE", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_bar_subclients[] = {
|
||||||
|
{ 0x00000000, "FB", NULL },
|
||||||
|
{ 0x00000001, "IN", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_client[] = {
|
||||||
|
{ 0x00000000, "STRMOUT", NULL },
|
||||||
|
{ 0x00000003, "DISPATCH", vm_dispatch_subclients },
|
||||||
|
{ 0x00000004, "PFIFO_WRITE", NULL },
|
||||||
|
{ 0x00000005, "CCACHE", vm_ccache_subclients },
|
||||||
|
{ 0x00000006, "PPPP", NULL },
|
||||||
|
{ 0x00000007, "CLIPID", NULL },
|
||||||
|
{ 0x00000008, "PFIFO_READ", NULL },
|
||||||
|
{ 0x00000009, "VFETCH", NULL },
|
||||||
|
{ 0x0000000a, "TEXTURE", NULL },
|
||||||
|
{ 0x0000000b, "PROP", vm_prop_subclients },
|
||||||
|
{ 0x0000000c, "PVP", NULL },
|
||||||
|
{ 0x0000000d, "PBSP", NULL },
|
||||||
|
{ 0x0000000e, "PCRYPT", NULL },
|
||||||
|
{ 0x0000000f, "PCOUNTER", NULL },
|
||||||
|
{ 0x00000011, "PDAEMON", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_engine[] = {
|
||||||
|
{ 0x00000000, "PGRAPH", NULL },
|
||||||
|
{ 0x00000001, "PVP", NULL },
|
||||||
|
{ 0x00000004, "PEEPHOLE", NULL },
|
||||||
|
{ 0x00000005, "PFIFO", vm_pfifo_subclients },
|
||||||
|
{ 0x00000006, "BAR", vm_bar_subclients },
|
||||||
|
{ 0x00000008, "PPPP", NULL },
|
||||||
|
{ 0x00000009, "PBSP", NULL },
|
||||||
|
{ 0x0000000a, "PCRYPT", NULL },
|
||||||
|
{ 0x0000000b, "PCOUNTER", NULL },
|
||||||
|
{ 0x0000000c, "SEMAPHORE_BG", NULL },
|
||||||
|
{ 0x0000000d, "PCOPY", NULL },
|
||||||
|
{ 0x0000000e, "PDAEMON", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nouveau_enum vm_fault[] = {
|
||||||
|
{ 0x00000000, "PT_NOT_PRESENT", NULL },
|
||||||
|
{ 0x00000001, "PT_TOO_SHORT", NULL },
|
||||||
|
{ 0x00000002, "PAGE_NOT_PRESENT", NULL },
|
||||||
|
{ 0x00000003, "PAGE_SYSTEM_ONLY", NULL },
|
||||||
|
{ 0x00000004, "PAGE_READ_ONLY", NULL },
|
||||||
|
{ 0x00000006, "NULL_DMAOBJ", NULL },
|
||||||
|
{ 0x00000007, "WRONG_MEMTYPE", NULL },
|
||||||
|
{ 0x0000000b, "VRAM_LIMIT", NULL },
|
||||||
|
{ 0x0000000f, "DMAOBJ_LIMIT", NULL },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name)
|
nv50_fb_vm_trap(struct drm_device *dev, int display)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
|
const struct nouveau_enum *en, *cl;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 trap[6], idx, chinst;
|
u32 trap[6], idx, chinst;
|
||||||
|
u8 st0, st1, st2, st3;
|
||||||
int i, ch;
|
int i, ch;
|
||||||
|
|
||||||
idx = nv_rd32(dev, 0x100c90);
|
idx = nv_rd32(dev, 0x100c90);
|
||||||
@@ -136,8 +233,8 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name)
|
|||||||
if (!display)
|
if (!display)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* lookup channel id */
|
||||||
chinst = (trap[2] << 16) | trap[1];
|
chinst = (trap[2] << 16) | trap[1];
|
||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->channels.lock, flags);
|
spin_lock_irqsave(&dev_priv->channels.lock, flags);
|
||||||
for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) {
|
for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) {
|
||||||
struct nouveau_channel *chan = dev_priv->channels.ptr[ch];
|
struct nouveau_channel *chan = dev_priv->channels.ptr[ch];
|
||||||
@@ -150,9 +247,48 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name)
|
|||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
|
spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
|
||||||
|
|
||||||
NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x "
|
/* decode status bits into something more useful */
|
||||||
"channel %d (0x%08x)\n",
|
if (dev_priv->chipset < 0xa3 ||
|
||||||
name, (trap[5] & 0x100 ? "read" : "write"),
|
dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) {
|
||||||
trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff,
|
st0 = (trap[0] & 0x0000000f) >> 0;
|
||||||
trap[0], ch, chinst);
|
st1 = (trap[0] & 0x000000f0) >> 4;
|
||||||
|
st2 = (trap[0] & 0x00000f00) >> 8;
|
||||||
|
st3 = (trap[0] & 0x0000f000) >> 12;
|
||||||
|
} else {
|
||||||
|
st0 = (trap[0] & 0x000000ff) >> 0;
|
||||||
|
st1 = (trap[0] & 0x0000ff00) >> 8;
|
||||||
|
st2 = (trap[0] & 0x00ff0000) >> 16;
|
||||||
|
st3 = (trap[0] & 0xff000000) >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
NV_INFO(dev, "VM: trapped %s at 0x%02x%04x%04x on ch %d [0x%08x] ",
|
||||||
|
(trap[5] & 0x00000100) ? "read" : "write",
|
||||||
|
trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ch, chinst);
|
||||||
|
|
||||||
|
en = nouveau_enum_find(vm_engine, st0);
|
||||||
|
if (en)
|
||||||
|
printk("%s/", en->name);
|
||||||
|
else
|
||||||
|
printk("%02x/", st0);
|
||||||
|
|
||||||
|
cl = nouveau_enum_find(vm_client, st2);
|
||||||
|
if (cl)
|
||||||
|
printk("%s/", cl->name);
|
||||||
|
else
|
||||||
|
printk("%02x/", st2);
|
||||||
|
|
||||||
|
if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3);
|
||||||
|
else if (en && en->data) cl = nouveau_enum_find(en->data, st3);
|
||||||
|
else cl = NULL;
|
||||||
|
if (cl)
|
||||||
|
printk("%s", cl->name);
|
||||||
|
else
|
||||||
|
printk("%02x", st3);
|
||||||
|
|
||||||
|
printk(" reason: ");
|
||||||
|
en = nouveau_enum_find(vm_fault, st1);
|
||||||
|
if (en)
|
||||||
|
printk("%s\n", en->name);
|
||||||
|
else
|
||||||
|
printk("0x%08x\n", st1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -550,11 +550,11 @@ nv86_graph_tlb_flush(struct drm_device *dev)
|
|||||||
|
|
||||||
static struct nouveau_enum nv50_mp_exec_error_names[] =
|
static struct nouveau_enum nv50_mp_exec_error_names[] =
|
||||||
{
|
{
|
||||||
{ 3, "STACK_UNDERFLOW" },
|
{ 3, "STACK_UNDERFLOW", NULL },
|
||||||
{ 4, "QUADON_ACTIVE" },
|
{ 4, "QUADON_ACTIVE", NULL },
|
||||||
{ 8, "TIMEOUT" },
|
{ 8, "TIMEOUT", NULL },
|
||||||
{ 0x10, "INVALID_OPCODE" },
|
{ 0x10, "INVALID_OPCODE", NULL },
|
||||||
{ 0x40, "BREAKPOINT" },
|
{ 0x40, "BREAKPOINT", NULL },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -582,47 +582,47 @@ static struct nouveau_bitfield nv50_graph_trap_ccache[] = {
|
|||||||
|
|
||||||
/* There must be a *lot* of these. Will take some time to gather them up. */
|
/* There must be a *lot* of these. Will take some time to gather them up. */
|
||||||
struct nouveau_enum nv50_data_error_names[] = {
|
struct nouveau_enum nv50_data_error_names[] = {
|
||||||
{ 0x00000003, "INVALID_QUERY_OR_TEXTURE" },
|
{ 0x00000003, "INVALID_QUERY_OR_TEXTURE", NULL },
|
||||||
{ 0x00000004, "INVALID_VALUE" },
|
{ 0x00000004, "INVALID_VALUE", NULL },
|
||||||
{ 0x00000005, "INVALID_ENUM" },
|
{ 0x00000005, "INVALID_ENUM", NULL },
|
||||||
{ 0x00000008, "INVALID_OBJECT" },
|
{ 0x00000008, "INVALID_OBJECT", NULL },
|
||||||
{ 0x00000009, "READ_ONLY_OBJECT" },
|
{ 0x00000009, "READ_ONLY_OBJECT", NULL },
|
||||||
{ 0x0000000a, "SUPERVISOR_OBJECT" },
|
{ 0x0000000a, "SUPERVISOR_OBJECT", NULL },
|
||||||
{ 0x0000000b, "INVALID_ADDRESS_ALIGNMENT" },
|
{ 0x0000000b, "INVALID_ADDRESS_ALIGNMENT", NULL },
|
||||||
{ 0x0000000c, "INVALID_BITFIELD" },
|
{ 0x0000000c, "INVALID_BITFIELD", NULL },
|
||||||
{ 0x0000000d, "BEGIN_END_ACTIVE" },
|
{ 0x0000000d, "BEGIN_END_ACTIVE", NULL },
|
||||||
{ 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT" },
|
{ 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT", NULL },
|
||||||
{ 0x0000000f, "VIEWPORT_ID_NEEDS_GP" },
|
{ 0x0000000f, "VIEWPORT_ID_NEEDS_GP", NULL },
|
||||||
{ 0x00000010, "RT_DOUBLE_BIND" },
|
{ 0x00000010, "RT_DOUBLE_BIND", NULL },
|
||||||
{ 0x00000011, "RT_TYPES_MISMATCH" },
|
{ 0x00000011, "RT_TYPES_MISMATCH", NULL },
|
||||||
{ 0x00000012, "RT_LINEAR_WITH_ZETA" },
|
{ 0x00000012, "RT_LINEAR_WITH_ZETA", NULL },
|
||||||
{ 0x00000015, "FP_TOO_FEW_REGS" },
|
{ 0x00000015, "FP_TOO_FEW_REGS", NULL },
|
||||||
{ 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH" },
|
{ 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH", NULL },
|
||||||
{ 0x00000017, "RT_LINEAR_WITH_MSAA" },
|
{ 0x00000017, "RT_LINEAR_WITH_MSAA", NULL },
|
||||||
{ 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT" },
|
{ 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT", NULL },
|
||||||
{ 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT" },
|
{ 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT", NULL },
|
||||||
{ 0x0000001a, "RT_INVALID_ALIGNMENT" },
|
{ 0x0000001a, "RT_INVALID_ALIGNMENT", NULL },
|
||||||
{ 0x0000001b, "SAMPLER_OVER_LIMIT" },
|
{ 0x0000001b, "SAMPLER_OVER_LIMIT", NULL },
|
||||||
{ 0x0000001c, "TEXTURE_OVER_LIMIT" },
|
{ 0x0000001c, "TEXTURE_OVER_LIMIT", NULL },
|
||||||
{ 0x0000001e, "GP_TOO_MANY_OUTPUTS" },
|
{ 0x0000001e, "GP_TOO_MANY_OUTPUTS", NULL },
|
||||||
{ 0x0000001f, "RT_BPP128_WITH_MS8" },
|
{ 0x0000001f, "RT_BPP128_WITH_MS8", NULL },
|
||||||
{ 0x00000021, "Z_OUT_OF_BOUNDS" },
|
{ 0x00000021, "Z_OUT_OF_BOUNDS", NULL },
|
||||||
{ 0x00000023, "XY_OUT_OF_BOUNDS" },
|
{ 0x00000023, "XY_OUT_OF_BOUNDS", NULL },
|
||||||
{ 0x00000027, "CP_MORE_PARAMS_THAN_SHARED" },
|
{ 0x00000027, "CP_MORE_PARAMS_THAN_SHARED", NULL },
|
||||||
{ 0x00000028, "CP_NO_REG_SPACE_STRIPED" },
|
{ 0x00000028, "CP_NO_REG_SPACE_STRIPED", NULL },
|
||||||
{ 0x00000029, "CP_NO_REG_SPACE_PACKED" },
|
{ 0x00000029, "CP_NO_REG_SPACE_PACKED", NULL },
|
||||||
{ 0x0000002a, "CP_NOT_ENOUGH_WARPS" },
|
{ 0x0000002a, "CP_NOT_ENOUGH_WARPS", NULL },
|
||||||
{ 0x0000002b, "CP_BLOCK_SIZE_MISMATCH" },
|
{ 0x0000002b, "CP_BLOCK_SIZE_MISMATCH", NULL },
|
||||||
{ 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS" },
|
{ 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS", NULL },
|
||||||
{ 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS" },
|
{ 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS", NULL },
|
||||||
{ 0x0000002e, "CP_NO_BLOCKDIM_LATCH" },
|
{ 0x0000002e, "CP_NO_BLOCKDIM_LATCH", NULL },
|
||||||
{ 0x00000031, "ENG2D_FORMAT_MISMATCH" },
|
{ 0x00000031, "ENG2D_FORMAT_MISMATCH", NULL },
|
||||||
{ 0x0000003f, "PRIMITIVE_ID_NEEDS_GP" },
|
{ 0x0000003f, "PRIMITIVE_ID_NEEDS_GP", NULL },
|
||||||
{ 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT" },
|
{ 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT", NULL },
|
||||||
{ 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT" },
|
{ 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT", NULL },
|
||||||
{ 0x00000046, "LAYER_ID_NEEDS_GP" },
|
{ 0x00000046, "LAYER_ID_NEEDS_GP", NULL },
|
||||||
{ 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT" },
|
{ 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT", NULL },
|
||||||
{ 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT" },
|
{ 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT", NULL },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -702,7 +702,6 @@ nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old,
|
|||||||
tps++;
|
tps++;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 6: /* texture error... unknown for now */
|
case 6: /* texture error... unknown for now */
|
||||||
nv50_fb_vm_trap(dev, display, name);
|
|
||||||
if (display) {
|
if (display) {
|
||||||
NV_ERROR(dev, "magic set %d:\n", i);
|
NV_ERROR(dev, "magic set %d:\n", i);
|
||||||
for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
|
for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
|
||||||
@@ -725,7 +724,6 @@ nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old,
|
|||||||
uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14);
|
uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14);
|
||||||
uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18);
|
uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18);
|
||||||
uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c);
|
uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c);
|
||||||
nv50_fb_vm_trap(dev, display, name);
|
|
||||||
/* 2d engine destination */
|
/* 2d engine destination */
|
||||||
if (ustatus & 0x00000010) {
|
if (ustatus & 0x00000010) {
|
||||||
if (display) {
|
if (display) {
|
||||||
@@ -1068,6 +1066,7 @@ nv50_graph_isr(struct drm_device *dev)
|
|||||||
NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) subc %d "
|
NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) subc %d "
|
||||||
"class 0x%04x mthd 0x%04x data 0x%08x\n",
|
"class 0x%04x mthd 0x%04x data 0x%08x\n",
|
||||||
chid, inst, subc, class, mthd, data);
|
chid, inst, subc, class, mthd, data);
|
||||||
|
nv50_fb_vm_trap(dev, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,5 +136,5 @@ nv84_crypt_isr(struct drm_device *dev)
|
|||||||
nv_wr32(dev, 0x102130, stat);
|
nv_wr32(dev, 0x102130, stat);
|
||||||
nv_wr32(dev, 0x10200c, 0x10);
|
nv_wr32(dev, 0x10200c, 0x10);
|
||||||
|
|
||||||
nv50_fb_vm_trap(dev, show, "PCRYPT");
|
nv50_fb_vm_trap(dev, show);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user