mirror of https://gitee.com/openkylin/linux.git
drm/nouveau: directly handle comptag allocation
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>
This commit is contained in:
parent
bd275f1d1a
commit
7b8656636a
|
@ -22,8 +22,6 @@ struct nvkm_ltc {
|
||||||
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);
|
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]);
|
int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]);
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "nouveau_drv.h"
|
#include "nouveau_drv.h"
|
||||||
#include "nouveau_bo.h"
|
#include "nouveau_bo.h"
|
||||||
|
|
||||||
|
#include <subdev/ltc.h>
|
||||||
|
|
||||||
#include <drm/ttm/ttm_bo_driver.h>
|
#include <drm/ttm/ttm_bo_driver.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -44,6 +46,8 @@ nouveau_mem_fini(struct nouveau_mem *mem)
|
||||||
nvkm_vm_unmap(&mem->vma[0]);
|
nvkm_vm_unmap(&mem->vma[0]);
|
||||||
nvkm_vm_put(&mem->vma[0]);
|
nvkm_vm_put(&mem->vma[0]);
|
||||||
}
|
}
|
||||||
|
nvkm_memory_tags_put(&mem->memory, nvxx_device(&mem->cli->device),
|
||||||
|
&mem->tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -74,17 +78,47 @@ int
|
||||||
nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page)
|
nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page)
|
||||||
{
|
{
|
||||||
struct nouveau_mem *mem = nouveau_mem(reg);
|
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);
|
u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mem->mem.page = page;
|
mem->mem.page = page;
|
||||||
mem->_mem->memory = &mem->memory;
|
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,
|
ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page,
|
||||||
(mem->comp << 8) | mem->kind, &mem->_mem);
|
(mem->comp << 8) | mem->kind, &mem->_mem);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
nvkm_memory_tags_put(mem->_mem->memory, device, &mem->tags);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mem->tags && mem->tags->mn)
|
||||||
|
mem->_mem->tag = mem->tags->mn;
|
||||||
|
|
||||||
reg->start = mem->_mem->offset >> PAGE_SHIFT;
|
reg->start = mem->_mem->offset >> PAGE_SHIFT;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct nouveau_mem {
|
||||||
struct nvkm_vma bar_vma;
|
struct nvkm_vma bar_vma;
|
||||||
|
|
||||||
struct nvkm_memory memory;
|
struct nvkm_memory memory;
|
||||||
|
struct nvkm_tags *tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nvif_vmm_get {
|
enum nvif_vmm_get {
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <subdev/bios/timing.h>
|
#include <subdev/bios/timing.h>
|
||||||
#include <subdev/clk.h>
|
#include <subdev/clk.h>
|
||||||
#include <subdev/clk/pll.h>
|
#include <subdev/clk/pll.h>
|
||||||
#include <subdev/ltc.h>
|
|
||||||
|
|
||||||
struct gf100_ramfuc {
|
struct gf100_ramfuc {
|
||||||
struct ramfuc base;
|
struct ramfuc base;
|
||||||
|
@ -423,7 +422,6 @@ gf100_ram_tidy(struct nvkm_ram *base)
|
||||||
void
|
void
|
||||||
gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem)
|
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;
|
struct nvkm_mem *mem = *pmem;
|
||||||
|
|
||||||
*pmem = NULL;
|
*pmem = NULL;
|
||||||
|
@ -431,8 +429,6 @@ gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&ram->fb->subdev.mutex);
|
mutex_lock(&ram->fb->subdev.mutex);
|
||||||
if (mem->tag)
|
|
||||||
nvkm_ltc_tags_free(ltc, &mem->tag);
|
|
||||||
__nv50_ram_put(ram, mem);
|
__nv50_ram_put(ram, mem);
|
||||||
mutex_unlock(&ram->fb->subdev.mutex);
|
mutex_unlock(&ram->fb->subdev.mutex);
|
||||||
|
|
||||||
|
@ -443,14 +439,11 @@ int
|
||||||
gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
|
gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
|
||||||
u32 memtype, struct nvkm_mem **pmem)
|
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 *mm = &ram->vram;
|
||||||
struct nvkm_mm_node **node, *r;
|
struct nvkm_mm_node **node, *r;
|
||||||
struct nvkm_mem *mem;
|
struct nvkm_mem *mem;
|
||||||
int type = (memtype & 0x0ff);
|
int type = (memtype & 0x0ff);
|
||||||
int back = (memtype & 0x800);
|
int back = (memtype & 0x800);
|
||||||
const bool comp = gf100_pte_storage_type_map[type] != type;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
size >>= NVKM_RAM_MM_SHIFT;
|
size >>= NVKM_RAM_MM_SHIFT;
|
||||||
|
@ -466,19 +459,6 @@ gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
|
||||||
mem->size = size;
|
mem->size = size;
|
||||||
|
|
||||||
mutex_lock(&ram->fb->subdev.mutex);
|
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;
|
mem->memtype = type;
|
||||||
|
|
||||||
node = &mem->mem;
|
node = &mem->mem;
|
||||||
|
|
|
@ -502,7 +502,6 @@ __nv50_ram_put(struct nvkm_ram *ram, struct nvkm_mem *mem)
|
||||||
next = node->next;
|
next = node->next;
|
||||||
nvkm_mm_free(&ram->vram, &node);
|
nvkm_mm_free(&ram->vram, &node);
|
||||||
}
|
}
|
||||||
nvkm_mm_free(&ram->fb->tags, &mem->tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -526,7 +525,6 @@ nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
|
||||||
u32 memtype, struct nvkm_mem **pmem)
|
u32 memtype, struct nvkm_mem **pmem)
|
||||||
{
|
{
|
||||||
struct nvkm_mm *heap = &ram->vram;
|
struct nvkm_mm *heap = &ram->vram;
|
||||||
struct nvkm_mm *tags = &ram->fb->tags;
|
|
||||||
struct nvkm_mm_node **node, *r;
|
struct nvkm_mm_node **node, *r;
|
||||||
struct nvkm_mem *mem;
|
struct nvkm_mem *mem;
|
||||||
int comp = (memtype & 0x300) >> 8;
|
int comp = (memtype & 0x300) >> 8;
|
||||||
|
@ -543,19 +541,6 @@ nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
mutex_lock(&ram->fb->subdev.mutex);
|
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->memtype = (comp << 7) | type;
|
||||||
mem->size = max;
|
mem->size = max;
|
||||||
|
|
||||||
|
|
|
@ -24,24 +24,6 @@
|
||||||
#include "priv.h"
|
#include "priv.h"
|
||||||
|
|
||||||
#include <core/memory.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
|
void
|
||||||
nvkm_ltc_tags_clear(struct nvkm_device *device, u32 first, u32 count)
|
nvkm_ltc_tags_clear(struct nvkm_device *device, u32 first, u32 count)
|
||||||
|
|
Loading…
Reference in New Issue