mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
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:
committed by
mobile promotions
parent
0a25376965
commit
643eb158a3
@@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -24,6 +24,114 @@
|
|||||||
#include <nvgpu/types.h>
|
#include <nvgpu/types.h>
|
||||||
#include <nvgpu/bug.h>
|
#include <nvgpu/bug.h>
|
||||||
#include <nvgpu/gk20a.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)
|
void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -336,6 +336,22 @@ struct gk20a {
|
|||||||
*/
|
*/
|
||||||
void (*gfree)(struct gk20a *g);
|
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.
|
* Handle to access nvhost APIs.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,44 @@
|
|||||||
|
|
||||||
#include <nvgpu/types.h>
|
#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
|
* @file
|
||||||
*
|
*
|
||||||
@@ -65,8 +103,7 @@ void nvgpu_writel(struct gk20a *g, u32 r, u32 v);
|
|||||||
* @param v [in] Value to write at the offset.
|
* @param v [in] Value to write at the offset.
|
||||||
*
|
*
|
||||||
* Write a 32-bit value to register offset in GPU IO space without
|
* Write a 32-bit value to register offset in GPU IO space without
|
||||||
* an ordering constraint on memory operations. This function is
|
* an ordering constraint on memory operations.
|
||||||
* implemented by the OS layer.
|
|
||||||
*
|
*
|
||||||
* @return None.
|
* @return None.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* 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 gk20a *g,
|
||||||
struct nvgpu_posix_io_callbacks *io_callbacks);
|
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 {
|
struct nvgpu_posix_io_reg_space {
|
||||||
u32 base;
|
u32 base;
|
||||||
u32 size;
|
u32 size;
|
||||||
|
|||||||
@@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
struct gk20a;
|
struct gk20a;
|
||||||
|
|
||||||
|
struct gk20a *nvgpu_posix_current_device(void);
|
||||||
struct gk20a *nvgpu_posix_probe(void);
|
struct gk20a *nvgpu_posix_probe(void);
|
||||||
void nvgpu_posix_cleanup(struct gk20a *g);
|
void nvgpu_posix_cleanup(struct gk20a *g);
|
||||||
|
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ static void nvgpu_init_vars(struct gk20a *g)
|
|||||||
nvgpu_mutex_init(&l->ctrl_privs_lock);
|
nvgpu_mutex_init(&l->ctrl_privs_lock);
|
||||||
nvgpu_init_list_node(&l->ctrl_privs);
|
nvgpu_init_list_node(&l->ctrl_privs);
|
||||||
|
|
||||||
l->regs_saved = l->regs;
|
g->regs_saved = g->regs;
|
||||||
l->bar1_saved = l->bar1;
|
g->bar1_saved = g->bar1;
|
||||||
|
|
||||||
g->emc3d_ratio = EMC3D_DEFAULT_RATIO;
|
g->emc3d_ratio = EMC3D_DEFAULT_RATIO;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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)
|
void nvgpu_usermode_writel(struct gk20a *g, u32 r, u32 v)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
uintptr_t reg = g->usermode_regs + (r - g->ops.usermode.base(g));
|
||||||
void __iomem *reg = l->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);
|
nvgpu_log(g, gpu_dbg_reg, "usermode r=0x%x v=0x%x", r, v);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||||
|
|
||||||
err = io_remap_pfn_range(vma, vma->vm_start,
|
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);
|
vma->vm_end - vma->vm_start, vma->vm_page_prot);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
priv->usermode_vma.vma = vma;
|
priv->usermode_vma.vma = vma;
|
||||||
@@ -2297,7 +2297,6 @@ static void alter_usermode_mapping(struct gk20a *g,
|
|||||||
struct gk20a_ctrl_priv *priv,
|
struct gk20a_ctrl_priv *priv,
|
||||||
bool poweroff)
|
bool poweroff)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
|
||||||
struct vm_area_struct *vma = priv->usermode_vma.vma;
|
struct vm_area_struct *vma = priv->usermode_vma.vma;
|
||||||
bool vma_mapped = priv->usermode_vma.vma_mapped;
|
bool vma_mapped = priv->usermode_vma.vma_mapped;
|
||||||
int err;
|
int err;
|
||||||
@@ -2335,7 +2334,7 @@ static void alter_usermode_mapping(struct gk20a *g,
|
|||||||
} else if (!poweroff && !vma_mapped) {
|
} else if (!poweroff && !vma_mapped) {
|
||||||
vma->vm_flags = priv->usermode_vma.flags;
|
vma->vm_flags = priv->usermode_vma.flags;
|
||||||
err = io_remap_pfn_range(vma, vma->vm_start,
|
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);
|
vma->vm_end - vma->vm_start, vma->vm_page_prot);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
nvgpu_err(g, "can't restore usermode mapping");
|
nvgpu_err(g, "can't restore usermode mapping");
|
||||||
|
|||||||
@@ -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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -12,125 +12,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nvgpu/io.h>
|
#include <nvgpu/io.h>
|
||||||
#include <nvgpu/types.h>
|
|
||||||
#include <nvgpu/gk20a.h>
|
|
||||||
#include <nvgpu/nvgpu_init.h>
|
|
||||||
|
|
||||||
#include "os_linux.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);
|
writel(v, (void __iomem *)addr);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
writel_relaxed(v, (void __iomem *)addr);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,10 +229,8 @@ void gk20a_idle(struct gk20a *g)
|
|||||||
*/
|
*/
|
||||||
static int gk20a_restore_registers(struct gk20a *g)
|
static int gk20a_restore_registers(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
g->regs = g->regs_saved;
|
||||||
|
g->bar1 = g->bar1_saved;
|
||||||
l->regs = l->regs_saved;
|
|
||||||
l->bar1 = l->bar1_saved;
|
|
||||||
|
|
||||||
nvgpu_restore_usermode_registers(g);
|
nvgpu_restore_usermode_registers(g);
|
||||||
|
|
||||||
@@ -547,10 +545,8 @@ done:
|
|||||||
*/
|
*/
|
||||||
static int gk20a_lockout_registers(struct gk20a *g)
|
static int gk20a_lockout_registers(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
g->regs = 0U;
|
||||||
|
g->bar1 = 0U;
|
||||||
l->regs = NULL;
|
|
||||||
l->bar1 = NULL;
|
|
||||||
|
|
||||||
nvgpu_lockout_usermode_registers(g);
|
nvgpu_lockout_usermode_registers(g);
|
||||||
|
|
||||||
@@ -1014,37 +1010,41 @@ static int gk20a_init_support(struct platform_device *pdev)
|
|||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct gk20a *g = get_gk20a(dev);
|
struct gk20a *g = get_gk20a(dev);
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
||||||
|
void __iomem *addr;
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
|
|
||||||
#ifdef CONFIG_NVGPU_VPR
|
#ifdef CONFIG_NVGPU_VPR
|
||||||
tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g);
|
tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
l->regs = nvgpu_devm_ioremap_resource(pdev,
|
addr = nvgpu_devm_ioremap_resource(pdev,
|
||||||
GK20A_BAR0_IORESOURCE_MEM,
|
GK20A_BAR0_IORESOURCE_MEM,
|
||||||
&l->reg_mem);
|
&l->reg_mem);
|
||||||
if (IS_ERR(l->regs)) {
|
if (IS_ERR(addr)) {
|
||||||
nvgpu_err(g, "failed to remap gk20a registers");
|
nvgpu_err(g, "failed to remap gk20a registers");
|
||||||
err = PTR_ERR(l->regs);
|
err = PTR_ERR(addr);
|
||||||
goto fail;
|
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);
|
GK20A_BAR0_IORESOURCE_MEM);
|
||||||
if (!l->regs_bus_addr) {
|
if (!g->regs_bus_addr) {
|
||||||
nvgpu_err(g, "failed to read register bus offset");
|
nvgpu_err(g, "failed to read register bus offset");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
l->bar1 = nvgpu_devm_ioremap_resource(pdev,
|
addr = nvgpu_devm_ioremap_resource(pdev,
|
||||||
GK20A_BAR1_IORESOURCE_MEM,
|
GK20A_BAR1_IORESOURCE_MEM,
|
||||||
&l->bar1_mem);
|
&l->bar1_mem);
|
||||||
if (IS_ERR(l->bar1)) {
|
if (IS_ERR(addr)) {
|
||||||
nvgpu_err(g, "failed to remap gk20a bar1");
|
nvgpu_err(g, "failed to remap gk20a bar1");
|
||||||
err = PTR_ERR(l->bar1);
|
err = PTR_ERR(addr);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
g->bar1 = (uintptr_t)addr;
|
||||||
|
|
||||||
err = nvgpu_init_sim_support_linux(g, pdev);
|
err = nvgpu_init_sim_support_linux(g, pdev);
|
||||||
if (err)
|
if (err)
|
||||||
@@ -1059,11 +1059,11 @@ static int gk20a_init_support(struct platform_device *pdev)
|
|||||||
fail_sim:
|
fail_sim:
|
||||||
nvgpu_remove_sim_support_linux(g);
|
nvgpu_remove_sim_support_linux(g);
|
||||||
fail:
|
fail:
|
||||||
if (l->regs)
|
if (g->regs)
|
||||||
l->regs = NULL;
|
g->regs = 0U;
|
||||||
|
|
||||||
if (l->bar1)
|
if (g->bar1)
|
||||||
l->bar1 = NULL;
|
g->bar1 = 0U;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -27,9 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
void nvgpu_lockout_usermode_registers(struct gk20a *g)
|
void nvgpu_lockout_usermode_registers(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
g->usermode_regs = 0U;
|
||||||
|
|
||||||
l->usermode_regs = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -37,33 +35,27 @@ void nvgpu_lockout_usermode_registers(struct gk20a *g)
|
|||||||
*/
|
*/
|
||||||
void nvgpu_restore_usermode_registers(struct gk20a *g)
|
void nvgpu_restore_usermode_registers(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
g->usermode_regs = g->usermode_regs_saved;
|
||||||
|
|
||||||
l->usermode_regs = l->usermode_regs_saved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvgpu_remove_usermode_support(struct gk20a *g)
|
void nvgpu_remove_usermode_support(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
if (g->usermode_regs) {
|
||||||
|
g->usermode_regs = 0U;
|
||||||
if (l->usermode_regs) {
|
|
||||||
l->usermode_regs = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvgpu_init_usermode_support(struct gk20a *g)
|
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) {
|
if (g->ops.usermode.base == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l->usermode_regs == NULL) {
|
if (g->usermode_regs == 0U) {
|
||||||
l->usermode_regs = l->regs + g->ops.usermode.bus_base(g);
|
g->usermode_regs = g->regs + g->ops.usermode.bus_base(g);
|
||||||
l->usermode_regs_saved = l->usermode_regs;
|
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);
|
g->ops.usermode.bus_base(g);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,17 +96,7 @@ struct nvgpu_os_linux {
|
|||||||
struct workqueue_struct *nonstall_work_queue;
|
struct workqueue_struct *nonstall_work_queue;
|
||||||
|
|
||||||
struct resource *reg_mem;
|
struct resource *reg_mem;
|
||||||
void __iomem *regs;
|
|
||||||
void __iomem *regs_saved;
|
|
||||||
u64 regs_bus_addr;
|
|
||||||
|
|
||||||
struct resource *bar1_mem;
|
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;
|
struct nvgpu_os_linux_ops ops;
|
||||||
|
|
||||||
|
|||||||
@@ -354,31 +354,34 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
|
|||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct gk20a *g = get_gk20a(&pdev->dev);
|
struct gk20a *g = get_gk20a(&pdev->dev);
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
|
||||||
struct device *dev = &pdev->dev;
|
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));
|
pci_resource_len(pdev, 0));
|
||||||
if (IS_ERR(l->regs)) {
|
if (IS_ERR(addr)) {
|
||||||
nvgpu_err(g, "failed to remap gk20a registers");
|
nvgpu_err(g, "failed to remap gk20a registers");
|
||||||
err = PTR_ERR(l->regs);
|
err = PTR_ERR(addr);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
g->regs = (uintptr_t)addr;
|
||||||
|
g->regs_size = pci_resource_len(pdev, 0);
|
||||||
|
|
||||||
l->regs_bus_addr = pci_resource_start(pdev, 0);
|
g->regs_bus_addr = pci_resource_start(pdev, 0);
|
||||||
if (!l->regs_bus_addr) {
|
if (!g->regs_bus_addr) {
|
||||||
nvgpu_err(g, "failed to read register bus offset");
|
nvgpu_err(g, "failed to read register bus offset");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto fail;
|
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));
|
pci_resource_len(pdev, 1));
|
||||||
if (IS_ERR(l->bar1)) {
|
if (IS_ERR(addr)) {
|
||||||
nvgpu_err(g, "failed to remap gk20a bar1");
|
nvgpu_err(g, "failed to remap gk20a bar1");
|
||||||
err = PTR_ERR(l->bar1);
|
err = PTR_ERR(addr);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
g->bar1 = (uintptr_t)addr;
|
||||||
|
|
||||||
err = nvgpu_init_sim_support_linux_pci(g);
|
err = nvgpu_init_sim_support_linux_pci(g);
|
||||||
if (err)
|
if (err)
|
||||||
@@ -392,11 +395,11 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
|
|||||||
fail_sim:
|
fail_sim:
|
||||||
nvgpu_remove_sim_support_linux_pci(g);
|
nvgpu_remove_sim_support_linux_pci(g);
|
||||||
fail:
|
fail:
|
||||||
if (l->regs)
|
if (g->regs)
|
||||||
l->regs = NULL;
|
g->regs = 0U;
|
||||||
|
|
||||||
if (l->bar1)
|
if (g->bar1)
|
||||||
l->bar1 = NULL;
|
g->bar1 = 0U;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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)
|
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;
|
struct sim_nvgpu_linux *sim_linux;
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
bool is_simulation;
|
bool is_simulation;
|
||||||
@@ -91,7 +90,7 @@ int nvgpu_init_sim_support_linux_pci(struct gk20a *g)
|
|||||||
return err;
|
return err;
|
||||||
g->sim = &sim_linux->sim;
|
g->sim = &sim_linux->sim;
|
||||||
g->sim->g = g;
|
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;
|
sim_linux->remove_support_linux = nvgpu_remove_sim_support_linux_pci;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ int gv11b_vgpu_probe(struct device *dev)
|
|||||||
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||||
struct resource *r;
|
struct resource *r;
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(platform->g);
|
|
||||||
struct gk20a *g = platform->g;
|
struct gk20a *g = platform->g;
|
||||||
#ifdef CONFIG_TEGRA_GK20A_NVHOST
|
#ifdef CONFIG_TEGRA_GK20A_NVHOST
|
||||||
int ret;
|
int ret;
|
||||||
@@ -49,14 +48,14 @@ int gv11b_vgpu_probe(struct device *dev)
|
|||||||
nvgpu_err(g, "failed to map usermode regs");
|
nvgpu_err(g, "failed to map usermode regs");
|
||||||
return PTR_ERR(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
|
#ifdef CONFIG_TEGRA_GK20A_NVHOST
|
||||||
ret = nvgpu_get_nvhost_dev(g);
|
ret = nvgpu_get_nvhost_dev(g);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
l->usermode_regs = NULL;
|
g->usermode_regs = 0U;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,15 +72,13 @@ struct vgpu_priv_data *vgpu_get_priv_data(struct gk20a *g)
|
|||||||
|
|
||||||
static void vgpu_remove_support(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);
|
vgpu_remove_support_common(g);
|
||||||
|
|
||||||
/* free mappings to registers, etc*/
|
/* free mappings to registers, etc*/
|
||||||
|
|
||||||
if (l->bar1) {
|
if (g->bar1) {
|
||||||
iounmap(l->bar1);
|
iounmap((void __iomem *)g->bar1);
|
||||||
l->bar1 = NULL;
|
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_mutex_init(&l->ctrl_privs_lock);
|
||||||
nvgpu_init_list_node(&l->ctrl_privs);
|
nvgpu_init_list_node(&l->ctrl_privs);
|
||||||
|
|
||||||
l->regs_saved = l->regs;
|
g->regs_saved = g->regs;
|
||||||
l->bar1_saved = l->bar1;
|
g->bar1_saved = g->bar1;
|
||||||
|
|
||||||
nvgpu_atomic_set(&g->clk_arb_global_nr, 0);
|
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);
|
err = PTR_ERR(regs);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
l->bar1 = regs;
|
g->bar1 = (uintptr_t)regs;
|
||||||
l->bar1_mem = r;
|
l->bar1_mem = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* 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
|
* 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
|
* 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->log_mask = NVGPU_DEFAULT_DBG_MASK;
|
||||||
g->mm.g = g;
|
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) {
|
if (nvgpu_kmem_init(g) != 0) {
|
||||||
goto fail_kmem;
|
goto fail_kmem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <nvgpu/posix/io.h>
|
#include <nvgpu/posix/io.h>
|
||||||
#include <nvgpu/posix/posix-fault-injection.h>
|
#include <nvgpu/posix/posix-fault-injection.h>
|
||||||
|
#include <nvgpu/posix/probe.h>
|
||||||
|
|
||||||
#include "os_posix.h"
|
#include "os_posix.h"
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ struct nvgpu_posix_io_callbacks *nvgpu_posix_register_io(
|
|||||||
return old_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 =
|
struct nvgpu_posix_io_callbacks *callbacks =
|
||||||
nvgpu_os_posix_from_gk20a(g)->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);
|
callbacks->writel(g, &access);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NVGPU_DGPU
|
static u32 nvgpu_posix_readl(struct gk20a *g, u32 r)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
struct nvgpu_posix_io_callbacks *callbacks =
|
struct nvgpu_posix_io_callbacks *callbacks =
|
||||||
nvgpu_os_posix_from_gk20a(g)->callbacks;
|
nvgpu_os_posix_from_gk20a(g)->callbacks;
|
||||||
@@ -109,33 +103,7 @@ u32 nvgpu_readl(struct gk20a *g, u32 r)
|
|||||||
return access.value;
|
return access.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NVGPU_NON_FUSA
|
static void nvgpu_posix_bar1_writel(struct gk20a *g, u32 b, u32 v)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
struct nvgpu_posix_io_callbacks *callbacks =
|
struct nvgpu_posix_io_callbacks *callbacks =
|
||||||
nvgpu_os_posix_from_gk20a(g)->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);
|
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 =
|
struct nvgpu_posix_io_callbacks *callbacks =
|
||||||
nvgpu_os_posix_from_gk20a(g)->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);
|
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)
|
void nvgpu_posix_io_init_reg_space(struct gk20a *g)
|
||||||
|
|||||||
Reference in New Issue
Block a user