diff options
-rw-r--r-- | shared-core/nouveau_drv.h | 10 | ||||
-rw-r--r-- | shared-core/nouveau_mem.c | 32 | ||||
-rw-r--r-- | shared-core/nouveau_state.c | 15 |
3 files changed, 55 insertions, 2 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 1cf13ef7..7b366f14 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -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__ */ diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 4d4100eb..df8641ed 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -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 */ diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 43f9c2a9..951e21f9 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -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 |