forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
....@@ -24,8 +24,7 @@
2424 #include <linux/string.h>
2525 #include <linux/acpi.h>
2626
27
-#include <drm/drmP.h>
28
-#include <drm/drm_crtc_helper.h>
27
+#include <drm/drm_probe_helper.h>
2928 #include <drm/amdgpu_drm.h>
3029 #include "dm_services.h"
3130 #include "amdgpu.h"
....@@ -33,6 +32,7 @@
3332 #include "amdgpu_dm_irq.h"
3433 #include "amdgpu_pm.h"
3534 #include "dm_pp_smu.h"
35
+#include "amdgpu_smu.h"
3636
3737
3838 bool dm_pp_apply_display_requirements(
....@@ -40,6 +40,7 @@
4040 const struct dm_pp_display_configuration *pp_display_cfg)
4141 {
4242 struct amdgpu_device *adev = ctx->driver_context;
43
+ struct smu_context *smu = &adev->smu;
4344 int i;
4445
4546 if (adev->pm.dpm_enabled) {
....@@ -101,17 +102,14 @@
101102 adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1;
102103 }
103104
104
- /* TODO: complete implementation of
105
- * pp_display_configuration_change().
106
- * Follow example of:
107
- * PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c
108
- * PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */
109
- if (adev->powerplay.pp_funcs->display_configuration_change)
105
+ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_configuration_change)
110106 adev->powerplay.pp_funcs->display_configuration_change(
111107 adev->powerplay.pp_handle,
112108 &adev->pm.pm_display_cfg);
109
+ else if (adev->smu.ppt_funcs)
110
+ smu_display_configuration_change(smu,
111
+ &adev->pm.pm_display_cfg);
113112
114
- /* TODO: replace by a separate call to 'apply display cfg'? */
115113 amdgpu_pm_compute_clocks(adev);
116114 }
117115
....@@ -148,6 +146,36 @@
148146 clks->num_levels = 0;
149147 break;
150148 }
149
+}
150
+
151
+static enum smu_clk_type dc_to_smu_clock_type(
152
+ enum dm_pp_clock_type dm_pp_clk_type)
153
+{
154
+ enum smu_clk_type smu_clk_type = SMU_CLK_COUNT;
155
+
156
+ switch (dm_pp_clk_type) {
157
+ case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
158
+ smu_clk_type = SMU_DISPCLK;
159
+ break;
160
+ case DM_PP_CLOCK_TYPE_ENGINE_CLK:
161
+ smu_clk_type = SMU_GFXCLK;
162
+ break;
163
+ case DM_PP_CLOCK_TYPE_MEMORY_CLK:
164
+ smu_clk_type = SMU_MCLK;
165
+ break;
166
+ case DM_PP_CLOCK_TYPE_DCEFCLK:
167
+ smu_clk_type = SMU_DCEFCLK;
168
+ break;
169
+ case DM_PP_CLOCK_TYPE_SOCCLK:
170
+ smu_clk_type = SMU_SOCCLK;
171
+ break;
172
+ default:
173
+ DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n",
174
+ dm_pp_clk_type);
175
+ break;
176
+ }
177
+
178
+ return smu_clk_type;
151179 }
152180
153181 static enum amd_pp_clock_type dc_to_pp_clock_type(
....@@ -293,7 +321,8 @@
293321 DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
294322
295323 for (i = 0; i < clk_level_info->num_levels; i++) {
296
- DRM_INFO("DM_PPLIB:\t %d in kHz\n", pp_clks->data[i].clocks_in_khz);
324
+ DRM_INFO("DM_PPLIB:\t %d in kHz, %d in mV\n", pp_clks->data[i].clocks_in_khz,
325
+ pp_clks->data[i].voltage_in_mv);
297326 clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz;
298327 clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv;
299328 }
....@@ -310,10 +339,17 @@
310339 struct amd_pp_simple_clock_info validation_clks = { 0 };
311340 uint32_t i;
312341
313
- if (adev->powerplay.pp_funcs->get_clock_by_type) {
342
+ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
314343 if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
315344 dc_to_pp_clock_type(clk_type), &pp_clks)) {
316
- /* Error in pplib. Provide default values. */
345
+ /* Error in pplib. Provide default values. */
346
+ get_default_clock_levels(clk_type, dc_clks);
347
+ return true;
348
+ }
349
+ } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type) {
350
+ if (smu_get_clock_by_type(&adev->smu,
351
+ dc_to_pp_clock_type(clk_type),
352
+ &pp_clks)) {
317353 get_default_clock_levels(clk_type, dc_clks);
318354 return true;
319355 }
....@@ -321,10 +357,17 @@
321357
322358 pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
323359
324
- if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
360
+ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
325361 if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
326362 pp_handle, &validation_clks)) {
327363 /* Error in pplib. Provide default values. */
364
+ DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
365
+ validation_clks.engine_max_clock = 72000;
366
+ validation_clks.memory_max_clock = 80000;
367
+ validation_clks.level = 0;
368
+ }
369
+ } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_max_high_clocks) {
370
+ if (smu_get_max_high_clocks(&adev->smu, &validation_clks)) {
328371 DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
329372 validation_clks.engine_max_clock = 72000;
330373 validation_clks.memory_max_clock = 80000;
....@@ -380,14 +423,21 @@
380423 void *pp_handle = adev->powerplay.pp_handle;
381424 struct pp_clock_levels_with_latency pp_clks = { 0 };
382425 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
426
+ int ret;
383427
384
- if (!pp_funcs || !pp_funcs->get_clock_by_type_with_latency)
385
- return false;
428
+ if (pp_funcs && pp_funcs->get_clock_by_type_with_latency) {
429
+ ret = pp_funcs->get_clock_by_type_with_latency(pp_handle,
430
+ dc_to_pp_clock_type(clk_type),
431
+ &pp_clks);
432
+ if (ret)
433
+ return false;
434
+ } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_latency) {
435
+ if (smu_get_clock_by_type_with_latency(&adev->smu,
436
+ dc_to_smu_clock_type(clk_type),
437
+ &pp_clks))
438
+ return false;
439
+ }
386440
387
- if (pp_funcs->get_clock_by_type_with_latency(pp_handle,
388
- dc_to_pp_clock_type(clk_type),
389
- &pp_clks))
390
- return false;
391441
392442 pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type);
393443
....@@ -403,11 +453,20 @@
403453 void *pp_handle = adev->powerplay.pp_handle;
404454 struct pp_clock_levels_with_voltage pp_clk_info = {0};
405455 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
456
+ int ret;
406457
407
- if (pp_funcs->get_clock_by_type_with_voltage(pp_handle,
408
- dc_to_pp_clock_type(clk_type),
409
- &pp_clk_info))
410
- return false;
458
+ if (pp_funcs && pp_funcs->get_clock_by_type_with_voltage) {
459
+ ret = pp_funcs->get_clock_by_type_with_voltage(pp_handle,
460
+ dc_to_pp_clock_type(clk_type),
461
+ &pp_clk_info);
462
+ if (ret)
463
+ return false;
464
+ } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_voltage) {
465
+ if (smu_get_clock_by_type_with_voltage(&adev->smu,
466
+ dc_to_pp_clock_type(clk_type),
467
+ &pp_clk_info))
468
+ return false;
469
+ }
411470
412471 pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type);
413472
....@@ -444,10 +503,14 @@
444503 if (!pp_clock_request.clock_type)
445504 return false;
446505
447
- if (adev->powerplay.pp_funcs->display_clock_voltage_request)
506
+ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_clock_voltage_request)
448507 ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
449508 adev->powerplay.pp_handle,
450509 &pp_clock_request);
510
+ else if (adev->smu.ppt_funcs &&
511
+ adev->smu.ppt_funcs->display_clock_voltage_request)
512
+ ret = smu_display_clock_voltage_request(&adev->smu,
513
+ &pp_clock_request);
451514 if (ret)
452515 return false;
453516 return true;
....@@ -461,10 +524,14 @@
461524 struct amd_pp_clock_info pp_clk_info = {0};
462525 int ret = 0;
463526
464
- if (adev->powerplay.pp_funcs->get_current_clocks)
527
+ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_current_clocks)
465528 ret = adev->powerplay.pp_funcs->get_current_clocks(
466529 adev->powerplay.pp_handle,
467530 &pp_clk_info);
531
+ else if (adev->smu.ppt_funcs)
532
+ ret = smu_get_current_clocks(&adev->smu, &pp_clk_info);
533
+ else
534
+ return false;
468535 if (ret)
469536 return false;
470537
....@@ -475,31 +542,10 @@
475542 return true;
476543 }
477544
478
-void pp_rv_set_display_requirement(struct pp_smu *pp,
479
- struct pp_smu_display_requirement_rv *req)
480
-{
481
- struct dc_context *ctx = pp->ctx;
482
- struct amdgpu_device *adev = ctx->driver_context;
483
- void *pp_handle = adev->powerplay.pp_handle;
484
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
485
- struct pp_display_clock_request clock = {0};
486
-
487
- if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
488
- return;
489
-
490
- clock.clock_type = amd_pp_dcf_clock;
491
- clock.clock_freq_in_khz = req->hard_min_dcefclk_khz;
492
- pp_funcs->display_clock_voltage_request(pp_handle, &clock);
493
-
494
- clock.clock_type = amd_pp_f_clock;
495
- clock.clock_freq_in_khz = req->hard_min_fclk_khz;
496
- pp_funcs->display_clock_voltage_request(pp_handle, &clock);
497
-}
498
-
499545 void pp_rv_set_wm_ranges(struct pp_smu *pp,
500546 struct pp_smu_wm_range_sets *ranges)
501547 {
502
- struct dc_context *ctx = pp->ctx;
548
+ const struct dc_context *ctx = pp->dm;
503549 struct amdgpu_device *adev = ctx->driver_context;
504550 void *pp_handle = adev->powerplay.pp_handle;
505551 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
....@@ -518,13 +564,13 @@
518564 wm_dce_clocks[i].wm_set_id =
519565 ranges->reader_wm_sets[i].wm_inst;
520566 wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz =
521
- ranges->reader_wm_sets[i].max_drain_clk_khz;
567
+ ranges->reader_wm_sets[i].max_drain_clk_mhz * 1000;
522568 wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz =
523
- ranges->reader_wm_sets[i].min_drain_clk_khz;
569
+ ranges->reader_wm_sets[i].min_drain_clk_mhz * 1000;
524570 wm_dce_clocks[i].wm_max_mem_clk_in_khz =
525
- ranges->reader_wm_sets[i].max_fill_clk_khz;
571
+ ranges->reader_wm_sets[i].max_fill_clk_mhz * 1000;
526572 wm_dce_clocks[i].wm_min_mem_clk_in_khz =
527
- ranges->reader_wm_sets[i].min_fill_clk_khz;
573
+ ranges->reader_wm_sets[i].min_fill_clk_mhz * 1000;
528574 }
529575
530576 for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) {
....@@ -534,37 +580,359 @@
534580 wm_soc_clocks[i].wm_set_id =
535581 ranges->writer_wm_sets[i].wm_inst;
536582 wm_soc_clocks[i].wm_max_socclk_clk_in_khz =
537
- ranges->writer_wm_sets[i].max_fill_clk_khz;
583
+ ranges->writer_wm_sets[i].max_fill_clk_mhz * 1000;
538584 wm_soc_clocks[i].wm_min_socclk_clk_in_khz =
539
- ranges->writer_wm_sets[i].min_fill_clk_khz;
585
+ ranges->writer_wm_sets[i].min_fill_clk_mhz * 1000;
540586 wm_soc_clocks[i].wm_max_mem_clk_in_khz =
541
- ranges->writer_wm_sets[i].max_drain_clk_khz;
587
+ ranges->writer_wm_sets[i].max_drain_clk_mhz * 1000;
542588 wm_soc_clocks[i].wm_min_mem_clk_in_khz =
543
- ranges->writer_wm_sets[i].min_drain_clk_khz;
589
+ ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
544590 }
545591
546
- pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges);
592
+ if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
593
+ pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
594
+ &wm_with_clock_ranges);
547595 }
548596
549597 void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
550598 {
551
- struct dc_context *ctx = pp->ctx;
599
+ const struct dc_context *ctx = pp->dm;
552600 struct amdgpu_device *adev = ctx->driver_context;
553601 void *pp_handle = adev->powerplay.pp_handle;
554602 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
555603
556
- if (!pp_funcs || !pp_funcs->notify_smu_enable_pwe)
557
- return;
558
-
559
- pp_funcs->notify_smu_enable_pwe(pp_handle);
604
+ if (pp_funcs && pp_funcs->notify_smu_enable_pwe)
605
+ pp_funcs->notify_smu_enable_pwe(pp_handle);
606
+ else if (adev->smu.ppt_funcs)
607
+ smu_notify_smu_enable_pwe(&adev->smu);
560608 }
561609
562
-void dm_pp_get_funcs_rv(
563
- struct dc_context *ctx,
564
- struct pp_smu_funcs_rv *funcs)
610
+void pp_rv_set_active_display_count(struct pp_smu *pp, int count)
565611 {
566
- funcs->pp_smu.ctx = ctx;
567
- funcs->set_display_requirement = pp_rv_set_display_requirement;
568
- funcs->set_wm_ranges = pp_rv_set_wm_ranges;
569
- funcs->set_pme_wa_enable = pp_rv_set_pme_wa_enable;
612
+ const struct dc_context *ctx = pp->dm;
613
+ struct amdgpu_device *adev = ctx->driver_context;
614
+ void *pp_handle = adev->powerplay.pp_handle;
615
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
616
+
617
+ if (!pp_funcs || !pp_funcs->set_active_display_count)
618
+ return;
619
+
620
+ pp_funcs->set_active_display_count(pp_handle, count);
621
+}
622
+
623
+void pp_rv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int clock)
624
+{
625
+ const struct dc_context *ctx = pp->dm;
626
+ struct amdgpu_device *adev = ctx->driver_context;
627
+ void *pp_handle = adev->powerplay.pp_handle;
628
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
629
+
630
+ if (!pp_funcs || !pp_funcs->set_min_deep_sleep_dcefclk)
631
+ return;
632
+
633
+ pp_funcs->set_min_deep_sleep_dcefclk(pp_handle, clock);
634
+}
635
+
636
+void pp_rv_set_hard_min_dcefclk_by_freq(struct pp_smu *pp, int clock)
637
+{
638
+ const struct dc_context *ctx = pp->dm;
639
+ struct amdgpu_device *adev = ctx->driver_context;
640
+ void *pp_handle = adev->powerplay.pp_handle;
641
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
642
+
643
+ if (!pp_funcs || !pp_funcs->set_hard_min_dcefclk_by_freq)
644
+ return;
645
+
646
+ pp_funcs->set_hard_min_dcefclk_by_freq(pp_handle, clock);
647
+}
648
+
649
+void pp_rv_set_hard_min_fclk_by_freq(struct pp_smu *pp, int mhz)
650
+{
651
+ const struct dc_context *ctx = pp->dm;
652
+ struct amdgpu_device *adev = ctx->driver_context;
653
+ void *pp_handle = adev->powerplay.pp_handle;
654
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
655
+
656
+ if (!pp_funcs || !pp_funcs->set_hard_min_fclk_by_freq)
657
+ return;
658
+
659
+ pp_funcs->set_hard_min_fclk_by_freq(pp_handle, mhz);
660
+}
661
+
662
+static enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp,
663
+ struct pp_smu_wm_range_sets *ranges)
664
+{
665
+ const struct dc_context *ctx = pp->dm;
666
+ struct amdgpu_device *adev = ctx->driver_context;
667
+
668
+ smu_set_watermarks_for_clock_ranges(&adev->smu, ranges);
669
+
670
+ return PP_SMU_RESULT_OK;
671
+}
672
+
673
+enum pp_smu_status pp_nv_set_pme_wa_enable(struct pp_smu *pp)
674
+{
675
+ const struct dc_context *ctx = pp->dm;
676
+ struct amdgpu_device *adev = ctx->driver_context;
677
+ struct smu_context *smu = &adev->smu;
678
+
679
+ if (!smu->ppt_funcs)
680
+ return PP_SMU_RESULT_UNSUPPORTED;
681
+
682
+ /* 0: successful or smu.ppt_funcs->set_azalia_d3_pme = NULL; 1: fail */
683
+ if (smu_set_azalia_d3_pme(smu))
684
+ return PP_SMU_RESULT_FAIL;
685
+
686
+ return PP_SMU_RESULT_OK;
687
+}
688
+
689
+static enum pp_smu_status pp_nv_set_display_count(struct pp_smu *pp, int count)
690
+{
691
+ const struct dc_context *ctx = pp->dm;
692
+ struct amdgpu_device *adev = ctx->driver_context;
693
+ struct smu_context *smu = &adev->smu;
694
+
695
+ if (!smu->ppt_funcs)
696
+ return PP_SMU_RESULT_UNSUPPORTED;
697
+
698
+ /* 0: successful or smu.ppt_funcs->set_display_count = NULL; 1: fail */
699
+ if (smu_set_display_count(smu, count))
700
+ return PP_SMU_RESULT_FAIL;
701
+
702
+ return PP_SMU_RESULT_OK;
703
+}
704
+
705
+static enum pp_smu_status
706
+pp_nv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int mhz)
707
+{
708
+ const struct dc_context *ctx = pp->dm;
709
+ struct amdgpu_device *adev = ctx->driver_context;
710
+ struct smu_context *smu = &adev->smu;
711
+
712
+ if (!smu->ppt_funcs)
713
+ return PP_SMU_RESULT_UNSUPPORTED;
714
+
715
+ /* 0: successful or smu.ppt_funcs->set_deep_sleep_dcefclk = NULL;1: fail */
716
+ if (smu_set_deep_sleep_dcefclk(smu, mhz))
717
+ return PP_SMU_RESULT_FAIL;
718
+
719
+ return PP_SMU_RESULT_OK;
720
+}
721
+
722
+static enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq(
723
+ struct pp_smu *pp, int mhz)
724
+{
725
+ const struct dc_context *ctx = pp->dm;
726
+ struct amdgpu_device *adev = ctx->driver_context;
727
+ struct smu_context *smu = &adev->smu;
728
+ struct pp_display_clock_request clock_req;
729
+
730
+ if (!smu->ppt_funcs)
731
+ return PP_SMU_RESULT_UNSUPPORTED;
732
+
733
+ clock_req.clock_type = amd_pp_dcef_clock;
734
+ clock_req.clock_freq_in_khz = mhz * 1000;
735
+
736
+ /* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
737
+ * 1: fail
738
+ */
739
+ if (smu_display_clock_voltage_request(smu, &clock_req))
740
+ return PP_SMU_RESULT_FAIL;
741
+
742
+ return PP_SMU_RESULT_OK;
743
+}
744
+
745
+static enum pp_smu_status
746
+pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz)
747
+{
748
+ const struct dc_context *ctx = pp->dm;
749
+ struct amdgpu_device *adev = ctx->driver_context;
750
+ struct smu_context *smu = &adev->smu;
751
+ struct pp_display_clock_request clock_req;
752
+
753
+ if (!smu->ppt_funcs)
754
+ return PP_SMU_RESULT_UNSUPPORTED;
755
+
756
+ clock_req.clock_type = amd_pp_mem_clock;
757
+ clock_req.clock_freq_in_khz = mhz * 1000;
758
+
759
+ /* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
760
+ * 1: fail
761
+ */
762
+ if (smu_display_clock_voltage_request(smu, &clock_req))
763
+ return PP_SMU_RESULT_FAIL;
764
+
765
+ return PP_SMU_RESULT_OK;
766
+}
767
+
768
+static enum pp_smu_status pp_nv_set_pstate_handshake_support(
769
+ struct pp_smu *pp, bool pstate_handshake_supported)
770
+{
771
+ const struct dc_context *ctx = pp->dm;
772
+ struct amdgpu_device *adev = ctx->driver_context;
773
+ struct smu_context *smu = &adev->smu;
774
+
775
+ if (smu_display_disable_memory_clock_switch(smu, !pstate_handshake_supported))
776
+ return PP_SMU_RESULT_FAIL;
777
+
778
+ return PP_SMU_RESULT_OK;
779
+}
780
+
781
+static enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp,
782
+ enum pp_smu_nv_clock_id clock_id, int mhz)
783
+{
784
+ const struct dc_context *ctx = pp->dm;
785
+ struct amdgpu_device *adev = ctx->driver_context;
786
+ struct smu_context *smu = &adev->smu;
787
+ struct pp_display_clock_request clock_req;
788
+
789
+ if (!smu->ppt_funcs)
790
+ return PP_SMU_RESULT_UNSUPPORTED;
791
+
792
+ switch (clock_id) {
793
+ case PP_SMU_NV_DISPCLK:
794
+ clock_req.clock_type = amd_pp_disp_clock;
795
+ break;
796
+ case PP_SMU_NV_PHYCLK:
797
+ clock_req.clock_type = amd_pp_phy_clock;
798
+ break;
799
+ case PP_SMU_NV_PIXELCLK:
800
+ clock_req.clock_type = amd_pp_pixel_clock;
801
+ break;
802
+ default:
803
+ break;
804
+ }
805
+ clock_req.clock_freq_in_khz = mhz * 1000;
806
+
807
+ /* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
808
+ * 1: fail
809
+ */
810
+ if (smu_display_clock_voltage_request(smu, &clock_req))
811
+ return PP_SMU_RESULT_FAIL;
812
+
813
+ return PP_SMU_RESULT_OK;
814
+}
815
+
816
+static enum pp_smu_status pp_nv_get_maximum_sustainable_clocks(
817
+ struct pp_smu *pp, struct pp_smu_nv_clock_table *max_clocks)
818
+{
819
+ const struct dc_context *ctx = pp->dm;
820
+ struct amdgpu_device *adev = ctx->driver_context;
821
+ struct smu_context *smu = &adev->smu;
822
+
823
+ if (!smu->ppt_funcs)
824
+ return PP_SMU_RESULT_UNSUPPORTED;
825
+
826
+ if (!smu->ppt_funcs->get_max_sustainable_clocks_by_dc)
827
+ return PP_SMU_RESULT_UNSUPPORTED;
828
+
829
+ if (!smu_get_max_sustainable_clocks_by_dc(smu, max_clocks))
830
+ return PP_SMU_RESULT_OK;
831
+
832
+ return PP_SMU_RESULT_FAIL;
833
+}
834
+
835
+static enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp,
836
+ unsigned int *clock_values_in_khz, unsigned int *num_states)
837
+{
838
+ const struct dc_context *ctx = pp->dm;
839
+ struct amdgpu_device *adev = ctx->driver_context;
840
+ struct smu_context *smu = &adev->smu;
841
+
842
+ if (!smu->ppt_funcs)
843
+ return PP_SMU_RESULT_UNSUPPORTED;
844
+
845
+ if (!smu->ppt_funcs->get_uclk_dpm_states)
846
+ return PP_SMU_RESULT_UNSUPPORTED;
847
+
848
+ if (!smu_get_uclk_dpm_states(smu,
849
+ clock_values_in_khz, num_states))
850
+ return PP_SMU_RESULT_OK;
851
+
852
+ return PP_SMU_RESULT_FAIL;
853
+}
854
+
855
+static enum pp_smu_status pp_rn_get_dpm_clock_table(
856
+ struct pp_smu *pp, struct dpm_clocks *clock_table)
857
+{
858
+ const struct dc_context *ctx = pp->dm;
859
+ struct amdgpu_device *adev = ctx->driver_context;
860
+ struct smu_context *smu = &adev->smu;
861
+
862
+ if (!smu->ppt_funcs)
863
+ return PP_SMU_RESULT_UNSUPPORTED;
864
+
865
+ if (!smu->ppt_funcs->get_dpm_clock_table)
866
+ return PP_SMU_RESULT_UNSUPPORTED;
867
+
868
+ if (!smu_get_dpm_clock_table(smu, clock_table))
869
+ return PP_SMU_RESULT_OK;
870
+
871
+ return PP_SMU_RESULT_FAIL;
872
+}
873
+
874
+static enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp,
875
+ struct pp_smu_wm_range_sets *ranges)
876
+{
877
+ const struct dc_context *ctx = pp->dm;
878
+ struct amdgpu_device *adev = ctx->driver_context;
879
+
880
+ smu_set_watermarks_for_clock_ranges(&adev->smu, ranges);
881
+
882
+ return PP_SMU_RESULT_OK;
883
+}
884
+
885
+void dm_pp_get_funcs(
886
+ struct dc_context *ctx,
887
+ struct pp_smu_funcs *funcs)
888
+{
889
+ switch (ctx->dce_version) {
890
+ case DCN_VERSION_1_0:
891
+ case DCN_VERSION_1_01:
892
+ funcs->ctx.ver = PP_SMU_VER_RV;
893
+ funcs->rv_funcs.pp_smu.dm = ctx;
894
+ funcs->rv_funcs.set_wm_ranges = pp_rv_set_wm_ranges;
895
+ funcs->rv_funcs.set_pme_wa_enable = pp_rv_set_pme_wa_enable;
896
+ funcs->rv_funcs.set_display_count =
897
+ pp_rv_set_active_display_count;
898
+ funcs->rv_funcs.set_min_deep_sleep_dcfclk =
899
+ pp_rv_set_min_deep_sleep_dcfclk;
900
+ funcs->rv_funcs.set_hard_min_dcfclk_by_freq =
901
+ pp_rv_set_hard_min_dcefclk_by_freq;
902
+ funcs->rv_funcs.set_hard_min_fclk_by_freq =
903
+ pp_rv_set_hard_min_fclk_by_freq;
904
+ break;
905
+ case DCN_VERSION_2_0:
906
+ funcs->ctx.ver = PP_SMU_VER_NV;
907
+ funcs->nv_funcs.pp_smu.dm = ctx;
908
+ funcs->nv_funcs.set_display_count = pp_nv_set_display_count;
909
+ funcs->nv_funcs.set_hard_min_dcfclk_by_freq =
910
+ pp_nv_set_hard_min_dcefclk_by_freq;
911
+ funcs->nv_funcs.set_min_deep_sleep_dcfclk =
912
+ pp_nv_set_min_deep_sleep_dcfclk;
913
+ funcs->nv_funcs.set_voltage_by_freq =
914
+ pp_nv_set_voltage_by_freq;
915
+ funcs->nv_funcs.set_wm_ranges = pp_nv_set_wm_ranges;
916
+
917
+ /* todo set_pme_wa_enable cause 4k@6ohz display not light up */
918
+ funcs->nv_funcs.set_pme_wa_enable = NULL;
919
+ /* todo debug waring message */
920
+ funcs->nv_funcs.set_hard_min_uclk_by_freq = pp_nv_set_hard_min_uclk_by_freq;
921
+ /* todo compare data with window driver*/
922
+ funcs->nv_funcs.get_maximum_sustainable_clocks = pp_nv_get_maximum_sustainable_clocks;
923
+ /*todo compare data with window driver */
924
+ funcs->nv_funcs.get_uclk_dpm_states = pp_nv_get_uclk_dpm_states;
925
+ funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support;
926
+ break;
927
+
928
+ case DCN_VERSION_2_1:
929
+ funcs->ctx.ver = PP_SMU_VER_RN;
930
+ funcs->rn_funcs.pp_smu.dm = ctx;
931
+ funcs->rn_funcs.set_wm_ranges = pp_rn_set_wm_ranges;
932
+ funcs->rn_funcs.get_dpm_clock_table = pp_rn_get_dpm_clock_table;
933
+ break;
934
+ default:
935
+ DRM_ERROR("smu version is not supported !\n");
936
+ break;
937
+ }
570938 }