From f89a576aece919f2f9bd42b7d36a5df62cb0d68e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 16:31:34 +1000 Subject: [PATCH 001/129] drm: i810_dma.c: fix pointer arithmetic for 64-bit target First warning result from open-coded PTR_ERR, the rest is caused by code like this: *(u32 *) ((u32) buf_priv->kernel_virtual + used) I've also fixed a missing PTR_ERR in i830_dma.c From: Denis Vlasenko Signed-off-by: Dave Airlie --- linux-core/i810_dma.c | 8 ++++---- linux-core/i830_dma.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index 800c5f61..27d8efb9 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -166,10 +166,10 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp) MAP_SHARED, buf->bus_address); dev_priv->mmap_buffer = NULL; filp->f_op = old_fops; - if ((unsigned long)buf_priv->virtual > -1024UL) { + if (IS_ERR(buf_priv->virtual)) { /* Real error */ DRM_ERROR("mmap error\n"); - retcode = (signed int)buf_priv->virtual; + retcode = PTR_ERR(buf_priv->virtual); buf_priv->virtual = NULL; } up_write(¤t->mm->mmap_sem); @@ -833,7 +833,7 @@ static void i810_dma_dispatch_vertex(drm_device_t * dev, ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2))); if (used & 4) { - *(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0; + *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0; used += 4; } @@ -1191,7 +1191,7 @@ static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used, if (buf_priv->currently_mapped == I810_BUF_MAPPED) { if (used & 4) { - *(u32 *) ((u32) buf_priv->virtual + used) = 0; + *(u32 *) ((char *) buf_priv->virtual + used) = 0; used += 4; } diff --git a/linux-core/i830_dma.c b/linux-core/i830_dma.c index a122898b..9694f64a 100644 --- a/linux-core/i830_dma.c +++ b/linux-core/i830_dma.c @@ -155,7 +155,7 @@ static int i830_map_buffer(drm_buf_t * buf, struct file *filp) if (IS_ERR((void *)virtual)) { /* ugh */ /* Real error */ DRM_ERROR("mmap error\n"); - retcode = virtual; + retcode = PTR_ERR((void *)virtual); buf_priv->virtual = NULL; } else { buf_priv->virtual = (void __user *)virtual; From 4b38f72672c53ed64f016241dcb5d770894657b8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 16:36:26 +1000 Subject: [PATCH 002/129] fixup some of the comments in drm_context.c --- linux-core/drm_context.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c index 95581b53..49042272 100644 --- a/linux-core/drm_context.c +++ b/linux-core/drm_context.c @@ -53,7 +53,7 @@ * \param ctx_handle context handle. * * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry - * in drm_device::context_sareas, while holding the drm_device::struct_sem + * in drm_device::context_sareas, while holding the drm_device::struct_mutex * lock. */ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) @@ -83,7 +83,7 @@ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) * * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates * drm_device::context_sareas to accommodate the new entry while holding the - * drm_device::struct_sem lock. + * drm_device::struct_mutex lock. */ static int drm_ctxbitmap_next(drm_device_t * dev) { @@ -145,7 +145,7 @@ static int drm_ctxbitmap_next(drm_device_t * dev) * \param dev DRM device. * * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding - * the drm_device::struct_sem lock. + * the drm_device::struct_mutex lock. */ int drm_ctxbitmap_init(drm_device_t * dev) { @@ -178,7 +178,7 @@ int drm_ctxbitmap_init(drm_device_t * dev) * \param dev DRM device. * * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding - * the drm_device::struct_sem lock. + * the drm_device::struct_mutex lock. */ void drm_ctxbitmap_cleanup(drm_device_t * dev) { From cc71393559b94ba491059822d7cad388460a0ddf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 16:43:16 +1000 Subject: [PATCH 003/129] remove some DRM_ARRAY_SIZE from linux core code --- linux-core/drm_drv.c | 2 +- linux-core/drm_fops.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 9712170b..da22700e 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -121,7 +121,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0}, }; -#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) +#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) /** * Take down the DRM device. diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 691edff9..74fcf4bd 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -71,7 +71,7 @@ static int drm_setup(drm_device_t * dev) return i; } - for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) + for (i = 0; i < ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER); From 3a681bb4c12ee1042eb31ec565a3eb2ecccddd3d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 16:55:00 +1000 Subject: [PATCH 004/129] remove local copies of pci domain/bus/slot/num --- linux-core/drmP.h | 10 ++++++---- linux-core/drm_ioctl.c | 12 ++++++++---- linux-core/drm_irq.c | 6 +++--- linux-core/drm_stub.c | 6 ------ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 6cbb810f..642ab4b0 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -747,10 +747,6 @@ typedef struct drm_device { drm_agp_head_t *agp; /**< AGP data */ struct pci_dev *pdev; /**< PCI device structure */ - int pci_domain; /**< PCI bus domain number */ - int pci_bus; /**< PCI bus number */ - int pci_slot; /**< PCI slot number */ - int pci_func; /**< PCI function number */ #ifdef __alpha__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) struct pci_controler *hose; @@ -776,6 +772,12 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, return ((dev->driver->driver_features & feature) ? 1 : 0); } +#ifdef __alpha__ +#define drm_get_pci_domain(dev) dev->hose->bus->number +#else +#define drm_get_pci_domain(dev) pci_domain_nr(dev->pdev->bus) +#endif + #if __OS_HAS_AGP static inline int drm_core_has_AGP(struct drm_device *dev) { diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index 54024e1b..2ea6af08 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -125,9 +125,10 @@ int drm_setunique(struct inode *inode, struct file *filp, domain = bus >> 8; bus &= 0xff; - if ((domain != dev->pci_domain) || - (bus != dev->pci_bus) || - (slot != dev->pci_slot) || (func != dev->pci_func)) + if ((domain != drm_get_pci_domain(dev)) || + (bus != dev->pdev->bus->number) || + (slot != PCI_SLOT(dev->pdev->devfn)) || + (func != PCI_FUNC(dev->pdev->devfn))) return -EINVAL; return 0; @@ -145,7 +146,10 @@ static int drm_set_busid(drm_device_t * dev) return ENOMEM; len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", - dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); + drm_get_pci_domain(dev), + dev->pdev->bus->number, + PCI_SLOT(dev->pdev->devfn), + PCI_FUNC(dev->pdev->devfn)); if (len > dev->unique_len) DRM_ERROR("buffer overflow"); diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c index d76fd51d..21a649bc 100644 --- a/linux-core/drm_irq.c +++ b/linux-core/drm_irq.c @@ -64,9 +64,9 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp, if (copy_from_user(&p, argp, sizeof(p))) return -EFAULT; - if ((p.busnum >> 8) != dev->pci_domain || - (p.busnum & 0xff) != dev->pci_bus || - p.devnum != dev->pci_slot || p.funcnum != dev->pci_func) + if ((p.busnum >> 8) != drm_get_pci_domain(dev) || + (p.busnum & 0xff) != dev->pdev->bus->number || + p.devnum != PCI_SLOT(dev->pdev->devfn) || p.funcnum != PCI_FUNC(dev->pdev->devfn)) return -EINVAL; p.irq = dev->irq; diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 25bb5f33..e4d61dcf 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -69,13 +69,7 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, #ifdef __alpha__ dev->hose = pdev->sysdata; - dev->pci_domain = dev->hose->bus->number; -#else - dev->pci_domain = 0; #endif - dev->pci_bus = pdev->bus->number; - dev->pci_slot = PCI_SLOT(pdev->devfn); - dev->pci_func = PCI_FUNC(pdev->devfn); dev->irq = pdev->irq; dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS); From d90a55fe3488020967a4d1b1699ef1f42d50b422 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 16:55:30 +1000 Subject: [PATCH 005/129] fix const pointer warnings with file_operations --- linux-core/drm_fops.c | 2 +- linux-core/i810_dma.c | 2 +- linux-core/i830_dma.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 74fcf4bd..377007c6 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -175,7 +175,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) drm_device_t *dev = NULL; int minor = iminor(inode); int err = -ENODEV; - struct file_operations *old_fops; + const struct file_operations *old_fops; DRM_DEBUG("\n"); diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index 27d8efb9..bdbb31fa 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -151,7 +151,7 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp) drm_device_t *dev = priv->head->dev; drm_i810_buf_priv_t *buf_priv = buf->dev_private; drm_i810_private_t *dev_priv = dev->dev_private; - struct file_operations *old_fops; + const struct file_operations *old_fops; int retcode = 0; if (buf_priv->currently_mapped == I810_BUF_MAPPED) diff --git a/linux-core/i830_dma.c b/linux-core/i830_dma.c index 9694f64a..4526ccf1 100644 --- a/linux-core/i830_dma.c +++ b/linux-core/i830_dma.c @@ -137,7 +137,7 @@ static int i830_map_buffer(drm_buf_t * buf, struct file *filp) drm_device_t *dev = priv->head->dev; drm_i830_buf_priv_t *buf_priv = buf->dev_private; drm_i830_private_t *dev_priv = dev->dev_private; - struct file_operations *old_fops; + const struct file_operations *old_fops; unsigned long virtual; int retcode = 0; From 78634c14a8f92fbbc404442ce6d7b170e6a6e561 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 16:56:03 +1000 Subject: [PATCH 006/129] add static function, and remove bad attributions --- linux-core/drm_bufs.c | 4 ++-- linux-core/drm_drv.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 2eeb401d..eaec611e 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -65,8 +65,8 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, return NULL; } -int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, - unsigned long user_token, int hashed_handle) +static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, + unsigned long user_token, int hashed_handle) { int use_hashed_handle; diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index da22700e..5ddcd4c1 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -50,7 +50,7 @@ #include "drmP.h" #include "drm_core.h" -static void __exit drm_cleanup(drm_device_t * dev); +static void drm_cleanup(drm_device_t * dev); int drm_fb_loaded = 0; static int drm_version(struct inode *inode, struct file *filp, @@ -336,7 +336,7 @@ EXPORT_SYMBOL(drm_init); * * \sa drm_init */ -static void __exit drm_cleanup(drm_device_t * dev) +static void drm_cleanup(drm_device_t * dev) { DRM_DEBUG("\n"); @@ -379,7 +379,7 @@ static void __exit drm_cleanup(drm_device_t * dev) DRM_ERROR("Cannot unload module\n"); } -void __exit drm_exit(struct drm_driver *driver) +void drm_exit(struct drm_driver *driver) { int i; drm_device_t *dev = NULL; From 0afb877a37a33e8493628ddc267fb00650fd1840 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 17:59:18 +1000 Subject: [PATCH 007/129] drm: lots of small cleanups and whitespace issues fixed up remove a mach64 warning, align a lot of things from linux kernel --- linux-core/drmP.h | 12 +++++------ linux-core/drm_bufs.c | 12 +++++------ linux-core/drm_fops.c | 4 ++-- linux-core/drm_ioctl.c | 10 +++++---- linux-core/drm_irq.c | 10 +++++---- linux-core/drm_lock.c | 2 +- linux-core/drm_pci.c | 18 ++-------------- linux-core/drm_proc.c | 8 ++++---- linux-core/drm_sman.c | 2 +- linux-core/drm_stub.c | 8 ++++---- linux-core/drm_vm.c | 18 ++++++++-------- linux-core/i810_drv.h | 20 +++++++++--------- linux-core/sis_drv.c | 14 ++++++------- linux-core/via_dmablit.c | 25 +++++++++++------------ linux-core/via_dmablit.h | 10 +++++---- shared-core/mach64_drm.h | 2 +- shared-core/radeon_drv.h | 2 +- shared-core/radeon_state.c | 8 ++++---- shared-core/sis_drv.h | 22 ++++++++++---------- shared-core/via_dma.c | 18 ++++++++-------- shared-core/via_drm.h | 42 +++++++++++++++++++------------------- shared-core/via_drv.h | 16 +++++++-------- shared-core/via_irq.c | 25 ++++++++++++----------- shared-core/via_verifier.h | 8 ++++---- 24 files changed, 153 insertions(+), 163 deletions(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 642ab4b0..6046dde6 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -298,8 +298,8 @@ typedef struct drm_devstate { } drm_devstate_t; typedef struct drm_magic_entry { - drm_hash_item_t hash_item; - struct list_head head; + drm_hash_item_t hash_item; + struct list_head head; struct drm_file *priv; } drm_magic_entry_t; @@ -506,7 +506,7 @@ typedef struct drm_sigdata { */ typedef struct drm_map_list { struct list_head head; /**< list head */ - drm_hash_item_t hash; + drm_hash_item_t hash; drm_map_t *map; /**< mapping */ unsigned int user_token; } drm_map_list_t; @@ -676,15 +676,15 @@ typedef struct drm_device { /*@{ */ drm_file_t *file_first; /**< file list head */ drm_file_t *file_last; /**< file list tail */ - drm_open_hash_t magiclist; - struct list_head magicfree; + drm_open_hash_t magiclist; + struct list_head magicfree; /*@} */ /** \name Memory management */ /*@{ */ drm_map_list_t *maplist; /**< Linked list of regions */ int map_count; /**< Number of mappable regions */ - drm_open_hash_t map_hash; /**< User token hash table for maps */ + drm_open_hash_t map_hash; /**< User token hash table for maps */ /** \name Context handle management */ /*@{ */ diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index eaec611e..7d3121d3 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -290,13 +290,13 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, user_token = (map->type == _DRM_SHM) ? (unsigned long) map->handle : map->offset; - ret = drm_map_handle(dev, &list->hash, user_token, 0); + ret = drm_map_handle(dev, &list->hash, user_token, 0); if (ret) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - drm_free(list, sizeof(*list), DRM_MEM_MAPS); - mutex_unlock(&dev->struct_mutex); - return ret; + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + drm_free(list, sizeof(*list), DRM_MEM_MAPS); + mutex_unlock(&dev->struct_mutex); + return ret; } list->user_token = list->hash.key; @@ -384,7 +384,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) if (r_list->map == map) { list_del(list); - drm_ht_remove_key(&dev->map_hash, r_list->user_token); + drm_ht_remove_key(&dev->map_hash, r_list->user_token); drm_free(list, sizeof(*list), DRM_MEM_MAPS); break; } diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 377007c6..48c77545 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -74,8 +74,8 @@ static int drm_setup(drm_device_t * dev) for (i = 0; i < ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); - drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER); - INIT_LIST_HEAD(&dev->magicfree); + drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER); + INIT_LIST_HEAD(&dev->magicfree); dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST); if (dev->ctxlist == NULL) diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index 2ea6af08..776f462e 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -242,7 +242,7 @@ int drm_getclient(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_client_t __user *argp = (void __user *)arg; + drm_client_t __user *argp = (drm_client_t __user *)arg; drm_client_t client; drm_file_t *pt; int idx; @@ -329,21 +329,23 @@ int drm_setversion(DRM_IOCTL_ARGS) int if_version; drm_set_version_t __user *argp = (void __user *)data; - DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); + if (copy_from_user(&sv, argp, sizeof(sv))) + return -EFAULT; retv.drm_di_major = DRM_IF_MAJOR; retv.drm_di_minor = DRM_IF_MINOR; retv.drm_dd_major = dev->driver->major; retv.drm_dd_minor = dev->driver->minor; - DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); + if (copy_to_user(argp, &retv, sizeof(sv))) + return -EFAULT; if (sv.drm_di_major != -1) { if (sv.drm_di_major != DRM_IF_MAJOR || sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR) return EINVAL; if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor); - dev->if_version = DRM_MAX(if_version, dev->if_version); + dev->if_version = max(if_version, dev->if_version); if (sv.drm_di_minor >= 1) { /* * Version 1.1 includes tying of DRM to specific device diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c index 21a649bc..c2a9e3d6 100644 --- a/linux-core/drm_irq.c +++ b/linux-core/drm_irq.c @@ -222,12 +222,12 @@ int drm_control(struct inode *inode, struct file *filp, * Wait for VBLANK. * * \param inode device inode. - * \param filp file pointer.rm. + * \param filp file pointer. * \param cmd command. * \param data user argument, pointing to a drm_wait_vblank structure. * \return zero on success or a negative number on failure. * - * Verifies the IRQ is installed + * Verifies the IRQ is installed. * * If a signal is requested checks if this task has already scheduled the same signal * for the same vblank sequence number - nothing to be done in @@ -253,7 +253,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) if ((!dev->irq) || (!dev->irq_enabled)) return -EINVAL; - DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait)); + if (copy_from_user(&vblwait, argp, sizeof(vblwait))) + return -EFAULT; switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) { case _DRM_VBLANK_RELATIVE: @@ -327,7 +328,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) } done: - DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait)); + if (copy_to_user(argp, &vblwait, sizeof(vblwait))) + return -EFAULT; return ret; } diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c index a268d8ee..7aa00bc2 100644 --- a/linux-core/drm_lock.c +++ b/linux-core/drm_lock.c @@ -104,7 +104,7 @@ int drm_lock(struct inode *inode, struct file *filp, __set_current_state(TASK_RUNNING); remove_wait_queue(&dev->lock.lock_queue, &entry); - DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); + DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); if (ret) return ret; sigemptyset(&dev->sigmask); diff --git a/linux-core/drm_pci.c b/linux-core/drm_pci.c index b69dda22..40a65f3e 100644 --- a/linux-core/drm_pci.c +++ b/linux-core/drm_pci.c @@ -37,6 +37,7 @@ */ #include +#include #include "drmP.h" /**********************************************************************/ @@ -83,11 +84,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, return NULL; dmah->size = size; -#if 0 - dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr); -#else dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP); -#endif #ifdef DRM_DEBUG_MEMORY if (dmah->vaddr == NULL) { @@ -112,14 +109,12 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, memset(dmah->vaddr, 0, size); -#if 1 /* XXX - Is virt_to_page() legal for consistent mem? */ /* Reserve */ for (addr = (unsigned long)dmah->vaddr, sz = size; sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { SetPageReserved(virt_to_page(addr)); } -#endif return dmah; } @@ -132,10 +127,8 @@ EXPORT_SYMBOL(drm_pci_alloc); */ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) { -#if 1 unsigned long addr; size_t sz; -#endif #ifdef DRM_DEBUG_MEMORY int area = DRM_MEM_DMA; int alloc_count; @@ -147,21 +140,14 @@ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) DRM_MEM_ERROR(area, "Attempt to free address 0\n"); #endif } else { -#if 1 /* XXX - Is virt_to_page() legal for consistent mem? */ /* Unreserve */ for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); } -#endif -#if 0 - pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr, - dmah->busaddr); -#else dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, dmah->busaddr); -#endif } #ifdef DRM_DEBUG_MEMORY @@ -181,7 +167,7 @@ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) } /** - * \brief Free a PCI consistent memory block. + * \brief Free a PCI consistent memory block */ void drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) { diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 014486c1..512a8f75 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -258,7 +258,7 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, } /** - * Simply calls _vm_info() while holding the drm_device::struct_sem lock. + * Simply calls _vm_info() while holding the drm_device::struct_mutex lock. */ static int drm_vm_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) @@ -331,7 +331,7 @@ static int drm__queues_info(char *buf, char **start, off_t offset, } /** - * Simply calls _queues_info() while holding the drm_device::struct_sem lock. + * Simply calls _queues_info() while holding the drm_device::struct_mutex lock. */ static int drm_queues_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) @@ -403,7 +403,7 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, } /** - * Simply calls _bufs_info() while holding the drm_device::struct_sem lock. + * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock. */ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) @@ -459,7 +459,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset, } /** - * Simply calls _clients_info() while holding the drm_device::struct_sem lock. + * Simply calls _clients_info() while holding the drm_device::struct_mutex lock. */ static int drm_clients_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) diff --git a/linux-core/drm_sman.c b/linux-core/drm_sman.c index b92f0ee7..425c8233 100644 --- a/linux-core/drm_sman.c +++ b/linux-core/drm_sman.c @@ -114,7 +114,7 @@ static void drm_sman_mm_destroy(void *private) drm_free(mm, sizeof(*mm), DRM_MEM_MM); } -unsigned long drm_sman_mm_offset(void *private, void *ref) +static unsigned long drm_sman_mm_offset(void *private, void *ref) { drm_mm_node_t *node = (drm_mm_node_t *) ref; return node->start; diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index e4d61dcf..bdc36552 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -76,10 +76,10 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, if (dev->maplist == NULL) return -ENOMEM; INIT_LIST_HEAD(&dev->maplist->head); - if (drm_ht_create(&dev->map_hash, 12)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); - return -ENOMEM; - } + if (drm_ht_create(&dev->map_hash, 12)) { + drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); + return -ENOMEM; + } /* the DRM has 6 counters */ dev->counters = 6; diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index cf3bc3cf..0391395d 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -59,7 +59,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, drm_device_t *dev = priv->head->dev; drm_map_t *map = NULL; drm_map_list_t *r_list; - drm_hash_item_t *hash; + drm_hash_item_t *hash; /* * Find the right map @@ -70,10 +70,10 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, if (!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; - if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash)) - goto vm_nopage_error; + if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash)) + goto vm_nopage_error; - r_list = drm_hash_entry(hash, drm_map_list_t, hash); + r_list = drm_hash_entry(hash, drm_map_list_t, hash); map = r_list->map; if (map && map->type == _DRM_AGP) { @@ -554,7 +554,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) drm_device_t *dev = priv->head->dev; drm_map_t *map = NULL; unsigned long offset = 0; - drm_hash_item_t *hash; + drm_hash_item_t *hash; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); @@ -574,11 +574,11 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) ) return drm_mmap_dma(filp, vma); - if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash)) { - DRM_ERROR("Could not find map\n"); + if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash)) { + DRM_ERROR("Could not find map\n"); return -EINVAL; - } - + } + map = drm_hash_entry(hash,drm_map_list_t, hash)->map; if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h index e8cf3ff6..bb7358d2 100644 --- a/linux-core/i810_drv.h +++ b/linux-core/i810_drv.h @@ -141,8 +141,8 @@ extern int i810_max_ioctl; volatile char *virt; #define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ + if (I810_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__);\ if (dev_priv->ring.space < n*4) \ i810_wait_ring(dev, n*4); \ dev_priv->ring.space -= n*4; \ @@ -151,17 +151,17 @@ extern int i810_max_ioctl; virt = dev_priv->ring.virtual_start; \ } while (0) -#define ADVANCE_LP_RING() do { \ +#define ADVANCE_LP_RING() do { \ if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) -#define OUT_RING(n) do { \ +#define OUT_RING(n) do { \ if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ } while (0) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) @@ -193,7 +193,7 @@ extern int i810_max_ioctl; #define HEAD_WRAP_ONE 0x00200000 #define HEAD_ADDR 0x001FFFFC #define RING_START 0x08 -#define START_ADDR 0x00FFFFF8 +#define START_ADDR 0x00FFFFF8 #define RING_LEN 0x0C #define RING_NR_PAGES 0x000FF000 #define RING_REPORT_MASK 0x00000006 diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c index 3fdbd88e..36a525dc 100644 --- a/linux-core/sis_drv.c +++ b/linux-core/sis_drv.c @@ -40,15 +40,15 @@ static struct pci_device_id pciidlist[] = { static int sis_driver_load(drm_device_t *dev, unsigned long chipset) { drm_sis_private_t *dev_priv; - int ret; + int ret; dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) return DRM_ERR(ENOMEM); dev->dev_private = (void *)dev_priv; - dev_priv->chipset = chipset; - ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); + dev_priv->chipset = chipset; + ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); if (ret) { drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER); } @@ -60,7 +60,7 @@ static int sis_driver_unload(drm_device_t *dev) { drm_sis_private_t *dev_priv = dev->dev_private; - drm_sman_takedown(&dev_priv->sman); + drm_sman_takedown(&dev_priv->sman); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); return 0; @@ -70,10 +70,10 @@ static int sis_driver_unload(drm_device_t *dev) static int probe(struct pci_dev *pdev, const struct pci_device_id *ent); static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, - .load = sis_driver_load, - .unload = sis_driver_unload, + .load = sis_driver_load, + .unload = sis_driver_unload, .context_dtor = NULL, - .dma_quiescent = sis_idle, + .dma_quiescent = sis_idle, .reclaim_buffers = NULL, .reclaim_buffers_locked = sis_reclaim_buffers_locked, .lastclose = sis_lastclose, diff --git a/linux-core/via_dmablit.c b/linux-core/via_dmablit.c index 4a3a7524..61e6a102 100644 --- a/linux-core/via_dmablit.c +++ b/linux-core/via_dmablit.c @@ -121,19 +121,18 @@ via_map_blit_for_device(struct pci_dev *pdev, while (line_len > 0) { - remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len); + remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len); line_len -= remaining_len; if (mode == 1) { - desc_ptr->mem_addr = - dma_map_page(&pdev->dev, - vsg->pages[VIA_PFN(cur_mem) - - VIA_PFN(first_addr)], - VIA_PGOFF(cur_mem), remaining_len, - vsg->direction); - desc_ptr->dev_addr = cur_fb; + desc_ptr->mem_addr = dma_map_page(&pdev->dev, + vsg->pages[VIA_PFN(cur_mem) - + VIA_PFN(first_addr)], + VIA_PGOFF(cur_mem), remaining_len, + vsg->direction); + desc_ptr->dev_addr = cur_fb; - desc_ptr->size = remaining_len; + desc_ptr->size = remaining_len; desc_ptr->next = (uint32_t) next; next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr), DMA_TO_DEVICE); @@ -167,7 +166,7 @@ via_map_blit_for_device(struct pci_dev *pdev, */ -void +static void via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) { struct page *page; @@ -648,13 +647,13 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t * if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) || ((xfer->num_lines > 1) && ((xfer->mem_stride & 3) != (xfer->fb_stride & 3)))) { DRM_ERROR("Invalid DRM bitblt alignment.\n"); - return DRM_ERR(EINVAL); + return DRM_ERR(EINVAL); } #else if ((((unsigned long)xfer->mem_addr & 15) || ((unsigned long)xfer->fb_addr & 3)) || ((xfer->num_lines > 1) && ((xfer->mem_stride & 15) || (xfer->fb_stride & 3)))) { DRM_ERROR("Invalid DRM bitblt alignment.\n"); - return DRM_ERR(EINVAL); + return DRM_ERR(EINVAL); } #endif @@ -732,7 +731,7 @@ via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer) drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; drm_via_sg_info_t *vsg; drm_via_blitq_t *blitq; - int ret; + int ret; int engine; unsigned long irqsave; diff --git a/linux-core/via_dmablit.h b/linux-core/via_dmablit.h index 64863917..f6ae03ec 100644 --- a/linux-core/via_dmablit.h +++ b/linux-core/via_dmablit.h @@ -30,6 +30,8 @@ #ifndef _VIA_DMABLIT_H #define _VIA_DMABLIT_H +#include + #define VIA_NUM_BLIT_ENGINES 2 #define VIA_NUM_BLIT_SLOTS 8 @@ -43,12 +45,12 @@ typedef struct _drm_via_sg_info { int num_desc; enum dma_data_direction direction; unsigned char *bounce_buffer; - dma_addr_t chain_start; + dma_addr_t chain_start; uint32_t free_on_sequence; - unsigned int descriptors_per_page; + unsigned int descriptors_per_page; int aborted; enum { - dr_via_device_mapped, + dr_via_device_mapped, dr_via_desc_pages_alloc, dr_via_pages_locked, dr_via_pages_alloc, @@ -66,7 +68,7 @@ typedef struct _drm_via_blitq { unsigned num_free; unsigned num_outstanding; unsigned long end; - int aborting; + int aborting; int is_active; drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS]; spinlock_t blit_lock; diff --git a/shared-core/mach64_drm.h b/shared-core/mach64_drm.h index d92ece2c..1fd8c002 100644 --- a/shared-core/mach64_drm.h +++ b/shared-core/mach64_drm.h @@ -68,7 +68,7 @@ /* Max number of swaps allowed on the ring * before the client must wait */ -#define MACH64_MAX_QUEUED_FRAMES 3 +#define MACH64_MAX_QUEUED_FRAMES 3U /* Byte offsets for host blit buffer data */ diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index ff75480a..5fa8254a 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1095,7 +1095,7 @@ do { \ n, __FUNCTION__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ - COMMIT_RING(); \ + COMMIT_RING(); \ radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 58251dd7..99672fa7 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -2653,10 +2653,10 @@ static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8); RING_LOCALS; - if (!sz) - return 0; - if (sz * 4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + if (!sz) + return 0; + if (sz * 4 > cmdbuf->bufsz) + return DRM_ERR(EINVAL); BEGIN_RING(5 + sz); OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); diff --git a/shared-core/sis_drv.h b/shared-core/sis_drv.h index b739a483..d1cdc19c 100644 --- a/shared-core/sis_drv.h +++ b/shared-core/sis_drv.h @@ -40,8 +40,8 @@ #define DRIVER_PATCHLEVEL 1 enum sis_family { - SIS_OTHER = 0, - SIS_CHIP_315 = 1, + SIS_OTHER = 0, + SIS_CHIP_315 = 1, }; #if defined(__linux__) @@ -52,18 +52,18 @@ enum sis_family { #include "drm_sman.h" #define SIS_BASE (dev_priv->mmio) -#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg); +#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg); #define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val); typedef struct drm_sis_private { - drm_local_map_t *mmio; - unsigned idle_fault; - drm_sman_t sman; - unsigned long chipset; - int vram_initialized; - int agp_initialized; - unsigned long vram_offset; - unsigned long agp_offset; + drm_local_map_t *mmio; + unsigned idle_fault; + drm_sman_t sman; + unsigned long chipset; + int vram_initialized; + int agp_initialized; + unsigned long vram_offset; + unsigned long agp_offset; } drm_sis_private_t; extern int sis_idle(drm_device_t *dev); diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c index 11fa7388..c6e7aa77 100644 --- a/shared-core/via_dma.c +++ b/shared-core/via_dma.c @@ -44,14 +44,14 @@ #define CMDBUF_ALIGNMENT_MASK (0x0ff) /* defines for VIA 3D registers */ -#define VIA_REG_STATUS 0x400 -#define VIA_REG_TRANSET 0x43C +#define VIA_REG_STATUS 0x400 +#define VIA_REG_TRANSET 0x43C #define VIA_REG_TRANSPACE 0x440 /* VIA_REG_STATUS(0x400): Engine Status */ #define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */ -#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */ -#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */ +#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */ #define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */ #define SetReg2DAGP(nReg, nData) { \ @@ -120,7 +120,7 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size) next_addr = cur_addr + size + 512*1024; count = 1000000; do { - hw_addr = *hw_addr_ptr - agp_base; + hw_addr = *hw_addr_ptr - agp_base; if (count-- == 0) { DRM_ERROR ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n", @@ -247,10 +247,10 @@ static int via_dma_init(DRM_IOCTL_ARGS) else retcode = via_dma_cleanup(dev); break; - case VIA_DMA_INITIALIZED: + case VIA_DMA_INITIALIZED: retcode = (dev_priv->ring.virtual_start != NULL) ? 0: DRM_ERR( EFAULT ); - break; + break; default: retcode = DRM_ERR(EINVAL); break; @@ -406,7 +406,7 @@ static int via_pci_cmdbuffer(DRM_IOCTL_ARGS) static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv, uint32_t * vb, int qw_count) { - for (; qw_count > 0; --qw_count) { + for (; qw_count > 0; --qw_count) { VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY); } return vb; @@ -471,7 +471,7 @@ static int via_hook_segment(drm_via_private_t *dev_priv, } if (paused && !no_pci_fire) { - uint32_t rgtr,ptr; + uint32_t rgtr,ptr; uint32_t ptr_low; count = 1000000; diff --git a/shared-core/via_drm.h b/shared-core/via_drm.h index 049c63e1..60fb92c8 100644 --- a/shared-core/via_drm.h +++ b/shared-core/via_drm.h @@ -47,12 +47,12 @@ #define VIA_DRM_DRIVER_MAJOR 2 #define VIA_DRM_DRIVER_MINOR 10 #define VIA_DRM_DRIVER_PATCHLEVEL 2 -#define VIA_DRM_DRIVER_VERSION (((VIA_DRM_DRIVER_MAJOR) << 16) | (VIA_DRM_DRIVER_MINOR)) +#define VIA_DRM_DRIVER_VERSION (((VIA_DRM_DRIVER_MAJOR) << 16) | (VIA_DRM_DRIVER_MINOR)) #define VIA_NR_SAREA_CLIPRECTS 8 -#define VIA_NR_XVMC_PORTS 10 -#define VIA_NR_XVMC_LOCKS 5 -#define VIA_MAX_CACHELINE_SIZE 64 +#define VIA_NR_XVMC_PORTS 10 +#define VIA_NR_XVMC_LOCKS 5 +#define VIA_MAX_CACHELINE_SIZE 64 #define XVMCLOCKPTR(saPriv,lockNo) \ ((volatile drm_hw_lock_t *)(((((unsigned long) (saPriv)->XvMCLockArea) + \ (VIA_MAX_CACHELINE_SIZE - 1)) & \ @@ -67,29 +67,29 @@ #define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ #define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ -#define VIA_UPLOAD_CTX 0x4 +#define VIA_UPLOAD_CTX 0x4 #define VIA_UPLOAD_BUFFERS 0x8 #define VIA_UPLOAD_TEX0 0x10 #define VIA_UPLOAD_TEX1 0x20 #define VIA_UPLOAD_CLIPRECTS 0x40 -#define VIA_UPLOAD_ALL 0xff +#define VIA_UPLOAD_ALL 0xff /* VIA specific ioctls */ #define DRM_VIA_ALLOCMEM 0x00 -#define DRM_VIA_FREEMEM 0x01 +#define DRM_VIA_FREEMEM 0x01 #define DRM_VIA_AGP_INIT 0x02 -#define DRM_VIA_FB_INIT 0x03 +#define DRM_VIA_FB_INIT 0x03 #define DRM_VIA_MAP_INIT 0x04 #define DRM_VIA_DEC_FUTEX 0x05 #define NOT_USED #define DRM_VIA_DMA_INIT 0x07 #define DRM_VIA_CMDBUFFER 0x08 -#define DRM_VIA_FLUSH 0x09 -#define DRM_VIA_PCICMD 0x0a +#define DRM_VIA_FLUSH 0x09 +#define DRM_VIA_PCICMD 0x0a #define DRM_VIA_CMDBUF_SIZE 0x0b #define NOT_USED -#define DRM_VIA_WAIT_IRQ 0x0d -#define DRM_VIA_DMA_BLIT 0x0e +#define DRM_VIA_WAIT_IRQ 0x0d +#define DRM_VIA_DMA_BLIT 0x0e #define DRM_VIA_BLIT_SYNC 0x0f #define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t) @@ -172,7 +172,7 @@ typedef struct _drm_via_dma_init { enum { VIA_INIT_DMA = 0x01, VIA_CLEANUP_DMA = 0x02, - VIA_DMA_INITIALIZED = 0x03 + VIA_DMA_INITIALIZED = 0x03 } func; unsigned long offset; @@ -217,7 +217,7 @@ typedef struct _drm_via_sarea { /* Used by the 3d driver only at this point, for pageflipping: */ - unsigned int pfCurrentOffset; + unsigned int pfCurrentOffset; } drm_via_sarea_t; typedef struct _drm_via_cmdbuf_size { @@ -273,17 +273,17 @@ typedef struct drm_via_blitsync { */ typedef struct drm_via_dmablit { - uint32_t num_lines; - uint32_t line_length; + uint32_t num_lines; + uint32_t line_length; - uint32_t fb_addr; - uint32_t fb_stride; + uint32_t fb_addr; + uint32_t fb_stride; - unsigned char *mem_addr; - uint32_t mem_stride; + unsigned char *mem_addr; + uint32_t mem_stride; uint32_t flags; - int to_fb; + int to_fb; drm_via_blitsync_t sync; } drm_via_dmablit_t; diff --git a/shared-core/via_drv.h b/shared-core/via_drv.h index 86cd049d..18d2a331 100644 --- a/shared-core/via_drv.h +++ b/shared-core/via_drv.h @@ -76,9 +76,9 @@ typedef struct drm_via_private { volatile uint32_t *last_pause_ptr; volatile uint32_t *hw_addr_ptr; drm_via_ring_buffer_t ring; - struct timeval last_vblank; - int last_vblank_valid; - unsigned usec_per_vblank; + struct timeval last_vblank; + int last_vblank_valid; + unsigned usec_per_vblank; drm_via_state_t hc_state; char pci_buf[VIA_PCI_BUF_SIZE]; const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; @@ -90,14 +90,14 @@ typedef struct drm_via_private { uint32_t irq_enable_mask; uint32_t irq_pending_mask; int *irq_map; - /* Memory manager stuff */ + /* Memory manager stuff */ #ifdef VIA_HAVE_CORE_MM - unsigned idle_fault; + unsigned int idle_fault; drm_sman_t sman; int vram_initialized; int agp_initialized; - unsigned long vram_offset; - unsigned long agp_offset; + unsigned long vram_offset; + unsigned long agp_offset; #endif #ifdef VIA_HAVE_DMABLIT drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; @@ -148,8 +148,6 @@ extern int via_driver_dma_quiescent(drm_device_t * dev); extern void via_init_futex(drm_via_private_t *dev_priv); extern void via_cleanup_futex(drm_via_private_t *dev_priv); extern void via_release_futex(drm_via_private_t *dev_priv, int context); -extern int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, - int force_sequence, unsigned int *sequence); #ifdef VIA_HAVE_CORE_MM extern void via_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); diff --git a/shared-core/via_irq.c b/shared-core/via_irq.c index aaba0cb6..1862fbcf 100644 --- a/shared-core/via_irq.c +++ b/shared-core/via_irq.c @@ -43,7 +43,7 @@ #define VIA_REG_INTERRUPT 0x200 /* VIA_REG_INTERRUPT */ -#define VIA_IRQ_GLOBAL (1 << 31) +#define VIA_IRQ_GLOBAL (1 << 31) #define VIA_IRQ_VBLANK_ENABLE (1 << 19) #define VIA_IRQ_VBLANK_PENDING (1 << 3) #define VIA_IRQ_HQV0_ENABLE (1 << 11) @@ -93,8 +93,8 @@ static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; static unsigned time_diff(struct timeval *now,struct timeval *then) { return (now->tv_usec >= then->tv_usec) ? - now->tv_usec - then->tv_usec : - 1000000 - (then->tv_usec - now->tv_usec); + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); } irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) @@ -110,21 +110,21 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) status = VIA_READ(VIA_REG_INTERRUPT); if (status & VIA_IRQ_VBLANK_PENDING) { atomic_inc(&dev->vbl_received); - if (!(atomic_read(&dev->vbl_received) & 0x0F)) { + if (!(atomic_read(&dev->vbl_received) & 0x0F)) { #ifdef __linux__ do_gettimeofday(&cur_vblank); #else microtime(&cur_vblank); #endif - if (dev_priv->last_vblank_valid) { + if (dev_priv->last_vblank_valid) { dev_priv->usec_per_vblank = time_diff(&cur_vblank, &dev_priv->last_vblank) >> 4; } dev_priv->last_vblank = cur_vblank; dev_priv->last_vblank_valid = 1; - } - if (!(atomic_read(&dev->vbl_received) & 0xFF)) { + } + if (!(atomic_read(&dev->vbl_received) & 0xFF)) { DRM_DEBUG("US per vblank is: %u\n", dev_priv->usec_per_vblank); } @@ -198,13 +198,13 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) return ret; } -int +static int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, unsigned int *sequence) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; unsigned int cur_irq_sequence; - drm_via_irq_t *cur_irq = dev_priv->via_irqs; + drm_via_irq_t *cur_irq; int ret = 0; maskarray_t *masks; int real_irq; @@ -231,7 +231,7 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, } masks = dev_priv->irq_masks; - cur_irq += real_irq; + cur_irq = dev_priv->via_irqs + real_irq; if (masks[real_irq][2] && !force_sequence) { DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, @@ -257,11 +257,12 @@ void via_driver_irq_preinstall(drm_device_t * dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; - drm_via_irq_t *cur_irq = dev_priv->via_irqs; + drm_via_irq_t *cur_irq; int i; DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv); if (dev_priv) { + cur_irq = dev_priv->via_irqs; dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; @@ -285,7 +286,7 @@ void via_driver_irq_preinstall(drm_device_t * dev) DRM_DEBUG("Initializing IRQ %d\n", i); } - dev_priv->last_vblank_valid = 0; + dev_priv->last_vblank_valid = 0; /* Clear VSync interrupt regs */ status = VIA_READ(VIA_REG_INTERRUPT); diff --git a/shared-core/via_verifier.h b/shared-core/via_verifier.h index c0ffc97f..96708a39 100644 --- a/shared-core/via_verifier.h +++ b/shared-core/via_verifier.h @@ -26,20 +26,20 @@ #ifndef _VIA_VERIFIER_H_ #define _VIA_VERIFIER_H_ -typedef enum{ +typedef enum { no_sequence = 0, z_address, dest_address, tex_address -}drm_via_sequence_t; +} drm_via_sequence_t; -typedef struct{ +typedef struct { unsigned texture; uint32_t z_addr; uint32_t d_addr; - uint32_t t_addr[2][10]; + uint32_t t_addr[2][10]; uint32_t pitch[2][10]; uint32_t height[2][10]; uint32_t tex_level_lo[2]; From fef9b30a2b437c0103c33443566604027529b91d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 27 Aug 2006 08:55:02 +1000 Subject: [PATCH 008/129] initial import of nouveau code from nouveau CVS --- linux-core/Makefile | 10 +- linux-core/Makefile.kernel | 2 + linux-core/nouveau_drv.c | 101 +++++++ shared-core/Makefile.am | 1 + shared-core/nouveau_drm.h | 119 ++++++++ shared-core/nouveau_drv.h | 168 +++++++++++ shared-core/nouveau_fifo.c | 270 +++++++++++++++++ shared-core/nouveau_irq.c | 208 +++++++++++++ shared-core/nouveau_mem.c | 503 +++++++++++++++++++++++++++++++ shared-core/nouveau_object.c | 565 +++++++++++++++++++++++++++++++++++ shared-core/nouveau_reg.h | 103 +++++++ shared-core/nouveau_state.c | 134 +++++++++ 12 files changed, 2182 insertions(+), 2 deletions(-) create mode 100644 linux-core/nouveau_drv.c create mode 100644 shared-core/nouveau_drm.h create mode 100644 shared-core/nouveau_drv.h create mode 100644 shared-core/nouveau_fifo.c create mode 100644 shared-core/nouveau_irq.c create mode 100644 shared-core/nouveau_mem.c create mode 100644 shared-core/nouveau_object.c create mode 100644 shared-core/nouveau_reg.h create mode 100644 shared-core/nouveau_state.c diff --git a/linux-core/Makefile b/linux-core/Makefile index 32828d28..e3432b5c 100644 --- a/linux-core/Makefile +++ b/linux-core/Makefile @@ -58,7 +58,7 @@ endif # Modules for all architectures MODULE_LIST := drm.o tdfx.o r128.o radeon.o mga.o sis.o savage.o via.o \ - mach64.o nv.o + mach64.o nv.o nouveau.o # Modules only for ix86 architectures ifneq (,$(findstring 86,$(MACHINE))) @@ -106,10 +106,12 @@ MACH64SHARED = mach64_drv.h mach64_drm.h mach64_dma.c \ NVHEADERS = nv_drv.h $(DRMHEADERS) NVSHARED = nv_drv.h FFBHEADERS = ffb_drv.h $(DRMHEADERS) +NOUVEAUHEADERS = nouveau_drv.h nouveau_drm.h nouveau_reg.h $(DRMHEADERS) +NOUVEAUSHARED = nouveau_drv.h nouveau_drm.h nouveau_reg.h nouveau_state.c nouveau_fifo.c nouveau_mem.c nouveau_object.c nouveau_irq.c SHAREDSRC = $(DRMSHARED) $(MGASHARED) $(R128SHARED) $(RADEONSHARED) \ $(SISSHARED) $(TDFXSHARED) $(VIASHARED) $(MACH64SHARED) \ - $(I915SHARED) $(SAVAGESHARED) $(NVSHARED) + $(I915SHARED) $(SAVAGESHARED) $(NVSHARED) $(NOUVEAUSHARED) PROGS = dristat drmstat @@ -372,6 +374,9 @@ endif ifneq (,$(findstring nv,$(DRM_MODULES))) CONFIG_DRM_NV := m endif +ifneq (,$(findstring nouveau,$(DRM_MODULES))) +CONFIG_DRM_NOUVEAU := m +endif # These require AGP support @@ -402,6 +407,7 @@ $(savage-objs): $(SAVAGEHEADERS) $(via-objs): $(VIAHEADERS) $(mach64-objs): $(MACH64HEADERS) $(nv-objs): $(NVHEADERS) +$(nouveau-objs): $(NOUVEAUHEADERS) endif diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 211e5b05..950259bd 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -19,6 +19,7 @@ mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o i810-objs := i810_drv.o i810_dma.o i830-objs := i830_drv.o i830_dma.o i830_irq.o i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o +nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o nouveau_object.o nouveau_irq.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o sis-objs := sis_drv.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o @@ -50,3 +51,4 @@ obj-$(CONFIG_DRM_SAVAGE)+= savage.o obj-$(CONFIG_DRM_VIA) += via.o obj-$(CONFIG_DRM_MACH64)+= mach64.o obj-$(CONFIG_DRM_NV) += nv.o +obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o diff --git a/linux-core/nouveau_drv.c b/linux-core/nouveau_drv.c new file mode 100644 index 00000000..2093ffee --- /dev/null +++ b/linux-core/nouveau_drv.c @@ -0,0 +1,101 @@ +/* + * Copyright 2005 Stephane Marchesin. + * 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. + */ + +#include +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +#include "drm_pciids.h" + +static struct pci_device_id pciidlist[] = { + nouveau_PCI_IDS +}; + +extern drm_ioctl_desc_t nouveau_ioctls[]; +extern int nouveau_max_ioctl; + +static int probe(struct pci_dev *pdev, const struct pci_device_id *ent); +static struct drm_driver driver = { + .driver_features = + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + .load = nouveau_load, + .firstopen = nouveau_firstopen, + .unload = nouveau_unload, + .preclose = nouveau_preclose, + .irq_preinstall = nouveau_irq_preinstall, + .irq_postinstall = nouveau_irq_postinstall, + .irq_uninstall = nouveau_irq_uninstall, + .irq_handler = nouveau_irq_handler, + .reclaim_buffers = drm_core_reclaim_buffers, + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, + .ioctls = nouveau_ioctls, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + .probe = probe, + .remove = __devexit_p(drm_cleanup_pci), + }, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, +}; + +static int probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_dev(pdev, ent, &driver); +} + +static int __init nouveau_init(void) +{ + driver.num_ioctls = nouveau_max_ioctl; + return drm_init(&driver, pciidlist); +} + +static void __exit nouveau_exit(void) +{ + drm_exit(&driver); +} + +module_init(nouveau_init); +module_exit(nouveau_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL and additional rights"); diff --git a/shared-core/Makefile.am b/shared-core/Makefile.am index cd278643..f0ebf2a3 100644 --- a/shared-core/Makefile.am +++ b/shared-core/Makefile.am @@ -29,6 +29,7 @@ klibdrminclude_HEADERS = \ i915_drm.h \ mach64_drm.h \ mga_drm.h \ + nouveau_drm.h \ r128_drm.h \ radeon_drm.h \ savage_drm.h \ diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h new file mode 100644 index 00000000..eab8ca29 --- /dev/null +++ b/shared-core/nouveau_drm.h @@ -0,0 +1,119 @@ +/* + * Copyright 2005 Stephane Marchesin. + * 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. + */ + +#ifndef __NOUVEAU_DRM_H__ +#define __NOUVEAU_DRM_H__ + +typedef struct drm_nouveau_fifo_init { + int channel; + uint32_t put_base; + /* FIFO control regs */ + drm_handle_t ctrl; + int ctrl_size; + /* DMA command buffer */ + drm_handle_t cmdbuf; + int cmdbuf_size; +} +drm_nouveau_fifo_init_t; + +typedef struct drm_nouveau_object_init { + uint32_t handle; + int class; + uint32_t flags0, flags1, flags2; + /* these are object handles */ + uint32_t dma0; + uint32_t dma1; + uint32_t dma_notifier; +} +drm_nouveau_object_init_t; + +typedef struct drm_nouveau_dma_object_init { + uint32_t handle; + int access; + int target; + uint32_t offset; + int size; +} +drm_nouveau_dma_object_init_t; + +#define NOUVEAU_MEM_FB 0x00000001 +#define NOUVEAU_MEM_AGP 0x00000002 +#define NOUVEAU_MEM_FB_ACCEPTABLE 0x00000004 +#define NOUVEAU_MEM_AGP_ACCEPTABLE 0x00000008 +#define NOUVEAU_MEM_PINNED 0x00000010 +#define NOUVEAU_MEM_USER_BACKED 0x00000020 +#define NOUVEAU_MEM_MAPPED 0x00000040 + +typedef struct drm_nouveau_mem_alloc { + int flags; + int alignment; + uint64_t size; // in bytes + uint64_t __user *region_offset; +} +drm_nouveau_mem_alloc_t; + +typedef struct drm_nouveau_mem_free { + int flags; + uint64_t region_offset; +} +drm_nouveau_mem_free_t; + +enum nouveau_card_type { + NV_UNKNOWN =0, + NV_01 =1, + NV_03 =3, + NV_04 =4, + NV_05 =5, + NV_10 =10, + NV_20 =20, + NV_30 =30, + NV_40 =40, + G_70 =50, + NV_LAST =0xffff, +}; + +enum nouveau_bus_type { + NV_AGP =0, + NV_PCI =1, + NV_PCIE =2, +}; + +#define NOUVEAU_MAX_SAREA_CLIPRECTS 16 + +typedef struct drm_nouveau_sarea { + /* the cliprects */ + drm_clip_rect_t boxes[NOUVEAU_MAX_SAREA_CLIPRECTS]; + unsigned int nbox; +} +drm_nouveau_sarea_t; + +#define DRM_NOUVEAU_FIFO_INIT 0x00 +#define DRM_NOUVEAU_PFIFO_REINIT 0x01 +#define DRM_NOUVEAU_OBJECT_INIT 0x02 +#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x03 // We don't want this eventually.. +#define DRM_NOUVEAU_MEM_ALLOC 0x04 +#define DRM_NOUVEAU_MEM_FREE 0x05 + +#endif /* __NOUVEAU_DRM_H__ */ + diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h new file mode 100644 index 00000000..c4f9718d --- /dev/null +++ b/shared-core/nouveau_drv.h @@ -0,0 +1,168 @@ +/* + * Copyright 2005 Stephane Marchesin. + * 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. + */ + +#ifndef __NOUVEAU_DRV_H__ +#define __NOUVEAU_DRV_H__ + +#define DRIVER_AUTHOR "Stephane Marchesin" +#define DRIVER_EMAIL "dri-devel@lists.sourceforge.net" + +#define DRIVER_NAME "nouveau" +#define DRIVER_DESC "nVidia Riva/TNT/GeForce" +#define DRIVER_DATE "20060213" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define NOUVEAU_FAMILY 0x0000FFFF +#define NOUVEAU_FLAGS 0xFFFF0000 + +#include "nouveau_drm.h" +#include "nouveau_reg.h" + +enum nouveau_flags { + NV_NFORCE =0x10000000, + NV_NFORCE2 =0x20000000 +}; + +struct nouveau_object +{ + struct nouveau_object *next; + struct nouveau_object *prev; + + uint32_t handle; + int class; + int engine; + uint32_t instance; + uint32_t ht_loc; +}; + +#define NV_DMA_TARGET_VIDMEM 0 +#define NV_DMA_TARGET_PCI 2 +#define NV_DMA_TARGET_AGP 3 +struct nouveau_fifo +{ + int used; + /* owner of this fifo */ + DRMFILE filp; + /* mapping of the fifo itself */ + drm_local_map_t *map; + /* mapping of the regs controling the fifo */ + drm_local_map_t *regs; + /* objects belonging to this fifo */ + struct nouveau_object *objs; +}; + +struct nouveau_object_store +{ + int ht_bits; + int ht_size; + int ht_base; + + uint32_t *inst_bmap; + uint32_t first_instance; + int num_instance; + int free_instance; +}; + +struct mem_block { + struct mem_block *next; + struct mem_block *prev; + uint64_t start; + uint64_t size; + DRMFILE filp; /* 0: free, -1: heap, other: real files */ + int flags; + drm_local_map_t *map; +}; + +typedef struct drm_nouveau_private { + /* the card type, takes NV_* as values */ + int card_type; + int flags; + + drm_local_map_t *mmio; + drm_local_map_t *fb; + + int64_t fb_usable_size; + + int cur_fifo; + + struct nouveau_object *fb_obj; + struct nouveau_object *cmdbuf_obj; + int cmdbuf_location; + int cmdbuf_base; + int cmdbuf_ch_size; + struct mem_block* cmdbuf_alloc; + + struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; + struct nouveau_object_store objs; + + struct mem_block *agp_heap; + struct mem_block *fb_heap; + struct mem_block *fb_nomap_heap; + +} +drm_nouveau_private_t; + +/* nouveau_state.c */ +extern void nouveau_preclose(drm_device_t * dev, DRMFILE filp); +extern int nouveau_load(struct drm_device *dev, unsigned long flags); +extern int nouveau_firstopen(struct drm_device *dev); +extern int nouveau_unload(struct drm_device *dev); + +/* nouveau_mem.c */ +extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev); +extern void nouveau_mem_release(DRMFILE filp, struct mem_block *heap); +extern int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS); +extern int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS); +extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, int flags, DRMFILE filp); +extern void nouveau_mem_free(struct drm_device* dev, struct mem_block*); +extern int nouveau_mem_init(struct drm_device *dev); +extern void nouveau_mem_close(struct drm_device *dev); + +/* nouveau_fifo.c */ +extern int nouveau_fifo_number(drm_device_t *dev); +extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp); +extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp); + +/* nouveau_object.c */ +extern void nouveau_hash_table_init(drm_device_t *dev); +extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp); +extern struct nouveau_object *nouveau_dma_object_create(drm_device_t *dev, + uint32_t offset, uint32_t size, int access, uint32_t target); +extern int nouveau_ioctl_object_init(DRM_IOCTL_ARGS); +extern int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS); + +/* nouveau_irq.c */ +extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); +extern void nouveau_irq_preinstall(drm_device_t*); +extern void nouveau_irq_postinstall(drm_device_t*); +extern void nouveau_irq_uninstall(drm_device_t*); + +#define NV_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) +#define NV_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) + +#endif /* __NOUVEAU_DRV_H__ */ + diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c new file mode 100644 index 00000000..18ad7c5f --- /dev/null +++ b/shared-core/nouveau_fifo.c @@ -0,0 +1,270 @@ +/* + * Copyright 2005-2006 Stephane Marchesin + * 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 + * PRECISION INSIGHT 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. + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + + +/* returns the number of hw fifos */ +int nouveau_fifo_number(drm_device_t* dev) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + switch(dev_priv->card_type) + { + case NV_03: + return 8; + case NV_04: + case NV_05: + return 16; + default: + return 32; + } +} + +/* setup the fifo enable register */ +static void nouveau_fifo_enable(drm_device_t* dev) +{ + int i; + unsigned enable_val=0; + drm_nouveau_private_t *dev_priv = dev->dev_private; + + for(i=31;i>=0;i--) + { + enable_val<<=1; + if (dev_priv->fifos[i].used) + enable_val|=1; + } + DRM_DEBUG("enable_val=0x%08x\n", enable_val); + NV_WRITE(NV03_FIFO_ENABLE,enable_val); +} + +/*********************************** + * functions doing the actual work + ***********************************/ + +/* voir nv_xaa.c : NVResetGraphics + * mémoire mappée par nv_driver.c : NVMapMem + * voir nv_driver.c : NVPreInit + */ + +/* initializes a fifo */ +static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DRMFILE filp) +{ + int i; + int ret; + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* + * Alright, here is the full story + * Nvidia cards have multiple hw fifo contexts (praise them for that, + * no complicated crash-prone context switches) + * X always uses context 0 (0x00800000) + * We allocate a new context for each app and let it write to it directly + * (woo, full userspace command submission !) + * When there are no more contexts, you lost + */ + for(i=0;ififos[i].used==0) + { + dev_priv->fifos[i].used=1; + break; + } + + /* no more fifos. you lost. */ + if (i==nouveau_fifo_number(dev)) + return DRM_ERR(EINVAL); + + /* that fifo is used */ + dev_priv->fifos[i].used=1; + dev_priv->fifos[i].filp=filp; + + /* enable the fifo */ + nouveau_fifo_enable(dev); + + /* make the fifo available to user space */ + init->channel = i; + init->put_base = i*dev_priv->cmdbuf_ch_size; + + NV_WRITE(NV03_FIFO_REGS_DMAPUT(i), init->put_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(i), init->put_base); + + /* first, the fifo control regs */ + init->ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(i); + init->ctrl_size = NV03_FIFO_REGS_SIZE; + ret = drm_addmap(dev, init->ctrl, init->ctrl_size, _DRM_REGISTERS, + 0, &dev_priv->fifos[i].regs); + if (ret != 0) + return ret; + + /* then, the fifo itself */ + init->cmdbuf = dev_priv->cmdbuf_base; + init->cmdbuf += init->channel * dev_priv->cmdbuf_ch_size; + init->cmdbuf_size = dev_priv->cmdbuf_ch_size; + ret = drm_addmap(dev, init->cmdbuf, init->cmdbuf_size, _DRM_REGISTERS, + 0, &dev_priv->fifos[i].map); + if (ret != 0) + return ret; + + /* FIFO has no objects yet */ + dev_priv->fifos[i].objs = NULL; + + DRM_DEBUG("%s: initialised FIFO %d\n", __func__, i); + dev_priv->cur_fifo = i; + return 0; +} +static void nouveau_pfifo_init(drm_device_t* dev); + +/* cleanups all the fifos from filp */ +void nouveau_fifo_cleanup(drm_device_t * dev, DRMFILE filp) +{ + int i; + drm_nouveau_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("clearing FIFO enables from filp\n"); + for(i=0;ififos[i].filp==filp) + dev_priv->fifos[i].used=0; + + if (dev_priv->cur_fifo == i) { + DRM_DEBUG("%s: cur_fifo is no longer owned.\n", __func__); + for (i=0;ififos[i].used) break; + if (i==nouveau_fifo_number(dev)) + i=0; + DRM_DEBUG("%s: new cur_fifo is %d\n", __func__, i); + dev_priv->cur_fifo = i; + } + + nouveau_pfifo_init(dev); +// nouveau_fifo_enable(dev); +} + +int nouveau_fifo_id_get(drm_device_t* dev, DRMFILE filp) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + int i; + + for(i=0;ififos[i].filp == filp) + return i; + return -1; +} + +static void nouveau_pfifo_init(drm_device_t* dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* Init PFIFO - This is an exact copy of what's done in the Xorg ddx so far. + * We should be able to figure out what's happening from the + * resources available.. + */ + + if (dev->irq_enabled) + nouveau_irq_postinstall(dev); + + if (dev_priv->card_type >= NV_40) + NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4); + + DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo); + + NV_WRITE(NV_PFIFO_CACHES, 0x00000000); + nouveau_fifo_enable(dev); + + NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); + if (dev_priv->card_type >= NV_40) + NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo); + else + NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo); + NV_WRITE(NV_PFIFO_CACH1_DMAP, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); + NV_WRITE(NV_PFIFO_CACH1_DMAG, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); + NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); + NV_WRITE(NV_PFIFO_CACH0_PSH0, 0x00000000); + NV_WRITE(NV_PFIFO_CACH0_PUL0, 0x00000000); + NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); + NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); + NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000); +#ifdef __BIG_ENDIAN + NV_WRITE(NV_PFIFO_CACH1_DMAF, 0x800F0078); +#else + NV_WRITE(NV_PFIFO_CACH1_DMAF, 0x000F0078); +#endif + NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001); + + NV_WRITE(NV_PFIFO_CACHES, 0x00000001); + + DRM_DEBUG("%s: CACHE1 GET/PUT readback %d/%d\n", __func__, + NV_READ(NV_PFIFO_CACH1_DMAG), + NV_READ(NV_PFIFO_CACH1_DMAP)); +} + +/*********************************** + * ioctls wrapping the functions + ***********************************/ + +static int nouveau_ioctl_fifo_init(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_nouveau_fifo_init_t init; + int res; + DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_init_t __user *) data, sizeof(init)); + + res=nouveau_fifo_init(dev,&init,filp); + if (!res) + DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_init_t __user *)data, init, sizeof(init)); + + return res; +} + +static int nouveau_ioctl_fifo_reinit(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + + nouveau_pfifo_init(dev); + return 0; +} + +/*********************************** + * finally, the ioctl table + ***********************************/ + +drm_ioctl_desc_t nouveau_ioctls[] = { + [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_INIT)] = {nouveau_ioctl_fifo_init, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_PFIFO_REINIT)] = {nouveau_ioctl_fifo_reinit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_OBJECT_INIT)] = {nouveau_ioctl_object_init, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_DMA_OBJECT_INIT)] = {nouveau_ioctl_dma_object_init, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_FREE)] = {nouveau_ioctl_mem_free, DRM_AUTH}, +}; + +int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); + + diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c new file mode 100644 index 00000000..d4691293 --- /dev/null +++ b/shared-core/nouveau_irq.c @@ -0,0 +1,208 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drm.h" +#include "nouveau_drv.h" +#include "nouveau_reg.h" + +void nouveau_irq_preinstall(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("IRQ: preinst\n"); + + /* Disable/Clear PFIFO interrupts */ + NV_WRITE(NV_PFIFO_INTEN, 0); + NV_WRITE(NV_PFIFO_INTSTAT, 0xFFFFFFFF); + /* Disable/Clear PGRAPH interrupts */ + NV_WRITE(NV_PGRAPH_INTEN, 0); + NV_WRITE(NV_PGRAPH_INTSTAT, 0xFFFFFFFF); +#if 0 + /* Disable/Clear CRTC0/1 interrupts */ + NV_WRITE(NV_CRTC0_INTEN, 0); + NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); + NV_WRITE(NV_CRTC1_INTEN, 0); + NV_WRITE(NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); +#endif + /* Master disable */ + NV_WRITE(NV_PMC_INTEN, 0); +} + +void nouveau_irq_postinstall(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("IRQ: postinst\n"); + + /* Enable PFIFO error reporting */ + NV_WRITE(NV_PFIFO_INTEN , NV_PFIFO_INTR_ERROR); + NV_WRITE(NV_PFIFO_INTSTAT, 0xFFFFFFFF); + + /* Enable PGRAPH interrupts */ + NV_WRITE(NV_PGRAPH_INTEN, + NV_PGRAPH_INTR_NOTIFY | + NV_PGRAPH_INTR_MISSING_HW | + NV_PGRAPH_INTR_BUFFER_NOTIFY | + NV_PGRAPH_INTR_ERROR + ); + NV_WRITE(NV_PGRAPH_INTSTAT, 0xFFFFFFFF); + +#if 0 + /* Enable CRTC0/1 interrupts */ + NV_WRITE(NV_CRTC0_INTEN, NV_CRTC_INTR_VBLANK); + NV_WRITE(NV_CRTC1_INTEN, NV_CRTC_INTR_VBLANK); +#endif + + /* Master enable */ + NV_WRITE(NV_PMC_INTEN, NV_PMC_INTEN_MASTER_ENABLE); +} + +void nouveau_irq_uninstall(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("IRQ: uninst\n"); + + /* Disable PFIFO interrupts */ + NV_WRITE(NV_PFIFO_INTEN, 0); + /* Disable PGRAPH interrupts */ + NV_WRITE(NV_PGRAPH_INTEN, 0); +#if 0 + /* Disable CRTC0/1 interrupts */ + NV_WRITE(NV_CRTC0_INTEN, 0); + NV_WRITE(NV_CRTC1_INTEN, 0); +#endif + /* Master disable */ + NV_WRITE(NV_PMC_INTEN, 0); +} + +void nouveau_fifo_irq_handler(drm_nouveau_private_t *dev_priv) +{ + uint32_t status, chmode, chstat; + + status = NV_READ(NV_PFIFO_INTSTAT); + if (!status) + return; + chmode = NV_READ(NV_PFIFO_MODE); + chstat = NV_READ(0x2508); + + DRM_DEBUG("NV: PFIFO interrupt! INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", + status, chmode, chstat); + + if (status & NV_PFIFO_INTR_ERROR) { + DRM_ERROR("NV: PFIFO error interrupt\n"); + + status &= ~NV_PFIFO_INTR_ERROR; + NV_WRITE(NV_PFIFO_INTSTAT, NV_PFIFO_INTR_ERROR); + } + + if (status) { + DRM_INFO("NV: unknown PFIFO interrupt. status=0x%08x\n", status); + + NV_WRITE(NV_PFIFO_INTSTAT, status); + } + + NV_WRITE(NV_PMC_INTSTAT, NV_PMC_INTSTAT_PFIFO_PENDING); +} + +void nouveau_pgraph_irq_handler(drm_nouveau_private_t *dev_priv) +{ + uint32_t status; + + status = NV_READ(NV_PGRAPH_INTSTAT); + if (!status) + return; + + if (status & NV_PGRAPH_INTR_NOTIFY) { + uint32_t nsource, nstatus, instance, notify; + DRM_DEBUG("NV: PGRAPH notify interrupt\n"); + + nstatus = NV_READ(0x00400104); + nsource = NV_READ(0x00400108); + DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus); + + instance = NV_READ(0x00400158); + notify = NV_READ(0x00400150) >> 16; + DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", nsource, nstatus); + + status &= ~NV_PGRAPH_INTR_NOTIFY; + NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_NOTIFY); + } + + if (status & NV_PGRAPH_INTR_BUFFER_NOTIFY) { + uint32_t nsource, nstatus, instance, notify; + DRM_DEBUG("NV: PGRAPH buffer notify interrupt\n"); + + nstatus = NV_READ(0x00400104); + nsource = NV_READ(0x00400108); + DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus); + + instance = NV_READ(0x00400158); + notify = NV_READ(0x00400150) >> 16; + DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", nsource, nstatus); + + status &= ~NV_PGRAPH_INTR_BUFFER_NOTIFY; + NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_BUFFER_NOTIFY); + } + + if (status & NV_PGRAPH_INTR_MISSING_HW) { + DRM_ERROR("NV: PGRAPH missing hw interrupt\n"); + + status &= ~NV_PGRAPH_INTR_MISSING_HW; + NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_MISSING_HW); + } + + if (status & NV_PGRAPH_INTR_ERROR) { + DRM_ERROR("NV: PGRAPH error interrupt\n"); + + status &= ~NV_PGRAPH_INTR_ERROR; + NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_ERROR); + } + + if (status) { + DRM_INFO("NV: Unknown PGRAPH interrupt! STAT=0x%08x\n", status); + NV_WRITE(NV_PGRAPH_INTSTAT, status); + } + + NV_WRITE(NV_PMC_INTSTAT, NV_PMC_INTSTAT_PGRAPH_PENDING); +} + +void nouveau_crtc_irq_handler(drm_nouveau_private_t *dev_priv, int crtc) +{ + 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) +{ + drm_device_t *dev = (drm_device_t*)arg; + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t status; + + status = NV_READ(NV_PMC_INTSTAT); + + DRM_DEBUG("PMC INTSTAT: 0x%08x\n", status); + + if (status & NV_PMC_INTSTAT_PFIFO_PENDING) { + nouveau_fifo_irq_handler(dev_priv); + status &= ~NV_PMC_INTSTAT_PFIFO_PENDING; + } + if (status & NV_PMC_INTSTAT_PGRAPH_PENDING) { + nouveau_pgraph_irq_handler(dev_priv); + status &= ~NV_PMC_INTSTAT_PGRAPH_PENDING; + } + if (status & NV_PMC_INTSTAT_CRTCn_PENDING) { + nouveau_crtc_irq_handler(dev_priv, (status>>24)&3); + status &= ~NV_PMC_INTSTAT_CRTCn_PENDING; + } + + if (status) + DRM_ERROR("Unhandled PMC INTR status bits 0x%08x\n", status); + + return IRQ_HANDLED; +} + diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c new file mode 100644 index 00000000..91fc6046 --- /dev/null +++ b/shared-core/nouveau_mem.c @@ -0,0 +1,503 @@ +/* + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * Copyright 2005 Stephane Marchesin + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * 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 + * THE AUTHORS AND/OR THEIR 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "drmP.h" +#include "drm.h" +#include "drm_sarea.h" +#include "nouveau_drv.h" + +static int meminit_ok=0; + +static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size, + DRMFILE filp) +{ + /* Maybe cut off the start of an existing block */ + if (start > p->start) { + struct mem_block *newblock = + drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); + if (!newblock) + goto out; + newblock->start = start; + newblock->size = p->size - (start - p->start); + newblock->filp = NULL; + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + p->size -= newblock->size; + p = newblock; + } + + /* Maybe cut off the end of an existing block */ + if (size < p->size) { + struct mem_block *newblock = + drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); + if (!newblock) + goto out; + newblock->start = start + size; + newblock->size = p->size - size; + newblock->filp = NULL; + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + p->size = size; + } + +out: + /* Our block is in the middle */ + p->filp = filp; + return p; +} + +static struct mem_block *alloc_block(struct mem_block *heap, uint64_t size, + int align2, DRMFILE filp) +{ + struct mem_block *p; + uint64_t mask = (1 << align2) - 1; + + if (!heap) + return NULL; + + list_for_each(p, heap) { + uint64_t start = (p->start + mask) & ~mask; + if (p->filp == 0 && start + size <= p->start + p->size) + return split_block(p, start, size, filp); + } + + return NULL; +} + +static struct mem_block *find_block(struct mem_block *heap, uint64_t start) +{ + struct mem_block *p; + + list_for_each(p, heap) + if (p->start == start) + return p; + + return NULL; +} + +static void free_block(struct mem_block *p) +{ + p->filp = NULL; + + /* Assumes a single contiguous range. Needs a special filp in + * 'heap' to stop it being subsumed. + */ + if (p->next->filp == 0) { + struct mem_block *q = p->next; + p->size += q->size; + p->next = q->next; + p->next->prev = p; + drm_free(q, sizeof(*q), DRM_MEM_BUFS); + } + + if (p->prev->filp == 0) { + struct mem_block *q = p->prev; + q->size += p->size; + q->next = p->next; + q->next->prev = q; + drm_free(p, sizeof(*q), DRM_MEM_BUFS); + } +} + +/* Initialize. How to check for an uninitialized heap? + */ +static int init_heap(struct mem_block **heap, uint64_t start, uint64_t size) +{ + struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); + + if (!blocks) + return DRM_ERR(ENOMEM); + + *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); + if (!*heap) { + drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); + return DRM_ERR(ENOMEM); + } + + blocks->start = start; + blocks->size = size; + blocks->filp = NULL; + blocks->next = blocks->prev = *heap; + + memset(*heap, 0, sizeof(**heap)); + (*heap)->filp = (DRMFILE) - 1; + (*heap)->next = (*heap)->prev = blocks; + return 0; +} + +/* + * Free all blocks associated with the releasing filp + */ +void nouveau_mem_release(DRMFILE filp, struct mem_block *heap) +{ + struct mem_block *p; + + if (!heap || !heap->next) + return; + + list_for_each(p, heap) { + if (p->filp == filp) + p->filp = NULL; + } + + /* Assumes a single contiguous range. Needs a special filp in + * 'heap' to stop it being subsumed. + */ + list_for_each(p, heap) { + while ((p->filp == 0) && (p->next->filp == 0) && (p->next!=heap)) { + struct mem_block *q = p->next; + p->size += q->size; + p->next = q->next; + p->next->prev = p; + drm_free(q, sizeof(*q), DRM_MEM_DRIVER); + } + } +} + +/* + * Cleanup everything + */ +static void nouveau_mem_takedown(struct mem_block **heap) +{ + struct mem_block *p; + + if (!*heap) + return; + + for (p = (*heap)->next; p != *heap;) { + struct mem_block *q = p; + p = p->next; + drm_free(q, sizeof(*q), DRM_MEM_DRIVER); + } + + drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER); + *heap = NULL; +} + +void nouveau_mem_close(struct drm_device *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + nouveau_mem_takedown(&dev_priv->agp_heap); + nouveau_mem_takedown(&dev_priv->fb_heap); +} + +/* returns the amount of FB ram in bytes */ +uint64_t nouveau_mem_fb_amount(struct drm_device *dev) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + switch(dev_priv->card_type) + { + case NV_03: + switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT) + { + case NV03_BOOT_0_RAM_AMOUNT_8MB: + case NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM: + return 8*1024*1024; + case NV03_BOOT_0_RAM_AMOUNT_4MB: + return 4*1024*1024; + case NV03_BOOT_0_RAM_AMOUNT_2MB: + return 2*1024*1024; + } + break; + case NV_04: + case NV_05: + switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT) + { + case NV04_BOOT_0_RAM_AMOUNT_32MB: + return 32*1024*1024; + case NV04_BOOT_0_RAM_AMOUNT_16MB: + return 16*1024*1024; + case NV04_BOOT_0_RAM_AMOUNT_8MB: + return 8*1024*1024; + case NV04_BOOT_0_RAM_AMOUNT_4MB: + return 4*1024*1024; + } + break; + case NV_10: + case NV_20: + case NV_30: + case NV_40: + case G_70: + default: + // XXX won't work on BSD because of pci_read_config_dword + if (dev_priv->flags&NV_NFORCE) { + uint32_t mem; + pci_read_config_dword(dev->pdev, 0x7C, &mem); + return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; + } else if(dev_priv->flags&NV_NFORCE2) { + uint32_t mem; + pci_read_config_dword(dev->pdev, 0x84, &mem); + return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; + } else { + uint64_t mem; + mem=(NV_READ(NV04_FIFO_DATA)&NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; + return mem*1024*1024; + } + break; + } + + DRM_ERROR("Unable to detect video ram size. Please report your setup to " DRIVER_EMAIL "\n"); + return 0; +} + + + +int nouveau_mem_init(struct drm_device *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* init AGP */ + dev_priv->agp_heap=NULL; + if (drm_device_is_agp(dev)) + { + int err; + drm_agp_info_t info; + drm_agp_mode_t mode; + drm_agp_buffer_t agp_req; + drm_agp_binding_t bind_req; + + err = drm_agp_acquire(dev); + if (err) { + DRM_ERROR("Unable to acquire AGP: %d\n", err); + goto no_agp; + } + + err = drm_agp_info(dev, &info); + if (err) { + DRM_ERROR("Unable to get AGP info: %d\n", err); + goto no_agp; + } + + /* see agp.h for the AGPSTAT_* modes available */ + mode.mode = info.mode; + err = drm_agp_enable(dev, mode); + if (err) { + DRM_ERROR("Unable to enable AGP: %d\n", err); + goto no_agp; + } + + agp_req.size = info.aperture_size; + agp_req.type = 0; + err = drm_agp_alloc(dev, &agp_req); + if (err) { + DRM_ERROR("Unable to alloc AGP: %d\n", err); + goto no_agp; + } + + bind_req.handle = agp_req.handle; + bind_req.offset = 0; + err = drm_agp_bind(dev, &bind_req); + if (err) { + DRM_ERROR("Unable to bind AGP: %d\n", err); + goto no_agp; + } + + if (init_heap(&dev_priv->agp_heap, info.aperture_base, info.aperture_size)) + goto no_agp; + } +no_agp: + + /* Init FB */ + if (nouveau_mem_fb_amount(dev)>256*1024*1024) { + /* On cards with > 256Mb, you can't map everything. + * So we create a second FB heap for that type of memory */ + if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), 256*1024*1024)) + return DRM_ERR(ENOMEM); + if (init_heap(&dev_priv->fb_nomap_heap, drm_get_resource_start(dev,1)+256*1024*1024, nouveau_mem_fb_amount(dev)-256*1024*1024)) + return DRM_ERR(ENOMEM); + } else { + if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), nouveau_mem_fb_amount(dev))) + return DRM_ERR(ENOMEM); + dev_priv->fb_nomap_heap=NULL; + } + + return 0; +} + +struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, int flags, DRMFILE filp) +{ + struct mem_block *block; + int type; + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* + * Init memory if needed + */ + if (meminit_ok==0) + { + nouveau_mem_init(dev); + meminit_ok=1; + } + + /* + * Make things easier on ourselves: all allocations are page-aligned. + * We need that to map allocated regions into the user space + */ + if (alignment < PAGE_SHIFT) + alignment = PAGE_SHIFT; + + /* + * Warn about 0 sized allocations, but let it go through. It'll return 1 page + */ + if (size == 0) + DRM_INFO("warning : 0 byte allocation\n"); + + /* + * Keep alloc size a multiple of the page size to keep drm_addmap() happy + */ + if (size & (~PAGE_MASK)) + size = ((size/PAGE_SIZE) + 1) * PAGE_SIZE; + + if (flags&NOUVEAU_MEM_AGP) { + type=NOUVEAU_MEM_AGP; + block = alloc_block(dev_priv->agp_heap, size, alignment, filp); + if (block) goto alloc_ok; + } + if (flags&(NOUVEAU_MEM_FB|NOUVEAU_MEM_FB_ACCEPTABLE)) { + type=NOUVEAU_MEM_FB; + if (!(flags&NOUVEAU_MEM_MAPPED)) { + block = alloc_block(dev_priv->fb_nomap_heap, size, alignment, filp); + if (block) goto alloc_ok; + } + block = alloc_block(dev_priv->fb_heap, size, alignment, filp); + if (block) goto alloc_ok; + } + if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) { + type=NOUVEAU_MEM_AGP; + block = alloc_block(dev_priv->agp_heap, size, alignment, filp); + if (block) goto alloc_ok; + } + + return NULL; + +alloc_ok: + block->flags=type; + + if (flags&NOUVEAU_MEM_MAPPED) + { + int ret; + block->flags|=NOUVEAU_MEM_MAPPED; + + if (type == NOUVEAU_MEM_AGP) + ret = drm_addmap(dev, block->start - dev->agp->base, block->size, + _DRM_AGP, 0, &block->map); + else + ret = drm_addmap(dev, block->start, block->size, + _DRM_FRAME_BUFFER, 0, &block->map); + if (ret) { + free_block(block); + return NULL; + } + } + + DRM_INFO("allocated 0x%llx\n", block->start); + return block; +} + +void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) +{ + DRM_INFO("freeing 0x%llx\n", block->start); + if (meminit_ok==0) + { + DRM_ERROR("%s called without init\n", __FUNCTION__); + return; + } + if (block->flags&NOUVEAU_MEM_MAPPED) + drm_rmmap(dev, block->map); + free_block(block); +} + +/* + * Ioctls + */ + +int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_nouveau_private_t *dev_priv = dev->dev_private; + drm_nouveau_mem_alloc_t alloc; + struct mem_block *block; + + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL(alloc, (drm_nouveau_mem_alloc_t __user *) data, + sizeof(alloc)); + + block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); + if (!block) + return DRM_ERR(ENOMEM); + + if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(uint64_t))) { + DRM_ERROR("copy_to_user\n"); + return DRM_ERR(EFAULT); + } + + return 0; +} + +int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_nouveau_private_t *dev_priv = dev->dev_private; + drm_nouveau_mem_free_t memfree; + struct mem_block *block; + + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL(memfree, (drm_nouveau_mem_free_t __user *) data, + sizeof(memfree)); + + block=NULL; + if (memfree.flags&NOUVEAU_MEM_FB) + block = find_block(dev_priv->fb_heap, memfree.region_offset); + else if (memfree.flags&NOUVEAU_MEM_AGP) + block = find_block(dev_priv->agp_heap, memfree.region_offset); + if (!block) + return DRM_ERR(EFAULT); + if (block->filp != filp) + return DRM_ERR(EPERM); + + nouveau_mem_free(dev, block); + return 0; +} + + diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c new file mode 100644 index 00000000..fb30d529 --- /dev/null +++ b/shared-core/nouveau_object.c @@ -0,0 +1,565 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +/* TODO + * - Check object class, deny unsafe objects (add card-specific versioning?) + * - Get rid of DMA object creation, this should be wrapped by MM routines. + */ + +static void nouveau_object_link(drm_device_t *dev, int fifo_num, + struct nouveau_object *obj) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_fifo *fifo = &dev_priv->fifos[fifo_num]; + + if (!fifo->objs) { + fifo->objs = obj; + return; + } + + obj->prev = NULL; + obj->next = fifo->objs; + + fifo->objs->prev = obj; + fifo->objs = obj; +} + +static void nouveau_object_unlink(drm_device_t *dev, int fifo_num, + struct nouveau_object *obj) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_fifo *fifo = &dev_priv->fifos[fifo_num]; + + if (obj->prev == NULL) { + if (obj->next) + obj->next->prev = NULL; + fifo->objs = obj->next; + } else if (obj->next == NULL) { + if (obj->prev) + obj->prev->next = NULL; + } else { + obj->prev->next = obj->next; + obj->next->prev = obj->prev; + } +} + +static struct nouveau_object * +nouveau_object_handle_find(drm_device_t *dev, int fifo_num, uint32_t handle) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_fifo *fifo = &dev_priv->fifos[fifo_num]; + struct nouveau_object *obj = fifo->objs; + + if (!handle) + return NULL; + + DRM_DEBUG("Looking for handle 0x%08x\n", handle); + while (obj) { + if (obj->handle == handle) + return obj; + obj = obj->next; + } + + DRM_DEBUG("...couldn't find handle\n"); + return NULL; +} + +/* NVidia uses context objects to drive drawing operations. + + Context objects can be selected into 8 subchannels in the FIFO, + and then used via DMA command buffers. + + A context object is referenced by a user defined handle (CARD32). The HW + looks up graphics objects in a hash table in the instance RAM. + + An entry in the hash table consists of 2 CARD32. The first CARD32 contains + the handle, the second one a bitfield, that contains the address of the + object in instance RAM. + + The format of the second CARD32 seems to be: + + NV4 to NV30: + + 15: 0 instance_addr >> 4 + 17:16 engine (here uses 1 = graphics) + 28:24 channel id (here uses 0) + 31 valid (use 1) + + NV40: + + 15: 0 instance_addr >> 4 (maybe 19-0) + 21:20 engine (here uses 1 = graphics) + I'm unsure about the other bits, but using 0 seems to work. + + The key into the hash table depends on the object handle and channel id and + is given as: +*/ +static uint32_t nouveau_handle_hash(drm_device_t* dev, uint32_t handle, + int fifo) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_object_store *objs=&dev_priv->objs; + uint32_t hash = 0; + int i; + + for (i=32;i>0;i-=objs->ht_bits) { + hash ^= (handle & ((1 << objs->ht_bits) - 1)); + handle >>= objs->ht_bits; + } + hash ^= fifo << (objs->ht_bits - 4); + return hash << 3; +} + +static int nouveau_hash_table_insert(drm_device_t* dev, int fifo, + struct nouveau_object *obj) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_object_store *objs=&dev_priv->objs; + int ht_base = NV_RAMIN + objs->ht_base; + int ht_end = ht_base + objs->ht_size; + int o_ofs, ofs; + + o_ofs = ofs = nouveau_handle_hash(dev, obj->handle, fifo); + + while (NV_READ(ht_base + ofs)) { + ofs += 8; + if (ofs == ht_end) ofs = ht_base; + if (ofs == o_ofs) { + DRM_ERROR("no free hash table entries\n"); + return 1; + } + } + ofs += ht_base; + + DRM_DEBUG("Channel %d - Handle 0x%08x at 0x%08x\n", + fifo, obj->handle, ofs); + + NV_WRITE(NV_RAMHT_HANDLE_OFFSET + ofs, obj->handle); + if (dev_priv->card_type >= NV_40) + NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, + (fifo << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | + (obj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT) | + (obj->instance>>4) + ); + else + NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, + NV_RAMHT_CONTEXT_VALID | + (fifo << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | + (obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT) | + (obj->instance>>4) + ); + + obj->ht_loc = ofs; + return 0; +} + +static void nouveau_hash_table_remove(drm_device_t* dev, + struct nouveau_object *obj) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("Remove handle 0x%08x at 0x%08x from HT\n", + obj->handle, obj->ht_loc); + if (obj->ht_loc) { + DRM_DEBUG("... HT entry was: 0x%08x/0x%08x\n", + NV_READ(obj->ht_loc), NV_READ(obj->ht_loc+4)); + NV_WRITE(obj->ht_loc , 0x00000000); + NV_WRITE(obj->ht_loc+4, 0x00000000); + } +} + +static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_object_store *objs=&dev_priv->objs; + struct nouveau_object *obj; + int instance = -1; + int i = 0, j = 0; + + /* Allocate a block of instance RAM */ + if (!objs->free_instance) { + DRM_ERROR("no free instance ram\n"); + return NULL; + } + for (i=0;i<(objs->num_instance>>5);i++) { + if (objs->inst_bmap[i] == ~0) continue; + for (j=0;j<32;j++) { + if (!(objs->inst_bmap[i] & (1<instance = objs->first_instance; + obj->instance += (instance << (dev_priv->card_type >= NV_40 ? 5 : 4)); + DRM_DEBUG("instance address is 0x%08x\n", instance); + + /* Mark instance slot as used */ + objs->inst_bmap[i] |= (1 << j); + objs->free_instance--; + + return obj; +} + +static void nouveau_object_instance_free(drm_device_t *dev, + struct nouveau_object *obj) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_object_store *objs=&dev_priv->objs; + int count, i; + uint32_t be, bb; + + if (dev_priv->card_type >= NV_40) + count = 8; + else + count = 4; + + DRM_DEBUG("Instance entry for 0x%08x" + "(engine %d, class 0x%x) before destroy:\n", + obj->handle, obj->engine, obj->class); + for (i=0;iinstance + (i*4))); + + /* Clean RAMIN entry */ + for (i=0;iinstance + (i*4), 0x00000000); + + /* Mark instance as free */ + obj->instance -= objs->first_instance; + obj->instance >>= (dev_priv->card_type >=NV_40 ? 5 : 4); + be = obj->instance / 32; + bb = obj->instance % 32; + objs->inst_bmap[be] &= ~bb; + objs->free_instance++; +} + +/* Where is the hash table located: + + Base address and size can be calculated from this register: + + ht_base = 0x1000 * GetBitField (pNv->PFIFO[0x0210/4],8:4); + ht_size = 0x1000 << GetBitField (pNv->PFIFO[0x0210/4],17:16); + + and the hash table will be located between address PRAMIN + ht_base and + PRAMIN + ht_base + ht_size. Each hash table entry has two longwords. +*/ +void nouveau_hash_table_init(drm_device_t* dev) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + int ht_start, ht_end; + int i; + + dev_priv->objs.ht_bits = 9; + dev_priv->objs.ht_base = 0x10000; + dev_priv->objs.ht_size = (1 << dev_priv->objs.ht_bits); + + NV_WRITE(NV_PFIFO_RAMHT, + (0x03 << 24) /* search 128 */ | + ((dev_priv->objs.ht_bits - 9) << 16) | + ((dev_priv->objs.ht_base >> 16) << 4) + ); + NV_WRITE(NV_PFIFO_RAMFC, 0x00000110); /* RAMIN+0x11000 0.5k */ + NV_WRITE(NV_PFIFO_RAMRO, 0x00000112); /* RAMIN+0x11200 0.5k */ + + dev_priv->objs.first_instance = 0x12000; + dev_priv->objs.free_instance = 1024; /*FIXME*/ + dev_priv->objs.num_instance = 1024; /*FIXME*/ + dev_priv->objs.inst_bmap = drm_calloc + (1, dev_priv->objs.num_instance/32, DRM_MEM_DRIVER); + + /* clear the hash table */ + ht_start = NV_RAMIN+dev_priv->objs.ht_base; + ht_end = ht_start + dev_priv->objs.ht_size; + for (i=ht_start; idev_private; + struct nouveau_object *obj; + uint32_t frame, adjust; + + DRM_DEBUG("offset:0x%08x, size:0x%08x, target:%d, access:%d\n", + offset, size, target, access); + + frame = offset & ~0x00000FFF; + adjust = offset & 0x00000FFF; + + obj = nouveau_instance_alloc(dev); + if (!obj) { + DRM_ERROR("couldn't allocate DMA object\n"); + return obj; + } + + obj->engine = 0; + obj->class = 0; + + NV_WRITE(NV_RAMIN + obj->instance + 0, ((1<<12) + | (1<<13) + | (adjust<<20) + | (access<<14) + | (target<<16) + | 2) + ); + NV_WRITE(NV_RAMIN + obj->instance + 4, + size - 1); + NV_WRITE(NV_RAMIN + obj->instance + 8, + frame | ((access != NV_DMA_ACCESS_RO) ? (1<<1) : 0)); + NV_WRITE(NV_RAMIN + obj->instance + 12, + 0xFFFFFFFF); + + return obj; +} + + +/* Context objects in the instance RAM have the following structure. + * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes. + + NV4 - NV30: + + entry[0] + 11:0 class + 12 chroma key enable + 13 user clip enable + 14 swizzle enable + 17:15 patch config: + scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre + 18 synchronize enable + 19 endian: 1 big, 0 little + 21:20 dither mode + 23 single step enable + 24 patch status: 0 invalid, 1 valid + 25 context_surface 0: 1 valid + 26 context surface 1: 1 valid + 27 context pattern: 1 valid + 28 context rop: 1 valid + 29,30 context beta, beta4 + entry[1] + 7:0 mono format + 15:8 color format + 31:16 notify instance address + entry[2] + 15:0 dma 0 instance address + 31:16 dma 1 instance address + entry[3] + dma method traps + + NV40: + No idea what the exact format is. Here's what can be deducted: + + entry[0]: + 11:0 class (maybe uses more bits here?) + 17 user clip enable + 21:19 patch config + 25 patch status valid ? + entry[1]: + 15:0 DMA notifier (maybe 20:0) + entry[2]: + 15:0 DMA 0 instance (maybe 20:0) + 24 big endian + entry[3]: + 15:0 DMA 1 instance (maybe 20:0) + entry[4]: + entry[5]: + set to 0? +*/ +static struct nouveau_object *nouveau_context_object_create(drm_device_t* dev, + int class, uint32_t flags0, uint32_t flags1, uint32_t flags2, + struct nouveau_object *dma0, + struct nouveau_object *dma1, + struct nouveau_object *dma_notifier) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_object *obj; + uint32_t d0, d1, dn; + + DRM_DEBUG("class=%x, dma0=%08x, dma1=%08x, dman=%08x\n", + class, + dma0 ? dma0->handle : 0, + dma1 ? dma1->handle : 0, + dma_notifier ? dma_notifier->handle : 0); + + obj = nouveau_instance_alloc(dev); + if (!obj) { + DRM_ERROR("couldn't allocate context object\n"); + return obj; + } + + obj->engine = 1; + obj->class = class; + + d0 = dma0 ? (dma0->instance >> 4) : 0; + d1 = dma1 ? (dma1->instance >> 4) : 0; + dn = dma_notifier ? (dma_notifier->instance >> 4) : 0; + + if (dev_priv->card_type >= NV_40) { + NV_WRITE(NV_RAMIN + obj->instance + 0, class | flags0); + NV_WRITE(NV_RAMIN + obj->instance + 4, dn | flags1); + NV_WRITE(NV_RAMIN + obj->instance + 8, d0 | flags2); + NV_WRITE(NV_RAMIN + obj->instance + 12, d1); + NV_WRITE(NV_RAMIN + obj->instance + 16, 0x00000000); + NV_WRITE(NV_RAMIN + obj->instance + 20, 0x00000000); + NV_WRITE(NV_RAMIN + obj->instance + 24, 0x00000000); + NV_WRITE(NV_RAMIN + obj->instance + 28, 0x00000000); + } else { + NV_WRITE(NV_RAMIN + obj->instance + 0, class | flags0); + NV_WRITE(NV_RAMIN + obj->instance + 4, (dn << 16) | flags1); + NV_WRITE(NV_RAMIN + obj->instance + 8, d0 | (d1 << 16)); + NV_WRITE(NV_RAMIN + obj->instance + 12, 0); + } + + return obj; +} + +static void +nouveau_object_free(drm_device_t *dev, int fifo_num, struct nouveau_object *obj) +{ + nouveau_object_unlink(dev, fifo_num, obj); + + nouveau_object_instance_free(dev, obj); + nouveau_hash_table_remove(dev, obj); + + drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER); + return; +} + +void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + int fifo; + + fifo = nouveau_fifo_id_get(dev, filp); + if (fifo == -1) + return; + + while (dev_priv->fifos[fifo].objs) + nouveau_object_free(dev, fifo, dev_priv->fifos[fifo].objs); +} + +int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_nouveau_object_init_t init; + struct nouveau_object *obj, *dma0, *dma1, *dman; + int fifo; + + fifo = nouveau_fifo_id_get(dev, filp); + + DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_object_init_t __user *) + data, sizeof(init)); + + //FIXME: check args, only allow trusted objects to be created + + if (nouveau_object_handle_find(dev, fifo, init.handle)) { + DRM_ERROR("Channel %d: handle 0x%08x already exists\n", + fifo, init.handle); + return DRM_ERR(EINVAL); + } + + dma0 = nouveau_object_handle_find(dev, fifo, init.dma0); + if (init.dma0 && !dma0) { + DRM_ERROR("context dma0 - invalid handle 0x%08x\n", init.dma0); + return DRM_ERR(EINVAL); + } + dma1 = nouveau_object_handle_find(dev, fifo, init.dma1); + if (init.dma1 && !dma1) { + DRM_ERROR("context dma1 - invalid handle 0x%08x\n", init.dma0); + return DRM_ERR(EINVAL); + } + dman = nouveau_object_handle_find(dev, fifo, init.dma_notifier); + if (init.dma_notifier && !dman) { + DRM_ERROR("context dman - invalid handle 0x%08x\n", + init.dma_notifier); + return DRM_ERR(EINVAL); + } + + obj = nouveau_context_object_create(dev, init.class, init.flags0, + init.flags1, init.flags2, dma0, dma1, dman); + if (!obj) + return DRM_ERR(ENOMEM); + + obj->handle = init.handle; + + if (nouveau_hash_table_insert(dev, fifo, obj)) { + nouveau_object_free(dev, fifo, obj); + return DRM_ERR(ENOMEM); + } + + nouveau_object_link(dev, fifo, obj); + + return 0; +} + +int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_nouveau_dma_object_init_t init; + struct nouveau_object *obj; + int fifo; + + fifo = nouveau_fifo_id_get(dev, filp); + + DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_dma_object_init_t __user *) + data, sizeof(init)); + + if (nouveau_object_handle_find(dev, fifo, init.handle)) { + DRM_ERROR("Channel %d: handle 0x%08x already exists\n", + fifo, init.handle); + return DRM_ERR(EINVAL); + } + + obj = nouveau_dma_object_create(dev, init.offset, init.size, + init.access, init.target); + if (!obj) + return DRM_ERR(ENOMEM); + + obj->handle = init.handle; + if (nouveau_hash_table_insert(dev, fifo, obj)) { + nouveau_object_free(dev, fifo, obj); + return DRM_ERR(ENOMEM); + } + + nouveau_object_link(dev, fifo, obj); + + return 0; +} + diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h new file mode 100644 index 00000000..42c5b851 --- /dev/null +++ b/shared-core/nouveau_reg.h @@ -0,0 +1,103 @@ + + +#define NV03_BOOT_0 0x00100000 +# define NV03_BOOT_0_RAM_AMOUNT 0x00000003 +# define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000 +# define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001 +# define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002 +# define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003 +# define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000 +# define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001 +# define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002 +# define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003 + +#define NV04_FIFO_DATA 0x0010020c +# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 +# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 + +#define NV03_STATUS 0x004006b0 +#define NV04_STATUS 0x00400700 + +#define NV_RAMIN 0x00700000 + +#define NV_RAMHT_HANDLE_OFFSET 0 +#define NV_RAMHT_CONTEXT_OFFSET 4 +# define NV_RAMHT_CONTEXT_VALID (1<<31) +# define NV_RAMHT_CONTEXT_CHANNEL_SHIFT 24 +# define NV_RAMHT_CONTEXT_ENGINE_SHIFT 16 +# define NV_RAMHT_CONTEXT_ENGINE_SOFTWARE 0 +# define NV_RAMHT_CONTEXT_ENGINE_GRAPHICS 1 +# define NV_RAMHT_CONTEXT_INSTANCE_SHIFT 0 +# define NV40_RAMHT_CONTEXT_CHANNEL_SHIFT 23 +# define NV40_RAMHT_CONTEXT_ENGINE_SHIFT 20 +# define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT 0 + +#define NV_DMA_ACCESS_RW 0 +#define NV_DMA_ACCESS_RO 1 +#define NV_DMA_ACCESS_WO 2 +#define NV_DMA_TARGET_VIDMEM 0 +#define NV_DMA_TARGET_AGP 3 + +#define NV03_FIFO_SIZE 0x8000 +#define NV_MAX_FIFO_NUMBER 32 +#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 NV_PMC_INTSTAT 0x00000100 +# define NV_PMC_INTSTAT_PFIFO_PENDING (1<< 8) +# define NV_PMC_INTSTAT_PGRAPH_PENDING (1<<12) +# define NV_PMC_INTSTAT_CRTC0_PENDING (1<<24) +# define NV_PMC_INTSTAT_CRTC1_PENDING (1<<25) +# define NV_PMC_INTSTAT_CRTCn_PENDING (3<<24) +#define NV_PMC_INTEN 0x00000140 +# define NV_PMC_INTEN_MASTER_ENABLE (1<< 0) + +#define NV_PGRAPH_INTSTAT 0x00400100 +#define NV_PGRAPH_INTEN 0x00400140 +# define NV_PGRAPH_INTR_NOTIFY (1<< 0) +# define NV_PGRAPH_INTR_MISSING_HW (1<< 4) +# define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16) +# define NV_PGRAPH_INTR_ERROR (1<<20) +#define NV_PGRAPH_NV40_UNK220 0x00400220 +# define NV_PGRAPH_NV40_UNK220_FB_INSTANCE + +/* It's a guess that this works on NV03. Confirmed on NV04, though */ +#define NV03_FIFO_ENABLE 0x00002504 +#define NV_PFIFO_INTSTAT 0x00002100 +#define NV_PFIFO_INTEN 0x00002140 +# define NV_PFIFO_INTR_ERROR (1<<0) +#define NV_PFIFO_RAMHT 0x00002210 +#define NV_PFIFO_RAMFC 0x00002214 +#define NV_PFIFO_RAMRO 0x00002218 +#define NV_PFIFO_CACHES 0x00002500 +#define NV_PFIFO_MODE 0x00002504 +#define NV_PFIFO_SIZE 0x0000250c +#define NV_PFIFO_CACH0_PSH0 0x00003000 +#define NV_PFIFO_CACH0_PUL0 0x00003050 +#define NV_PFIFO_CACH0_PUL1 0x00003054 +#define NV_PFIFO_CACH1_PSH0 0x00003200 +#define NV_PFIFO_CACH1_PSH1 0x00003204 +#define NV_PFIFO_CACH1_DMAS 0x00003220 +#define NV_PFIFO_CACH1_DMAF 0x00003224 +#define NV_PFIFO_CACH1_DMAI 0x0000322c +#define NV_PFIFO_CACH1_DMAC 0x00003230 +#define NV_PFIFO_CACH1_DMAP 0x00003240 +#define NV_PFIFO_CACH1_DMAG 0x00003244 +#define NV_PFIFO_CACH1_PUL0 0x00003250 +#define NV_PFIFO_CACH1_PUL1 0x00003254 +#define NV_PFIFO_CACH1_HASH 0x00003258 +#define NV_PFIFO_CACH1_ENG 0x00003280 + +#define NV_CRTC0_INTSTAT 0x00600100 +#define NV_CRTC0_INTEN 0x00600140 +#define NV_CRTC1_INTSTAT 0x00602100 +#define NV_CRTC1_INTEN 0x00602140 +# define NV_CRTC_INTR_VBLANK (1<<0) + +/* Fifo commands. These are not regs, neither masks */ +#define NV03_FIFO_CMD_JUMP 0x20000000 +#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc +#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) + diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c new file mode 100644 index 00000000..3bfa99ca --- /dev/null +++ b/shared-core/nouveau_state.c @@ -0,0 +1,134 @@ +/* + * Copyright 2005 Stephane Marchesin + * 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 + * PRECISION INSIGHT 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. + */ + +#include "drmP.h" +#include "drm.h" +#include "drm_sarea.h" +#include "nouveau_drv.h" + +/* here a client dies, release the stuff that was allocated for its filp */ +void nouveau_preclose(drm_device_t * dev, DRMFILE filp) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + nouveau_mem_release(filp,dev_priv->fb_heap); + nouveau_mem_release(filp,dev_priv->agp_heap); + nouveau_object_cleanup(dev, filp); + nouveau_fifo_cleanup(dev, filp); +} + +/* first module load, setup the mmio/fb mapping */ +int nouveau_firstopen(struct drm_device *dev) +{ + int ret; + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* resource 0 is mmio regs */ + /* resource 1 is linear FB */ + /* resource 2 is ??? (mmio regs + 0x1000000) */ + /* resource 6 is bios */ + + /* map the mmio regs */ + ret = drm_addmap(dev, drm_get_resource_start(dev, 0), drm_get_resource_len(dev, 0), + _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); + if (dev_priv->mmio) + { + DRM_INFO("regs mapped ok at 0x%lx\n",dev_priv->mmio->offset); + } + else + { + DRM_ERROR("Unable to initialize the mmio mapping. Please report your setup to " DRIVER_EMAIL "\n"); + return 1; + } + + DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20); + + if (dev_priv->card_type>=NV_40) + dev_priv->fb_usable_size=nouveau_mem_fb_amount(dev)-560*1024; + else + dev_priv->fb_usable_size=nouveau_mem_fb_amount(dev)-256*1024; + + nouveau_hash_table_init(dev); + + if (dev_priv->card_type >= NV_40) + dev_priv->fb_obj = nouveau_dma_object_create(dev, + 0, nouveau_mem_fb_amount(dev), + NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); + + /* allocate one buffer for all the fifos */ + dev_priv->cmdbuf_alloc = nouveau_mem_alloc(dev, 0, 1024*1024, NOUVEAU_MEM_FB, (DRMFILE)-2); + + if (dev_priv->cmdbuf_alloc->flags&NOUVEAU_MEM_AGP) { + dev_priv->cmdbuf_location = NV_DMA_TARGET_AGP; + dev_priv->cmdbuf_ch_size = NV03_FIFO_SIZE; + dev_priv->cmdbuf_base = dev_priv->cmdbuf_alloc->start; + dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, + dev_priv->cmdbuf_base, nouveau_fifo_number(dev)*NV03_FIFO_SIZE, + NV_DMA_ACCESS_RO, dev_priv->cmdbuf_location); + } else { /* NOUVEAU_MEM_FB */ + dev_priv->cmdbuf_location = NV_DMA_TARGET_VIDMEM; + dev_priv->cmdbuf_ch_size = NV03_FIFO_SIZE; + dev_priv->cmdbuf_base = dev_priv->cmdbuf_alloc->start; + dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, + dev_priv->cmdbuf_base - drm_get_resource_start(dev, 1), + nouveau_fifo_number(dev)*NV03_FIFO_SIZE, + NV_DMA_ACCESS_RO, dev_priv->cmdbuf_location); + } + + DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n", + (nouveau_fifo_number(dev)*dev_priv->cmdbuf_ch_size)/1024, + dev_priv->cmdbuf_base, + dev_priv->cmdbuf_location == NV_DMA_TARGET_AGP ? "AGP" : "VRAM" + ); + + return 0; +} + +int nouveau_load(struct drm_device *dev, unsigned long flags) +{ + drm_nouveau_private_t *dev_priv; + + if (flags==NV_UNKNOWN) + return DRM_ERR(EINVAL); + + dev_priv = drm_alloc(sizeof(drm_nouveau_private_t), DRM_MEM_DRIVER); + if (!dev_priv) + return DRM_ERR(ENOMEM); + + memset(dev_priv, 0, sizeof(drm_nouveau_private_t)); + dev_priv->card_type=flags&NOUVEAU_FAMILY; + dev_priv->flags=flags&NOUVEAU_FLAGS; + + dev->dev_private = (void *)dev_priv; + + return 0; +} + +int nouveau_unload(struct drm_device *dev) +{ + drm_free(dev->dev_private, sizeof(*dev->dev_private), DRM_MEM_DRIVER); + dev->dev_private = NULL; + return 0; +} + From 88928380c87e60d22a0a9698c468036f180f0761 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 27 Aug 2006 08:59:50 +1000 Subject: [PATCH 009/129] add pci ids for nouveau --- shared-core/drm_pciids.txt | 208 +++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index 9ef2c001..9f421953 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -461,3 +461,211 @@ 0x10DE 0x009C NV40 "NVidia 0x009C" 0x10DE 0x009D NV40 "NVidia Quadro FX 4500" 0x10DE 0x009E NV40 "NVidia 0x009E" + +[nouveau] +0x12d2 0x0008 NV_01 "NV1" +0x12d2 0x0009 NV_01 "DAC64" +0x12d2 0x0018 NV_03 "Riva128" +0x12d2 0x0019 NV_03 "Riva128ZX" +0x12d2 0x0020 NV_04 "TNT" +0x12d2 0x0028 NV_05 "TNT2" +0x12d2 0x0029 NV_05 "UTNT2" +0x12d2 0x002c NV_05 "VTNT2" +0x12d2 0x00a0 NV_05 "ITNT2" +0x10de 0x0020 NV_04 "RIVA TNT" +0x10de 0x0028 NV_05 "RIVA TNT2/TNT2 Pro" +0x10de 0x00a0 NV_05 "Aladdin TNT2" +0x10de 0x002c NV_05 "Vanta/Vanta LT" +0x10de 0x0029 NV_05 "RIVA TNT2 Ultra" +0x10de 0x002d NV_05 "RIVA TNT2 Model 64/Model 64 Pro" +0x10de 0x0100 NV_10 "GeForce 256" +0x10de 0x0101 NV_10 "GeForce DDR" +0x10de 0x0103 NV_10 "Quadro" +0x10de 0x0110 NV_10 "GeForce2 MX/MX 400" +0x10de 0x0111 NV_10 "GeForce2 MX 100/200" +0x10de 0x0113 NV_10 "Quadro2 MXR/EX/Go" +0x10de 0x01a0 NV_10|NV_NFORCE "GeForce2 Integrated GPU" +0x10de 0x0150 NV_10 "GeForce2 GTS/GeForce2 Pro" +0x10de 0x0151 NV_10 "GeForce2 Ti" +0x10de 0x0152 NV_10 "GeForce2 Ultra" +0x10de 0x0153 NV_10 "Quadro2 Pro" +0x10de 0x0170 NV_10 "GeForce4 MX 460" +0x10de 0x0171 NV_10 "GeForce4 MX 440" +0x10de 0x0172 NV_10 "GeForce4 MX 420" +0x10de 0x0173 NV_10 "GeForce4 MX 440-SE" +0x10de 0x0178 NV_20 "Quadro4 550 XGL" +0x10de 0x017a NV_10 "Quadro NVS" +0x10de 0x0181 NV_10 "GeForce4 MX 440 with AGP8X" +0x10de 0x0182 NV_10 "GeForce4 MX 440SE with AGP8X" +0x10de 0x0183 NV_10 "GeForce4 MX 420 with AGP8X" +0x10de 0x0185 NV_10 "GeForce4 MX 4000" +0x10de 0x0188 NV_20 "Quadro4 580 XGL" +0x10de 0x018a NV_10 "Quadro NVS with AGP8X" +0x10de 0x018b NV_20 "Quadro4 380 XGL" +0x10de 0x018c NV_10 "Quadro NVS 50 PCI" +0x10de 0x01f0 NV_10|NV_NFORCE2 "GeForce4 MX Integrated GPU" +0x10de 0x0200 NV_20 "GeForce3" +0x10de 0x0201 NV_20 "GeForce3 Ti 200" +0x10de 0x0202 NV_20 "GeForce3 Ti 500" +0x10de 0x0203 NV_10 "Quadro DCC" +0x10de 0x0250 NV_20 "GeForce4 Ti 4600" +0x10de 0x0251 NV_20 "GeForce4 Ti 4400" +0x10de 0x0252 NV_20 "NV25" +0x10de 0x0253 NV_20 "GeForce4 Ti 4200" +0x10de 0x0258 NV_20 "Quadro4 900 XGL" +0x10de 0x0259 NV_20 "Quadro4 750 XGL" +0x10de 0x025b NV_20 "Quadro4 700 XGL" +0x10de 0x0280 NV_20 "GeForce4 Ti 4800" +0x10de 0x0281 NV_20 "GeForce4 Ti 4200 with AGP8X" +0x10de 0x0282 NV_20 "GeForce4 Ti 4800 SE" +0x10de 0x0288 NV_20 "Quadro4 980 XGL" +0x10de 0x0289 NV_20 "Quadro4 780 XGL" +0x10de 0x0301 NV_30 "GeForce FX 5800 Ultra" +0x10de 0x0302 NV_30 "GeForce FX 5800" +0x10de 0x0308 NV_30 "Quadro FX 2000" +0x10de 0x0309 NV_30 "Quadro FX 1000" +0x10de 0x0311 NV_30 "GeForce FX 5600 Ultra" +0x10de 0x0312 NV_30 "GeForce FX 5600" +0x10de 0x0313 NV_30 "NV31" +0x10de 0x0314 NV_30 "GeForce FX 5600XT" +0x10de 0x0320 NV_30 "GeForce FX 5200" +0x10de 0x0321 NV_30 "GeForce FX 5200 Ultra" +0x10de 0x0322 NV_30 "GeForce FX 5200" +0x10de 0x0323 NV_30 "GeForce FX 5200LE" +0x10de 0x0326 NV_30 "GeForce FX 5500" +0x10de 0x0327 NV_30 "GeForce FX 5100" +0x10de 0x032a NV_10 "Quadro NVS 280 PCI" +0x10de 0x032b NV_30 "Quadro FX 500/FX 600" +0x10de 0x032f NV_30 "NV34GL" +0x10de 0x0330 NV_30 "GeForce FX 5900 Ultra" +0x10de 0x0331 NV_30 "GeForce FX 5900" +0x10de 0x0332 NV_30 "GeForce FX 5900XT" +0x10de 0x0333 NV_30 "GeForce FX 5950 Ultra" +0x10de 0x0334 NV_30 "GeForce FX 5900ZT" +0x10de 0x0338 NV_30 "Quadro FX 3000" +0x10de 0x033f NV_30 "Quadro FX 700" +0x10de 0x0341 NV_30 "GeForce FX 5700 Ultra" +0x10de 0x0342 NV_30 "GeForce FX 5700" +0x10de 0x0343 NV_30 "GeForce FX 5700LE" +0x10de 0x0344 NV_30 "GeForce FX 5700VE" +0x10de 0x0345 NV_30 "NV36" +0x10de 0x034e NV_30 "Quadro FX 1100" +0x10de 0x034f NV_30 "NV36GL" +0x10de 0x0040 NV_40 "GeForce 6800 Ultra" +0x10de 0x0041 NV_40 "GeForce 6800" +0x10de 0x0042 NV_40 "GeForce 6800 LE" +0x10de 0x0043 NV_40 "NV40" +0x10de 0x0045 NV_40 "GeForce 6800 GT" +0x10de 0x0049 NV_40 "NV40GL" +0x10de 0x004e NV_30 "Quadro FX 4000" +0x10de 0x00c0 NV_40 "NV41" +0x10de 0x00c1 NV_40 "GeForce 6800" +0x10de 0x00c2 NV_40 "GeForce 6800 LE" +0x10de 0x00cc NV_30 "Quadro FX Go1400" +0x10de 0x00cd NV_30 "Quadro FX 3450/4000 SDI" +0x10de 0x00ce NV_30 "Quadro FX 1400" +0x10de 0x0140 NV_40 "GeForce 6600 GT" +0x10de 0x0141 NV_40 "GeForce 6600" +0x10de 0x0142 NV_40 "NV43" +0x10de 0x0143 NV_40 "NV43" +0x10de 0x0145 NV_40 "GeForce 6610 XL" +0x10de 0x014b NV_40 "NV43" +0x10de 0x014c NV_40 "NV43GL" +0x10de 0x014d NV_40 "NV43GL" +0x10de 0x014e NV_30 "Quadro FX 540" +0x10de 0x014f NV_40 "GeForce 6200" +0x10de 0x0160 NV_40 "NV44" +0x10de 0x0161 NV_40 "GeForce 6200 TurboCache(TM)" +0x10de 0x0162 NV_40 "NV44" +0x10de 0x0163 NV_40 "NV44" +0x10de 0x0165 NV_10 "Quadro NVS 285" +0x10de 0x016e NV_40 "NV44GL" +0x10de 0x0220 NV_40 "NV44" +0x10de 0x0221 NV_40 "NV44" +0x10de 0x0222 NV_40 "NV44" +0x10de 0x0211 NV_40 "GeForce 6800" +0x10de 0x0212 NV_40 "GeForce 6800 LE" +0x10de 0x0215 NV_40 "GeForce 6800 GT" +0x10de 0x00f0 NV_40 "GeForce 6800 Ultra" +0x10de 0x00f0 NV_40 "GeForce 6800" +0x10de 0x00f1 NV_40 "GeForce 6600 GT" +0x10de 0x00f1 NV_40 "GeForce 6600 GT" +0x10de 0x00f2 NV_40 "GeForce 6600" +0x10de 0x00f2 NV_40 "GeForce 6600" +0x10de 0x00f3 NV_40 "GeForce 6200" +0x10de 0x00f3 NV_40 "GeForce 6200" +0x10de 0x00f8 NV_30 "Quadro FX 4400" +0x10de 0x00f8 NV_30 "Quadro FX 3400" +0x10de 0x00f8 NV_30 "Quadro FX 3400/4400" +0x10de 0x00f9 NV_40 "GeForce 6800 Ultra" +0x10de 0x00f9 NV_40 "GeForce 6800 GT" +0x10de 0x00f9 NV_40 "GeForce 6800 Series GPU" +0x10de 0x0091 NV_10 "GeForce 7800 GTX" +0x10de 0x00fa NV_30 "GeForce PCX 5750" +0x10de 0x00fa NV_30 "GeForce PCX 5750" +0x10de 0x00fb NV_30 "GeForce PCX 5900" +0x10de 0x00fb NV_30 "GeForce PCX 5900" +0x10de 0x00fc NV_30 "GeForce PCX 5300" +0x10de 0x00fc NV_30 "Quadro FX 330" +0x10de 0x00fc NV_30 "GeForce PCX 5300" +0x10de 0x00fd NV_10 "Quadro NVS 280 PCI-E" +0x10de 0x00fd NV_30 "Quadro FX 330" +0x10de 0x00fd NV_10 "Quadro PCI-E Series" +0x10de 0x00fe NV_30 "Quadro FX 1300" +0x10de 0x00fe NV_30 "Quadro FX 1300" +0x10de 0x00ff NV_10 "GeForce PCX 4300" +0x10de 0x00ff NV_10 "GeForce PCX 4300" +0x10de 0x0112 NV_10 "GeForce2 Go" +0x10de 0x0174 NV_20 "GeForce4 440 Go" +0x10de 0x0175 NV_20 "GeForce4 420 Go" +0x10de 0x0176 NV_20 "GeForce4 420 Go 32M" +0x10de 0x0177 NV_20 "GeForce4 460 Go" +0x10de 0x0179 NV_20 "GeForce4 440 Go 64M" +0x10de 0x017d NV_20 "GeForce4 410 Go 16M" +0x10de 0x017c NV_20 "Quadro4 500 GoGL" +0x10de 0x0186 NV_20 "GeForce4 448 Go" +0x10de 0x0187 NV_20 "GeForce4 488 Go" +0x10de 0x018d NV_20 "GeForce4 448 Go" +0x10de 0x0286 NV_20 "GeForce4 4200 Go" +0x10de 0x028c NV_20 "Quadro4 700 GoGL" +0x10de 0x0316 NV_30 "NV31M" +0x10de 0x0317 NV_30 "NV31M Pro" +0x10de 0x031a NV_30 "GeForce FX Go5600" +0x10de 0x031b NV_30 "GeForce FX Go5650" +0x10de 0x031c NV_30 "Quadro FX Go700" +0x10de 0x031d NV_30 "NV31GLM" +0x10de 0x031e NV_30 "NV31GLM Pro" +0x10de 0x031f NV_30 "NV31GLM Pro" +0x10de 0x0324 NV_30 "GeForce FX Go5200" +0x10de 0x0325 NV_30 "GeForce FX Go5250" +0x10de 0x0328 NV_30 "GeForce FX Go5200 32M/64M" +0x10de 0x0329 NV_30 "NV34MAP" +0x10de 0x032c NV_30 "GeForce FX Go53xx" +0x10de 0x032d NV_30 "GeForce FX Go5100" +0x10de 0x0347 NV_30 "GeForce FX Go5700" +0x10de 0x0348 NV_30 "GeForce FX Go5700" +0x10de 0x0349 NV_30 "NV36M Pro" +0x10de 0x034b NV_30 "NV36MAP" +0x10de 0x034c NV_30 "Quadro FX Go1000" +0x10de 0x00c8 NV_30 "GeForce Go 6800" +0x10de 0x00c9 NV_30 "GeForce Go 6800 Ultra" +0x10de 0x00cc NV_30 "Quadro FX Go1400" +0x10de 0x0140 NV_40 "NV43" +0x10de 0x0144 NV_30 "GeForce Go 6600" +0x10de 0x0147 NV_40 "NV43" +0x10de 0x0148 NV_30 "GeForce Go 6600" +0x10de 0x0149 NV_40 "NV43" +0x10de 0x014c NV_40 "NV43GL" +0x10de 0x0164 NV_30 "GeForce Go 6200" +0x10de 0x0167 NV_30 "GeForce Go 6200" +0x10de 0x0169 NV_40 "NV44M" +0x10de 0x016b NV_40 "NV44GLM" +0x10de 0x016c NV_40 "NV44GLM" +0x10de 0x016d NV_40 "NV44GLM" +0x10de 0x0228 NV_40 "NV44M" +0x10de 0x0091 NV_10 "NVIDIA GeForce 7800 GTX" +0x10de 0x0092 NV_10 "NVIDIA GeForce 7800 GT" +0x10de 0x009d NV_30 "NVIDIA Quadro FX 4500" +0x10de 0x0240 NV_40 "NVIDIA GeForce 6150" +0x10de 0x0241 NV_40 "NVIDIA GeForce 6150 LE" +0x10de 0x0242 NV_40 "NVIDIA GeForce 6100" From 24dddc27549f2b8cf837305ee84dd1ca97df98e7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 30 Aug 2006 16:55:02 +1000 Subject: [PATCH 010/129] Add stub {get,set}param ioctls. --- shared-core/nouveau_drm.h | 14 ++++++++++++++ shared-core/nouveau_drv.h | 2 ++ shared-core/nouveau_fifo.c | 2 ++ shared-core/nouveau_state.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index eab8ca29..76fb3a17 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -79,6 +79,18 @@ typedef struct drm_nouveau_mem_free { } drm_nouveau_mem_free_t; +typedef struct drm_nouveau_getparam { + unsigned int param; + unsigned int value; +} +drm_nouveau_getparam_t; + +typedef struct drm_nouveau_setparam { + unsigned int param; + unsigned int value; +} +drm_nouveau_setparam_t; + enum nouveau_card_type { NV_UNKNOWN =0, NV_01 =1, @@ -114,6 +126,8 @@ drm_nouveau_sarea_t; #define DRM_NOUVEAU_DMA_OBJECT_INIT 0x03 // We don't want this eventually.. #define DRM_NOUVEAU_MEM_ALLOC 0x04 #define DRM_NOUVEAU_MEM_FREE 0x05 +#define DRM_NOUVEAU_GETPARAM 0x06 +#define DRM_NOUVEAU_SETPARAM 0x07 #endif /* __NOUVEAU_DRM_H__ */ diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index c4f9718d..d7014017 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -131,6 +131,8 @@ extern void nouveau_preclose(drm_device_t * dev, DRMFILE filp); extern int nouveau_load(struct drm_device *dev, unsigned long flags); extern int nouveau_firstopen(struct drm_device *dev); extern int nouveau_unload(struct drm_device *dev); +extern int nouveau_ioctl_getparam(DRM_IOCTL_ARGS); +extern int nouveau_ioctl_setparam(DRM_IOCTL_ARGS); /* nouveau_mem.c */ extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 18ad7c5f..c0d54b33 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -263,6 +263,8 @@ drm_ioctl_desc_t nouveau_ioctls[] = { [DRM_IOCTL_NR(DRM_NOUVEAU_DMA_OBJECT_INIT)] = {nouveau_ioctl_dma_object_init, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_FREE)] = {nouveau_ioctl_mem_free, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_GETPARAM)] = {nouveau_ioctl_getparam, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_SETPARAM)] = {nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, }; int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 3bfa99ca..01ebbc8f 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -132,3 +132,39 @@ int nouveau_unload(struct drm_device *dev) return 0; } +int nouveau_ioctl_getparam(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_nouveau_getparam_t getparam; + + DRM_COPY_FROM_USER_IOCTL(getparam, (drm_nouveau_getparam_t __user *)data, + sizeof(getparam)); + + switch (getparam.param) { + default: + DRM_ERROR("unknown parameter %d\n", getparam.param); + return DRM_ERR(EINVAL); + } + + DRM_COPY_TO_USER_IOCTL((drm_nouveau_getparam_t __user *)data, getparam, + sizeof(getparam)); + return 0; +} + +int nouveau_ioctl_setparam(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_nouveau_setparam_t setparam; + + DRM_COPY_FROM_USER_IOCTL(setparam, (drm_nouveau_setparam_t __user *)data, + sizeof(setparam)); + + switch (setparam.param) { + default: + DRM_ERROR("unknown parameter %d\n", setparam.param); + return DRM_ERR(EINVAL); + } + + return 0; +} + From 97291a6ad05848b05af69e52453d93db1e96473b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 2 Sep 2006 22:25:26 +1000 Subject: [PATCH 011/129] Use DMA_IN_MEMORY for DMA objects. This is needed for a DDX change that will be committed soon after this. Without the change, MEMFORMAT_DMA_OUT appears to have no effect. --- shared-core/nouveau_object.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index fb30d529..f5c16c5e 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -338,14 +338,17 @@ struct nouveau_object *nouveau_dma_object_create(drm_device_t* dev, | (adjust<<20) | (access<<14) | (target<<16) - | 2) + | 0x3D /* DMA_IN_MEMORY */) ); NV_WRITE(NV_RAMIN + obj->instance + 4, size - 1); NV_WRITE(NV_RAMIN + obj->instance + 8, frame | ((access != NV_DMA_ACCESS_RO) ? (1<<1) : 0)); + /* I don't actually know what this is, the DMA objects I see + * in renouveau dumps usually have this as the same as +8 + */ NV_WRITE(NV_RAMIN + obj->instance + 12, - 0xFFFFFFFF); + frame | ((access != NV_DMA_ACCESS_RO) ? (1<<1) : 0)); return obj; } From b119966ae65c9ee74096cf0b246bf7703cb58ec4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 3 Sep 2006 06:36:06 +1000 Subject: [PATCH 012/129] Allow cmdbuf location(AGP,VRAM) and size to be configured. --- shared-core/nouveau_drm.h | 2 + shared-core/nouveau_drv.h | 13 ++++-- shared-core/nouveau_fifo.c | 16 +++++-- shared-core/nouveau_state.c | 89 ++++++++++++++++++++++++++----------- 4 files changed, 88 insertions(+), 32 deletions(-) diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index 76fb3a17..1180a135 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -85,6 +85,8 @@ typedef struct drm_nouveau_getparam { } drm_nouveau_getparam_t; +#define NOUVEAU_SETPARAM_CMDBUF_LOCATION 1 +#define NOUVEAU_SETPARAM_CMDBUF_SIZE 2 typedef struct drm_nouveau_setparam { unsigned int param; unsigned int value; diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index d7014017..7af9c618 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -97,6 +97,13 @@ struct mem_block { drm_local_map_t *map; }; +struct nouveau_config { + struct { + int location; + int size; + } cmdbuf; +}; + typedef struct drm_nouveau_private { /* the card type, takes NV_* as values */ int card_type; @@ -111,9 +118,7 @@ typedef struct drm_nouveau_private { struct nouveau_object *fb_obj; struct nouveau_object *cmdbuf_obj; - int cmdbuf_location; - int cmdbuf_base; - int cmdbuf_ch_size; + int cmdbuf_ch_size; struct mem_block* cmdbuf_alloc; struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; @@ -123,6 +128,7 @@ typedef struct drm_nouveau_private { struct mem_block *fb_heap; struct mem_block *fb_nomap_heap; + struct nouveau_config config; } drm_nouveau_private_t; @@ -133,6 +139,7 @@ extern int nouveau_firstopen(struct drm_device *dev); extern int nouveau_unload(struct drm_device *dev); extern int nouveau_ioctl_getparam(DRM_IOCTL_ARGS); extern int nouveau_ioctl_setparam(DRM_IOCTL_ARGS); +extern int nouveau_dma_init(struct drm_device *dev); /* nouveau_mem.c */ extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index c0d54b33..67ee6c71 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -77,6 +77,15 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; + /* Init cmdbuf on first FIFO init, this is delayed until now to + * give the ddx a chance to configure the cmdbuf with SETPARAM + */ + if (!dev_priv->cmdbuf_alloc) { + ret = nouveau_dma_init(dev); + if (ret) + return ret; + } + /* * Alright, here is the full story * Nvidia cards have multiple hw fifo contexts (praise them for that, @@ -120,7 +129,7 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR return ret; /* then, the fifo itself */ - init->cmdbuf = dev_priv->cmdbuf_base; + init->cmdbuf = dev_priv->cmdbuf_alloc->start; init->cmdbuf += init->channel * dev_priv->cmdbuf_ch_size; init->cmdbuf_size = dev_priv->cmdbuf_ch_size; ret = drm_addmap(dev, init->cmdbuf, init->cmdbuf_size, _DRM_REGISTERS, @@ -157,8 +166,9 @@ void nouveau_fifo_cleanup(drm_device_t * dev, DRMFILE filp) DRM_DEBUG("%s: new cur_fifo is %d\n", __func__, i); dev_priv->cur_fifo = i; } - - nouveau_pfifo_init(dev); + + if (dev_priv->cmdbuf_alloc) + nouveau_pfifo_init(dev); // nouveau_fifo_enable(dev); } diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 01ebbc8f..fbe94641 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -76,32 +76,6 @@ int nouveau_firstopen(struct drm_device *dev) 0, nouveau_mem_fb_amount(dev), NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); - /* allocate one buffer for all the fifos */ - dev_priv->cmdbuf_alloc = nouveau_mem_alloc(dev, 0, 1024*1024, NOUVEAU_MEM_FB, (DRMFILE)-2); - - if (dev_priv->cmdbuf_alloc->flags&NOUVEAU_MEM_AGP) { - dev_priv->cmdbuf_location = NV_DMA_TARGET_AGP; - dev_priv->cmdbuf_ch_size = NV03_FIFO_SIZE; - dev_priv->cmdbuf_base = dev_priv->cmdbuf_alloc->start; - dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, - dev_priv->cmdbuf_base, nouveau_fifo_number(dev)*NV03_FIFO_SIZE, - NV_DMA_ACCESS_RO, dev_priv->cmdbuf_location); - } else { /* NOUVEAU_MEM_FB */ - dev_priv->cmdbuf_location = NV_DMA_TARGET_VIDMEM; - dev_priv->cmdbuf_ch_size = NV03_FIFO_SIZE; - dev_priv->cmdbuf_base = dev_priv->cmdbuf_alloc->start; - dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, - dev_priv->cmdbuf_base - drm_get_resource_start(dev, 1), - nouveau_fifo_number(dev)*NV03_FIFO_SIZE, - NV_DMA_ACCESS_RO, dev_priv->cmdbuf_location); - } - - DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n", - (nouveau_fifo_number(dev)*dev_priv->cmdbuf_ch_size)/1024, - dev_priv->cmdbuf_base, - dev_priv->cmdbuf_location == NV_DMA_TARGET_AGP ? "AGP" : "VRAM" - ); - return 0; } @@ -154,12 +128,27 @@ int nouveau_ioctl_getparam(DRM_IOCTL_ARGS) int nouveau_ioctl_setparam(DRM_IOCTL_ARGS) { DRM_DEVICE; + drm_nouveau_private_t *dev_priv = dev->dev_private; drm_nouveau_setparam_t setparam; DRM_COPY_FROM_USER_IOCTL(setparam, (drm_nouveau_setparam_t __user *)data, sizeof(setparam)); switch (setparam.param) { + case NOUVEAU_SETPARAM_CMDBUF_LOCATION: + switch (setparam.value) { + case NOUVEAU_MEM_AGP: + case NOUVEAU_MEM_FB: + break; + default: + DRM_ERROR("invalid CMDBUF_LOCATION value=%d\n", setparam.value); + return DRM_ERR(EINVAL); + } + dev_priv->config.cmdbuf.location = setparam.value; + break; + case NOUVEAU_SETPARAM_CMDBUF_SIZE: + dev_priv->config.cmdbuf.size = setparam.value; + break; default: DRM_ERROR("unknown parameter %d\n", setparam.param); return DRM_ERR(EINVAL); @@ -168,3 +157,51 @@ int nouveau_ioctl_setparam(DRM_IOCTL_ARGS) return 0; } +int nouveau_dma_init(struct drm_device *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_config *config = &dev_priv->config; + struct mem_block *cb; + int cb_min_size = nouveau_fifo_number(dev) * NV03_FIFO_SIZE; + + /* allocate one buffer for all the fifos */ + dev_priv->cmdbuf_alloc = nouveau_mem_alloc(dev, 0, 1024*1024, NOUVEAU_MEM_FB, (DRMFILE)-2); + + /* Defaults for unconfigured values */ + if (!config->cmdbuf.location) + config->cmdbuf.location = NOUVEAU_MEM_FB; + if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size) + config->cmdbuf.size = cb_min_size; + + cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, + config->cmdbuf.location, (DRMFILE)-2); + /* Try defaults if that didn't succeed */ + if (!cb) { + config->cmdbuf.location = NOUVEAU_MEM_FB; + config->cmdbuf.size = cb_min_size; + cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, + config->cmdbuf.location, (DRMFILE)-2); + } + if (!cb) { + DRM_ERROR("Couldn't allocate DMA command buffer.\n"); + return DRM_ERR(ENOMEM); + } + + if (config->cmdbuf.location == NOUVEAU_MEM_AGP) + dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, + cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); + else + dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, + cb->start - drm_get_resource_start(dev, 1), + cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); + dev_priv->cmdbuf_ch_size = cb->size / nouveau_fifo_number(dev); + dev_priv->cmdbuf_alloc = cb; + + DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n", + (uint32_t)cb->size>>10, (uint32_t)cb->start, + config->cmdbuf.location == NOUVEAU_MEM_FB ? "VRAM" : "AGP"); + DRM_INFO("FIFO size is %dKiB\n", dev_priv->cmdbuf_ch_size>>10); + + return 0; +} + From d89c623f8e739815ea952adc77cfe5c0f7204407 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 7 Sep 2006 00:35:17 +0200 Subject: [PATCH 013/129] Remove a 64 bit div. --- shared-core/nouveau_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index fbe94641..707d42ef 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -194,7 +194,7 @@ int nouveau_dma_init(struct drm_device *dev) dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, cb->start - drm_get_resource_start(dev, 1), cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); - dev_priv->cmdbuf_ch_size = cb->size / nouveau_fifo_number(dev); + dev_priv->cmdbuf_ch_size = (uint32_t)cb->size / nouveau_fifo_number(dev); dev_priv->cmdbuf_alloc = cb; DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n", From 0ef29768ca909421539c3d8f65bb8e94912fa597 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 7 Sep 2006 23:59:19 +1000 Subject: [PATCH 014/129] Fix second start of X server without module reload beforehand, and a couple of other fixes. - Mark the correct RAMIN slots as free (oops) - Remove a VRAM alloc that shouldn't have been there (oops) - Move HT init out of firstopen() and into dma_init() - Setup PFIFO_RAM{HT,FC,RO} in pfifo_init() --- shared-core/nouveau_fifo.c | 7 +++++++ shared-core/nouveau_object.c | 10 +--------- shared-core/nouveau_state.c | 15 ++++++--------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 67ee6c71..ca7ddef6 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -216,6 +216,13 @@ static void nouveau_pfifo_init(drm_device_t* dev) NV_WRITE(NV_PFIFO_CACH0_PUL0, 0x00000000); NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); + NV_WRITE(NV_PFIFO_RAMHT, + (0x03 << 24) /* search 128 */ | + ((dev_priv->objs.ht_bits - 9) << 16) | + (dev_priv->objs.ht_base >> 8) + ); + NV_WRITE(NV_PFIFO_RAMFC, 0x00000110); /* RAMIN+0x11000 0.5k */ + NV_WRITE(NV_PFIFO_RAMRO, 0x00000112); /* RAMIN+0x11200 0.5k */ NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000); diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index f5c16c5e..a7fe06c2 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -241,7 +241,7 @@ static void nouveau_object_instance_free(drm_device_t *dev, obj->instance >>= (dev_priv->card_type >=NV_40 ? 5 : 4); be = obj->instance / 32; bb = obj->instance % 32; - objs->inst_bmap[be] &= ~bb; + objs->inst_bmap[be] &= ~(1<free_instance++; } @@ -265,14 +265,6 @@ void nouveau_hash_table_init(drm_device_t* dev) dev_priv->objs.ht_base = 0x10000; dev_priv->objs.ht_size = (1 << dev_priv->objs.ht_bits); - NV_WRITE(NV_PFIFO_RAMHT, - (0x03 << 24) /* search 128 */ | - ((dev_priv->objs.ht_bits - 9) << 16) | - ((dev_priv->objs.ht_base >> 16) << 4) - ); - NV_WRITE(NV_PFIFO_RAMFC, 0x00000110); /* RAMIN+0x11000 0.5k */ - NV_WRITE(NV_PFIFO_RAMRO, 0x00000112); /* RAMIN+0x11200 0.5k */ - dev_priv->objs.first_instance = 0x12000; dev_priv->objs.free_instance = 1024; /*FIXME*/ dev_priv->objs.num_instance = 1024; /*FIXME*/ diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 707d42ef..6c5cc153 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -69,13 +69,6 @@ int nouveau_firstopen(struct drm_device *dev) else dev_priv->fb_usable_size=nouveau_mem_fb_amount(dev)-256*1024; - nouveau_hash_table_init(dev); - - if (dev_priv->card_type >= NV_40) - dev_priv->fb_obj = nouveau_dma_object_create(dev, - 0, nouveau_mem_fb_amount(dev), - NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); - return 0; } @@ -164,8 +157,12 @@ int nouveau_dma_init(struct drm_device *dev) struct mem_block *cb; int cb_min_size = nouveau_fifo_number(dev) * NV03_FIFO_SIZE; - /* allocate one buffer for all the fifos */ - dev_priv->cmdbuf_alloc = nouveau_mem_alloc(dev, 0, 1024*1024, NOUVEAU_MEM_FB, (DRMFILE)-2); + nouveau_hash_table_init(dev); + + if (dev_priv->card_type >= NV_40) + dev_priv->fb_obj = nouveau_dma_object_create(dev, + 0, nouveau_mem_fb_amount(dev), + NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); /* Defaults for unconfigured values */ if (!config->cmdbuf.location) From aa80e2f48f291aa41524dfb53023499c91473705 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 9 Sep 2006 07:35:55 +1000 Subject: [PATCH 015/129] Add copyright notices while I still remember.. --- shared-core/nouveau_irq.c | 32 ++++++++++++++++++++++++++++++++ shared-core/nouveau_object.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index d4691293..5088edac 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -1,3 +1,35 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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 THE COPYRIGHT OWNER(S) 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. + * + */ + +/* + * Authors: + * Ben Skeggs + */ + #include "drmP.h" #include "drm.h" #include "nouveau_drm.h" diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index a7fe06c2..4e0571b4 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -1,3 +1,35 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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 THE COPYRIGHT OWNER(S) 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. + * + */ + +/* + * Authors: + * Ben Skeggs + */ + #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" From 22382bd8c540231641bfc75d778a50ddf1463783 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 17 Sep 2006 13:00:27 +1000 Subject: [PATCH 016/129] Add pciid for GeForce Go 6150 (0x0244). --- shared-core/drm_pciids.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index 9f421953..cbb30d25 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -669,3 +669,4 @@ 0x10de 0x0240 NV_40 "NVIDIA GeForce 6150" 0x10de 0x0241 NV_40 "NVIDIA GeForce 6150 LE" 0x10de 0x0242 NV_40 "NVIDIA GeForce 6100" +0x10de 0x0244 NV_40 "NVIDIA GeForce 6150 Go" From dd473411f889cc16af255437d2a61c616bcee695 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 11 Oct 2006 00:28:15 +0200 Subject: [PATCH 017/129] Context switching work. Added preliminary support for context switches (triggers the interrupts, but hangs after the switch ; something's not quite right yet). Removed the PFIFO_REINIT ioctl. I hope it's that a good idea... Requires the upcoming commit to the DDX. --- shared-core/nouveau_drm.h | 19 ++- shared-core/nouveau_drv.h | 5 +- shared-core/nouveau_fifo.c | 308 +++++++++++++++++++++++------------- shared-core/nouveau_irq.c | 122 ++++++++++++-- shared-core/nouveau_reg.h | 83 +++++++++- shared-core/nouveau_state.c | 59 ++----- 6 files changed, 412 insertions(+), 184 deletions(-) diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index 1180a135..ed87f5c4 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -25,7 +25,7 @@ #ifndef __NOUVEAU_DRM_H__ #define __NOUVEAU_DRM_H__ -typedef struct drm_nouveau_fifo_init { +typedef struct drm_nouveau_fifo_alloc { int channel; uint32_t put_base; /* FIFO control regs */ @@ -35,7 +35,7 @@ typedef struct drm_nouveau_fifo_init { drm_handle_t cmdbuf; int cmdbuf_size; } -drm_nouveau_fifo_init_t; +drm_nouveau_fifo_alloc_t; typedef struct drm_nouveau_object_init { uint32_t handle; @@ -122,14 +122,13 @@ typedef struct drm_nouveau_sarea { } drm_nouveau_sarea_t; -#define DRM_NOUVEAU_FIFO_INIT 0x00 -#define DRM_NOUVEAU_PFIFO_REINIT 0x01 -#define DRM_NOUVEAU_OBJECT_INIT 0x02 -#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x03 // We don't want this eventually.. -#define DRM_NOUVEAU_MEM_ALLOC 0x04 -#define DRM_NOUVEAU_MEM_FREE 0x05 -#define DRM_NOUVEAU_GETPARAM 0x06 -#define DRM_NOUVEAU_SETPARAM 0x07 +#define DRM_NOUVEAU_FIFO_ALLOC 0x00 +#define DRM_NOUVEAU_OBJECT_INIT 0x01 +#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x02 // We don't want this eventually.. +#define DRM_NOUVEAU_MEM_ALLOC 0x03 +#define DRM_NOUVEAU_MEM_FREE 0x04 +#define DRM_NOUVEAU_GETPARAM 0x05 +#define DRM_NOUVEAU_SETPARAM 0x06 #endif /* __NOUVEAU_DRM_H__ */ diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 7af9c618..007bdd6a 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -123,6 +123,9 @@ typedef struct drm_nouveau_private { struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; struct nouveau_object_store objs; + /* RAMFC and RAMRO offsets */ + uint32_t ramfc_offset; + uint32_t ramro_offset; struct mem_block *agp_heap; struct mem_block *fb_heap; @@ -139,7 +142,7 @@ extern int nouveau_firstopen(struct drm_device *dev); extern int nouveau_unload(struct drm_device *dev); extern int nouveau_ioctl_getparam(DRM_IOCTL_ARGS); extern int nouveau_ioctl_setparam(DRM_IOCTL_ARGS); -extern int nouveau_dma_init(struct drm_device *dev); +extern void nouveau_wait_for_idle(struct drm_device *dev); /* nouveau_mem.c */ extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index ca7ddef6..de23f96d 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -44,23 +44,6 @@ int nouveau_fifo_number(drm_device_t* dev) } } -/* setup the fifo enable register */ -static void nouveau_fifo_enable(drm_device_t* dev) -{ - int i; - unsigned enable_val=0; - drm_nouveau_private_t *dev_priv = dev->dev_private; - - for(i=31;i>=0;i--) - { - enable_val<<=1; - if (dev_priv->fifos[i].used) - enable_val|=1; - } - DRM_DEBUG("enable_val=0x%08x\n", enable_val); - NV_WRITE(NV03_FIFO_ENABLE,enable_val); -} - /*********************************** * functions doing the actual work ***********************************/ @@ -70,12 +53,141 @@ static void nouveau_fifo_enable(drm_device_t* dev) * voir nv_driver.c : NVPreInit */ -/* initializes a fifo */ -static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DRMFILE filp) +static void nouveau_fifo_init(drm_device_t* dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* Init PFIFO - This is an exact copy of what's done in the Xorg ddx so far. + * We should be able to figure out what's happening from the + * resources available.. + */ + + if (dev->irq_enabled) + nouveau_irq_postinstall(dev); + + if (dev_priv->card_type >= NV_40) + NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4); + + DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo); + + NV_WRITE(NV_PFIFO_CACHES, 0x00000000); + NV_WRITE(NV_PFIFO_MODE, 0x00000000); + + NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); + if (dev_priv->card_type >= NV_40) + NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo); + else + NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo); + NV_WRITE(NV_PFIFO_CACH1_DMAP, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); + NV_WRITE(NV_PFIFO_CACH1_DMAG, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); + NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); + NV_WRITE(NV_PFIFO_CACH0_PSH0, 0x00000000); + NV_WRITE(NV_PFIFO_CACH0_PUL0, 0x00000000); + NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); + NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); + NV_WRITE(NV_PFIFO_RAMHT, + (0x03 << 24) /* search 128 */ | + ((dev_priv->objs.ht_bits - 9) << 16) | + (dev_priv->objs.ht_base >> 8) + ); + dev_priv->ramfc_offset=0x11000; + dev_priv->ramro_offset=0x11200; + NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */ + NV_WRITE(NV_PFIFO_RAMRO, dev_priv->ramro_offset>>8); /* RAMIN+0x11200 0.5k */ + NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000); +#ifdef __BIG_ENDIAN + NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); +#else + NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); +#endif + NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001); + + NV_WRITE(NV_PGRAPH_CTX_USER, 0x0); + NV_WRITE(NV_PGRAPH_CTX_SWITCH1, 0x19); + NV_WRITE(NV_PFIFO_DELAY_0, 0xff /* retrycount*/ ); + if (dev_priv->card_type >= NV_40) + NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x00002001); + else + NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10110000); + + NV_WRITE(NV_PFIFO_DMA_TIMESLICE, 0x001fffff); + NV_WRITE(NV_PFIFO_CACHES, 0x00000001); + + DRM_DEBUG("%s: CACHE1 GET/PUT readback %d/%d\n", __func__, + NV_READ(NV_PFIFO_CACH1_DMAG), + NV_READ(NV_PFIFO_CACH1_DMAP)); + + DRM_INFO("%s: OK\n", __func__); +} + +static int nouveau_dma_init(struct drm_device *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_config *config = &dev_priv->config; + struct mem_block *cb; + int cb_min_size = nouveau_fifo_number(dev) * NV03_FIFO_SIZE; + + /* XXX this should be done earlier on init */ + nouveau_hash_table_init(dev); + + if (dev_priv->card_type >= NV_40) + dev_priv->fb_obj = nouveau_dma_object_create(dev, + 0, nouveau_mem_fb_amount(dev), + NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); + + /* Defaults for unconfigured values */ + if (!config->cmdbuf.location) + config->cmdbuf.location = NOUVEAU_MEM_FB; + if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size) + config->cmdbuf.size = cb_min_size; + + cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, + config->cmdbuf.location, (DRMFILE)-2); + /* Try defaults if that didn't succeed */ + if (!cb) { + config->cmdbuf.location = NOUVEAU_MEM_FB; + config->cmdbuf.size = cb_min_size; + cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, + config->cmdbuf.location, (DRMFILE)-2); + } + if (!cb) { + DRM_ERROR("Couldn't allocate DMA command buffer.\n"); + return DRM_ERR(ENOMEM); + } + + if (config->cmdbuf.location == NOUVEAU_MEM_AGP) + dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, + cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); + else + dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, + cb->start - drm_get_resource_start(dev, 1), + cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); + dev_priv->cmdbuf_ch_size = (uint32_t)cb->size / nouveau_fifo_number(dev); + dev_priv->cmdbuf_alloc = cb; + + nouveau_fifo_init(dev); + DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n", + (uint32_t)cb->size>>10, (uint32_t)cb->start, + config->cmdbuf.location == NOUVEAU_MEM_FB ? "VRAM" : "AGP"); + DRM_INFO("FIFO size is %dKiB\n", dev_priv->cmdbuf_ch_size>>10); + + return 0; +} + +/* allocates and initializes a fifo for user space consumption */ +static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, DRMFILE filp) { int i; int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t ctx_addr; /* Init cmdbuf on first FIFO init, this is delayed until now to * give the ddx a chance to configure the cmdbuf with SETPARAM @@ -90,18 +202,15 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR * Alright, here is the full story * Nvidia cards have multiple hw fifo contexts (praise them for that, * no complicated crash-prone context switches) - * X always uses context 0 (0x00800000) * We allocate a new context for each app and let it write to it directly * (woo, full userspace command submission !) * When there are no more contexts, you lost */ for(i=0;ififos[i].used==0) - { - dev_priv->fifos[i].used=1; break; - } + DRM_INFO("Allocating FIFO number %d\n", i); /* no more fifos. you lost. */ if (i==nouveau_fifo_number(dev)) return DRM_ERR(EINVAL); @@ -110,16 +219,49 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR dev_priv->fifos[i].used=1; dev_priv->fifos[i].filp=filp; - /* enable the fifo */ - nouveau_fifo_enable(dev); + nouveau_wait_for_idle(dev); + + /* disable the fifo caches */ + NV_WRITE(NV_PFIFO_CACHES, 0x00000000); + + // FIXME i*32 is true on nv04, what is it on >=nv10 ? + ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+i*32; + + // clear the first 2 RAMFC entries + // FIXME try to fill GET/PUT and see what that changes + NV_WRITE(ctx_addr,0x0); + NV_WRITE(ctx_addr+4,0x0); + + // FIXME that's what is done in nvosdk, but that part of the code is buggy so... + // RAMFC + 8 = instoffset + NV_WRITE(ctx_addr+8,dev_priv->cmdbuf_obj->instance >> 4); + + // RAMFC + 16 = defaultFetch + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); + + /* enable the fifo dma operation */ + NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<cur_fifo=i; + if (dev_priv->card_type >= NV_40) + NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo); + else + NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo); - /* make the fifo available to user space */ init->channel = i; init->put_base = i*dev_priv->cmdbuf_ch_size; NV_WRITE(NV03_FIFO_REGS_DMAPUT(i), init->put_base); NV_WRITE(NV03_FIFO_REGS_DMAGET(i), init->put_base); + NV_WRITE(NV_PFIFO_CACH1_DMAP, init->put_base); + NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base); + /* reenable the fifo caches */ + NV_WRITE(NV_PFIFO_CACHES, 0x00000001); + + /* make the fifo available to user space */ /* first, the fifo control regs */ init->ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(i); init->ctrl_size = NV03_FIFO_REGS_SIZE; @@ -140,14 +282,29 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR /* FIFO has no objects yet */ dev_priv->fifos[i].objs = NULL; - DRM_DEBUG("%s: initialised FIFO %d\n", __func__, i); - dev_priv->cur_fifo = i; + DRM_INFO("%s: initialised FIFO %d\n", __func__, i); return 0; } -static void nouveau_pfifo_init(drm_device_t* dev); + +/* stops a fifo */ +void nouveau_fifo_free(drm_device_t* dev,int n) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + dev_priv->fifos[n].used=0; + DRM_DEBUG("%s: freeing fifo %d\n", __func__, n); + + /* disable the fifo caches */ + NV_WRITE(NV_PFIFO_CACHES, 0x00000000); + + NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)&~(1<dev_private; @@ -155,9 +312,10 @@ void nouveau_fifo_cleanup(drm_device_t * dev, DRMFILE filp) DRM_DEBUG("clearing FIFO enables from filp\n"); for(i=0;ififos[i].filp==filp) - dev_priv->fifos[i].used=0; + nouveau_fifo_free(dev,i); - if (dev_priv->cur_fifo == i) { + /* check we still point at an active channel */ + if (dev_priv->fifos[dev_priv->cur_fifo].used == 0) { DRM_DEBUG("%s: cur_fifo is no longer owned.\n", __func__); for (i=0;ififos[i].used) break; @@ -167,9 +325,8 @@ void nouveau_fifo_cleanup(drm_device_t * dev, DRMFILE filp) dev_priv->cur_fifo = i; } - if (dev_priv->cmdbuf_alloc) - nouveau_pfifo_init(dev); -// nouveau_fifo_enable(dev); +/* if (dev_priv->cmdbuf_alloc) + nouveau_fifo_init(dev);*/ } int nouveau_fifo_id_get(drm_device_t* dev, DRMFILE filp) @@ -183,99 +340,30 @@ int nouveau_fifo_id_get(drm_device_t* dev, DRMFILE filp) return -1; } -static void nouveau_pfifo_init(drm_device_t* dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - - /* Init PFIFO - This is an exact copy of what's done in the Xorg ddx so far. - * We should be able to figure out what's happening from the - * resources available.. - */ - - if (dev->irq_enabled) - nouveau_irq_postinstall(dev); - - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4); - - DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo); - - NV_WRITE(NV_PFIFO_CACHES, 0x00000000); - nouveau_fifo_enable(dev); - - NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); - NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo); - else - NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo); - NV_WRITE(NV_PFIFO_CACH1_DMAP, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); - NV_WRITE(NV_PFIFO_CACH1_DMAG, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); - NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); - NV_WRITE(NV_PFIFO_CACH0_PSH0, 0x00000000); - NV_WRITE(NV_PFIFO_CACH0_PUL0, 0x00000000); - NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); - NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); - NV_WRITE(NV_PFIFO_RAMHT, - (0x03 << 24) /* search 128 */ | - ((dev_priv->objs.ht_bits - 9) << 16) | - (dev_priv->objs.ht_base >> 8) - ); - NV_WRITE(NV_PFIFO_RAMFC, 0x00000110); /* RAMIN+0x11000 0.5k */ - NV_WRITE(NV_PFIFO_RAMRO, 0x00000112); /* RAMIN+0x11200 0.5k */ - NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); - NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); - NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000); -#ifdef __BIG_ENDIAN - NV_WRITE(NV_PFIFO_CACH1_DMAF, 0x800F0078); -#else - NV_WRITE(NV_PFIFO_CACH1_DMAF, 0x000F0078); -#endif - NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000001); - NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); - NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); - NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001); - - NV_WRITE(NV_PFIFO_CACHES, 0x00000001); - - DRM_DEBUG("%s: CACHE1 GET/PUT readback %d/%d\n", __func__, - NV_READ(NV_PFIFO_CACH1_DMAG), - NV_READ(NV_PFIFO_CACH1_DMAP)); -} - /*********************************** * ioctls wrapping the functions ***********************************/ -static int nouveau_ioctl_fifo_init(DRM_IOCTL_ARGS) +static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_nouveau_fifo_init_t init; + drm_nouveau_fifo_alloc_t init; int res; - DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_init_t __user *) data, sizeof(init)); + DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, sizeof(init)); - res=nouveau_fifo_init(dev,&init,filp); + res=nouveau_fifo_alloc(dev,&init,filp); if (!res) - DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_init_t __user *)data, init, sizeof(init)); + DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, init, sizeof(init)); return res; } -static int nouveau_ioctl_fifo_reinit(DRM_IOCTL_ARGS) -{ - DRM_DEVICE; - - nouveau_pfifo_init(dev); - return 0; -} - /*********************************** * finally, the ioctl table ***********************************/ drm_ioctl_desc_t nouveau_ioctls[] = { - [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_INIT)] = {nouveau_ioctl_fifo_init, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_PFIFO_REINIT)] = {nouveau_ioctl_fifo_reinit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_OBJECT_INIT)] = {nouveau_ioctl_object_init, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_DMA_OBJECT_INIT)] = {nouveau_ioctl_dma_object_init, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH}, diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 5088edac..9cd2c77f 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -46,7 +46,10 @@ void nouveau_irq_preinstall(drm_device_t *dev) NV_WRITE(NV_PFIFO_INTEN, 0); NV_WRITE(NV_PFIFO_INTSTAT, 0xFFFFFFFF); /* Disable/Clear PGRAPH interrupts */ - NV_WRITE(NV_PGRAPH_INTEN, 0); + if (dev_priv->card_typecard_typecard_typedev_private; status = NV_READ(NV_PFIFO_INTSTAT); if (!status) return; chmode = NV_READ(NV_PFIFO_MODE); - chstat = NV_READ(0x2508); + chstat = NV_READ(NV_PFIFO_DMA); DRM_DEBUG("NV: PFIFO interrupt! INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", status, chmode, chstat); @@ -136,9 +153,73 @@ void nouveau_fifo_irq_handler(drm_nouveau_private_t *dev_priv) NV_WRITE(NV_PMC_INTSTAT, NV_PMC_INTSTAT_PFIFO_PENDING); } -void nouveau_pgraph_irq_handler(drm_nouveau_private_t *dev_priv) +static void nouveau_nv04_context_switch(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t channel,i; + uint32_t max=0; + NV_WRITE(NV_PGRAPH_FIFO,0x0); + channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1); + //DRM_INFO("raw PFIFO_CACH1_PHS1 reg is %x\n",NV_READ(NV_PFIFO_CACH1_PSH1)); + //DRM_INFO("currently on channel %d\n",channel); + for (i=0;ififos[i].used)&&(i!=channel)) { + uint32_t put,get,pending; + //put=NV_READ(dev_priv->ramfc_offset+i*32); + //get=NV_READ(dev_priv->ramfc_offset+4+i*32); + put=NV_READ(NV03_FIFO_REGS_DMAPUT(i)); + get=NV_READ(NV03_FIFO_REGS_DMAGET(i)); + pending=NV_READ(NV_PFIFO_DMA); + //DRM_INFO("Channel %d (put/get %x/%x)\n",i,put,get); + /* mark all pending channels as such */ + if ((put!=get)&!(pending&(1<cur_fifo=channel; + NV_WRITE(0x2050,channel|0x100); +#endif + //NV_WRITE(NV_PFIFO_CACH1_PSH1,max|0x100); + //NV_WRITE(0x2050,max|0x100); + + NV_WRITE(NV_PGRAPH_FIFO,0x1); + +} + +static void nouveau_nv10_context_switch(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + int channel; + + channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1); + /* 2-channel commute */ + if (channel==0) + channel=1; + else + channel=0; + dev_priv->cur_fifo=channel; + + NV_WRITE(NV_PGRAPH_CTX_USER, (NV_READ(NV_PGRAPH_CTX_USER)&0xE0FFFFFF)|(dev_priv->cur_fifo<<24)); + NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10010100); + NV_WRITE(NV_PGRAPH_FFINTFC_ST2, NV_READ(NV_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); +} + +static void nouveau_pgraph_irq_handler(drm_device_t *dev) { uint32_t status; + drm_nouveau_private_t *dev_priv = dev->dev_private; status = NV_READ(NV_PGRAPH_INTSTAT); if (!status) @@ -190,6 +271,26 @@ void nouveau_pgraph_irq_handler(drm_nouveau_private_t *dev_priv) NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_ERROR); } + if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { + uint32_t channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1); + DRM_INFO("NV: PGRAPH context switch interrupt channel %x\n",channel); + switch(dev_priv->card_type) + { + case NV_04: + nouveau_nv04_context_switch(dev); + break; + case NV_10: + nouveau_nv10_context_switch(dev); + break; + default: + DRM_INFO("NV: Context switch not implemented\n"); + break; + } + + status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_CONTEXT_SWITCH); + } + if (status) { DRM_INFO("NV: Unknown PGRAPH interrupt! STAT=0x%08x\n", status); NV_WRITE(NV_PGRAPH_INTSTAT, status); @@ -198,8 +299,9 @@ void nouveau_pgraph_irq_handler(drm_nouveau_private_t *dev_priv) NV_WRITE(NV_PMC_INTSTAT, NV_PMC_INTSTAT_PGRAPH_PENDING); } -void nouveau_crtc_irq_handler(drm_nouveau_private_t *dev_priv, int crtc) +static void nouveau_crtc_irq_handler(drm_device_t *dev, int crtc) { + drm_nouveau_private_t *dev_priv = dev->dev_private; if (crtc&1) { NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); } @@ -220,15 +322,15 @@ irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS) DRM_DEBUG("PMC INTSTAT: 0x%08x\n", status); if (status & NV_PMC_INTSTAT_PFIFO_PENDING) { - nouveau_fifo_irq_handler(dev_priv); + nouveau_fifo_irq_handler(dev); status &= ~NV_PMC_INTSTAT_PFIFO_PENDING; } if (status & NV_PMC_INTSTAT_PGRAPH_PENDING) { - nouveau_pgraph_irq_handler(dev_priv); + nouveau_pgraph_irq_handler(dev); status &= ~NV_PMC_INTSTAT_PGRAPH_PENDING; } if (status & NV_PMC_INTSTAT_CRTCn_PENDING) { - nouveau_crtc_irq_handler(dev_priv, (status>>24)&3); + nouveau_crtc_irq_handler(dev, (status>>24)&3); status &= ~NV_PMC_INTSTAT_CRTCn_PENDING; } diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 42c5b851..2b723c76 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -15,8 +15,8 @@ # define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 # define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 -#define NV03_STATUS 0x004006b0 -#define NV04_STATUS 0x00400700 +#define NV03_PGRAPH_STATUS 0x004006b0 +#define NV04_PGRAPH_STATUS 0x00400700 #define NV_RAMIN 0x00700000 @@ -55,16 +55,24 @@ # define NV_PMC_INTEN_MASTER_ENABLE (1<< 0) #define NV_PGRAPH_INTSTAT 0x00400100 -#define NV_PGRAPH_INTEN 0x00400140 +#define NV04_PGRAPH_INTEN 0x00400140 +#define NV40_PGRAPH_INTEN 0x0040013C # define NV_PGRAPH_INTR_NOTIFY (1<< 0) # define NV_PGRAPH_INTR_MISSING_HW (1<< 4) +# define NV_PGRAPH_INTR_CONTEXT_SWITCH (1<<12) # define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16) # define NV_PGRAPH_INTR_ERROR (1<<20) +#define NV_PGRAPH_CTX_CONTROL 0x00400144 #define NV_PGRAPH_NV40_UNK220 0x00400220 # define NV_PGRAPH_NV40_UNK220_FB_INSTANCE +#define NV_PGRAPH_CTX_USER 0x00400148 +#define NV_PGRAPH_CTX_SWITCH1 0x0040014C +#define NV_PGRAPH_FIFO 0x00400720 +#define NV_PGRAPH_FFINTFC_ST2 0x00400764 /* It's a guess that this works on NV03. Confirmed on NV04, though */ -#define NV03_FIFO_ENABLE 0x00002504 +#define NV_PFIFO_DELAY_0 0x00002040 +#define NV_PFIFO_DMA_TIMESLICE 0x00002044 #define NV_PFIFO_INTSTAT 0x00002100 #define NV_PFIFO_INTEN 0x00002140 # define NV_PFIFO_INTR_ERROR (1<<0) @@ -73,14 +81,78 @@ #define NV_PFIFO_RAMRO 0x00002218 #define NV_PFIFO_CACHES 0x00002500 #define NV_PFIFO_MODE 0x00002504 +#define NV_PFIFO_DMA 0x00002508 #define NV_PFIFO_SIZE 0x0000250c #define NV_PFIFO_CACH0_PSH0 0x00003000 #define NV_PFIFO_CACH0_PUL0 0x00003050 #define NV_PFIFO_CACH0_PUL1 0x00003054 #define NV_PFIFO_CACH1_PSH0 0x00003200 #define NV_PFIFO_CACH1_PSH1 0x00003204 -#define NV_PFIFO_CACH1_DMAS 0x00003220 +#define NV_PFIFO_CACH1_DMAPSH 0x00003220 #define NV_PFIFO_CACH1_DMAF 0x00003224 +# define NV_PFIFO_CACH1_DMAF_TRIG_8_BYTES 0x00000000 +# define NV_PFIFO_CACH1_DMAF_TRIG_8_BYTES 0x00000000 +# define NV_PFIFO_CACH1_DMAF_TRIG_16_BYTES 0x00000008 +# define NV_PFIFO_CACH1_DMAF_TRIG_24_BYTES 0x00000010 +# define NV_PFIFO_CACH1_DMAF_TRIG_32_BYTES 0x00000018 +# define NV_PFIFO_CACH1_DMAF_TRIG_40_BYTES 0x00000020 +# define NV_PFIFO_CACH1_DMAF_TRIG_48_BYTES 0x00000028 +# define NV_PFIFO_CACH1_DMAF_TRIG_56_BYTES 0x00000030 +# define NV_PFIFO_CACH1_DMAF_TRIG_64_BYTES 0x00000038 +# define NV_PFIFO_CACH1_DMAF_TRIG_72_BYTES 0x00000040 +# define NV_PFIFO_CACH1_DMAF_TRIG_80_BYTES 0x00000048 +# define NV_PFIFO_CACH1_DMAF_TRIG_88_BYTES 0x00000050 +# define NV_PFIFO_CACH1_DMAF_TRIG_96_BYTES 0x00000058 +# define NV_PFIFO_CACH1_DMAF_TRIG_104_BYTES 0x00000060 +# define NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES 0x00000068 +# define NV_PFIFO_CACH1_DMAF_TRIG_120_BYTES 0x00000070 +# define NV_PFIFO_CACH1_DMAF_TRIG_128_BYTES 0x00000078 +# define NV_PFIFO_CACH1_DMAF_TRIG_136_BYTES 0x00000080 +# define NV_PFIFO_CACH1_DMAF_TRIG_144_BYTES 0x00000088 +# define NV_PFIFO_CACH1_DMAF_TRIG_152_BYTES 0x00000090 +# define NV_PFIFO_CACH1_DMAF_TRIG_160_BYTES 0x00000098 +# define NV_PFIFO_CACH1_DMAF_TRIG_168_BYTES 0x000000A0 +# define NV_PFIFO_CACH1_DMAF_TRIG_176_BYTES 0x000000A8 +# define NV_PFIFO_CACH1_DMAF_TRIG_184_BYTES 0x000000B0 +# define NV_PFIFO_CACH1_DMAF_TRIG_192_BYTES 0x000000B8 +# define NV_PFIFO_CACH1_DMAF_TRIG_200_BYTES 0x000000C0 +# define NV_PFIFO_CACH1_DMAF_TRIG_208_BYTES 0x000000C8 +# define NV_PFIFO_CACH1_DMAF_TRIG_216_BYTES 0x000000D0 +# define NV_PFIFO_CACH1_DMAF_TRIG_224_BYTES 0x000000D8 +# define NV_PFIFO_CACH1_DMAF_TRIG_232_BYTES 0x000000E0 +# define NV_PFIFO_CACH1_DMAF_TRIG_240_BYTES 0x000000E8 +# define NV_PFIFO_CACH1_DMAF_TRIG_248_BYTES 0x000000F0 +# define NV_PFIFO_CACH1_DMAF_TRIG_256_BYTES 0x000000F8 +# define NV_PFIFO_CACH1_DMAF_SIZE 0x0000E000 +# define NV_PFIFO_CACH1_DMAF_SIZE_32_BYTES 0x00000000 +# define NV_PFIFO_CACH1_DMAF_SIZE_64_BYTES 0x00002000 +# define NV_PFIFO_CACH1_DMAF_SIZE_96_BYTES 0x00004000 +# define NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES 0x00006000 +# define NV_PFIFO_CACH1_DMAF_SIZE_160_BYTES 0x00008000 +# define NV_PFIFO_CACH1_DMAF_SIZE_192_BYTES 0x0000A000 +# define NV_PFIFO_CACH1_DMAF_SIZE_224_BYTES 0x0000C000 +# define NV_PFIFO_CACH1_DMAF_SIZE_256_BYTES 0x0000E000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS 0x001F0000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_0 0x00000000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_1 0x00010000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_2 0x00020000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_3 0x00030000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_4 0x00040000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_5 0x00050000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_6 0x00060000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_7 0x00070000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_8 0x00080000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_9 0x00090000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_10 0x000A0000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_11 0x000B0000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_12 0x000C0000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_13 0x000D0000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_14 0x000E0000 +# define NV_PFIFO_CACH1_DMAF_MAX_REQS_15 0x000F0000 +# define NV_PFIFO_CACH1_ENDIAN 0x80000000 +# define NV_PFIFO_CACH1_LITTLE_ENDIAN 0x7FFFFFFF +# define NV_PFIFO_CACH1_BIG_ENDIAN 0x80000000 +#define NV_PFIFO_CACH1_DMAS 0x00003228 #define NV_PFIFO_CACH1_DMAI 0x0000322c #define NV_PFIFO_CACH1_DMAC 0x00003230 #define NV_PFIFO_CACH1_DMAP 0x00003240 @@ -101,3 +173,4 @@ #define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc #define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) + diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 6c5cc153..a015a0fe 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -150,55 +150,18 @@ int nouveau_ioctl_setparam(DRM_IOCTL_ARGS) return 0; } -int nouveau_dma_init(struct drm_device *dev) +/* waits for idle */ +void nouveau_wait_for_idle(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_config *config = &dev_priv->config; - struct mem_block *cb; - int cb_min_size = nouveau_fifo_number(dev) * NV03_FIFO_SIZE; - - nouveau_hash_table_init(dev); - - if (dev_priv->card_type >= NV_40) - dev_priv->fb_obj = nouveau_dma_object_create(dev, - 0, nouveau_mem_fb_amount(dev), - NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); - - /* Defaults for unconfigured values */ - if (!config->cmdbuf.location) - config->cmdbuf.location = NOUVEAU_MEM_FB; - if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size) - config->cmdbuf.size = cb_min_size; - - cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, - config->cmdbuf.location, (DRMFILE)-2); - /* Try defaults if that didn't succeed */ - if (!cb) { - config->cmdbuf.location = NOUVEAU_MEM_FB; - config->cmdbuf.size = cb_min_size; - cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, - config->cmdbuf.location, (DRMFILE)-2); + drm_nouveau_private_t *dev_priv=dev->dev_private; + switch(dev_priv->card_type) + { + case NV_03: + while(NV_READ(NV03_PGRAPH_STATUS)); + break; + default: + while(NV_READ(NV04_PGRAPH_STATUS)); + break; } - if (!cb) { - DRM_ERROR("Couldn't allocate DMA command buffer.\n"); - return DRM_ERR(ENOMEM); - } - - if (config->cmdbuf.location == NOUVEAU_MEM_AGP) - dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, - cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); - else - dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, - cb->start - drm_get_resource_start(dev, 1), - cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); - dev_priv->cmdbuf_ch_size = (uint32_t)cb->size / nouveau_fifo_number(dev); - dev_priv->cmdbuf_alloc = cb; - - DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n", - (uint32_t)cb->size>>10, (uint32_t)cb->start, - config->cmdbuf.location == NOUVEAU_MEM_FB ? "VRAM" : "AGP"); - DRM_INFO("FIFO size is %dKiB\n", dev_priv->cmdbuf_ch_size>>10); - - return 0; } From a749d9d5b49ea0e402848bd6024e5c44826e784f Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 12 Oct 2006 01:08:15 +0200 Subject: [PATCH 018/129] More work on the context switch code. Still doesn't work. I'm mostly convinced it's an initialization issue. --- shared-core/nouveau_fifo.c | 70 +++++++++++++++++++++++--------------- shared-core/nouveau_irq.c | 4 ++- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index de23f96d..da9a8630 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -110,7 +110,6 @@ static void nouveau_fifo_init(drm_device_t* dev) NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001); NV_WRITE(NV_PGRAPH_CTX_USER, 0x0); - NV_WRITE(NV_PGRAPH_CTX_SWITCH1, 0x19); NV_WRITE(NV_PFIFO_DELAY_0, 0xff /* retrycount*/ ); if (dev_priv->card_type >= NV_40) NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x00002001); @@ -187,7 +186,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, int i; int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t ctx_addr; + uint32_t ctx_addr,ctx_size; /* Init cmdbuf on first FIFO init, this is delayed until now to * give the ddx a chance to configure the cmdbuf with SETPARAM @@ -219,54 +218,71 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, dev_priv->fifos[i].used=1; dev_priv->fifos[i].filp=filp; + init->channel = i; + init->put_base = i*dev_priv->cmdbuf_ch_size; + dev_priv->cur_fifo = init->channel; + nouveau_wait_for_idle(dev); /* disable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000000); - // FIXME i*32 is true on nv04, what is it on >=nv10 ? - ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+i*32; + if (dev_priv->card_type <= NV_04) + ctx_size=32; + else + ctx_size=128; - // clear the first 2 RAMFC entries - // FIXME try to fill GET/PUT and see what that changes - NV_WRITE(ctx_addr,0x0); - NV_WRITE(ctx_addr+4,0x0); + ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; + // clear the fifo context + for(i=0;icmdbuf_obj->instance >> 4); - - // RAMFC + 16 = defaultFetch - NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); + NV_WRITE(ctx_addr,init->put_base); + NV_WRITE(ctx_addr+4,init->put_base); + if (dev_priv->card_type <= NV_04) + { + // that's what is done in nvosdk, but that part of the code is buggy so... + NV_WRITE(ctx_addr+8,dev_priv->cmdbuf_obj->instance >> 4); +#ifdef __BIG_ENDIAN + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); +#else + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); +#endif + } + else + { + NV_WRITE(ctx_addr+12,dev_priv->cmdbuf_obj->instance >> 4/*DMA INST/DMA COUNT*/); +#ifdef __BIG_ENDIAN + NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); +#else + NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); +#endif + } /* enable the fifo dma operation */ - NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<channel)); // FIXME check if we need to refill the time quota with something like NV_WRITE(0x204C, 0x0003FFFF); - dev_priv->cur_fifo=i; if (dev_priv->card_type >= NV_40) NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo); else NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo); - init->channel = i; - init->put_base = i*dev_priv->cmdbuf_ch_size; - - NV_WRITE(NV03_FIFO_REGS_DMAPUT(i), init->put_base); - NV_WRITE(NV03_FIFO_REGS_DMAGET(i), init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAP, init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base); + NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); /* reenable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000001); /* make the fifo available to user space */ /* first, the fifo control regs */ - init->ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(i); + init->ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(init->channel); init->ctrl_size = NV03_FIFO_REGS_SIZE; ret = drm_addmap(dev, init->ctrl, init->ctrl_size, _DRM_REGISTERS, - 0, &dev_priv->fifos[i].regs); + 0, &dev_priv->fifos[init->channel].regs); if (ret != 0) return ret; @@ -275,14 +291,14 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, init->cmdbuf += init->channel * dev_priv->cmdbuf_ch_size; init->cmdbuf_size = dev_priv->cmdbuf_ch_size; ret = drm_addmap(dev, init->cmdbuf, init->cmdbuf_size, _DRM_REGISTERS, - 0, &dev_priv->fifos[i].map); + 0, &dev_priv->fifos[init->channel].map); if (ret != 0) return ret; /* FIFO has no objects yet */ - dev_priv->fifos[i].objs = NULL; + dev_priv->fifos[init->channel].objs = NULL; - DRM_INFO("%s: initialised FIFO %d\n", __func__, i); + DRM_INFO("%s: initialised FIFO %d\n", __func__, init->channel); return 0; } @@ -291,7 +307,7 @@ void nouveau_fifo_free(drm_device_t* dev,int n) { drm_nouveau_private_t *dev_priv = dev->dev_private; dev_priv->fifos[n].used=0; - DRM_DEBUG("%s: freeing fifo %d\n", __func__, n); + DRM_INFO("%s: freeing fifo %d\n", __func__, n); /* disable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000000); diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 9cd2c77f..39b33ea6 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -211,9 +211,11 @@ static void nouveau_nv10_context_switch(drm_device_t *dev) channel=0; dev_priv->cur_fifo=channel; + NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10000100); NV_WRITE(NV_PGRAPH_CTX_USER, (NV_READ(NV_PGRAPH_CTX_USER)&0xE0FFFFFF)|(dev_priv->cur_fifo<<24)); - NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10010100); NV_WRITE(NV_PGRAPH_FFINTFC_ST2, NV_READ(NV_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); + /* touch PGRAPH_CTX_SWITCH* here ? */ + NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10010100); } static void nouveau_pgraph_irq_handler(drm_device_t *dev) From 7ef44b2b8dd1745f5b228e6161ebd989844c3088 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 12 Oct 2006 17:31:49 +0200 Subject: [PATCH 019/129] Still more work on the context switching code. --- shared-core/nouveau_drv.h | 2 -- shared-core/nouveau_fifo.c | 4 ++-- shared-core/nouveau_irq.c | 11 ++++++++++- shared-core/nouveau_reg.h | 9 +++++++-- shared-core/nouveau_state.c | 5 ----- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 007bdd6a..94b46efd 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -112,8 +112,6 @@ typedef struct drm_nouveau_private { drm_local_map_t *mmio; drm_local_map_t *fb; - int64_t fb_usable_size; - int cur_fifo; struct nouveau_object *fb_obj; diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index da9a8630..1761bbec 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -227,7 +227,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, /* disable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000000); - if (dev_priv->card_type <= NV_04) + if (dev_priv->card_type <= NV_05) ctx_size=32; else ctx_size=128; @@ -239,7 +239,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(ctx_addr,init->put_base); NV_WRITE(ctx_addr+4,init->put_base); - if (dev_priv->card_type <= NV_04) + if (dev_priv->card_type <= NV_05) { // that's what is done in nvosdk, but that part of the code is buggy so... NV_WRITE(ctx_addr+8,dev_priv->cmdbuf_obj->instance >> 4); diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 39b33ea6..4e58540d 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -69,7 +69,15 @@ void nouveau_irq_postinstall(drm_device_t *dev) DRM_DEBUG("IRQ: postinst\n"); /* Enable PFIFO error reporting */ - NV_WRITE(NV_PFIFO_INTEN , NV_PFIFO_INTR_ERROR); + NV_WRITE(NV_PFIFO_INTEN , + NV_PFIFO_INTR_CACHE_ERROR | + NV_PFIFO_INTR_RUNOUT | + NV_PFIFO_INTR_RUNOUT_OVERFLOW | + NV_PFIFO_INTR_DMA_PUSHER | + NV_PFIFO_INTR_DMA_PT | + NV_PFIFO_INTR_SEMAPHORE | + NV_PFIFO_INTR_ACQUIRE_TIMEOUT + ); NV_WRITE(NV_PFIFO_INTSTAT, 0xFFFFFFFF); /* Enable PGRAPH interrupts */ @@ -279,6 +287,7 @@ static void nouveau_pgraph_irq_handler(drm_device_t *dev) switch(dev_priv->card_type) { case NV_04: + case NV_05: nouveau_nv04_context_switch(dev); break; case NV_10: diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 2b723c76..ac7c932b 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -75,7 +75,13 @@ #define NV_PFIFO_DMA_TIMESLICE 0x00002044 #define NV_PFIFO_INTSTAT 0x00002100 #define NV_PFIFO_INTEN 0x00002140 -# define NV_PFIFO_INTR_ERROR (1<<0) +# define NV_PFIFO_INTR_CACHE_ERROR (1<< 0) +# define NV_PFIFO_INTR_RUNOUT (1<< 4) +# define NV_PFIFO_INTR_RUNOUT_OVERFLOW (1<< 8) +# define NV_PFIFO_INTR_DMA_PUSHER (1<<12) +# define NV_PFIFO_INTR_DMA_PT (1<<16) +# define NV_PFIFO_INTR_SEMAPHORE (1<<20) +# define NV_PFIFO_INTR_ACQUIRE_TIMEOUT (1<<24) #define NV_PFIFO_RAMHT 0x00002210 #define NV_PFIFO_RAMFC 0x00002214 #define NV_PFIFO_RAMRO 0x00002218 @@ -91,7 +97,6 @@ #define NV_PFIFO_CACH1_DMAPSH 0x00003220 #define NV_PFIFO_CACH1_DMAF 0x00003224 # define NV_PFIFO_CACH1_DMAF_TRIG_8_BYTES 0x00000000 -# define NV_PFIFO_CACH1_DMAF_TRIG_8_BYTES 0x00000000 # define NV_PFIFO_CACH1_DMAF_TRIG_16_BYTES 0x00000008 # define NV_PFIFO_CACH1_DMAF_TRIG_24_BYTES 0x00000010 # define NV_PFIFO_CACH1_DMAF_TRIG_32_BYTES 0x00000018 diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index a015a0fe..bd70aef9 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -64,11 +64,6 @@ int nouveau_firstopen(struct drm_device *dev) DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20); - if (dev_priv->card_type>=NV_40) - dev_priv->fb_usable_size=nouveau_mem_fb_amount(dev)-560*1024; - else - dev_priv->fb_usable_size=nouveau_mem_fb_amount(dev)-256*1024; - return 0; } From a9c6c3f21d90257db94536f202b3a1f03896b2f7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 12 Oct 2006 21:18:55 +0200 Subject: [PATCH 020/129] Oops. --- shared-core/nouveau_irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 4e58540d..c3755d7a 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -145,11 +145,11 @@ static void nouveau_fifo_irq_handler(drm_device_t *dev) DRM_DEBUG("NV: PFIFO interrupt! INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", status, chmode, chstat); - if (status & NV_PFIFO_INTR_ERROR) { + if (status & NV_PFIFO_INTR_CACHE_ERROR) { DRM_ERROR("NV: PFIFO error interrupt\n"); - status &= ~NV_PFIFO_INTR_ERROR; - NV_WRITE(NV_PFIFO_INTSTAT, NV_PFIFO_INTR_ERROR); + status &= ~NV_PFIFO_INTR_CACHE_ERROR; + NV_WRITE(NV_PFIFO_INTSTAT, NV_PFIFO_INTR_CACHE_ERROR); } if (status) { From 4988074794531939ec0cb0ad183633b59e9ccff4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 14 Oct 2006 06:57:49 +1100 Subject: [PATCH 021/129] Fix some randomness in activating a second channel on NV40 (odd GET/PUT vals). Ch 1 GET now advances, but no ctx_switch. --- shared-core/nouveau_fifo.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 1761bbec..bd924f5f 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -259,6 +259,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, #endif } + /* disable the pusher ? */ + NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0); + NV_WRITE(NV_PFIFO_CACH1_PSH0, 0); + /* enable the fifo dma operation */ NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<channel)); @@ -274,6 +278,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); + /* reenable the pusher ? */ + NV_WRITE(NV_PFIFO_CACH1_PSH0, 1); + NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 1); + /* reenable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000001); From b509abe413f74bd08f6415dec8147bd07e78a84b Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 13 Oct 2006 22:35:22 +0200 Subject: [PATCH 022/129] Fix the fifo context size on nv10, nv20 and nv30. --- shared-core/nouveau_fifo.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index bd924f5f..9615e084 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -227,10 +227,22 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, /* disable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000000); - if (dev_priv->card_type <= NV_05) - ctx_size=32; - else - ctx_size=128; + switch(dev_priv->card_type) + { + case NV_03: + case NV_04: + case NV_05: + ctx_size=32; + break; + case NV_10: + case NV_20: + case NV_30: + ctx_size=64; + case NV_40: + case G_70: + default: + ctx_size=128; + } ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; // clear the fifo context From 3a0cd7c7e221f625585675490f626de8677a9dc7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 14 Oct 2006 01:21:31 +0200 Subject: [PATCH 023/129] Add the missing breaks. --- shared-core/nouveau_fifo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 9615e084..6de6a615 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -238,10 +238,12 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, case NV_20: case NV_30: ctx_size=64; + break; case NV_40: case G_70: default: ctx_size=128; + break; } ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; From 2c5b91aecf3d21684ffca758c034cd9a8ed2155d Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 14 Oct 2006 16:36:11 +0200 Subject: [PATCH 024/129] Again more work on context switches. They work, sometimes. And when they do they seem to screw up the PGRAPH state. --- shared-core/nouveau_fifo.c | 27 ++++++++++++++++++++------- shared-core/nouveau_irq.c | 32 +++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 6de6a615..5b8cabd8 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -70,6 +70,7 @@ static void nouveau_fifo_init(drm_device_t* dev) DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo); + // FIXME remove all the stuff that's done in nouveau_fifo_alloc NV_WRITE(NV_PFIFO_CACHES, 0x00000000); NV_WRITE(NV_PFIFO_MODE, 0x00000000); @@ -226,6 +227,9 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, /* disable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_DMAPSH, NV_READ(NV_PFIFO_CACH1_DMAPSH)&(~0x1)); + NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); switch(dev_priv->card_type) { @@ -273,10 +277,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, #endif } - /* disable the pusher ? */ - NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0); - NV_WRITE(NV_PFIFO_CACH1_PSH0, 0); - /* enable the fifo dma operation */ NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<channel)); @@ -291,10 +291,23 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base); NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); + NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); + NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); + NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); - /* reenable the pusher ? */ - NV_WRITE(NV_PFIFO_CACH1_PSH0, 1); - NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 1); + NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000); +#ifdef __BIG_ENDIAN + NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); +#else + NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); +#endif + NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); + NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001); /* reenable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000001); diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index c3755d7a..da68868b 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -152,6 +152,20 @@ static void nouveau_fifo_irq_handler(drm_device_t *dev) NV_WRITE(NV_PFIFO_INTSTAT, NV_PFIFO_INTR_CACHE_ERROR); } + if (status & NV_PFIFO_INTR_DMA_PUSHER) { + DRM_INFO("NV: PFIFO DMA pusher interrupt\n"); + + status &= ~NV_PFIFO_INTR_DMA_PUSHER; + NV_WRITE(NV_PFIFO_INTSTAT, NV_PFIFO_INTR_DMA_PUSHER); + + NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000000); + if (NV_READ(NV_PFIFO_CACH1_DMAP)!=NV_READ(NV_PFIFO_CACH1_DMAG)) + { + uint32_t getval=NV_READ(NV_PFIFO_CACH1_DMAG)+4; + NV_WRITE(NV_PFIFO_CACH1_DMAG,getval); + } + } + if (status) { DRM_INFO("NV: unknown PFIFO interrupt. status=0x%08x\n", status); @@ -213,17 +227,17 @@ static void nouveau_nv10_context_switch(drm_device_t *dev) channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1); /* 2-channel commute */ - if (channel==0) - channel=1; - else - channel=0; - dev_priv->cur_fifo=channel; +// if (channel==0) +// channel=1; +// else +// channel=0; +// dev_priv->cur_fifo=channel; - NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10000100); - NV_WRITE(NV_PGRAPH_CTX_USER, (NV_READ(NV_PGRAPH_CTX_USER)&0xE0FFFFFF)|(dev_priv->cur_fifo<<24)); - NV_WRITE(NV_PGRAPH_FFINTFC_ST2, NV_READ(NV_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); +// NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10000100); + NV_WRITE(NV_PGRAPH_CTX_USER, NV_READ(NV_PGRAPH_CTX_USER)|0x1F000000); +// NV_WRITE(NV_PGRAPH_FFINTFC_ST2, NV_READ(NV_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); /* touch PGRAPH_CTX_SWITCH* here ? */ - NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10010100); + NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10000100); } static void nouveau_pgraph_irq_handler(drm_device_t *dev) From 95486bbde05ae51975c4d51fd194111788edee9a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 06:12:18 +1100 Subject: [PATCH 025/129] Some info on NV40's RAMFC --- shared-core/nouveau_reg.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index ac7c932b..c74feeb3 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -178,4 +178,26 @@ #define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc #define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) +/* RAMFC offsets */ +#define NV40_RAMFC_DMA_PUT 0x00 +#define NV40_RAMFC_DMA_GET 0x04 +#define NV40_RAMFC_REF_CNT 0x08 +#define NV40_RAMFC_DMA_INSTANCE 0x0C +#define NV40_RAMFC_DMA_DCOUNT /* ? */ 0x10 +#define NV40_RAMFC_DMA_STATE 0x14 +#define NV40_RAMFC_DMA_FETCH 0x18 +#define NV40_RAMFC_ENGINE 0x1C +#define NV40_RAMFC_PULL1_ENGINE 0x20 +#define NV40_RAMFC_ACQUIRE_VALUE 0x24 +#define NV40_RAMFC_ACQUIRE_TIMESTAMP 0x28 +#define NV40_RAMFC_ACQUIRE_TIMEOUT 0x2C +#define NV40_RAMFC_SEMAPHORE 0x30 +#define NV40_RAMFC_DMA_SUBROUTINE 0x34 +#define NV40_RAMFC_GRCTX_INSTANCE_32E0 /* guess */ 0x38 +#define NV40_RAMFC_DMA_TIMESLICE 0x3C +#define NV40_RAMFC_UNK_40 0x40 +#define NV40_RAMFC_UNK_44 0x44 +#define NV40_RAMFC_UNK_48 0x48 +#define NV40_RAMFC_2088 0x4C +#define NV40_RAMFC_3300 0x50 From 1943f39d8ce27c799f928bab172e521f4d540166 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 06:37:40 +1100 Subject: [PATCH 026/129] Setup NV40 RAMFC (in wrong location.. but anyway), rearrange the RAMFC setup code a bit. --- shared-core/nouveau_fifo.c | 124 +++++++++++++++++++++++-------------- shared-core/nouveau_reg.h | 2 +- 2 files changed, 80 insertions(+), 46 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 5b8cabd8..96c3c5e3 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -181,13 +181,88 @@ static int nouveau_dma_init(struct drm_device *dev) return 0; } +static void nouveau_context_init(drm_device_t *dev, + drm_nouveau_fifo_alloc_t *init) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t ctx_addr,ctx_size; + int i; + + switch(dev_priv->card_type) + { + case NV_03: + case NV_04: + case NV_05: + ctx_size=32; + break; + case NV_10: + case NV_20: + case NV_30: + default: + ctx_size=64; + break; + } + + ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; + // clear the fifo context + for(i=0;iput_base); + NV_WRITE(ctx_addr+4,init->put_base); + if (dev_priv->card_type <= NV_05) + { + // that's what is done in nvosdk, but that part of the code is buggy so... + NV_WRITE(ctx_addr+8,dev_priv->cmdbuf_obj->instance >> 4); +#ifdef __BIG_ENDIAN + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); +#else + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); +#endif + } + else + { + NV_WRITE(ctx_addr+12,dev_priv->cmdbuf_obj->instance >> 4/*DMA INST/DMA COUNT*/); +#ifdef __BIG_ENDIAN + NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); +#else + NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); +#endif + } + +} + +static void nouveau_nv40_context_init(drm_device_t *dev, + drm_nouveau_fifo_alloc_t *init) +{ +#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t fifoctx; + int i; + + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + init->channel*128; + for (i=0;i<128;i+=4) + NV_WRITE(fifoctx + i, 0); + + /* Fill entries that are seen filled in dumps of nvidia driver just + * after channel's is put into DMA mode + */ + RAMFC_WR(DMA_PUT , init->put_base); + RAMFC_WR(DMA_GET , init->put_base); + RAMFC_WR(DMA_INSTANCE , dev_priv->cmdbuf_obj->instance >> 4); + RAMFC_WR(DMA_FETCH , 0x30086078); + RAMFC_WR(DMA_SUBROUTINE, init->put_base); + RAMFC_WR(GRCTX_INSTANCE, 0); /* XXX */ + RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF); +#undef RAMFC_WR +} + /* allocates and initializes a fifo for user space consumption */ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, DRMFILE filp) { int i; int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t ctx_addr,ctx_size; /* Init cmdbuf on first FIFO init, this is delayed until now to * give the ddx a chance to configure the cmdbuf with SETPARAM @@ -231,51 +306,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); - switch(dev_priv->card_type) - { - case NV_03: - case NV_04: - case NV_05: - ctx_size=32; - break; - case NV_10: - case NV_20: - case NV_30: - ctx_size=64; - break; - case NV_40: - case G_70: - default: - ctx_size=128; - break; - } - - ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; - // clear the fifo context - for(i=0;iput_base); - NV_WRITE(ctx_addr+4,init->put_base); - if (dev_priv->card_type <= NV_05) - { - // that's what is done in nvosdk, but that part of the code is buggy so... - NV_WRITE(ctx_addr+8,dev_priv->cmdbuf_obj->instance >> 4); -#ifdef __BIG_ENDIAN - NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); -#else - NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); -#endif - } + if (dev_priv->card_type < NV_40) + nouveau_context_init(dev, init); else - { - NV_WRITE(ctx_addr+12,dev_priv->cmdbuf_obj->instance >> 4/*DMA INST/DMA COUNT*/); -#ifdef __BIG_ENDIAN - NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); -#else - NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); -#endif - } + nouveau_nv40_context_init(dev, init); /* enable the fifo dma operation */ NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<channel)); diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index c74feeb3..7a0f429a 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -193,7 +193,7 @@ #define NV40_RAMFC_ACQUIRE_TIMEOUT 0x2C #define NV40_RAMFC_SEMAPHORE 0x30 #define NV40_RAMFC_DMA_SUBROUTINE 0x34 -#define NV40_RAMFC_GRCTX_INSTANCE_32E0 /* guess */ 0x38 +#define NV40_RAMFC_GRCTX_INSTANCE /* guess */ 0x38 #define NV40_RAMFC_DMA_TIMESLICE 0x3C #define NV40_RAMFC_UNK_40 0x40 #define NV40_RAMFC_UNK_44 0x44 From 98e718d48fcd166accf1af3c017c34e331ab09cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 07:29:31 +1100 Subject: [PATCH 027/129] NV40: FIFO context switching now WorksForMe(tm) --- shared-core/nouveau_fifo.c | 25 ++++++++++++++++++++----- shared-core/nouveau_irq.c | 6 +++--- shared-core/nouveau_object.c | 2 +- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 96c3c5e3..d015d420 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -92,9 +92,12 @@ static void nouveau_fifo_init(drm_device_t* dev) ((dev_priv->objs.ht_bits - 9) << 16) | (dev_priv->objs.ht_base >> 8) ); - dev_priv->ramfc_offset=0x11000; + dev_priv->ramfc_offset=0x12000; dev_priv->ramro_offset=0x11200; - NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */ + if (dev_priv->card_type < NV_40) + NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */ + else + NV_WRITE(0x2220, 0x30002); NV_WRITE(NV_PFIFO_RAMRO, dev_priv->ramro_offset>>8); /* RAMIN+0x11200 0.5k */ NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); @@ -314,6 +317,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, /* enable the fifo dma operation */ NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<channel)); + NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); + +if (init->channel == 0) { // FIXME check if we need to refill the time quota with something like NV_WRITE(0x204C, 0x0003FFFF); if (dev_priv->card_type >= NV_40) @@ -323,8 +330,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV_PFIFO_CACH1_DMAP, init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base); - NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); - NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); @@ -338,6 +343,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, #else NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif +} NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); @@ -375,6 +381,8 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, void nouveau_fifo_free(drm_device_t* dev,int n) { drm_nouveau_private_t *dev_priv = dev->dev_private; + int i; + dev_priv->fifos[n].used=0; DRM_INFO("%s: freeing fifo %d\n", __func__, n); @@ -382,7 +390,14 @@ void nouveau_fifo_free(drm_device_t* dev,int n) NV_WRITE(NV_PFIFO_CACHES, 0x00000000); NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)&~(1<ramfc_offset + n*128 + i)); + NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + n*128 + i, 0); + } /* reenable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000001); diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index da68868b..cff6bbba 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -133,7 +133,7 @@ void nouveau_irq_uninstall(drm_device_t *dev) static void nouveau_fifo_irq_handler(drm_device_t *dev) { - uint32_t status, chmode, chstat; + uint32_t status, chmode, chstat, channel; drm_nouveau_private_t *dev_priv = dev->dev_private; status = NV_READ(NV_PFIFO_INTSTAT); @@ -141,9 +141,9 @@ static void nouveau_fifo_irq_handler(drm_device_t *dev) return; chmode = NV_READ(NV_PFIFO_MODE); chstat = NV_READ(NV_PFIFO_DMA); + channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1); - DRM_DEBUG("NV: PFIFO interrupt! INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", - status, chmode, chstat); + DRM_DEBUG("NV: PFIFO interrupt! Channel=%d, INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", channel, status, chmode, chstat); if (status & NV_PFIFO_INTR_CACHE_ERROR) { DRM_ERROR("NV: PFIFO error interrupt\n"); diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 4e0571b4..5f11cfa7 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -297,7 +297,7 @@ void nouveau_hash_table_init(drm_device_t* dev) dev_priv->objs.ht_base = 0x10000; dev_priv->objs.ht_size = (1 << dev_priv->objs.ht_bits); - dev_priv->objs.first_instance = 0x12000; + dev_priv->objs.first_instance = 0x13000; dev_priv->objs.free_instance = 1024; /*FIXME*/ dev_priv->objs.num_instance = 1024; /*FIXME*/ dev_priv->objs.inst_bmap = drm_calloc From 4b43ee63f90c93701c9f1cdf7fefd1816b316d33 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 12:33:49 +1100 Subject: [PATCH 028/129] NV40: *Now* fifo ctx switching works for me.. Ok, I lied before.. it was a fluke it worked and required magic to repeat it.. It actually helps to fill in RAMFC entries in the correct place. The code also clears RAMIN entirely instead of just the hash-table. --- shared-core/nouveau_fifo.c | 7 +++++-- shared-core/nouveau_object.c | 6 ++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index d015d420..5a7b8638 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -92,12 +92,15 @@ static void nouveau_fifo_init(drm_device_t* dev) ((dev_priv->objs.ht_bits - 9) << 16) | (dev_priv->objs.ht_base >> 8) ); - dev_priv->ramfc_offset=0x12000; - dev_priv->ramro_offset=0x11200; + /* RAMFC needs to be at RAMIN+0x20000 on NV40, I currently don't know + * how to move it.. + */ + dev_priv->ramfc_offset=0x20000; if (dev_priv->card_type < NV_40) NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */ else NV_WRITE(0x2220, 0x30002); + dev_priv->ramro_offset=0x11200; NV_WRITE(NV_PFIFO_RAMRO, dev_priv->ramro_offset>>8); /* RAMIN+0x11200 0.5k */ NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 5f11cfa7..18c50763 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -303,10 +303,8 @@ void nouveau_hash_table_init(drm_device_t* dev) dev_priv->objs.inst_bmap = drm_calloc (1, dev_priv->objs.num_instance/32, DRM_MEM_DRIVER); - /* clear the hash table */ - ht_start = NV_RAMIN+dev_priv->objs.ht_base; - ht_end = ht_start + dev_priv->objs.ht_size; - for (i=ht_start; i Date: Tue, 17 Oct 2006 23:08:03 +1100 Subject: [PATCH 029/129] typo --- shared-core/nouveau_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index cff6bbba..086c064c 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -275,7 +275,7 @@ static void nouveau_pgraph_irq_handler(drm_device_t *dev) instance = NV_READ(0x00400158); notify = NV_READ(0x00400150) >> 16; - DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", nsource, nstatus); + DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", instance, notify); status &= ~NV_PGRAPH_INTR_BUFFER_NOTIFY; NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_BUFFER_NOTIFY); From 55de3f763f0de66b99f1afde9872f0072a84a9e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 23:44:05 +1100 Subject: [PATCH 030/129] Useful output on a FIFO error interrupt. --- shared-core/nouveau_irq.c | 17 +++++++++++++++++ shared-core/nouveau_object.c | 1 - shared-core/nouveau_reg.h | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 086c064c..af6109e9 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -146,8 +146,25 @@ static void nouveau_fifo_irq_handler(drm_device_t *dev) DRM_DEBUG("NV: PFIFO interrupt! Channel=%d, INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", channel, status, chmode, chstat); if (status & NV_PFIFO_INTR_CACHE_ERROR) { + uint32_t c1get, c1method, c1data; + DRM_ERROR("NV: PFIFO error interrupt\n"); + c1get = NV_READ(NV_PFIFO_CACH1_GET) >> 2; + if (dev_priv->card_type < NV_40) { + /* Untested, so it may not work.. */ + c1method = NV_READ(NV_PFIFO_CACH1_METHOD(c1get)); + c1data = NV_READ(NV_PFIFO_CACH1_DATA(c1get)); + } else { + c1method = NV_READ(NV40_PFIFO_CACH1_METHOD(c1get)); + c1data = NV_READ(NV40_PFIFO_CACH1_DATA(c1get)); + } + + DRM_ERROR("NV: Channel %d/%d - Method 0x%04x, Data 0x%08x\n", + channel, (c1method >> 13) & 3, + c1method & 0x1ffc, c1data + ); + status &= ~NV_PFIFO_INTR_CACHE_ERROR; NV_WRITE(NV_PFIFO_INTSTAT, NV_PFIFO_INTR_CACHE_ERROR); } diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 18c50763..78a4b78f 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -290,7 +290,6 @@ static void nouveau_object_instance_free(drm_device_t *dev, void nouveau_hash_table_init(drm_device_t* dev) { drm_nouveau_private_t *dev_priv=dev->dev_private; - int ht_start, ht_end; int i; dev_priv->objs.ht_bits = 9; diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 7a0f429a..b393e87f 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -165,7 +165,12 @@ #define NV_PFIFO_CACH1_PUL0 0x00003250 #define NV_PFIFO_CACH1_PUL1 0x00003254 #define NV_PFIFO_CACH1_HASH 0x00003258 +#define NV_PFIFO_CACH1_GET 0x00003270 #define NV_PFIFO_CACH1_ENG 0x00003280 +#define NV_PFIFO_CACH1_METHOD(i) (0x00003800+(i*8)) +#define NV_PFIFO_CACH1_DATA(i) (0x00003804+(i*8)) +#define NV40_PFIFO_CACH1_METHOD(i) (0x00090000+(i*8)) +#define NV40_PFIFO_CACH1_DATA(i) (0x00090004+(i*8)) #define NV_CRTC0_INTSTAT 0x00600100 #define NV_CRTC0_INTEN 0x00600140 From 725984364bd899c2dee1ca9b44f56fc70ccba3ad Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 18 Oct 2006 01:07:48 +1100 Subject: [PATCH 031/129] Oops, we have more than 4 subchannels.. --- shared-core/nouveau_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index af6109e9..6de4a5e4 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -161,7 +161,7 @@ static void nouveau_fifo_irq_handler(drm_device_t *dev) } DRM_ERROR("NV: Channel %d/%d - Method 0x%04x, Data 0x%08x\n", - channel, (c1method >> 13) & 3, + channel, (c1method >> 13) & 7, c1method & 0x1ffc, c1data ); From b5cf0d635c81d2c99510ce5e3f67f4aa593cd6d7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 18 Oct 2006 02:37:19 +1100 Subject: [PATCH 032/129] Remove hack which delays activation of a additional channel. The previously active channel's state is saved to RAMFC before PFIFO gets clobbered. --- shared-core/nouveau_fifo.c | 44 +++++++++++++++++++++++++++++++++----- shared-core/nouveau_reg.h | 8 +++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 5a7b8638..5c328668 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -238,10 +238,10 @@ static void nouveau_context_init(drm_device_t *dev, } +#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) static void nouveau_nv40_context_init(drm_device_t *dev, drm_nouveau_fifo_alloc_t *init) { -#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) drm_nouveau_private_t *dev_priv = dev->dev_private; uint32_t fifoctx; int i; @@ -260,9 +260,37 @@ static void nouveau_nv40_context_init(drm_device_t *dev, RAMFC_WR(DMA_SUBROUTINE, init->put_base); RAMFC_WR(GRCTX_INSTANCE, 0); /* XXX */ RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF); -#undef RAMFC_WR } +static void nouveau_nv40_context_save(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t fifoctx; + int channel; + + channel = NV_READ(NV_PFIFO_CACH1_PSH1) & (nouveau_fifo_number(dev)-1); + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128; + + RAMFC_WR(DMA_PUT , NV_READ(NV_PFIFO_CACH1_DMAP)); + RAMFC_WR(DMA_GET , NV_READ(NV_PFIFO_CACH1_DMAG)); + RAMFC_WR(REF_CNT , NV_READ(NV_PFIFO_CACH1_REF_CNT)); + RAMFC_WR(DMA_INSTANCE , NV_READ(NV_PFIFO_CACH1_DMAI)); + RAMFC_WR(DMA_DCOUNT , NV_READ(NV_PFIFO_CACH1_DMA_DCOUNT)); + RAMFC_WR(DMA_STATE , NV_READ(NV_PFIFO_CACH1_DMAS)); + //fetch + RAMFC_WR(ENGINE , NV_READ(NV_PFIFO_CACH1_ENG)); + RAMFC_WR(PULL1_ENGINE , NV_READ(NV_PFIFO_CACH1_PUL1)); + RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV_PFIFO_CACH1_ACQUIRE_VALUE)); + RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMESTAMP)); + RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMEOUT)); + RAMFC_WR(SEMAPHORE , NV_READ(NV_PFIFO_CACH1_SEMAPHORE)); + RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV_PFIFO_CACH1_DMAG)); + RAMFC_WR(GRCTX_INSTANCE , NV_READ(NV40_PFIFO_GRCTX_INSTANCE)); + RAMFC_WR(DMA_TIMESLICE , NV_READ(NV_PFIFO_DMA_TIMESLICE) & 0x1FFFF); + RAMFC_WR(UNK_40 , NV_READ(NV40_PFIFO_UNK32E4)); +} +#undef RAMFC_WR + /* allocates and initializes a fifo for user space consumption */ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, DRMFILE filp) { @@ -314,8 +342,16 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, if (dev_priv->card_type < NV_40) nouveau_context_init(dev, init); - else + else { + /* Save current channel's state to it's RAMFC entry */ + nouveau_nv40_context_save(dev); + /* Construct inital RAMFC for new channel, I'm not entirely + * sure this is needed if we activate the channel immediately. + * My understanding is that the GPU will fill RAMFC itself + * when it switches away from the channel + */ nouveau_nv40_context_init(dev, init); + } /* enable the fifo dma operation */ NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<channel)); @@ -323,7 +359,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); -if (init->channel == 0) { // FIXME check if we need to refill the time quota with something like NV_WRITE(0x204C, 0x0003FFFF); if (dev_priv->card_type >= NV_40) @@ -346,7 +381,6 @@ if (init->channel == 0) { #else NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif -} NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index b393e87f..f15b621c 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -162,11 +162,19 @@ #define NV_PFIFO_CACH1_DMAC 0x00003230 #define NV_PFIFO_CACH1_DMAP 0x00003240 #define NV_PFIFO_CACH1_DMAG 0x00003244 +#define NV_PFIFO_CACH1_REF_CNT 0x00003248 #define NV_PFIFO_CACH1_PUL0 0x00003250 #define NV_PFIFO_CACH1_PUL1 0x00003254 #define NV_PFIFO_CACH1_HASH 0x00003258 +#define NV_PFIFO_CACH1_ACQUIRE_TIMEOUT 0x00003260 +#define NV_PFIFO_CACH1_ACQUIRE_TIMESTAMP 0x00003264 +#define NV_PFIFO_CACH1_ACQUIRE_VALUE 0x00003268 +#define NV_PFIFO_CACH1_SEMAPHORE 0x0000326C #define NV_PFIFO_CACH1_GET 0x00003270 #define NV_PFIFO_CACH1_ENG 0x00003280 +#define NV_PFIFO_CACH1_DMA_DCOUNT 0x000032A0 +#define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0 +#define NV40_PFIFO_UNK32E4 0x000032E4 #define NV_PFIFO_CACH1_METHOD(i) (0x00003800+(i*8)) #define NV_PFIFO_CACH1_DATA(i) (0x00003804+(i*8)) #define NV40_PFIFO_CACH1_METHOD(i) (0x00090000+(i*8)) From 3ea0500be1ab7a058c90be35b5d8d2be26692f6a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 4 Nov 2006 16:56:10 +0100 Subject: [PATCH 033/129] Move the context object creation flag handling to the drm. --- shared-core/nouveau_drm.h | 7 ++++++- shared-core/nouveau_object.c | 40 +++++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index ed87f5c4..9e996de9 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -37,10 +37,15 @@ typedef struct drm_nouveau_fifo_alloc { } drm_nouveau_fifo_alloc_t; +#define NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND 0x1 +#define NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY 0x2 +#define NV_DMA_CONTEXT_FLAGS_CLIP_ENABLE 0x4 +#define NV_DMA_CONTEXT_FLAGS_MONO 0x8 + typedef struct drm_nouveau_object_init { uint32_t handle; int class; - uint32_t flags0, flags1, flags2; + uint32_t flags; /* these are object handles */ uint32_t dma0; uint32_t dma1; diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 78a4b78f..b539ee65 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -427,7 +427,7 @@ struct nouveau_object *nouveau_dma_object_create(drm_device_t* dev, set to 0? */ static struct nouveau_object *nouveau_context_object_create(drm_device_t* dev, - int class, uint32_t flags0, uint32_t flags1, uint32_t flags2, + int class, uint32_t flags, struct nouveau_object *dma0, struct nouveau_object *dma1, struct nouveau_object *dma_notifier) @@ -435,6 +435,40 @@ static struct nouveau_object *nouveau_context_object_create(drm_device_t* dev, drm_nouveau_private_t *dev_priv=dev->dev_private; struct nouveau_object *obj; uint32_t d0, d1, dn; + uint32_t flags0,flags1,flags2; + flags0=0;flags1=0;flags2=0; + + if (dev_priv->card_type >= NV_40) { + if (flags & NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND) + flags0 |= 0x02080000; + else if (flags & NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY) + flags0 |= 0x02080000; + if (flags & NV_DMA_CONTEXT_FLAGS_CLIP_ENABLE) + flags0 |= 0x00020000; +#ifdef __BIG_ENDIAN + if (flags & NV_DMA_CONTEXT_FLAGS_MONO) + flags1 |= 0x01000000; + flags2 |= 0x01000000; +#else + if (flags & NV_DMA_CONTEXT_FLAGS_MONO) + flags1 |= 0x02000000; +#endif + } else { + if (flags & NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND) + flags0 |= 0x01008000; + else if (flags & NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY) + flags0 |= 0x01018000; + if (flags & NV_DMA_CONTEXT_FLAGS_CLIP_ENABLE) + flags0 |= 0x00002000; +#ifdef __BIG_ENDIAN + flags0 |= 0x00080000; + if (flags & NV_DMA_CONTEXT_FLAGS_MONO) + flags1 |= 0x00000001; +#else + if (flags & NV_DMA_CONTEXT_FLAGS_MONO) + flags1 |= 0x00000002; +#endif + } DRM_DEBUG("class=%x, dma0=%08x, dma1=%08x, dman=%08x\n", class, @@ -536,8 +570,8 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } - obj = nouveau_context_object_create(dev, init.class, init.flags0, - init.flags1, init.flags2, dma0, dma1, dman); + obj = nouveau_context_object_create(dev, init.class, init.flags, + dma0, dma1, dman); if (!obj) return DRM_ERR(ENOMEM); From 06639801ce1d515f790739a70b051498c8615288 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 4 Nov 2006 20:39:59 +0100 Subject: [PATCH 034/129] Add some getparams. --- shared-core/drm_pciids.txt | 40 ++++++++++++++++++------------------- shared-core/nouveau_drm.h | 4 ++++ shared-core/nouveau_state.c | 14 +++++++++++++ 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index a6e917ac..f1d8731e 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -494,21 +494,21 @@ 0x10de 0x0171 NV_10 "GeForce4 MX 440" 0x10de 0x0172 NV_10 "GeForce4 MX 420" 0x10de 0x0173 NV_10 "GeForce4 MX 440-SE" -0x10de 0x0178 NV_20 "Quadro4 550 XGL" +0x10de 0x0178 NV_10 "Quadro4 550 XGL" 0x10de 0x017a NV_10 "Quadro NVS" 0x10de 0x0181 NV_10 "GeForce4 MX 440 with AGP8X" 0x10de 0x0182 NV_10 "GeForce4 MX 440SE with AGP8X" 0x10de 0x0183 NV_10 "GeForce4 MX 420 with AGP8X" 0x10de 0x0185 NV_10 "GeForce4 MX 4000" -0x10de 0x0188 NV_20 "Quadro4 580 XGL" +0x10de 0x0188 NV_10 "Quadro4 580 XGL" 0x10de 0x018a NV_10 "Quadro NVS with AGP8X" -0x10de 0x018b NV_20 "Quadro4 380 XGL" +0x10de 0x018b NV_10 "Quadro4 380 XGL" 0x10de 0x018c NV_10 "Quadro NVS 50 PCI" 0x10de 0x01f0 NV_10|NV_NFORCE2 "GeForce4 MX Integrated GPU" 0x10de 0x0200 NV_20 "GeForce3" 0x10de 0x0201 NV_20 "GeForce3 Ti 200" 0x10de 0x0202 NV_20 "GeForce3 Ti 500" -0x10de 0x0203 NV_10 "Quadro DCC" +0x10de 0x0203 NV_20 "Quadro DCC" 0x10de 0x0250 NV_20 "GeForce4 Ti 4600" 0x10de 0x0251 NV_20 "GeForce4 Ti 4400" 0x10de 0x0252 NV_20 "NV25" @@ -535,7 +535,7 @@ 0x10de 0x0323 NV_30 "GeForce FX 5200LE" 0x10de 0x0326 NV_30 "GeForce FX 5500" 0x10de 0x0327 NV_30 "GeForce FX 5100" -0x10de 0x032a NV_10 "Quadro NVS 280 PCI" +0x10de 0x032a NV_30 "Quadro NVS 280 PCI" 0x10de 0x032b NV_30 "Quadro FX 500/FX 600" 0x10de 0x032f NV_30 "NV34GL" 0x10de 0x0330 NV_30 "GeForce FX 5900 Ultra" @@ -558,13 +558,13 @@ 0x10de 0x0043 NV_40 "NV40" 0x10de 0x0045 NV_40 "GeForce 6800 GT" 0x10de 0x0049 NV_40 "NV40GL" -0x10de 0x004e NV_30 "Quadro FX 4000" +0x10de 0x004e NV_40 "Quadro FX 4000" 0x10de 0x00c0 NV_40 "NV41" 0x10de 0x00c1 NV_40 "GeForce 6800" 0x10de 0x00c2 NV_40 "GeForce 6800 LE" -0x10de 0x00cc NV_30 "Quadro FX Go1400" -0x10de 0x00cd NV_30 "Quadro FX 3450/4000 SDI" -0x10de 0x00ce NV_30 "Quadro FX 1400" +0x10de 0x00cc NV_40 "Quadro FX Go1400" +0x10de 0x00cd NV_40 "Quadro FX 3450/4000 SDI" +0x10de 0x00ce NV_40 "Quadro FX 1400" 0x10de 0x0140 NV_40 "GeForce 6600 GT" 0x10de 0x0141 NV_40 "GeForce 6600" 0x10de 0x0142 NV_40 "NV43" @@ -573,13 +573,13 @@ 0x10de 0x014b NV_40 "NV43" 0x10de 0x014c NV_40 "NV43GL" 0x10de 0x014d NV_40 "NV43GL" -0x10de 0x014e NV_30 "Quadro FX 540" +0x10de 0x014e NV_40 "Quadro FX 540" 0x10de 0x014f NV_40 "GeForce 6200" 0x10de 0x0160 NV_40 "NV44" 0x10de 0x0161 NV_40 "GeForce 6200 TurboCache(TM)" 0x10de 0x0162 NV_40 "NV44" 0x10de 0x0163 NV_40 "NV44" -0x10de 0x0165 NV_10 "Quadro NVS 285" +0x10de 0x0165 NV_40 "Quadro NVS 285" 0x10de 0x016e NV_40 "NV44GL" 0x10de 0x0220 NV_40 "NV44" 0x10de 0x0221 NV_40 "NV44" @@ -601,7 +601,7 @@ 0x10de 0x00f9 NV_40 "GeForce 6800 Ultra" 0x10de 0x00f9 NV_40 "GeForce 6800 GT" 0x10de 0x00f9 NV_40 "GeForce 6800 Series GPU" -0x10de 0x0091 NV_10 "GeForce 7800 GTX" +0x10de 0x0091 G_70 "GeForce 7800 GTX" 0x10de 0x00fa NV_30 "GeForce PCX 5750" 0x10de 0x00fa NV_30 "GeForce PCX 5750" 0x10de 0x00fb NV_30 "GeForce PCX 5900" @@ -609,7 +609,7 @@ 0x10de 0x00fc NV_30 "GeForce PCX 5300" 0x10de 0x00fc NV_30 "Quadro FX 330" 0x10de 0x00fc NV_30 "GeForce PCX 5300" -0x10de 0x00fd NV_10 "Quadro NVS 280 PCI-E" +0x10de 0x00fd NV_30 "Quadro NVS 280 PCI-E" 0x10de 0x00fd NV_30 "Quadro FX 330" 0x10de 0x00fd NV_10 "Quadro PCI-E Series" 0x10de 0x00fe NV_30 "Quadro FX 1300" @@ -652,21 +652,21 @@ 0x10de 0x00c9 NV_30 "GeForce Go 6800 Ultra" 0x10de 0x00cc NV_30 "Quadro FX Go1400" 0x10de 0x0140 NV_40 "NV43" -0x10de 0x0144 NV_30 "GeForce Go 6600" +0x10de 0x0144 NV_40 "GeForce Go 6600" 0x10de 0x0147 NV_40 "NV43" -0x10de 0x0148 NV_30 "GeForce Go 6600" +0x10de 0x0148 NV_40 "GeForce Go 6600" 0x10de 0x0149 NV_40 "NV43" 0x10de 0x014c NV_40 "NV43GL" -0x10de 0x0164 NV_30 "GeForce Go 6200" -0x10de 0x0167 NV_30 "GeForce Go 6200" +0x10de 0x0164 NV_40 "GeForce Go 6200" +0x10de 0x0167 NV_40 "GeForce Go 6200" 0x10de 0x0169 NV_40 "NV44M" 0x10de 0x016b NV_40 "NV44GLM" 0x10de 0x016c NV_40 "NV44GLM" 0x10de 0x016d NV_40 "NV44GLM" 0x10de 0x0228 NV_40 "NV44M" -0x10de 0x0091 NV_10 "NVIDIA GeForce 7800 GTX" -0x10de 0x0092 NV_10 "NVIDIA GeForce 7800 GT" -0x10de 0x009d NV_30 "NVIDIA Quadro FX 4500" +0x10de 0x0091 G_70 "NVIDIA GeForce 7800 GTX" +0x10de 0x0092 G_70 "NVIDIA GeForce 7800 GT" +0x10de 0x009d G_70 "NVIDIA Quadro FX 4500" 0x10de 0x0240 NV_40 "NVIDIA GeForce 6150" 0x10de 0x0241 NV_40 "NVIDIA GeForce 6150 LE" 0x10de 0x0242 NV_40 "NVIDIA GeForce 6100" diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index 9e996de9..865dbe95 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -84,6 +84,10 @@ typedef struct drm_nouveau_mem_free { } drm_nouveau_mem_free_t; +/* FIXME : maybe unify {GET,SET}PARAMs */ +#define NOUVEAU_GETPARAM_PCI_VENDOR 3 +#define NOUVEAU_GETPARAM_PCI_DEVICE 4 +#define NOUVEAU_GETPARAM_BUS_TYPE 5 typedef struct drm_nouveau_getparam { unsigned int param; unsigned int value; diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index bd70aef9..1901f08c 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -103,6 +103,20 @@ int nouveau_ioctl_getparam(DRM_IOCTL_ARGS) sizeof(getparam)); switch (getparam.param) { + case NOUVEAU_GETPARAM_PCI_VENDOR: + getparam.value=dev->pci_vendor; + break; + case NOUVEAU_GETPARAM_PCI_DEVICE: + getparam.value=dev->pci_device; + break; + case NOUVEAU_GETPARAM_BUS_TYPE: + if (drm_device_is_agp(dev)) + getparam.value=NV_AGP; + else if (drm_device_is_pcie(dev)) + getparam.value=NV_PCIE; + else + getparam.value=NV_PCI; + break; default: DRM_ERROR("unknown parameter %d\n", getparam.param); return DRM_ERR(EINVAL); From 1e118aeb39076a103c6581640b04a9b7e2a8209a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 5 Nov 2006 19:46:30 +1100 Subject: [PATCH 035/129] remove config.h --- linux-core/nouveau_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/linux-core/nouveau_drv.c b/linux-core/nouveau_drv.c index 2093ffee..8ad1d849 100644 --- a/linux-core/nouveau_drv.c +++ b/linux-core/nouveau_drv.c @@ -22,7 +22,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" From 665c8385c7865dcc4f92b9c212d6e2b35d7fa9f0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 5 Nov 2006 19:46:53 +1100 Subject: [PATCH 036/129] add powerpc mmio swapper to NV_READ/WRITE macros --- shared-core/nouveau_drv.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 94b46efd..4b35e6d1 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -171,8 +171,13 @@ extern void nouveau_irq_preinstall(drm_device_t*); extern void nouveau_irq_postinstall(drm_device_t*); extern void nouveau_irq_uninstall(drm_device_t*); +#if defined(__powerpc__) +#define NV_READ(reg) in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) ) +#define NV_WRITE(reg,val) out_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) , (val) ) +#else #define NV_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) #define NV_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) +#endif #endif /* __NOUVEAU_DRV_H__ */ From 94ab96c4d8203c236c6a5a8d8a6a761ccf808662 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 5 Nov 2006 20:38:44 +1100 Subject: [PATCH 037/129] nouveau: add compat ioc32 support --- linux-core/Makefile.kernel | 1 + linux-core/nouveau_drv.c | 3 ++ linux-core/nouveau_ioc32.c | 73 ++++++++++++++++++++++++++++++++++++++ shared-core/nouveau_drv.h | 3 ++ 4 files changed, 80 insertions(+) create mode 100644 linux-core/nouveau_ioc32.c diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 950259bd..71605de6 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -35,6 +35,7 @@ radeon-objs += radeon_ioc32.o mga-objs += mga_ioc32.o r128-objs += r128_ioc32.o i915-objs += i915_ioc32.o +nouveau-objs += nouveau_ioc32.o endif obj-m += drm.o diff --git a/linux-core/nouveau_drv.c b/linux-core/nouveau_drv.c index 8ad1d849..57b55ce1 100644 --- a/linux-core/nouveau_drv.c +++ b/linux-core/nouveau_drv.c @@ -60,6 +60,9 @@ static struct drm_driver driver = { .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, +#if defined(CONFIG_COMPAT) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) + .compat_ioctl = nouveau_compat_ioctl, +#endif }, .pci_driver = { .name = DRIVER_NAME, diff --git a/linux-core/nouveau_ioc32.c b/linux-core/nouveau_ioc32.c new file mode 100644 index 00000000..a752a581 --- /dev/null +++ b/linux-core/nouveau_ioc32.c @@ -0,0 +1,73 @@ +/** + * \file mga_ioc32.c + * + * 32-bit ioctl compatibility routines for the MGA DRM. + * + * \author Dave Airlie with code from patches by Egbert Eich + * + * + * Copyright (C) Paul Mackerras 2005 + * Copyright (C) Egbert Eich 2003,2004 + * Copyright (C) Dave Airlie 2005 + * 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 + * THE AUTHOR 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. + */ + +#include +#include + +#include "drmP.h" +#include "drm.h" + +#include "nouveau_drm.h" + +/** + * Called whenever a 32-bit process running under a 64-bit kernel + * performs an ioctl on /dev/dri/card. + * + * \param filp file pointer. + * \param cmd command. + * \param arg user argument. + * \return zero on success or negative number on failure. + */ +long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + unsigned int nr = DRM_IOCTL_NR(cmd); + drm_ioctl_compat_t *fn = NULL; + int ret; + + if (nr < DRM_COMMAND_BASE) + return drm_compat_ioctl(filp, cmd, arg); + +#if 0 + if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) + fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; +#endif + lock_kernel(); /* XXX for now */ + if (fn != NULL) + ret = (*fn)(filp, cmd, arg); + else + ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); + unlock_kernel(); + + return ret; +} diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 4b35e6d1..f579026a 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -171,6 +171,9 @@ extern void nouveau_irq_preinstall(drm_device_t*); extern void nouveau_irq_postinstall(drm_device_t*); extern void nouveau_irq_uninstall(drm_device_t*); +extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); + #if defined(__powerpc__) #define NV_READ(reg) in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) ) #define NV_WRITE(reg,val) out_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) , (val) ) From 0c34d0f31a691bb649ed69f19e93fc1a723aa1d4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Nov 2006 05:46:03 +1100 Subject: [PATCH 038/129] Leave the bottom 64kb of RAMIN untouched. The binary driver will screw up either it's init or shutdown, leaving the screen(s) in an unusable state without this. Something important in there? --- shared-core/nouveau_object.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index b539ee65..935297fa 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -302,8 +302,12 @@ void nouveau_hash_table_init(drm_device_t* dev) dev_priv->objs.inst_bmap = drm_calloc (1, dev_priv->objs.num_instance/32, DRM_MEM_DRIVER); - /* clear all of RAMIN */ - for (i=0x00700000; i<0x00800000; i+=4) + /* clear all of RAMIN + * NOTE: except the bottom 0x10000 bytes, the binary driver doesn't + * like this and will die either sometime during init, or during + * shutdown - leaving the screen in an unusable state... + */ + for (i=0x00710000; i<0x00800000; i+=4) NV_WRITE(i, 0x00000000); } From 5e55594061b24521551c45838fbe6c3df57050d1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Nov 2006 11:41:51 +1100 Subject: [PATCH 039/129] use a uint64_t for this not a pointer --- shared-core/nouveau_drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index 865dbe95..2517bbc3 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -74,7 +74,7 @@ typedef struct drm_nouveau_mem_alloc { int flags; int alignment; uint64_t size; // in bytes - uint64_t __user *region_offset; + uint64_t region_offset; } drm_nouveau_mem_alloc_t; From 2dd3c039fdbe86db4043abcc69babf768edb3ab8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Nov 2006 11:42:15 +1100 Subject: [PATCH 040/129] fixup fifo size so it is page aligned --- shared-core/nouveau_fifo.c | 2 +- shared-core/nouveau_reg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 5c328668..cf389647 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -138,7 +138,7 @@ static int nouveau_dma_init(struct drm_device *dev) drm_nouveau_private_t *dev_priv = dev->dev_private; struct nouveau_config *config = &dev_priv->config; struct mem_block *cb; - int cb_min_size = nouveau_fifo_number(dev) * NV03_FIFO_SIZE; + int cb_min_size = nouveau_fifo_number(dev) * max(NV03_FIFO_SIZE,PAGE_SIZE); /* XXX this should be done earlier on init */ nouveau_hash_table_init(dev); diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index f15b621c..868a0678 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -38,7 +38,7 @@ #define NV_DMA_TARGET_VIDMEM 0 #define NV_DMA_TARGET_AGP 3 -#define NV03_FIFO_SIZE 0x8000 +#define NV03_FIFO_SIZE 0x8000UL #define NV_MAX_FIFO_NUMBER 32 #define NV03_FIFO_REGS_SIZE 0x10000 #define NV03_FIFO_REGS(i) (0x00800000+i*NV03_FIFO_REGS_SIZE) From f7affda35bb0c47fbc973725e05847669e215d46 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Nov 2006 11:44:36 +1100 Subject: [PATCH 041/129] drm: fixup page alignment on SAREA map on ppc64 --- linux-core/drm_fops.c | 6 +++--- shared-core/drm_sarea.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index b60ced34..60ea57a2 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -46,7 +46,7 @@ static int drm_setup(drm_device_t * dev) drm_local_map_t *map; int i; int ret; - + int sareapage; if (dev->driver->firstopen) { ret = dev->driver->firstopen(dev); @@ -57,8 +57,8 @@ static int drm_setup(drm_device_t * dev) dev->magicfree.next = NULL; /* prebuild the SAREA */ - - i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); + sareapage = max(SAREA_MAX, PAGE_SIZE); + i = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); if (i != 0) return i; diff --git a/shared-core/drm_sarea.h b/shared-core/drm_sarea.h index 0d5baf69..43d1114f 100644 --- a/shared-core/drm_sarea.h +++ b/shared-core/drm_sarea.h @@ -41,7 +41,7 @@ #define SAREA_MAX 0x10000 /* 64kB */ #else /* Intel 830M driver needs at least 8k SAREA */ -#define SAREA_MAX 0x2000 +#define SAREA_MAX 0x2000UL #endif /** Maximum number of drawables in the SAREA */ From 1123ab089075af3141c794696ec394fa46b4353f Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 10 Nov 2006 02:18:38 +0100 Subject: [PATCH 042/129] Fix memory detection on TNT2 M64/TNT2 vanta. --- shared-core/nouveau_mem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 91fc6046..897badd4 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -234,6 +234,9 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) break; case NV_04: case NV_05: + if (NV_READ(NV03_BOOT_0) & 0x00000100) { + return (((NV_READ(NV03_BOOT_0) >> 12) & 0xf)*2+2)*1024*1024; + } else switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT) { case NV04_BOOT_0_RAM_AMOUNT_32MB: From 9ef4bbc66c1b055b4450ea9354945d784751cef7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 14 Nov 2006 04:51:13 +1100 Subject: [PATCH 043/129] Hack around yet another "X restart borkage without nouveau.ko reload" problem. On X init, PFIFO and PGRAPH are reset to defaults. This causes the GPU to loose the configuration done by the drm. Perhaps a CARD_INIT ioctl a proper solution to having this problem again in the future.. --- shared-core/nouveau_drv.h | 2 ++ shared-core/nouveau_fifo.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index f579026a..ac21f654 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -112,6 +112,7 @@ typedef struct drm_nouveau_private { drm_local_map_t *mmio; drm_local_map_t *fb; + //TODO: Remove me, I'm bogus :) int cur_fifo; struct nouveau_object *fb_obj; @@ -119,6 +120,7 @@ typedef struct drm_nouveau_private { int cmdbuf_ch_size; struct mem_block* cmdbuf_alloc; + int fifo_alloc_count; struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; struct nouveau_object_store objs; /* RAMFC and RAMRO offsets */ diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index cf389647..ef63f084 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -178,7 +178,6 @@ static int nouveau_dma_init(struct drm_device *dev) dev_priv->cmdbuf_ch_size = (uint32_t)cb->size / nouveau_fifo_number(dev); dev_priv->cmdbuf_alloc = cb; - nouveau_fifo_init(dev); DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n", (uint32_t)cb->size>>10, (uint32_t)cb->start, config->cmdbuf.location == NOUVEAU_MEM_FB ? "VRAM" : "AGP"); @@ -306,6 +305,9 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, if (ret) return ret; } + /* Initialise PFIFO regs */ + if (!dev_priv->fifo_alloc_count) + nouveau_fifo_init(dev); /* * Alright, here is the full story @@ -409,6 +411,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, /* FIFO has no objects yet */ dev_priv->fifos[init->channel].objs = NULL; + dev_priv->fifo_alloc_count++; DRM_INFO("%s: initialised FIFO %d\n", __func__, init->channel); return 0; @@ -438,6 +441,8 @@ void nouveau_fifo_free(drm_device_t* dev,int n) /* reenable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000001); + + dev_priv->fifo_alloc_count--; } /* cleanups all the fifos from filp */ From 7002082944a69e1d11b0146b1176fd4293581dcd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 14 Nov 2006 08:11:49 +1100 Subject: [PATCH 044/129] Restructure initialisation a bit. - Do important card init in firstopen - Give each channel it's own cmdbuf dma object - Move RAMHT config state to the same place as RAMRO/RAMFC - Make sure instance mem for objects is *after* RAM{FC,HT,RO} --- shared-core/nouveau_drv.h | 15 +-- shared-core/nouveau_fifo.c | 175 ++++++++++++++++++++++------------- shared-core/nouveau_object.c | 42 ++------- shared-core/nouveau_reg.h | 1 + shared-core/nouveau_state.c | 19 ++++ 5 files changed, 151 insertions(+), 101 deletions(-) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index ac21f654..03c7bd12 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -71,16 +71,14 @@ struct nouveau_fifo drm_local_map_t *map; /* mapping of the regs controling the fifo */ drm_local_map_t *regs; + /* dma object for the command buffer itself */ + struct nouveau_object *cmdbuf_obj; /* objects belonging to this fifo */ struct nouveau_object *objs; }; struct nouveau_object_store { - int ht_bits; - int ht_size; - int ht_base; - uint32_t *inst_bmap; uint32_t first_instance; int num_instance; @@ -116,7 +114,6 @@ typedef struct drm_nouveau_private { int cur_fifo; struct nouveau_object *fb_obj; - struct nouveau_object *cmdbuf_obj; int cmdbuf_ch_size; struct mem_block* cmdbuf_alloc; @@ -124,8 +121,13 @@ typedef struct drm_nouveau_private { struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; struct nouveau_object_store objs; /* RAMFC and RAMRO offsets */ + uint32_t ramht_offset; + uint32_t ramht_size; + uint32_t ramht_bits; uint32_t ramfc_offset; + uint32_t ramfc_size; uint32_t ramro_offset; + uint32_t ramro_size; struct mem_block *agp_heap; struct mem_block *fb_heap; @@ -155,12 +157,13 @@ extern int nouveau_mem_init(struct drm_device *dev); extern void nouveau_mem_close(struct drm_device *dev); /* nouveau_fifo.c */ +extern int nouveau_fifo_init(drm_device_t *dev); extern int nouveau_fifo_number(drm_device_t *dev); extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp); extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp); /* nouveau_object.c */ -extern void nouveau_hash_table_init(drm_device_t *dev); +extern int nouveau_object_init(drm_device_t *dev); extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp); extern struct nouveau_object *nouveau_dma_object_create(drm_device_t *dev, uint32_t offset, uint32_t size, int access, uint32_t target); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index ef63f084..d4e5b1dd 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -53,63 +53,111 @@ int nouveau_fifo_number(drm_device_t* dev) * voir nv_driver.c : NVPreInit */ -static void nouveau_fifo_init(drm_device_t* dev) +static int nouveau_fifo_instmem_configure(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; - - /* Init PFIFO - This is an exact copy of what's done in the Xorg ddx so far. - * We should be able to figure out what's happening from the - * resources available.. + int i; + + /* Clear RAMIN */ + for (i=0x00710000; i<0x00800000; i++) + NV_WRITE(i, 0x00000000); + + /* FIFO hash table (RAMHT) + * use 4k hash table at RAMIN+0x10000 + * TODO: extend the hash table */ + dev_priv->ramht_offset = 0x10000; + dev_priv->ramht_bits = 9; + dev_priv->ramht_size = (1 << dev_priv->ramht_bits); + NV_WRITE(NV_PFIFO_RAMHT, + (0x03 << 24) /* search 128 */ | + ((dev_priv->ramht_bits - 9) << 16) | + (dev_priv->ramht_offset >> 8) + ); + DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", + dev_priv->ramht_offset, + dev_priv->ramht_size); - if (dev->irq_enabled) - nouveau_irq_postinstall(dev); + /* FIFO runout table (RAMRO) - 512k at 0x11200 */ + dev_priv->ramro_offset = 0x11200; + dev_priv->ramro_size = 512; + NV_WRITE(NV_PFIFO_RAMRO, dev_priv->ramro_offset>>8); + DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", + dev_priv->ramro_offset, + dev_priv->ramro_size); - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4); + /* FIFO context table (RAMFC) + * NV40 : Not sure exactly how to position RAMFC on some cards, + * 0x30002 seems to position it at RAMIN+0x20000 on these + * cards. RAMFC is 4kb (32 fifos, 128byte entries). + * Others: Position RAMFC at RAMIN+0x11400 + */ + if (dev_priv->card_type >= NV_40) { + dev_priv->ramfc_offset = 0x20000; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * 128; + NV_WRITE(NV40_PFIFO_RAMFC, 0x30002); + } else if (dev_priv->card_type >= NV_10) { + dev_priv->ramfc_offset = 0x11400; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * 64; + NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); + } else { + dev_priv->ramfc_offset = 0x11400; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * 32; + NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); + } + DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", + dev_priv->ramfc_offset, + dev_priv->ramfc_size); - DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo); + return 0; +} + +int nouveau_fifo_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + int ret; - // FIXME remove all the stuff that's done in nouveau_fifo_alloc NV_WRITE(NV_PFIFO_CACHES, 0x00000000); + + ret = nouveau_fifo_instmem_configure(dev); + if (ret) { + DRM_ERROR("Failed to configure instance memory\n"); + return ret; + } + + /* FIXME remove all the stuff that's done in nouveau_fifo_alloc */ + + DRM_DEBUG("Setting defaults for remaining PFIFO regs\n"); + + /* All channels into PIO mode */ NV_WRITE(NV_PFIFO_MODE, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo); - else - NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo); - NV_WRITE(NV_PFIFO_CACH1_DMAP, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); - NV_WRITE(NV_PFIFO_CACH1_DMAG, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size); - NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); + /* Channel 0 active, PIO mode */ + NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000000); + /* PUT and GET to 0 */ + NV_WRITE(NV_PFIFO_CACH1_DMAP, 0x00000000); + NV_WRITE(NV_PFIFO_CACH1_DMAP, 0x00000000); + /* No cmdbuf object */ + NV_WRITE(NV_PFIFO_CACH1_DMAI, 0x00000000); NV_WRITE(NV_PFIFO_CACH0_PSH0, 0x00000000); NV_WRITE(NV_PFIFO_CACH0_PUL0, 0x00000000); - NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); + NV_WRITE(NV_PFIFO_SIZE, 0x0000FFFF); NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); - NV_WRITE(NV_PFIFO_RAMHT, - (0x03 << 24) /* search 128 */ | - ((dev_priv->objs.ht_bits - 9) << 16) | - (dev_priv->objs.ht_base >> 8) - ); - /* RAMFC needs to be at RAMIN+0x20000 on NV40, I currently don't know - * how to move it.. - */ - dev_priv->ramfc_offset=0x20000; - if (dev_priv->card_type < NV_40) - NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */ - else - NV_WRITE(0x2220, 0x30002); - dev_priv->ramro_offset=0x11200; - NV_WRITE(NV_PFIFO_RAMRO, dev_priv->ramro_offset>>8); /* RAMIN+0x11200 0.5k */ NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000); #ifdef __BIG_ENDIAN - NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); + NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES | + NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | + NV_PFIFO_CACH1_DMAF_MAX_REQS_4 | + NV_PFIFO_CACH1_BIG_ENDIAN); #else - NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); + NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES | + NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | + NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); @@ -126,11 +174,7 @@ static void nouveau_fifo_init(drm_device_t* dev) NV_WRITE(NV_PFIFO_DMA_TIMESLICE, 0x001fffff); NV_WRITE(NV_PFIFO_CACHES, 0x00000001); - DRM_DEBUG("%s: CACHE1 GET/PUT readback %d/%d\n", __func__, - NV_READ(NV_PFIFO_CACH1_DMAG), - NV_READ(NV_PFIFO_CACH1_DMAP)); - - DRM_INFO("%s: OK\n", __func__); + return 0; } static int nouveau_dma_init(struct drm_device *dev) @@ -140,14 +184,6 @@ static int nouveau_dma_init(struct drm_device *dev) struct mem_block *cb; int cb_min_size = nouveau_fifo_number(dev) * max(NV03_FIFO_SIZE,PAGE_SIZE); - /* XXX this should be done earlier on init */ - nouveau_hash_table_init(dev); - - if (dev_priv->card_type >= NV_40) - dev_priv->fb_obj = nouveau_dma_object_create(dev, - 0, nouveau_mem_fb_amount(dev), - NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); - /* Defaults for unconfigured values */ if (!config->cmdbuf.location) config->cmdbuf.location = NOUVEAU_MEM_FB; @@ -168,13 +204,6 @@ static int nouveau_dma_init(struct drm_device *dev) return DRM_ERR(ENOMEM); } - if (config->cmdbuf.location == NOUVEAU_MEM_AGP) - dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, - cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); - else - dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev, - cb->start - drm_get_resource_start(dev, 1), - cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); dev_priv->cmdbuf_ch_size = (uint32_t)cb->size / nouveau_fifo_number(dev); dev_priv->cmdbuf_alloc = cb; @@ -190,6 +219,7 @@ static void nouveau_context_init(drm_device_t *dev, drm_nouveau_fifo_alloc_t *init) { drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_object *cb_obj; uint32_t ctx_addr,ctx_size; int i; @@ -208,6 +238,8 @@ static void nouveau_context_init(drm_device_t *dev, break; } + cb_obj = dev_priv->fifos[init->channel].cmdbuf_obj; + ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; // clear the fifo context for(i=0;icard_type <= NV_05) { // that's what is done in nvosdk, but that part of the code is buggy so... - NV_WRITE(ctx_addr+8,dev_priv->cmdbuf_obj->instance >> 4); + NV_WRITE(ctx_addr+8, cb_obj->instance >> 4); #ifdef __BIG_ENDIAN NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); #else @@ -227,7 +259,7 @@ static void nouveau_context_init(drm_device_t *dev, } else { - NV_WRITE(ctx_addr+12,dev_priv->cmdbuf_obj->instance >> 4/*DMA INST/DMA COUNT*/); + NV_WRITE(ctx_addr+12,cb_obj->instance >> 4/*DMA INST/DMA COUNT*/); #ifdef __BIG_ENDIAN NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); #else @@ -242,9 +274,11 @@ static void nouveau_nv40_context_init(drm_device_t *dev, drm_nouveau_fifo_alloc_t *init) { drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_object *cb_obj; uint32_t fifoctx; int i; + cb_obj = dev_priv->fifos[init->channel].cmdbuf_obj; fifoctx = NV_RAMIN + dev_priv->ramfc_offset + init->channel*128; for (i=0;i<128;i+=4) NV_WRITE(fifoctx + i, 0); @@ -254,7 +288,7 @@ static void nouveau_nv40_context_init(drm_device_t *dev, */ RAMFC_WR(DMA_PUT , init->put_base); RAMFC_WR(DMA_GET , init->put_base); - RAMFC_WR(DMA_INSTANCE , dev_priv->cmdbuf_obj->instance >> 4); + RAMFC_WR(DMA_INSTANCE , cb_obj->instance >> 4); RAMFC_WR(DMA_FETCH , 0x30086078); RAMFC_WR(DMA_SUBROUTINE, init->put_base); RAMFC_WR(GRCTX_INSTANCE, 0); /* XXX */ @@ -296,6 +330,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, int i; int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_object *cb_obj; /* Init cmdbuf on first FIFO init, this is delayed until now to * give the ddx a chance to configure the cmdbuf with SETPARAM @@ -305,9 +340,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, if (ret) return ret; } - /* Initialise PFIFO regs */ - if (!dev_priv->fifo_alloc_count) - nouveau_fifo_init(dev); /* * Alright, here is the full story @@ -326,6 +358,23 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, if (i==nouveau_fifo_number(dev)) return DRM_ERR(EINVAL); + /* allocate a dma object for the command buffer */ + if (dev_priv->cmdbuf_alloc->flags & NOUVEAU_MEM_AGP) { + cb_obj = nouveau_dma_object_create(dev, + dev_priv->cmdbuf_alloc->start, + dev_priv->cmdbuf_alloc->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_AGP); + } else { + cb_obj = nouveau_dma_object_create(dev, + dev_priv->cmdbuf_alloc->start - + drm_get_resource_start(dev, 1), + dev_priv->cmdbuf_alloc->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_VIDMEM); + } + dev_priv->fifos[i].cmdbuf_obj = cb_obj; + /* that fifo is used */ dev_priv->fifos[i].used=1; dev_priv->fifos[i].filp=filp; @@ -370,7 +419,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV_PFIFO_CACH1_DMAP, init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base); - NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); + NV_WRITE(NV_PFIFO_CACH1_DMAI, cb_obj->instance >> 4); NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 935297fa..abd8bec5 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -132,15 +132,14 @@ static uint32_t nouveau_handle_hash(drm_device_t* dev, uint32_t handle, int fifo) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_object_store *objs=&dev_priv->objs; uint32_t hash = 0; int i; - for (i=32;i>0;i-=objs->ht_bits) { - hash ^= (handle & ((1 << objs->ht_bits) - 1)); - handle >>= objs->ht_bits; + for (i=32;i>0;i-=dev_priv->ramht_bits) { + hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); + handle >>= dev_priv->ramht_bits; } - hash ^= fifo << (objs->ht_bits - 4); + hash ^= fifo << (dev_priv->ramht_bits - 4); return hash << 3; } @@ -148,9 +147,8 @@ static int nouveau_hash_table_insert(drm_device_t* dev, int fifo, struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_object_store *objs=&dev_priv->objs; - int ht_base = NV_RAMIN + objs->ht_base; - int ht_end = ht_base + objs->ht_size; + int ht_base = NV_RAMIN + dev_priv->ramht_offset; + int ht_end = ht_base + dev_priv->ramht_size; int o_ofs, ofs; o_ofs = ofs = nouveau_handle_hash(dev, obj->handle, fifo); @@ -277,38 +275,18 @@ static void nouveau_object_instance_free(drm_device_t *dev, objs->free_instance++; } -/* Where is the hash table located: - - Base address and size can be calculated from this register: - - ht_base = 0x1000 * GetBitField (pNv->PFIFO[0x0210/4],8:4); - ht_size = 0x1000 << GetBitField (pNv->PFIFO[0x0210/4],17:16); - - and the hash table will be located between address PRAMIN + ht_base and - PRAMIN + ht_base + ht_size. Each hash table entry has two longwords. -*/ -void nouveau_hash_table_init(drm_device_t* dev) +int nouveau_object_init(drm_device_t* dev) { drm_nouveau_private_t *dev_priv=dev->dev_private; - int i; - dev_priv->objs.ht_bits = 9; - dev_priv->objs.ht_base = 0x10000; - dev_priv->objs.ht_size = (1 << dev_priv->objs.ht_bits); - - dev_priv->objs.first_instance = 0x13000; + dev_priv->objs.first_instance = + dev_priv->ramfc_offset +dev_priv->ramfc_size; dev_priv->objs.free_instance = 1024; /*FIXME*/ dev_priv->objs.num_instance = 1024; /*FIXME*/ dev_priv->objs.inst_bmap = drm_calloc (1, dev_priv->objs.num_instance/32, DRM_MEM_DRIVER); - /* clear all of RAMIN - * NOTE: except the bottom 0x10000 bytes, the binary driver doesn't - * like this and will die either sometime during init, or during - * shutdown - leaving the screen in an unusable state... - */ - for (i=0x00710000; i<0x00800000; i+=4) - NV_WRITE(i, 0x00000000); + return 0; } /* diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 868a0678..844ee865 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -85,6 +85,7 @@ #define NV_PFIFO_RAMHT 0x00002210 #define NV_PFIFO_RAMFC 0x00002214 #define NV_PFIFO_RAMRO 0x00002218 +#define NV40_PFIFO_RAMFC 0x00002220 #define NV_PFIFO_CACHES 0x00002500 #define NV_PFIFO_MODE 0x00002504 #define NV_PFIFO_DMA 0x00002508 diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 1901f08c..b05442fb 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -64,6 +64,25 @@ int nouveau_firstopen(struct drm_device *dev) DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20); + /* Clear RAMIN + * Determine locations for RAMHT/FC/RO + * Initialise PFIFO + */ + ret = nouveau_fifo_init(dev); + if (ret) return ret; + /* Initialise instance memory allocation */ + ret = nouveau_object_init(dev); + if (ret) return ret; + + /* FIXME: doesn't belong here, and have no idea what it's for.. */ + if (dev_priv->card_type >= NV_40) { + dev_priv->fb_obj = nouveau_dma_object_create(dev, + 0, nouveau_mem_fb_amount(dev), + NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); + + NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4); + } + return 0; } From 2fd812f8ef8adb09fd8d17cab869f9fc8b047d75 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 14 Nov 2006 09:00:31 +1100 Subject: [PATCH 045/129] Completely untested NV10/20/30 FIFO context switching changes. --- shared-core/nouveau_fifo.c | 116 ++++++++++++++++++++++++------------- shared-core/nouveau_reg.h | 14 +++++ 2 files changed, 89 insertions(+), 41 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index d4e5b1dd..c662165b 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -220,24 +220,9 @@ static void nouveau_context_init(drm_device_t *dev, { drm_nouveau_private_t *dev_priv = dev->dev_private; struct nouveau_object *cb_obj; - uint32_t ctx_addr,ctx_size; + uint32_t ctx_addr, ctx_size = 32; int i; - switch(dev_priv->card_type) - { - case NV_03: - case NV_04: - case NV_05: - ctx_size=32; - break; - case NV_10: - case NV_20: - case NV_30: - default: - ctx_size=64; - break; - } - cb_obj = dev_priv->fifos[init->channel].cmdbuf_obj; ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; @@ -247,28 +232,73 @@ static void nouveau_context_init(drm_device_t *dev, NV_WRITE(ctx_addr,init->put_base); NV_WRITE(ctx_addr+4,init->put_base); - if (dev_priv->card_type <= NV_05) - { - // that's what is done in nvosdk, but that part of the code is buggy so... - NV_WRITE(ctx_addr+8, cb_obj->instance >> 4); + // that's what is done in nvosdk, but that part of the code is buggy so... + NV_WRITE(ctx_addr+8, cb_obj->instance >> 4); #ifdef __BIG_ENDIAN - NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); #else - NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif - } - else - { - NV_WRITE(ctx_addr+12,cb_obj->instance >> 4/*DMA INST/DMA COUNT*/); -#ifdef __BIG_ENDIAN - NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); -#else - NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); -#endif - } - } +#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV10_RAMFC_##offset, (val)) +static void nouveau_nv10_context_init(drm_device_t *dev, + drm_nouveau_fifo_alloc_t *init) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_object *cb_obj; + uint32_t fifoctx; + int i; + + cb_obj = dev_priv->fifos[init->channel].cmdbuf_obj; + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + init->channel*64; + for (i=0;i<64;i+=4) + NV_WRITE(fifoctx + i, 0); + + /* Fill entries that are seen filled in dumps of nvidia driver just + * after channel's is put into DMA mode + */ + RAMFC_WR(DMA_PUT , init->put_base); + RAMFC_WR(DMA_GET , init->put_base); + RAMFC_WR(DMA_INSTANCE , cb_obj->instance >> 4); +#ifdef __BIG_ENDIAN + RAMFC_WR(DMA_FETCH, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES | + NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | + NV_PFIFO_CACH1_DMAF_MAX_REQS_4 | + NV_PFIFO_CACH1_BIG_ENDIAN); +#else + RAMFC_WR(DMA_FETCH, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES | + NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | + NV_PFIFO_CACH1_DMAF_MAX_REQS_4); +#endif + RAMFC_WR(DMA_SUBROUTINE, init->put_base); +} + +static void nouveau_nv10_context_save(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t fifoctx; + int channel; + + channel = NV_READ(NV_PFIFO_CACH1_PSH1) & (nouveau_fifo_number(dev)-1); + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64; + + RAMFC_WR(DMA_PUT , NV_READ(NV_PFIFO_CACH1_DMAP)); + RAMFC_WR(DMA_GET , NV_READ(NV_PFIFO_CACH1_DMAG)); + RAMFC_WR(REF_CNT , NV_READ(NV_PFIFO_CACH1_REF_CNT)); + RAMFC_WR(DMA_INSTANCE , NV_READ(NV_PFIFO_CACH1_DMAI)); + RAMFC_WR(DMA_STATE , NV_READ(NV_PFIFO_CACH1_DMAS)); + RAMFC_WR(DMA_FETCH , NV_READ(NV_PFIFO_CACH1_DMAF)); + RAMFC_WR(ENGINE , NV_READ(NV_PFIFO_CACH1_ENG)); + RAMFC_WR(PULL1_ENGINE , NV_READ(NV_PFIFO_CACH1_PUL1)); + RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV_PFIFO_CACH1_ACQUIRE_VALUE)); + RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMESTAMP)); + RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMEOUT)); + RAMFC_WR(SEMAPHORE , NV_READ(NV_PFIFO_CACH1_SEMAPHORE)); + RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV_PFIFO_CACH1_DMAG)); +} +#undef RAMFC_WR + #define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) static void nouveau_nv40_context_init(drm_device_t *dev, drm_nouveau_fifo_alloc_t *init) @@ -391,16 +421,20 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); - if (dev_priv->card_type < NV_40) + /* Save current channel's state to it's RAMFC entry. + * + * Then, construct inital RAMFC for new channel, I'm not entirely + * sure this is needed if we activate the channel immediately. + * My understanding is that the GPU will fill RAMFC itself when + * it switches away from the channel + */ + if (dev_priv->card_type < NV_10) { nouveau_context_init(dev, init); - else { - /* Save current channel's state to it's RAMFC entry */ + } else if (dev_priv->card_type < NV_40) { + nouveau_nv10_context_save(dev); + nouveau_nv10_context_init(dev, init); + } else { nouveau_nv40_context_save(dev); - /* Construct inital RAMFC for new channel, I'm not entirely - * sure this is needed if we activate the channel immediately. - * My understanding is that the GPU will fill RAMFC itself - * when it switches away from the channel - */ nouveau_nv40_context_init(dev, init); } diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 844ee865..fe42f986 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -193,6 +193,20 @@ #define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) /* RAMFC offsets */ +#define NV10_RAMFC_DMA_PUT 0x00 +#define NV10_RAMFC_DMA_GET 0x04 +#define NV10_RAMFC_REF_CNT 0x08 +#define NV10_RAMFC_DMA_INSTANCE 0x0C +#define NV10_RAMFC_DMA_STATE 0x10 +#define NV10_RAMFC_DMA_FETCH 0x14 +#define NV10_RAMFC_ENGINE 0x18 +#define NV10_RAMFC_PULL1_ENGINE 0x1C +#define NV10_RAMFC_ACQUIRE_VALUE 0x20 +#define NV10_RAMFC_ACQUIRE_TIMESTAMP 0x24 +#define NV10_RAMFC_ACQUIRE_TIMEOUT 0x28 +#define NV10_RAMFC_SEMAPHORE 0x2C +#define NV10_RAMFC_DMA_SUBROUTINE 0x30 + #define NV40_RAMFC_DMA_PUT 0x00 #define NV40_RAMFC_DMA_GET 0x04 #define NV40_RAMFC_REF_CNT 0x08 From 18bba3fa29187bb5122ed057989203dc05bc46aa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 17 Nov 2006 08:05:23 +1100 Subject: [PATCH 046/129] Dump some useful info when a PGRAPH error occurs. The "channel" detect doesn't work on my nv40, but the rest seems to produce sane info. --- shared-core/nouveau_fifo.c | 2 +- shared-core/nouveau_irq.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index c662165b..73c4e9f9 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -536,7 +536,7 @@ void nouveau_fifo_cleanup(drm_device_t* dev, DRMFILE filp) DRM_DEBUG("clearing FIFO enables from filp\n"); for(i=0;ififos[i].filp==filp) + if (dev_priv->fifos[i].used && dev_priv->fifos[i].filp==filp) nouveau_fifo_free(dev,i); /* check we still point at an active channel */ diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 6de4a5e4..9131125f 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -306,8 +306,33 @@ static void nouveau_pgraph_irq_handler(drm_device_t *dev) } if (status & NV_PGRAPH_INTR_ERROR) { + uint32_t nsource, nstatus, instance; + uint32_t address; + uint32_t channel; + uint32_t method, subc, data; + DRM_ERROR("NV: PGRAPH error interrupt\n"); + nstatus = NV_READ(0x00400104); + nsource = NV_READ(0x00400108); + DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus); + + instance = NV_READ(0x00400158); + DRM_DEBUG("instance:0x%08x\n", instance); + + address = NV_READ(0x400704); + data = NV_READ(0x400708); + channel = (address >> 20) & 0x1F; + subc = (address >> 16) & 0x7; + method = address & 0x1FFC; + DRM_DEBUG("NV: 0x400704 = 0x%08x\n", address); + DRM_ERROR("NV: Channel %d/%d (class 0x%04x) -" + "Method 0x%04x, Data 0x%08x\n", + channel, subc, + NV_READ(0x400160+subc*4) & 0xFFFF, + method, data + ); + status &= ~NV_PGRAPH_INTR_ERROR; NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_ERROR); } From e9194dd1b068666dd94e73d95dc3cd031a89a6b7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 18 Nov 2006 10:03:45 +1100 Subject: [PATCH 047/129] Check some return vals, fixes a couple of oopses. --- shared-core/nouveau_fifo.c | 4 ++++ shared-core/nouveau_object.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 73c4e9f9..441bde40 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -403,6 +403,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); } + if (!cb_obj) { + DRM_ERROR("unable to alloc object for command buffer\n"); + return DRM_ERR(EINVAL); + } dev_priv->fifos[i].cmdbuf_obj = cb_obj; /* that fifo is used */ diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index abd8bec5..0db92ec4 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -523,6 +523,8 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) int fifo; fifo = nouveau_fifo_id_get(dev, filp); + if (fifo == -1) + return DRM_ERR(EINVAL); DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_object_init_t __user *) data, sizeof(init)); @@ -577,6 +579,8 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS) int fifo; fifo = nouveau_fifo_id_get(dev, filp); + if (fifo == -1) + return DRM_ERR(EINVAL); DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_dma_object_init_t __user *) data, sizeof(init)); From 9ac7a8b0b4c0431b605c3f8d0b4a696903010c51 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 18 Nov 2006 10:09:29 +1100 Subject: [PATCH 048/129] Only return FIFO number if the FIFO is marked as in use.. --- shared-core/nouveau_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 441bde40..b6fc613c 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -564,7 +564,7 @@ int nouveau_fifo_id_get(drm_device_t* dev, DRMFILE filp) int i; for(i=0;ififos[i].filp == filp) + if (dev_priv->fifos[i].used && dev_priv->fifos[i].filp == filp) return i; return -1; } From adf71cb29b72b7d199f737b7b00eb7e80939ea4b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 21 Nov 2006 11:41:46 +1100 Subject: [PATCH 049/129] Don't spam dmesg if PMC_INTSTAT is 0 --- shared-core/nouveau_irq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 9131125f..160016ea 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -385,6 +385,8 @@ irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS) uint32_t status; status = NV_READ(NV_PMC_INTSTAT); + if (!status) + return IRQ_NONE; DRM_DEBUG("PMC INTSTAT: 0x%08x\n", status); From ddcb994c3eac97e153922e2a4c71384404f68597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 26 Oct 2006 13:15:30 +0200 Subject: [PATCH 050/129] i915_vblank_tasklet: Try harder to avoid tearing. Previously, if there were several buffer swaps scheduled for the same vertical blank, all but the first blit emitted stood a chance of exhibiting tearing. In order to avoid this, split the blits along slices of each output top to bottom. --- shared-core/i915_irq.c | 201 ++++++++++++++++++++++++++++------------- 1 file changed, 140 insertions(+), 61 deletions(-) diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index a48e1ff8..a9bbf971 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -46,88 +46,167 @@ static void i915_vblank_tasklet(drm_device_t *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; - struct list_head *list, *tmp; + struct list_head *list, *tmp, hits, *hit; + int nhits, nrects, slice[2], upper[2], lower[2], i; + unsigned counter[2] = { atomic_read(&dev->vbl_received), + atomic_read(&dev->vbl_received2) }; + drm_drawable_info_t *drw; + drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; + u32 cpp = dev_priv->cpp; + u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | + XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB) + : XY_SRC_COPY_BLT_CMD; + u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | + (cpp << 23) | (1 << 24); + RING_LOCALS; DRM_DEBUG("\n"); + INIT_LIST_HEAD(&hits); + + nhits = nrects = 0; + spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); + /* Find buffer swaps scheduled for this vertical blank */ list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { drm_i915_vbl_swap_t *vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); - atomic_t *counter = vbl_swap->pipe ? &dev->vbl_received2 : - &dev->vbl_received; - if ((atomic_read(counter) - vbl_swap->sequence) <= (1<<23)) { - drm_drawable_info_t *drw; + if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) + continue; - spin_unlock(&dev_priv->swaps_lock); + list_del(list); + dev_priv->swaps_pending--; - spin_lock(&dev->drw_lock); + spin_unlock(&dev_priv->swaps_lock); + spin_lock(&dev->drw_lock); - drw = drm_get_drawable_info(dev, vbl_swap->drw_id); - - if (drw) { - int i, num_rects = drw->num_rects; - drm_clip_rect_t *rect = drw->rects; - drm_i915_sarea_t *sarea_priv = - dev_priv->sarea_priv; - u32 cpp = dev_priv->cpp; - u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | - XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB) - : XY_SRC_COPY_BLT_CMD; - u32 pitchropcpp = (sarea_priv->pitch * cpp) | - (0xcc << 16) | (cpp << 23) | - (1 << 24); - RING_LOCALS; + drw = drm_get_drawable_info(dev, vbl_swap->drw_id); - i915_kernel_lost_context(dev); + if (!drw) { + spin_unlock(&dev->drw_lock); + drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); + spin_lock(&dev_priv->swaps_lock); + continue; + } - BEGIN_LP_RING(6); + list_for_each(hit, &hits) { + drm_i915_vbl_swap_t *swap_cmp = + list_entry(hit, drm_i915_vbl_swap_t, head); + drm_drawable_info_t *drw_cmp = + drm_get_drawable_info(dev, swap_cmp->drw_id); - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(0); - OUT_RING(0); - OUT_RING(sarea_priv->width | - sarea_priv->height << 16); - OUT_RING(sarea_priv->width | - sarea_priv->height << 16); - OUT_RING(0); + if (drw_cmp && + drw_cmp->rects[0].y1 > drw->rects[0].y1) { + list_add_tail(list, hit); + break; + } + } + + spin_unlock(&dev->drw_lock); + + /* List of hits was empty, or we reached the end of it */ + if (hit == &hits) + list_add_tail(list, hits.prev); + + nhits++; + + spin_lock(&dev_priv->swaps_lock); + } + + if (nhits == 0) { + spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); + return; + } + + spin_unlock(&dev_priv->swaps_lock); + + i915_kernel_lost_context(dev); + + BEGIN_LP_RING(6); + + OUT_RING(GFX_OP_DRAWRECT_INFO); + OUT_RING(0); + OUT_RING(0); + OUT_RING(sarea_priv->width | sarea_priv->height << 16); + OUT_RING(sarea_priv->width | sarea_priv->height << 16); + OUT_RING(0); + + ADVANCE_LP_RING(); + + sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; + + upper[0] = upper[1] = 0; + slice[0] = max(sarea_priv->pipeA_h / nhits, 1); + slice[1] = max(sarea_priv->pipeB_h / nhits, 1); + lower[0] = sarea_priv->pipeA_y + slice[0]; + lower[1] = sarea_priv->pipeB_y + slice[0]; + + spin_lock(&dev->drw_lock); + + /* Emit blits for buffer swaps, partitioning both outputs into as many + * slices as there are buffer swaps scheduled in order to avoid tearing + * (based on the assumption that a single buffer swap would always + * complete before scanout starts). + */ + for (i = 0; i++ < nhits; + upper[0] = lower[0], lower[0] += slice[0], + upper[1] = lower[1], lower[1] += slice[1]) { + if (i == nhits) + lower[0] = lower[1] = sarea_priv->height; + + list_for_each(hit, &hits) { + drm_i915_vbl_swap_t *swap_hit = + list_entry(hit, drm_i915_vbl_swap_t, head); + drm_clip_rect_t *rect; + int num_rects, pipe; + unsigned short top, bottom; + + drw = drm_get_drawable_info(dev, swap_hit->drw_id); + + if (!drw) + continue; + + rect = drw->rects; + pipe = swap_hit->pipe; + top = upper[pipe]; + bottom = lower[pipe]; + + for (num_rects = drw->num_rects; num_rects--; rect++) { + int y1 = max(rect->y1, top); + int y2 = min(rect->y2, bottom); + + if (y1 >= y2) + continue; + + BEGIN_LP_RING(8); + + OUT_RING(cmd); + OUT_RING(pitchropcpp); + OUT_RING((y1 << 16) | rect->x1); + OUT_RING((y2 << 16) | rect->x2); + OUT_RING(sarea_priv->front_offset); + OUT_RING((y1 << 16) | rect->x1); + OUT_RING(pitchropcpp & 0xffff); + OUT_RING(sarea_priv->back_offset); ADVANCE_LP_RING(); - - sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; - - for (i = 0; i < num_rects; i++, rect++) { - BEGIN_LP_RING(8); - - OUT_RING(cmd); - OUT_RING(pitchropcpp); - OUT_RING((rect->y1 << 16) | rect->x1); - OUT_RING((rect->y2 << 16) | rect->x2); - OUT_RING(sarea_priv->front_offset); - OUT_RING((rect->y1 << 16) | rect->x1); - OUT_RING(pitchropcpp & 0xffff); - OUT_RING(sarea_priv->back_offset); - - ADVANCE_LP_RING(); - } } - - spin_unlock(&dev->drw_lock); - - spin_lock(&dev_priv->swaps_lock); - - list_del(list); - - drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); - - dev_priv->swaps_pending--; } } - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); + spin_unlock_irqrestore(&dev->drw_lock, irqflags); + + list_for_each_safe(hit, tmp, &hits) { + drm_i915_vbl_swap_t *swap_hit = + list_entry(hit, drm_i915_vbl_swap_t, head); + + list_del(hit); + + drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER); + } } irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) From f48a7685bd7a241001cec89acd8cce6cdefa941e Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Tue, 28 Nov 2006 21:32:03 +0100 Subject: [PATCH 051/129] For nv10, bit 16 of RAMFC need to be set for 64 bytes fifo context. When cleaning a fifo, we shouldn't assume everybody use nv40 ;) Fill DMA_SUBROUTINE fill correct value. --- shared-core/nouveau_fifo.c | 27 +++++++++++++++++++++------ shared-core/nouveau_reg.h | 1 + 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index b6fc613c..d67cdc3c 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -44,6 +44,19 @@ int nouveau_fifo_number(drm_device_t* dev) } } +/* returns the size of fifo context */ +static int nouveau_fifo_ctx_size(drm_device_t* dev) +{ + drm_nouveau_private_t *dev_priv=dev->dev_private; + + if (dev_priv->card_type >= NV_40) + return 128; + else if (dev_priv->card_type >= NV_10) + return 64; + else + return 32; +} + /*********************************** * functions doing the actual work ***********************************/ @@ -99,7 +112,8 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) } else if (dev_priv->card_type >= NV_10) { dev_priv->ramfc_offset = 0x11400; dev_priv->ramfc_size = nouveau_fifo_number(dev) * 64; - NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); + NV_WRITE(NV_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) | + (1 << 16) /* 64 Bytes entry*/); } else { dev_priv->ramfc_offset = 0x11400; dev_priv->ramfc_size = nouveau_fifo_number(dev) * 32; @@ -271,7 +285,7 @@ static void nouveau_nv10_context_init(drm_device_t *dev, NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif - RAMFC_WR(DMA_SUBROUTINE, init->put_base); + RAMFC_WR(DMA_SUBROUTINE, 0); } static void nouveau_nv10_context_save(drm_device_t *dev) @@ -295,7 +309,7 @@ static void nouveau_nv10_context_save(drm_device_t *dev) RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMESTAMP)); RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMEOUT)); RAMFC_WR(SEMAPHORE , NV_READ(NV_PFIFO_CACH1_SEMAPHORE)); - RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV_PFIFO_CACH1_DMAG)); + RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV_PFIFO_CACH1_DMASR)); } #undef RAMFC_WR @@ -509,6 +523,7 @@ void nouveau_fifo_free(drm_device_t* dev,int n) { drm_nouveau_private_t *dev_priv = dev->dev_private; int i; + int ctx_size = nouveau_fifo_ctx_size(dev); dev_priv->fifos[n].used=0; DRM_INFO("%s: freeing fifo %d\n", __func__, n); @@ -520,10 +535,10 @@ void nouveau_fifo_free(drm_device_t* dev,int n) // FIXME XXX needs more code /* Clean RAMFC */ - for (i=0;i<128;i+=4) { + for (i=0;iramfc_offset + n*128 + i)); - NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + n*128 + i, 0); + dev_priv->ramfc_offset + n*ctx_size + i)); + NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + n*ctx_size + i, 0); } /* reenable the fifo caches */ diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index fe42f986..e56630f0 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -164,6 +164,7 @@ #define NV_PFIFO_CACH1_DMAP 0x00003240 #define NV_PFIFO_CACH1_DMAG 0x00003244 #define NV_PFIFO_CACH1_REF_CNT 0x00003248 +#define NV_PFIFO_CACH1_DMASR 0x0000324C #define NV_PFIFO_CACH1_PUL0 0x00003250 #define NV_PFIFO_CACH1_PUL1 0x00003254 #define NV_PFIFO_CACH1_HASH 0x00003258 From b1a9a769711d83af8ab4c7ba4eec52a05a351533 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 30 Nov 2006 08:35:42 +1100 Subject: [PATCH 052/129] Wrap access to objects in RAMIN. This will make it easier to support extra RAMIN in vram at a later point. --- shared-core/nouveau_drv.h | 4 ++ shared-core/nouveau_fifo.c | 11 ++++-- shared-core/nouveau_object.c | 74 +++++++++++++++++++----------------- shared-core/nouveau_state.c | 6 ++- 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 03c7bd12..93887839 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -169,6 +169,7 @@ extern struct nouveau_object *nouveau_dma_object_create(drm_device_t *dev, uint32_t offset, uint32_t size, int access, uint32_t target); extern int nouveau_ioctl_object_init(DRM_IOCTL_ARGS); extern int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS); +extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, uint32_t instance); /* nouveau_irq.c */ extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); @@ -187,5 +188,8 @@ extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, #define NV_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #endif +#define INSTANCE_WR(inst,ofs,val) NV_WRITE(NV_RAMIN+(inst)+((ofs)<<2),(val)) +#define INSTANCE_RD(inst,ofs) NV_READ(NV_RAMIN+(inst)+((ofs)<<2)) + #endif /* __NOUVEAU_DRV_H__ */ diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index d67cdc3c..9ff0563c 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -247,7 +247,7 @@ static void nouveau_context_init(drm_device_t *dev, NV_WRITE(ctx_addr,init->put_base); NV_WRITE(ctx_addr+4,init->put_base); // that's what is done in nvosdk, but that part of the code is buggy so... - NV_WRITE(ctx_addr+8, cb_obj->instance >> 4); + NV_WRITE(ctx_addr+8, nouveau_chip_instance_get(dev, cb_obj->instance)); #ifdef __BIG_ENDIAN NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); #else @@ -274,7 +274,8 @@ static void nouveau_nv10_context_init(drm_device_t *dev, */ RAMFC_WR(DMA_PUT , init->put_base); RAMFC_WR(DMA_GET , init->put_base); - RAMFC_WR(DMA_INSTANCE , cb_obj->instance >> 4); + RAMFC_WR(DMA_INSTANCE , nouveau_chip_instance_get(dev, + cb_obj->instance)); #ifdef __BIG_ENDIAN RAMFC_WR(DMA_FETCH, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES | NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | @@ -332,7 +333,8 @@ static void nouveau_nv40_context_init(drm_device_t *dev, */ RAMFC_WR(DMA_PUT , init->put_base); RAMFC_WR(DMA_GET , init->put_base); - RAMFC_WR(DMA_INSTANCE , cb_obj->instance >> 4); + RAMFC_WR(DMA_INSTANCE , nouveau_chip_instance_get(dev, + cb_obj->instance)); RAMFC_WR(DMA_FETCH , 0x30086078); RAMFC_WR(DMA_SUBROUTINE, init->put_base); RAMFC_WR(GRCTX_INSTANCE, 0); /* XXX */ @@ -471,7 +473,8 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV_PFIFO_CACH1_DMAP, init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base); - NV_WRITE(NV_PFIFO_CACH1_DMAI, cb_obj->instance >> 4); + NV_WRITE(NV_PFIFO_CACH1_DMAI, + nouveau_chip_instance_get(dev, cb_obj->instance)); NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 0db92ec4..2c899335 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -40,6 +40,15 @@ * - Get rid of DMA object creation, this should be wrapped by MM routines. */ +/* Translate a RAMIN offset into a value the card understands, will be useful + * in the future when we can access more instance ram which isn't mapped into + * the PRAMIN aperture + */ +uint32_t nouveau_chip_instance_get(drm_device_t *dev, uint32_t instance) +{ + return (instance>>4); +} + static void nouveau_object_link(drm_device_t *dev, int fifo_num, struct nouveau_object *obj) { @@ -171,14 +180,14 @@ static int nouveau_hash_table_insert(drm_device_t* dev, int fifo, NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, (fifo << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | (obj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT) | - (obj->instance>>4) + nouveau_chip_instance_get(dev, obj->instance) ); else NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, NV_RAMHT_CONTEXT_VALID | (fifo << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | (obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT) | - (obj->instance>>4) + nouveau_chip_instance_get(dev, obj->instance) ); obj->ht_loc = ofs; @@ -255,16 +264,15 @@ static void nouveau_object_instance_free(drm_device_t *dev, else count = 4; + /* Clean RAMIN entry */ DRM_DEBUG("Instance entry for 0x%08x" "(engine %d, class 0x%x) before destroy:\n", obj->handle, obj->engine, obj->class); - for (i=0;iinstance + (i*4))); - - /* Clean RAMIN entry */ - for (i=0;iinstance + (i*4), 0x00000000); + INSTANCE_RD(obj->instance, i)); + INSTANCE_WR(obj->instance, i, 0x00000000); + } /* Mark instance as free */ obj->instance -= objs->first_instance; @@ -336,21 +344,18 @@ struct nouveau_object *nouveau_dma_object_create(drm_device_t* dev, obj->engine = 0; obj->class = 0; - NV_WRITE(NV_RAMIN + obj->instance + 0, ((1<<12) - | (1<<13) - | (adjust<<20) - | (access<<14) - | (target<<16) - | 0x3D /* DMA_IN_MEMORY */) - ); - NV_WRITE(NV_RAMIN + obj->instance + 4, - size - 1); - NV_WRITE(NV_RAMIN + obj->instance + 8, + INSTANCE_WR(obj->instance, 0, ((1<<12) | (1<<13) | + (adjust << 20) | + (access << 14) | + (target << 16) | + 0x3D /* DMA_IN_MEMORY */)); + INSTANCE_WR(obj->instance, 1, size-1); + INSTANCE_WR(obj->instance, 2, frame | ((access != NV_DMA_ACCESS_RO) ? (1<<1) : 0)); /* I don't actually know what this is, the DMA objects I see * in renouveau dumps usually have this as the same as +8 */ - NV_WRITE(NV_RAMIN + obj->instance + 12, + INSTANCE_WR(obj->instance, 3, frame | ((access != NV_DMA_ACCESS_RO) ? (1<<1) : 0)); return obj; @@ -467,24 +472,25 @@ static struct nouveau_object *nouveau_context_object_create(drm_device_t* dev, obj->engine = 1; obj->class = class; - d0 = dma0 ? (dma0->instance >> 4) : 0; - d1 = dma1 ? (dma1->instance >> 4) : 0; - dn = dma_notifier ? (dma_notifier->instance >> 4) : 0; + d0 = dma0 ? nouveau_chip_instance_get(dev, dma0->instance) : 0; + d1 = dma1 ? nouveau_chip_instance_get(dev, dma1->instance) : 0; + dn = dma_notifier ? + nouveau_chip_instance_get(dev, dma_notifier->instance) : 0; if (dev_priv->card_type >= NV_40) { - NV_WRITE(NV_RAMIN + obj->instance + 0, class | flags0); - NV_WRITE(NV_RAMIN + obj->instance + 4, dn | flags1); - NV_WRITE(NV_RAMIN + obj->instance + 8, d0 | flags2); - NV_WRITE(NV_RAMIN + obj->instance + 12, d1); - NV_WRITE(NV_RAMIN + obj->instance + 16, 0x00000000); - NV_WRITE(NV_RAMIN + obj->instance + 20, 0x00000000); - NV_WRITE(NV_RAMIN + obj->instance + 24, 0x00000000); - NV_WRITE(NV_RAMIN + obj->instance + 28, 0x00000000); + INSTANCE_WR(obj->instance, 0, class | flags0); + INSTANCE_WR(obj->instance, 1, dn | flags1); + INSTANCE_WR(obj->instance, 2, d0 | flags2); + INSTANCE_WR(obj->instance, 3, d1); + INSTANCE_WR(obj->instance, 4, 0x00000000); + INSTANCE_WR(obj->instance, 5, 0x00000000); + INSTANCE_WR(obj->instance, 6, 0x00000000); + INSTANCE_WR(obj->instance, 7, 0x00000000); } else { - NV_WRITE(NV_RAMIN + obj->instance + 0, class | flags0); - NV_WRITE(NV_RAMIN + obj->instance + 4, (dn << 16) | flags1); - NV_WRITE(NV_RAMIN + obj->instance + 8, d0 | (d1 << 16)); - NV_WRITE(NV_RAMIN + obj->instance + 12, 0); + INSTANCE_WR(obj->instance, 0, class | flags0); + INSTANCE_WR(obj->instance, 1, (dn << 16) | flags1); + INSTANCE_WR(obj->instance, 2, d0 | (d1 << 16)); + INSTANCE_WR(obj->instance, 3, 0); } return obj; diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index b05442fb..1128da54 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -76,11 +76,15 @@ int nouveau_firstopen(struct drm_device *dev) /* FIXME: doesn't belong here, and have no idea what it's for.. */ if (dev_priv->card_type >= NV_40) { + uint32_t pg0220_inst; + dev_priv->fb_obj = nouveau_dma_object_create(dev, 0, nouveau_mem_fb_amount(dev), NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM); - NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4); + pg0220_inst = nouveau_chip_instance_get(dev, + dev_priv->fb_obj->instance); + NV_WRITE(NV_PGRAPH_NV40_UNK220, pg0220_inst); } return 0; From 80d75cf6950acf1a00a031ceb6511b26dcc9b056 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 30 Nov 2006 10:31:42 +1100 Subject: [PATCH 053/129] Use nouveau_mem.c to allocate RAMIN. --- shared-core/nouveau_drm.h | 1 + shared-core/nouveau_drv.h | 29 ++++++++-------- shared-core/nouveau_fifo.c | 8 +++++ shared-core/nouveau_mem.c | 43 +++++++++++++++++++++++ shared-core/nouveau_object.c | 67 ++++++++---------------------------- shared-core/nouveau_state.c | 3 -- 6 files changed, 81 insertions(+), 70 deletions(-) diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index 2517bbc3..2874d36a 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -69,6 +69,7 @@ drm_nouveau_dma_object_init_t; #define NOUVEAU_MEM_PINNED 0x00000010 #define NOUVEAU_MEM_USER_BACKED 0x00000020 #define NOUVEAU_MEM_MAPPED 0x00000040 +#define NOUVEAU_MEM_INSTANCE 0x00000080 /* internal */ typedef struct drm_nouveau_mem_alloc { int flags; diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 93887839..be8f4cf4 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -52,11 +52,12 @@ struct nouveau_object struct nouveau_object *next; struct nouveau_object *prev; + struct mem_block *instance; + uint32_t ht_loc; + uint32_t handle; int class; int engine; - uint32_t instance; - uint32_t ht_loc; }; #define NV_DMA_TARGET_VIDMEM 0 @@ -77,14 +78,6 @@ struct nouveau_fifo struct nouveau_object *objs; }; -struct nouveau_object_store -{ - uint32_t *inst_bmap; - uint32_t first_instance; - int num_instance; - int free_instance; -}; - struct mem_block { struct mem_block *next; struct mem_block *prev; @@ -119,7 +112,7 @@ typedef struct drm_nouveau_private { int fifo_alloc_count; struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; - struct nouveau_object_store objs; + /* RAMFC and RAMRO offsets */ uint32_t ramht_offset; uint32_t ramht_size; @@ -132,6 +125,7 @@ typedef struct drm_nouveau_private { struct mem_block *agp_heap; struct mem_block *fb_heap; struct mem_block *fb_nomap_heap; + struct mem_block *ramin_heap; struct nouveau_config config; } @@ -155,6 +149,12 @@ extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment extern void nouveau_mem_free(struct drm_device* dev, struct mem_block*); extern int nouveau_mem_init(struct drm_device *dev); extern void nouveau_mem_close(struct drm_device *dev); +extern int nouveau_instmem_init(struct drm_device *dev, + uint32_t offset, uint32_t size); +extern struct mem_block* nouveau_instmem_alloc(struct drm_device *dev, + uint32_t size, uint32_t align); +extern void nouveau_instmem_free(struct drm_device *dev, + struct mem_block *block); /* nouveau_fifo.c */ extern int nouveau_fifo_init(drm_device_t *dev); @@ -163,13 +163,12 @@ extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp); extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp); /* nouveau_object.c */ -extern int nouveau_object_init(drm_device_t *dev); extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp); extern struct nouveau_object *nouveau_dma_object_create(drm_device_t *dev, uint32_t offset, uint32_t size, int access, uint32_t target); extern int nouveau_ioctl_object_init(DRM_IOCTL_ARGS); extern int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS); -extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, uint32_t instance); +extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem); /* nouveau_irq.c */ extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); @@ -188,8 +187,8 @@ extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, #define NV_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #endif -#define INSTANCE_WR(inst,ofs,val) NV_WRITE(NV_RAMIN+(inst)+((ofs)<<2),(val)) -#define INSTANCE_RD(inst,ofs) NV_READ(NV_RAMIN+(inst)+((ofs)<<2)) +#define INSTANCE_WR(mem,ofs,val) NV_WRITE(NV_RAMIN+(uint32_t)(mem)->start+((ofs)<<2),(val)) +#define INSTANCE_RD(mem,ofs) NV_READ(NV_RAMIN+(uint32_t)(mem)->start+((ofs)<<2)) #endif /* __NOUVEAU_DRV_H__ */ diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 9ff0563c..94762139 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -69,6 +69,7 @@ static int nouveau_fifo_ctx_size(drm_device_t* dev) static int nouveau_fifo_instmem_configure(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t obj_base, obj_size; int i; /* Clear RAMIN */ @@ -123,6 +124,13 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) dev_priv->ramfc_offset, dev_priv->ramfc_size); + obj_base = dev_priv->ramfc_offset + dev_priv->ramfc_size; + obj_size = (512*1024) - obj_base; /*XXX: probably wrong on some cards*/ + if (nouveau_instmem_init(dev, obj_base, obj_size)) + return 1; + DRM_DEBUG("RAMIN object space: offset=0x%08x, size=%dKiB\n", + obj_base, obj_size>>10); + return 0; } diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 897badd4..93b9c869 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -443,6 +443,49 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) free_block(block); } +int nouveau_instmem_init(struct drm_device *dev, uint32_t offset, + uint32_t size) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + int ret; + + ret = init_heap(&dev_priv->ramin_heap, offset, size); + if (ret) { + dev_priv->ramin_heap = NULL; + DRM_ERROR("Failed to init RAMIN heap\n"); + } + + return ret; +} + +struct mem_block *nouveau_instmem_alloc(struct drm_device *dev, + uint32_t size, uint32_t align) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct mem_block *block; + + if (!dev_priv->ramin_heap) { + DRM_ERROR("instmem alloc called without init\n"); + return NULL; + } + + block = alloc_block(dev_priv->ramin_heap, size, align, (DRMFILE)-2); + if (block) { + block->flags = NOUVEAU_MEM_INSTANCE; + DRM_DEBUG("instance(size=%d, align=%d) alloc'd at 0x%08x\n", + size, (1<start); + } + + return block; +} + +void nouveau_instmem_free(struct drm_device *dev, struct mem_block *block) +{ + if (dev && block) { + free_block(block); + } +} + /* * Ioctls */ diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 2c899335..c11b05eb 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -44,9 +44,13 @@ * in the future when we can access more instance ram which isn't mapped into * the PRAMIN aperture */ -uint32_t nouveau_chip_instance_get(drm_device_t *dev, uint32_t instance) +uint32_t nouveau_chip_instance_get(drm_device_t *dev, + struct mem_block *mem) { - return (instance>>4); + uint32_t inst = (uint32_t)mem->start >> 4; + DRM_DEBUG("****** on-chip instance for 0x%016llx = 0x%08x\n", + mem->start, inst); + return inst; } static void nouveau_object_link(drm_device_t *dev, int fifo_num, @@ -212,27 +216,7 @@ static void nouveau_hash_table_remove(drm_device_t* dev, static struct nouveau_object *nouveau_instance_alloc(drm_device_t* dev) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_object_store *objs=&dev_priv->objs; struct nouveau_object *obj; - int instance = -1; - int i = 0, j = 0; - - /* Allocate a block of instance RAM */ - if (!objs->free_instance) { - DRM_ERROR("no free instance ram\n"); - return NULL; - } - for (i=0;i<(objs->num_instance>>5);i++) { - if (objs->inst_bmap[i] == ~0) continue; - for (j=0;j<32;j++) { - if (!(objs->inst_bmap[i] & (1<instance = objs->first_instance; - obj->instance += (instance << (dev_priv->card_type >= NV_40 ? 5 : 4)); - DRM_DEBUG("instance address is 0x%08x\n", instance); - - /* Mark instance slot as used */ - objs->inst_bmap[i] |= (1 << j); - objs->free_instance--; + obj->instance = nouveau_instmem_alloc(dev, + (dev_priv->card_type >= NV_40 ? 32 : 16), 4); + if (!obj->instance) { + DRM_ERROR("couldn't alloc RAMIN for object\n"); + drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER); + return NULL; + } return obj; } @@ -255,9 +239,7 @@ static void nouveau_object_instance_free(drm_device_t *dev, struct nouveau_object *obj) { drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_object_store *objs=&dev_priv->objs; int count, i; - uint32_t be, bb; if (dev_priv->card_type >= NV_40) count = 8; @@ -274,27 +256,8 @@ static void nouveau_object_instance_free(drm_device_t *dev, INSTANCE_WR(obj->instance, i, 0x00000000); } - /* Mark instance as free */ - obj->instance -= objs->first_instance; - obj->instance >>= (dev_priv->card_type >=NV_40 ? 5 : 4); - be = obj->instance / 32; - bb = obj->instance % 32; - objs->inst_bmap[be] &= ~(1<free_instance++; -} - -int nouveau_object_init(drm_device_t* dev) -{ - drm_nouveau_private_t *dev_priv=dev->dev_private; - - dev_priv->objs.first_instance = - dev_priv->ramfc_offset +dev_priv->ramfc_size; - dev_priv->objs.free_instance = 1024; /*FIXME*/ - dev_priv->objs.num_instance = 1024; /*FIXME*/ - dev_priv->objs.inst_bmap = drm_calloc - (1, dev_priv->objs.num_instance/32, DRM_MEM_DRIVER); - - return 0; + /* Free RAMIN */ + nouveau_instmem_free(dev, obj->instance); } /* diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 1128da54..b2934b43 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -70,9 +70,6 @@ int nouveau_firstopen(struct drm_device *dev) */ ret = nouveau_fifo_init(dev); if (ret) return ret; - /* Initialise instance memory allocation */ - ret = nouveau_object_init(dev); - if (ret) return ret; /* FIXME: doesn't belong here, and have no idea what it's for.. */ if (dev_priv->card_type >= NV_40) { From 4a0e61d91013f88ca9555a280e2363bed14aec02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Sat, 21 Oct 2006 16:14:20 +0200 Subject: [PATCH 054/129] Track linux-core symlinks in git. --- .gitignore | 102 +++++++++++++++++++------------------- linux-core/Makefile | 39 ++------------- linux-core/drm.h | 1 + linux-core/drm_drawable.c | 1 + linux-core/drm_sarea.h | 1 + linux-core/i915_dma.c | 1 + linux-core/i915_drm.h | 1 + linux-core/i915_drv.h | 1 + linux-core/i915_irq.c | 1 + linux-core/i915_mem.c | 1 + linux-core/linux | 1 + linux-core/mach64_dma.c | 1 + linux-core/mach64_drm.h | 1 + linux-core/mach64_drv.h | 1 + linux-core/mach64_irq.c | 1 + linux-core/mach64_state.c | 1 + linux-core/mga_dma.c | 1 + linux-core/mga_drm.h | 1 + linux-core/mga_drv.h | 1 + linux-core/mga_irq.c | 1 + linux-core/mga_state.c | 1 + linux-core/mga_ucode.h | 1 + linux-core/mga_warp.c | 1 + linux-core/nv_drv.h | 1 + linux-core/r128_cce.c | 1 + linux-core/r128_drm.h | 1 + linux-core/r128_drv.h | 1 + linux-core/r128_irq.c | 1 + linux-core/r128_state.c | 1 + linux-core/r300_cmdbuf.c | 1 + linux-core/r300_reg.h | 1 + linux-core/radeon_cp.c | 1 + linux-core/radeon_drm.h | 1 + linux-core/radeon_drv.h | 1 + linux-core/radeon_irq.c | 1 + linux-core/radeon_mem.c | 1 + linux-core/radeon_state.c | 1 + linux-core/savage_bci.c | 1 + linux-core/savage_drm.h | 1 + linux-core/savage_drv.h | 1 + linux-core/savage_state.c | 1 + linux-core/sis_drm.h | 1 + linux-core/sis_drv.h | 1 + linux-core/tdfx_drv.h | 1 + linux-core/via_3d_reg.h | 1 + linux-core/via_dma.c | 1 + linux-core/via_drm.h | 1 + linux-core/via_drv.c | 1 + linux-core/via_drv.h | 1 + linux-core/via_irq.c | 1 + linux-core/via_map.c | 1 + linux-core/via_verifier.c | 1 + linux-core/via_verifier.h | 1 + linux-core/via_video.c | 1 + 54 files changed, 106 insertions(+), 87 deletions(-) create mode 120000 linux-core/drm.h create mode 120000 linux-core/drm_drawable.c create mode 120000 linux-core/drm_sarea.h create mode 120000 linux-core/i915_dma.c create mode 120000 linux-core/i915_drm.h create mode 120000 linux-core/i915_drv.h create mode 120000 linux-core/i915_irq.c create mode 120000 linux-core/i915_mem.c create mode 120000 linux-core/linux create mode 120000 linux-core/mach64_dma.c create mode 120000 linux-core/mach64_drm.h create mode 120000 linux-core/mach64_drv.h create mode 120000 linux-core/mach64_irq.c create mode 120000 linux-core/mach64_state.c create mode 120000 linux-core/mga_dma.c create mode 120000 linux-core/mga_drm.h create mode 120000 linux-core/mga_drv.h create mode 120000 linux-core/mga_irq.c create mode 120000 linux-core/mga_state.c create mode 120000 linux-core/mga_ucode.h create mode 120000 linux-core/mga_warp.c create mode 120000 linux-core/nv_drv.h create mode 120000 linux-core/r128_cce.c create mode 120000 linux-core/r128_drm.h create mode 120000 linux-core/r128_drv.h create mode 120000 linux-core/r128_irq.c create mode 120000 linux-core/r128_state.c create mode 120000 linux-core/r300_cmdbuf.c create mode 120000 linux-core/r300_reg.h create mode 120000 linux-core/radeon_cp.c create mode 120000 linux-core/radeon_drm.h create mode 120000 linux-core/radeon_drv.h create mode 120000 linux-core/radeon_irq.c create mode 120000 linux-core/radeon_mem.c create mode 120000 linux-core/radeon_state.c create mode 120000 linux-core/savage_bci.c create mode 120000 linux-core/savage_drm.h create mode 120000 linux-core/savage_drv.h create mode 120000 linux-core/savage_state.c create mode 120000 linux-core/sis_drm.h create mode 120000 linux-core/sis_drv.h create mode 120000 linux-core/tdfx_drv.h create mode 120000 linux-core/via_3d_reg.h create mode 120000 linux-core/via_dma.c create mode 120000 linux-core/via_drm.h create mode 120000 linux-core/via_drv.c create mode 120000 linux-core/via_drv.h create mode 120000 linux-core/via_irq.c create mode 120000 linux-core/via_map.c create mode 120000 linux-core/via_verifier.c create mode 120000 linux-core/via_verifier.h create mode 120000 linux-core/via_video.c diff --git a/.gitignore b/.gitignore index 333bbadc..4386f408 100644 --- a/.gitignore +++ b/.gitignore @@ -1,54 +1,54 @@ -*-core/linux -*-core/drm.h -*-core/drm_sarea.h -*-core/i915_dma.c -*-core/i915_drm.h -*-core/i915_drv.h -*-core/i915_irq.c -*-core/i915_mem.c -*-core/mach64_dma.c -*-core/mach64_drm.h -*-core/mach64_drv.h -*-core/mach64_irq.c -*-core/mach64_state.c -*-core/mga_dma.c -*-core/mga_drm.h -*-core/mga_drv.h -*-core/mga_irq.c -*-core/mga_state.c -*-core/mga_ucode.h -*-core/mga_warp.c -*-core/nv_drv.h -*-core/r128_cce.c -*-core/r128_drm.h -*-core/r128_drv.h -*-core/r128_irq.c -*-core/r128_state.c -*-core/r300_cmdbuf.c -*-core/r300_reg.h -*-core/radeon_cp.c -*-core/radeon_drm.h -*-core/radeon_drv.h -*-core/radeon_irq.c -*-core/radeon_mem.c -*-core/radeon_state.c -*-core/savage_bci.c -*-core/savage_drm.h -*-core/savage_drv.h -*-core/savage_state.c -*-core/sis_drm.h -*-core/sis_drv.h -*-core/tdfx_drv.h -*-core/via_3d_reg.h -*-core/via_dma.c -*-core/via_drm.h -*-core/via_drv.c -*-core/via_drv.h -*-core/via_irq.c -*-core/via_map.c -*-core/via_verifier.c -*-core/via_verifier.h -*-core/via_video.c +bsd-core/linux +bsd-core/drm.h +bsd-core/drm_sarea.h +bsd-core/i915_dma.c +bsd-core/i915_drm.h +bsd-core/i915_drv.h +bsd-core/i915_irq.c +bsd-core/i915_mem.c +bsd-core/mach64_dma.c +bsd-core/mach64_drm.h +bsd-core/mach64_drv.h +bsd-core/mach64_irq.c +bsd-core/mach64_state.c +bsd-core/mga_dma.c +bsd-core/mga_drm.h +bsd-core/mga_drv.h +bsd-core/mga_irq.c +bsd-core/mga_state.c +bsd-core/mga_ucode.h +bsd-core/mga_warp.c +bsd-core/nv_drv.h +bsd-core/r128_cce.c +bsd-core/r128_drm.h +bsd-core/r128_drv.h +bsd-core/r128_irq.c +bsd-core/r128_state.c +bsd-core/r300_cmdbuf.c +bsd-core/r300_reg.h +bsd-core/radeon_cp.c +bsd-core/radeon_drm.h +bsd-core/radeon_drv.h +bsd-core/radeon_irq.c +bsd-core/radeon_mem.c +bsd-core/radeon_state.c +bsd-core/savage_bci.c +bsd-core/savage_drm.h +bsd-core/savage_drv.h +bsd-core/savage_state.c +bsd-core/sis_drm.h +bsd-core/sis_drv.h +bsd-core/tdfx_drv.h +bsd-core/via_3d_reg.h +bsd-core/via_dma.c +bsd-core/via_drm.h +bsd-core/via_drv.c +bsd-core/via_drv.h +bsd-core/via_irq.c +bsd-core/via_map.c +bsd-core/via_verifier.c +bsd-core/via_verifier.h +bsd-core/via_video.c *.flags *.ko *.ko.cmd diff --git a/linux-core/Makefile b/linux-core/Makefile index 3aecec43..b4cff78a 100644 --- a/linux-core/Makefile +++ b/linux-core/Makefile @@ -75,45 +75,26 @@ DRM_MODULES ?= $(MODULE_LIST) # These definitions are for handling dependencies in the out of kernel build. -DRMSHARED = drm.h drm_sarea.h drm_drawable.c DRMHEADERS = drmP.h drm_compat.h drm_os_linux.h drm.h drm_sarea.h COREHEADERS = drm_core.h drm_sman.h drm_hashtab.h TDFXHEADERS = tdfx_drv.h $(DRMHEADERS) -TDFXSHARED = tdfx_drv.h R128HEADERS = r128_drv.h r128_drm.h $(DRMHEADERS) -R128SHARED = r128_drv.h r128_drm.h r128_cce.c r128_state.c r128_irq.c RADEONHEADERS = radeon_drv.h radeon_drm.h r300_reg.h $(DRMHEADERS) -RADEONSHARED = radeon_drv.h radeon_drm.h radeon_cp.c radeon_irq.c \ - radeon_mem.c radeon_state.c r300_cmdbuf.c r300_reg.h MGAHEADERS = mga_drv.h mga_drm.h mga_ucode.h $(DRMHEADERS) -MGASHARED = mga_dma.c mga_drm.h mga_drv.h mga_irq.c mga_state.c \ - mga_ucode.h mga_warp.c I810HEADERS = i810_drv.h i810_drm.h $(DRMHEADERS) I830HEADERS = i830_drv.h i830_drm.h $(DRMHEADERS) I915HEADERS = i915_drv.h i915_drm.h $(DRMHEADERS) -I915SHARED = i915_drv.h i915_drm.h i915_irq.c i915_mem.c i915_dma.c SISHEADERS= sis_drv.h sis_drm.h drm_hashtab.h drm_sman.h $(DRMHEADERS) -SISSHARED= sis_drv.h sis_drm.h SAVAGEHEADERS= savage_drv.h savage_drm.h $(DRMHEADERS) -SAVAGESHARED= savage_drv.h savage_drm.h savage_bci.c savage_state.c VIAHEADERS = via_drm.h via_drv.h via_3d_reg.h via_verifier.h $(DRMHEADERS) -VIASHARED = via_drm.h via_drv.h via_3d_reg.h via_drv.c via_irq.c via_map.c \ - via_dma.c via_verifier.c via_verifier.h via_video.c MACH64HEADERS = mach64_drv.h mach64_drm.h $(DRMHEADERS) -MACH64SHARED = mach64_drv.h mach64_drm.h mach64_dma.c \ - mach64_irq.c mach64_state.c NVHEADERS = nv_drv.h $(DRMHEADERS) -NVSHARED = nv_drv.h FFBHEADERS = ffb_drv.h $(DRMHEADERS) -SHAREDSRC = $(DRMSHARED) $(MGASHARED) $(R128SHARED) $(RADEONSHARED) \ - $(SISSHARED) $(TDFXSHARED) $(VIASHARED) $(MACH64SHARED) \ - $(I915SHARED) $(SAVAGESHARED) $(NVSHARED) - PROGS = dristat drmstat -CLEANFILES = *.o *.ko $(PROGS) .depend .*.flags .*.d .*.cmd *.mod.c linux drm_pciids.h .tmp_versions +CLEANFILES = *.o *.ko $(PROGS) .depend .*.flags .*.d .*.cmd *.mod.c drm_pciids.h .tmp_versions # VERSION is not defined from the initial invocation. It is defined when # this Makefile is invoked from the kernel's root Makefile. @@ -226,27 +207,13 @@ endif SHAREDDIR := ../shared-core -HASSHARED := $(shell if [ -d $(SHAREDDIR) ]; then echo y; fi) - -ifeq ($(HASSHARED),y) -includes:: $(SHAREDSRC) drm_pciids.h +ifeq ($(shell if [ -d $(SHAREDDIR) ]; then echo y; fi),y) +includes:: drm_pciids.h drm_pciids.h: $(SHAREDDIR)/drm_pciids.txt sh ../scripts/create_linux_pci_lists.sh < $(SHAREDDIR)/drm_pciids.txt - -$(SHAREDSRC): - @if [ -r $(SHAREDDIR)/$@ ]; then \ - (rm -f $@; set -x; ln -s $(SHAREDDIR)/$@ $@); fi - -CLEANFILES += $(SHAREDSRC) endif -includes:: linux - -linux: - rm -f linux - ln -s . linux - clean cleandir: rm -rf $(CLEANFILES) diff --git a/linux-core/drm.h b/linux-core/drm.h new file mode 120000 index 00000000..29636692 --- /dev/null +++ b/linux-core/drm.h @@ -0,0 +1 @@ +../shared-core/drm.h \ No newline at end of file diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c new file mode 120000 index 00000000..d64bbe10 --- /dev/null +++ b/linux-core/drm_drawable.c @@ -0,0 +1 @@ +../shared-core/drm_drawable.c \ No newline at end of file diff --git a/linux-core/drm_sarea.h b/linux-core/drm_sarea.h new file mode 120000 index 00000000..fd428f42 --- /dev/null +++ b/linux-core/drm_sarea.h @@ -0,0 +1 @@ +../shared-core/drm_sarea.h \ No newline at end of file diff --git a/linux-core/i915_dma.c b/linux-core/i915_dma.c new file mode 120000 index 00000000..c61d967e --- /dev/null +++ b/linux-core/i915_dma.c @@ -0,0 +1 @@ +../shared-core/i915_dma.c \ No newline at end of file diff --git a/linux-core/i915_drm.h b/linux-core/i915_drm.h new file mode 120000 index 00000000..ed53f01d --- /dev/null +++ b/linux-core/i915_drm.h @@ -0,0 +1 @@ +../shared-core/i915_drm.h \ No newline at end of file diff --git a/linux-core/i915_drv.h b/linux-core/i915_drv.h new file mode 120000 index 00000000..085558ca --- /dev/null +++ b/linux-core/i915_drv.h @@ -0,0 +1 @@ +../shared-core/i915_drv.h \ No newline at end of file diff --git a/linux-core/i915_irq.c b/linux-core/i915_irq.c new file mode 120000 index 00000000..2058a2e4 --- /dev/null +++ b/linux-core/i915_irq.c @@ -0,0 +1 @@ +../shared-core/i915_irq.c \ No newline at end of file diff --git a/linux-core/i915_mem.c b/linux-core/i915_mem.c new file mode 120000 index 00000000..e8e56553 --- /dev/null +++ b/linux-core/i915_mem.c @@ -0,0 +1 @@ +../shared-core/i915_mem.c \ No newline at end of file diff --git a/linux-core/linux b/linux-core/linux new file mode 120000 index 00000000..945c9b46 --- /dev/null +++ b/linux-core/linux @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/linux-core/mach64_dma.c b/linux-core/mach64_dma.c new file mode 120000 index 00000000..e5c28975 --- /dev/null +++ b/linux-core/mach64_dma.c @@ -0,0 +1 @@ +../shared-core/mach64_dma.c \ No newline at end of file diff --git a/linux-core/mach64_drm.h b/linux-core/mach64_drm.h new file mode 120000 index 00000000..136ea936 --- /dev/null +++ b/linux-core/mach64_drm.h @@ -0,0 +1 @@ +../shared-core/mach64_drm.h \ No newline at end of file diff --git a/linux-core/mach64_drv.h b/linux-core/mach64_drv.h new file mode 120000 index 00000000..85222cc2 --- /dev/null +++ b/linux-core/mach64_drv.h @@ -0,0 +1 @@ +../shared-core/mach64_drv.h \ No newline at end of file diff --git a/linux-core/mach64_irq.c b/linux-core/mach64_irq.c new file mode 120000 index 00000000..a1235d58 --- /dev/null +++ b/linux-core/mach64_irq.c @@ -0,0 +1 @@ +../shared-core/mach64_irq.c \ No newline at end of file diff --git a/linux-core/mach64_state.c b/linux-core/mach64_state.c new file mode 120000 index 00000000..b11f202c --- /dev/null +++ b/linux-core/mach64_state.c @@ -0,0 +1 @@ +../shared-core/mach64_state.c \ No newline at end of file diff --git a/linux-core/mga_dma.c b/linux-core/mga_dma.c new file mode 120000 index 00000000..f290be9b --- /dev/null +++ b/linux-core/mga_dma.c @@ -0,0 +1 @@ +../shared-core/mga_dma.c \ No newline at end of file diff --git a/linux-core/mga_drm.h b/linux-core/mga_drm.h new file mode 120000 index 00000000..1c87036f --- /dev/null +++ b/linux-core/mga_drm.h @@ -0,0 +1 @@ +../shared-core/mga_drm.h \ No newline at end of file diff --git a/linux-core/mga_drv.h b/linux-core/mga_drv.h new file mode 120000 index 00000000..cb0c9e1d --- /dev/null +++ b/linux-core/mga_drv.h @@ -0,0 +1 @@ +../shared-core/mga_drv.h \ No newline at end of file diff --git a/linux-core/mga_irq.c b/linux-core/mga_irq.c new file mode 120000 index 00000000..cf521d29 --- /dev/null +++ b/linux-core/mga_irq.c @@ -0,0 +1 @@ +../shared-core/mga_irq.c \ No newline at end of file diff --git a/linux-core/mga_state.c b/linux-core/mga_state.c new file mode 120000 index 00000000..8bda8ba9 --- /dev/null +++ b/linux-core/mga_state.c @@ -0,0 +1 @@ +../shared-core/mga_state.c \ No newline at end of file diff --git a/linux-core/mga_ucode.h b/linux-core/mga_ucode.h new file mode 120000 index 00000000..728b9aca --- /dev/null +++ b/linux-core/mga_ucode.h @@ -0,0 +1 @@ +../shared-core/mga_ucode.h \ No newline at end of file diff --git a/linux-core/mga_warp.c b/linux-core/mga_warp.c new file mode 120000 index 00000000..d35b3255 --- /dev/null +++ b/linux-core/mga_warp.c @@ -0,0 +1 @@ +../shared-core/mga_warp.c \ No newline at end of file diff --git a/linux-core/nv_drv.h b/linux-core/nv_drv.h new file mode 120000 index 00000000..c9617800 --- /dev/null +++ b/linux-core/nv_drv.h @@ -0,0 +1 @@ +../shared-core/nv_drv.h \ No newline at end of file diff --git a/linux-core/r128_cce.c b/linux-core/r128_cce.c new file mode 120000 index 00000000..0c1d659e --- /dev/null +++ b/linux-core/r128_cce.c @@ -0,0 +1 @@ +../shared-core/r128_cce.c \ No newline at end of file diff --git a/linux-core/r128_drm.h b/linux-core/r128_drm.h new file mode 120000 index 00000000..363852cb --- /dev/null +++ b/linux-core/r128_drm.h @@ -0,0 +1 @@ +../shared-core/r128_drm.h \ No newline at end of file diff --git a/linux-core/r128_drv.h b/linux-core/r128_drv.h new file mode 120000 index 00000000..4f7e822d --- /dev/null +++ b/linux-core/r128_drv.h @@ -0,0 +1 @@ +../shared-core/r128_drv.h \ No newline at end of file diff --git a/linux-core/r128_irq.c b/linux-core/r128_irq.c new file mode 120000 index 00000000..66d28b05 --- /dev/null +++ b/linux-core/r128_irq.c @@ -0,0 +1 @@ +../shared-core/r128_irq.c \ No newline at end of file diff --git a/linux-core/r128_state.c b/linux-core/r128_state.c new file mode 120000 index 00000000..e83d84b5 --- /dev/null +++ b/linux-core/r128_state.c @@ -0,0 +1 @@ +../shared-core/r128_state.c \ No newline at end of file diff --git a/linux-core/r300_cmdbuf.c b/linux-core/r300_cmdbuf.c new file mode 120000 index 00000000..6674d056 --- /dev/null +++ b/linux-core/r300_cmdbuf.c @@ -0,0 +1 @@ +../shared-core/r300_cmdbuf.c \ No newline at end of file diff --git a/linux-core/r300_reg.h b/linux-core/r300_reg.h new file mode 120000 index 00000000..ef54eba2 --- /dev/null +++ b/linux-core/r300_reg.h @@ -0,0 +1 @@ +../shared-core/r300_reg.h \ No newline at end of file diff --git a/linux-core/radeon_cp.c b/linux-core/radeon_cp.c new file mode 120000 index 00000000..ee860943 --- /dev/null +++ b/linux-core/radeon_cp.c @@ -0,0 +1 @@ +../shared-core/radeon_cp.c \ No newline at end of file diff --git a/linux-core/radeon_drm.h b/linux-core/radeon_drm.h new file mode 120000 index 00000000..54f595a3 --- /dev/null +++ b/linux-core/radeon_drm.h @@ -0,0 +1 @@ +../shared-core/radeon_drm.h \ No newline at end of file diff --git a/linux-core/radeon_drv.h b/linux-core/radeon_drv.h new file mode 120000 index 00000000..5b415ea8 --- /dev/null +++ b/linux-core/radeon_drv.h @@ -0,0 +1 @@ +../shared-core/radeon_drv.h \ No newline at end of file diff --git a/linux-core/radeon_irq.c b/linux-core/radeon_irq.c new file mode 120000 index 00000000..2f394a5e --- /dev/null +++ b/linux-core/radeon_irq.c @@ -0,0 +1 @@ +../shared-core/radeon_irq.c \ No newline at end of file diff --git a/linux-core/radeon_mem.c b/linux-core/radeon_mem.c new file mode 120000 index 00000000..8cc27989 --- /dev/null +++ b/linux-core/radeon_mem.c @@ -0,0 +1 @@ +../shared-core/radeon_mem.c \ No newline at end of file diff --git a/linux-core/radeon_state.c b/linux-core/radeon_state.c new file mode 120000 index 00000000..ccee8761 --- /dev/null +++ b/linux-core/radeon_state.c @@ -0,0 +1 @@ +../shared-core/radeon_state.c \ No newline at end of file diff --git a/linux-core/savage_bci.c b/linux-core/savage_bci.c new file mode 120000 index 00000000..b8436713 --- /dev/null +++ b/linux-core/savage_bci.c @@ -0,0 +1 @@ +../shared-core/savage_bci.c \ No newline at end of file diff --git a/linux-core/savage_drm.h b/linux-core/savage_drm.h new file mode 120000 index 00000000..0dab2e3b --- /dev/null +++ b/linux-core/savage_drm.h @@ -0,0 +1 @@ +../shared-core/savage_drm.h \ No newline at end of file diff --git a/linux-core/savage_drv.h b/linux-core/savage_drv.h new file mode 120000 index 00000000..8397009c --- /dev/null +++ b/linux-core/savage_drv.h @@ -0,0 +1 @@ +../shared-core/savage_drv.h \ No newline at end of file diff --git a/linux-core/savage_state.c b/linux-core/savage_state.c new file mode 120000 index 00000000..e55dc5d4 --- /dev/null +++ b/linux-core/savage_state.c @@ -0,0 +1 @@ +../shared-core/savage_state.c \ No newline at end of file diff --git a/linux-core/sis_drm.h b/linux-core/sis_drm.h new file mode 120000 index 00000000..36c77aac --- /dev/null +++ b/linux-core/sis_drm.h @@ -0,0 +1 @@ +../shared-core/sis_drm.h \ No newline at end of file diff --git a/linux-core/sis_drv.h b/linux-core/sis_drv.h new file mode 120000 index 00000000..3fddfdae --- /dev/null +++ b/linux-core/sis_drv.h @@ -0,0 +1 @@ +../shared-core/sis_drv.h \ No newline at end of file diff --git a/linux-core/tdfx_drv.h b/linux-core/tdfx_drv.h new file mode 120000 index 00000000..8df70329 --- /dev/null +++ b/linux-core/tdfx_drv.h @@ -0,0 +1 @@ +../shared-core/tdfx_drv.h \ No newline at end of file diff --git a/linux-core/via_3d_reg.h b/linux-core/via_3d_reg.h new file mode 120000 index 00000000..90d238ec --- /dev/null +++ b/linux-core/via_3d_reg.h @@ -0,0 +1 @@ +../shared-core/via_3d_reg.h \ No newline at end of file diff --git a/linux-core/via_dma.c b/linux-core/via_dma.c new file mode 120000 index 00000000..1f4d920f --- /dev/null +++ b/linux-core/via_dma.c @@ -0,0 +1 @@ +../shared-core/via_dma.c \ No newline at end of file diff --git a/linux-core/via_drm.h b/linux-core/via_drm.h new file mode 120000 index 00000000..7cd175d3 --- /dev/null +++ b/linux-core/via_drm.h @@ -0,0 +1 @@ +../shared-core/via_drm.h \ No newline at end of file diff --git a/linux-core/via_drv.c b/linux-core/via_drv.c new file mode 120000 index 00000000..b6ff160e --- /dev/null +++ b/linux-core/via_drv.c @@ -0,0 +1 @@ +../shared-core/via_drv.c \ No newline at end of file diff --git a/linux-core/via_drv.h b/linux-core/via_drv.h new file mode 120000 index 00000000..8954fe88 --- /dev/null +++ b/linux-core/via_drv.h @@ -0,0 +1 @@ +../shared-core/via_drv.h \ No newline at end of file diff --git a/linux-core/via_irq.c b/linux-core/via_irq.c new file mode 120000 index 00000000..f615af87 --- /dev/null +++ b/linux-core/via_irq.c @@ -0,0 +1 @@ +../shared-core/via_irq.c \ No newline at end of file diff --git a/linux-core/via_map.c b/linux-core/via_map.c new file mode 120000 index 00000000..b5056634 --- /dev/null +++ b/linux-core/via_map.c @@ -0,0 +1 @@ +../shared-core/via_map.c \ No newline at end of file diff --git a/linux-core/via_verifier.c b/linux-core/via_verifier.c new file mode 120000 index 00000000..00b411bd --- /dev/null +++ b/linux-core/via_verifier.c @@ -0,0 +1 @@ +../shared-core/via_verifier.c \ No newline at end of file diff --git a/linux-core/via_verifier.h b/linux-core/via_verifier.h new file mode 120000 index 00000000..62d3e287 --- /dev/null +++ b/linux-core/via_verifier.h @@ -0,0 +1 @@ +../shared-core/via_verifier.h \ No newline at end of file diff --git a/linux-core/via_video.c b/linux-core/via_video.c new file mode 120000 index 00000000..a6d27947 --- /dev/null +++ b/linux-core/via_video.c @@ -0,0 +1 @@ +../shared-core/via_video.c \ No newline at end of file From a97bb85c2a6852e37ed560e6cbe1242e5f68ad8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 1 Dec 2006 10:46:21 +0100 Subject: [PATCH 055/129] Unshare drm_drawable.c again for now. The current version didn't build on BSD, where the new functionality isn't used yet anyway. Whoever changes that will hopefully be able to make the OSes share this file as well. --- bsd-core/drm_drawable.c | 52 +++++- linux-core/drm_drawable.c | 331 ++++++++++++++++++++++++++++++++++++- shared-core/drm_drawable.c | 330 ------------------------------------ 3 files changed, 381 insertions(+), 332 deletions(-) mode change 120000 => 100644 bsd-core/drm_drawable.c mode change 120000 => 100644 linux-core/drm_drawable.c delete mode 100644 shared-core/drm_drawable.c diff --git a/bsd-core/drm_drawable.c b/bsd-core/drm_drawable.c deleted file mode 120000 index d64bbe10..00000000 --- a/bsd-core/drm_drawable.c +++ /dev/null @@ -1 +0,0 @@ -../shared-core/drm_drawable.c \ No newline at end of file diff --git a/bsd-core/drm_drawable.c b/bsd-core/drm_drawable.c new file mode 100644 index 00000000..379e0aa7 --- /dev/null +++ b/bsd-core/drm_drawable.c @@ -0,0 +1,51 @@ +/* drm_drawable.h -- IOCTLs for drawables -*- linux-c -*- + * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com + */ +/*- + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * 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. + * + * Authors: + * Rickard E. (Rik) Faith + * Gareth Hughes + * + */ + +#include "drmP.h" + +int drm_adddraw(DRM_IOCTL_ARGS) +{ + drm_draw_t draw; + + draw.handle = 0; /* NOOP */ + DRM_DEBUG("%d\n", draw.handle); + + DRM_COPY_TO_USER_IOCTL( (drm_draw_t *)data, draw, sizeof(draw) ); + + return 0; +} + +int drm_rmdraw(DRM_IOCTL_ARGS) +{ + return 0; /* NOOP */ +} diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c deleted file mode 120000 index d64bbe10..00000000 --- a/linux-core/drm_drawable.c +++ /dev/null @@ -1 +0,0 @@ -../shared-core/drm_drawable.c \ No newline at end of file diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c new file mode 100644 index 00000000..0817e321 --- /dev/null +++ b/linux-core/drm_drawable.c @@ -0,0 +1,330 @@ +/** + * \file drm_drawable.c + * IOCTLs for drawables + * + * \author Rickard E. (Rik) Faith + * \author Gareth Hughes + * \author Michel Dänzer + */ + +/* + * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota. + * 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. + */ + +#include "drmP.h" + +/** + * Allocate drawable ID and memory to store information about it. + */ +int drm_adddraw(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + unsigned long irqflags; + int i, j; + u32 *bitfield = dev->drw_bitfield; + unsigned int bitfield_length = dev->drw_bitfield_length; + drm_drawable_info_t **info = dev->drw_info; + unsigned int info_length = dev->drw_info_length; + drm_draw_t draw; + + for (i = 0, j = 0; i < bitfield_length; i++) { + if (bitfield[i] == ~0) + continue; + + for (; j < 8 * sizeof(*bitfield); j++) + if (!(bitfield[i] & (1 << j))) + goto done; + } +done: + + if (i == bitfield_length) { + bitfield_length++; + + bitfield = drm_alloc(bitfield_length * sizeof(*bitfield), + DRM_MEM_BUFS); + + if (!bitfield) { + DRM_ERROR("Failed to allocate new drawable bitfield\n"); + return DRM_ERR(ENOMEM); + } + + if (8 * sizeof(*bitfield) * bitfield_length > info_length) { + info_length += 8 * sizeof(*bitfield); + + info = drm_alloc(info_length * sizeof(*info), + DRM_MEM_BUFS); + + if (!info) { + DRM_ERROR("Failed to allocate new drawable info" + " array\n"); + + drm_free(bitfield, + bitfield_length * sizeof(*bitfield), + DRM_MEM_BUFS); + return DRM_ERR(ENOMEM); + } + } + + bitfield[i] = 0; + } + + draw.handle = i * 8 * sizeof(*bitfield) + j + 1; + DRM_DEBUG("%d\n", draw.handle); + + spin_lock_irqsave(&dev->drw_lock, irqflags); + + bitfield[i] |= 1 << j; + info[draw.handle - 1] = NULL; + + if (bitfield != dev->drw_bitfield) { + memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length * + sizeof(*bitfield)); + drm_free(dev->drw_bitfield, sizeof(*bitfield) * + dev->drw_bitfield_length, DRM_MEM_BUFS); + dev->drw_bitfield = bitfield; + dev->drw_bitfield_length = bitfield_length; + } + + if (info != dev->drw_info) { + memcpy(info, dev->drw_info, dev->drw_info_length * + sizeof(*info)); + drm_free(dev->drw_info, sizeof(*info) * dev->drw_info_length, + DRM_MEM_BUFS); + dev->drw_info = info; + dev->drw_info_length = info_length; + } + + spin_unlock_irqrestore(&dev->drw_lock, irqflags); + + DRM_COPY_TO_USER_IOCTL((drm_draw_t __user *)data, draw, sizeof(draw)); + + return 0; +} + +/** + * Free drawable ID and memory to store information about it. + */ +int drm_rmdraw(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_draw_t draw; + int id, idx; + unsigned int shift; + unsigned long irqflags; + u32 *bitfield = dev->drw_bitfield; + unsigned int bitfield_length = dev->drw_bitfield_length; + drm_drawable_info_t **info = dev->drw_info; + unsigned int info_length = dev->drw_info_length; + + DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, + sizeof(draw)); + + id = draw.handle - 1; + idx = id / (8 * sizeof(*bitfield)); + shift = id % (8 * sizeof(*bitfield)); + + if (idx < 0 || idx >= bitfield_length || + !(bitfield[idx] & (1 << shift))) { + DRM_DEBUG("No such drawable %d\n", draw.handle); + return 0; + } + + spin_lock_irqsave(&dev->drw_lock, irqflags); + + bitfield[idx] &= ~(1 << shift); + + spin_unlock_irqrestore(&dev->drw_lock, irqflags); + + if (info[id]) { + drm_free(info[id]->rects, info[id]->num_rects * + sizeof(drm_clip_rect_t), DRM_MEM_BUFS); + drm_free(info[id], sizeof(**info), DRM_MEM_BUFS); + } + + /* Can we shrink the arrays? */ + if (idx == bitfield_length - 1) { + while (idx >= 0 && !bitfield[idx]) + --idx; + + bitfield_length = idx + 1; + + if (idx != id / (8 * sizeof(*bitfield))) + bitfield = drm_alloc(bitfield_length * + sizeof(*bitfield), DRM_MEM_BUFS); + + if (!bitfield && bitfield_length) { + bitfield = dev->drw_bitfield; + bitfield_length = dev->drw_bitfield_length; + } + } + + if (bitfield != dev->drw_bitfield) { + info_length = 8 * sizeof(*bitfield) * bitfield_length; + + info = drm_alloc(info_length * sizeof(*info), DRM_MEM_BUFS); + + if (!info && info_length) { + info = dev->drw_info; + info_length = dev->drw_info_length; + } + + spin_lock_irqsave(&dev->drw_lock, irqflags); + + memcpy(bitfield, dev->drw_bitfield, bitfield_length * + sizeof(*bitfield)); + drm_free(dev->drw_bitfield, sizeof(*bitfield) * + dev->drw_bitfield_length, DRM_MEM_BUFS); + dev->drw_bitfield = bitfield; + dev->drw_bitfield_length = bitfield_length; + + if (info != dev->drw_info) { + memcpy(info, dev->drw_info, info_length * + sizeof(*info)); + drm_free(dev->drw_info, sizeof(*info) * + dev->drw_info_length, DRM_MEM_BUFS); + dev->drw_info = info; + dev->drw_info_length = info_length; + } + + spin_unlock_irqrestore(&dev->drw_lock, irqflags); + } + + DRM_DEBUG("%d\n", draw.handle); + return 0; +} + +int drm_update_drawable_info(DRM_IOCTL_ARGS) { + DRM_DEVICE; + drm_update_draw_t update; + unsigned int id, idx, shift, bitfield_length = dev->drw_bitfield_length; + u32 *bitfield = dev->drw_bitfield; + unsigned long irqflags; + drm_drawable_info_t *info; + drm_clip_rect_t *rects; + int err; + + DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data, + sizeof(update)); + + id = update.handle - 1; + idx = id / (8 * sizeof(*bitfield)); + shift = id % (8 * sizeof(*bitfield)); + + if (idx < 0 || idx >= bitfield_length || + !(bitfield[idx] & (1 << shift))) { + DRM_ERROR("No such drawable %d\n", update.handle); + return DRM_ERR(EINVAL); + } + + info = dev->drw_info[id]; + + if (!info) { + info = drm_calloc(1, sizeof(drm_drawable_info_t), DRM_MEM_BUFS); + + if (!info) { + DRM_ERROR("Failed to allocate drawable info memory\n"); + return DRM_ERR(ENOMEM); + } + } + + switch (update.type) { + case DRM_DRAWABLE_CLIPRECTS: + if (update.num != info->num_rects) { + rects = drm_alloc(update.num * sizeof(drm_clip_rect_t), + DRM_MEM_BUFS); + } else + rects = info->rects; + + if (update.num && !rects) { + DRM_ERROR("Failed to allocate cliprect memory\n"); + err = DRM_ERR(ENOMEM); + goto error; + } + + if (update.num && DRM_COPY_FROM_USER(rects, + (drm_clip_rect_t __user *) + (unsigned long)update.data, + update.num * + sizeof(*rects))) { + DRM_ERROR("Failed to copy cliprects from userspace\n"); + err = DRM_ERR(EFAULT); + goto error; + } + + spin_lock_irqsave(&dev->drw_lock, irqflags); + + if (rects != info->rects) { + drm_free(info->rects, info->num_rects * + sizeof(drm_clip_rect_t), DRM_MEM_BUFS); + } + + info->rects = rects; + info->num_rects = update.num; + dev->drw_info[id] = info; + + spin_unlock_irqrestore(&dev->drw_lock, irqflags); + + DRM_DEBUG("Updated %d cliprects for drawable %d\n", + info->num_rects, id); + break; + default: + DRM_ERROR("Invalid update type %d\n", update.type); + return DRM_ERR(EINVAL); + } + + return 0; + +error: + if (!dev->drw_info[id]) + drm_free(info, sizeof(*info), DRM_MEM_BUFS); + else if (rects != dev->drw_info[id]->rects) + drm_free(rects, update.num * + sizeof(drm_clip_rect_t), DRM_MEM_BUFS); + + return err; +} + +/** + * Caller must hold the drawable spinlock! + */ +drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { + u32 *bitfield = dev->drw_bitfield; + unsigned int idx, shift; + + id--; + idx = id / (8 * sizeof(*bitfield)); + shift = id % (8 * sizeof(*bitfield)); + + if (idx < 0 || idx >= dev->drw_bitfield_length || + !(bitfield[idx] & (1 << shift))) { + DRM_DEBUG("No such drawable %d\n", id); + return NULL; + } + + return dev->drw_info[id]; +} +EXPORT_SYMBOL(drm_get_drawable_info); diff --git a/shared-core/drm_drawable.c b/shared-core/drm_drawable.c deleted file mode 100644 index 0817e321..00000000 --- a/shared-core/drm_drawable.c +++ /dev/null @@ -1,330 +0,0 @@ -/** - * \file drm_drawable.c - * IOCTLs for drawables - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - * \author Michel Dänzer - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota. - * 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. - */ - -#include "drmP.h" - -/** - * Allocate drawable ID and memory to store information about it. - */ -int drm_adddraw(DRM_IOCTL_ARGS) -{ - DRM_DEVICE; - unsigned long irqflags; - int i, j; - u32 *bitfield = dev->drw_bitfield; - unsigned int bitfield_length = dev->drw_bitfield_length; - drm_drawable_info_t **info = dev->drw_info; - unsigned int info_length = dev->drw_info_length; - drm_draw_t draw; - - for (i = 0, j = 0; i < bitfield_length; i++) { - if (bitfield[i] == ~0) - continue; - - for (; j < 8 * sizeof(*bitfield); j++) - if (!(bitfield[i] & (1 << j))) - goto done; - } -done: - - if (i == bitfield_length) { - bitfield_length++; - - bitfield = drm_alloc(bitfield_length * sizeof(*bitfield), - DRM_MEM_BUFS); - - if (!bitfield) { - DRM_ERROR("Failed to allocate new drawable bitfield\n"); - return DRM_ERR(ENOMEM); - } - - if (8 * sizeof(*bitfield) * bitfield_length > info_length) { - info_length += 8 * sizeof(*bitfield); - - info = drm_alloc(info_length * sizeof(*info), - DRM_MEM_BUFS); - - if (!info) { - DRM_ERROR("Failed to allocate new drawable info" - " array\n"); - - drm_free(bitfield, - bitfield_length * sizeof(*bitfield), - DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); - } - } - - bitfield[i] = 0; - } - - draw.handle = i * 8 * sizeof(*bitfield) + j + 1; - DRM_DEBUG("%d\n", draw.handle); - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - bitfield[i] |= 1 << j; - info[draw.handle - 1] = NULL; - - if (bitfield != dev->drw_bitfield) { - memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length * - sizeof(*bitfield)); - drm_free(dev->drw_bitfield, sizeof(*bitfield) * - dev->drw_bitfield_length, DRM_MEM_BUFS); - dev->drw_bitfield = bitfield; - dev->drw_bitfield_length = bitfield_length; - } - - if (info != dev->drw_info) { - memcpy(info, dev->drw_info, dev->drw_info_length * - sizeof(*info)); - drm_free(dev->drw_info, sizeof(*info) * dev->drw_info_length, - DRM_MEM_BUFS); - dev->drw_info = info; - dev->drw_info_length = info_length; - } - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - DRM_COPY_TO_USER_IOCTL((drm_draw_t __user *)data, draw, sizeof(draw)); - - return 0; -} - -/** - * Free drawable ID and memory to store information about it. - */ -int drm_rmdraw(DRM_IOCTL_ARGS) -{ - DRM_DEVICE; - drm_draw_t draw; - int id, idx; - unsigned int shift; - unsigned long irqflags; - u32 *bitfield = dev->drw_bitfield; - unsigned int bitfield_length = dev->drw_bitfield_length; - drm_drawable_info_t **info = dev->drw_info; - unsigned int info_length = dev->drw_info_length; - - DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, - sizeof(draw)); - - id = draw.handle - 1; - idx = id / (8 * sizeof(*bitfield)); - shift = id % (8 * sizeof(*bitfield)); - - if (idx < 0 || idx >= bitfield_length || - !(bitfield[idx] & (1 << shift))) { - DRM_DEBUG("No such drawable %d\n", draw.handle); - return 0; - } - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - bitfield[idx] &= ~(1 << shift); - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - if (info[id]) { - drm_free(info[id]->rects, info[id]->num_rects * - sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - drm_free(info[id], sizeof(**info), DRM_MEM_BUFS); - } - - /* Can we shrink the arrays? */ - if (idx == bitfield_length - 1) { - while (idx >= 0 && !bitfield[idx]) - --idx; - - bitfield_length = idx + 1; - - if (idx != id / (8 * sizeof(*bitfield))) - bitfield = drm_alloc(bitfield_length * - sizeof(*bitfield), DRM_MEM_BUFS); - - if (!bitfield && bitfield_length) { - bitfield = dev->drw_bitfield; - bitfield_length = dev->drw_bitfield_length; - } - } - - if (bitfield != dev->drw_bitfield) { - info_length = 8 * sizeof(*bitfield) * bitfield_length; - - info = drm_alloc(info_length * sizeof(*info), DRM_MEM_BUFS); - - if (!info && info_length) { - info = dev->drw_info; - info_length = dev->drw_info_length; - } - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - memcpy(bitfield, dev->drw_bitfield, bitfield_length * - sizeof(*bitfield)); - drm_free(dev->drw_bitfield, sizeof(*bitfield) * - dev->drw_bitfield_length, DRM_MEM_BUFS); - dev->drw_bitfield = bitfield; - dev->drw_bitfield_length = bitfield_length; - - if (info != dev->drw_info) { - memcpy(info, dev->drw_info, info_length * - sizeof(*info)); - drm_free(dev->drw_info, sizeof(*info) * - dev->drw_info_length, DRM_MEM_BUFS); - dev->drw_info = info; - dev->drw_info_length = info_length; - } - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - } - - DRM_DEBUG("%d\n", draw.handle); - return 0; -} - -int drm_update_drawable_info(DRM_IOCTL_ARGS) { - DRM_DEVICE; - drm_update_draw_t update; - unsigned int id, idx, shift, bitfield_length = dev->drw_bitfield_length; - u32 *bitfield = dev->drw_bitfield; - unsigned long irqflags; - drm_drawable_info_t *info; - drm_clip_rect_t *rects; - int err; - - DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data, - sizeof(update)); - - id = update.handle - 1; - idx = id / (8 * sizeof(*bitfield)); - shift = id % (8 * sizeof(*bitfield)); - - if (idx < 0 || idx >= bitfield_length || - !(bitfield[idx] & (1 << shift))) { - DRM_ERROR("No such drawable %d\n", update.handle); - return DRM_ERR(EINVAL); - } - - info = dev->drw_info[id]; - - if (!info) { - info = drm_calloc(1, sizeof(drm_drawable_info_t), DRM_MEM_BUFS); - - if (!info) { - DRM_ERROR("Failed to allocate drawable info memory\n"); - return DRM_ERR(ENOMEM); - } - } - - switch (update.type) { - case DRM_DRAWABLE_CLIPRECTS: - if (update.num != info->num_rects) { - rects = drm_alloc(update.num * sizeof(drm_clip_rect_t), - DRM_MEM_BUFS); - } else - rects = info->rects; - - if (update.num && !rects) { - DRM_ERROR("Failed to allocate cliprect memory\n"); - err = DRM_ERR(ENOMEM); - goto error; - } - - if (update.num && DRM_COPY_FROM_USER(rects, - (drm_clip_rect_t __user *) - (unsigned long)update.data, - update.num * - sizeof(*rects))) { - DRM_ERROR("Failed to copy cliprects from userspace\n"); - err = DRM_ERR(EFAULT); - goto error; - } - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - if (rects != info->rects) { - drm_free(info->rects, info->num_rects * - sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - } - - info->rects = rects; - info->num_rects = update.num; - dev->drw_info[id] = info; - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - DRM_DEBUG("Updated %d cliprects for drawable %d\n", - info->num_rects, id); - break; - default: - DRM_ERROR("Invalid update type %d\n", update.type); - return DRM_ERR(EINVAL); - } - - return 0; - -error: - if (!dev->drw_info[id]) - drm_free(info, sizeof(*info), DRM_MEM_BUFS); - else if (rects != dev->drw_info[id]->rects) - drm_free(rects, update.num * - sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - - return err; -} - -/** - * Caller must hold the drawable spinlock! - */ -drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { - u32 *bitfield = dev->drw_bitfield; - unsigned int idx, shift; - - id--; - idx = id / (8 * sizeof(*bitfield)); - shift = id % (8 * sizeof(*bitfield)); - - if (idx < 0 || idx >= dev->drw_bitfield_length || - !(bitfield[idx] & (1 << shift))) { - DRM_DEBUG("No such drawable %d\n", id); - return NULL; - } - - return dev->drw_info[id]; -} -EXPORT_SYMBOL(drm_get_drawable_info); From 74a92bbf6ea9b9766a2b827f22605559791569b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 1 Dec 2006 11:00:32 +0100 Subject: [PATCH 056/129] Core build fix for BSD. --- bsd-core/drm_bufs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index 33da79e7..343ab1e8 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -316,6 +316,9 @@ void drm_rmmap(drm_device_t *dev, drm_local_map_t *map) case _DRM_CONSISTENT: drm_pci_free(dev, map->dmah); break; + default: + DRM_ERROR("Bad map type %d\n", map->type); + break; } if (map->bsr != NULL) { From 30acb90a6077798b1e0c4927273067500905d6d1 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 3 Dec 2006 10:02:54 +0100 Subject: [PATCH 057/129] Merge the pciid work. Add getparams for AGP and FB physical adresses. Fix the MEM_ALLOC issue properly. Fix context switches for nv44. Change the DRM version to 0.0.1. --- shared-core/drm_pciids.txt | 375 +++++++++++++++++++----------------- shared-core/nouveau_drm.h | 18 +- shared-core/nouveau_drv.h | 8 +- shared-core/nouveau_fifo.c | 41 ++-- shared-core/nouveau_mem.c | 16 +- shared-core/nouveau_state.c | 7 + 6 files changed, 262 insertions(+), 203 deletions(-) diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index f1d8731e..b6dfe400 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -464,63 +464,167 @@ 0x10DE 0x009E NV40 "NVidia 0x009E" [nouveau] -0x12d2 0x0008 NV_01 "NV1" -0x12d2 0x0009 NV_01 "DAC64" -0x12d2 0x0018 NV_03 "Riva128" -0x12d2 0x0019 NV_03 "Riva128ZX" -0x12d2 0x0020 NV_04 "TNT" -0x12d2 0x0028 NV_05 "TNT2" -0x12d2 0x0029 NV_05 "UTNT2" -0x12d2 0x002c NV_05 "VTNT2" -0x12d2 0x00a0 NV_05 "ITNT2" +0x10de 0x0008 NV_03 "EDGE 3D" +0x10de 0x0009 NV_03 "EDGE 3D" +0x10de 0x0010 NV_03 "Mutara V08" 0x10de 0x0020 NV_04 "RIVA TNT" -0x10de 0x0028 NV_05 "RIVA TNT2/TNT2 Pro" -0x10de 0x00a0 NV_05 "Aladdin TNT2" -0x10de 0x002c NV_05 "Vanta/Vanta LT" -0x10de 0x0029 NV_05 "RIVA TNT2 Ultra" -0x10de 0x002d NV_05 "RIVA TNT2 Model 64/Model 64 Pro" -0x10de 0x0100 NV_10 "GeForce 256" -0x10de 0x0101 NV_10 "GeForce DDR" +0x10de 0x0028 NV_04 "RIVA TNT2/TNT2 Pro" +0x10de 0x0029 NV_04 "RIVA TNT2 Ultra" +0x10de 0x002a NV_04 "Riva TnT2" +0x10de 0x002b NV_04 "Riva TnT2" +0x10de 0x002c NV_04 "Vanta/Vanta LT" +0x10de 0x002d NV_04 "RIVA TNT2 Model 64/Model 64 Pro" +0x10de 0x002e NV_04 "Vanta" +0x10de 0x002f NV_04 "Vanta" +0x10de 0x0040 NV_40 "GeForce 6800 Ultra" +0x10de 0x0041 NV_40 "GeForce 6800" +0x10de 0x0042 NV_40 "GeForce 6800 LE" +0x10de 0x0043 NV_40 "NV40.3" +0x10de 0x0044 NV_40 "GeForce 6800 XT" +0x10de 0x0045 NV_40 "GeForce 6800 GT" +0x10de 0x0046 NV_40 "GeForce 6800 GT" +0x10de 0x0047 NV_40 "GeForce 6800 GS" +0x10de 0x0048 NV_40 "GeForce 6800 XT" +0x10de 0x0049 NV_40 "NV40GL" +0x10de 0x004d NV_40 "Quadro FX 4000" +0x10de 0x004e NV_40 "Quadro FX 4000" +0x10de 0x0090 NV_40 "GeForce 7800 GTX" +0x10de 0x0091 NV_40 "GeForce 7800 GTX" +0x10de 0x0092 NV_40 "GeForce 7800 GT" +0x10de 0x0093 NV_40 "GeForce 7800 GS" +0x10de 0x0098 NV_40 "GeForce Go 7800" +0x10de 0x0099 NV_40 "GE Force Go 7800 GTX" +0x10de 0x009d NV_40 "Quadro FX4500" +0x10de 0x00a0 NV_04 "Aladdin TNT2" +0x10de 0x00c0 NV_40 "GeForce 6800 GS" +0x10de 0x00c1 NV_40 "GeForce 6800" +0x10de 0x00c2 NV_40 "GeForce 6800 LE" +0x10de 0x00c3 NV_40 "Geforce 6800 XT" +0x10de 0x00c8 NV_40 "GeForce Go 6800" +0x10de 0x00c9 NV_40 "GeForce Go 6800 Ultra" +0x10de 0x00cc NV_40 "Quadro FX Go1400" +0x10de 0x00cd NV_40 "Quadro FX 3450/4000 SDI" +0x10de 0x00ce NV_40 "Quadro FX 1400" +0x10de 0x00f0 NV_40 "GeForce 6800/GeForce 6800 Ultra" +0x10de 0x00f1 NV_40 "GeForce 6600/GeForce 6600 GT" +0x10de 0x00f2 NV_40 "GeForce 6600/GeForce 6600 GT" +0x10de 0x00f3 NV_40 "GeForce 6200" +0x10de 0x00f4 NV_40 "GeForce 6600 LE" +0x10de 0x00f5 NV_40 "GeForce 7800 GS" +0x10de 0x00f6 NV_40 "GeForce 6600 GS" +0x10de 0x00f8 NV_40 "Quadro FX 3400/4400" +0x10de 0x00f9 NV_40 "GeForce 6800 Ultra/GeForce 6800 GT" +0x10de 0x00fa NV_30 "GeForce PCX 5750" +0x10de 0x00fb NV_30 "GeForce PCX 5900" +0x10de 0x00fc NV_30 "Quadro FX 330/GeForce PCX 5300" +0x10de 0x00fd NV_30 "Quadro FX 330/Quadro NVS280" +0x10de 0x00fe NV_30 "Quadro FX 1300" +0x10de 0x00ff NV_17 "GeForce PCX 4300" +0x10de 0x0100 NV_10 "GeForce 256 SDR" +0x10de 0x0101 NV_10 "GeForce 256 DDR" 0x10de 0x0103 NV_10 "Quadro" -0x10de 0x0110 NV_10 "GeForce2 MX/MX 400" -0x10de 0x0111 NV_10 "GeForce2 MX 100/200" -0x10de 0x0113 NV_10 "Quadro2 MXR/EX/Go" -0x10de 0x01a0 NV_10|NV_NFORCE "GeForce2 Integrated GPU" -0x10de 0x0150 NV_10 "GeForce2 GTS/GeForce2 Pro" -0x10de 0x0151 NV_10 "GeForce2 Ti" -0x10de 0x0152 NV_10 "GeForce2 Ultra" -0x10de 0x0153 NV_10 "Quadro2 Pro" -0x10de 0x0170 NV_10 "GeForce4 MX 460" -0x10de 0x0171 NV_10 "GeForce4 MX 440" -0x10de 0x0172 NV_10 "GeForce4 MX 420" -0x10de 0x0173 NV_10 "GeForce4 MX 440-SE" -0x10de 0x0178 NV_10 "Quadro4 550 XGL" -0x10de 0x017a NV_10 "Quadro NVS" -0x10de 0x0181 NV_10 "GeForce4 MX 440 with AGP8X" -0x10de 0x0182 NV_10 "GeForce4 MX 440SE with AGP8X" -0x10de 0x0183 NV_10 "GeForce4 MX 420 with AGP8X" -0x10de 0x0185 NV_10 "GeForce4 MX 4000" -0x10de 0x0188 NV_10 "Quadro4 580 XGL" -0x10de 0x018a NV_10 "Quadro NVS with AGP8X" -0x10de 0x018b NV_10 "Quadro4 380 XGL" -0x10de 0x018c NV_10 "Quadro NVS 50 PCI" -0x10de 0x01f0 NV_10|NV_NFORCE2 "GeForce4 MX Integrated GPU" +0x10de 0x0110 NV_11 "GeForce2 MX/MX 400" +0x10de 0x0111 NV_11 "GeForce2 MX 100 DDR/200 DDR" +0x10de 0x0112 NV_11 "GeForce2 Go" +0x10de 0x0113 NV_11 "Quadro2 MXR/EX/Go" +0x10de 0x0140 NV_40 "GeForce 6600 GT" +0x10de 0x0141 NV_40 "GeForce 6600" +0x10de 0x0142 NV_40 "GeForce 6600 PCIe" +0x10de 0x0144 NV_40 "GeForce Go 6600" +0x10de 0x0145 NV_40 "GeForce 6610 XL" +0x10de 0x0146 NV_40 "Geforce Go 6600TE/6200TE" +0x10de 0x0148 NV_40 "GeForce Go 6600" +0x10de 0x0149 NV_40 "GeForce Go 6600 GT" +0x10de 0x014a NV_40 "Quadro NVS 440" +0x10de 0x014d NV_17 "Quadro FX 550" +0x10de 0x014e NV_40 "Quadro FX 540" +0x10de 0x014f NV_40 "GeForce 6200" +0x10de 0x0150 NV_15 "GeForce2 GTS/Pro" +0x10de 0x0151 NV_15 "GeForce2 Ti" +0x10de 0x0152 NV_15 "GeForce2 Ultra, Bladerunner" +0x10de 0x0153 NV_15 "Quadro2 Pro" +0x10de 0x0161 NV_44 "GeForce 6200 TurboCache(TM)" +0x10de 0x0162 NV_44 "GeForce 6200 SE TurboCache (TM)" +0x10de 0x0163 NV_44 "GeForce 6200 LE" +0x10de 0x0164 NV_44 "GeForce Go 6200" +0x10de 0x0165 NV_44 "Quadro NVS 285" +0x10de 0x0166 NV_44 "GeForce Go 6400" +0x10de 0x0167 NV_44 "GeForce Go 6200 TurboCache" +0x10de 0x0168 NV_44 "GeForce Go 6200 TurboCache" +0x10de 0x0170 NV_17 "GeForce4 MX 460" +0x10de 0x0171 NV_17 "GeForce4 MX 440" +0x10de 0x0172 NV_17 "GeForce4 MX 420" +0x10de 0x0173 NV_17 "GeForce4 MX 440-SE" +0x10de 0x0174 NV_17 "GeForce4 440 Go" +0x10de 0x0175 NV_17 "GeForce4 420 Go" +0x10de 0x0176 NV_17 "GeForce4 420 Go 32M" +0x10de 0x0177 NV_17 "GeForce4 460 Go" +0x10de 0x0178 NV_17 "Quadro4 550 XGL" +0x10de 0x0179 NV_17 "GeForce4 420 Go 32M" +0x10de 0x017a NV_17 "Quadro4 200/400 NVS" +0x10de 0x017b NV_17 "Quadro4 550 XGL" +0x10de 0x017c NV_17 "Quadro4 500 GoGL" +0x10de 0x017d NV_17 "GeForce4 410 Go 16M" +0x10de 0x0181 NV_17 "GeForce4 MX 440 AGP 8x" +0x10de 0x0182 NV_17 "GeForce4 MX 440SE AGP 8x" +0x10de 0x0183 NV_17 "GeForce4 MX 420 AGP 8x" +0x10de 0x0185 NV_17 "GeForce4 MX 4000 AGP 8x" +0x10de 0x0186 NV_17 "GeForce4 448 Go" +0x10de 0x0187 NV_17 "GeForce4 488 Go" +0x10de 0x0188 NV_17 "Quadro4 580 XGL" +0x10de 0x018a NV_17 "Quadro4 NVS AGP 8x" +0x10de 0x018b NV_17 "Quadro4 380 XGL" +0x10de 0x018c NV_17 "Quadro NVS 50 PCI" +0x10de 0x018d NV_17 "GeForce4 448 Go" +0x10de 0x0191 NV_50 "GeForce 8800 GTX" +0x10de 0x0193 NV_50 "GeForce 8800 GTS" +0x10de 0x01a0 NV_11|NV_NFORCE "GeForce2 MX Integrated Graphics" +0x10de 0x01d1 NV_44 "GeForce 7300 LE" +0x10de 0x01d6 NV_44 "GeForce Go 7200" +0x10de 0x01d7 NV_44 "Quadro NVS 110M / GeForce Go 7300" +0x10de 0x01d8 NV_44 "GeForce Go 7400" +0x10de 0x01da NV_44 "Quadro NVS 110M" +0x10de 0x01df NV_44 "GeForce 7300 GS" +0x10de 0x01f0 NV_17|NV_NFORCE2 "GeForce4 MX - nForce GPU" 0x10de 0x0200 NV_20 "GeForce3" 0x10de 0x0201 NV_20 "GeForce3 Ti 200" 0x10de 0x0202 NV_20 "GeForce3 Ti 500" 0x10de 0x0203 NV_20 "Quadro DCC" -0x10de 0x0250 NV_20 "GeForce4 Ti 4600" -0x10de 0x0251 NV_20 "GeForce4 Ti 4400" -0x10de 0x0252 NV_20 "NV25" -0x10de 0x0253 NV_20 "GeForce4 Ti 4200" -0x10de 0x0258 NV_20 "Quadro4 900 XGL" -0x10de 0x0259 NV_20 "Quadro4 750 XGL" -0x10de 0x025b NV_20 "Quadro4 700 XGL" -0x10de 0x0280 NV_20 "GeForce4 Ti 4800" -0x10de 0x0281 NV_20 "GeForce4 Ti 4200 with AGP8X" -0x10de 0x0282 NV_20 "GeForce4 Ti 4800 SE" -0x10de 0x0288 NV_20 "Quadro4 980 XGL" -0x10de 0x0289 NV_20 "Quadro4 780 XGL" +0x10de 0x0211 NV_40 "GeForce 6800" +0x10de 0x0212 NV_40 "GeForce 6800 LE" +0x10de 0x0215 NV_40 "GeForce 6800 GT" +0x10de 0x0218 NV_40 "GeForce 6800 XT" +0x10de 0x0221 NV_44 "GeForce 6200" +0x10de 0x0240 NV_44 "GeForce 6150" +0x10de 0x0242 NV_44 "GeForce 6100" +0x10de 0x0250 NV_25 "GeForce4 Ti 4600" +0x10de 0x0251 NV_25 "GeForce4 Ti 4400" +0x10de 0x0252 NV_25 "GeForce4 Ti" +0x10de 0x0253 NV_25 "GeForce4 Ti 4200" +0x10de 0x0258 NV_25 "Quadro4 900 XGL" +0x10de 0x0259 NV_25 "Quadro4 750 XGL" +0x10de 0x025b NV_25 "Quadro4 700 XGL" +0x10de 0x0280 NV_25 "GeForce4 Ti 4800" +0x10de 0x0281 NV_25 "GeForce4 Ti 4200 AGP 8x" +0x10de 0x0282 NV_25 "GeForce4 Ti 4800 SE" +0x10de 0x0286 NV_25 "GeForce4 Ti 4200 Go AGP 8x" +0x10de 0x0288 NV_25 "Quadro4 980 XGL" +0x10de 0x0289 NV_25 "Quadro4 780 XGL" +0x10de 0x028c NV_25 "Quadro4 700 GoGL" +0x10de 0x0290 NV_40 "GeForce 7900 GTX" +0x10de 0x0291 NV_40 "GeForce 7900 GT" +0x10de 0x0292 NV_40 "GeForce 7900 GS" +0x10de 0x0298 NV_40 "GeForce Go 7900 GS" +0x10de 0x0299 NV_40 "GeForce Go 7900 GTX" +0x10de 0x029a NV_40 "Quadro FX 2500M" +0x10de 0x029b NV_40 "Quadro FX 1500M" +0x10de 0x029c NV_40 "Quadro FX 5500" +0x10de 0x029d NV_40 "Quadro FX 3500" +0x10de 0x029e NV_40 "Quadro FX 1500" +0x10de 0x029f NV_40 "Quadro FX 4500 X2" +0x10de 0x02a0 NV_20 "XGPU" +0x10de 0x02e1 NV_40 "GeForce 7600 GS" +0x10de 0x0300 NV_30 "GeForce FX" 0x10de 0x0301 NV_30 "GeForce FX 5800 Ultra" 0x10de 0x0302 NV_30 "GeForce FX 5800" 0x10de 0x0308 NV_30 "Quadro FX 2000" @@ -529,15 +633,28 @@ 0x10de 0x0312 NV_30 "GeForce FX 5600" 0x10de 0x0313 NV_30 "NV31" 0x10de 0x0314 NV_30 "GeForce FX 5600XT" -0x10de 0x0320 NV_30 "GeForce FX 5200" -0x10de 0x0321 NV_30 "GeForce FX 5200 Ultra" -0x10de 0x0322 NV_30 "GeForce FX 5200" -0x10de 0x0323 NV_30 "GeForce FX 5200LE" -0x10de 0x0326 NV_30 "GeForce FX 5500" -0x10de 0x0327 NV_30 "GeForce FX 5100" -0x10de 0x032a NV_30 "Quadro NVS 280 PCI" -0x10de 0x032b NV_30 "Quadro FX 500/FX 600" -0x10de 0x032f NV_30 "NV34GL" +0x10de 0x0316 NV_30 "NV31M" +0x10de 0x0317 NV_30 "NV31M Pro" +0x10de 0x031a NV_30 "GeForce FX Go5600" +0x10de 0x031b NV_30 "GeForce FX Go5650" +0x10de 0x031d NV_30 "NV31GLM" +0x10de 0x031e NV_30 "NV31GLM Pro" +0x10de 0x031f NV_30 "NV31GLM Pro" +0x10de 0x0320 NV_34 "GeForce FX 5200" +0x10de 0x0321 NV_34 "GeForce FX 5200 Ultra" +0x10de 0x0322 NV_34 "GeForce FX 5200" +0x10de 0x0323 NV_34 "GeForce FX 5200LE" +0x10de 0x0324 NV_34 "GeForce FX Go5200" +0x10de 0x0325 NV_34 "GeForce FX Go5250" +0x10de 0x0326 NV_34 "GeForce FX 5500" +0x10de 0x0327 NV_34 "GeForce FX 5100" +0x10de 0x0328 NV_34 "GeForce FX Go5200 32M/64M" +0x10de 0x0329 NV_34 "GeForce FX Go5200" +0x10de 0x032a NV_34 "Quadro NVS 280 PCI" +0x10de 0x032b NV_34 "Quadro FX 500/600 PCI" +0x10de 0x032c NV_34 "GeForce FX Go 5300" +0x10de 0x032d NV_34 "GeForce FX Go5100" +0x10de 0x032f NV_34 "NV34GL" 0x10de 0x0330 NV_30 "GeForce FX 5900 Ultra" 0x10de 0x0331 NV_30 "GeForce FX 5900" 0x10de 0x0332 NV_30 "GeForce FX 5900XT" @@ -549,125 +666,29 @@ 0x10de 0x0342 NV_30 "GeForce FX 5700" 0x10de 0x0343 NV_30 "GeForce FX 5700LE" 0x10de 0x0344 NV_30 "GeForce FX 5700VE" -0x10de 0x0345 NV_30 "NV36" -0x10de 0x034e NV_30 "Quadro FX 1100" -0x10de 0x034f NV_30 "NV36GL" -0x10de 0x0040 NV_40 "GeForce 6800 Ultra" -0x10de 0x0041 NV_40 "GeForce 6800" -0x10de 0x0042 NV_40 "GeForce 6800 LE" -0x10de 0x0043 NV_40 "NV40" -0x10de 0x0045 NV_40 "GeForce 6800 GT" -0x10de 0x0049 NV_40 "NV40GL" -0x10de 0x004e NV_40 "Quadro FX 4000" -0x10de 0x00c0 NV_40 "NV41" -0x10de 0x00c1 NV_40 "GeForce 6800" -0x10de 0x00c2 NV_40 "GeForce 6800 LE" -0x10de 0x00cc NV_40 "Quadro FX Go1400" -0x10de 0x00cd NV_40 "Quadro FX 3450/4000 SDI" -0x10de 0x00ce NV_40 "Quadro FX 1400" -0x10de 0x0140 NV_40 "GeForce 6600 GT" -0x10de 0x0141 NV_40 "GeForce 6600" -0x10de 0x0142 NV_40 "NV43" -0x10de 0x0143 NV_40 "NV43" -0x10de 0x0145 NV_40 "GeForce 6610 XL" -0x10de 0x014b NV_40 "NV43" -0x10de 0x014c NV_40 "NV43GL" -0x10de 0x014d NV_40 "NV43GL" -0x10de 0x014e NV_40 "Quadro FX 540" -0x10de 0x014f NV_40 "GeForce 6200" -0x10de 0x0160 NV_40 "NV44" -0x10de 0x0161 NV_40 "GeForce 6200 TurboCache(TM)" -0x10de 0x0162 NV_40 "NV44" -0x10de 0x0163 NV_40 "NV44" -0x10de 0x0165 NV_40 "Quadro NVS 285" -0x10de 0x016e NV_40 "NV44GL" -0x10de 0x0220 NV_40 "NV44" -0x10de 0x0221 NV_40 "NV44" -0x10de 0x0222 NV_40 "NV44" -0x10de 0x0211 NV_40 "GeForce 6800" -0x10de 0x0212 NV_40 "GeForce 6800 LE" -0x10de 0x0215 NV_40 "GeForce 6800 GT" -0x10de 0x00f0 NV_40 "GeForce 6800 Ultra" -0x10de 0x00f0 NV_40 "GeForce 6800" -0x10de 0x00f1 NV_40 "GeForce 6600 GT" -0x10de 0x00f1 NV_40 "GeForce 6600 GT" -0x10de 0x00f2 NV_40 "GeForce 6600" -0x10de 0x00f2 NV_40 "GeForce 6600" -0x10de 0x00f3 NV_40 "GeForce 6200" -0x10de 0x00f3 NV_40 "GeForce 6200" -0x10de 0x00f8 NV_30 "Quadro FX 4400" -0x10de 0x00f8 NV_30 "Quadro FX 3400" -0x10de 0x00f8 NV_30 "Quadro FX 3400/4400" -0x10de 0x00f9 NV_40 "GeForce 6800 Ultra" -0x10de 0x00f9 NV_40 "GeForce 6800 GT" -0x10de 0x00f9 NV_40 "GeForce 6800 Series GPU" -0x10de 0x0091 G_70 "GeForce 7800 GTX" -0x10de 0x00fa NV_30 "GeForce PCX 5750" -0x10de 0x00fa NV_30 "GeForce PCX 5750" -0x10de 0x00fb NV_30 "GeForce PCX 5900" -0x10de 0x00fb NV_30 "GeForce PCX 5900" -0x10de 0x00fc NV_30 "GeForce PCX 5300" -0x10de 0x00fc NV_30 "Quadro FX 330" -0x10de 0x00fc NV_30 "GeForce PCX 5300" -0x10de 0x00fd NV_30 "Quadro NVS 280 PCI-E" -0x10de 0x00fd NV_30 "Quadro FX 330" -0x10de 0x00fd NV_10 "Quadro PCI-E Series" -0x10de 0x00fe NV_30 "Quadro FX 1300" -0x10de 0x00fe NV_30 "Quadro FX 1300" -0x10de 0x00ff NV_10 "GeForce PCX 4300" -0x10de 0x00ff NV_10 "GeForce PCX 4300" -0x10de 0x0112 NV_10 "GeForce2 Go" -0x10de 0x0174 NV_20 "GeForce4 440 Go" -0x10de 0x0175 NV_20 "GeForce4 420 Go" -0x10de 0x0176 NV_20 "GeForce4 420 Go 32M" -0x10de 0x0177 NV_20 "GeForce4 460 Go" -0x10de 0x0179 NV_20 "GeForce4 440 Go 64M" -0x10de 0x017d NV_20 "GeForce4 410 Go 16M" -0x10de 0x017c NV_20 "Quadro4 500 GoGL" -0x10de 0x0186 NV_20 "GeForce4 448 Go" -0x10de 0x0187 NV_20 "GeForce4 488 Go" -0x10de 0x018d NV_20 "GeForce4 448 Go" -0x10de 0x0286 NV_20 "GeForce4 4200 Go" -0x10de 0x028c NV_20 "Quadro4 700 GoGL" -0x10de 0x0316 NV_30 "NV31M" -0x10de 0x0317 NV_30 "NV31M Pro" -0x10de 0x031a NV_30 "GeForce FX Go5600" -0x10de 0x031b NV_30 "GeForce FX Go5650" -0x10de 0x031c NV_30 "Quadro FX Go700" -0x10de 0x031d NV_30 "NV31GLM" -0x10de 0x031e NV_30 "NV31GLM Pro" -0x10de 0x031f NV_30 "NV31GLM Pro" -0x10de 0x0324 NV_30 "GeForce FX Go5200" -0x10de 0x0325 NV_30 "GeForce FX Go5250" -0x10de 0x0328 NV_30 "GeForce FX Go5200 32M/64M" -0x10de 0x0329 NV_30 "NV34MAP" -0x10de 0x032c NV_30 "GeForce FX Go53xx" -0x10de 0x032d NV_30 "GeForce FX Go5100" +0x10de 0x0345 NV_30 "NV36.5" 0x10de 0x0347 NV_30 "GeForce FX Go5700" 0x10de 0x0348 NV_30 "GeForce FX Go5700" 0x10de 0x0349 NV_30 "NV36M Pro" 0x10de 0x034b NV_30 "NV36MAP" 0x10de 0x034c NV_30 "Quadro FX Go1000" -0x10de 0x00c8 NV_30 "GeForce Go 6800" -0x10de 0x00c9 NV_30 "GeForce Go 6800 Ultra" -0x10de 0x00cc NV_30 "Quadro FX Go1400" -0x10de 0x0140 NV_40 "NV43" -0x10de 0x0144 NV_40 "GeForce Go 6600" -0x10de 0x0147 NV_40 "NV43" -0x10de 0x0148 NV_40 "GeForce Go 6600" -0x10de 0x0149 NV_40 "NV43" -0x10de 0x014c NV_40 "NV43GL" -0x10de 0x0164 NV_40 "GeForce Go 6200" -0x10de 0x0167 NV_40 "GeForce Go 6200" -0x10de 0x0169 NV_40 "NV44M" -0x10de 0x016b NV_40 "NV44GLM" -0x10de 0x016c NV_40 "NV44GLM" -0x10de 0x016d NV_40 "NV44GLM" -0x10de 0x0228 NV_40 "NV44M" -0x10de 0x0091 G_70 "NVIDIA GeForce 7800 GTX" -0x10de 0x0092 G_70 "NVIDIA GeForce 7800 GT" -0x10de 0x009d G_70 "NVIDIA Quadro FX 4500" -0x10de 0x0240 NV_40 "NVIDIA GeForce 6150" -0x10de 0x0241 NV_40 "NVIDIA GeForce 6150 LE" -0x10de 0x0242 NV_40 "NVIDIA GeForce 6100" -0x10de 0x0244 NV_40 "NVIDIA GeForce 6150 Go" +0x10de 0x034e NV_30 "Quadro FX 1100" +0x10de 0x034f NV_30 "NV36GL" +0x10de 0x0391 NV_40 "GeForce 7600 GT" +0x10de 0x0392 NV_40 "GeForce 7600 GS" +0x10de 0x0393 NV_40 "GeForce 7300 GT" +0x10de 0x0398 NV_40 "GeForce Go 7600" +0x10de 0x03d0 NV_44 "GeForce 6100 nForce 430" +0x10de 0x03d1 NV_44 "GeForce 6100 nForce 405" +0x10de 0x03d2 NV_44 "GeForce 6100 nForce 400" +0x10de 0x03d5 NV_44 "GeForce 6100 nForce 420" +0x12d2 0x0008 NV_03 "NV1" +0x12d2 0x0009 NV_03 "DAC64" +0x12d2 0x0018 NV_03 "Riva128" +0x12d2 0x0019 NV_03 "Riva128ZX" +0x12d2 0x0020 NV_04 "TNT" +0x12d2 0x0028 NV_04 "TNT2" +0x12d2 0x0029 NV_04 "UTNT2" +0x12d2 0x002c NV_04 "VTNT2" +0x12d2 0x00a0 NV_04 "ITNT2" + diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index 2874d36a..3f363192 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -86,12 +86,14 @@ typedef struct drm_nouveau_mem_free { drm_nouveau_mem_free_t; /* FIXME : maybe unify {GET,SET}PARAMs */ -#define NOUVEAU_GETPARAM_PCI_VENDOR 3 -#define NOUVEAU_GETPARAM_PCI_DEVICE 4 -#define NOUVEAU_GETPARAM_BUS_TYPE 5 +#define NOUVEAU_GETPARAM_PCI_VENDOR 3 +#define NOUVEAU_GETPARAM_PCI_DEVICE 4 +#define NOUVEAU_GETPARAM_BUS_TYPE 5 +#define NOUVEAU_GETPARAM_FB_PHYSICAL 6 +#define NOUVEAU_GETPARAM_AGP_PHYSICAL 7 typedef struct drm_nouveau_getparam { unsigned int param; - unsigned int value; + uint64_t value; } drm_nouveau_getparam_t; @@ -110,10 +112,16 @@ enum nouveau_card_type { NV_04 =4, NV_05 =5, NV_10 =10, + NV_11 =10, + NV_15 =10, + NV_17 =10, NV_20 =20, + NV_25 =20, NV_30 =30, + NV_34 =30, NV_40 =40, - G_70 =50, + NV_44 =44, + NV_50 =50, NV_LAST =0xffff, }; diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index be8f4cf4..4dff0c59 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -32,9 +32,9 @@ #define DRIVER_DESC "nVidia Riva/TNT/GeForce" #define DRIVER_DATE "20060213" -#define DRIVER_MAJOR 1 +#define DRIVER_MAJOR 0 #define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 +#define DRIVER_PATCHLEVEL 1 #define NOUVEAU_FAMILY 0x0000FFFF #define NOUVEAU_FLAGS 0xFFFF0000 @@ -122,6 +122,10 @@ typedef struct drm_nouveau_private { uint32_t ramro_offset; uint32_t ramro_size; + /* base physical adresses */ + uint64_t fb_phys; + uint64_t agp_phys; + struct mem_block *agp_heap; struct mem_block *fb_heap; struct mem_block *fb_nomap_heap; diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 94762139..67c790b4 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -106,19 +106,34 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) * cards. RAMFC is 4kb (32 fifos, 128byte entries). * Others: Position RAMFC at RAMIN+0x11400 */ - if (dev_priv->card_type >= NV_40) { - dev_priv->ramfc_offset = 0x20000; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * 128; - NV_WRITE(NV40_PFIFO_RAMFC, 0x30002); - } else if (dev_priv->card_type >= NV_10) { - dev_priv->ramfc_offset = 0x11400; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * 64; - NV_WRITE(NV_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) | - (1 << 16) /* 64 Bytes entry*/); - } else { - dev_priv->ramfc_offset = 0x11400; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * 32; - NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); + switch(dev_priv->card_type) + { + case NV_50: + case NV_40: + dev_priv->ramfc_offset = 0x20000; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); + NV_WRITE(NV40_PFIFO_RAMFC, 0x30002); + break; + case NV_44: + dev_priv->ramfc_offset = 0x20000; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); + NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) | + (2 << 16)); + break; + case NV_30: + case NV_20: + case NV_10: + dev_priv->ramfc_offset = 0x11400; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); + NV_WRITE(NV_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) | + (1 << 16) /* 64 Bytes entry*/); + break; + case NV_04: + case NV_03: + dev_priv->ramfc_offset = 0x11400; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); + NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); + break; } DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 93b9c869..82221c8f 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -253,7 +253,8 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) case NV_20: case NV_30: case NV_40: - case G_70: + case NV_44: + case NV_50: default: // XXX won't work on BSD because of pci_read_config_dword if (dev_priv->flags&NV_NFORCE) { @@ -281,6 +282,8 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) int nouveau_mem_init(struct drm_device *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; + dev_priv->agp_phys=0; + dev_priv->fb_phys=0; /* init AGP */ dev_priv->agp_heap=NULL; @@ -330,10 +333,13 @@ int nouveau_mem_init(struct drm_device *dev) if (init_heap(&dev_priv->agp_heap, info.aperture_base, info.aperture_size)) goto no_agp; + + dev_priv->agp_phys=info.aperture_base; } no_agp: /* Init FB */ + dev_priv->fb_phys=drm_get_resource_start(dev,1); if (nouveau_mem_fb_amount(dev)>256*1024*1024) { /* On cards with > 256Mb, you can't map everything. * So we create a second FB heap for that type of memory */ @@ -473,7 +479,7 @@ struct mem_block *nouveau_instmem_alloc(struct drm_device *dev, if (block) { block->flags = NOUVEAU_MEM_INSTANCE; DRM_DEBUG("instance(size=%d, align=%d) alloc'd at 0x%08x\n", - size, (1<start); + size, (1<start); } return block; @@ -508,11 +514,9 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); if (!block) return DRM_ERR(ENOMEM); + alloc.region_offset=block->start; - if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(uint64_t))) { - DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); - } + DRM_COPY_TO_USER_IOCTL((drm_nouveau_mem_alloc_t __user *) data, alloc, sizeof(alloc)); return 0; } diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index b2934b43..914d1453 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -117,6 +117,7 @@ int nouveau_unload(struct drm_device *dev) int nouveau_ioctl_getparam(DRM_IOCTL_ARGS) { DRM_DEVICE; + drm_nouveau_private_t *dev_priv = dev->dev_private; drm_nouveau_getparam_t getparam; DRM_COPY_FROM_USER_IOCTL(getparam, (drm_nouveau_getparam_t __user *)data, @@ -137,6 +138,12 @@ int nouveau_ioctl_getparam(DRM_IOCTL_ARGS) else getparam.value=NV_PCI; break; + case NOUVEAU_GETPARAM_FB_PHYSICAL: + getparam.value=dev_priv->fb_phys; + break; + case NOUVEAU_GETPARAM_AGP_PHYSICAL: + getparam.value=dev_priv->agp_phys; + break; default: DRM_ERROR("unknown parameter %d\n", getparam.param); return DRM_ERR(EINVAL); From 1a40f3318c2660b83f64f7ed189d0f1692644ee4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Dec 2006 00:11:42 +1100 Subject: [PATCH 058/129] Port remaining NV4 RAMIN access from the ddx into the drm. Should fix lockups seen on NV4 cards. --- shared-core/nouveau_fifo.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 67c790b4..a611e438 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -434,13 +434,24 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, dev_priv->cmdbuf_alloc->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); - } else { + + } else if (dev_priv->card_type != NV_04) { cb_obj = nouveau_dma_object_create(dev, dev_priv->cmdbuf_alloc->start - drm_get_resource_start(dev, 1), dev_priv->cmdbuf_alloc->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); + } else { + /* NV04 cmdbuf hack, from original ddx.. not sure of it's + * exact reason for existing :) PCI access to cmdbuf in + * VRAM. + */ + cb_obj = nouveau_dma_object_create(dev, + dev_priv->cmdbuf_alloc->start, + dev_priv->cmdbuf_alloc->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_PCI); } if (!cb_obj) { DRM_ERROR("unable to alloc object for command buffer\n"); From aefc7a34431a8f1540b261e23d8b8d05d824b60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 14 Dec 2006 19:31:56 +0100 Subject: [PATCH 059/129] Unify radeon offset checking. Replace r300_check_offset() with generic radeon_check_offset(), which doesn't reject valid offsets when the framebuffer area is at the very end of the card's 32 bit address space. Make radeon_check_and_fixup_offset() use radeon_check_offset() as well. This fixes https://bugs.freedesktop.org/show_bug.cgi?id=7697 . --- shared-core/r300_cmdbuf.c | 32 ++++++-------------------------- shared-core/radeon_drv.h | 15 +++++++++++++++ shared-core/radeon_state.c | 13 ++++--------- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index c65ffd59..0c04b5f8 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -242,26 +242,6 @@ static __inline__ int r300_check_range(unsigned reg, int count) return 0; } -/* - * we expect offsets passed to the framebuffer to be either within video - * memory or within AGP space - */ -static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, - u32 offset) -{ - /* we realy want to check against end of video aperture - but this value is not being kept. - This code is correct for now (does the same thing as the - code that sets MC_FB_LOCATION) in radeon_cp.c */ - if (offset >= dev_priv->fb_location && - offset < (dev_priv->fb_location + dev_priv->fb_size)) - return 0; - if (offset >= dev_priv->gart_vm_start && - offset < (dev_priv->gart_vm_start + dev_priv->gart_size)) - return 0; - return 1; -} - static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * dev_priv, drm_radeon_kcmd_buffer_t @@ -290,7 +270,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * case MARK_SAFE: break; case MARK_CHECK_OFFSET: - if (r300_check_offset(dev_priv, (u32) values[i])) { + if (!radeon_check_offset(dev_priv, (u32) values[i])) { DRM_ERROR ("Offset failed range check (reg=%04x sz=%d)\n", reg, sz); @@ -452,7 +432,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, i = 1; while ((k < narrays) && (i < (count + 1))) { i++; /* skip attribute field */ - if (r300_check_offset(dev_priv, payload[i])) { + if (!radeon_check_offset(dev_priv, payload[i])) { DRM_ERROR ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i); @@ -463,7 +443,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, if (k == narrays) break; /* have one more to process, they come in pairs */ - if (r300_check_offset(dev_priv, payload[i])) { + if (!radeon_check_offset(dev_priv, payload[i])) { DRM_ERROR ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i); @@ -508,7 +488,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[2] << 10; - ret = r300_check_offset(dev_priv, offset); + ret = !radeon_check_offset(dev_priv, offset); if (ret) { DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); return DRM_ERR(EINVAL); @@ -518,7 +498,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[3] << 10; - ret = r300_check_offset(dev_priv, offset); + ret = !radeon_check_offset(dev_priv, offset); if (ret) { DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); return DRM_ERR(EINVAL); @@ -551,7 +531,7 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); return DRM_ERR(EINVAL); } - ret = r300_check_offset(dev_priv, cmd[2]); + ret = !radeon_check_offset(dev_priv, cmd[2]); if (ret) { DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); return DRM_ERR(EINVAL); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 6ea2a175..5c426fe0 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -306,6 +306,21 @@ extern int radeon_no_wb; extern drm_ioctl_desc_t radeon_ioctls[]; extern int radeon_max_ioctl; +/* Check whether the given hardware address is inside the framebuffer or the + * GART area. + */ +static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, + u64 off) +{ + u32 fb_start = dev_priv->fb_location; + u32 fb_end = fb_start + dev_priv->fb_size - 1; + u32 gart_start = dev_priv->gart_vm_start; + u32 gart_end = gart_start + dev_priv->gart_size - 1; + + return ((off >= fb_start && off <= fb_end) || + (off >= gart_start && off <= gart_end)); +} + /* radeon_cp.c */ extern int radeon_cp_init(DRM_IOCTL_ARGS); extern int radeon_cp_start(DRM_IOCTL_ARGS); diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index bf5e3d29..40b7d6ce 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -43,10 +43,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * u32 * offset) { u64 off = *offset; - u32 fb_start = dev_priv->fb_location; - u32 fb_end = fb_start + dev_priv->fb_size - 1; - u32 gart_start = dev_priv->gart_vm_start; - u32 gart_end = gart_start + dev_priv->gart_size - 1; + u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1; struct drm_radeon_driver_file_fields *radeon_priv; /* Hrm ... the story of the offset ... So this function converts @@ -66,8 +63,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * /* First, the best case, the offset already lands in either the * framebuffer or the GART mapped space */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) + if (radeon_check_offset(dev_priv, off)) return 0; /* Ok, that didn't happen... now check if we have a zero based @@ -81,11 +77,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * /* Finally, assume we aimed at a GART offset if beyond the fb */ if (off > fb_end) - off = off - fb_end - 1 + gart_start; + off = off - fb_end - 1 + dev_priv->gart_vm_start; /* Now recheck and fail if out of bounds */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) { + if (radeon_check_offset(dev_priv, off)) { DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); *offset = off; return 0; From 38ed67196f4ba891568c5ff66e67ced341696eb9 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 15 Dec 2006 12:37:24 +0100 Subject: [PATCH 060/129] Remove the memory caches for fence objects and memory manager nodes, since the support for memory caches has gone from 2.6.20. --- linux-core/drmP.h | 31 ------------------------- linux-core/drm_drv.c | 51 ------------------------------------------ linux-core/drm_fence.c | 9 +++----- linux-core/drm_mm.c | 15 +++++-------- linux-core/drm_stub.c | 5 ----- 5 files changed, 9 insertions(+), 102 deletions(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index d02184c7..13f97eee 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -755,17 +755,6 @@ typedef struct drm_head { struct class_device *dev_class; } drm_head_t; -typedef struct drm_cache { - - /* - * Memory caches - */ - - kmem_cache_t *mm; - kmem_cache_t *fence_object; -} drm_cache_t; - - typedef struct drm_fence_driver{ int no_types; @@ -1318,7 +1307,6 @@ extern int drm_put_head(drm_head_t * head); extern unsigned int drm_debug; /* 1 to enable debug output */ extern unsigned int drm_cards_limit; extern drm_head_t **drm_heads; -extern drm_cache_t drm_cache; extern struct drm_sysfs_class *drm_class; extern struct proc_dir_entry *drm_proc_root; @@ -1581,25 +1569,6 @@ static inline void drm_ctl_free(void *pt, size_t size, int area) drm_free_memctl(size); } -static inline void *drm_ctl_cache_alloc(kmem_cache_t *cache, size_t size, - int flags) -{ - void *ret; - if (drm_alloc_memctl(size)) - return NULL; - ret = kmem_cache_alloc(cache, flags); - if (!ret) - drm_free_memctl(size); - return ret; -} - -static inline void drm_ctl_cache_free(kmem_cache_t *cache, size_t size, - void *obj) -{ - kmem_cache_free(cache, obj); - drm_free_memctl(size); -} - /*@}*/ #endif /* __KERNEL__ */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 518e2aa3..45f563ff 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -446,52 +446,6 @@ static struct file_operations drm_stub_fops = { .open = drm_stub_open }; -static int drm_create_memory_caches(void) -{ - drm_cache.mm = kmem_cache_create("drm_mm_node_t", - sizeof(drm_mm_node_t), - 0, - SLAB_HWCACHE_ALIGN, - NULL,NULL); - if (!drm_cache.mm) - return -ENOMEM; - - drm_cache.fence_object= kmem_cache_create("drm_fence_object_t", - sizeof(drm_fence_object_t), - 0, - SLAB_HWCACHE_ALIGN, - NULL,NULL); - if (!drm_cache.fence_object) - return -ENOMEM; - - return 0; -} - -static void drm_free_mem_cache(kmem_cache_t *cache, - const char *name) -{ - if (!cache) - return; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) - if (kmem_cache_destroy(cache)) { - DRM_ERROR("Warning! DRM is leaking %s memory.\n", - name); - } -#else - kmem_cache_destroy(cache); -#endif -} - -static void drm_free_memory_caches(void ) -{ - - drm_free_mem_cache(drm_cache.fence_object, "fence object"); - drm_cache.fence_object = NULL; - drm_free_mem_cache(drm_cache.mm, "memory manager block"); - drm_cache.mm = NULL; -} - - static int __init drm_core_init(void) { int ret; @@ -499,9 +453,6 @@ static int __init drm_core_init(void) si_meminfo(&si); drm_init_memctl(si.totalram/2, si.totalram*3/4); - ret = drm_create_memory_caches(); - if (ret) - goto err_p1; ret = -ENOMEM; drm_cards_limit = @@ -539,13 +490,11 @@ err_p2: unregister_chrdev(DRM_MAJOR, "drm"); drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); err_p1: - drm_free_memory_caches(); return ret; } static void __exit drm_core_exit(void) { - drm_free_memory_caches(); remove_proc_entry("dri", NULL); drm_sysfs_destroy(drm_class); diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index f656340e..06d48255 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -117,8 +117,7 @@ void drm_fence_usage_deref_locked(drm_device_t * dev, DRM_DEBUG("Destroyed a fence object 0x%08lx\n", fence->base.hash.key); atomic_dec(&fm->count); - drm_ctl_cache_free(drm_cache.fence_object, sizeof(*fence), - fence); + drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE); } } @@ -132,8 +131,7 @@ void drm_fence_usage_deref_unlocked(drm_device_t * dev, if (atomic_read(&fence->usage) == 0) { drm_fence_unring(dev, &fence->ring); atomic_dec(&fm->count); - drm_ctl_cache_free(drm_cache.fence_object, - sizeof(*fence), fence); + drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE); } mutex_unlock(&dev->struct_mutex); } @@ -439,8 +437,7 @@ int drm_fence_object_create(drm_device_t * dev, uint32_t type, int ret; drm_fence_manager_t *fm = &dev->fm; - fence = drm_ctl_cache_alloc(drm_cache.fence_object, - sizeof(*fence), GFP_KERNEL); + fence = drm_ctl_alloc(sizeof(*fence), DRM_MEM_FENCE); if (!fence) return -ENOMEM; ret = drm_fence_object_init(dev, type, flags, fence); diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index a5566b2f..34708ef9 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -82,8 +82,7 @@ static int drm_mm_create_tail_node(drm_mm_t *mm, drm_mm_node_t *child; child = (drm_mm_node_t *) - drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), - GFP_KERNEL); + drm_ctl_alloc(sizeof(*child), DRM_MEM_MM); if (!child) return -ENOMEM; @@ -119,8 +118,7 @@ static drm_mm_node_t *drm_mm_split_at_start(drm_mm_node_t *parent, drm_mm_node_t *child; child = (drm_mm_node_t *) - drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), - GFP_KERNEL); + drm_ctl_alloc(sizeof(*child), DRM_MEM_MM); if (!child) return NULL; @@ -207,9 +205,8 @@ void drm_mm_put_block(drm_mm_node_t * cur) prev_node->size += next_node->size; list_del(&next_node->ml_entry); list_del(&next_node->fl_entry); - drm_ctl_cache_free(drm_cache.mm, - sizeof(*next_node), - next_node); + drm_ctl_free(next_node, sizeof(*next_node), + DRM_MEM_MM); } else { next_node->size += cur->size; next_node->start = cur->start; @@ -222,7 +219,7 @@ void drm_mm_put_block(drm_mm_node_t * cur) list_add(&cur->fl_entry, &list_root->fl_entry); } else { list_del(&cur->ml_entry); - drm_ctl_cache_free(drm_cache.mm, sizeof(*cur), cur); + drm_ctl_free(cur, sizeof(*cur), DRM_MEM_MM); } } @@ -296,7 +293,7 @@ void drm_mm_takedown(drm_mm_t * mm) list_del(&entry->fl_entry); list_del(&entry->ml_entry); - drm_ctl_cache_free(drm_cache.mm, sizeof(*entry), entry); + drm_ctl_free(entry, sizeof(*entry), DRM_MEM_MM); } EXPORT_SYMBOL(drm_mm_takedown); diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index c03a56a1..4f6cd3f1 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -54,11 +54,6 @@ drm_head_t **drm_heads; struct drm_sysfs_class *drm_class; struct proc_dir_entry *drm_proc_root; -drm_cache_t drm_cache = -{ .mm = NULL, - .fence_object = NULL -}; - static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) From b3c88d31e1e83458c6125a02b80f2e57ebcf750d Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Fri, 15 Dec 2006 14:24:24 +0100 Subject: [PATCH 061/129] drm/linux-core: drmP.h compilation fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I need the following patch to fix compilation of latest drm/linux-core on my ppc64 machine. /home/mb/develop/git/drm/linux-core/savage_bci.c: In function ‘savage_driver_firstopen’: /home/mb/develop/git/drm/linux-core/savage_bci.c:587: error: ‘DRM_MTRR_WC’ undeclared (first use in this function) /home/mb/develop/git/drm/linux-core/savage_bci.c:587: error: (Each undeclared identifier is reported only once /home/mb/develop/git/drm/linux-core/savage_bci.c:587: error: for each function it appears in.) /home/mb/develop/git/drm/linux-core/savage_bci.c: In function ‘savage_driver_lastclose’: /home/mb/develop/git/drm/linux-core/savage_bci.c:664: error: ‘DRM_MTRR_WC’ undeclared (first use in this function) I looked at in-kernel drmP.h and it actually has the same fix in it. Signed-off-by: Michael Buesch --- linux-core/drmP.h | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 13f97eee..5827efba 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1083,6 +1083,7 @@ static inline int drm_mtrr_del(int handle, unsigned long offset, } #define drm_core_has_MTRR(dev) (0) +#define DRM_MTRR_WC 0 #endif From cc22cd8bde39f3e4be8ca9f726a773b0270ebdbc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 16:39:13 +1100 Subject: [PATCH 062/129] drm: ioremap balanced with iounmap for drivers/char/drm ioremap must be balanced by an iounmap and failing to do so can result in a memory leak. Tested (compilation only) to make sure the files are compiling without any warning/error due to new changes Signed-off-by: Amol Lad Signed-off-by: Dave Airlie --- linux-core/drm_bufs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index d6ebc8d1..1ff7c90b 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -279,6 +279,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); if (!list) { + if (map->type == _DRM_REGISTERS) + drm_ioremap(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } @@ -295,6 +297,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, ret = drm_map_handle(dev, &list->hash, user_token, 0); if (ret) { + if (map->type == _DRM_REGISTERS) + drm_ioremap(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(list, sizeof(*list), DRM_MEM_MAPS); mutex_unlock(&dev->struct_mutex); From 696f2bfbd1b6da73893bce082308a43878e6ab75 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 16:44:57 +1100 Subject: [PATCH 063/129] Revert "drm: ioremap balanced with iounmap for drivers/char/drm" This reverts cc22cd8bde39f3e4be8ca9f726a773b0270ebdbc commit. I put this patch incorrectly in .. will fix now --- linux-core/drm_bufs.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 1ff7c90b..d6ebc8d1 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -279,8 +279,6 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); if (!list) { - if (map->type == _DRM_REGISTERS) - drm_ioremap(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } @@ -297,8 +295,6 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, ret = drm_map_handle(dev, &list->hash, user_token, 0); if (ret) { - if (map->type == _DRM_REGISTERS) - drm_ioremap(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(list, sizeof(*list), DRM_MEM_MAPS); mutex_unlock(&dev->struct_mutex); From cb280ad3c0b048fe5b024439af70e9fcc8d04269 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 16:58:27 +1100 Subject: [PATCH 064/129] fix missing DRM_ERR from kernel --- shared-core/savage_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/savage_state.c b/shared-core/savage_state.c index 5c8a43eb..acc98f89 100644 --- a/shared-core/savage_state.c +++ b/shared-core/savage_state.c @@ -993,7 +993,7 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) if (cmdbuf.size) { kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); if (kcmd_addr == NULL) - return ENOMEM; + return DRM_ERR(ENOMEM); if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, cmdbuf.size * 8)) From 6c8712ba8a3c3c2c2fd9dd1ff5ab71e30ecdf50a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 16:58:48 +1100 Subject: [PATCH 065/129] use spin_lock_init in via dmablit --- linux-core/via_dmablit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-core/via_dmablit.c b/linux-core/via_dmablit.c index fdc2bd67..cbb73711 100644 --- a/linux-core/via_dmablit.c +++ b/linux-core/via_dmablit.c @@ -562,7 +562,7 @@ via_init_dmablit(drm_device_t *dev) blitq->num_outstanding = 0; blitq->is_active = 0; blitq->aborting = 0; - blitq->blit_lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&blitq->blit_lock); for (j=0; jblit_queue + j); } From 13659357adeae90dbeb1b3284f08667f6edd4cad Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 17:03:42 +1100 Subject: [PATCH 066/129] make a savage function static from kernel --- shared-core/savage_bci.c | 4 +++- shared-core/savage_drv.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/shared-core/savage_bci.c b/shared-core/savage_bci.c index 01121b92..5632b5c8 100644 --- a/shared-core/savage_bci.c +++ b/shared-core/savage_bci.c @@ -32,6 +32,8 @@ #define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ #define SAVAGE_FREELIST_DEBUG 0 +static int savage_do_cleanup_bci(drm_device_t *dev); + static int savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n) { @@ -895,7 +897,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) return 0; } -int savage_do_cleanup_bci(drm_device_t *dev) +static int savage_do_cleanup_bci(drm_device_t *dev) { drm_savage_private_t *dev_priv = dev->dev_private; diff --git a/shared-core/savage_drv.h b/shared-core/savage_drv.h index 560f934e..88c571e1 100644 --- a/shared-core/savage_drv.h +++ b/shared-core/savage_drv.h @@ -212,7 +212,6 @@ extern int savage_driver_load(drm_device_t *dev, unsigned long chipset); extern int savage_driver_firstopen(drm_device_t *dev); extern void savage_driver_lastclose(drm_device_t *dev); extern int savage_driver_unload(drm_device_t *dev); -extern int savage_do_cleanup_bci(drm_device_t *dev); extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp); /* state functions */ From 8cc82c50332d62d1c58bbc4f184b1ab4ecfa9efc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 17:22:04 +1100 Subject: [PATCH 067/129] remove inline from large function --- shared-core/r128_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c index deeb67ed..17b11e7d 100644 --- a/shared-core/r128_state.c +++ b/shared-core/r128_state.c @@ -221,7 +221,7 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static __inline__ void r128_emit_state(drm_r128_private_t * dev_priv) +static void r128_emit_state(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; From 2253e334cc6f8cf7dff6dbe398dd9ecbbcb4c5fe Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 17:42:45 +1100 Subject: [PATCH 068/129] make sizeof match the copy struct --- linux-core/drm_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index 776f462e..3dcc4bfb 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -337,7 +337,7 @@ int drm_setversion(DRM_IOCTL_ARGS) retv.drm_dd_major = dev->driver->major; retv.drm_dd_minor = dev->driver->minor; - if (copy_to_user(argp, &retv, sizeof(sv))) + if (copy_to_user(argp, &retv, sizeof(retv))) return -EFAULT; if (sv.drm_di_major != -1) { From c52dea9a7d9ea978307441842b02c09c97720467 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 17:46:10 +1100 Subject: [PATCH 069/129] fix some sizes in sis_drv.h --- shared-core/sis_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-core/sis_drv.h b/shared-core/sis_drv.h index d1cdc19c..006d148c 100644 --- a/shared-core/sis_drv.h +++ b/shared-core/sis_drv.h @@ -57,9 +57,9 @@ enum sis_family { typedef struct drm_sis_private { drm_local_map_t *mmio; - unsigned idle_fault; + unsigned int idle_fault; drm_sman_t sman; - unsigned long chipset; + unsigned int chipset; int vram_initialized; int agp_initialized; unsigned long vram_offset; From 07635f26a9310d2a4f0f65c5e773e6cfa92346bc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 17:57:01 +1100 Subject: [PATCH 070/129] fix comment in r128 --- shared-core/r128_irq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shared-core/r128_irq.c b/shared-core/r128_irq.c index de1597ec..87f8ca2b 100644 --- a/shared-core/r128_irq.c +++ b/shared-core/r128_irq.c @@ -1,5 +1,4 @@ -/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- - */ +/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */ /* * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * From 1a3316f667963fca2f9a3bffcbee39cb01bf5f09 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 17:57:16 +1100 Subject: [PATCH 071/129] use unifdef to clean up some code --- scripts/create_lk_drm.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/scripts/create_lk_drm.sh b/scripts/create_lk_drm.sh index 4b57ce20..2f00d7a3 100755 --- a/scripts/create_lk_drm.sh +++ b/scripts/create_lk_drm.sh @@ -27,3 +27,17 @@ cp linux-core/Makefile.kernel $OUTDIR/Makefile echo "Copying 2.6 Kernel files" cp linux-core/Kconfig $OUTDIR/ +cd $OUTDIR + +for i in via*.[ch] +do +unifdef -D__linux__ -DVIA_HAVE_DMABLIT -DVIA_HAVE_CORE_MM $i > $i.tmp +mv $i.tmp $i +done + +for i in sis*.[ch] +do +unifdef -D__linux__ -DVIA_HAVE_DMABLIT -DSIS_HAVE_CORE_MM $i > $i.tmp +mv $i.tmp $i +done +cd - From 303307d25484f3f7179e6967697d28369a73dca9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 18:03:20 +1100 Subject: [PATCH 072/129] fix irq args compatiblity with pre 2.6.19 --- linux-core/drm_compat.h | 6 ++++++ linux-core/drm_os_linux.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h index a1a94399..c4e80e91 100644 --- a/linux-core/drm_compat.h +++ b/linux-core/drm_compat.h @@ -57,6 +57,12 @@ #define module_param(name, type, perm) #endif +/* older kernels had different irq args */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) +#undef DRM_IRQ_ARGS +#define DRM_IRQ_ARGS int irq, void *arg, struct pt_regs *regs +#endif + #ifndef list_for_each_safe #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h index 42700978..49ba2fbc 100644 --- a/linux-core/drm_os_linux.h +++ b/linux-core/drm_os_linux.h @@ -56,7 +56,7 @@ drm_device_t *dev = priv->head->dev /** IRQ handler arguments and return type and values */ -#define DRM_IRQ_ARGS int irq, void *arg, struct pt_regs *regs +#define DRM_IRQ_ARGS int irq, void *arg /** backwards compatibility with old irq return values */ #ifndef IRQ_HANDLED typedef void irqreturn_t; From 0ab48b0841de138f4a428a6d32d3e4d3e552db53 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 18:24:44 +1100 Subject: [PATCH 073/129] [PATCH] mm: incorrect VM_FAULT_OOM returns from drivers Some drivers are returning OOM when it is not in response to a memory shortage. Signed-off-by: Nick Piggin --- linux-core/drm_vm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 6eb996ad..4f6a20eb 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -269,13 +269,13 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!map) - return NOPAGE_OOM; /* Nothing allocated */ + return NOPAGE_SIGBUS; /* Nothing allocated */ offset = address - vma->vm_start; i = (unsigned long)map->handle + offset; page = vmalloc_to_page((void *)i); if (!page) - return NOPAGE_OOM; + return NOPAGE_SIGBUS; get_page(page); DRM_DEBUG("shm_nopage 0x%lx\n", address); @@ -396,7 +396,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!dma->pagelist) - return NOPAGE_OOM; /* Nothing allocated */ + return NOPAGE_SIGBUS; /* Nothing allocated */ offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ page_nr = offset >> PAGE_SHIFT; @@ -435,7 +435,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!entry->pagelist) - return NOPAGE_OOM; /* Nothing allocated */ + return NOPAGE_SIGBUS; /* Nothing allocated */ offset = address - vma->vm_start; map_offset = map->offset - (unsigned long)dev->sg->virtual; From 656c3a3737180d507bec352d56fbd9ef8b8a4feb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 18:27:20 +1100 Subject: [PATCH 074/129] [SPARC]: Respect vm_page_prot in io_remap_page_range(). Make sure the callers do a pgprot_noncached() on vma->vm_page_prot. Pointed out by Hugh Dickens. Signed-off-by: David S. Miller --- linux-core/drm_vm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 4f6a20eb..a65fbc73 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -829,6 +829,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_IO; /* not in core dump */ vma->vm_page_prot = drm_io_prot(map->type, vma); #ifdef __sparc__ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (io_remap_pfn_range(vma, vma->vm_start, (map->offset + offset) >>PAGE_SHIFT, vma->vm_end - vma->vm_start, From 86ff2aeb9bfea357d5748b3587ab224e813b37b6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 20:29:03 +1100 Subject: [PATCH 075/129] drm: remove all 2.4 support for drm development tree. Bye bye 2.4 you served us well.. --- linux-core/Makefile | 31 ++----------- linux-core/drmP.h | 18 +------- linux-core/drm_agpsupport.c | 4 -- linux-core/drm_compat.h | 92 +------------------------------------ linux-core/drm_memory.h | 20 +------- linux-core/drm_os_linux.h | 5 -- linux-core/drm_stub.c | 4 +- linux-core/drm_vm.c | 47 ------------------- linux-core/sis_mm.c | 4 -- 9 files changed, 8 insertions(+), 217 deletions(-) diff --git a/linux-core/Makefile b/linux-core/Makefile index b4cff78a..06a15ff2 100644 --- a/linux-core/Makefile +++ b/linux-core/Makefile @@ -241,11 +241,11 @@ else # Check for kernel versions that we don't support. -BELOW24 := $(shell if [ $(VERSION) -lt 2 -o $(PATCHLEVEL) -lt 4 ]; then \ +BELOW26 := $(shell if [ $(VERSION) -lt 2 -o $(PATCHLEVEL) -lt 6 ]; then \ echo y; fi) -ifeq ($(BELOW24),y) -$(error Only 2.4.x and later kernels are supported \ +ifeq ($(BELOW26),y) +$(error Only 2.6.x and later kernels are supported \ ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL))) endif @@ -258,30 +258,6 @@ endif # This needs to go before all other include paths. CC += -I$(DRMSRCDIR) -# Check for Red Hat's 4-argument do_munmap(). -DOMUNMAP := $(shell grep do_munmap $(LINUXDIR)/include/linux/mm.h | \ - grep -c acct) - -ifneq ($(DOMUNMAP),0) -EXTRA_CFLAGS += -DDO_MUNMAP_4_ARGS -endif - -# Check for 5-argument remap_page_range() in RH9 kernel, and 2.5.x kernels -RPR := $(shell grep remap_page_range $(LINUXDIR)/include/linux/mm.h | \ - grep -c vma) - -ifneq ($(RPR),0) -EXTRA_CFLAGS += -DREMAP_PAGE_RANGE_5_ARGS -endif - -# Check for 4-argument vmap() in some 2.5.x and 2.4.x kernels -VMAP := $(shell grep -A1 'vmap.*count,$$' $(LINUXDIR)/include/linux/vmalloc.h | \ - grep -c prot) - -ifneq ($(VMAP),0) -EXTRA_CFLAGS += -DVMAP_4_ARGS -endif - # Check for PAGE_AGP definition PAGE_AGP := $(shell cat $(LINUXDIR)/include/asm/agp.h 2>/dev/null | \ grep -c PAGE_AGP) @@ -290,7 +266,6 @@ ifneq ($(PAGE_AGP),0) EXTRA_CFLAGS += -DHAVE_PAGE_AGP endif - # Start with all modules turned off. CONFIG_DRM_GAMMA := n CONFIG_DRM_TDFX := n diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 5827efba..c19b6afb 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -70,16 +70,7 @@ #include #include #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41) -#define HAS_WORKQUEUE 0 -#else -#define HAS_WORKQUEUE 1 -#endif -#if !HAS_WORKQUEUE -#include -#else #include -#endif #include #include #include "drm.h" @@ -897,11 +888,8 @@ typedef struct drm_device { unsigned long last_switch; /**< jiffies at last context switch */ /*@} */ -#if !HAS_WORKQUEUE - struct tq_struct tq; -#else struct work_struct work; -#endif + /** \name VBLANK IRQ support */ /*@{ */ @@ -929,11 +917,7 @@ typedef struct drm_device { int pci_vendor; /**< PCI vendor id */ int pci_device; /**< PCI device id */ #ifdef __alpha__ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) - struct pci_controler *hose; -#else struct pci_controller *hose; -#endif #endif drm_sg_mem_t *sg; /**< Scatter gather memory */ unsigned long *ctx_bitmap; /**< context bitmap */ diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index a5f1f9ee..79d9a835 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -106,10 +106,6 @@ int drm_agp_acquire(drm_device_t * dev) return -ENODEV; if (dev->agp->acquired) return -EBUSY; -#ifndef VMAP_4_ARGS - if (dev->agp->cant_use_aperture) - return -EINVAL; -#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11) if ((retcode = agp_backend_acquire())) return retcode; diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h index c4e80e91..13a2ba81 100644 --- a/linux-core/drm_compat.h +++ b/linux-core/drm_compat.h @@ -86,92 +86,12 @@ pos = n, n = list_entry(n->member.next, typeof(*n), member)) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) -static inline struct page *vmalloc_to_page(void *vmalloc_addr) -{ - unsigned long addr = (unsigned long)vmalloc_addr; - struct page *page = NULL; - pgd_t *pgd = pgd_offset_k(addr); - pmd_t *pmd; - pte_t *ptep, pte; - - if (!pgd_none(*pgd)) { - pmd = pmd_offset(pgd, addr); - if (!pmd_none(*pmd)) { - preempt_disable(); - ptep = pte_offset_map(pmd, addr); - pte = *ptep; - if (pte_present(pte)) - page = pte_page(pte); - pte_unmap(ptep); - preempt_enable(); - } - } - return page; -} -#endif - -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2) -#define down_write down -#define up_write up -#endif - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #define DRM_PCI_DEV(pdev) &pdev->dev #else #define DRM_PCI_DEV(pdev) NULL #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static inline unsigned iminor(struct inode *inode) -{ - return MINOR(inode->i_rdev); -} - -#define old_encode_dev(x) (x) - -struct drm_sysfs_class; -struct class_simple; -struct device; - -#define pci_dev_put(x) do {} while (0) -#define pci_get_subsys pci_find_subsys - -static inline struct class_device *DRM(sysfs_device_add) (struct drm_sysfs_class - * cs, dev_t dev, - struct device * - device, - const char *fmt, - ...) { - return NULL; -} - -static inline void DRM(sysfs_device_remove) (dev_t dev) { -} - -static inline void DRM(sysfs_destroy) (struct drm_sysfs_class * cs) { -} - -static inline struct drm_sysfs_class *DRM(sysfs_create) (struct module * owner, - char *name) { - return NULL; -} - -#ifndef pci_pretty_name -#define pci_pretty_name(x) x->name -#endif - -struct drm_device; -static inline int radeon_create_i2c_busses(struct drm_device *dev) -{ - return 0; -}; -static inline void radeon_delete_i2c_busses(struct drm_device *dev) -{ -}; - -#endif - #ifndef __user #define __user #endif @@ -184,18 +104,12 @@ static inline void radeon_delete_i2c_busses(struct drm_device *dev) #define __GFP_COMP 0 #endif -#ifndef REMAP_PAGE_RANGE_5_ARGS -#define DRM_RPR_ARG(vma) -#else -#define DRM_RPR_ARG(vma) vma, -#endif - #define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) static inline int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t pgprot) { - return remap_page_range(DRM_RPR_ARG(vma) from, + return remap_page_range(vma, from, pfn << PAGE_SHIFT, size, pgprot); @@ -221,10 +135,6 @@ static inline int remap_pfn_range(struct vm_area_struct *vma, unsigned long from #define __x86_64__ #endif -#ifndef pci_pretty_name -#define pci_pretty_name(dev) "" -#endif - /* sysfs __ATTR macro */ #ifndef __ATTR #define __ATTR(_name,_mode,_show,_store) { \ diff --git a/linux-core/drm_memory.h b/linux-core/drm_memory.h index 4a2c3583..c299e25a 100644 --- a/linux-core/drm_memory.h +++ b/linux-core/drm_memory.h @@ -43,7 +43,7 @@ */ /* Need the 4-argument version of vmap(). */ -#if __OS_HAS_AGP && defined(VMAP_4_ARGS) +#if __OS_HAS_AGP #include @@ -57,18 +57,6 @@ # endif #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#ifndef pte_offset_kernel -# define pte_offset_kernel(dir, address) pte_offset(dir, address) -#endif -#ifndef pte_pfn -# define pte_pfn(pte) (pte_page(pte) - mem_map) -#endif -#ifndef pfn_to_page -# define pfn_to_page(pfn) (mem_map + (pfn)) -#endif -#endif - /* * Find the drm_map that covers the range [offset, offset+size). */ @@ -171,14 +159,12 @@ static inline unsigned long drm_follow_page(void *vaddr) static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t * dev) { -#if defined(VMAP_4_ARGS) if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { drm_map_t *map = drm_lookup_map(offset, size, dev); if (map && map->type == _DRM_AGP) return agp_remap(offset, size, dev); } -#endif return ioremap(offset, size); } @@ -186,14 +172,12 @@ static inline void *drm_ioremap(unsigned long offset, unsigned long size, static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size, drm_device_t * dev) { -#if defined(VMAP_4_ARGS) if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { drm_map_t *map = drm_lookup_map(offset, size, dev); if (map && map->type == _DRM_AGP) return agp_remap(offset, size, dev); } -#endif return ioremap_nocache(offset, size); } @@ -201,7 +185,6 @@ static inline void *drm_ioremap_nocache(unsigned long offset, static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev) { -#if defined(VMAP_4_ARGS) /* * This is a bit ugly. It would be much cleaner if the DRM API would use separate * routines for handling mappings in the AGP space. Hopefully this can be done in @@ -220,7 +203,6 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, return; } } -#endif iounmap(pt); } #else diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h index 49ba2fbc..78dd00e5 100644 --- a/linux-core/drm_os_linux.h +++ b/linux-core/drm_os_linux.h @@ -66,13 +66,8 @@ typedef void irqreturn_t; /** AGP types */ #if __OS_HAS_AGP -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,70) -#define DRM_AGP_MEM agp_memory -#define DRM_AGP_KERN agp_kern_info -#else #define DRM_AGP_MEM struct agp_memory #define DRM_AGP_KERN struct agp_kern_info -#endif #else /* define some dummy types for non AGP supporting kernels */ struct no_agp_kern { diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 4f6cd3f1..e9d0ac6c 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -244,9 +244,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if ((ret = drm_get_head(dev, &dev->primary))) goto err_g1; - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary.minor, pci_pretty_name(dev->pdev)); + driver->date, dev->primary.minor); return 0; diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index a65fbc73..2bf408eb 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -446,8 +446,6 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, return page; } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) - static struct page *drm_vm_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { @@ -481,34 +479,6 @@ static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma, } -#else /* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */ - -static struct page *drm_vm_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_nopage(vma, address); -} - -static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_shm_nopage(vma, address); -} - -static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_dma_nopage(vma, address); -} - -static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_sg_nopage(vma, address); -} - -#endif - /** AGP virtual memory operations */ static struct vm_operations_struct drm_vm_ops = { .nopage = drm_vm_nopage, @@ -712,12 +682,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) } vma->vm_ops = &drm_vm_dma_ops; - -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ -#else vma->vm_flags |= VM_RESERVED; /* Don't swap */ -#endif vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open(vma); @@ -860,20 +825,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_private_data = (void *)map; /* Don't let this area swap. Change when DRM_KERNEL advisory is supported. */ -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED; -#else vma->vm_flags |= VM_RESERVED; -#endif break; case _DRM_SCATTER_GATHER: vma->vm_ops = &drm_vm_sg_ops; vma->vm_private_data = (void *)map; -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED; -#else vma->vm_flags |= VM_RESERVED; -#endif break; case _DRM_TTM: { vma->vm_ops = &drm_vm_ttm_ops; @@ -892,11 +849,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) default: return -EINVAL; /* This should never happen. */ } -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ -#else vma->vm_flags |= VM_RESERVED; /* Don't swap */ -#endif vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open(vma); diff --git a/linux-core/sis_mm.c b/linux-core/sis_mm.c index eca535fb..5efbada4 100644 --- a/linux-core/sis_mm.c +++ b/linux-core/sis_mm.c @@ -36,11 +36,7 @@ #include "sis_drv.h" #if defined(__linux__) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include