From 88ee812d56333375f7ae44e28b483c1a161d75da Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Tue, 17 Oct 2017 17:12:28 -0700 Subject: gpu: nvgpu: Remove buffer_attrs struct Remove the buffer_attrs struct and replace it with a more streamlined nvgpu_ctag_buffer_info struct. This struct allows several different fields to all be passed by pointer to the various kind/compression functions in the VM map process. This path also moves several comptag/kind related functions to the core vm.c code since these functions can be reused by other OSes. Change-Id: I2a0f0a1c4b554ce4c8f2acdbe3161392e717d3bf Signed-off-by: Alex Waterman Reviewed-on: https://git-master.nvidia.com/r/1583984 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Reviewed-by: svc-mobile-coverity Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/mm/vm.c | 122 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) (limited to 'drivers/gpu/nvgpu/common/mm') diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c index 2ce62e75..64c9c217 100644 --- a/drivers/gpu/nvgpu/common/mm/vm.c +++ b/drivers/gpu/nvgpu/common/mm/vm.c @@ -35,6 +35,7 @@ #include "gk20a/gk20a.h" #include "gk20a/mm_gk20a.h" +#include "gk20a/kind_gk20a.h" static void __nvgpu_vm_unmap(struct nvgpu_mapped_buf *mapped_buffer, struct vm_gk20a_mapping_batch *batch); @@ -827,3 +828,124 @@ done: nvgpu_mutex_release(&vm->update_gmmu_lock); return; } + +int nvgpu_vm_init_kind_info(struct nvgpu_ctag_buffer_info *binfo, + s16 compr_kind, s16 incompr_kind) +{ + if (binfo->flags & NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL) { + /* were we supplied with a kind in either parameter? */ + if ((compr_kind < 0 || compr_kind >= NV_KIND_ATTR_SIZE) && + (incompr_kind < 0 || incompr_kind >= NV_KIND_ATTR_SIZE)) + return -EINVAL; + + if (compr_kind != NV_KIND_INVALID) { + binfo->use_kind_v = true; + binfo->kind_v = (u8)compr_kind; + } + + if (incompr_kind != NV_KIND_INVALID) { + binfo->use_uc_kind_v = true; + binfo->uc_kind_v = (u8)incompr_kind; + } + } else { + if (compr_kind < 0 || compr_kind >= NV_KIND_ATTR_SIZE) + return -EINVAL; + + binfo->use_kind_v = true; + binfo->kind_v = (u8)compr_kind; + + /* + * Note: nvgpu_vm_kind_and_compression() will figure out + * uc_kind_v or return an error. + */ + } + + return 0; +} + +static int nvgpu_vm_setup_kind_legacy(struct vm_gk20a *vm, + struct nvgpu_ctag_buffer_info *binfo, + bool *pkind_compressible) +{ + struct gk20a *g = gk20a_from_vm(vm); + bool kind_compressible; + + if (unlikely(binfo->kind_v == g->ops.mm.get_kind_invalid())) + binfo->kind_v = g->ops.mm.get_kind_pitch(); + + if (unlikely(!gk20a_kind_is_supported(binfo->kind_v))) { + nvgpu_err(g, "kind 0x%x not supported", binfo->kind_v); + return -EINVAL; + } + + binfo->uc_kind_v = g->ops.mm.get_kind_invalid(); + + /* + * Find a suitable incompressible kind if it becomes necessary later. + */ + kind_compressible = gk20a_kind_is_compressible(binfo->kind_v); + if (kind_compressible) { + binfo->uc_kind_v = gk20a_get_uncompressed_kind(binfo->kind_v); + if (binfo->uc_kind_v == g->ops.mm.get_kind_invalid()) { + /* + * Shouldn't happen, but it is worth cross-checking. + */ + nvgpu_err(g, "comptag kind 0x%x can't be" + " downgraded to uncompressed kind", + binfo->kind_v); + return -EINVAL; + } + } + + *pkind_compressible = kind_compressible; + + return 0; +} + +int nvgpu_vm_compute_kind_and_compression(struct vm_gk20a *vm, + struct nvgpu_ctag_buffer_info *binfo) +{ + bool kind_compressible; + struct gk20a *g = gk20a_from_vm(vm); + int ctag_granularity = g->ops.fb.compression_page_size(g); + + if (!binfo->use_kind_v) + binfo->kind_v = g->ops.mm.get_kind_invalid(); + if (!binfo->use_uc_kind_v) + binfo->uc_kind_v = g->ops.mm.get_kind_invalid(); + + if (binfo->flags & NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL) { + kind_compressible = (binfo->kind_v != + g->ops.mm.get_kind_invalid()); + if (!kind_compressible) + binfo->kind_v = binfo->uc_kind_v; + } else { + int err = nvgpu_vm_setup_kind_legacy(vm, binfo, + &kind_compressible); + + if (err) + return err; + } + + /* comptags only supported for suitable kinds, 128KB pagesize */ + if (kind_compressible && + vm->gmmu_page_sizes[binfo->pgsz_idx] < + g->ops.fb.compressible_page_size(g)) { + /* it is safe to fall back to uncompressed as + functionality is not harmed */ + binfo->kind_v = binfo->uc_kind_v; + kind_compressible = false; + } + + if (kind_compressible) + binfo->ctag_lines = DIV_ROUND_UP_ULL(binfo->size, + ctag_granularity); + else + binfo->ctag_lines = 0; + + binfo->use_kind_v = (binfo->kind_v != g->ops.mm.get_kind_invalid()); + binfo->use_uc_kind_v = (binfo->uc_kind_v != + g->ops.mm.get_kind_invalid()); + + return 0; +} -- cgit v1.2.2