gpu: nvgpu: separate tegra fuse read from under CONFIG_NVGPU_TEGRA_FUSE

tegra_fuse_readl is supported in upstream. Separate out the functions
using this API from the config CONFIG_NVGPU_TEGRA_FUSE.

Following four fuses are defined in downstream kernel repositories in
tegra fuse header. It can be incorporated in upstream if nvgpu starts
reading those fuses using nvmem APIs. Hence define those fuse offsets
in nvgpu itself for now.

1. FUSE_RESERVED_CALIB0_0
2. FUSE_GCPLEX_CONFIG_FUSE_0
3. FUSE_PDI0
4. FUSE_PDI1

Bug 200625647

Change-Id: I8da8c0c3a0682fdab806fa57035fedd29ef22c26
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2369955
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com>
Reviewed-by: Jonathan Hunter <jonathanh@nvidia.com>
Reviewed-by: Sami Kiminki <skiminki@nvidia.com>
Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com>
Reviewed-by: Debarshi Dutta <ddutta@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Sagar Kamble
2020-07-02 18:01:31 +05:30
committed by Alex Waterman
parent 04a179a161
commit b117f40f6c
7 changed files with 152 additions and 135 deletions

View File

@@ -238,6 +238,7 @@ headers:
include/nvgpu/linux/rwsem.h,
include/nvgpu/linux/sim.h,
include/nvgpu/linux/sim_pci.h,
include/nvgpu/linux/soc_fuse.h,
include/nvgpu/linux/thread.h,
include/nvgpu/linux/log.h,
include/nvgpu/linux/utils.h,

View File

@@ -430,8 +430,8 @@ nvgpu-$(CONFIG_DEBUG_FS) += \
os/linux/debug_fecs_trace.o
endif
nvgpu-$(CONFIG_TEGRA_GK20A) += \
os/linux/fuse.o \
os/linux/module.o \
os/linux/module_usermode.o \
os/linux/platform_gk20a_tegra.o \
@@ -439,8 +439,7 @@ nvgpu-$(CONFIG_TEGRA_GK20A) += \
os/linux/platform_gv11b_tegra.o
ifeq ($(CONFIG_TEGRA_GK20A),y)
nvgpu-$(CONFIG_NVGPU_TEGRA_FUSE) += os/linux/fuse.o \
os/linux/soc.o
nvgpu-$(CONFIG_NVGPU_TEGRA_FUSE) += os/linux/soc.o
endif
nvgpu-$(CONFIG_NVGPU_SYNCFD_ANDROID) += \

View File

@@ -37,16 +37,13 @@ srcs += os/posix/nvgpu.c \
os/posix/stubs.c \
os/posix/posix-nvhost.c \
os/posix/posix-vgpu.c \
os/posix/posix-dt.c
os/posix/posix-dt.c \
os/posix/fuse.c
ifdef CONFIG_NVGPU_VPR
srcs += os/posix/posix-vpr.c
endif
ifdef CONFIG_NVGPU_TEGRA_FUSE
srcs += os/posix/fuse.c
endif
ifdef CONFIG_NVGPU_FECS_TRACE
srcs += os/posix/fecs_trace_posix.c
endif

View File

@@ -36,13 +36,38 @@ struct gk20a;
#include "include/nvgpu/nvgpu_next_fuse.h"
#endif
#ifdef CONFIG_NVGPU_TEGRA_FUSE
#ifdef CONFIG_NVGPU_NON_FUSA
int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g, int *id);
int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val);
#endif /* CONFIG_NVGPU_NON_FUSA */
/**
* @brief - Reads GCPLEX_CONFIG_FUSE configuration.
*
* @param g [in] - GPU super structure.
* @param val [out] - Populated with register GCPLEX_CONFIG_FUSE value.
*
* - Provide information about the GPU complex configuration.
*
* @return 0 on success.
*
*/
int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val);
/**
* @brief - Reads the per-device identifier fuses.
*
* @param g [in] - GPU super structure.
* @param pdi [out] - Per-device identifier
*
* The per-device identifier fuses are FUSE_PDI0 and FUSE_PDI1.
*
* @return 0 on success
*/
int nvgpu_tegra_fuse_read_per_device_identifier(struct gk20a *g, u64 *pdi);
#ifdef CONFIG_NVGPU_TEGRA_FUSE
/**
* @brief - Write Fuse bypass register which controls fuse bypass.
*
@@ -92,46 +117,8 @@ void nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(struct gk20a *g, u32 val);
*/
void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g, u32 val);
/**
* @brief - Reads GCPLEX_CONFIG_FUSE configuration.
*
* @param g [in] - GPU super structure.
* @param val [out] - Populated with register GCPLEX_CONFIG_FUSE value.
*
* - Provide information about the GPU complex configuration.
*
* @return 0 on success.
*
*/
int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val);
/**
* @brief - Reads the per-device identifier fuses.
*
* @param g [in] - GPU super structure.
* @param pdi [out] - Per-device identifier
*
* The per-device identifier fuses are FUSE_PDI0 and FUSE_PDI1.
*
* @return 0 on success
*/
int nvgpu_tegra_fuse_read_per_device_identifier(struct gk20a *g, u64 *pdi);
#else /* CONFIG_NVGPU_TEGRA_FUSE */
#ifdef CONFIG_NVGPU_NON_FUSA
static inline int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g, int *id)
{
return -EINVAL;
}
static inline int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g,
u32 *val)
{
return -EINVAL;
}
#endif /* CONFIG_NVGPU_NON_FUSA */
static inline void nvgpu_tegra_fuse_write_bypass(struct gk20a *g, u32 val)
{
}
@@ -150,24 +137,6 @@ static inline void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g,
{
}
static inline int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g,
u32 *val)
{
/*
* Setting gcplex_config fuse to wpr_enabled/vpr_auto_fetch_disable
* by default that is expected on the production chip.
*/
*val = 0x4;
return 0;
}
static inline int nvgpu_tegra_fuse_read_per_device_identifier(struct gk20a *g, u64 *pdi)
{
*pdi = 0U;
return 0;
}
#endif /* CONFIG_NVGPU_TEGRA_FUSE */
#endif /* NVGPU_FUSE_H */

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2020, 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NVGPU_LINUX_SOC_FUSE_H
#define NVGPU_LINUX_SOC_FUSE_H
/*
* Note: Following defines should be ideally in tegra fuse driver. They are
* defined here since nvgpu uses the tegra_fuse_readl API directly to read
* those fuses. Once nvgpu starts using nvmem API to read these fuses,
* these offsets can be defined in tegra fuse driver.
* See Bug 200633045.
*/
#ifndef FUSE_GCPLEX_CONFIG_FUSE_0
#define FUSE_GCPLEX_CONFIG_FUSE_0 0x1c8
#endif
#ifndef FUSE_RESERVED_CALIB0_0
#define FUSE_RESERVED_CALIB0_0 0x204
#endif
/* T186+ */
#if !defined(FUSE_PDI0) && !defined(FUSE_PDI1)
#define FUSE_PDI0 0x300
#define FUSE_PDI1 0x304
#endif
#endif /* NVGPU_LINUX_SOC_FUSE_H */

View File

@@ -11,10 +11,12 @@
* more details.
*/
#include <soc/tegra/fuse.h>
#include <nvgpu/fuse.h>
#include <nvgpu/linux/soc_fuse.h>
#include <soc/tegra/fuse.h>
int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g, int *id)
{
*id = tegra_sku_info.gpu_speedo_id;
@@ -22,6 +24,37 @@ int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g, int *id)
return 0;
}
int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val)
{
return tegra_fuse_readl(FUSE_RESERVED_CALIB0_0, val);
}
int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val)
{
return tegra_fuse_readl(FUSE_GCPLEX_CONFIG_FUSE_0, val);
}
int nvgpu_tegra_fuse_read_per_device_identifier(struct gk20a *g, u64 *pdi)
{
u32 lo = 0U;
u32 hi = 0U;
int err;
err = tegra_fuse_readl(FUSE_PDI0, &lo);
if (err)
return err;
err = tegra_fuse_readl(FUSE_PDI1, &hi);
if (err)
return err;
*pdi = ((u64)lo) | (((u64)hi) << 32);
return 0;
}
#ifdef CONFIG_NVGPU_TEGRA_FUSE
/*
* Use tegra_fuse_control_read/write() APIs for fuse offsets upto 0x100
* Use tegra_fuse_readl/writel() APIs for fuse offsets above 0x100
@@ -46,31 +79,4 @@ void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g, u32 val)
tegra_fuse_writel(val, FUSE_OPT_GPU_TPC1_DISABLE_0);
}
int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val)
{
return tegra_fuse_readl(FUSE_GCPLEX_CONFIG_FUSE_0, val);
}
int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val)
{
return tegra_fuse_readl(FUSE_RESERVED_CALIB0_0, val);
}
int nvgpu_tegra_fuse_read_per_device_identifier(struct gk20a *g, u64 *pdi)
{
u32 lo = 0U;
u32 hi = 0U;
int err;
err = tegra_fuse_readl(FUSE_PDI0, &lo);
if (err)
return err;
err = tegra_fuse_readl(FUSE_PDI1, &hi);
if (err)
return err;
*pdi = ((u64)lo) | (((u64)hi) << 32);
return 0;
}
#endif /* CONFIG_NVGPU_TEGRA_FUSE */

View File

@@ -33,8 +33,48 @@ int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g, int *id)
{
return 0;
}
int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val)
{
struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g);
if (p->callbacks == NULL || p->callbacks->tegra_fuse_readl == NULL) {
return -ENODEV;
}
return p->callbacks->tegra_fuse_readl(FUSE_RESERVED_CALIB0_0, val);
}
#endif
int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val)
{
struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g);
if (p->callbacks == NULL || p->callbacks->tegra_fuse_readl == NULL) {
/*
* Generally for nvgpu, if priv_sec is enabled, we are expecting
* WPR to be enabled and auto fetching of VPR to _not_ be
* disabled (in other words VPR autofetch to be enabled - cause
* that's not confusing at all).
*/
*val = GCPLEX_CONFIG_WPR_ENABLED_MASK;
return 0;
}
return p->callbacks->tegra_fuse_readl(FUSE_GCPLEX_CONFIG_FUSE_0, val);
}
int nvgpu_tegra_fuse_read_per_device_identifier(struct gk20a *g, u64 *pdi)
{
*pdi = 0;
return 0;
}
#ifdef CONFIG_NVGPU_TEGRA_FUSE
/*
* Use tegra_fuse_control_read/write() APIs for fuse offsets upto 0x100
* Use tegra_fuse_readl/writel() APIs for fuse offsets above 0x100
@@ -84,41 +124,4 @@ void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g, u32 val)
return p->callbacks->tegra_fuse_writel(val, FUSE_OPT_GPU_TPC1_DISABLE_0);
}
int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val)
{
struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g);
if (p->callbacks == NULL || p->callbacks->tegra_fuse_readl == NULL) {
/*
* Generally for nvgpu, if priv_sec is enabled, we are expecting
* WPR to be enabled and auto fetching of VPR to _not_ be
* disabled (in other words VPR autofetch to be enabled - cause
* that's not confusing at all).
*/
*val = GCPLEX_CONFIG_WPR_ENABLED_MASK;
return 0;
}
return p->callbacks->tegra_fuse_readl(FUSE_GCPLEX_CONFIG_FUSE_0, val);
}
#ifdef CONFIG_NVGPU_NON_FUSA
int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val)
{
struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g);
if (p->callbacks == NULL || p->callbacks->tegra_fuse_readl == NULL) {
return -ENODEV;
}
return p->callbacks->tegra_fuse_readl(FUSE_RESERVED_CALIB0_0, val);
}
#endif
int nvgpu_tegra_fuse_read_per_device_identifier(struct gk20a *g, u64 *pdi)
{
*pdi = 0;
return 0;
}
#endif /* CONFIG_NVGPU_TEGRA_FUSE */