Merge tag 'char-misc-5.15-rc1-lkdtm' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / pm / swsmu / smu12 / renoir_ppt.c
index f43b4c6..5aa175e 100644 (file)
@@ -109,6 +109,8 @@ static struct cmn2asic_mapping renoir_clk_map[SMU_CLK_COUNT] = {
        CLK_MAP(SOCCLK, CLOCK_SOCCLK),
        CLK_MAP(UCLK, CLOCK_FCLK),
        CLK_MAP(MCLK, CLOCK_FCLK),
+       CLK_MAP(VCLK, CLOCK_VCLK),
+       CLK_MAP(DCLK, CLOCK_DCLK),
 };
 
 static struct cmn2asic_mapping renoir_table_map[SMU_TABLE_COUNT] = {
@@ -126,6 +128,22 @@ static struct cmn2asic_mapping renoir_workload_map[PP_SMC_POWER_PROFILE_COUNT] =
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,               WORKLOAD_PPLIB_CUSTOM_BIT),
 };
 
+static const uint8_t renoir_throttler_map[] = {
+       [THROTTLER_STATUS_BIT_SPL]              = (SMU_THROTTLER_SPL_BIT),
+       [THROTTLER_STATUS_BIT_FPPT]             = (SMU_THROTTLER_FPPT_BIT),
+       [THROTTLER_STATUS_BIT_SPPT]             = (SMU_THROTTLER_SPPT_BIT),
+       [THROTTLER_STATUS_BIT_SPPT_APU]         = (SMU_THROTTLER_SPPT_APU_BIT),
+       [THROTTLER_STATUS_BIT_THM_CORE]         = (SMU_THROTTLER_TEMP_CORE_BIT),
+       [THROTTLER_STATUS_BIT_THM_GFX]          = (SMU_THROTTLER_TEMP_GPU_BIT),
+       [THROTTLER_STATUS_BIT_THM_SOC]          = (SMU_THROTTLER_TEMP_SOC_BIT),
+       [THROTTLER_STATUS_BIT_TDC_VDD]          = (SMU_THROTTLER_TDC_VDD_BIT),
+       [THROTTLER_STATUS_BIT_TDC_SOC]          = (SMU_THROTTLER_TDC_SOC_BIT),
+       [THROTTLER_STATUS_BIT_PROCHOT_CPU]      = (SMU_THROTTLER_PROCHOT_CPU_BIT),
+       [THROTTLER_STATUS_BIT_PROCHOT_GFX]      = (SMU_THROTTLER_PROCHOT_GFX_BIT),
+       [THROTTLER_STATUS_BIT_EDC_CPU]          = (SMU_THROTTLER_EDC_CPU_BIT),
+       [THROTTLER_STATUS_BIT_EDC_GFX]          = (SMU_THROTTLER_EDC_GFX_BIT),
+};
+
 static int renoir_init_smc_tables(struct smu_context *smu)
 {
        struct smu_table_context *smu_table = &smu->smu_table;
@@ -151,7 +169,7 @@ static int renoir_init_smc_tables(struct smu_context *smu)
        if (!smu_table->watermarks_table)
                goto err2_out;
 
-       smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_1);
+       smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
        smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
        if (!smu_table->gpu_metrics_table)
                goto err3_out;
@@ -202,6 +220,17 @@ static int renoir_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type
                        return -EINVAL;
                *freq = clk_table->FClocks[dpm_level].Freq;
                break;
+       case SMU_VCLK:
+               if (dpm_level >= NUM_VCN_DPM_LEVELS)
+                       return -EINVAL;
+               *freq = clk_table->VClocks[dpm_level].Freq;
+               break;
+       case SMU_DCLK:
+               if (dpm_level >= NUM_VCN_DPM_LEVELS)
+                       return -EINVAL;
+               *freq = clk_table->DClocks[dpm_level].Freq;
+               break;
+
        default:
                return -EINVAL;
        }
@@ -397,7 +426,7 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
                } else {
                        if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) {
                                dev_err(smu->adev->dev,
-                                       "The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
+                                       "The setting minimum sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
                                        smu->gfx_actual_hard_min_freq,
                                        smu->gfx_actual_soft_max_freq);
                                return -EINVAL;
@@ -481,16 +510,16 @@ static int renoir_print_clk_levels(struct smu_context *smu,
                                                0, &max);
                        if (ret)
                                return ret;
-                       size += sprintf(buf + size, "OD_RANGE\nSCLK: %10uMhz %10uMhz\n", min, max);
+                       size += sysfs_emit_at(buf, size, "OD_RANGE\nSCLK: %10uMhz %10uMhz\n", min, max);
                }
                break;
        case SMU_OD_SCLK:
                if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
                        min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
                        max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
-                       size += sprintf(buf + size, "OD_SCLK\n");
-                       size += sprintf(buf + size, "0:%10uMhz\n", min);
-                       size += sprintf(buf + size, "1:%10uMhz\n", max);
+                       size += sysfs_emit_at(buf, size, "OD_SCLK\n");
+                       size += sysfs_emit_at(buf, size, "0:%10uMhz\n", min);
+                       size += sysfs_emit_at(buf, size, "1:%10uMhz\n", max);
                }
                break;
        case SMU_GFXCLK:
@@ -507,12 +536,12 @@ static int renoir_print_clk_levels(struct smu_context *smu,
                        else
                                i = 1;
 
-                       size += sprintf(buf + size, "0: %uMhz %s\n", min,
+                       size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
                                        i == 0 ? "*" : "");
-                       size += sprintf(buf + size, "1: %uMhz %s\n",
+                       size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
                                        i == 1 ? cur_value : RENOIR_UMD_PSTATE_GFXCLK,
                                        i == 1 ? "*" : "");
-                       size += sprintf(buf + size, "2: %uMhz %s\n", max,
+                       size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
                                        i == 2 ? "*" : "");
                }
                return size;
@@ -532,6 +561,14 @@ static int renoir_print_clk_levels(struct smu_context *smu,
                count = NUM_FCLK_DPM_LEVELS;
                cur_value = metrics.ClockFrequency[CLOCK_FCLK];
                break;
+       case SMU_VCLK:
+               count = NUM_VCN_DPM_LEVELS;
+               cur_value = metrics.ClockFrequency[CLOCK_VCLK];
+               break;
+       case SMU_DCLK:
+               count = NUM_VCN_DPM_LEVELS;
+               cur_value = metrics.ClockFrequency[CLOCK_DCLK];
+               break;
        default:
                break;
        }
@@ -543,20 +580,22 @@ static int renoir_print_clk_levels(struct smu_context *smu,
        case SMU_MCLK:
        case SMU_DCEFCLK:
        case SMU_FCLK:
+       case SMU_VCLK:
+       case SMU_DCLK:
                for (i = 0; i < count; i++) {
                        ret = renoir_get_dpm_clk_limited(smu, clk_type, i, &value);
                        if (ret)
                                return ret;
                        if (!value)
                                continue;
-                       size += sprintf(buf + size, "%d: %uMhz %s\n", i, value,
+                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value,
                                        cur_value == value ? "*" : "");
                        if (cur_value == value)
                                cur_value_match_level = true;
                }
 
                if (!cur_value_match_level)
-                       size += sprintf(buf + size, "   %uMhz *\n", cur_value);
+                       size += sysfs_emit_at(buf, size, "   %uMhz *\n", cur_value);
 
                break;
        default:
@@ -730,6 +769,16 @@ static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks
                clock_table->MemClocks[i].Vol = table->MemClocks[i].Vol;
        }
 
+       for (i = 0; i < NUM_VCN_DPM_LEVELS; i++) {
+               clock_table->VClocks[i].Freq = table->VClocks[i].Freq;
+               clock_table->VClocks[i].Vol = table->VClocks[i].Vol;
+       }
+
+       for (i = 0; i < NUM_VCN_DPM_LEVELS; i++) {
+               clock_table->DClocks[i].Freq = table->DClocks[i].Freq;
+               clock_table->DClocks[i].Vol = table->DClocks[i].Vol;
+       }
+
        return 0;
 }
 
@@ -1069,7 +1118,7 @@ static int renoir_get_power_profile_mode(struct smu_context *smu,
                if (workload_type < 0)
                        continue;
 
-               size += sprintf(buf + size, "%2d %14s%s\n",
+               size += sysfs_emit_at(buf, size, "%2d %14s%s\n",
                        i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
        }
 
@@ -1131,6 +1180,28 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu,
        case METRICS_VOLTAGE_VDDSOC:
                *value = metrics->Voltage[1];
                break;
+       case METRICS_SS_APU_SHARE:
+               /* return the percentage of APU power with respect to APU's power limit.
+                * percentage is reported, this isn't boost value. Smartshift power
+                * boost/shift is only when the percentage is more than 100.
+                */
+               if (metrics->StapmOriginalLimit > 0)
+                       *value =  (metrics->ApuPower * 100) / metrics->StapmOriginalLimit;
+               else
+                       *value = 0;
+               break;
+       case METRICS_SS_DGPU_SHARE:
+               /* return the percentage of dGPU power with respect to dGPU's power limit.
+                * percentage is reported, this isn't boost value. Smartshift power
+                * boost/shift is only when the percentage is more than 100.
+                */
+               if ((metrics->dGpuPower > 0) &&
+                   (metrics->StapmCurrentLimit > metrics->StapmOriginalLimit))
+                       *value = (metrics->dGpuPower * 100) /
+                                 (metrics->StapmCurrentLimit - metrics->StapmOriginalLimit);
+               else
+                       *value = 0;
+               break;
        default:
                *value = UINT_MAX;
                break;
@@ -1202,6 +1273,18 @@ static int renoir_read_sensor(struct smu_context *smu,
                                                  (uint32_t *)data);
                *size = 4;
                break;
+       case AMDGPU_PP_SENSOR_SS_APU_SHARE:
+               ret = renoir_get_smu_metrics_data(smu,
+                                                 METRICS_SS_APU_SHARE,
+                                                 (uint32_t *)data);
+               *size = 4;
+               break;
+       case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
+               ret = renoir_get_smu_metrics_data(smu,
+                                                 METRICS_SS_DGPU_SHARE,
+                                                 (uint32_t *)data);
+               *size = 4;
+               break;
        default:
                ret = -EOPNOTSUPP;
                break;
@@ -1231,8 +1314,8 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
                                      void **table)
 {
        struct smu_table_context *smu_table = &smu->smu_table;
-       struct gpu_metrics_v2_1 *gpu_metrics =
-               (struct gpu_metrics_v2_1 *)smu_table->gpu_metrics_table;
+       struct gpu_metrics_v2_2 *gpu_metrics =
+               (struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
        SmuMetrics_t metrics;
        int ret = 0;
 
@@ -1240,7 +1323,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
        if (ret)
                return ret;
 
-       smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 1);
+       smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
 
        gpu_metrics->temperature_gfx = metrics.GfxTemperature;
        gpu_metrics->temperature_soc = metrics.SocTemperature;
@@ -1278,6 +1361,9 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
        gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1];
 
        gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+       gpu_metrics->indep_throttle_status =
+               smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+                                                  renoir_throttler_map);
 
        gpu_metrics->fan_pwm = metrics.FanPwm;
 
@@ -1285,7 +1371,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
 
        *table = (void *)gpu_metrics;
 
-       return sizeof(struct gpu_metrics_v2_1);
+       return sizeof(struct gpu_metrics_v2_2);
 }
 
 static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state)