summaryrefslogtreecommitdiff
path: root/shared-core
AgeCommit message (Collapse)Author
2007-10-25i915: relocate buffers before validation add memory barrier between twoDave Airlie
2007-10-25i915: remove relocatee kernel mapping sooner stops mutex taking during sleepDave Airlie
2007-10-24Fix missing \n on some DRM_ERROR in i915_dma.cEric Anholt
2007-10-24i915: use a drm memory barrier defineDave Airlie
2007-10-23Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into ↵Alan Hourihane
modesetting-101
2007-10-23i915: require mfence before submitting batchbufferDave Airlie
2007-10-23nouveau: fix IGPStephane Marchesin
2007-10-22A cmdbuf mutex to implement validate-submit-fence atomicity in the absenceThomas Hellstrom
of a hardware lock.
2007-10-22i915: split reloc execution into separate functionDave Airlie
2007-10-21Adapt i915 super-ioctl for lock-free operation.Thomas Hellstrom
2007-10-21Remove the need for the hardware lock in the buffer manager.Thomas Hellstrom
Add interface entry cleaning a memory type without touching NO_EVICT buffers.
2007-10-20Simple replacement for hardware lock in some cases.Thomas Hellstrom
Fix i915 since last commit.
2007-10-17Remove the op ioctl, and replace it with a setuser ioctl.Thomas Hellstrom
Remove need for lock for now. May create races when we clean memory areas or on takedown. Needs to be fixed. Really do a validate on buffer creation in order to avoid problems with fixed memory buffers.
2007-10-17Revert "Replace NO_MOVE/NO_EVICT flags to buffer objects with an ioctl to ↵Thomas Hellstrom
set pinning." This reverts cf2d569daca6954d11a796f4d110148ae2e0c827 commit.
2007-10-17Revert "Add some more verbosity to drm_bo_set_pin_req comments."Thomas Hellstrom
This reverts e7bfeb3031374653f7e55d67cc1b5c823849359f commit.
2007-10-17Fix a crash on X startupAlan Hourihane
2007-10-17i915: lock struct mutex about buffer object lookupsDave Airlie
2007-10-16Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into ↵Alan Hourihane
modesetting-101 Conflicts: linux-core/drm_bo.c linux-core/drm_objects.h shared-core/i915_dma.c shared-core/i915_drv.h
2007-10-16Drop destroy ioctls for fences and buffer objects.Kristian Høgsberg
We now always create a drm_ref_object for user objects and this is then the only things that holds a reference to the user object. This way unreference on will destroy the user object when the last drm_ref_object goes way.
2007-10-16Take bo type argument out of the ioctl interface.Kristian Høgsberg
The buffer object type is still tracked internally, but it is no longer part of the user space visible ioctl interface. If the bo create ioctl specifies a non-NULL buffer address we assume drm_bo_type_user, otherwise drm_bo_type_dc. Kernel side allocations call drm_buffer_object_create() directly and can still specify drm_bo_type_kernel. Not 100% this makes sense either, but with this patch, the buffer type is no longer exported and we can clean up the internals later on.
2007-10-16Eliminate support for fake buffers.[utf-8] Kristian Høgsberg
2007-10-16nouveau: revert unintended change.Ben Skeggs
2007-10-16nouveau: Cleanup PGRAPH handler, attempt to survive PGRAPH exceptions.Ben Skeggs
2007-10-16nouveau: Survive PFIFO_CACHE_ERROR.Ben Skeggs
2007-10-16nouveau: Handle multiple PFIFO exceptions per irq, cleanup output.Ben Skeggs
2007-10-14nouveau: PPC fixes. These regs are very touchy.Stephane Marchesin
2007-10-14nouveau: fix warning.Jeremy Kolb
2007-10-14nouveau: fix warning.Jeremy Kolb
2007-10-14i915: fix vbl_swap allocationDave Airlie
2007-10-12nouveau: Fix a typo in nv25_graph_context_initPekka Paalanen
2007-10-12nouveau: Fix typos in nv20_graph_context_initStuart Bennett
2007-10-12nouveau: Make notifiers go into PCI memoryPekka Paalanen
On some hardware notifers in AGP memory just don't work.
2007-10-12nouveau: mandatory "oops I forgot half of the files" commitArthur Huillet
2007-10-12nouveau: added support for software methods, and implemented those necessary ↵Arthur Huillet
for NV04 (TNT1) to start X
2007-10-12i915: add superioctl support to i915Dave Airlie
This adds the initial i915 superioctl interface. The interface should be sufficent even if the implementation may needs fixes/optimisations internally in the drm wrt caching etc.
2007-10-10nouveau : nv10 and nv04 PGRAPH_NSTATUS are differentMatthieu Castet
2007-10-10nouveau: PMC_BOOT_1 was not mapped.Maarten Maathuis
2007-10-10nouveau: try to fix big endian.Stephane Marchesin
2007-10-07nouveau: A char is signed, so it may overflow for >NV50.Maarten Maathuis
2007-10-06nouveau : print correct value in nouveau_graph_dump_trap_info for nv04Matthieu Castet
2007-10-05Merge branch 'pre-superioctl-branch'Dave Airlie
2007-10-04nouveau: Remove excess device classes.Maarten Maathuis
2007-10-04nouveau: NV47 context switching voodoo + warningMaarten Maathuis
2007-10-04nouveau: Switch over to using PMC_BOOT_0 for card detection.Maarten Maathuis
2007-10-04nouveau: nv2a drm context switch support.Stephane Marchesin
2007-10-02nouveau: nv20 graph_create_context differencePekka Paalanen
nv20 writes the chan->id to a different place than nv28. This still does not make nv20 run nv10_demo.
2007-10-02nouveau: fix nv25_graph_context_initPekka Paalanen
It was writing 4x the data in a loop.
2007-10-02nouveau: nv20 graph context initStuart Bennett
2007-10-01nouveau: Fix dereferencing a NULL pointer when erroring out during ↵Maarten Maathuis
initialization.
2007-10-01nouveau: flip the ctx switch bit on. it seems to be ignored on nv34 but ↵Stephane Marchesin
causes nv30 issues.
opt">(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; /* Master disable */ NV_WRITE(NV03_PMC_INTR_EN_0, 0); } static void nouveau_fifo_irq_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->Engine; uint32_t status; while ((status = NV_READ(NV03_PFIFO_INTR_0))) { uint32_t chid, get; NV_WRITE(NV03_PFIFO_CACHES, 0); chid = engine->fifo.channel_id(dev); get = NV_READ(NV03_PFIFO_CACHE1_GET); if (status & NV_PFIFO_INTR_CACHE_ERROR) { uint32_t mthd, data; int ptr; ptr = get >> 2; if (dev_priv->card_type < NV_40) { mthd = NV_READ(NV04_PFIFO_CACHE1_METHOD(ptr)); data = NV_READ(NV04_PFIFO_CACHE1_DATA(ptr)); } else { mthd = NV_READ(NV40_PFIFO_CACHE1_METHOD(ptr)); data = NV_READ(NV40_PFIFO_CACHE1_DATA(ptr)); } DRM_INFO("PFIFO_CACHE_ERROR - " "Ch %d/%d Mthd 0x%04x Data 0x%08x\n", chid, (mthd >> 13) & 7, mthd & 0x1ffc, data); NV_WRITE(NV03_PFIFO_CACHE1_GET, get + 4); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 1); status &= ~NV_PFIFO_INTR_CACHE_ERROR; NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR); } if (status & NV_PFIFO_INTR_DMA_PUSHER) { DRM_INFO("PFIFO_DMA_PUSHER - Ch %d\n", chid); status &= ~NV_PFIFO_INTR_DMA_PUSHER; NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER); NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); if (NV_READ(NV04_PFIFO_CACHE1_DMA_PUT) != get) NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, get + 4); } if (status) { DRM_INFO("Unhandled PFIFO_INTR - 0x%08x\n", status); NV_WRITE(NV03_PFIFO_INTR_0, status); } NV_WRITE(NV03_PFIFO_CACHES, 1); } NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); } struct nouveau_bitfield_names { uint32_t mask; const char * name; }; static struct nouveau_bitfield_names nouveau_nstatus_names[] = { { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } }; static struct nouveau_bitfield_names nouveau_nstatus_names_nv10[] = { { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } }; static struct nouveau_bitfield_names nouveau_nsource_names[] = { { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, }; static void nouveau_print_bitfield_names(uint32_t value, const struct nouveau_bitfield_names *namelist, const int namelist_len) { int i; for(i=0; i<namelist_len; ++i) { uint32_t mask = namelist[i].mask; if(value & mask) { printk(" %s", namelist[i].name); value &= ~mask; } } if(value) printk(" (unknown bits 0x%08x)", value); } static int nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->Engine; int channel; if (dev_priv->card_type < NV_10) { channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf; } else if (dev_priv->card_type < NV_40) { channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; } else if (dev_priv->card_type < NV_50) { uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 4; /* 0x400704 *sometimes* contains a sensible channel ID, but * mostly not.. for now lookup which channel owns the active * PGRAPH context. Probably a better way, but this'll do * for now. */ for (channel = 0; channel < 32; channel++) { if (dev_priv->fifos[channel] == NULL) continue; if (cur_grctx == dev_priv->fifos[channel]->ramin_grctx->instance) break; } if (channel == 32) { DRM_ERROR("AIII, unable to determine active channel " "from PGRAPH context 0x%08x\n", cur_grctx); return -EINVAL; } } else { uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 12; for (channel = 0; channel < 128; channel++) { if (dev_priv->fifos[channel] == NULL) continue; if (cur_grctx == dev_priv->fifos[channel]->ramin_grctx->instance) break; } if (channel == 128) { DRM_ERROR("AIII, unable to determine active channel " "from PGRAPH context 0x%08x\n", cur_grctx); return -EINVAL; } } if (channel > engine->fifo.channels || !dev_priv->fifos[channel]) { DRM_ERROR("AIII, invalid/inactive channel id %d\n", channel); return -EINVAL; } *channel_ret = channel; return 0; } struct nouveau_pgraph_trap { int channel; int class; int subc, mthd, size; uint32_t data, data2; }; static void nouveau_graph_trap_info(struct drm_device *dev, struct nouveau_pgraph_trap *trap) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t address; if (nouveau_graph_trapped_channel(dev, &trap->channel)) trap->channel = -1; address = NV_READ(NV04_PGRAPH_TRAPPED_ADDR); trap->mthd = address & 0x1FFC; trap->data = NV_READ(NV04_PGRAPH_TRAPPED_DATA); if (dev_priv->card_type < NV_10) { trap->subc = (address >> 13) & 0x7; } else { trap->subc = (address >> 16) & 0x7; trap->data2 = NV_READ(NV10_PGRAPH_TRAPPED_DATA_HIGH); } if (dev_priv->card_type < NV_10) { trap->class = NV_READ(0x400180 + trap->subc*4) & 0xFF; } else if (dev_priv->card_type < NV_40) { trap->class = NV_READ(0x400160 + trap->subc*4) & 0xFFF; } else if (dev_priv->card_type < NV_50) { trap->class = NV_READ(0x400160 + trap->subc*4) & 0xFFFF; } else { trap->class = NV_READ(0x400814); } } static void nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, struct nouveau_pgraph_trap *trap) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t nsource, nstatus; nsource = NV_READ(NV03_PGRAPH_NSOURCE); nstatus = NV_READ(NV03_PGRAPH_NSTATUS); DRM_INFO("%s - nSource:", id); nouveau_print_bitfield_names(nsource, nouveau_nsource_names, ARRAY_SIZE(nouveau_nsource_names)); printk(", nStatus:"); if (dev_priv->card_type < NV_10) nouveau_print_bitfield_names(nstatus, nouveau_nstatus_names, ARRAY_SIZE(nouveau_nstatus_names)); else nouveau_print_bitfield_names(nstatus, nouveau_nstatus_names_nv10, ARRAY_SIZE(nouveau_nstatus_names_nv10)); printk("\n"); DRM_INFO("%s - Ch %d/%d Class 0x%04x Mthd 0x%04x Data 0x%08x:0x%08x\n", id, trap->channel, trap->subc, trap->class, trap->mthd, trap->data2, trap->data); } static inline void nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) { struct nouveau_pgraph_trap trap; int unhandled = 0; nouveau_graph_trap_info(dev, &trap); if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { /* NV4 (nvidia TNT 1) reports software methods with * PGRAPH NOTIFY ILLEGAL_MTHD */ DRM_DEBUG("Got NV04 software method method %x for class %#x\n", trap.mthd, trap.class); if (nouveau_sw_method_execute(dev, trap.class, trap.mthd)) { DRM_ERROR("Unable to execute NV04 software method %x " "for object class %x. Please report.\n", trap.mthd, trap.class); unhandled = 1; } } else { unhandled = 1; } if (unhandled) nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); } static inline void nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) { struct nouveau_pgraph_trap trap; int unhandled = 0; nouveau_graph_trap_info(dev, &trap); if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { if (trap.channel >= 0 && trap.mthd == 0x0150) { nouveau_fence_handler(dev, trap.channel); } else if (nouveau_sw_method_execute(dev, trap.class, trap.mthd)) { unhandled = 1; } } else { unhandled = 1; } if (unhandled) nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR", &trap); } static inline void nouveau_pgraph_intr_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->Engine; uint32_t chid; chid = engine->fifo.channel_id(dev); DRM_DEBUG("PGRAPH context switch interrupt channel %x\n", chid); switch(dev_priv->card_type) { case NV_04: case NV_05: nouveau_nv04_context_switch(dev); break; case NV_10: case NV_11: case NV_17: nouveau_nv10_context_switch(dev); break; default: DRM_ERROR("Context switch not implemented\n"); break; } } static void nouveau_pgraph_irq_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t status; while ((status = NV_READ(NV03_PGRAPH_INTR))) { uint32_t nsource = NV_READ(NV03_PGRAPH_NSOURCE); if (status & NV_PGRAPH_INTR_NOTIFY) { nouveau_pgraph_intr_notify(dev, nsource); status &= ~NV_PGRAPH_INTR_NOTIFY; NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY); } if (status & NV_PGRAPH_INTR_ERROR) { nouveau_pgraph_intr_error(dev, nsource); status &= ~NV_PGRAPH_INTR_ERROR; NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR); } if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { nouveau_pgraph_intr_context_switch(dev); status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); } if (status) { DRM_INFO("Unhandled PGRAPH_INTR - 0x%08x\n", status); NV_WRITE(NV03_PGRAPH_INTR, status); } if ((NV_READ(NV04_PGRAPH_FIFO) & (1 << 0)) == 0) NV_WRITE(NV04_PGRAPH_FIFO, 1); } NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); } static void nouveau_crtc_irq_handler(struct drm_device *dev, int crtc) { struct drm_nouveau_private *dev_priv = dev->dev_private; if (crtc&1) { NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); } if (crtc&2) { NV_WRITE(NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); } } irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device*)arg; struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t status; status = NV_READ(NV03_PMC_INTR_0); if (!status) return IRQ_NONE; if (status & NV_PMC_INTR_0_PFIFO_PENDING) { nouveau_fifo_irq_handler(dev); status &= ~NV_PMC_INTR_0_PFIFO_PENDING; } if (status & NV_PMC_INTR_0_PGRAPH_PENDING) { nouveau_pgraph_irq_handler(dev); status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; } if (status & NV_PMC_INTR_0_CRTCn_PENDING) { nouveau_crtc_irq_handler(dev, (status>>24)&3); status &= ~NV_PMC_INTR_0_CRTCn_PENDING; } if (status) DRM_ERROR("Unhandled PMC INTR status bits 0x%08x\n", status); return IRQ_HANDLED; }