From 0afb877a37a33e8493628ddc267fb00650fd1840 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 19 Aug 2006 17:59:18 +1000 Subject: drm: lots of small cleanups and whitespace issues fixed up remove a mach64 warning, align a lot of things from linux kernel --- 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 ++++---- 9 files changed, 71 insertions(+), 72 deletions(-) (limited to 'shared-core') 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]; -- cgit v1.2.3 From fef9b30a2b437c0103c33443566604027529b91d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 27 Aug 2006 08:55:02 +1000 Subject: initial import of nouveau code from nouveau CVS --- 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 ++++++++++ 9 files changed, 2071 insertions(+) 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 (limited to 'shared-core') 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; +} + -- cgit v1.2.3 From 88928380c87e60d22a0a9698c468036f180f0761 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 27 Aug 2006 08:59:50 +1000 Subject: add pci ids for nouveau --- shared-core/drm_pciids.txt | 208 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) (limited to 'shared-core') 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" -- cgit v1.2.3 From 24dddc27549f2b8cf837305ee84dd1ca97df98e7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 30 Aug 2006 16:55:02 +1000 Subject: 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(+) (limited to 'shared-core') 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; +} + -- cgit v1.2.3 From 97291a6ad05848b05af69e52453d93db1e96473b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 2 Sep 2006 22:25:26 +1000 Subject: 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(-) (limited to 'shared-core') 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; } -- cgit v1.2.3 From b119966ae65c9ee74096cf0b246bf7703cb58ec4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 3 Sep 2006 06:36:06 +1000 Subject: 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(-) (limited to 'shared-core') 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; +} + -- cgit v1.2.3 From d89c623f8e739815ea952adc77cfe5c0f7204407 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 7 Sep 2006 00:35:17 +0200 Subject: Remove a 64 bit div. --- shared-core/nouveau_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') 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", -- cgit v1.2.3 From 0ef29768ca909421539c3d8f65bb8e94912fa597 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 7 Sep 2006 23:59:19 +1000 Subject: 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(-) (limited to 'shared-core') 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) -- cgit v1.2.3 From aa80e2f48f291aa41524dfb53023499c91473705 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 9 Sep 2006 07:35:55 +1000 Subject: Add copyright notices while I still remember.. --- shared-core/nouveau_irq.c | 32 ++++++++++++++++++++++++++++++++ shared-core/nouveau_object.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) (limited to 'shared-core') 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" -- cgit v1.2.3 From 22382bd8c540231641bfc75d778a50ddf1463783 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 17 Sep 2006 13:00:27 +1000 Subject: Add pciid for GeForce Go 6150 (0x0244). --- shared-core/drm_pciids.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') 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" -- cgit v1.2.3 From dd473411f889cc16af255437d2a61c616bcee695 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 11 Oct 2006 00:28:15 +0200 Subject: 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(-) (limited to 'shared-core') 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); - } - if (!cb) { - DRM_ERROR("Couldn't allocate DMA command buffer.\n"); - return DRM_ERR(ENOMEM); + 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 (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; } -- cgit v1.2.3 From a749d9d5b49ea0e402848bd6024e5c44826e784f Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 12 Oct 2006 01:08:15 +0200 Subject: 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(-) (limited to 'shared-core') 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; - - // 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); + if (dev_priv->card_type <= NV_04) + ctx_size=32; + else + ctx_size=128; - // 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); + 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_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) -- cgit v1.2.3 From 7ef44b2b8dd1745f5b228e6161ebd989844c3088 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 12 Oct 2006 17:31:49 +0200 Subject: 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(-) (limited to 'shared-core') 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; } -- cgit v1.2.3 From a9c6c3f21d90257db94536f202b3a1f03896b2f7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 12 Oct 2006 21:18:55 +0200 Subject: Oops. --- shared-core/nouveau_irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'shared-core') 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) { -- cgit v1.2.3 From 4988074794531939ec0cb0ad183633b59e9ccff4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 14 Oct 2006 06:57:49 +1100 Subject: 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(+) (limited to 'shared-core') 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); -- cgit v1.2.3 From b509abe413f74bd08f6415dec8147bd07e78a84b Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 13 Oct 2006 22:35:22 +0200 Subject: Fix the fifo context size on nv10, nv20 and nv30. --- shared-core/nouveau_fifo.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'shared-core') 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 -- cgit v1.2.3 From 3a0cd7c7e221f625585675490f626de8677a9dc7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 14 Oct 2006 01:21:31 +0200 Subject: Add the missing breaks. --- shared-core/nouveau_fifo.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core') 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; -- cgit v1.2.3 From 2c5b91aecf3d21684ffca758c034cd9a8ed2155d Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 14 Oct 2006 16:36:11 +0200 Subject: 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 | 34 ++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 17 deletions(-) (limited to 'shared-core') 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; - - 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); +// 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)|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) -- cgit v1.2.3 From 95486bbde05ae51975c4d51fd194111788edee9a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 06:12:18 +1100 Subject: Some info on NV40's RAMFC --- shared-core/nouveau_reg.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'shared-core') 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 -- cgit v1.2.3 From 1943f39d8ce27c799f928bab172e521f4d540166 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 06:37:40 +1100 Subject: 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(-) (limited to 'shared-core') 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 -- cgit v1.2.3 From 98e718d48fcd166accf1af3c017c34e331ab09cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 07:29:31 +1100 Subject: 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(-) (limited to 'shared-core') 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 -- cgit v1.2.3 From 4b43ee63f90c93701c9f1cdf7fefd1816b316d33 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 12:33:49 +1100 Subject: 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(-) (limited to 'shared-core') 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: typo --- shared-core/nouveau_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') 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); -- cgit v1.2.3 From 55de3f763f0de66b99f1afde9872f0072a84a9e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Oct 2006 23:44:05 +1100 Subject: 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(-) (limited to 'shared-core') 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 -- cgit v1.2.3 From 725984364bd899c2dee1ca9b44f56fc70ccba3ad Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 18 Oct 2006 01:07:48 +1100 Subject: Oops, we have more than 4 subchannels.. --- shared-core/nouveau_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') 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 ); -- cgit v1.2.3 From b5cf0d635c81d2c99510ce5e3f67f4aa593cd6d7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 18 Oct 2006 02:37:19 +1100 Subject: 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(-) (limited to 'shared-core') 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)) -- cgit v1.2.3 From 3ea0500be1ab7a058c90be35b5d8d2be26692f6a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 4 Nov 2006 16:56:10 +0100 Subject: 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(-) (limited to 'shared-core') 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); -- cgit v1.2.3 From 06639801ce1d515f790739a70b051498c8615288 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 4 Nov 2006 20:39:59 +0100 Subject: 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(-) (limited to 'shared-core') 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); -- cgit v1.2.3 From 665c8385c7865dcc4f92b9c212d6e2b35d7fa9f0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 5 Nov 2006 19:46:53 +1100 Subject: add powerpc mmio swapper to NV_READ/WRITE macros --- shared-core/nouveau_drv.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'shared-core') 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__ */ -- cgit v1.2.3 From 94ab96c4d8203c236c6a5a8d8a6a761ccf808662 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 5 Nov 2006 20:38:44 +1100 Subject: nouveau: add compat ioc32 support --- shared-core/nouveau_drv.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') 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) ) -- cgit v1.2.3 From 0c34d0f31a691bb649ed69f19e93fc1a723aa1d4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Nov 2006 05:46:03 +1100 Subject: 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(-) (limited to 'shared-core') 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); } -- cgit v1.2.3 From 5e55594061b24521551c45838fbe6c3df57050d1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Nov 2006 11:41:51 +1100 Subject: use a uint64_t for this not a pointer --- shared-core/nouveau_drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') 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; -- cgit v1.2.3 From 2dd3c039fdbe86db4043abcc69babf768edb3ab8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Nov 2006 11:42:15 +1100 Subject: 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(-) (limited to 'shared-core') 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) -- cgit v1.2.3 From f7affda35bb0c47fbc973725e05847669e215d46 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Nov 2006 11:44:36 +1100 Subject: drm: fixup page alignment on SAREA map on ppc64 --- shared-core/drm_sarea.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') 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 */ -- cgit v1.2.3 From 1123ab089075af3141c794696ec394fa46b4353f Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 10 Nov 2006 02:18:38 +0100 Subject: Fix memory detection on TNT2 M64/TNT2 vanta. --- shared-core/nouveau_mem.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') 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: -- cgit v1.2.3 From 9ef4bbc66c1b055b4450ea9354945d784751cef7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 14 Nov 2006 04:51:13 +1100 Subject: 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(-) (limited to 'shared-core') 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 */ -- cgit v1.2.3 From 7002082944a69e1d11b0146b1176fd4293581dcd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 14 Nov 2006 08:11:49 +1100 Subject: 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 | 177 +++++++++++++++++++++++++++---------------- shared-core/nouveau_object.c | 42 +++------- shared-core/nouveau_reg.h | 1 + shared-core/nouveau_state.c | 19 +++++ 5 files changed, 152 insertions(+), 102 deletions(-) (limited to 'shared-core') 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; - if (dev->irq_enabled) - nouveau_irq_postinstall(dev); + /* Clear RAMIN */ + for (i=0x00710000; i<0x00800000; i++) + NV_WRITE(i, 0x00000000); - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4); + /* 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); + + /* 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); + + /* 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); + + return 0; +} - DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo); +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; } -- cgit v1.2.3 From 2fd812f8ef8adb09fd8d17cab869f9fc8b047d75 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 14 Nov 2006 09:00:31 +1100 Subject: Completely untested NV10/20/30 FIFO context switching changes. --- shared-core/nouveau_fifo.c | 108 +++++++++++++++++++++++++++++---------------- shared-core/nouveau_reg.h | 14 ++++++ 2 files changed, 85 insertions(+), 37 deletions(-) (limited to 'shared-core') 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,27 +232,72 @@ 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*/); +} + +#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 - 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); + 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 - 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); + 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, @@ -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 -- cgit v1.2.3 From 18bba3fa29187bb5122ed057989203dc05bc46aa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 17 Nov 2006 08:05:23 +1100 Subject: 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(-) (limited to 'shared-core') 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); } -- cgit v1.2.3 From e9194dd1b068666dd94e73d95dc3cd031a89a6b7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 18 Nov 2006 10:03:45 +1100 Subject: 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(+) (limited to 'shared-core') 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)); -- cgit v1.2.3 From 9ac7a8b0b4c0431b605c3f8d0b4a696903010c51 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 18 Nov 2006 10:09:29 +1100 Subject: 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(-) (limited to 'shared-core') 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; } -- cgit v1.2.3 From adf71cb29b72b7d199f737b7b00eb7e80939ea4b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 21 Nov 2006 11:41:46 +1100 Subject: Don't spam dmesg if PMC_INTSTAT is 0 --- shared-core/nouveau_irq.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core') 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); -- cgit v1.2.3 From f48a7685bd7a241001cec89acd8cce6cdefa941e Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Tue, 28 Nov 2006 21:32:03 +0100 Subject: 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(-) (limited to 'shared-core') 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 -- cgit v1.2.3 From b1a9a769711d83af8ab4c7ba4eec52a05a351533 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 30 Nov 2006 08:35:42 +1100 Subject: 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(-) (limited to 'shared-core') 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; -- cgit v1.2.3 From 80d75cf6950acf1a00a031ceb6511b26dcc9b056 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 30 Nov 2006 10:31:42 +1100 Subject: 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(-) (limited to 'shared-core') 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) { -- cgit v1.2.3 From 30acb90a6077798b1e0c4927273067500905d6d1 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 3 Dec 2006 10:02:54 +0100 Subject: 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 | 371 +++++++++++++++++++++++--------------------- 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, 260 insertions(+), 201 deletions(-) (limited to 'shared-core') 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,210 +464,231 @@ 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 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 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 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_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" -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 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" +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 0x00c0 NV_40 "NV41" +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_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 "NV43" -0x10de 0x0143 NV_40 "NV43" +0x10de 0x0142 NV_40 "GeForce 6600 PCIe" +0x10de 0x0144 NV_40 "GeForce Go 6600" 0x10de 0x0145 NV_40 "GeForce 6610 XL" -0x10de 0x014b NV_40 "NV43" -0x10de 0x014c NV_40 "NV43GL" -0x10de 0x014d NV_40 "NV43GL" +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 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 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 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 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" +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 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 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" +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.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); -- cgit v1.2.3 From 1a40f3318c2660b83f64f7ed189d0f1692644ee4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Dec 2006 00:11:42 +1100 Subject: 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(-) (limited to 'shared-core') 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"); -- cgit v1.2.3