Another transition step to allow finer-grained patches transitioning to
new MMU backends.
Old backends will continue operate as before (accessing nvkm_mem::tag),
and new backends will get a reference to the tags allocated here.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
u32 zbc_depth[NVKM_LTC_MAX_ZBC_CNT];
};
u32 zbc_depth[NVKM_LTC_MAX_ZBC_CNT];
};
-int nvkm_ltc_tags_alloc(struct nvkm_ltc *, u32 count, struct nvkm_mm_node **);
-void nvkm_ltc_tags_free(struct nvkm_ltc *, struct nvkm_mm_node **);
void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count);
int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]);
void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count);
int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]);
#include "nouveau_drv.h"
#include "nouveau_bo.h"
#include "nouveau_drv.h"
#include "nouveau_bo.h"
+#include <subdev/ltc.h>
+
#include <drm/ttm/ttm_bo_driver.h>
int
#include <drm/ttm/ttm_bo_driver.h>
int
nvkm_vm_unmap(&mem->vma[0]);
nvkm_vm_put(&mem->vma[0]);
}
nvkm_vm_unmap(&mem->vma[0]);
nvkm_vm_put(&mem->vma[0]);
}
+ nvkm_memory_tags_put(&mem->memory, nvxx_device(&mem->cli->device),
+ &mem->tags);
nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page)
{
struct nouveau_mem *mem = nouveau_mem(reg);
nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page)
{
struct nouveau_mem *mem = nouveau_mem(reg);
- struct nvkm_ram *ram = nvxx_fb(&mem->cli->device)->ram;
+ struct nouveau_cli *cli = mem->cli;
+ struct nvkm_device *device = nvxx_device(&cli->device);
+ struct nvkm_ram *ram = nvxx_fb(&cli->device)->ram;
u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page);
int ret;
mem->mem.page = page;
mem->_mem->memory = &mem->memory;
u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page);
int ret;
mem->mem.page = page;
mem->_mem->memory = &mem->memory;
+ if (cli->device.info.chipset < 0xc0 && mem->comp) {
+ if (page == 16) {
+ ret = nvkm_memory_tags_get(mem->_mem->memory, device,
+ size >> page, NULL,
+ &mem->tags);
+ WARN_ON(ret);
+ }
+ if (!mem->tags || !mem->tags->mn)
+ mem->comp = 0;
+ } else
+ if (cli->device.info.chipset >= 0xc0 &&
+ gf100_pte_storage_type_map[mem->kind] != mem->kind) {
+ if (page == 17) {
+ ret = nvkm_memory_tags_get(mem->_mem->memory, device,
+ size >> page,
+ nvkm_ltc_tags_clear,
+ &mem->tags);
+ WARN_ON(ret);
+ }
+ if (!mem->tags || !mem->tags->mn)
+ mem->kind = gf100_pte_storage_type_map[mem->kind];
+ }
+
ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page,
(mem->comp << 8) | mem->kind, &mem->_mem);
ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page,
(mem->comp << 8) | mem->kind, &mem->_mem);
+ if (ret) {
+ nvkm_memory_tags_put(mem->_mem->memory, device, &mem->tags);
+ }
+
+ if (mem->tags && mem->tags->mn)
+ mem->_mem->tag = mem->tags->mn;
reg->start = mem->_mem->offset >> PAGE_SHIFT;
return ret;
reg->start = mem->_mem->offset >> PAGE_SHIFT;
return ret;
struct nvkm_vma bar_vma;
struct nvkm_memory memory;
struct nvkm_vma bar_vma;
struct nvkm_memory memory;
+ struct nvkm_tags *tags;
#include <subdev/bios/timing.h>
#include <subdev/clk.h>
#include <subdev/clk/pll.h>
#include <subdev/bios/timing.h>
#include <subdev/clk.h>
#include <subdev/clk/pll.h>
struct gf100_ramfuc {
struct ramfuc base;
struct gf100_ramfuc {
struct ramfuc base;
void
gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem)
{
void
gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem)
{
- struct nvkm_ltc *ltc = ram->fb->subdev.device->ltc;
struct nvkm_mem *mem = *pmem;
*pmem = NULL;
struct nvkm_mem *mem = *pmem;
*pmem = NULL;
return;
mutex_lock(&ram->fb->subdev.mutex);
return;
mutex_lock(&ram->fb->subdev.mutex);
- if (mem->tag)
- nvkm_ltc_tags_free(ltc, &mem->tag);
__nv50_ram_put(ram, mem);
mutex_unlock(&ram->fb->subdev.mutex);
__nv50_ram_put(ram, mem);
mutex_unlock(&ram->fb->subdev.mutex);
gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
u32 memtype, struct nvkm_mem **pmem)
{
gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
u32 memtype, struct nvkm_mem **pmem)
{
- struct nvkm_device *device = ram->fb->subdev.device;
- struct nvkm_ltc *ltc = ram->fb->subdev.device->ltc;
struct nvkm_mm *mm = &ram->vram;
struct nvkm_mm_node **node, *r;
struct nvkm_mem *mem;
int type = (memtype & 0x0ff);
int back = (memtype & 0x800);
struct nvkm_mm *mm = &ram->vram;
struct nvkm_mm_node **node, *r;
struct nvkm_mem *mem;
int type = (memtype & 0x0ff);
int back = (memtype & 0x800);
- const bool comp = gf100_pte_storage_type_map[type] != type;
int ret;
size >>= NVKM_RAM_MM_SHIFT;
int ret;
size >>= NVKM_RAM_MM_SHIFT;
mem->size = size;
mutex_lock(&ram->fb->subdev.mutex);
mem->size = size;
mutex_lock(&ram->fb->subdev.mutex);
- if (comp) {
- /* compression only works with lpages */
- if (align == (1 << (17 - NVKM_RAM_MM_SHIFT))) {
- int n = size >> 5;
- if (!nvkm_ltc_tags_alloc(ltc, n, &mem->tag)) {
- nvkm_ltc_tags_clear(device, mem->tag->offset,
- mem->tag->length);
- }
- }
-
- if (unlikely(!mem->tag))
- type = gf100_pte_storage_type_map[type];
- }
mem->memtype = type;
node = &mem->mem;
mem->memtype = type;
node = &mem->mem;
next = node->next;
nvkm_mm_free(&ram->vram, &node);
}
next = node->next;
nvkm_mm_free(&ram->vram, &node);
}
- nvkm_mm_free(&ram->fb->tags, &mem->tag);
u32 memtype, struct nvkm_mem **pmem)
{
struct nvkm_mm *heap = &ram->vram;
u32 memtype, struct nvkm_mem **pmem)
{
struct nvkm_mm *heap = &ram->vram;
- struct nvkm_mm *tags = &ram->fb->tags;
struct nvkm_mm_node **node, *r;
struct nvkm_mem *mem;
int comp = (memtype & 0x300) >> 8;
struct nvkm_mm_node **node, *r;
struct nvkm_mem *mem;
int comp = (memtype & 0x300) >> 8;
return -ENOMEM;
mutex_lock(&ram->fb->subdev.mutex);
return -ENOMEM;
mutex_lock(&ram->fb->subdev.mutex);
- if (comp) {
- if (align == (1 << (16 - NVKM_RAM_MM_SHIFT))) {
- int n = (max >> 4) * comp;
-
- ret = nvkm_mm_head(tags, 0, 1, n, n, 1, &mem->tag);
- if (ret)
- mem->tag = NULL;
- }
-
- if (unlikely(!mem->tag))
- comp = 0;
- }
-
mem->memtype = (comp << 7) | type;
mem->size = max;
mem->memtype = (comp << 7) | type;
mem->size = max;
#include "priv.h"
#include <core/memory.h>
#include "priv.h"
#include <core/memory.h>
-#include <subdev/fb.h>
-
-int
-nvkm_ltc_tags_alloc(struct nvkm_ltc *ltc, u32 n, struct nvkm_mm_node **pnode)
-{
- struct nvkm_fb *fb = ltc->subdev.device->fb;
- int ret = nvkm_mm_head(&fb->tags, 0, 1, n, n, 1, pnode);
- if (ret)
- *pnode = NULL;
- return ret;
-}
-
-void
-nvkm_ltc_tags_free(struct nvkm_ltc *ltc, struct nvkm_mm_node **pnode)
-{
- struct nvkm_fb *fb = ltc->subdev.device->fb;
- nvkm_mm_free(&fb->tags, pnode);
-}
void
nvkm_ltc_tags_clear(struct nvkm_device *device, u32 first, u32 count)
void
nvkm_ltc_tags_clear(struct nvkm_device *device, u32 first, u32 count)