gpu: nvgpu: move mapped regs to gk20a

- moved reg fields to gk20a
- added os abstract register accessor in nvgpu/io.h
- defined linux register access abstract implementation
- hook up with posix. posix implementation of the register accessor uses
  the high 4 bit of address to identify register apertures then call the
  according callbacks.

It helps to unify code across OSes.

Bug 2999617

Signed-off-by: Richard Zhao <rizhao@nvidia.com>
Change-Id: Ifcb737e4b4d5b1d8bae310ae50b1ce0aa04f750c
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2497937
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Richard Zhao
2021-03-11 20:54:38 -08:00
committed by mobile promotions
parent 0a25376965
commit 643eb158a3
18 changed files with 302 additions and 244 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,6 +24,114 @@
#include <nvgpu/types.h>
#include <nvgpu/bug.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/nvgpu_init.h>
static void nvgpu_warn_on_no_regs(struct gk20a *g)
{
nvgpu_warn(g, "Attempted access to GPU regs after unmapping!");
}
void nvgpu_writel(struct gk20a *g, u32 r, u32 v)
{
if (unlikely(!g->regs)) {
nvgpu_warn_on_no_regs(g);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
nvgpu_os_writel(v, g->regs + r);
nvgpu_wmb();
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
}
}
#ifdef CONFIG_NVGPU_DGPU
void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v)
{
if (unlikely(!g->regs)) {
nvgpu_warn_on_no_regs(g);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
nvgpu_os_writel_relaxed(v, g->regs + r);
}
}
#endif
u32 nvgpu_readl(struct gk20a *g, u32 r)
{
u32 v = nvgpu_readl_impl(g, r);
if (v == 0xffffffff)
nvgpu_check_gpu_state(g);
return v;
}
u32 nvgpu_readl_impl(struct gk20a *g, u32 r)
{
u32 v = 0xffffffff;
if (unlikely(!g->regs)) {
nvgpu_warn_on_no_regs(g);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
v = nvgpu_os_readl(g->regs + r);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
}
return v;
}
#ifdef CONFIG_NVGPU_NON_FUSA
void nvgpu_writel_loop(struct gk20a *g, u32 r, u32 v)
{
if (unlikely(!g->regs)) {
nvgpu_warn_on_no_regs(g);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
nvgpu_wmb();
do {
nvgpu_os_writel(v, g->regs + r);
} while (nvgpu_os_readl(g->regs + r) != v);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
}
}
#endif
void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v)
{
if (unlikely(!g->bar1)) {
nvgpu_warn_on_no_regs(g);
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
} else {
nvgpu_wmb();
nvgpu_os_writel(v, g->bar1 + b);
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
}
}
u32 nvgpu_bar1_readl(struct gk20a *g, u32 b)
{
u32 v = 0xffffffff;
if (unlikely(!g->bar1)) {
nvgpu_warn_on_no_regs(g);
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
} else {
v = nvgpu_os_readl(g->bar1 + b);
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
}
return v;
}
bool nvgpu_io_exists(struct gk20a *g)
{
return g->regs != 0U;
}
bool nvgpu_io_valid_reg(struct gk20a *g, u32 r)
{
return r < g->regs_size;
}
void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v)
{

View File

@@ -336,6 +336,22 @@ struct gk20a {
*/
void (*gfree)(struct gk20a *g);
/** Starting virtual address of mapped bar0 io region. */
uintptr_t regs;
u64 regs_size;
u64 regs_bus_addr;
/** Starting virtual address of mapped bar1 io region. */
uintptr_t bar1;
/** Starting virtual address of usermode registers io region. */
uintptr_t usermode_regs;
u64 usermode_regs_bus_addr;
uintptr_t regs_saved;
uintptr_t bar1_saved;
uintptr_t usermode_regs_saved;
/**
* Handle to access nvhost APIs.
*/

View File

@@ -24,6 +24,44 @@
#include <nvgpu/types.h>
/**
* @brief Read a value from a register.
*
* @param addr [in] Register cpu virtual address.
*
* Read a 32-bit value from the register cpu virtuall address.
* OS layer much implement this function.
*
* @return Value of the given register.
*/
u32 nvgpu_os_readl(uintptr_t addr);
/**
* @brief Write a value to a register with an ordering constraint.
*
* @param v [in] Value to write at the offset.
* @param addr [in] Register cpu virtual address.
*
* Write a 32-bit value to the register cpu virtual address with an
* ordering constraint on memory operations.
* OS layer much implement this function.
*
* @return None.
*/
void nvgpu_os_writel(u32 v, uintptr_t addr);
/**
* @brief Write a value to a register without an ordering constraint.
*
* @param v [in] Value to write at the offset.
* @param addr [in] Register cpu virtual address.
*
* Write a 32-bit value to the register cpu virtual address without an
* ordering constraint on memory operations.
* OS layer much implement this function.
*
* @return None.
*/
void nvgpu_os_writel_relaxed(u32 v, uintptr_t addr);
/**
* @file
*
@@ -65,8 +103,7 @@ void nvgpu_writel(struct gk20a *g, u32 r, u32 v);
* @param v [in] Value to write at the offset.
*
* Write a 32-bit value to register offset in GPU IO space without
* an ordering constraint on memory operations. This function is
* implemented by the OS layer.
* an ordering constraint on memory operations.
*
* @return None.
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -72,6 +72,18 @@ struct nvgpu_posix_io_callbacks *nvgpu_posix_register_io(
struct gk20a *g,
struct nvgpu_posix_io_callbacks *io_callbacks);
/**
* The high 4 bits of the register mapped address are used for identify which
* register aperture it tries to access.
* In nvgpu_os_writel/readl, it uses the high 4 bits to call different
* callbacks, like nvgpu_readl/writel or nvgpu_bar1_readl/writel.
*/
#define NVGPU_POSIX_REG_SHIFT 60
#define NVGPU_POSIX_REG_MASK 0xfULL
#define NVGPU_POSIX_REG_BAR0 1ULL
#define NVGPU_POSIX_REG_BAR1 2ULL
#define NVGPU_POSIX_REG_USERMODE 3ULL
struct nvgpu_posix_io_reg_space {
u32 base;
u32 size;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -36,6 +36,7 @@
struct gk20a;
struct gk20a *nvgpu_posix_current_device(void);
struct gk20a *nvgpu_posix_probe(void);
void nvgpu_posix_cleanup(struct gk20a *g);

View File

@@ -82,8 +82,8 @@ static void nvgpu_init_vars(struct gk20a *g)
nvgpu_mutex_init(&l->ctrl_privs_lock);
nvgpu_init_list_node(&l->ctrl_privs);
l->regs_saved = l->regs;
l->bar1_saved = l->bar1;
g->regs_saved = g->regs;
g->bar1_saved = g->bar1;
g->emc3d_ratio = EMC3D_DEFAULT_RATIO;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -19,9 +19,8 @@
void nvgpu_usermode_writel(struct gk20a *g, u32 r, u32 v)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
void __iomem *reg = l->usermode_regs + (r - g->ops.usermode.base(g));
uintptr_t reg = g->usermode_regs + (r - g->ops.usermode.base(g));
writel_relaxed(v, reg);
nvgpu_os_writel_relaxed(v, reg);
nvgpu_log(g, gpu_dbg_reg, "usermode r=0x%x v=0x%x", r, v);
}

View File

@@ -2278,7 +2278,7 @@ int gk20a_ctrl_dev_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
err = io_remap_pfn_range(vma, vma->vm_start,
l->usermode_regs_bus_addr >> PAGE_SHIFT,
g->usermode_regs_bus_addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
if (!err) {
priv->usermode_vma.vma = vma;
@@ -2297,7 +2297,6 @@ static void alter_usermode_mapping(struct gk20a *g,
struct gk20a_ctrl_priv *priv,
bool poweroff)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
struct vm_area_struct *vma = priv->usermode_vma.vma;
bool vma_mapped = priv->usermode_vma.vma_mapped;
int err;
@@ -2335,7 +2334,7 @@ static void alter_usermode_mapping(struct gk20a *g,
} else if (!poweroff && !vma_mapped) {
vma->vm_flags = priv->usermode_vma.flags;
err = io_remap_pfn_range(vma, vma->vm_start,
l->usermode_regs_bus_addr >> PAGE_SHIFT,
g->usermode_regs_bus_addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
if (err != 0) {
nvgpu_err(g, "can't restore usermode mapping");

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -12,125 +12,20 @@
*/
#include <nvgpu/io.h>
#include <nvgpu/types.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/nvgpu_init.h>
#include "os_linux.h"
static void nvgpu_warn_on_no_regs(void)
u32 nvgpu_os_readl(uintptr_t addr)
{
WARN_ONCE(true, "Attempted access to GPU regs after unmapping!");
return readl((void __iomem *)addr);
}
void nvgpu_writel(struct gk20a *g, u32 r, u32 v)
void nvgpu_os_writel(u32 v, uintptr_t addr)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
if (unlikely(!l->regs)) {
nvgpu_warn_on_no_regs();
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
writel_relaxed(v, l->regs + r);
nvgpu_wmb();
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
}
writel(v, (void __iomem *)addr);
}
void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v)
void nvgpu_os_writel_relaxed(u32 v, uintptr_t addr)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
if (unlikely(!l->regs)) {
nvgpu_warn_on_no_regs();
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
writel_relaxed(v, l->regs + r);
}
}
u32 nvgpu_readl(struct gk20a *g, u32 r)
{
u32 v = nvgpu_readl_impl(g, r);
if (v == 0xffffffff)
nvgpu_check_gpu_state(g);
return v;
}
u32 nvgpu_readl_impl(struct gk20a *g, u32 r)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
u32 v = 0xffffffff;
if (unlikely(!l->regs)) {
nvgpu_warn_on_no_regs();
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
v = readl(l->regs + r);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
}
return v;
}
void nvgpu_writel_loop(struct gk20a *g, u32 r, u32 v)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
if (unlikely(!l->regs)) {
nvgpu_warn_on_no_regs();
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
nvgpu_wmb();
do {
writel_relaxed(v, l->regs + r);
} while (readl(l->regs + r) != v);
nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
}
}
void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
if (unlikely(!l->bar1)) {
nvgpu_warn_on_no_regs();
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
} else {
nvgpu_wmb();
writel_relaxed(v, l->bar1 + b);
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
}
}
u32 nvgpu_bar1_readl(struct gk20a *g, u32 b)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
u32 v = 0xffffffff;
if (unlikely(!l->bar1)) {
nvgpu_warn_on_no_regs();
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
} else {
v = readl(l->bar1 + b);
nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
}
return v;
}
bool nvgpu_io_exists(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
return l->regs != NULL;
}
bool nvgpu_io_valid_reg(struct gk20a *g, u32 r)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
return r < resource_size(l->regs);
writel_relaxed(v, (void __iomem *)addr);
}

View File

@@ -229,10 +229,8 @@ void gk20a_idle(struct gk20a *g)
*/
static int gk20a_restore_registers(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
l->regs = l->regs_saved;
l->bar1 = l->bar1_saved;
g->regs = g->regs_saved;
g->bar1 = g->bar1_saved;
nvgpu_restore_usermode_registers(g);
@@ -547,10 +545,8 @@ done:
*/
static int gk20a_lockout_registers(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
l->regs = NULL;
l->bar1 = NULL;
g->regs = 0U;
g->bar1 = 0U;
nvgpu_lockout_usermode_registers(g);
@@ -1014,37 +1010,41 @@ static int gk20a_init_support(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct gk20a *g = get_gk20a(dev);
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
void __iomem *addr;
int err = -ENOMEM;
#ifdef CONFIG_NVGPU_VPR
tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g);
#endif
l->regs = nvgpu_devm_ioremap_resource(pdev,
addr = nvgpu_devm_ioremap_resource(pdev,
GK20A_BAR0_IORESOURCE_MEM,
&l->reg_mem);
if (IS_ERR(l->regs)) {
if (IS_ERR(addr)) {
nvgpu_err(g, "failed to remap gk20a registers");
err = PTR_ERR(l->regs);
err = PTR_ERR(addr);
goto fail;
}
g->regs = (uintptr_t)addr;
g->regs_size = resource_size(l->reg_mem);
l->regs_bus_addr = nvgpu_resource_addr(pdev,
g->regs_bus_addr = nvgpu_resource_addr(pdev,
GK20A_BAR0_IORESOURCE_MEM);
if (!l->regs_bus_addr) {
if (!g->regs_bus_addr) {
nvgpu_err(g, "failed to read register bus offset");
err = -ENODEV;
goto fail;
}
l->bar1 = nvgpu_devm_ioremap_resource(pdev,
addr = nvgpu_devm_ioremap_resource(pdev,
GK20A_BAR1_IORESOURCE_MEM,
&l->bar1_mem);
if (IS_ERR(l->bar1)) {
if (IS_ERR(addr)) {
nvgpu_err(g, "failed to remap gk20a bar1");
err = PTR_ERR(l->bar1);
err = PTR_ERR(addr);
goto fail;
}
g->bar1 = (uintptr_t)addr;
err = nvgpu_init_sim_support_linux(g, pdev);
if (err)
@@ -1059,11 +1059,11 @@ static int gk20a_init_support(struct platform_device *pdev)
fail_sim:
nvgpu_remove_sim_support_linux(g);
fail:
if (l->regs)
l->regs = NULL;
if (g->regs)
g->regs = 0U;
if (l->bar1)
l->bar1 = NULL;
if (g->bar1)
g->bar1 = 0U;
return err;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -27,9 +27,7 @@
*/
void nvgpu_lockout_usermode_registers(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
l->usermode_regs = NULL;
g->usermode_regs = 0U;
}
/*
@@ -37,33 +35,27 @@ void nvgpu_lockout_usermode_registers(struct gk20a *g)
*/
void nvgpu_restore_usermode_registers(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
l->usermode_regs = l->usermode_regs_saved;
g->usermode_regs = g->usermode_regs_saved;
}
void nvgpu_remove_usermode_support(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
if (l->usermode_regs) {
l->usermode_regs = NULL;
if (g->usermode_regs) {
g->usermode_regs = 0U;
}
}
void nvgpu_init_usermode_support(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
if (g->ops.usermode.base == NULL) {
return;
}
if (l->usermode_regs == NULL) {
l->usermode_regs = l->regs + g->ops.usermode.bus_base(g);
l->usermode_regs_saved = l->usermode_regs;
if (g->usermode_regs == 0U) {
g->usermode_regs = g->regs + g->ops.usermode.bus_base(g);
g->usermode_regs_saved = g->usermode_regs;
}
l->usermode_regs_bus_addr = l->regs_bus_addr +
g->usermode_regs_bus_addr = g->regs_bus_addr +
g->ops.usermode.bus_base(g);
}

View File

@@ -96,17 +96,7 @@ struct nvgpu_os_linux {
struct workqueue_struct *nonstall_work_queue;
struct resource *reg_mem;
void __iomem *regs;
void __iomem *regs_saved;
u64 regs_bus_addr;
struct resource *bar1_mem;
void __iomem *bar1;
void __iomem *bar1_saved;
void __iomem *usermode_regs;
void __iomem *usermode_regs_saved;
u64 usermode_regs_bus_addr;
struct nvgpu_os_linux_ops ops;

View File

@@ -354,31 +354,34 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
{
int err = 0;
struct gk20a *g = get_gk20a(&pdev->dev);
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
struct device *dev = &pdev->dev;
void __iomem *addr;
l->regs = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 0),
addr = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (IS_ERR(l->regs)) {
if (IS_ERR(addr)) {
nvgpu_err(g, "failed to remap gk20a registers");
err = PTR_ERR(l->regs);
err = PTR_ERR(addr);
goto fail;
}
g->regs = (uintptr_t)addr;
g->regs_size = pci_resource_len(pdev, 0);
l->regs_bus_addr = pci_resource_start(pdev, 0);
if (!l->regs_bus_addr) {
g->regs_bus_addr = pci_resource_start(pdev, 0);
if (!g->regs_bus_addr) {
nvgpu_err(g, "failed to read register bus offset");
err = -ENODEV;
goto fail;
}
l->bar1 = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 1),
addr = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 1),
pci_resource_len(pdev, 1));
if (IS_ERR(l->bar1)) {
if (IS_ERR(addr)) {
nvgpu_err(g, "failed to remap gk20a bar1");
err = PTR_ERR(l->bar1);
err = PTR_ERR(addr);
goto fail;
}
g->bar1 = (uintptr_t)addr;
err = nvgpu_init_sim_support_linux_pci(g);
if (err)
@@ -392,11 +395,11 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
fail_sim:
nvgpu_remove_sim_support_linux_pci(g);
fail:
if (l->regs)
l->regs = NULL;
if (g->regs)
g->regs = 0U;
if (l->bar1)
l->bar1 = NULL;
if (g->bar1)
g->bar1 = 0U;
return err;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -75,7 +75,6 @@ void nvgpu_remove_sim_support_linux_pci(struct gk20a *g)
int nvgpu_init_sim_support_linux_pci(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
struct sim_nvgpu_linux *sim_linux;
int err = -ENOMEM;
bool is_simulation;
@@ -91,7 +90,7 @@ int nvgpu_init_sim_support_linux_pci(struct gk20a *g)
return err;
g->sim = &sim_linux->sim;
g->sim->g = g;
sim_linux->regs = l->regs + sim_r();
sim_linux->regs = (void __iomem *)g->regs + sim_r();
sim_linux->remove_support_linux = nvgpu_remove_sim_support_linux_pci;
return 0;

View File

@@ -33,7 +33,6 @@ int gv11b_vgpu_probe(struct device *dev)
struct gk20a_platform *platform = dev_get_drvdata(dev);
struct resource *r;
void __iomem *regs;
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(platform->g);
struct gk20a *g = platform->g;
#ifdef CONFIG_TEGRA_GK20A_NVHOST
int ret;
@@ -49,14 +48,14 @@ int gv11b_vgpu_probe(struct device *dev)
nvgpu_err(g, "failed to map usermode regs");
return PTR_ERR(regs);
}
l->usermode_regs = regs;
g->usermode_regs = (uintptr_t)regs;
l->usermode_regs_bus_addr = r->start;
g->usermode_regs_bus_addr = r->start;
#ifdef CONFIG_TEGRA_GK20A_NVHOST
ret = nvgpu_get_nvhost_dev(g);
if (ret) {
l->usermode_regs = NULL;
g->usermode_regs = 0U;
return ret;
}

View File

@@ -72,15 +72,13 @@ struct vgpu_priv_data *vgpu_get_priv_data(struct gk20a *g)
static void vgpu_remove_support(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
vgpu_remove_support_common(g);
/* free mappings to registers, etc*/
if (l->bar1) {
iounmap(l->bar1);
l->bar1 = NULL;
if (g->bar1) {
iounmap((void __iomem *)g->bar1);
g->bar1 = 0U;
}
}
@@ -101,8 +99,8 @@ static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform)
nvgpu_mutex_init(&l->ctrl_privs_lock);
nvgpu_init_list_node(&l->ctrl_privs);
l->regs_saved = l->regs;
l->bar1_saved = l->bar1;
g->regs_saved = g->regs;
g->bar1_saved = g->bar1;
nvgpu_atomic_set(&g->clk_arb_global_nr, 0);
@@ -140,7 +138,7 @@ static int vgpu_init_support(struct platform_device *pdev)
err = PTR_ERR(regs);
goto fail;
}
l->bar1 = regs;
g->bar1 = (uintptr_t)regs;
l->bar1_mem = r;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -218,6 +218,12 @@ static void nvgpu_posix_load_regs(struct gk20a *g)
}
}
static __thread struct gk20a *g_saved;
struct gk20a *nvgpu_posix_current_device(void)
{
return g_saved;
}
/*
* This function aims to initialize enough stuff to make unit testing worth
* while. There are several interfaces and APIs that rely on the struct gk20a's
@@ -251,6 +257,12 @@ struct gk20a *nvgpu_posix_probe(void)
g->log_mask = NVGPU_DEFAULT_DBG_MASK;
g->mm.g = g;
g_saved = g;
g->regs = NVGPU_POSIX_REG_BAR0 << NVGPU_POSIX_REG_SHIFT;
g->bar1 = NVGPU_POSIX_REG_BAR1 << NVGPU_POSIX_REG_SHIFT;
g->usermode_regs = NVGPU_POSIX_REG_USERMODE << NVGPU_POSIX_REG_SHIFT;
if (nvgpu_kmem_init(g) != 0) {
goto fail_kmem;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,6 +26,7 @@
#include <nvgpu/posix/io.h>
#include <nvgpu/posix/posix-fault-injection.h>
#include <nvgpu/posix/probe.h>
#include "os_posix.h"
@@ -59,7 +60,7 @@ struct nvgpu_posix_io_callbacks *nvgpu_posix_register_io(
return old_io;
}
void nvgpu_writel(struct gk20a *g, u32 r, u32 v)
static void nvgpu_posix_writel(struct gk20a *g, u32 r, u32 v)
{
struct nvgpu_posix_io_callbacks *callbacks =
nvgpu_os_posix_from_gk20a(g)->callbacks;
@@ -76,14 +77,7 @@ void nvgpu_writel(struct gk20a *g, u32 r, u32 v)
callbacks->writel(g, &access);
}
#ifdef CONFIG_NVGPU_DGPU
void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v)
{
nvgpu_writel(g, r, v);
}
#endif
u32 nvgpu_readl(struct gk20a *g, u32 r)
static u32 nvgpu_posix_readl(struct gk20a *g, u32 r)
{
struct nvgpu_posix_io_callbacks *callbacks =
nvgpu_os_posix_from_gk20a(g)->callbacks;
@@ -109,33 +103,7 @@ u32 nvgpu_readl(struct gk20a *g, u32 r)
return access.value;
}
#ifdef CONFIG_NVGPU_NON_FUSA
void nvgpu_writel_loop(struct gk20a *g, u32 r, u32 v)
{
BUG();
}
#endif
u32 nvgpu_readl_impl(struct gk20a *g, u32 r)
{
struct nvgpu_posix_io_callbacks *callbacks =
nvgpu_os_posix_from_gk20a(g)->callbacks;
struct nvgpu_reg_access access = {
.addr = r,
.value = 0L
};
if (callbacks == NULL || callbacks->__readl == NULL) {
BUG();
}
callbacks->__readl(g, &access);
return access.value;
}
void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v)
static void nvgpu_posix_bar1_writel(struct gk20a *g, u32 b, u32 v)
{
struct nvgpu_posix_io_callbacks *callbacks =
nvgpu_os_posix_from_gk20a(g)->callbacks;
@@ -152,7 +120,7 @@ void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v)
callbacks->bar1_writel(g, &access);
}
u32 nvgpu_bar1_readl(struct gk20a *g, u32 b)
static u32 nvgpu_posix_bar1_readl(struct gk20a *g, u32 b)
{
struct nvgpu_posix_io_callbacks *callbacks =
nvgpu_os_posix_from_gk20a(g)->callbacks;
@@ -188,14 +156,44 @@ void nvgpu_usermode_writel(struct gk20a *g, u32 r, u32 v)
callbacks->usermode_writel(g, &access);
}
bool nvgpu_io_exists(struct gk20a *g)
u32 nvgpu_os_readl(uintptr_t addr)
{
return false;
struct gk20a *g = nvgpu_posix_current_device();
u32 r, type;
r = (u32)(addr & ~(NVGPU_POSIX_REG_MASK << NVGPU_POSIX_REG_SHIFT));
type = (u32)(addr >> NVGPU_POSIX_REG_SHIFT);
switch (type) {
case NVGPU_POSIX_REG_BAR0:
return nvgpu_posix_readl(g, r);
case NVGPU_POSIX_REG_BAR1:
return nvgpu_posix_bar1_readl(g, r);
default:
BUG();
}
}
bool nvgpu_io_valid_reg(struct gk20a *g, u32 r)
void nvgpu_os_writel(u32 v, uintptr_t addr)
{
return false;
struct gk20a *g = nvgpu_posix_current_device();
u32 r;
u64 type;
r = (u32)(addr & ~(NVGPU_POSIX_REG_MASK << NVGPU_POSIX_REG_SHIFT));
type = addr >> NVGPU_POSIX_REG_SHIFT;
switch (type) {
case NVGPU_POSIX_REG_BAR0:
return nvgpu_posix_writel(g, r, v);
case NVGPU_POSIX_REG_BAR1:
return nvgpu_posix_bar1_writel(g, r, v);
default:
BUG();
}
}
void nvgpu_os_writel_relaxed(u32 v, uintptr_t addr)
{
nvgpu_os_writel(v, addr);
}
void nvgpu_posix_io_init_reg_space(struct gk20a *g)