nouveau: map pci resource 2 on >=nv40
authorBen Skeggs <darktama@iinet.net.au>
Sun, 7 Jan 2007 12:56:45 +0000 (23:56 +1100)
committerBen Skeggs <darktama@iinet.net.au>
Sun, 7 Jan 2007 13:44:02 +0000 (00:44 +1100)
shared-core/nouveau_drv.h
shared-core/nouveau_mem.c
shared-core/nouveau_state.c

index 1cf13ef..7b366f1 100644 (file)
@@ -108,6 +108,7 @@ typedef struct drm_nouveau_private {
 
        drm_local_map_t *mmio;
        drm_local_map_t *fb;
+       drm_local_map_t *ramin; /* NV40 onwards */
 
        //TODO: Remove me, I'm bogus :)
        int      cur_fifo;
@@ -169,6 +170,11 @@ 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);
+extern uint32_t          nouveau_instmem_r32(drm_nouveau_private_t *dev_priv,
+                                            struct mem_block *mem, int index);
+extern void              nouveau_instmem_w32(drm_nouveau_private_t *dev_priv,
+                                            struct mem_block *mem, int index,
+                                            uint32_t val);
 
 /* nouveau_fifo.c */
 extern int  nouveau_fifo_init(drm_device_t *dev);
@@ -208,8 +214,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(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))
+#define INSTANCE_WR(mem,ofs,val) nouveau_instmem_w32(dev_priv,(mem),(ofs),(val))
+#define INSTANCE_RD(mem,ofs)     nouveau_instmem_r32(dev_priv,(mem),(ofs))
 
 #endif /* __NOUVEAU_DRV_H__ */
 
index 4d4100e..df8641e 100644 (file)
@@ -492,6 +492,38 @@ void nouveau_instmem_free(struct drm_device *dev, struct mem_block *block)
        }
 }
 
+uint32_t nouveau_instmem_r32(drm_nouveau_private_t *dev_priv,
+                            struct mem_block *mem, int index)
+{
+       uint32_t ofs = (uint32_t)mem->start + (index<<2);
+
+       if (dev_priv->ramin) {
+#if defined(__powerpc__)
+               return in_be32((void __iomem *)(dev_priv->ramin)->handle + ofs);
+#else
+               return DRM_READ32(dev_priv->ramin, ofs);
+#endif
+       } else {
+               return NV_READ(NV_RAMIN+ofs);
+       }
+}
+
+void nouveau_instmem_w32(drm_nouveau_private_t *dev_priv,
+                        struct mem_block *mem, int index, uint32_t val)
+{
+       uint32_t ofs = (uint32_t)mem->start + (index<<2);
+
+       if (dev_priv->ramin) {
+#if defined(__powerpc__)
+               out_be32((void __iomem *)(dev_priv->ramin)->handle + ofs, val);
+#else
+               DRM_WRITE32(dev_priv->ramin, ofs, val);
+#endif
+       } else {
+               NV_WRITE(NV_RAMIN+ofs, val);
+       }
+}
+
 /*
  * Ioctls
  */
index 43f9c2a..951e21f 100644 (file)
@@ -64,6 +64,21 @@ int nouveau_firstopen(struct drm_device *dev)
 
        DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20);
 
+       /* map larger RAMIN aperture on NV40 cards */
+       if (dev_priv->card_type >= NV_40) {
+               ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
+                                     drm_get_resource_len(dev, 2),
+                                     _DRM_REGISTERS,
+                                     _DRM_READ_ONLY,
+                                     &dev_priv->ramin);
+               if (ret) {
+                       DRM_ERROR("Failed to init RAMIN mapping, "
+                                 "limited instance memory available\n");
+                       dev_priv->ramin = NULL;
+               }
+       } else
+               dev_priv->ramin = NULL;
+
        /* Clear RAMIN
         * Determine locations for RAMHT/FC/RO
         * Initialise PFIFO