diff options
-rw-r--r-- | bsd-core/drmP.h | 1 | ||||
l--------- | bsd-core/drm_internal.h | 1 | ||||
-rw-r--r-- | linux-core/drmP.h | 10 | ||||
l--------- | linux-core/drm_internal.h | 1 | ||||
-rw-r--r-- | linux-core/drm_sysfs.c | 2 | ||||
-rw-r--r-- | linux-core/i915_compat.c | 124 | ||||
-rw-r--r-- | linux-core/i915_drv.c | 11 | ||||
-rw-r--r-- | linux-core/nouveau_fence.c | 3 | ||||
-rw-r--r-- | shared-core/drm_internal.h | 40 | ||||
-rw-r--r-- | shared-core/nouveau_dma.c | 6 | ||||
-rw-r--r-- | shared-core/nouveau_dma.h | 3 | ||||
-rw-r--r-- | shared-core/nouveau_drv.h | 17 | ||||
-rw-r--r-- | shared-core/nouveau_fifo.c | 114 | ||||
-rw-r--r-- | shared-core/nouveau_irq.c | 11 | ||||
-rw-r--r-- | shared-core/nouveau_reg.h | 48 | ||||
-rw-r--r-- | shared-core/nouveau_state.c | 31 | ||||
-rw-r--r-- | shared-core/nv04_fifo.c | 12 | ||||
-rw-r--r-- | shared-core/nv04_graph.c | 5 | ||||
-rw-r--r-- | shared-core/nv04_instmem.c | 9 | ||||
-rw-r--r-- | shared-core/nv10_fifo.c | 12 | ||||
-rw-r--r-- | shared-core/nv10_graph.c | 11 | ||||
-rw-r--r-- | shared-core/nv20_graph.c | 15 | ||||
-rw-r--r-- | shared-core/nv40_fifo.c | 4 | ||||
-rw-r--r-- | shared-core/nv50_fifo.c | 9 | ||||
-rw-r--r-- | tests/ttmtest/src/ttmtest.c | 39 | ||||
-rw-r--r-- | tests/ttmtest/src/xf86dri.c | 1 |
26 files changed, 401 insertions, 139 deletions
diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 8a768f0c..9732d509 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -108,6 +108,7 @@ typedef struct drm_file drm_file_t; #include "drm.h" #include "drm_linux_list.h" #include "drm_atomic.h" +#include "drm_internal.h" #ifdef __FreeBSD__ #include <opt_drm.h> diff --git a/bsd-core/drm_internal.h b/bsd-core/drm_internal.h new file mode 120000 index 00000000..b30ef94a --- /dev/null +++ b/bsd-core/drm_internal.h @@ -0,0 +1 @@ +../shared-core/drm_internal.h
\ No newline at end of file diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 3d30ec7d..208b48f4 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -83,6 +83,7 @@ #include "drm_os_linux.h" #include "drm_hashtab.h" +#include "drm_internal.h" struct drm_file; @@ -590,15 +591,6 @@ struct drm_vbl_sig { struct task_struct *task; }; -/** - * Drawable information. - */ -struct drm_drawable_info { - unsigned int num_rects; - struct drm_clip_rect *rects; -}; - - /* location of GART table */ #define DRM_ATI_GART_MAIN 1 #define DRM_ATI_GART_FB 2 diff --git a/linux-core/drm_internal.h b/linux-core/drm_internal.h new file mode 120000 index 00000000..b30ef94a --- /dev/null +++ b/linux-core/drm_internal.h @@ -0,0 +1 @@ +../shared-core/drm_internal.h
\ No newline at end of file diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index 6f8623ce..caec120a 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -89,8 +89,10 @@ struct class *drm_sysfs_create(struct module *owner, char *name) goto err_out; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) class->suspend = drm_sysfs_suspend; class->resume = drm_sysfs_resume; +#endif err = class_create_file(class, &class_attr_version); if (err) diff --git a/linux-core/i915_compat.c b/linux-core/i915_compat.c index b09cc9f2..e119a992 100644 --- a/linux-core/i915_compat.c +++ b/linux-core/i915_compat.c @@ -19,10 +19,15 @@ #define I915_IFPADDR 0x60 #define I965_IFPADDR 0x70 -static struct _intel_private_compat { +static struct _i9xx_private_compat { void __iomem *flush_page; struct resource ifp_resource; -} intel_private; +} i9xx_private; + +static struct _i8xx_private_compat { + void *flush_page; + struct page *page; +} i8xx_private; static void intel_compat_align_resource(void *data, struct resource *res, @@ -35,7 +40,7 @@ intel_compat_align_resource(void *data, struct resource *res, static int intel_alloc_chipset_flush_resource(struct pci_dev *pdev) { int ret; - ret = pci_bus_alloc_resource(pdev->bus, &intel_private.ifp_resource, PAGE_SIZE, + ret = pci_bus_alloc_resource(pdev->bus, &i9xx_private.ifp_resource, PAGE_SIZE, PAGE_SIZE, PCIBIOS_MIN_MEM, 0, intel_compat_align_resource, pdev); if (ret != 0) @@ -53,15 +58,15 @@ static void intel_i915_setup_chipset_flush(struct pci_dev *pdev) if (!(temp & 0x1)) { intel_alloc_chipset_flush_resource(pdev); - pci_write_config_dword(pdev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); + pci_write_config_dword(pdev, I915_IFPADDR, (i9xx_private.ifp_resource.start & 0xffffffff) | 0x1); } else { temp &= ~1; - intel_private.ifp_resource.start = temp; - intel_private.ifp_resource.end = temp + PAGE_SIZE; - ret = request_resource(&iomem_resource, &intel_private.ifp_resource); + i9xx_private.ifp_resource.start = temp; + i9xx_private.ifp_resource.end = temp + PAGE_SIZE; + ret = request_resource(&iomem_resource, &i9xx_private.ifp_resource); if (ret) { - intel_private.ifp_resource.start = 0; + i9xx_private.ifp_resource.start = 0; printk("Failed inserting resource into tree\n"); } } @@ -79,34 +84,70 @@ static void intel_i965_g33_setup_chipset_flush(struct pci_dev *pdev) intel_alloc_chipset_flush_resource(pdev); - pci_write_config_dword(pdev, I965_IFPADDR + 4, (intel_private.ifp_resource.start >> 32)); - pci_write_config_dword(pdev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); + pci_write_config_dword(pdev, I965_IFPADDR + 4, (i9xx_private.ifp_resource.start >> 32)); + pci_write_config_dword(pdev, I965_IFPADDR, (i9xx_private.ifp_resource.start & 0xffffffff) | 0x1); } else { u64 l64; temp_lo &= ~0x1; l64 = ((u64)temp_hi << 32) | temp_lo; - intel_private.ifp_resource.start = l64; - intel_private.ifp_resource.end = l64 + PAGE_SIZE; - ret = request_resource(&iomem_resource, &intel_private.ifp_resource); + i9xx_private.ifp_resource.start = l64; + i9xx_private.ifp_resource.end = l64 + PAGE_SIZE; + ret = request_resource(&iomem_resource, &i9xx_private.ifp_resource); if (!ret) { - intel_private.ifp_resource.start = 0; + i9xx_private.ifp_resource.start = 0; printk("Failed inserting resource into tree\n"); } } } -void intel_init_chipset_flush_compat(struct drm_device *dev) +static void intel_i8xx_fini_flush(struct drm_device *dev) { - struct pci_dev *agp_dev = dev->agp->agp_info.device; + kunmap(i8xx_private.page); + i8xx_private.flush_page = NULL; + unmap_page_from_agp(i8xx_private.page); + flush_agp_mappings(); - /* not flush on i8xx */ - if (!IS_I9XX(dev)) + __free_page(i8xx_private.page); +} + +static void intel_i8xx_setup_flush(struct drm_device *dev) +{ + + i8xx_private.page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32); + if (!i8xx_private.page) { return; + } + + /* make page uncached */ + map_page_into_agp(i8xx_private.page); + flush_agp_mappings(); + + i8xx_private.flush_page = kmap(i8xx_private.page); + if (!i8xx_private.flush_page) + intel_i8xx_fini_flush(dev); +} + + +static void intel_i8xx_flush_page(struct drm_device *dev) +{ + unsigned int *pg = i8xx_private.flush_page; + int i; + + /* HAI NUT CAN I HAZ HAMMER?? */ + for (i = 0; i < 256; i++) + *(pg + i) = i; + + DRM_MEMORYBARRIER(); +} - intel_private.ifp_resource.name = "GMCH IFPBAR"; - intel_private.ifp_resource.flags = IORESOURCE_MEM; +static void intel_i9xx_setup_flush(struct drm_device *dev) +{ + struct pci_dev *agp_dev = dev->agp->agp_info.device; + + i9xx_private.ifp_resource.name = "GMCH IFPBAR"; + i9xx_private.ifp_resource.flags = IORESOURCE_MEM; /* Setup chipset flush for 915 */ if (IS_I965G(dev) || IS_G33(dev)) { @@ -115,26 +156,49 @@ void intel_init_chipset_flush_compat(struct drm_device *dev) intel_i915_setup_chipset_flush(agp_dev); } - if (intel_private.ifp_resource.start) { - intel_private.flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); - if (!intel_private.flush_page) + if (i9xx_private.ifp_resource.start) { + i9xx_private.flush_page = ioremap_nocache(i9xx_private.ifp_resource.start, PAGE_SIZE); + if (!i9xx_private.flush_page) printk("unable to ioremap flush page - no chipset flushing"); } } -void intel_fini_chipset_flush_compat(struct drm_device *dev) +static void intel_i9xx_fini_flush(struct drm_device *dev) +{ + iounmap(i9xx_private.flush_page); + release_resource(&i9xx_private.ifp_resource); +} + +static void intel_i9xx_flush_page(struct drm_device *dev) +{ + if (i9xx_private.flush_page) + writel(1, i9xx_private.flush_page); +} + +void intel_init_chipset_flush_compat(struct drm_device *dev) { /* not flush on i8xx */ - if (!IS_I9XX(dev)) - return; + if (IS_I9XX(dev)) + intel_i9xx_setup_flush(dev); + else + intel_i8xx_setup_flush(dev); + +} - iounmap(intel_private.flush_page); - release_resource(&intel_private.ifp_resource); +void intel_fini_chipset_flush_compat(struct drm_device *dev) +{ + /* not flush on i8xx */ + if (IS_I9XX(dev)) + intel_i9xx_fini_flush(dev); + else + intel_i8xx_fini_flush(dev); } void drm_agp_chipset_flush(struct drm_device *dev) { - if (intel_private.flush_page) - writel(1, intel_private.flush_page); + if (IS_I9XX(dev)) + intel_i9xx_flush_page(dev); + else + intel_i8xx_flush_page(dev); } #endif diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 74b4c32e..fb4149c4 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -432,7 +432,11 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); } - I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); + + if ((dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) && + (dev_priv->saveDPLL_A & DPLL_VGA_MODE_DIS)) + I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); + i915_restore_palette(dev, PIPE_A); /* Enable the plane */ I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); @@ -472,7 +476,10 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); } - I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); + + if ((dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) && + (dev_priv->saveDPLL_B & DPLL_VGA_MODE_DIS)) + I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); i915_restore_palette(dev, PIPE_A); /* Enable the plane */ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); diff --git a/linux-core/nouveau_fence.c b/linux-core/nouveau_fence.c index b3e81a89..4e624a7a 100644 --- a/linux-core/nouveau_fence.c +++ b/linux-core/nouveau_fence.c @@ -79,6 +79,7 @@ nouveau_fence_perform_flush(struct drm_device *dev, uint32_t class) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_fence_class_manager *fc = &dev->fm.fence_class[class]; + struct nouveau_channel *chan = dev_priv->fifos[class]; uint32_t pending_types = 0; DRM_DEBUG("class=%d\n", class); @@ -89,7 +90,7 @@ nouveau_fence_perform_flush(struct drm_device *dev, uint32_t class) fc->pending_flush); if (pending_types) { - uint32_t sequence = NV_READ(NV03_FIFO_REGS(class) + 0x48); + uint32_t sequence = NV_READ(chan->ref_cnt); DRM_DEBUG("got 0x%08x\n", sequence); drm_fence_handler(dev, class, sequence, pending_types, 0); diff --git a/shared-core/drm_internal.h b/shared-core/drm_internal.h new file mode 100644 index 00000000..b82a189d --- /dev/null +++ b/shared-core/drm_internal.h @@ -0,0 +1,40 @@ +/* + * Copyright 2007 Red Hat, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* This header file holds function prototypes and data types that are + * internal to the drm (not exported to user space) but shared across + * drivers and platforms */ + +#ifndef __DRM_INTERNAL_H__ +#define __DRM_INTERNAL_H__ + +/** + * Drawable information. + */ +struct drm_drawable_info { + unsigned int num_rects; + struct drm_clip_rect *rects; +}; + +#endif diff --git a/shared-core/nouveau_dma.c b/shared-core/nouveau_dma.c index b406c22d..dff786d4 100644 --- a/shared-core/nouveau_dma.c +++ b/shared-core/nouveau_dma.c @@ -133,10 +133,10 @@ nouveau_dma_channel_takedown(struct drm_device *dev) #define RING_SKIPS 8 -#define READ_GET() ((NV_READ(NV03_FIFO_REGS_DMAGET(dchan->chan->id)) - \ - dchan->chan->pushbuf_base) >> 2) +#define READ_GET() ((NV_READ(dchan->chan->get) - \ + dchan->chan->pushbuf_base) >> 2) #define WRITE_PUT(val) do { \ - NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \ + NV_WRITE(dchan->chan->put, \ ((val) << 2) + dchan->chan->pushbuf_base); \ } while(0) diff --git a/shared-core/nouveau_dma.h b/shared-core/nouveau_dma.h index f8df54eb..ce3c58cb 100644 --- a/shared-core/nouveau_dma.h +++ b/shared-core/nouveau_dma.h @@ -89,8 +89,7 @@ typedef enum { if (dchan->cur != dchan->put) { \ DRM_MEMORYBARRIER(); \ dchan->put = dchan->cur; \ - NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \ - (dchan->put<<2)); \ + NV_WRITE(dchan->chan->put, dchan->put << 2); \ } \ } while(0) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 8b00726b..85a0d0b5 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -114,6 +114,12 @@ struct nouveau_channel struct mem_block *pushbuf_mem; uint32_t pushbuf_base; + /* FIFO user control regs */ + uint32_t user, user_size; + uint32_t put; + uint32_t get; + uint32_t ref_cnt; + /* Notifier memory */ struct mem_block *notifier_block; struct mem_block *notifier_heap; @@ -193,9 +199,13 @@ struct nouveau_fb_engine { struct nouveau_fifo_engine { void *priv; + int channels; + int (*init)(struct drm_device *); void (*takedown)(struct drm_device *); + int (*channel_id)(struct drm_device *); + int (*create_context)(struct nouveau_channel *); void (*destroy_context)(struct nouveau_channel *); int (*load_context)(struct nouveau_channel *); @@ -221,6 +231,7 @@ struct nouveau_engine { struct nouveau_fifo_engine fifo; }; +#define NOUVEAU_MAX_CHANNEL_NR 128 struct drm_nouveau_private { enum { NOUVEAU_CARD_INIT_DOWN, @@ -241,7 +252,7 @@ struct drm_nouveau_private { drm_local_map_t *ramin; /* NV40 onwards */ int fifo_alloc_count; - struct nouveau_channel *fifos[NV_MAX_FIFO_NUMBER]; + struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; struct nouveau_engine Engine; struct nouveau_drm_channel channel; @@ -364,7 +375,6 @@ extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, /* nouveau_fifo.c */ extern int nouveau_fifo_init(struct drm_device *); -extern int nouveau_fifo_number(struct drm_device *); extern int nouveau_fifo_ctx_size(struct drm_device *); extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *); extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *, @@ -452,12 +462,14 @@ extern int nv40_fb_init(struct drm_device *); extern void nv40_fb_takedown(struct drm_device *); /* nv04_fifo.c */ +extern int nv04_fifo_channel_id(struct drm_device *); extern int nv04_fifo_create_context(struct nouveau_channel *); extern void nv04_fifo_destroy_context(struct nouveau_channel *); extern int nv04_fifo_load_context(struct nouveau_channel *); extern int nv04_fifo_save_context(struct nouveau_channel *); /* nv10_fifo.c */ +extern int nv10_fifo_channel_id(struct drm_device *); extern int nv10_fifo_create_context(struct nouveau_channel *); extern void nv10_fifo_destroy_context(struct nouveau_channel *); extern int nv10_fifo_load_context(struct nouveau_channel *); @@ -473,6 +485,7 @@ extern int nv40_fifo_save_context(struct nouveau_channel *); /* nv50_fifo.c */ extern int nv50_fifo_init(struct drm_device *); extern void nv50_fifo_takedown(struct drm_device *); +extern int nv50_fifo_channel_id(struct drm_device *); extern int nv50_fifo_create_context(struct nouveau_channel *); extern void nv50_fifo_destroy_context(struct nouveau_channel *); extern int nv50_fifo_load_context(struct nouveau_channel *); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index e2cb209c..d00f1938 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -28,22 +28,6 @@ #include "nouveau_drm.h" -/* returns the number of hw fifos */ -int nouveau_fifo_number(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv=dev->dev_private; - switch(dev_priv->card_type) - { - case NV_04: - case NV_05: - return 16; - case NV_50: - return 128; - default: - return 32; - } -} - /* returns the size of fifo context */ int nouveau_fifo_ctx_size(struct drm_device *dev) { @@ -288,12 +272,13 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, * (woo, full userspace command submission !) * When there are no more contexts, you lost */ - for(channel=0; channel<nouveau_fifo_number(dev); channel++) { + for (channel = 0; channel < engine->fifo.channels; channel++) { if (dev_priv->fifos[channel] == NULL) break; } + /* no more fifos. you lost. */ - if (channel==nouveau_fifo_number(dev)) + if (channel == engine->fifo.channels) return -EINVAL; dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel), @@ -309,6 +294,28 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, DRM_INFO("Allocating FIFO number %d\n", channel); + /* Locate channel's user control regs */ + if (dev_priv->card_type < NV_40) { + chan->user = NV03_USER(channel); + chan->user_size = NV03_USER_SIZE; + chan->put = NV03_USER_DMA_PUT(channel); + chan->get = NV03_USER_DMA_GET(channel); + chan->ref_cnt = NV03_USER_REF_CNT(channel); + } else + if (dev_priv->card_type < NV_50) { + chan->user = NV40_USER(channel); + chan->user_size = NV40_USER_SIZE; + chan->put = NV40_USER_DMA_PUT(channel); + chan->get = NV40_USER_DMA_GET(channel); + chan->ref_cnt = NV40_USER_REF_CNT(channel); + } else { + chan->user = NV50_USER(channel); + chan->user_size = NV50_USER_SIZE; + chan->put = NV50_USER_DMA_PUT(channel); + chan->get = NV50_USER_DMA_GET(channel); + chan->ref_cnt = NV50_USER_REF_CNT(channel); + } + /* Allocate space for per-channel fixed notifier memory */ ret = nouveau_notifier_init_channel(chan); if (ret) { @@ -352,14 +359,11 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return ret; } - /* setup channel's default get/put values */ - if (dev_priv->card_type < NV_50) { - NV_WRITE(NV03_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base); - NV_WRITE(NV03_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); - } else { - NV_WRITE(NV50_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base); - NV_WRITE(NV50_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); - } + /* setup channel's default get/put values + * XXX: quite possibly extremely pointless.. + */ + NV_WRITE(chan->get, chan->pushbuf_base); + NV_WRITE(chan->put, chan->pushbuf_base); /* If this is the first channel, setup PFIFO ourselves. For any * other case, the GPU will handle this when it switches contexts. @@ -398,9 +402,37 @@ void nouveau_fifo_free(struct nouveau_channel *chan) struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->Engine; + uint64_t t_start; DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id); + /* Disable channel switching, if this channel isn't currenly + * active re-enable it if there's still pending commands. + * We really should do a manual context switch here, but I'm + * not sure I trust our ability to do this reliably yet.. + */ + NV_WRITE(NV03_PFIFO_CACHES, 0); + if (engine->fifo.channel_id(dev) != chan->id && + NV_READ(chan->get) != NV_READ(chan->put)) { + NV_WRITE(NV03_PFIFO_CACHES, 1); + } + + /* Give the channel a chance to idle, wait 2s (hopefully) */ + t_start = engine->timer.read(dev); + while (NV_READ(chan->get) != NV_READ(chan->put) || + NV_READ(NV03_PFIFO_CACHE1_GET) != + NV_READ(NV03_PFIFO_CACHE1_PUT)) { + if (engine->timer.read(dev) - t_start > 2000000000ULL) { + DRM_ERROR("Failed to idle channel %d before destroy." + "Prepare for strangeness..\n", chan->id); + break; + } + } + + /*XXX: Maybe should wait for PGRAPH to finish with the stuff it fetched + * from CACHE1 too? + */ + /* disable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1)); @@ -408,14 +440,12 @@ void nouveau_fifo_free(struct nouveau_channel *chan) NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); /* stop the fifo, otherwise it could be running and - * it will crash when removing gpu objects */ - if (dev_priv->card_type < NV_50) { - NV_WRITE(NV03_FIFO_REGS_DMAPUT(chan->id), chan->pushbuf_base); - NV_WRITE(NV03_FIFO_REGS_DMAGET(chan->id), chan->pushbuf_base); - } else { - NV_WRITE(NV50_FIFO_REGS_DMAPUT(chan->id), chan->pushbuf_base); - NV_WRITE(NV50_FIFO_REGS_DMAGET(chan->id), chan->pushbuf_base); - } + * it will crash when removing gpu objects + *XXX: from real-world evidence, absolutely useless.. + */ + NV_WRITE(chan->get, chan->pushbuf_base); + NV_WRITE(chan->put, chan->pushbuf_base); + // FIXME XXX needs more code engine->fifo.destroy_context(chan); @@ -451,10 +481,11 @@ void nouveau_fifo_free(struct nouveau_channel *chan) void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; int i; DRM_DEBUG("clearing FIFO enables from file_priv\n"); - for(i = 0; i < nouveau_fifo_number(dev); i++) { + for(i = 0; i < engine->fifo.channels; i++) { struct nouveau_channel *chan = dev_priv->fifos[i]; if (chan && chan->file_priv == file_priv) @@ -467,8 +498,9 @@ nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv, int channel) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; - if (channel >= nouveau_fifo_number(dev)) + if (channel >= engine->fifo.channels) return 0; if (dev_priv->fifos[channel] == NULL) return 0; @@ -508,14 +540,8 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, /* make the fifo available to user space */ /* first, the fifo control regs */ - init->ctrl = dev_priv->mmio->offset; - if (dev_priv->card_type < NV_50) { - init->ctrl += NV03_FIFO_REGS(init->channel); - init->ctrl_size = NV03_FIFO_REGS_SIZE; - } else { - init->ctrl += NV50_FIFO_REGS(init->channel); - init->ctrl_size = NV50_FIFO_REGS_SIZE; - } + init->ctrl = dev_priv->mmio->offset + chan->user; + init->ctrl_size = chan->user_size; res = drm_addmap(dev, init->ctrl, init->ctrl_size, _DRM_REGISTERS, 0, &chan->regs); if (res != 0) diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 43f37ca0..500fda2f 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -68,6 +68,7 @@ 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))) { @@ -75,8 +76,7 @@ nouveau_fifo_irq_handler(struct drm_device *dev) NV_WRITE(NV03_PFIFO_CACHES, 0); - chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & - (nouveau_fifo_number(dev) - 1); + chid = engine->fifo.channel_id(dev); get = NV_READ(NV03_PFIFO_CACHE1_GET); if (status & NV_PFIFO_INTR_CACHE_ERROR) { @@ -190,6 +190,7 @@ 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) { @@ -234,8 +235,7 @@ nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) } } - if (channel > nouveau_fifo_number(dev) || - dev_priv->fifos[channel] == NULL) { + if (channel > engine->fifo.channels || !dev_priv->fifos[channel]) { DRM_ERROR("AIII, invalid/inactive channel id %d\n", channel); return -EINVAL; } @@ -365,9 +365,10 @@ 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 = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); + chid = engine->fifo.channel_id(dev); DRM_DEBUG("PGRAPH context switch interrupt channel %x\n", chid); switch(dev_priv->card_type) { diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 43573f2c..7ac02f4a 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -45,16 +45,40 @@ #define NV_CLASS_NULL 0x00000030 #define NV_CLASS_DMA_IN_MEMORY 0x0000003D +#define NV03_USER(i) (0x00800000+(i*NV03_USER_SIZE)) +#define NV03_USER__SIZE 16 +#define NV10_USER__SIZE 32 +#define NV03_USER_SIZE 0x00010000 +#define NV03_USER_DMA_PUT(i) (0x00800040+(i*NV03_USER_SIZE)) +#define NV03_USER_DMA_PUT__SIZE 16 +#define NV10_USER_DMA_PUT__SIZE 32 +#define NV03_USER_DMA_GET(i) (0x00800044+(i*NV03_USER_SIZE)) +#define NV03_USER_DMA_GET__SIZE 16 +#define NV10_USER_DMA_GET__SIZE 32 +#define NV03_USER_REF_CNT(i) (0x00800048+(i*NV03_USER_SIZE)) +#define NV03_USER_REF_CNT__SIZE 16 +#define NV10_USER_REF_CNT__SIZE 32 + +#define NV40_USER(i) (0x00c00000+(i*NV40_USER_SIZE)) +#define NV40_USER_SIZE 0x00001000 +#define NV40_USER_DMA_PUT(i) (0x00c00040+(i*NV40_USER_SIZE)) +#define NV40_USER_DMA_PUT__SIZE 32 +#define NV40_USER_DMA_GET(i) (0x00c00044+(i*NV40_USER_SIZE)) +#define NV40_USER_DMA_GET__SIZE 32 +#define NV40_USER_REF_CNT(i) (0x00c00048+(i*NV40_USER_SIZE)) +#define NV40_USER_REF_CNT__SIZE 32 + +#define NV50_USER(i) (0x00c00000+(i*NV50_USER_SIZE)) +#define NV50_USER_SIZE 0x00002000 +#define NV50_USER_DMA_PUT(i) (0x00c00040+(i*NV50_USER_SIZE)) +#define NV50_USER_DMA_PUT__SIZE 128 +#define NV50_USER_DMA_GET(i) (0x00c00044+(i*NV50_USER_SIZE)) +#define NV50_USER_DMA_GET__SIZE 128 +/*XXX: I don't think this actually exists.. */ +#define NV50_USER_REF_CNT(i) (0x00c00048+(i*NV50_USER_SIZE)) +#define NV50_USER_REF_CNT__SIZE 128 + #define NV03_FIFO_SIZE 0x8000UL -#define NV_MAX_FIFO_NUMBER 128 -#define NV03_FIFO_REGS_SIZE 0x10000 -#define NV03_FIFO_REGS(i) (0x00800000+i*NV03_FIFO_REGS_SIZE) -# define NV03_FIFO_REGS_DMAPUT(i) (NV03_FIFO_REGS(i)+0x40) -# define NV03_FIFO_REGS_DMAGET(i) (NV03_FIFO_REGS(i)+0x44) -#define NV50_FIFO_REGS_SIZE 0x2000 -#define NV50_FIFO_REGS(i) (0x00c00000+i*NV50_FIFO_REGS_SIZE) -# define NV50_FIFO_REGS_DMAPUT(i) (NV50_FIFO_REGS(i)+0x40) -# define NV50_FIFO_REGS_DMAGET(i) (NV50_FIFO_REGS(i)+0x44) #define NV03_PMC_BOOT_0 0x00000000 #define NV03_PMC_BOOT_1 0x00000004 @@ -406,6 +430,12 @@ #define NV04_PFIFO_CACHE0_PULL1 0x00003054 #define NV03_PFIFO_CACHE1_PUSH0 0x00003200 #define NV03_PFIFO_CACHE1_PUSH1 0x00003204 +#define NV03_PFIFO_CACHE1_PUSH1_DMA (1<<8) +#define NV40_PFIFO_CACHE1_PUSH1_DMA (1<<16) +#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000000f +#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000001f +#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000007f +#define NV03_PFIFO_CACHE1_PUT 0x00003210 #define NV04_PFIFO_CACHE1_DMA_PUSH 0x00003220 #define NV04_PFIFO_CACHE1_DMA_FETCH 0x00003224 # define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 610d24e2..57ae9243 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -116,8 +116,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv04_graph_destroy_context; engine->graph.load_context = nv04_graph_load_context; engine->graph.save_context = nv04_graph_save_context; + engine->fifo.channels = 16; engine->fifo.init = nouveau_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.channel_id = nv04_fifo_channel_id; engine->fifo.create_context = nv04_fifo_create_context; engine->fifo.destroy_context = nv04_fifo_destroy_context; engine->fifo.load_context = nv04_fifo_load_context; @@ -143,8 +145,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv10_graph_destroy_context; engine->graph.load_context = nv10_graph_load_context; engine->graph.save_context = nv10_graph_save_context; + engine->fifo.channels = 32; engine->fifo.init = nouveau_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; @@ -170,8 +174,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv20_graph_destroy_context; engine->graph.load_context = nv20_graph_load_context; engine->graph.save_context = nv20_graph_save_context; + engine->fifo.channels = 32; engine->fifo.init = nouveau_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; @@ -197,8 +203,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv20_graph_destroy_context; engine->graph.load_context = nv20_graph_load_context; engine->graph.save_context = nv20_graph_save_context; + engine->fifo.channels = 32; engine->fifo.init = nouveau_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; @@ -224,8 +232,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv40_graph_destroy_context; engine->graph.load_context = nv40_graph_load_context; engine->graph.save_context = nv40_graph_save_context; + engine->fifo.channels = 32; engine->fifo.init = nv40_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv40_fifo_create_context; engine->fifo.destroy_context = nv40_fifo_destroy_context; engine->fifo.load_context = nv40_fifo_load_context; @@ -252,8 +262,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv50_graph_destroy_context; engine->graph.load_context = nv50_graph_load_context; engine->graph.save_context = nv50_graph_save_context; + engine->fifo.channels = 128; engine->fifo.init = nv50_fifo_init; engine->fifo.takedown = nv50_fifo_takedown; + engine->fifo.channel_id = nv50_fifo_channel_id; engine->fifo.create_context = nv50_fifo_create_context; engine->fifo.destroy_context = nv50_fifo_destroy_context; engine->fifo.load_context = nv50_fifo_load_context; @@ -273,6 +285,9 @@ nouveau_card_init(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; int ret; +#if defined(__powerpc__) + struct device_node *dn; +#endif DRM_DEBUG("prev state = %d\n", dev_priv->init_state); @@ -292,6 +307,22 @@ nouveau_card_init(struct drm_device *dev) DRM_MEMORYBARRIER(); #endif +#if defined(__powerpc__) + /* if we have an OF card, copy vbios to RAMIN */ + dn = pci_device_to_OF_node(dev->pdev); + if (dn) + { + int size; + const uint32_t *bios = of_get_property(dn, "NVDA,BMP", &size); + if (bios) + { + int i; + for(i=0;i<size;i+=4) + NV_WI32(i, bios[i/4]); + } + } +#endif + /* Determine exact chipset we're running on */ if (dev_priv->card_type < NV_10) dev_priv->chipset = dev_priv->card_type; diff --git a/shared-core/nv04_fifo.c b/shared-core/nv04_fifo.c index d172302c..230c8e72 100644 --- a/shared-core/nv04_fifo.c +++ b/shared-core/nv04_fifo.c @@ -36,6 +36,15 @@ #define NV04_RAMFC__SIZE 32 int +nv04_fifo_channel_id(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + return (NV_READ(NV03_PFIFO_CACHE1_PUSH1) & + NV03_PFIFO_CACHE1_PUSH1_CHID_MASK); +} + +int nv04_fifo_create_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; @@ -84,7 +93,8 @@ nv04_fifo_load_context(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t tmp; - NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, (1<<8) | chan->id); + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, + NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, RAMFC_RD(DMA_GET)); NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT, RAMFC_RD(DMA_PUT)); diff --git a/shared-core/nv04_graph.c b/shared-core/nv04_graph.c index 04dbf0ed..81a6d5c8 100644 --- a/shared-core/nv04_graph.c +++ b/shared-core/nv04_graph.c @@ -353,6 +353,7 @@ struct graph_state { void nouveau_nv04_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; struct nouveau_channel *next, *last; int chid; @@ -370,7 +371,7 @@ void nouveau_nv04_context_switch(struct drm_device *dev) return; } - chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); + chid = engine->fifo.channel_id(dev); next = dev_priv->fifos[chid]; if (!next) { @@ -378,7 +379,7 @@ void nouveau_nv04_context_switch(struct drm_device *dev) return; } - chid = (NV_READ(NV04_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + chid = (NV_READ(NV04_PGRAPH_CTX_USER) >> 24) & (engine->fifo.channels - 1); last = dev_priv->fifos[chid]; if (!last) { diff --git a/shared-core/nv04_instmem.c b/shared-core/nv04_instmem.c index 56968181..804f9a75 100644 --- a/shared-core/nv04_instmem.c +++ b/shared-core/nv04_instmem.c @@ -33,6 +33,7 @@ static void nv04_instmem_configure_fixed_tables(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; /* FIFO hash table (RAMHT) * use 4k hash table at RAMIN+0x10000 @@ -61,8 +62,8 @@ nv04_instmem_configure_fixed_tables(struct drm_device *dev) case NV_40: case NV_44: dev_priv->ramfc_offset = 0x20000; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * - nouveau_fifo_ctx_size(dev); + dev_priv->ramfc_size = engine->fifo.channels * + nouveau_fifo_ctx_size(dev); break; case NV_30: case NV_20: @@ -72,8 +73,8 @@ nv04_instmem_configure_fixed_tables(struct drm_device *dev) case NV_04: default: dev_priv->ramfc_offset = 0x11400; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * - nouveau_fifo_ctx_size(dev); + dev_priv->ramfc_size = engine->fifo.channels * + nouveau_fifo_ctx_size(dev); break; } DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, diff --git a/shared-core/nv10_fifo.c b/shared-core/nv10_fifo.c index 45d2603a..6d50b6ca 100644 --- a/shared-core/nv10_fifo.c +++ b/shared-core/nv10_fifo.c @@ -37,6 +37,15 @@ #define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32) int +nv10_fifo_channel_id(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + return (NV_READ(NV03_PFIFO_CACHE1_PUSH1) & + NV10_PFIFO_CACHE1_PUSH1_CHID_MASK); +} + +int nv10_fifo_create_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; @@ -87,7 +96,8 @@ nv10_fifo_load_context(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t tmp; - NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00000100 | chan->id); + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, + NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET)); NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT)); diff --git a/shared-core/nv10_graph.c b/shared-core/nv10_graph.c index 606fb43f..d0c2285f 100644 --- a/shared-core/nv10_graph.c +++ b/shared-core/nv10_graph.c @@ -692,6 +692,7 @@ int nv10_graph_save_context(struct nouveau_channel *chan) void nouveau_nv10_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv; + struct nouveau_engine *engine; struct nouveau_channel *next, *last; int chid; @@ -708,8 +709,10 @@ void nouveau_nv10_context_switch(struct drm_device *dev) DRM_DEBUG("Invalid drm_nouveau_private->fifos\n"); return; } + engine = &dev_priv->Engine; - chid = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20)&(nouveau_fifo_number(dev)-1); + chid = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & + (engine->fifo.channels - 1); next = dev_priv->fifos[chid]; if (!next) { @@ -717,7 +720,8 @@ void nouveau_nv10_context_switch(struct drm_device *dev) return; } - chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & + (engine->fifo.channels - 1); last = dev_priv->fifos[chid]; if (!last) { @@ -827,13 +831,14 @@ void nv10_graph_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; struct graph_state* pgraph_ctx = chan->pgraph_ctx; int chid; drm_free(pgraph_ctx, sizeof(*pgraph_ctx), DRM_MEM_DRIVER); chan->pgraph_ctx = NULL; - chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (engine->fifo.channels - 1); /* This code seems to corrupt the 3D pipe, but blob seems to do similar things ???? */ diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c index a21fde71..dace7edb 100644 --- a/shared-core/nv20_graph.c +++ b/shared-core/nv20_graph.c @@ -29,7 +29,7 @@ #define NV2A_GRCTX_SIZE (3500*4) #define NV30_31_GRCTX_SIZE (24392) -#define NV34_GRCTX_SIZE (18140) +#define NV34_GRCTX_SIZE (22000) #define NV35_36_GRCTX_SIZE (22396) static void nv20_graph_context_init(struct drm_device *dev, @@ -432,6 +432,19 @@ static void nv30_31_graph_context_init(struct drm_device *dev, INSTANCE_WR(ctx, 0x385c/4, 0x3f800000); INSTANCE_WR(ctx, 0x3864/4, 0xbf800000); INSTANCE_WR(ctx, 0x386c/4, 0xbf800000); + + /* nv30gl stuff */ + for (i=0; i<8; i++) { + INSTANCE_WR(ctx, (0x4dfc/4)+i, 0x001c527d); + } + INSTANCE_WR(ctx, 0x4e3c/4, 0x001c527c); +/* these ones make dma fifo hang + INSTANCE_WR(ctx, 0x567c/4, 0x000a0000); + INSTANCE_WR(ctx, 0x0878/4, 0x01000000); + INSTANCE_WR(ctx, 0x02f4/4, 0x0001ffff); + + INSTANCE_WR(ctx, 0x0028/4, INSTANCE_RD(ctx, 0x0028/4) | 1); +*/ } static void nv34_graph_context_init(struct drm_device *dev, diff --git a/shared-core/nv40_fifo.c b/shared-core/nv40_fifo.c index 5b3eda09..7f9d5e31 100644 --- a/shared-core/nv40_fifo.c +++ b/shared-core/nv40_fifo.c @@ -135,7 +135,9 @@ nv40_fifo_load_context(struct nouveau_channel *chan) NV_WRITE(NV04_PFIFO_DMA_TIMESLICE, tmp); /* Set channel active, and in DMA mode */ - NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00010000 | chan->id); + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, + NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); + /* Reset DMA_CTL_AT_INFO to INVALID */ tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31); NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, tmp); diff --git a/shared-core/nv50_fifo.c b/shared-core/nv50_fifo.c index f77de6e7..c5cde913 100644 --- a/shared-core/nv50_fifo.c +++ b/shared-core/nv50_fifo.c @@ -213,6 +213,15 @@ nv50_fifo_takedown(struct drm_device *dev) } int +nv50_fifo_channel_id(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + return (NV_READ(NV03_PFIFO_CACHE1_PUSH1) & + NV50_PFIFO_CACHE1_PUSH1_CHID_MASK); +} + +int nv50_fifo_create_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; diff --git a/tests/ttmtest/src/ttmtest.c b/tests/ttmtest/src/ttmtest.c index 052947b1..36df2428 100644 --- a/tests/ttmtest/src/ttmtest.c +++ b/tests/ttmtest/src/ttmtest.c @@ -35,6 +35,7 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> +#include <stdint.h> #include <drm/drm.h> #include "xf86dri.h" #include "xf86drm.h" @@ -176,13 +177,11 @@ benchmarkBuffer(TinyDRIContext * ctx, unsigned long size, /* * Test system memory objects. */ - BM_CKFATAL(drmGetLock(ctx->drmFD, ctx->hwContext, 0)); oldTime = fastrdtsc(); - BM_CKFATAL(drmBOCreate(ctx->drmFD, 0, size, 0, NULL, - drm_bo_type_dc, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_LOCAL /*| DRM_BO_FLAG_NO_MOVE*/, 0, &buf)); + BM_CKFATAL(drmBOCreate(ctx->drmFD, size, 0, NULL, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_LOCAL, 0, &buf)); curTime = fastrdtsc(); *ticks++ = time_diff(oldTime, curTime); @@ -216,12 +215,12 @@ benchmarkBuffer(TinyDRIContext * ctx, unsigned long size, * Test TT bound buffer objects. */ - // BM_CKFATAL(drmGetLock(ctx->drmFD, ctx->hwContext, 0)); oldTime = fastrdtsc(); - BM_CKFATAL(drmBOValidate(ctx->drmFD, &buf, - DRM_BO_FLAG_MEM_TT, DRM_BO_MASK_MEM, DRM_BO_HINT_DONT_FENCE)); + BM_CKFATAL(drmBOSetStatus(ctx->drmFD, &buf, + DRM_BO_FLAG_MEM_TT, + DRM_BO_MASK_MEM, + 0,0,0)); curTime = fastrdtsc(); - BM_CKFATAL(drmUnlock(ctx->drmFD, ctx->hwContext)); *ticks++ = time_diff(oldTime, curTime); oldTime = fastrdtsc(); @@ -247,10 +246,9 @@ benchmarkBuffer(TinyDRIContext * ctx, unsigned long size, BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf)); - BM_CKFATAL(drmGetLock(ctx->drmFD, ctx->hwContext, 0)); oldTime = fastrdtsc(); - BM_CKFATAL(drmBOValidate(ctx->drmFD, &buf, - DRM_BO_FLAG_MEM_LOCAL, DRM_BO_MASK_MEM, DRM_BO_HINT_DONT_FENCE)); + BM_CKFATAL(drmBOSetStatus(ctx->drmFD, &buf, + DRM_BO_FLAG_MEM_LOCAL, DRM_BO_MASK_MEM, 0, 0,0)); curTime = fastrdtsc(); *ticks++ = time_diff(oldTime, curTime); @@ -259,15 +257,18 @@ benchmarkBuffer(TinyDRIContext * ctx, unsigned long size, */ oldTime = fastrdtsc(); - ret = drmBOValidate(ctx->drmFD, &buf, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING, - DRM_BO_MASK_MEMTYPE | DRM_BO_FLAG_FORCE_CACHING, DRM_BO_HINT_DONT_FENCE); + ret = drmBOSetStatus(ctx->drmFD, &buf, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_CACHED | + DRM_BO_FLAG_FORCE_CACHING, + DRM_BO_MASK_MEMTYPE | + DRM_BO_FLAG_FORCE_CACHING, + 0, 0, 0); curTime = fastrdtsc(); - drmUnlock(ctx->drmFD, ctx->hwContext); if (ret) { printf("Couldn't bind cached. Probably no support\n"); - BM_CKFATAL(drmBODestroy(ctx->drmFD, &buf)); + BM_CKFATAL(drmBOUnreference(ctx->drmFD, &buf)); return 1; } *ticks++ = time_diff(oldTime, curTime); @@ -295,7 +296,7 @@ benchmarkBuffer(TinyDRIContext * ctx, unsigned long size, *ticks++ = time_diff(oldTime, curTime); BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf)); - BM_CKFATAL(drmBODestroy(ctx->drmFD, &buf)); + BM_CKFATAL(drmBOUnreference(ctx->drmFD, &buf)); return 0; } diff --git a/tests/ttmtest/src/xf86dri.c b/tests/ttmtest/src/xf86dri.c index ad92504e..5491473c 100644 --- a/tests/ttmtest/src/xf86dri.c +++ b/tests/ttmtest/src/xf86dri.c @@ -45,6 +45,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <X11/Xlibint.h> #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> +#include <stdint.h> #include "xf86dristr.h" static XExtensionInfo _xf86dri_info_data; |