diff --git a/drivers/gpu/nvgpu/common/io/io.c b/drivers/gpu/nvgpu/common/io/io.c index 18a912df5..859244eeb 100644 --- a/drivers/gpu/nvgpu/common/io/io.c +++ b/drivers/gpu/nvgpu/common/io/io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2023, 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"), @@ -147,18 +147,28 @@ void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v) void nvgpu_func_writel(struct gk20a *g, u32 r, u32 v) { - if (g->ops.func.get_full_phys_offset == NULL) { - BUG_ON(1); + if (unlikely(!g->func_regs)) { + nvgpu_warn_on_no_regs(g, r); + nvgpu_log(g, gpu_dbg_reg, "f=0x%x v=0x%x (failed)", r, v); + } else { + nvgpu_os_writel(v, g->func_regs + r); + nvgpu_wmb(); + nvgpu_log(g, gpu_dbg_reg, "f=0x%x v=0x%x", r, v); } - nvgpu_writel(g, - nvgpu_safe_add_u32(r, g->ops.func.get_full_phys_offset(g)), v); } u32 nvgpu_func_readl(struct gk20a *g, u32 r) { - if (g->ops.func.get_full_phys_offset == NULL) { - BUG_ON(1); + u32 v = 0xffffffff; + + if (unlikely(!g->func_regs)) { + nvgpu_warn_on_no_regs(g, r); + nvgpu_log(g, gpu_dbg_reg, "f=0x%x v=0x%x (failed)", r, v); + nvgpu_check_gpu_state(g); + } else { + v = nvgpu_os_readl(g->func_regs + r); + nvgpu_log(g, gpu_dbg_reg, "f=0x%x v=0x%x", r, v); } - return nvgpu_readl(g, - nvgpu_safe_add_u32(r, g->ops.func.get_full_phys_offset(g))); + + return v; } diff --git a/drivers/gpu/nvgpu/hal/init/hal_init.c b/drivers/gpu/nvgpu/hal/init/hal_init.c index 69912dd69..5e611322e 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_init.c +++ b/drivers/gpu/nvgpu/hal/init/hal_init.c @@ -1,7 +1,7 @@ /* * NVIDIA GPU HAL interface. * - * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2023, 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"), @@ -143,5 +143,12 @@ int nvgpu_detect_chip(struct gk20a *g) return err; } + if (g->func_regs == 0U && + g->ops.func.get_full_phys_offset != NULL) { + g->func_regs = nvgpu_safe_add_u64(g->regs, + g->ops.func.get_full_phys_offset(g)); + g->func_regs_saved = g->func_regs; + } + return 0; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 3ee9188c4..1bf8c04c8 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2023, NVIDIA CORPORATION. All rights reserved. * * GK20A Graphics * @@ -401,9 +401,13 @@ struct gk20a { uintptr_t usermode_regs; u64 usermode_regs_bus_addr; + /** Starting virtual address of mapped func io region. */ + uintptr_t func_regs; + uintptr_t regs_saved; uintptr_t bar1_saved; uintptr_t usermode_regs_saved; + uintptr_t func_regs_saved; /** * Handle to access nvhost APIs. diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 63ee11042..8067ddccf 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -264,6 +264,7 @@ static int gk20a_restore_registers(struct gk20a *g) { g->regs = g->regs_saved; g->bar1 = g->bar1_saved; + g->func_regs = g->func_regs_saved; nvgpu_restore_usermode_registers(g);