From d49d64e7202b32635d7c4c8a25ad15500e0e90f5 Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Thu, 15 Nov 2018 13:20:57 +0200 Subject: [PATCH] gpu: nvgpu: store usermode regs bus addr directly Instead of just the base address of the main register range, store (also) the base address of usermode area. All regs may not be always available; on vgpu guests we have only the usermode regs. Store the usermode addr we get from a platform resource directly in gv11b_vgpu_probe() for vgpu. In that case the main reg addr is unset. The base address is computed in gk20a_pm_finalize_poweron() for native environments; when the reg addr is read from a resource, the chip is still unknown and as such the HAL op for reading the usermode base offset is unavailable. Bug 200145225 Bug 200467197 Change-Id: I8855bb54a6456eb63b69559c84398f7eeaec3513 Signed-off-by: Konsta Holtta Reviewed-on: https://git-master.nvidia.com/r/1951524 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 11 +++-------- drivers/gpu/nvgpu/os/linux/module.c | 10 ++++++++++ drivers/gpu/nvgpu/os/linux/os_linux.h | 4 ++-- .../os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c | 2 ++ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index 2c9c51373..9549a4195 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -1943,7 +1943,6 @@ int gk20a_ctrl_dev_mmap(struct file *filp, struct vm_area_struct *vma) struct gk20a_ctrl_priv *priv = filp->private_data; struct gk20a *g = priv->g; struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); - u64 addr; int err; if (g->ops.fifo.usermode_base == NULL) @@ -1958,8 +1957,6 @@ int gk20a_ctrl_dev_mmap(struct file *filp, struct vm_area_struct *vma) if (vma->vm_pgoff != 0UL) return -EINVAL; - addr = l->regs_bus_addr + g->ops.fifo.usermode_base(g); - /* Sync with poweron/poweroff, and require valid regs */ err = gk20a_busy(g); if (err) { @@ -1973,7 +1970,8 @@ int gk20a_ctrl_dev_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_ops = &usermode_vma_ops; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - err = io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, + err = io_remap_pfn_range(vma, vma->vm_start, + l->usermode_regs_bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot); if (!err) { priv->usermode_vma.vma = vma; @@ -1993,7 +1991,6 @@ static void alter_usermode_mapping(struct gk20a *g, { struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); struct vm_area_struct *vma = priv->usermode_vma.vma; - u64 addr; int err; if (!vma) { @@ -2001,8 +1998,6 @@ static void alter_usermode_mapping(struct gk20a *g, return; } - addr = l->regs_bus_addr + g->ops.fifo.usermode_base(g); - down_write(&vma->vm_mm->mmap_sem); if (poweroff) { @@ -2015,7 +2010,7 @@ static void alter_usermode_mapping(struct gk20a *g, } else { vma->vm_flags = priv->usermode_vma.flags; err = io_remap_pfn_range(vma, vma->vm_start, - addr >> PAGE_SHIFT, + l->usermode_regs_bus_addr >> PAGE_SHIFT, SZ_4K, vma->vm_page_prot); if (err != 0) { nvgpu_err(g, "can't restore usermode mapping"); diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 1054819fc..823f92cc6 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -286,6 +286,16 @@ int gk20a_pm_finalize_poweron(struct device *dev) if (err) goto done; + if (g->ops.fifo.usermode_base != NULL) { + /* + * Native has regs_bus_addr set but not this one yet. Virtual + * gets usermode_regs_bus_addr directly from chip-specific + * probe, and regs_bus_addr stays unset. + */ + l->usermode_regs_bus_addr = l->regs_bus_addr + + g->ops.fifo.usermode_base(g); + } + err = nvgpu_finalize_poweron_linux(l); if (err) goto done; diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h index 5880384a0..393180327 100644 --- a/drivers/gpu/nvgpu/os/linux/os_linux.h +++ b/drivers/gpu/nvgpu/os/linux/os_linux.h @@ -124,6 +124,7 @@ struct nvgpu_os_linux { struct resource *reg_mem; void __iomem *regs; void __iomem *regs_saved; + u64 regs_bus_addr; struct resource *bar1_mem; void __iomem *bar1; @@ -131,8 +132,7 @@ struct nvgpu_os_linux { void __iomem *usermode_regs; void __iomem *usermode_regs_saved; - - u64 regs_bus_addr; + u64 usermode_regs_bus_addr; struct nvgpu_os_linux_ops ops; diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c b/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c index fa060847d..252ab4876 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c @@ -49,6 +49,8 @@ static int gv11b_vgpu_probe(struct device *dev) } l->usermode_regs = regs; + l->usermode_regs_bus_addr = r->start; + #ifdef CONFIG_TEGRA_GK20A_NVHOST ret = nvgpu_get_nvhost_dev(g); if (ret) {