diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2018-07-02 17:30:26 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-07-12 23:44:13 -0400 |
commit | b97bcb3c689426a1b099e88ceef4d55584e2362b (patch) | |
tree | 4ad683912a323eca81a493314db3d74b46b6aa71 /drivers/gpu/nvgpu/common/fb/fb_gv100.c | |
parent | b07a304ba3e747c80fe3e0a16caec88c8e1e8b28 (diff) |
gpu: nvgpu: Move FB to common
Move all FB HAL implementations to common/fb.
JIRA NVGPU-596
Change-Id: Id4ea09d608f5d6d1b245bddac09ecf1444b8ab30
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1769724
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/fb/fb_gv100.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/fb/fb_gv100.c | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/fb/fb_gv100.c b/drivers/gpu/nvgpu/common/fb/fb_gv100.c new file mode 100644 index 00000000..155c1e8b --- /dev/null +++ b/drivers/gpu/nvgpu/common/fb/fb_gv100.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * GV100 FB | ||
3 | * | ||
4 | * Copyright (c) 2017-2018, 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 | |||
27 | #include <nvgpu/dma.h> | ||
28 | #include <nvgpu/log.h> | ||
29 | #include <nvgpu/enabled.h> | ||
30 | #include <nvgpu/gmmu.h> | ||
31 | #include <nvgpu/nvgpu_common.h> | ||
32 | #include <nvgpu/kmem.h> | ||
33 | #include <nvgpu/nvgpu_mem.h> | ||
34 | #include <nvgpu/acr/nvgpu_acr.h> | ||
35 | #include <nvgpu/firmware.h> | ||
36 | #include <nvgpu/pmu.h> | ||
37 | #include <nvgpu/falcon.h> | ||
38 | |||
39 | #include "gk20a/gk20a.h" | ||
40 | #include "gm20b/acr_gm20b.h" | ||
41 | |||
42 | #include "fb_gv100.h" | ||
43 | |||
44 | #include <nvgpu/hw/gv100/hw_fb_gv100.h> | ||
45 | #include <nvgpu/hw/gv100/hw_falcon_gv100.h> | ||
46 | #include <nvgpu/hw/gv100/hw_mc_gv100.h> | ||
47 | |||
48 | #define HW_SCRUB_TIMEOUT_DEFAULT 100 /* usec */ | ||
49 | #define HW_SCRUB_TIMEOUT_MAX 2000000 /* usec */ | ||
50 | #define MEM_UNLOCK_TIMEOUT 3500 /* msec */ | ||
51 | |||
52 | void gv100_fb_reset(struct gk20a *g) | ||
53 | { | ||
54 | u32 val; | ||
55 | int retries = HW_SCRUB_TIMEOUT_MAX / HW_SCRUB_TIMEOUT_DEFAULT; | ||
56 | |||
57 | nvgpu_info(g, "reset gv100 fb"); | ||
58 | |||
59 | /* wait for memory to be accessible */ | ||
60 | do { | ||
61 | u32 w = gk20a_readl(g, fb_niso_scrub_status_r()); | ||
62 | if (fb_niso_scrub_status_flag_v(w)) { | ||
63 | nvgpu_info(g, "done"); | ||
64 | break; | ||
65 | } | ||
66 | nvgpu_udelay(HW_SCRUB_TIMEOUT_DEFAULT); | ||
67 | } while (--retries); | ||
68 | |||
69 | val = gk20a_readl(g, fb_mmu_priv_level_mask_r()); | ||
70 | val &= ~fb_mmu_priv_level_mask_write_violation_m(); | ||
71 | gk20a_writel(g, fb_mmu_priv_level_mask_r(), val); | ||
72 | } | ||
73 | |||
74 | void gv100_fb_enable_hub_intr(struct gk20a *g) | ||
75 | { | ||
76 | u32 mask = 0; | ||
77 | |||
78 | mask = fb_niso_intr_en_set_mmu_other_fault_notify_m() | | ||
79 | fb_niso_intr_en_set_mmu_nonreplayable_fault_notify_m() | | ||
80 | fb_niso_intr_en_set_mmu_nonreplayable_fault_overflow_m() | | ||
81 | fb_niso_intr_en_set_mmu_replayable_fault_notify_m() | | ||
82 | fb_niso_intr_en_set_mmu_replayable_fault_overflow_m(); | ||
83 | |||
84 | gk20a_writel(g, fb_niso_intr_en_set_r(0), | ||
85 | mask); | ||
86 | } | ||
87 | |||
88 | void gv100_fb_disable_hub_intr(struct gk20a *g) | ||
89 | { | ||
90 | u32 mask = 0; | ||
91 | |||
92 | mask = fb_niso_intr_en_set_mmu_other_fault_notify_m() | | ||
93 | fb_niso_intr_en_set_mmu_nonreplayable_fault_notify_m() | | ||
94 | fb_niso_intr_en_set_mmu_nonreplayable_fault_overflow_m() | | ||
95 | fb_niso_intr_en_set_mmu_replayable_fault_notify_m() | | ||
96 | fb_niso_intr_en_set_mmu_replayable_fault_overflow_m(); | ||
97 | |||
98 | gk20a_writel(g, fb_niso_intr_en_clr_r(0), | ||
99 | mask); | ||
100 | } | ||
101 | |||
102 | int gv100_fb_memory_unlock(struct gk20a *g) | ||
103 | { | ||
104 | struct nvgpu_firmware *mem_unlock_fw = NULL; | ||
105 | struct bin_hdr *hsbin_hdr = NULL; | ||
106 | struct acr_fw_header *fw_hdr = NULL; | ||
107 | u32 *mem_unlock_ucode = NULL; | ||
108 | u32 *mem_unlock_ucode_header = NULL; | ||
109 | u32 sec_imem_dest = 0; | ||
110 | u32 val = 0; | ||
111 | int err = 0; | ||
112 | |||
113 | nvgpu_log_fn(g, " "); | ||
114 | |||
115 | nvgpu_log_info(g, "fb_mmu_vpr_info = 0x%08x", | ||
116 | gk20a_readl(g, fb_mmu_vpr_info_r())); | ||
117 | /* | ||
118 | * mem_unlock.bin should be written to install | ||
119 | * traps even if VPR isn’t actually supported | ||
120 | */ | ||
121 | mem_unlock_fw = nvgpu_request_firmware(g, "mem_unlock.bin", 0); | ||
122 | if (!mem_unlock_fw) { | ||
123 | nvgpu_err(g, "mem unlock ucode get fail"); | ||
124 | err = -ENOENT; | ||
125 | goto exit; | ||
126 | } | ||
127 | |||
128 | /* Enable nvdec */ | ||
129 | g->ops.mc.enable(g, mc_enable_nvdec_enabled_f()); | ||
130 | |||
131 | /* nvdec falcon reset */ | ||
132 | nvgpu_flcn_reset(&g->nvdec_flcn); | ||
133 | |||
134 | hsbin_hdr = (struct bin_hdr *)mem_unlock_fw->data; | ||
135 | fw_hdr = (struct acr_fw_header *)(mem_unlock_fw->data + | ||
136 | hsbin_hdr->header_offset); | ||
137 | |||
138 | mem_unlock_ucode_header = (u32 *)(mem_unlock_fw->data + | ||
139 | fw_hdr->hdr_offset); | ||
140 | mem_unlock_ucode = (u32 *)(mem_unlock_fw->data + | ||
141 | hsbin_hdr->data_offset); | ||
142 | |||
143 | /* Patch Ucode singnatures */ | ||
144 | if (acr_ucode_patch_sig(g, mem_unlock_ucode, | ||
145 | (u32 *)(mem_unlock_fw->data + fw_hdr->sig_prod_offset), | ||
146 | (u32 *)(mem_unlock_fw->data + fw_hdr->sig_dbg_offset), | ||
147 | (u32 *)(mem_unlock_fw->data + fw_hdr->patch_loc), | ||
148 | (u32 *)(mem_unlock_fw->data + fw_hdr->patch_sig)) < 0) { | ||
149 | nvgpu_err(g, "mem unlock patch signatures fail"); | ||
150 | err = -EPERM; | ||
151 | goto exit; | ||
152 | } | ||
153 | |||
154 | /* Clear interrupts */ | ||
155 | nvgpu_flcn_set_irq(&g->nvdec_flcn, false, 0x0, 0x0); | ||
156 | |||
157 | /* Copy Non Secure IMEM code */ | ||
158 | nvgpu_flcn_copy_to_imem(&g->nvdec_flcn, 0, | ||
159 | (u8 *)&mem_unlock_ucode[ | ||
160 | mem_unlock_ucode_header[OS_CODE_OFFSET] >> 2], | ||
161 | mem_unlock_ucode_header[OS_CODE_SIZE], 0, false, | ||
162 | GET_IMEM_TAG(mem_unlock_ucode_header[OS_CODE_OFFSET])); | ||
163 | |||
164 | /* Put secure code after non-secure block */ | ||
165 | sec_imem_dest = GET_NEXT_BLOCK(mem_unlock_ucode_header[OS_CODE_SIZE]); | ||
166 | |||
167 | nvgpu_flcn_copy_to_imem(&g->nvdec_flcn, sec_imem_dest, | ||
168 | (u8 *)&mem_unlock_ucode[ | ||
169 | mem_unlock_ucode_header[APP_0_CODE_OFFSET] >> 2], | ||
170 | mem_unlock_ucode_header[APP_0_CODE_SIZE], 0, true, | ||
171 | GET_IMEM_TAG(mem_unlock_ucode_header[APP_0_CODE_OFFSET])); | ||
172 | |||
173 | /* load DMEM: ensure that signatures are patched */ | ||
174 | nvgpu_flcn_copy_to_dmem(&g->nvdec_flcn, 0, (u8 *)&mem_unlock_ucode[ | ||
175 | mem_unlock_ucode_header[OS_DATA_OFFSET] >> 2], | ||
176 | mem_unlock_ucode_header[OS_DATA_SIZE], 0); | ||
177 | |||
178 | nvgpu_log_info(g, "nvdec sctl reg %x\n", | ||
179 | gk20a_readl(g, g->nvdec_flcn.flcn_base + | ||
180 | falcon_falcon_sctl_r())); | ||
181 | |||
182 | /* set BOOTVEC to start of non-secure code */ | ||
183 | nvgpu_flcn_bootstrap(&g->nvdec_flcn, 0); | ||
184 | |||
185 | /* wait for complete & halt */ | ||
186 | nvgpu_flcn_wait_for_halt(&g->nvdec_flcn, MEM_UNLOCK_TIMEOUT); | ||
187 | |||
188 | /* check mem unlock status */ | ||
189 | val = nvgpu_flcn_mailbox_read(&g->nvdec_flcn, 0); | ||
190 | if (val) { | ||
191 | nvgpu_err(g, "memory unlock failed, err %x", val); | ||
192 | err = -1; | ||
193 | goto exit; | ||
194 | } | ||
195 | |||
196 | nvgpu_log_info(g, "nvdec sctl reg %x\n", | ||
197 | gk20a_readl(g, g->nvdec_flcn.flcn_base + | ||
198 | falcon_falcon_sctl_r())); | ||
199 | |||
200 | exit: | ||
201 | if (mem_unlock_fw) | ||
202 | nvgpu_release_firmware(g, mem_unlock_fw); | ||
203 | |||
204 | nvgpu_log_fn(g, "done, status - %d", err); | ||
205 | |||
206 | return err; | ||
207 | } | ||
208 | |||
209 | int gv100_fb_init_nvlink(struct gk20a *g) | ||
210 | { | ||
211 | u32 data; | ||
212 | u32 mask = g->nvlink.enabled_links; | ||
213 | |||
214 | /* Map enabled link to SYSMEM */ | ||
215 | data = nvgpu_readl(g, fb_hshub_config0_r()); | ||
216 | data = set_field(data, fb_hshub_config0_sysmem_nvlink_mask_m(), | ||
217 | fb_hshub_config0_sysmem_nvlink_mask_f(mask)); | ||
218 | nvgpu_writel(g, fb_hshub_config0_r(), data); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | int gv100_fb_enable_nvlink(struct gk20a *g) | ||
224 | { | ||
225 | u32 data; | ||
226 | |||
227 | nvgpu_log(g, gpu_dbg_nvlink|gpu_dbg_info, "enabling nvlink"); | ||
228 | |||
229 | /* Enable nvlink for NISO FBHUB */ | ||
230 | data = nvgpu_readl(g, fb_niso_cfg1_r()); | ||
231 | data = set_field(data, fb_niso_cfg1_sysmem_nvlink_m(), | ||
232 | fb_niso_cfg1_sysmem_nvlink_enabled_f()); | ||
233 | nvgpu_writel(g, fb_niso_cfg1_r(), data); | ||
234 | |||
235 | /* Setup atomics */ | ||
236 | data = nvgpu_readl(g, fb_mmu_ctrl_r()); | ||
237 | data = set_field(data, fb_mmu_ctrl_atomic_capability_mode_m(), | ||
238 | fb_mmu_ctrl_atomic_capability_mode_rmw_f()); | ||
239 | nvgpu_writel(g, fb_mmu_ctrl_r(), data); | ||
240 | |||
241 | data = nvgpu_readl(g, fb_hsmmu_pri_mmu_ctrl_r()); | ||
242 | data = set_field(data, fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_m(), | ||
243 | fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_rmw_f()); | ||
244 | nvgpu_writel(g, fb_hsmmu_pri_mmu_ctrl_r(), data); | ||
245 | |||
246 | data = nvgpu_readl(g, fb_fbhub_num_active_ltcs_r()); | ||
247 | data = set_field(data, fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_m(), | ||
248 | fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_f()); | ||
249 | nvgpu_writel(g, fb_fbhub_num_active_ltcs_r(), data); | ||
250 | |||
251 | data = nvgpu_readl(g, fb_hshub_num_active_ltcs_r()); | ||
252 | data = set_field(data, fb_hshub_num_active_ltcs_hub_sys_atomic_mode_m(), | ||
253 | fb_hshub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_f()); | ||
254 | nvgpu_writel(g, fb_hshub_num_active_ltcs_r(), data); | ||
255 | |||
256 | return 0; | ||
257 | } | ||