diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b')
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/fuse_gm20b.c | 90 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/fuse_gm20b.h | 37 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/hal_gm20b.c | 22 |
3 files changed, 136 insertions, 13 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/fuse_gm20b.c b/drivers/gpu/nvgpu/gm20b/fuse_gm20b.c new file mode 100644 index 00000000..165d5b43 --- /dev/null +++ b/drivers/gpu/nvgpu/gm20b/fuse_gm20b.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * GM20B FUSE | ||
3 | * | ||
4 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | */ | ||
24 | |||
25 | #include <nvgpu/types.h> | ||
26 | #include <nvgpu/fuse.h> | ||
27 | #include <nvgpu/enabled.h> | ||
28 | |||
29 | #include "gk20a/gk20a.h" | ||
30 | |||
31 | #include "fuse_gm20b.h" | ||
32 | |||
33 | #include <nvgpu/hw/gm20b/hw_fuse_gm20b.h> | ||
34 | |||
35 | int gm20b_fuse_check_priv_security(struct gk20a *g) | ||
36 | { | ||
37 | u32 gcplex_config; | ||
38 | |||
39 | if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { | ||
40 | __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true); | ||
41 | __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false); | ||
42 | nvgpu_log(g, gpu_dbg_info, "priv sec is enabled in fmodel"); | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | if (nvgpu_tegra_fuse_read_gcplex_config_fuse(g, &gcplex_config)) { | ||
47 | nvgpu_err(g, "err reading gcplex config fuse, check fuse clk"); | ||
48 | return -EINVAL; | ||
49 | } | ||
50 | |||
51 | __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false); | ||
52 | |||
53 | if (gk20a_readl(g, fuse_opt_priv_sec_en_r())) { | ||
54 | /* | ||
55 | * all falcons have to boot in LS mode and this needs | ||
56 | * wpr_enabled set to 1 and vpr_auto_fetch_disable | ||
57 | * set to 0. In this case gmmu tries to pull wpr | ||
58 | * and vpr settings from tegra mc | ||
59 | */ | ||
60 | __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true); | ||
61 | if ((gcplex_config & | ||
62 | GCPLEX_CONFIG_WPR_ENABLED_MASK) && | ||
63 | !(gcplex_config & | ||
64 | GCPLEX_CONFIG_VPR_AUTO_FETCH_DISABLE_MASK)) { | ||
65 | if (gk20a_readl(g, fuse_opt_sec_debug_en_r())) | ||
66 | nvgpu_log(g, gpu_dbg_info, | ||
67 | "gcplex_config = 0x%08x, " | ||
68 | "secure mode: ACR debug", | ||
69 | gcplex_config); | ||
70 | else | ||
71 | nvgpu_log(g, gpu_dbg_info, | ||
72 | "gcplex_config = 0x%08x, " | ||
73 | "secure mode: ACR non debug", | ||
74 | gcplex_config); | ||
75 | } else { | ||
76 | nvgpu_err(g, "gcplex_config = 0x%08x " | ||
77 | "invalid wpr_enabled/vpr_auto_fetch_disable " | ||
78 | "with priv_sec_en", gcplex_config); | ||
79 | /* do not try to boot GPU */ | ||
80 | return -EINVAL; | ||
81 | } | ||
82 | } else { | ||
83 | __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, false); | ||
84 | nvgpu_log(g, gpu_dbg_info, | ||
85 | "gcplex_config = 0x%08x, non secure mode", | ||
86 | gcplex_config); | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
diff --git a/drivers/gpu/nvgpu/gm20b/fuse_gm20b.h b/drivers/gpu/nvgpu/gm20b/fuse_gm20b.h new file mode 100644 index 00000000..51734b2f --- /dev/null +++ b/drivers/gpu/nvgpu/gm20b/fuse_gm20b.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * GM20B FUSE | ||
3 | * | ||
4 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | */ | ||
24 | |||
25 | #ifndef _NVGPU_GM20B_FUSE | ||
26 | #define _NVGPU_GM20B_FUSE | ||
27 | |||
28 | #define GCPLEX_CONFIG_VPR_AUTO_FETCH_DISABLE_MASK ((u32)(1 << 0)) | ||
29 | #define GCPLEX_CONFIG_VPR_ENABLED_MASK ((u32)(1 << 1)) | ||
30 | #define GCPLEX_CONFIG_WPR_ENABLED_MASK ((u32)(1 << 2)) | ||
31 | |||
32 | |||
33 | struct gk20a; | ||
34 | |||
35 | int gm20b_fuse_check_priv_security(struct gk20a *g); | ||
36 | |||
37 | #endif | ||
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index bb18d2d7..779dde3d 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include "bus_gm20b.h" | 54 | #include "bus_gm20b.h" |
55 | #include "hal_gm20b.h" | 55 | #include "hal_gm20b.h" |
56 | #include "acr_gm20b.h" | 56 | #include "acr_gm20b.h" |
57 | #include "fuse_gm20b.h" | ||
57 | 58 | ||
58 | #include <nvgpu/debug.h> | 59 | #include <nvgpu/debug.h> |
59 | #include <nvgpu/bug.h> | 60 | #include <nvgpu/bug.h> |
@@ -582,6 +583,9 @@ static const struct gpu_ops gm20b_ops = { | |||
582 | .priv_ring = { | 583 | .priv_ring = { |
583 | .isr = gk20a_priv_ring_isr, | 584 | .isr = gk20a_priv_ring_isr, |
584 | }, | 585 | }, |
586 | .fuse = { | ||
587 | .check_priv_security = gm20b_fuse_check_priv_security, | ||
588 | }, | ||
585 | .chip_init_gpu_characteristics = gk20a_init_gpu_characteristics, | 589 | .chip_init_gpu_characteristics = gk20a_init_gpu_characteristics, |
586 | .get_litter_value = gm20b_get_litter_value, | 590 | .get_litter_value = gm20b_get_litter_value, |
587 | }; | 591 | }; |
@@ -589,7 +593,6 @@ static const struct gpu_ops gm20b_ops = { | |||
589 | int gm20b_init_hal(struct gk20a *g) | 593 | int gm20b_init_hal(struct gk20a *g) |
590 | { | 594 | { |
591 | struct gpu_ops *gops = &g->ops; | 595 | struct gpu_ops *gops = &g->ops; |
592 | u32 val; | ||
593 | 596 | ||
594 | gops->ltc = gm20b_ops.ltc; | 597 | gops->ltc = gm20b_ops.ltc; |
595 | gops->ce2 = gm20b_ops.ce2; | 598 | gops->ce2 = gm20b_ops.ce2; |
@@ -625,26 +628,19 @@ int gm20b_init_hal(struct gk20a *g) | |||
625 | 628 | ||
626 | gops->priv_ring = gm20b_ops.priv_ring; | 629 | gops->priv_ring = gm20b_ops.priv_ring; |
627 | 630 | ||
631 | gops->fuse = gm20b_ops.fuse; | ||
632 | |||
628 | /* Lone functions */ | 633 | /* Lone functions */ |
629 | gops->chip_init_gpu_characteristics = | 634 | gops->chip_init_gpu_characteristics = |
630 | gm20b_ops.chip_init_gpu_characteristics; | 635 | gm20b_ops.chip_init_gpu_characteristics; |
631 | gops->get_litter_value = gm20b_ops.get_litter_value; | 636 | gops->get_litter_value = gm20b_ops.get_litter_value; |
632 | 637 | ||
633 | __nvgpu_set_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP, true); | 638 | __nvgpu_set_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP, true); |
634 | __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false); | ||
635 | __nvgpu_set_enabled(g, NVGPU_PMU_PSTATE, false); | 639 | __nvgpu_set_enabled(g, NVGPU_PMU_PSTATE, false); |
636 | 640 | ||
637 | if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { | 641 | /* Read fuses to check if gpu needs to boot in secure/non-secure mode */ |
638 | __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true); | 642 | if (gops->fuse.check_priv_security(g)) |
639 | } else { | 643 | return -EINVAL; /* Do not boot gpu */ |
640 | val = gk20a_readl(g, fuse_opt_priv_sec_en_r()); | ||
641 | if (!val) { | ||
642 | gk20a_dbg_info("priv security is disabled in HW"); | ||
643 | __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, false); | ||
644 | } else { | ||
645 | __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true); | ||
646 | } | ||
647 | } | ||
648 | 644 | ||
649 | /* priv security dependent ops */ | 645 | /* priv security dependent ops */ |
650 | if (nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { | 646 | if (nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { |