diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm206/pmu_gm206.c | 158 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm206/pmu_gm206.h | 22 |
3 files changed, 184 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 9d9dbb4b..b60d1b71 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | |||
@@ -3367,6 +3367,10 @@ static u8 get_perfmon_id(struct pmu_gk20a *pmu) | |||
3367 | unit_id = PMU_UNIT_PERFMON_T18X; | 3367 | unit_id = PMU_UNIT_PERFMON_T18X; |
3368 | break; | 3368 | break; |
3369 | #endif | 3369 | #endif |
3370 | case GK20A_GPUID_GM206: | ||
3371 | case GK20A_GPUID_GM204: | ||
3372 | unit_id = PMU_UNIT_PERFMON_T18X; | ||
3373 | break; | ||
3370 | default: | 3374 | default: |
3371 | gk20a_err(g->dev, "no support for %x", ver); | 3375 | gk20a_err(g->dev, "no support for %x", ver); |
3372 | BUG(); | 3376 | BUG(); |
diff --git a/drivers/gpu/nvgpu/gm206/pmu_gm206.c b/drivers/gpu/nvgpu/gm206/pmu_gm206.c new file mode 100644 index 00000000..e0ae06ea --- /dev/null +++ b/drivers/gpu/nvgpu/gm206/pmu_gm206.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> /* for udelay */ | ||
15 | #include "gk20a/gk20a.h" | ||
16 | #include "gk20a/pmu_gk20a.h" | ||
17 | #include "gk20a/pmu_gk20a.h" | ||
18 | #include "gm20b/acr_gm20b.h" | ||
19 | #include "gm206/acr_gm206.h" | ||
20 | #include "gm20b/pmu_gm20b.h" | ||
21 | #include "gm206/pmu_gm206.h" | ||
22 | #include "hw_gr_gm206.h" | ||
23 | #include "hw_pwr_gm206.h" | ||
24 | |||
25 | |||
26 | #define gm206_dbg_pmu(fmt, arg...) \ | ||
27 | gk20a_dbg(gpu_dbg_pmu, fmt, ##arg) | ||
28 | |||
29 | bool gm206_is_lazy_bootstrap(u32 falcon_id) | ||
30 | { | ||
31 | bool enable_status = false; | ||
32 | |||
33 | switch (falcon_id) { | ||
34 | case LSF_FALCON_ID_FECS: | ||
35 | enable_status = true; | ||
36 | break; | ||
37 | case LSF_FALCON_ID_GPCCS: | ||
38 | enable_status = true; | ||
39 | break; | ||
40 | default: | ||
41 | break; | ||
42 | } | ||
43 | |||
44 | return enable_status; | ||
45 | } | ||
46 | |||
47 | bool gm206_is_priv_load(u32 falcon_id) | ||
48 | { | ||
49 | bool enable_status = false; | ||
50 | |||
51 | switch (falcon_id) { | ||
52 | case LSF_FALCON_ID_FECS: | ||
53 | enable_status = true; | ||
54 | break; | ||
55 | case LSF_FALCON_ID_GPCCS: | ||
56 | enable_status = true; | ||
57 | break; | ||
58 | default: | ||
59 | break; | ||
60 | } | ||
61 | |||
62 | return enable_status; | ||
63 | } | ||
64 | |||
65 | static void gm206_pmu_load_multiple_falcons(struct gk20a *g, u32 falconidmask, | ||
66 | u32 flags) | ||
67 | { | ||
68 | struct pmu_gk20a *pmu = &g->pmu; | ||
69 | struct pmu_cmd cmd; | ||
70 | u32 seq; | ||
71 | |||
72 | gk20a_dbg_fn(""); | ||
73 | |||
74 | gm206_dbg_pmu("wprinit status = %x\n", g->ops.pmu.lspmuwprinitdone); | ||
75 | if (g->ops.pmu.lspmuwprinitdone) { | ||
76 | /* send message to load FECS falcon */ | ||
77 | memset(&cmd, 0, sizeof(struct pmu_cmd)); | ||
78 | cmd.hdr.unit_id = PMU_UNIT_ACR; | ||
79 | cmd.hdr.size = PMU_CMD_HDR_SIZE + | ||
80 | sizeof(struct pmu_acr_cmd_bootstrap_multiple_falcons); | ||
81 | cmd.cmd.acr.boot_falcons.cmd_type = | ||
82 | PMU_ACR_CMD_ID_BOOTSTRAP_MULTIPLE_FALCONS; | ||
83 | cmd.cmd.acr.boot_falcons.flags = flags; | ||
84 | cmd.cmd.acr.boot_falcons.falconidmask = | ||
85 | falconidmask; | ||
86 | cmd.cmd.acr.boot_falcons.usevamask = 0; | ||
87 | cmd.cmd.acr.boot_falcons.wprvirtualbase.lo = 0; | ||
88 | cmd.cmd.acr.boot_falcons.wprvirtualbase.hi = 0; | ||
89 | |||
90 | gm206_dbg_pmu("PMU_ACR_CMD_ID_BOOTSTRAP_MULTIPLE_FALCONS:%x\n", | ||
91 | falconidmask); | ||
92 | gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ, | ||
93 | pmu_handle_fecs_boot_acr_msg, pmu, &seq, ~0); | ||
94 | } | ||
95 | |||
96 | gk20a_dbg_fn("done"); | ||
97 | } | ||
98 | |||
99 | int gm206_load_falcon_ucode(struct gk20a *g, u32 falconidmask) | ||
100 | { | ||
101 | u32 flags = PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES; | ||
102 | |||
103 | /* GM20B PMU supports loading FECS and GPCCS only */ | ||
104 | if (falconidmask == 0) | ||
105 | return -EINVAL; | ||
106 | if (falconidmask & ~((1 << LSF_FALCON_ID_FECS) | | ||
107 | (1 << LSF_FALCON_ID_GPCCS))) | ||
108 | return -EINVAL; | ||
109 | g->ops.pmu.lsfloadedfalconid = 0; | ||
110 | /* check whether pmu is ready to bootstrap lsf if not wait for it */ | ||
111 | if (!g->ops.pmu.lspmuwprinitdone) { | ||
112 | pmu_wait_message_cond(&g->pmu, | ||
113 | gk20a_get_gr_idle_timeout(g), | ||
114 | &g->ops.pmu.lspmuwprinitdone, 1); | ||
115 | /* check again if it still not ready indicate an error */ | ||
116 | if (!g->ops.pmu.lspmuwprinitdone) { | ||
117 | gk20a_err(dev_from_gk20a(g), | ||
118 | "PMU not ready to load LSF"); | ||
119 | return -ETIMEDOUT; | ||
120 | } | ||
121 | } | ||
122 | /* load falcon(s) */ | ||
123 | gm206_pmu_load_multiple_falcons(g, falconidmask, flags); | ||
124 | pmu_wait_message_cond(&g->pmu, | ||
125 | gk20a_get_gr_idle_timeout(g), | ||
126 | &g->ops.pmu.lsfloadedfalconid, falconidmask); | ||
127 | if (g->ops.pmu.lsfloadedfalconid != falconidmask) | ||
128 | return -ETIMEDOUT; | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | |||
133 | void gm206_init_pmu_ops(struct gpu_ops *gops) | ||
134 | { | ||
135 | if (gops->privsecurity) { | ||
136 | gm206_init_secure_pmu(gops); | ||
137 | gops->pmu.init_wpr_region = gm20b_pmu_init_acr; | ||
138 | gops->pmu.load_lsfalcon_ucode = gm206_load_falcon_ucode; | ||
139 | gops->pmu.is_lazy_bootstrap = gm206_is_lazy_bootstrap; | ||
140 | gops->pmu.is_priv_load = gm206_is_priv_load; | ||
141 | } else { | ||
142 | gk20a_init_pmu_ops(gops); | ||
143 | gops->pmu.pmu_setup_hw_and_bootstrap = | ||
144 | gm20b_init_nspmu_setup_hw1; | ||
145 | gops->pmu.load_lsfalcon_ucode = NULL; | ||
146 | gops->pmu.init_wpr_region = NULL; | ||
147 | } | ||
148 | gops->pmu.pmu_setup_elpg = NULL; | ||
149 | gops->pmu.lspmuwprinitdone = 0; | ||
150 | gops->pmu.fecsbootstrapdone = false; | ||
151 | gops->pmu.write_dmatrfbase = gm20b_write_dmatrfbase; | ||
152 | gops->pmu.pmu_elpg_statistics = NULL; | ||
153 | gops->pmu.pmu_pg_grinit_param = NULL; | ||
154 | gops->pmu.send_lrf_tex_ltc_dram_overide_en_dis_cmd = NULL; | ||
155 | gops->pmu.dump_secure_fuses = NULL; | ||
156 | gops->pmu.reset = gk20a_pmu_reset; | ||
157 | } | ||
158 | |||
diff --git a/drivers/gpu/nvgpu/gm206/pmu_gm206.h b/drivers/gpu/nvgpu/gm206/pmu_gm206.h new file mode 100644 index 00000000..418f30ac --- /dev/null +++ b/drivers/gpu/nvgpu/gm206/pmu_gm206.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef __PMU_GM206_H_ | ||
15 | #define __PMU_GM206_H_ | ||
16 | |||
17 | void gm206_init_pmu_ops(struct gpu_ops *gops); | ||
18 | bool gm206_is_priv_load(u32 falcon_id); | ||
19 | bool gm206_is_lazy_bootstrap(u32 falcon_id); | ||
20 | int gm206_load_falcon_ucode(struct gk20a *g, u32 falconidmask); | ||
21 | |||
22 | #endif /*__PMU_GM206_H_*/ | ||