diff --git a/arch/nvgpu-linux.yaml b/arch/nvgpu-linux.yaml
index dff9cbe94..098a644fa 100644
--- a/arch/nvgpu-linux.yaml
+++ b/arch/nvgpu-linux.yaml
@@ -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,
diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile
index 3d0339ac7..922cfe889 100644
--- a/drivers/gpu/nvgpu/Makefile
+++ b/drivers/gpu/nvgpu/Makefile
@@ -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) += \
diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources
index 7fb4b8ed1..c631e41f2 100644
--- a/drivers/gpu/nvgpu/Makefile.sources
+++ b/drivers/gpu/nvgpu/Makefile.sources
@@ -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
diff --git a/drivers/gpu/nvgpu/include/nvgpu/fuse.h b/drivers/gpu/nvgpu/include/nvgpu/fuse.h
index e52f77e8c..8d4c13d77 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/fuse.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/fuse.h
@@ -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 */
diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/soc_fuse.h b/drivers/gpu/nvgpu/include/nvgpu/linux/soc_fuse.h
new file mode 100644
index 000000000..01c480c4c
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/linux/soc_fuse.h
@@ -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 .
+ */
+
+#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 */
diff --git a/drivers/gpu/nvgpu/os/linux/fuse.c b/drivers/gpu/nvgpu/os/linux/fuse.c
index ca2748d19..ada735ee5 100644
--- a/drivers/gpu/nvgpu/os/linux/fuse.c
+++ b/drivers/gpu/nvgpu/os/linux/fuse.c
@@ -11,10 +11,12 @@
* more details.
*/
-#include
-
#include
+#include
+
+#include
+
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 */
diff --git a/drivers/gpu/nvgpu/os/posix/fuse.c b/drivers/gpu/nvgpu/os/posix/fuse.c
index c97d9eb02..9d78e2f13 100644
--- a/drivers/gpu/nvgpu/os/posix/fuse.c
+++ b/drivers/gpu/nvgpu/os/posix/fuse.c
@@ -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 */