summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-11-15 15:04:19 +1100
committerDave Airlie <airlied@linux.ie>2007-11-15 15:04:19 +1100
commitf0fe478c1587780690edc465d957a762e02acc8a (patch)
treede129251264e7c4fa5c8c7119583dc18af9a3fab
parente1bc147ac9aa8ac2ac271b0a21f4138b17875ce5 (diff)
parent62cdc6dbb3545d21bc3a68987d0781f277ae6ee4 (diff)
Merge branch 'master' into modesetting-101
Conflicts: shared-core/i915_dma.c tests/ttmtest/src/ttmtest.c
-rw-r--r--bsd-core/drmP.h1
l---------bsd-core/drm_internal.h1
-rw-r--r--linux-core/drmP.h10
l---------linux-core/drm_internal.h1
-rw-r--r--linux-core/drm_sysfs.c2
-rw-r--r--linux-core/i915_compat.c124
-rw-r--r--linux-core/i915_drv.c11
-rw-r--r--linux-core/nouveau_fence.c3
-rw-r--r--shared-core/drm_internal.h40
-rw-r--r--shared-core/nouveau_dma.c6
-rw-r--r--shared-core/nouveau_dma.h3
-rw-r--r--shared-core/nouveau_drv.h17
-rw-r--r--shared-core/nouveau_fifo.c114
-rw-r--r--shared-core/nouveau_irq.c11
-rw-r--r--shared-core/nouveau_reg.h48
-rw-r--r--shared-core/nouveau_state.c31
-rw-r--r--shared-core/nv04_fifo.c12
-rw-r--r--shared-core/nv04_graph.c5
-rw-r--r--shared-core/nv04_instmem.c9
-rw-r--r--shared-core/nv10_fifo.c12
-rw-r--r--shared-core/nv10_graph.c11
-rw-r--r--shared-core/nv20_graph.c15
-rw-r--r--shared-core/nv40_fifo.c4
-rw-r--r--shared-core/nv50_fifo.c9
-rw-r--r--tests/ttmtest/src/ttmtest.c39
-rw-r--r--tests/ttmtest/src/xf86dri.c1
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;