diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/module.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index 2e90fbe4..6b27c9f1 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/reset.h> | 25 | #include <linux/reset.h> |
26 | #include <linux/platform/tegra/common.h> | 26 | #include <linux/platform/tegra/common.h> |
27 | #include <uapi/linux/nvgpu.h> | 27 | #include <uapi/linux/nvgpu.h> |
28 | #include <dt-bindings/soc/gm20b-fuse.h> | ||
29 | #include <dt-bindings/soc/gp10b-fuse.h> | ||
28 | 30 | ||
29 | #include <nvgpu/dma.h> | 31 | #include <nvgpu/dma.h> |
30 | #include <nvgpu/kmem.h> | 32 | #include <nvgpu/kmem.h> |
@@ -994,6 +996,48 @@ static inline void set_gk20a(struct platform_device *pdev, struct gk20a *gk20a) | |||
994 | gk20a_get_platform(&pdev->dev)->g = gk20a; | 996 | gk20a_get_platform(&pdev->dev)->g = gk20a; |
995 | } | 997 | } |
996 | 998 | ||
999 | static int nvgpu_read_fuse_overrides(struct gk20a *g) | ||
1000 | { | ||
1001 | struct device_node *np = dev_from_gk20a(g)->of_node; | ||
1002 | u32 *fuses; | ||
1003 | int count, i; | ||
1004 | |||
1005 | if (!np) /* may be pcie device */ | ||
1006 | return 0; | ||
1007 | |||
1008 | count = of_property_count_elems_of_size(np, "fuse-overrides", 8); | ||
1009 | if (count <= 0) | ||
1010 | return count; | ||
1011 | |||
1012 | fuses = nvgpu_kmalloc(g, sizeof(u32) * count * 2); | ||
1013 | if (!fuses) | ||
1014 | return -ENOMEM; | ||
1015 | of_property_read_u32_array(np, "fuse-overrides", fuses, count * 2); | ||
1016 | for (i = 0; i < count; i++) { | ||
1017 | u32 fuse, value; | ||
1018 | |||
1019 | fuse = fuses[2 * i]; | ||
1020 | value = fuses[2 * i + 1]; | ||
1021 | switch (fuse) { | ||
1022 | case GM20B_FUSE_OPT_TPC_DISABLE: | ||
1023 | g->tpc_fs_mask_user = ~value; | ||
1024 | break; | ||
1025 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | ||
1026 | case GP10B_FUSE_OPT_ECC_EN: | ||
1027 | g->gr.t18x.fecs_feature_override_ecc_val = value; | ||
1028 | break; | ||
1029 | #endif | ||
1030 | default: | ||
1031 | nvgpu_err(g, "ignore unknown fuse override %08x", fuse); | ||
1032 | break; | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | nvgpu_kfree(g, fuses); | ||
1037 | |||
1038 | return 0; | ||
1039 | } | ||
1040 | |||
997 | static int gk20a_probe(struct platform_device *dev) | 1041 | static int gk20a_probe(struct platform_device *dev) |
998 | { | 1042 | { |
999 | struct nvgpu_os_linux *l; | 1043 | struct nvgpu_os_linux *l; |
@@ -1077,6 +1121,8 @@ static int gk20a_probe(struct platform_device *dev) | |||
1077 | if (err) | 1121 | if (err) |
1078 | return err; | 1122 | return err; |
1079 | 1123 | ||
1124 | err = nvgpu_read_fuse_overrides(gk20a); | ||
1125 | |||
1080 | #ifdef CONFIG_RESET_CONTROLLER | 1126 | #ifdef CONFIG_RESET_CONTROLLER |
1081 | platform->reset_control = devm_reset_control_get(&dev->dev, NULL); | 1127 | platform->reset_control = devm_reset_control_get(&dev->dev, NULL); |
1082 | if (IS_ERR(platform->reset_control)) | 1128 | if (IS_ERR(platform->reset_control)) |