mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 01:50:07 +03:00
Commit 81868a187f updated barrier
usage to use the nvgpu wrappers and in doing so downgraded many
plain barriers {mb(), wmb(), rmb()} to the SMP versions of these
barriers.
The SMP version of the barriers in question are only issued
when running on an SMP machine. In most of the cases mentioned
above this is fine since the barriers are present to faciliate
proper ordering across CPUs. A single CPU is always coherent
with itself, so on a non-SMP case we don't need those barriers.
However, there are a few places where the barriers in use (GMMU
page table programming, IO accessors, userd) where the barrier
usage is for communicating and establishing ordering for the
GPU. We need these barriers for both SMP machines and non-SMP
machines. Therefor we must use the plain barrier versions.
Change-Id: I376129840b7dc64af8f3f23f88057e4e81360f89
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1599744
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
111 lines
2.6 KiB
C
111 lines
2.6 KiB
C
/*
|
|
* Copyright (c) 2017, 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,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*/
|
|
|
|
#include <nvgpu/io.h>
|
|
#include <nvgpu/types.h>
|
|
|
|
#include "os_linux.h"
|
|
#include "gk20a/gk20a.h"
|
|
|
|
void nvgpu_writel(struct gk20a *g, u32 r, u32 v)
|
|
{
|
|
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
|
|
|
if (unlikely(!l->regs)) {
|
|
__gk20a_warn_on_no_regs();
|
|
gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
|
|
} else {
|
|
writel_relaxed(v, l->regs + r);
|
|
nvgpu_wmb();
|
|
gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
|
|
}
|
|
}
|
|
|
|
u32 nvgpu_readl(struct gk20a *g, u32 r)
|
|
{
|
|
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
|
u32 v = 0xffffffff;
|
|
|
|
if (unlikely(!l->regs)) {
|
|
__gk20a_warn_on_no_regs();
|
|
gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
|
|
} else {
|
|
v = readl(l->regs + r);
|
|
if (v == 0xffffffff)
|
|
__nvgpu_check_gpu_state(g);
|
|
gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v)
|
|
{
|
|
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
|
|
|
if (unlikely(!l->regs)) {
|
|
__gk20a_warn_on_no_regs();
|
|
gk20a_dbg(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);
|
|
gk20a_dbg(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)) {
|
|
__gk20a_warn_on_no_regs();
|
|
gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
|
|
} else {
|
|
nvgpu_wmb();
|
|
writel_relaxed(v, l->bar1 + b);
|
|
gk20a_dbg(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)) {
|
|
__gk20a_warn_on_no_regs();
|
|
gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
|
|
} else {
|
|
v = readl(l->bar1 + b);
|
|
gk20a_dbg(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);
|
|
}
|