aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2017-05-18 09:24:30 -0400
committerSean Paul <seanpaul@chromium.org>2017-05-18 09:24:30 -0400
commit6b7781b42dc9bc9bcd1523b6c24b876cdda0bef3 (patch)
treeee55c67e4ea30b9eb44f301ba0bde2e631a26162 /drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
parent52d9d38c183bf0e09601d875ea31bb53c05dd8cf (diff)
parente98c58e55f68f8785aebfab1f8c9a03d8de0afe1 (diff)
Merge remote-tracking branch 'airlied/drm-next' into drm-misc-next
Picking up drm-next @ 4.12-rc1 in order to apply Michal Hocko's vmalloc patch set Signed-off-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c229
1 files changed, 146 insertions, 83 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index e6cf91ca5761..596e3957bdd9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -55,6 +55,8 @@ static int psp_sw_init(void *handle)
55 psp->bootloader_load_sos = psp_v3_1_bootloader_load_sos; 55 psp->bootloader_load_sos = psp_v3_1_bootloader_load_sos;
56 psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf; 56 psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf;
57 psp->ring_init = psp_v3_1_ring_init; 57 psp->ring_init = psp_v3_1_ring_init;
58 psp->ring_create = psp_v3_1_ring_create;
59 psp->ring_destroy = psp_v3_1_ring_destroy;
58 psp->cmd_submit = psp_v3_1_cmd_submit; 60 psp->cmd_submit = psp_v3_1_cmd_submit;
59 psp->compare_sram_data = psp_v3_1_compare_sram_data; 61 psp->compare_sram_data = psp_v3_1_compare_sram_data;
60 psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; 62 psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk;
@@ -152,11 +154,6 @@ static void psp_prep_tmr_cmd_buf(struct psp_gfx_cmd_resp *cmd,
152static int psp_tmr_init(struct psp_context *psp) 154static int psp_tmr_init(struct psp_context *psp)
153{ 155{
154 int ret; 156 int ret;
155 struct psp_gfx_cmd_resp *cmd;
156
157 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
158 if (!cmd)
159 return -ENOMEM;
160 157
161 /* 158 /*
162 * Allocate 3M memory aligned to 1M from Frame Buffer (local 159 * Allocate 3M memory aligned to 1M from Frame Buffer (local
@@ -168,22 +165,30 @@ static int psp_tmr_init(struct psp_context *psp)
168 ret = amdgpu_bo_create_kernel(psp->adev, 0x300000, 0x100000, 165 ret = amdgpu_bo_create_kernel(psp->adev, 0x300000, 0x100000,
169 AMDGPU_GEM_DOMAIN_VRAM, 166 AMDGPU_GEM_DOMAIN_VRAM,
170 &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); 167 &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
171 if (ret) 168
172 goto failed; 169 return ret;
170}
171
172static int psp_tmr_load(struct psp_context *psp)
173{
174 int ret;
175 struct psp_gfx_cmd_resp *cmd;
176
177 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
178 if (!cmd)
179 return -ENOMEM;
173 180
174 psp_prep_tmr_cmd_buf(cmd, psp->tmr_mc_addr, 0x300000); 181 psp_prep_tmr_cmd_buf(cmd, psp->tmr_mc_addr, 0x300000);
175 182
176 ret = psp_cmd_submit_buf(psp, NULL, cmd, 183 ret = psp_cmd_submit_buf(psp, NULL, cmd,
177 psp->fence_buf_mc_addr, 1); 184 psp->fence_buf_mc_addr, 1);
178 if (ret) 185 if (ret)
179 goto failed_mem; 186 goto failed;
180 187
181 kfree(cmd); 188 kfree(cmd);
182 189
183 return 0; 190 return 0;
184 191
185failed_mem:
186 amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
187failed: 192failed:
188 kfree(cmd); 193 kfree(cmd);
189 return ret; 194 return ret;
@@ -203,104 +208,78 @@ static void psp_prep_asd_cmd_buf(struct psp_gfx_cmd_resp *cmd,
203 cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; 208 cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
204} 209}
205 210
206static int psp_asd_load(struct psp_context *psp) 211static int psp_asd_init(struct psp_context *psp)
207{ 212{
208 int ret; 213 int ret;
209 struct amdgpu_bo *asd_bo, *asd_shared_bo;
210 uint64_t asd_mc_addr, asd_shared_mc_addr;
211 void *asd_buf, *asd_shared_buf;
212 struct psp_gfx_cmd_resp *cmd;
213
214 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
215 if (!cmd)
216 return -ENOMEM;
217 214
218 /* 215 /*
219 * Allocate 16k memory aligned to 4k from Frame Buffer (local 216 * Allocate 16k memory aligned to 4k from Frame Buffer (local
220 * physical) for shared ASD <-> Driver 217 * physical) for shared ASD <-> Driver
221 */ 218 */
222 ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE, PAGE_SIZE, 219 ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE,
223 AMDGPU_GEM_DOMAIN_VRAM, 220 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
224 &asd_shared_bo, &asd_shared_mc_addr, &asd_buf); 221 &psp->asd_shared_bo,
225 if (ret) 222 &psp->asd_shared_mc_addr,
226 goto failed; 223 &psp->asd_shared_buf);
227 224
228 /* 225 return ret;
229 * Allocate 256k memory aligned to 4k from Frame Buffer (local 226}
230 * physical) for ASD firmware 227
231 */ 228static int psp_asd_load(struct psp_context *psp)
232 ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_BIN_SIZE, PAGE_SIZE, 229{
233 AMDGPU_GEM_DOMAIN_VRAM, 230 int ret;
234 &asd_bo, &asd_mc_addr, &asd_buf); 231 struct psp_gfx_cmd_resp *cmd;
235 if (ret) 232
236 goto failed_mem; 233 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
234 if (!cmd)
235 return -ENOMEM;
237 236
238 memcpy(asd_buf, psp->asd_start_addr, psp->asd_ucode_size); 237 memset(psp->fw_pri_buf, 0, PSP_1_MEG);
238 memcpy(psp->fw_pri_buf, psp->asd_start_addr, psp->asd_ucode_size);
239 239
240 psp_prep_asd_cmd_buf(cmd, asd_mc_addr, asd_shared_mc_addr, 240 psp_prep_asd_cmd_buf(cmd, psp->fw_pri_mc_addr, psp->asd_shared_mc_addr,
241 psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE); 241 psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE);
242 242
243 ret = psp_cmd_submit_buf(psp, NULL, cmd, 243 ret = psp_cmd_submit_buf(psp, NULL, cmd,
244 psp->fence_buf_mc_addr, 2); 244 psp->fence_buf_mc_addr, 2);
245 if (ret)
246 goto failed_mem1;
247 245
248 amdgpu_bo_free_kernel(&asd_bo, &asd_mc_addr, &asd_buf);
249 amdgpu_bo_free_kernel(&asd_shared_bo, &asd_shared_mc_addr, &asd_shared_buf);
250 kfree(cmd); 246 kfree(cmd);
251 247
252 return 0;
253
254failed_mem1:
255 amdgpu_bo_free_kernel(&asd_bo, &asd_mc_addr, &asd_buf);
256failed_mem:
257 amdgpu_bo_free_kernel(&asd_shared_bo, &asd_shared_mc_addr, &asd_shared_buf);
258failed:
259 kfree(cmd);
260 return ret; 248 return ret;
261} 249}
262 250
263static int psp_load_fw(struct amdgpu_device *adev) 251static int psp_hw_start(struct psp_context *psp)
264{ 252{
265 int ret; 253 int ret;
266 struct psp_gfx_cmd_resp *cmd;
267 int i;
268 struct amdgpu_firmware_info *ucode;
269 struct psp_context *psp = &adev->psp;
270
271 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
272 if (!cmd)
273 return -ENOMEM;
274 254
275 ret = psp_bootloader_load_sysdrv(psp); 255 ret = psp_bootloader_load_sysdrv(psp);
276 if (ret) 256 if (ret)
277 goto failed; 257 return ret;
278 258
279 ret = psp_bootloader_load_sos(psp); 259 ret = psp_bootloader_load_sos(psp);
280 if (ret) 260 if (ret)
281 goto failed; 261 return ret;
282
283 ret = psp_ring_init(psp, PSP_RING_TYPE__KM);
284 if (ret)
285 goto failed;
286 262
287 ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, 263 ret = psp_ring_create(psp, PSP_RING_TYPE__KM);
288 AMDGPU_GEM_DOMAIN_VRAM,
289 &psp->fence_buf_bo,
290 &psp->fence_buf_mc_addr,
291 &psp->fence_buf);
292 if (ret) 264 if (ret)
293 goto failed; 265 return ret;
294
295 memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE);
296 266
297 ret = psp_tmr_init(psp); 267 ret = psp_tmr_load(psp);
298 if (ret) 268 if (ret)
299 goto failed_mem; 269 return ret;
300 270
301 ret = psp_asd_load(psp); 271 ret = psp_asd_load(psp);
302 if (ret) 272 if (ret)
303 goto failed_mem; 273 return ret;
274
275 return 0;
276}
277
278static int psp_np_fw_load(struct psp_context *psp)
279{
280 int i, ret;
281 struct amdgpu_firmware_info *ucode;
282 struct amdgpu_device* adev = psp->adev;
304 283
305 for (i = 0; i < adev->firmware.max_ucodes; i++) { 284 for (i = 0; i < adev->firmware.max_ucodes; i++) {
306 ucode = &adev->firmware.ucode[i]; 285 ucode = &adev->firmware.ucode[i];
@@ -310,15 +289,21 @@ static int psp_load_fw(struct amdgpu_device *adev)
310 if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && 289 if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
311 psp_smu_reload_quirk(psp)) 290 psp_smu_reload_quirk(psp))
312 continue; 291 continue;
292 if (amdgpu_sriov_vf(adev) &&
293 (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
294 || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
295 || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G))
296 /*skip ucode loading in SRIOV VF */
297 continue;
313 298
314 ret = psp_prep_cmd_buf(ucode, cmd); 299 ret = psp_prep_cmd_buf(ucode, psp->cmd);
315 if (ret) 300 if (ret)
316 goto failed_mem; 301 return ret;
317 302
318 ret = psp_cmd_submit_buf(psp, ucode, cmd, 303 ret = psp_cmd_submit_buf(psp, ucode, psp->cmd,
319 psp->fence_buf_mc_addr, i + 3); 304 psp->fence_buf_mc_addr, i + 3);
320 if (ret) 305 if (ret)
321 goto failed_mem; 306 return ret;
322 307
323#if 0 308#if 0
324 /* check if firmware loaded sucessfully */ 309 /* check if firmware loaded sucessfully */
@@ -327,8 +312,59 @@ static int psp_load_fw(struct amdgpu_device *adev)
327#endif 312#endif
328 } 313 }
329 314
330 amdgpu_bo_free_kernel(&psp->fence_buf_bo, 315 return 0;
331 &psp->fence_buf_mc_addr, &psp->fence_buf); 316}
317
318static int psp_load_fw(struct amdgpu_device *adev)
319{
320 int ret;
321 struct psp_context *psp = &adev->psp;
322 struct psp_gfx_cmd_resp *cmd;
323
324 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
325 if (!cmd)
326 return -ENOMEM;
327
328 psp->cmd = cmd;
329
330 ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
331 AMDGPU_GEM_DOMAIN_GTT,
332 &psp->fw_pri_bo,
333 &psp->fw_pri_mc_addr,
334 &psp->fw_pri_buf);
335 if (ret)
336 goto failed;
337
338 ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE,
339 AMDGPU_GEM_DOMAIN_VRAM,
340 &psp->fence_buf_bo,
341 &psp->fence_buf_mc_addr,
342 &psp->fence_buf);
343 if (ret)
344 goto failed_mem1;
345
346 memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE);
347
348 ret = psp_ring_init(psp, PSP_RING_TYPE__KM);
349 if (ret)
350 goto failed_mem1;
351
352 ret = psp_tmr_init(psp);
353 if (ret)
354 goto failed_mem;
355
356 ret = psp_asd_init(psp);
357 if (ret)
358 goto failed_mem;
359
360 ret = psp_hw_start(psp);
361 if (ret)
362 goto failed_mem;
363
364 ret = psp_np_fw_load(psp);
365 if (ret)
366 goto failed_mem;
367
332 kfree(cmd); 368 kfree(cmd);
333 369
334 return 0; 370 return 0;
@@ -336,6 +372,9 @@ static int psp_load_fw(struct amdgpu_device *adev)
336failed_mem: 372failed_mem:
337 amdgpu_bo_free_kernel(&psp->fence_buf_bo, 373 amdgpu_bo_free_kernel(&psp->fence_buf_bo,
338 &psp->fence_buf_mc_addr, &psp->fence_buf); 374 &psp->fence_buf_mc_addr, &psp->fence_buf);
375failed_mem1:
376 amdgpu_bo_free_kernel(&psp->fw_pri_bo,
377 &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
339failed: 378failed:
340 kfree(cmd); 379 kfree(cmd);
341 return ret; 380 return ret;
@@ -379,12 +418,24 @@ static int psp_hw_fini(void *handle)
379 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 418 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
380 struct psp_context *psp = &adev->psp; 419 struct psp_context *psp = &adev->psp;
381 420
382 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) 421 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
383 amdgpu_ucode_fini_bo(adev); 422 return 0;
423
424 amdgpu_ucode_fini_bo(adev);
425
426 psp_ring_destroy(psp, PSP_RING_TYPE__KM);
384 427
385 if (psp->tmr_buf) 428 if (psp->tmr_buf)
386 amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); 429 amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
387 430
431 if (psp->fw_pri_buf)
432 amdgpu_bo_free_kernel(&psp->fw_pri_bo,
433 &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
434
435 if (psp->fence_buf_bo)
436 amdgpu_bo_free_kernel(&psp->fence_buf_bo,
437 &psp->fence_buf_mc_addr, &psp->fence_buf);
438
388 return 0; 439 return 0;
389} 440}
390 441
@@ -397,18 +448,30 @@ static int psp_resume(void *handle)
397{ 448{
398 int ret; 449 int ret;
399 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 450 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
451 struct psp_context *psp = &adev->psp;
400 452
401 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) 453 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
402 return 0; 454 return 0;
403 455
456 DRM_INFO("PSP is resuming...\n");
457
404 mutex_lock(&adev->firmware.mutex); 458 mutex_lock(&adev->firmware.mutex);
405 459
406 ret = psp_load_fw(adev); 460 ret = psp_hw_start(psp);
407 if (ret) 461 if (ret)
408 DRM_ERROR("PSP resume failed\n"); 462 goto failed;
463
464 ret = psp_np_fw_load(psp);
465 if (ret)
466 goto failed;
409 467
410 mutex_unlock(&adev->firmware.mutex); 468 mutex_unlock(&adev->firmware.mutex);
411 469
470 return 0;
471
472failed:
473 DRM_ERROR("PSP resume failed\n");
474 mutex_unlock(&adev->firmware.mutex);
412 return ret; 475 return ret;
413} 476}
414 477