summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/nouveau_drv.c1
-rw-r--r--shared-core/nouveau_drv.h4
-rw-r--r--shared-core/nouveau_state.c16
3 files changed, 20 insertions, 1 deletions
diff --git a/linux-core/nouveau_drv.c b/linux-core/nouveau_drv.c
index 57b55ce1..91de2b31 100644
--- a/linux-core/nouveau_drv.c
+++ b/linux-core/nouveau_drv.c
@@ -42,6 +42,7 @@ static struct drm_driver driver = {
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.load = nouveau_load,
.firstopen = nouveau_firstopen,
+ .lastclose = nouveau_lastclose,
.unload = nouveau_unload,
.preclose = nouveau_preclose,
.irq_preinstall = nouveau_irq_preinstall,
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 44479d70..1cf13ef7 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -132,6 +132,9 @@ typedef struct drm_nouveau_private {
uint64_t fb_phys;
uint64_t agp_phys;
+ /* the mtrr covering the FB */
+ int fb_mtrr;
+
struct mem_block *agp_heap;
struct mem_block *fb_heap;
struct mem_block *fb_nomap_heap;
@@ -145,6 +148,7 @@ drm_nouveau_private_t;
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 void nouveau_lastclose(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);
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index c66ecd4e..2d0f7985 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -46,7 +46,7 @@ int nouveau_firstopen(struct drm_device *dev)
/* resource 0 is mmio regs */
/* resource 1 is linear FB */
- /* resource 2 is ??? (mmio regs + 0x1000000) */
+ /* resource 2 is RAMIN (mmio regs + 0x1000000) */
/* resource 6 is bios */
/* map the mmio regs */
@@ -71,6 +71,11 @@ int nouveau_firstopen(struct drm_device *dev)
ret = nouveau_fifo_init(dev);
if (ret) return ret;
+#if __OS_HAS_MTRR
+ /* setup a mtrr over the FB */
+ dev_priv->fb_mtrr=drm_mtrr_add(drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
+#endif
+
/* FIXME: doesn't belong here, and have no idea what it's for.. */
if (dev_priv->card_type >= NV_40)
nv40_graph_init(dev);
@@ -98,6 +103,15 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
return 0;
}
+void nouveau_lastclose(struct drm_device *dev)
+{
+#if __OS_HAS_MTRR
+ drm_nouveau_private_t *dev_priv = dev->dev_private;
+ if(dev_priv->fb_mtrr>0)
+ drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
+#endif
+}
+
int nouveau_unload(struct drm_device *dev)
{
drm_free(dev->dev_private, sizeof(*dev->dev_private), DRM_MEM_DRIVER);