Commit eaecf032 authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ben Skeggs

make RAM device optional

Having a RAM device does not make sense for chips like GK20A which have
no dedicated video memory. The dummy RAM device that we used so far
works as a temporary band-aid, but in the longer term it is desirable
for the driver to be able to work without any kind of VRAM.

This patch adds a few conditionals in places where a RAM device was
assumed to be present and allows some more objects to be allocated from
the TT domain, allowing Nouveau to handle GPUs for which
pfb->ram == NULL.
Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent c6a7b026
...@@ -869,13 +869,20 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, ...@@ -869,13 +869,20 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args) struct drm_mode_create_dumb *args)
{ {
struct nouveau_bo *bo; struct nouveau_bo *bo;
uint32_t domain;
int ret; int ret;
args->pitch = roundup(args->width * (args->bpp / 8), 256); args->pitch = roundup(args->width * (args->bpp / 8), 256);
args->size = args->pitch * args->height; args->size = args->pitch * args->height;
args->size = roundup(args->size, PAGE_SIZE); args->size = roundup(args->size, PAGE_SIZE);
ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo); /* Use VRAM if there is any ; otherwise fallback to system memory */
if (nouveau_drm(dev)->device.info.ram_size != 0)
domain = NOUVEAU_GEM_DOMAIN_VRAM;
else
domain = NOUVEAU_GEM_DOMAIN_GART;
ret = nouveau_gem_new(dev, args->size, 0, domain, 0, 0, &bo);
if (ret) if (ret)
return ret; return ret;
......
...@@ -82,6 +82,9 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, ...@@ -82,6 +82,9 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
u32 size_nc = 0; u32 size_nc = 0;
int ret; int ret;
if (drm->device.info.ram_size == 0)
return -ENOMEM;
if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
size_nc = 1 << nvbo->page_shift; size_nc = 1 << nvbo->page_shift;
......
...@@ -215,6 +215,7 @@ nv84_fence_create(struct nouveau_drm *drm) ...@@ -215,6 +215,7 @@ nv84_fence_create(struct nouveau_drm *drm)
{ {
struct nvkm_fifo *pfifo = nvxx_fifo(&drm->device); struct nvkm_fifo *pfifo = nvxx_fifo(&drm->device);
struct nv84_fence_priv *priv; struct nv84_fence_priv *priv;
u32 domain;
int ret; int ret;
priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
...@@ -231,10 +232,17 @@ nv84_fence_create(struct nouveau_drm *drm) ...@@ -231,10 +232,17 @@ nv84_fence_create(struct nouveau_drm *drm)
priv->base.context_base = fence_context_alloc(priv->base.contexts); priv->base.context_base = fence_context_alloc(priv->base.contexts);
priv->base.uevent = true; priv->base.uevent = true;
ret = nouveau_bo_new(drm->dev, 16 * priv->base.contexts, 0, /* Use VRAM if there is any ; otherwise fallback to system memory */
TTM_PL_FLAG_VRAM, 0, 0, NULL, NULL, &priv->bo); domain = drm->device.info.ram_size != 0 ? TTM_PL_FLAG_VRAM :
/*
* fences created in sysmem must be non-cached or we
* will lose CPU/GPU coherency!
*/
TTM_PL_FLAG_TT | TTM_PL_FLAG_UNCACHED;
ret = nouveau_bo_new(drm->dev, 16 * priv->base.contexts, 0, domain, 0,
0, NULL, NULL, &priv->bo);
if (ret == 0) { if (ret == 0) {
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM, false); ret = nouveau_bo_pin(priv->bo, domain, false);
if (ret == 0) { if (ret == 0) {
ret = nouveau_bo_map(priv->bo); ret = nouveau_bo_map(priv->bo);
if (ret) if (ret)
......
...@@ -139,9 +139,13 @@ nvkm_devobj_info(struct nvkm_object *object, void *data, u32 size) ...@@ -139,9 +139,13 @@ nvkm_devobj_info(struct nvkm_object *object, void *data, u32 size)
args->v0.chipset = device->chipset; args->v0.chipset = device->chipset;
args->v0.revision = device->chiprev; args->v0.revision = device->chiprev;
if (pfb) args->v0.ram_size = args->v0.ram_user = pfb->ram->size; if (pfb && pfb->ram)
else args->v0.ram_size = args->v0.ram_user = 0; args->v0.ram_size = args->v0.ram_user = pfb->ram->size;
if (imem) args->v0.ram_user = args->v0.ram_user - imem->reserved; else
args->v0.ram_size = args->v0.ram_user = 0;
if (imem && args->v0.ram_size > 0)
args->v0.ram_user = args->v0.ram_user - imem->reserved;
return 0; return 0;
} }
......
...@@ -184,7 +184,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei) ...@@ -184,7 +184,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
nv_debug(clk, "setting performance state %d\n", pstatei); nv_debug(clk, "setting performance state %d\n", pstatei);
clk->pstate = pstatei; clk->pstate = pstatei;
if (pfb->ram->calc) { if (pfb->ram && pfb->ram->calc) {
int khz = pstate->base.domain[nv_clk_src_mem]; int khz = pstate->base.domain[nv_clk_src_mem];
do { do {
ret = pfb->ram->calc(pfb, khz); ret = pfb->ram->calc(pfb, khz);
......
...@@ -55,9 +55,11 @@ _nvkm_fb_fini(struct nvkm_object *object, bool suspend) ...@@ -55,9 +55,11 @@ _nvkm_fb_fini(struct nvkm_object *object, bool suspend)
struct nvkm_fb *pfb = (void *)object; struct nvkm_fb *pfb = (void *)object;
int ret; int ret;
ret = nv_ofuncs(pfb->ram)->fini(nv_object(pfb->ram), suspend); if (pfb->ram) {
if (ret && suspend) ret = nv_ofuncs(pfb->ram)->fini(nv_object(pfb->ram), suspend);
return ret; if (ret && suspend)
return ret;
}
return nvkm_subdev_fini(&pfb->base, suspend); return nvkm_subdev_fini(&pfb->base, suspend);
} }
...@@ -72,9 +74,11 @@ _nvkm_fb_init(struct nvkm_object *object) ...@@ -72,9 +74,11 @@ _nvkm_fb_init(struct nvkm_object *object)
if (ret) if (ret)
return ret; return ret;
ret = nv_ofuncs(pfb->ram)->init(nv_object(pfb->ram)); if (pfb->ram) {
if (ret) ret = nv_ofuncs(pfb->ram)->init(nv_object(pfb->ram));
return ret; if (ret)
return ret;
}
for (i = 0; i < pfb->tile.regions; i++) for (i = 0; i < pfb->tile.regions; i++)
pfb->tile.prog(pfb, i, &pfb->tile.region[i]); pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
...@@ -91,9 +95,12 @@ _nvkm_fb_dtor(struct nvkm_object *object) ...@@ -91,9 +95,12 @@ _nvkm_fb_dtor(struct nvkm_object *object)
for (i = 0; i < pfb->tile.regions; i++) for (i = 0; i < pfb->tile.regions; i++)
pfb->tile.fini(pfb, i, &pfb->tile.region[i]); pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
nvkm_mm_fini(&pfb->tags); nvkm_mm_fini(&pfb->tags);
nvkm_mm_fini(&pfb->vram);
nvkm_object_ref(NULL, (struct nvkm_object **)&pfb->ram); if (pfb->ram) {
nvkm_mm_fini(&pfb->vram);
nvkm_object_ref(NULL, (struct nvkm_object **)&pfb->ram);
}
nvkm_subdev_destroy(&pfb->base); nvkm_subdev_destroy(&pfb->base);
} }
...@@ -127,6 +134,9 @@ nvkm_fb_create_(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -127,6 +134,9 @@ nvkm_fb_create_(struct nvkm_object *parent, struct nvkm_object *engine,
pfb->memtype_valid = impl->memtype; pfb->memtype_valid = impl->memtype;
if (!impl->ram)
return 0;
ret = nvkm_object_ctor(nv_object(pfb), NULL, impl->ram, NULL, 0, &ram); ret = nvkm_object_ctor(nv_object(pfb), NULL, impl->ram, NULL, 0, &ram);
if (ret) { if (ret) {
nv_fatal(pfb, "error detecting memory configuration!!\n"); nv_fatal(pfb, "error detecting memory configuration!!\n");
......
...@@ -136,7 +136,8 @@ gf100_ltc_dtor(struct nvkm_object *object) ...@@ -136,7 +136,8 @@ gf100_ltc_dtor(struct nvkm_object *object)
struct nvkm_ltc_priv *priv = (void *)object; struct nvkm_ltc_priv *priv = (void *)object;
nvkm_mm_fini(&priv->tags); nvkm_mm_fini(&priv->tags);
nvkm_mm_free(&pfb->vram, &priv->tag_ram); if (pfb->ram)
nvkm_mm_free(&pfb->vram, &priv->tag_ram);
nvkm_ltc_destroy(priv); nvkm_ltc_destroy(priv);
} }
...@@ -149,6 +150,12 @@ gf100_ltc_init_tag_ram(struct nvkm_fb *pfb, struct nvkm_ltc_priv *priv) ...@@ -149,6 +150,12 @@ gf100_ltc_init_tag_ram(struct nvkm_fb *pfb, struct nvkm_ltc_priv *priv)
u32 tag_size, tag_margin, tag_align; u32 tag_size, tag_margin, tag_align;
int ret; int ret;
/* No VRAM, no tags for now. */
if (!pfb->ram) {
priv->num_tags = 0;
goto mm_init;
}
/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */ /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
priv->num_tags = (pfb->ram->size >> 17) / 4; priv->num_tags = (pfb->ram->size >> 17) / 4;
if (priv->num_tags > (1 << 17)) if (priv->num_tags > (1 << 17))
...@@ -183,6 +190,7 @@ gf100_ltc_init_tag_ram(struct nvkm_fb *pfb, struct nvkm_ltc_priv *priv) ...@@ -183,6 +190,7 @@ gf100_ltc_init_tag_ram(struct nvkm_fb *pfb, struct nvkm_ltc_priv *priv)
priv->tag_base = tag_base; priv->tag_base = tag_base;
} }
mm_init:
ret = nvkm_mm_init(&priv->tags, 0, priv->num_tags, 1); ret = nvkm_mm_init(&priv->tags, 0, priv->num_tags, 1);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment