diff options
author | Likun Gao <Likun.Gao@amd.com> | 2018-12-20 07:31:55 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-03-19 16:03:57 -0400 |
commit | d6a4aa825a65ee7ec0293666fd1572e4621ad13d (patch) | |
tree | 3b62539d79f3a6d03e6416af2f140456e1187ab9 /drivers | |
parent | e1c6f86a915f7c3f6bba7a72713f9e61221dafe4 (diff) |
drm/amd/powerplay: set defalut dpm table for smu
Add smu_set_default_dpm_table function to set dpm table for smu11.
Modified the sequence to populate smc pptable, as it should be done after
related dpm feature is enabled.
Signed-off-by: Likun Gao <Likun.Gao@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 38 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 236 |
4 files changed, 251 insertions, 44 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 47b46115a4f3..e03132c17f4e 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | |||
@@ -348,15 +348,6 @@ static int smu_smc_table_hw_init(struct smu_context *smu) | |||
348 | return ret; | 348 | return ret; |
349 | 349 | ||
350 | /* | 350 | /* |
351 | * Set initialized values (get from vbios) to dpm tables context such as | ||
352 | * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each | ||
353 | * type of clks. | ||
354 | */ | ||
355 | ret = smu_populate_smc_pptable(smu); | ||
356 | if (ret) | ||
357 | return ret; | ||
358 | |||
359 | /* | ||
360 | * Send msg GetDriverIfVersion to check if the return value is equal | 351 | * Send msg GetDriverIfVersion to check if the return value is equal |
361 | * with DRIVER_IF_VERSION of smc header. | 352 | * with DRIVER_IF_VERSION of smc header. |
362 | */ | 353 | */ |
@@ -394,6 +385,15 @@ static int smu_smc_table_hw_init(struct smu_context *smu) | |||
394 | return ret; | 385 | return ret; |
395 | 386 | ||
396 | /* | 387 | /* |
388 | * Set initialized values (get from vbios) to dpm tables context such as | ||
389 | * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each | ||
390 | * type of clks. | ||
391 | */ | ||
392 | ret = smu_populate_smc_pptable(smu); | ||
393 | if (ret) | ||
394 | return ret; | ||
395 | |||
396 | /* | ||
397 | * Set PMSTATUSLOG table bo address with SetToolsDramAddr MSG for tools. | 397 | * Set PMSTATUSLOG table bo address with SetToolsDramAddr MSG for tools. |
398 | */ | 398 | */ |
399 | ret = smu_set_tool_table_location(smu); | 399 | ret = smu_set_tool_table_location(smu); |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index 154f74eb9081..24babb836a0c 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | |||
@@ -208,6 +208,7 @@ struct pptable_funcs { | |||
208 | int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index); | 208 | int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index); |
209 | int (*run_afll_btc)(struct smu_context *smu); | 209 | int (*run_afll_btc)(struct smu_context *smu); |
210 | int (*get_unallowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num); | 210 | int (*get_unallowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num); |
211 | int (*set_default_dpm_table)(struct smu_context *smu); | ||
211 | }; | 212 | }; |
212 | 213 | ||
213 | struct smu_funcs | 214 | struct smu_funcs |
@@ -313,6 +314,8 @@ struct smu_funcs | |||
313 | ((smu)->ppt_funcs->check_powerplay_table ? (smu)->ppt_funcs->check_powerplay_table((smu)) : 0) | 314 | ((smu)->ppt_funcs->check_powerplay_table ? (smu)->ppt_funcs->check_powerplay_table((smu)) : 0) |
314 | #define smu_append_powerplay_table(smu) \ | 315 | #define smu_append_powerplay_table(smu) \ |
315 | ((smu)->ppt_funcs->append_powerplay_table ? (smu)->ppt_funcs->append_powerplay_table((smu)) : 0) | 316 | ((smu)->ppt_funcs->append_powerplay_table ? (smu)->ppt_funcs->append_powerplay_table((smu)) : 0) |
317 | #define smu_set_default_dpm_table(smu) \ | ||
318 | ((smu)->ppt_funcs->set_default_dpm_table ? (smu)->ppt_funcs->set_default_dpm_table((smu)) : 0) | ||
316 | 319 | ||
317 | #define smu_msg_get_index(smu, msg) \ | 320 | #define smu_msg_get_index(smu, msg) \ |
318 | ((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_msg_index? (smu)->ppt_funcs->get_smu_msg_index((smu), (msg)) : -EINVAL) : -EINVAL) | 321 | ((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_msg_index? (smu)->ppt_funcs->get_smu_msg_index((smu), (msg)) : -EINVAL) : -EINVAL) |
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index bfda4a30a14f..66af3e61d33a 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c | |||
@@ -525,43 +525,11 @@ static int smu_v11_0_parse_pptable(struct smu_context *smu) | |||
525 | 525 | ||
526 | static int smu_v11_0_populate_smc_pptable(struct smu_context *smu) | 526 | static int smu_v11_0_populate_smc_pptable(struct smu_context *smu) |
527 | { | 527 | { |
528 | struct smu_dpm_context *smu_dpm = &smu->smu_dpm; | 528 | int ret; |
529 | |||
530 | PPTable_t *driver_ppt = (PPTable_t *)&(smu->smu_table.tables[TABLE_PPTABLE]); | ||
531 | struct smu_11_0_dpm_context *dpm_context = (struct smu_11_0_dpm_context *)smu_dpm->dpm_context; | ||
532 | |||
533 | if (dpm_context && driver_ppt) { | ||
534 | dpm_context->dpm_tables.soc_table.min = driver_ppt->FreqTableSocclk[0]; | ||
535 | dpm_context->dpm_tables.soc_table.max = driver_ppt->FreqTableSocclk[NUM_SOCCLK_DPM_LEVELS - 1]; | ||
536 | |||
537 | dpm_context->dpm_tables.gfx_table.min = driver_ppt->FreqTableGfx[0]; | ||
538 | dpm_context->dpm_tables.gfx_table.max = driver_ppt->FreqTableGfx[NUM_GFXCLK_DPM_LEVELS - 1]; | ||
539 | |||
540 | dpm_context->dpm_tables.uclk_table.min = driver_ppt->FreqTableUclk[0]; | ||
541 | dpm_context->dpm_tables.uclk_table.max = driver_ppt->FreqTableUclk[NUM_UCLK_DPM_LEVELS - 1]; | ||
542 | |||
543 | dpm_context->dpm_tables.vclk_table.min = driver_ppt->FreqTableVclk[0]; | ||
544 | dpm_context->dpm_tables.vclk_table.max = driver_ppt->FreqTableVclk[NUM_VCLK_DPM_LEVELS - 1]; | ||
545 | |||
546 | dpm_context->dpm_tables.dclk_table.min = driver_ppt->FreqTableDclk[0]; | ||
547 | dpm_context->dpm_tables.dclk_table.max = driver_ppt->FreqTableDclk[NUM_DCLK_DPM_LEVELS - 1]; | ||
548 | |||
549 | dpm_context->dpm_tables.dcef_table.min = driver_ppt->FreqTableDcefclk[0]; | ||
550 | dpm_context->dpm_tables.dcef_table.max = driver_ppt->FreqTableDcefclk[NUM_DCEFCLK_DPM_LEVELS - 1]; | ||
551 | |||
552 | dpm_context->dpm_tables.pixel_table.min = driver_ppt->FreqTablePixclk[0]; | ||
553 | dpm_context->dpm_tables.pixel_table.max = driver_ppt->FreqTablePixclk[NUM_PIXCLK_DPM_LEVELS - 1]; | ||
554 | |||
555 | dpm_context->dpm_tables.display_table.min = driver_ppt->FreqTableDispclk[0]; | ||
556 | dpm_context->dpm_tables.display_table.max = driver_ppt->FreqTableDispclk[NUM_DISPCLK_DPM_LEVELS - 1]; | ||
557 | 529 | ||
558 | dpm_context->dpm_tables.phy_table.min = driver_ppt->FreqTablePhyclk[0]; | 530 | ret = smu_set_default_dpm_table(smu); |
559 | dpm_context->dpm_tables.phy_table.max = driver_ppt->FreqTablePhyclk[NUM_PHYCLK_DPM_LEVELS - 1]; | ||
560 | 531 | ||
561 | return 0; | 532 | return ret; |
562 | } | ||
563 | |||
564 | return -EINVAL; | ||
565 | } | 533 | } |
566 | 534 | ||
567 | static int smu_v11_0_copy_table_to_smc(struct smu_context *smu, | 535 | static int smu_v11_0_copy_table_to_smc(struct smu_context *smu, |
diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index 4b756e84115b..bca4085696d2 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c | |||
@@ -291,6 +291,241 @@ vega20_get_unallowed_feature_mask(struct smu_context *smu, | |||
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | static int | ||
295 | vega20_set_single_dpm_table(struct smu_context *smu, | ||
296 | struct vega20_single_dpm_table *single_dpm_table, | ||
297 | PPCLK_e clk_id) | ||
298 | { | ||
299 | int ret = 0; | ||
300 | uint32_t i, num_of_levels, clk; | ||
301 | |||
302 | ret = smu_send_smc_msg_with_param(smu, | ||
303 | SMU_MSG_GetDpmFreqByIndex, | ||
304 | (clk_id << 16 | 0xFF)); | ||
305 | if (ret) { | ||
306 | pr_err("[GetNumOfDpmLevel] failed to get dpm levels!"); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | smu_read_smc_arg(smu, &num_of_levels); | ||
311 | if (!num_of_levels) { | ||
312 | pr_err("[GetNumOfDpmLevel] number of clk levels is invalid!"); | ||
313 | return -EINVAL; | ||
314 | } | ||
315 | |||
316 | single_dpm_table->count = num_of_levels; | ||
317 | |||
318 | for (i = 0; i < num_of_levels; i++) { | ||
319 | ret = smu_send_smc_msg_with_param(smu, | ||
320 | SMU_MSG_GetDpmFreqByIndex, | ||
321 | (clk_id << 16 | i)); | ||
322 | if (ret) { | ||
323 | pr_err("[GetDpmFreqByIndex] failed to get dpm freq by index!"); | ||
324 | return ret; | ||
325 | } | ||
326 | smu_read_smc_arg(smu, &clk); | ||
327 | if (!clk) { | ||
328 | pr_err("[GetDpmFreqByIndex] clk value is invalid!"); | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | single_dpm_table->dpm_levels[i].value = clk; | ||
332 | single_dpm_table->dpm_levels[i].enabled = true; | ||
333 | } | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static void vega20_init_single_dpm_state(struct vega20_dpm_state *dpm_state) | ||
338 | { | ||
339 | dpm_state->soft_min_level = 0x0; | ||
340 | dpm_state->soft_max_level = 0xffff; | ||
341 | dpm_state->hard_min_level = 0x0; | ||
342 | dpm_state->hard_max_level = 0xffff; | ||
343 | } | ||
344 | |||
345 | static int vega20_set_default_dpm_table(struct smu_context *smu) | ||
346 | { | ||
347 | int ret; | ||
348 | |||
349 | struct smu_dpm_context *smu_dpm = &smu->smu_dpm; | ||
350 | struct vega20_dpm_table *dpm_table = NULL; | ||
351 | struct vega20_single_dpm_table *single_dpm_table; | ||
352 | |||
353 | dpm_table = smu_dpm->dpm_context; | ||
354 | |||
355 | /* socclk */ | ||
356 | single_dpm_table = &(dpm_table->soc_table); | ||
357 | |||
358 | if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) { | ||
359 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
360 | PPCLK_SOCCLK); | ||
361 | if (ret) { | ||
362 | pr_err("[SetupDefaultDpmTable] failed to get socclk dpm levels!"); | ||
363 | return ret; | ||
364 | } | ||
365 | } else { | ||
366 | single_dpm_table->count = 1; | ||
367 | single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100; | ||
368 | } | ||
369 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
370 | |||
371 | /* gfxclk */ | ||
372 | single_dpm_table = &(dpm_table->gfx_table); | ||
373 | |||
374 | if (smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT)) { | ||
375 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
376 | PPCLK_GFXCLK); | ||
377 | if (ret) { | ||
378 | pr_err("[SetupDefaultDpmTable] failed to get gfxclk dpm levels!"); | ||
379 | return ret; | ||
380 | } | ||
381 | } else { | ||
382 | single_dpm_table->count = 1; | ||
383 | single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100; | ||
384 | } | ||
385 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
386 | |||
387 | /* memclk */ | ||
388 | single_dpm_table = &(dpm_table->mem_table); | ||
389 | |||
390 | if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) { | ||
391 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
392 | PPCLK_UCLK); | ||
393 | if (ret) { | ||
394 | pr_err("[SetupDefaultDpmTable] failed to get memclk dpm levels!"); | ||
395 | return ret; | ||
396 | } | ||
397 | } else { | ||
398 | single_dpm_table->count = 1; | ||
399 | single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100; | ||
400 | } | ||
401 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
402 | |||
403 | #if 0 | ||
404 | /* eclk */ | ||
405 | single_dpm_table = &(dpm_table->eclk_table); | ||
406 | |||
407 | if (feature->fea_enabled[FEATURE_DPM_VCE_BIT]) { | ||
408 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_ECLK); | ||
409 | if (ret) { | ||
410 | pr_err("[SetupDefaultDpmTable] failed to get eclk dpm levels!"); | ||
411 | return ret; | ||
412 | } | ||
413 | } else { | ||
414 | single_dpm_table->count = 1; | ||
415 | single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.eclock / 100; | ||
416 | } | ||
417 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
418 | |||
419 | /* vclk */ | ||
420 | single_dpm_table = &(dpm_table->vclk_table); | ||
421 | |||
422 | if (feature->fea_enabled[FEATURE_DPM_UVD_BIT]) { | ||
423 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_VCLK); | ||
424 | if (ret) { | ||
425 | pr_err("[SetupDefaultDpmTable] failed to get vclk dpm levels!"); | ||
426 | return ret; | ||
427 | } | ||
428 | } else { | ||
429 | single_dpm_table->count = 1; | ||
430 | single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclock / 100; | ||
431 | } | ||
432 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
433 | |||
434 | /* dclk */ | ||
435 | single_dpm_table = &(dpm_table->dclk_table); | ||
436 | |||
437 | if (feature->fea_enabled[FEATURE_DPM_UVD_BIT]) { | ||
438 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_DCLK); | ||
439 | if (ret) { | ||
440 | pr_err("[SetupDefaultDpmTable] failed to get dclk dpm levels!"); | ||
441 | return ret; | ||
442 | } | ||
443 | } else { | ||
444 | single_dpm_table->count = 1; | ||
445 | single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclock / 100; | ||
446 | } | ||
447 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
448 | #endif | ||
449 | |||
450 | /* dcefclk */ | ||
451 | single_dpm_table = &(dpm_table->dcef_table); | ||
452 | |||
453 | if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { | ||
454 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
455 | PPCLK_DCEFCLK); | ||
456 | if (ret) { | ||
457 | pr_err("[SetupDefaultDpmTable] failed to get dcefclk dpm levels!"); | ||
458 | return ret; | ||
459 | } | ||
460 | } else { | ||
461 | single_dpm_table->count = 1; | ||
462 | single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; | ||
463 | } | ||
464 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
465 | |||
466 | /* pixclk */ | ||
467 | single_dpm_table = &(dpm_table->pixel_table); | ||
468 | |||
469 | if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { | ||
470 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
471 | PPCLK_PIXCLK); | ||
472 | if (ret) { | ||
473 | pr_err("[SetupDefaultDpmTable] failed to get pixclk dpm levels!"); | ||
474 | return ret; | ||
475 | } | ||
476 | } else { | ||
477 | single_dpm_table->count = 0; | ||
478 | } | ||
479 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
480 | |||
481 | /* dispclk */ | ||
482 | single_dpm_table = &(dpm_table->display_table); | ||
483 | |||
484 | if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { | ||
485 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
486 | PPCLK_DISPCLK); | ||
487 | if (ret) { | ||
488 | pr_err("[SetupDefaultDpmTable] failed to get dispclk dpm levels!"); | ||
489 | return ret; | ||
490 | } | ||
491 | } else { | ||
492 | single_dpm_table->count = 0; | ||
493 | } | ||
494 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
495 | |||
496 | /* phyclk */ | ||
497 | single_dpm_table = &(dpm_table->phy_table); | ||
498 | |||
499 | if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { | ||
500 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
501 | PPCLK_PHYCLK); | ||
502 | if (ret) { | ||
503 | pr_err("[SetupDefaultDpmTable] failed to get phyclk dpm levels!"); | ||
504 | return ret; | ||
505 | } | ||
506 | } else { | ||
507 | single_dpm_table->count = 0; | ||
508 | } | ||
509 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
510 | |||
511 | /* fclk */ | ||
512 | single_dpm_table = &(dpm_table->fclk_table); | ||
513 | |||
514 | if (smu_feature_is_enabled(smu,FEATURE_DPM_FCLK_BIT)) { | ||
515 | ret = vega20_set_single_dpm_table(smu, single_dpm_table, | ||
516 | PPCLK_FCLK); | ||
517 | if (ret) { | ||
518 | pr_err("[SetupDefaultDpmTable] failed to get fclk dpm levels!"); | ||
519 | return ret; | ||
520 | } | ||
521 | } else { | ||
522 | single_dpm_table->count = 0; | ||
523 | } | ||
524 | vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
294 | static const struct pptable_funcs vega20_ppt_funcs = { | 529 | static const struct pptable_funcs vega20_ppt_funcs = { |
295 | .alloc_dpm_context = vega20_allocate_dpm_context, | 530 | .alloc_dpm_context = vega20_allocate_dpm_context, |
296 | .store_powerplay_table = vega20_store_powerplay_table, | 531 | .store_powerplay_table = vega20_store_powerplay_table, |
@@ -299,6 +534,7 @@ static const struct pptable_funcs vega20_ppt_funcs = { | |||
299 | .get_smu_msg_index = vega20_get_smu_msg_index, | 534 | .get_smu_msg_index = vega20_get_smu_msg_index, |
300 | .run_afll_btc = vega20_run_btc_afll, | 535 | .run_afll_btc = vega20_run_btc_afll, |
301 | .get_unallowed_feature_mask = vega20_get_unallowed_feature_mask, | 536 | .get_unallowed_feature_mask = vega20_get_unallowed_feature_mask, |
537 | .set_default_dpm_table = vega20_set_default_dpm_table, | ||
302 | }; | 538 | }; |
303 | 539 | ||
304 | void vega20_set_ppt_funcs(struct smu_context *smu) | 540 | void vega20_set_ppt_funcs(struct smu_context *smu) |