summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shared-core/nouveau_drv.h4
-rw-r--r--shared-core/nouveau_mem.c104
-rw-r--r--shared-core/nouveau_state.c10
3 files changed, 98 insertions, 20 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 83836270..d35d670d 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -42,7 +42,6 @@
#include "nouveau_drm.h"
#include "nouveau_reg.h"
-
struct mem_block {
struct mem_block *next;
struct mem_block *prev;
@@ -229,6 +228,8 @@ struct drm_nouveau_private {
NOUVEAU_CARD_INIT_FAILED
} init_state;
+ int ttm;
+
/* the card type, takes NV_* as values */
int card_type;
/* exact chipset, derived from NV_PMC_BOOT_0 */
@@ -348,6 +349,7 @@ extern struct mem_block* nouveau_mem_alloc(struct drm_device *,
int flags, struct drm_file *);
extern void nouveau_mem_free(struct drm_device *dev, struct mem_block*);
extern int nouveau_mem_init(struct drm_device *);
+extern int nouveau_mem_init_ttm(struct drm_device *);
extern void nouveau_mem_close(struct drm_device *);
/* nouveau_notifier.c */
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index 0e73c149..eb97a1c7 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -301,13 +301,11 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
}
static int
-nouveau_mem_init_agp(struct drm_device *dev)
+nouveau_mem_init_agp(struct drm_device *dev, int ttm)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_agp_info info;
struct drm_agp_mode mode;
- struct drm_agp_buffer agp_req;
- struct drm_agp_binding bind_req;
int ret;
ret = drm_agp_acquire(dev);
@@ -330,20 +328,25 @@ nouveau_mem_init_agp(struct drm_device *dev)
return ret;
}
- agp_req.size = info.aperture_size;
- agp_req.type = 0;
- ret = drm_agp_alloc(dev, &agp_req);
- if (ret) {
- DRM_ERROR("Unable to alloc AGP: %d\n", ret);
- return ret;
- }
+ if (!ttm) {
+ struct drm_agp_buffer agp_req;
+ struct drm_agp_binding bind_req;
- bind_req.handle = agp_req.handle;
- bind_req.offset = 0;
- ret = drm_agp_bind(dev, &bind_req);
- if (ret) {
- DRM_ERROR("Unable to bind AGP: %d\n", ret);
- return ret;
+ agp_req.size = info.aperture_size;
+ agp_req.type = 0;
+ ret = drm_agp_alloc(dev, &agp_req);
+ if (ret) {
+ DRM_ERROR("Unable to alloc AGP: %d\n", ret);
+ return ret;
+ }
+
+ bind_req.handle = agp_req.handle;
+ bind_req.offset = 0;
+ ret = drm_agp_bind(dev, &bind_req);
+ if (ret) {
+ DRM_ERROR("Unable to bind AGP: %d\n", ret);
+ return ret;
+ }
}
dev_priv->gart_info.type = NOUVEAU_GART_AGP;
@@ -352,6 +355,73 @@ nouveau_mem_init_agp(struct drm_device *dev)
return 0;
}
+#define HACK_OLD_MM
+int
+nouveau_mem_init_ttm(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t vram_size, bar1_size;
+ int ret;
+
+ dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL;
+ dev_priv->fb_phys = drm_get_resource_start(dev,1);
+ dev_priv->gart_info.type = NOUVEAU_GART_NONE;
+
+ drm_bo_driver_init(dev);
+
+ /* non-mappable vram */
+ dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
+ dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
+ vram_size = dev_priv->fb_available_size >> PAGE_SHIFT;
+ bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT;
+ if (bar1_size < vram_size) {
+ if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0,
+ bar1_size, vram_size - bar1_size))) {
+ DRM_ERROR("Failed PRIV0 mm init: %d\n", ret);
+ return ret;
+ }
+ vram_size = bar1_size;
+ }
+
+ /* mappable vram */
+#ifdef HACK_OLD_MM
+ vram_size /= 4;
+#endif
+ if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size))) {
+ DRM_ERROR("Failed VRAM mm init: %d\n", ret);
+ return ret;
+ }
+
+ /* GART */
+#ifndef __powerpc__
+ if (drm_device_is_agp(dev) && dev->agp) {
+ if ((ret = nouveau_mem_init_agp(dev, 1)))
+ DRM_ERROR("Error initialising AGP: %d\n", ret);
+ }
+#endif
+
+ if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) {
+ if ((ret = nouveau_sgdma_init(dev)))
+ DRM_ERROR("Error initialising PCI SGDMA: %d\n", ret);
+ }
+
+ if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
+ dev_priv->gart_info.aper_size >>
+ PAGE_SHIFT))) {
+ DRM_ERROR("Failed TT mm init: %d\n", ret);
+ return ret;
+ }
+
+#ifdef HACK_OLD_MM
+ vram_size <<= PAGE_SHIFT;
+ DRM_INFO("Old MM using %dKiB VRAM\n", (vram_size * 3) >> 10);
+ if (nouveau_mem_init_heap(&dev_priv->fb_heap, vram_size, vram_size * 3))
+ return -ENOMEM;
+#endif
+
+ return 0;
+}
+
int nouveau_mem_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -395,7 +465,7 @@ int nouveau_mem_init(struct drm_device *dev)
#ifndef __powerpc__
/* Init AGP / NV50 PCIEGART */
if (drm_device_is_agp(dev) && dev->agp) {
- if ((ret = nouveau_mem_init_agp(dev)))
+ if ((ret = nouveau_mem_init_agp(dev, 0)))
DRM_ERROR("Error initialising AGP: %d\n", ret);
}
#endif
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index c617bfd3..fee17d0a 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -278,6 +278,7 @@ nouveau_card_init(struct drm_device *dev)
if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
return 0;
+ dev_priv->ttm = 0;
/* Map any PCI resources we need on the card */
ret = nouveau_init_card_mappings(dev);
@@ -315,8 +316,13 @@ nouveau_card_init(struct drm_device *dev)
if (ret) return ret;
/* Setup the memory manager */
- ret = nouveau_mem_init(dev);
- if (ret) return ret;
+ if (dev_priv->ttm) {
+ ret = nouveau_mem_init_ttm(dev);
+ if (ret) return ret;
+ } else {
+ ret = nouveau_mem_init(dev);
+ if (ret) return ret;
+ }
ret = nouveau_gpuobj_init(dev);
if (ret) return ret;