summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp106/pmu_gp106.c
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2016-06-08 07:59:48 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:17 -0500
commitee6be7beca896e8fbb324c164c6382fe8d695971 (patch)
tree4fa73764117cfb63bc7ed475ca4462451501f07e /drivers/gpu/nvgpu/gp106/pmu_gp106.c
parent6ed3cffb73488b22d671c88d30061cd045417378 (diff)
gpu: nvgpu: PMU/SEC2 reset sequence & OPS update
- Enable OPS to support secure boot - PMU/SEC2 reset sequence change for GP104/GP106 JIRA DNVGPU-34 Change-Id: I583a6af1d5354649c3df9d9b4d74141d52d6ca9d Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1161132 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gp106/pmu_gp106.c')
-rw-r--r--drivers/gpu/nvgpu/gp106/pmu_gp106.c165
1 files changed, 159 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gp106/pmu_gp106.c b/drivers/gpu/nvgpu/gp106/pmu_gp106.c
index 42ed85ec..be3e8c64 100644
--- a/drivers/gpu/nvgpu/gp106/pmu_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/pmu_gp106.c
@@ -15,32 +15,185 @@
15#include "gk20a/gk20a.h" 15#include "gk20a/gk20a.h"
16#include "gk20a/pmu_gk20a.h" 16#include "gk20a/pmu_gk20a.h"
17 17
18#include "gm206/pmu_gm206.h"
19#include "gm20b/pmu_gm20b.h"
18#include "gp10b/pmu_gp10b.h" 20#include "gp10b/pmu_gp10b.h"
21#include "gp106/pmu_gp106.h"
22#include "gp106/acr_gp106.h"
23#include "gp106/hw_psec_gp106.h"
19#include "hw_mc_gp106.h" 24#include "hw_mc_gp106.h"
20#include "hw_pwr_gp106.h" 25#include "hw_pwr_gp106.h"
21 26
22static int gp106_pmu_reset(struct gk20a *g) 27#define PMU_MEM_SCRUBBING_TIMEOUT_MAX 1000
28#define PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT 10
29
30int gp106_pmu_enable_hw(struct pmu_gk20a *pmu, bool enable)
23{ 31{
32 struct gk20a *g = gk20a_from_pmu(pmu);
33
24 gk20a_dbg_fn(""); 34 gk20a_dbg_fn("");
25 35
26 gk20a_reset(g, mc_enable_pwr_enabled_f()); 36 /*
37 * From GP10X onwards, we are using PPWR_FALCON_ENGINE for reset. And as
38 * it may come into same behaviour, reading NV_PPWR_FALCON_ENGINE again
39 * after Reset.
40 */
41
42 if (enable) {
43 int retries = PMU_MEM_SCRUBBING_TIMEOUT_MAX /
44 PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT;
45 gk20a_writel(g, pwr_falcon_engine_r(),
46 pwr_falcon_engine_reset_false_f());
47 gk20a_readl(g, pwr_falcon_engine_r());
48
49 /* make sure ELPG is in a good state */
50 if (g->ops.clock_gating.slcg_pmu_load_gating_prod)
51 g->ops.clock_gating.slcg_pmu_load_gating_prod(g,
52 g->slcg_enabled);
53 if (g->ops.clock_gating.blcg_pmu_load_gating_prod)
54 g->ops.clock_gating.blcg_pmu_load_gating_prod(g,
55 g->blcg_enabled);
56
57 /* wait for Scrubbing to complete */
58 do {
59 u32 w = gk20a_readl(g, pwr_falcon_dmactl_r()) &
60 (pwr_falcon_dmactl_dmem_scrubbing_m() |
61 pwr_falcon_dmactl_imem_scrubbing_m());
27 62
28 gk20a_writel(g, pwr_falcon_engine_r(), 63 if (!w) {
64 gk20a_dbg_fn("done");
65 return 0;
66 }
67 udelay(PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT);
68 } while (--retries || !tegra_platform_is_silicon());
69
70 /* If scrubbing timeout, keep PMU in reset state */
71 gk20a_writel(g, pwr_falcon_engine_r(),
72 pwr_falcon_engine_reset_true_f());
73 gk20a_readl(g, pwr_falcon_engine_r());
74 gk20a_err(dev_from_gk20a(g), "Falcon mem scrubbing timeout");
75 return -ETIMEDOUT;
76 } else {
77 /* DISBALE */
78 gk20a_writel(g, pwr_falcon_engine_r(),
79 pwr_falcon_engine_reset_true_f());
80 gk20a_readl(g, pwr_falcon_engine_r());
81 return 0;
82 }
83}
84
85static int pmu_enable(struct pmu_gk20a *pmu, bool enable)
86{
87 struct gk20a *g = gk20a_from_pmu(pmu);
88 u32 reg_reset;
89 int err;
90
91 gk20a_dbg_fn("");
92
93 if (!enable) {
94 reg_reset = gk20a_readl(g, pwr_falcon_engine_r());
95 if (reg_reset !=
96 pwr_falcon_engine_reset_true_f()) {
97
98 pmu_enable_irq(pmu, false);
99 gp106_pmu_enable_hw(pmu, false);
100 udelay(10);
101 }
102 } else {
103 gp106_pmu_enable_hw(pmu, true);
104 /* TBD: post reset */
105
106 /*idle the PMU and enable interrupts on the Falcon*/
107 err = pmu_idle(pmu);
108 if (err)
109 return err;
110 udelay(5);
111 pmu_enable_irq(pmu, true);
112 }
113
114 gk20a_dbg_fn("done");
115 return 0;
116}
117
118int gp106_pmu_reset(struct gk20a *g)
119{
120 struct pmu_gk20a *pmu = &g->pmu;
121 int err = 0;
122
123 gk20a_dbg_fn("");
124
125 err = pmu_idle(pmu);
126 if (err)
127 return err;
128
129 /* TBD: release pmu hw mutex */
130
131 err = pmu_enable(pmu, false);
132 if (err)
133 return err;
134
135 /* TBD: cancel all sequences */
136 /* TBD: init all sequences and state tables */
137 /* TBD: restore pre-init message handler */
138
139 err = pmu_enable(pmu, true);
140 if (err)
141 return err;
142
143 return err;
144}
145
146int gp106_sec2_reset(struct gk20a *g)
147{
148 gk20a_dbg_fn("");
149 //sec2 reset
150 gk20a_writel(g, psec_falcon_engine_r(),
29 pwr_falcon_engine_reset_true_f()); 151 pwr_falcon_engine_reset_true_f());
30 udelay(10); 152 udelay(10);
31 gk20a_writel(g, pwr_falcon_engine_r(), 153 gk20a_writel(g, psec_falcon_engine_r(),
32 pwr_falcon_engine_reset_false_f()); 154 pwr_falcon_engine_reset_false_f());
33 155
34 gk20a_dbg_fn("done"); 156 gk20a_dbg_fn("done");
35 return 0; 157 return 0;
36} 158}
37 159
160static int gp106_falcon_reset(struct gk20a *g)
161{
162 gk20a_dbg_fn("");
163
164 gp106_pmu_reset(g);
165 gp106_sec2_reset(g);
166
167 gk20a_dbg_fn("done");
168 return 0;
169}
170
38void gp106_init_pmu_ops(struct gpu_ops *gops) 171void gp106_init_pmu_ops(struct gpu_ops *gops)
39{ 172{
40 gk20a_dbg_fn(""); 173 gk20a_dbg_fn("");
41 174
42 gp10b_init_pmu_ops(gops); 175 if (gops->privsecurity) {
43 gops->pmu.reset = gp106_pmu_reset; 176 gp106_init_secure_pmu(gops);
177 gops->pmu.init_wpr_region = gm20b_pmu_init_acr;
178 gops->pmu.load_lsfalcon_ucode = gm206_load_falcon_ucode;
179 gops->pmu.is_lazy_bootstrap = gm206_is_lazy_bootstrap;
180 gops->pmu.is_priv_load = gm206_is_priv_load;
181 } else {
182 gk20a_init_pmu_ops(gops);
183 gops->pmu.pmu_setup_hw_and_bootstrap =
184 gm20b_init_nspmu_setup_hw1;
185 gops->pmu.load_lsfalcon_ucode = NULL;
186 gops->pmu.init_wpr_region = NULL;
187 }
188 gops->pmu.pmu_setup_elpg = NULL;
189 gops->pmu.lspmuwprinitdone = 0;
190 gops->pmu.fecsbootstrapdone = false;
191 gops->pmu.write_dmatrfbase = gp10b_write_dmatrfbase;
192 gops->pmu.pmu_elpg_statistics = NULL;
193 gops->pmu.pmu_pg_grinit_param = NULL;
194 gops->pmu.send_lrf_tex_ltc_dram_overide_en_dis_cmd = NULL;
195 gops->pmu.dump_secure_fuses = NULL;
196 gops->pmu.reset = gp106_falcon_reset;
44 197
45 gk20a_dbg_fn("done"); 198 gk20a_dbg_fn("done");
46} 199}