1 /* 2 * Copyright 2015 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include <linux/string.h> 27 #include <linux/acpi.h> 28 29 #include <drm/drmP.h> 30 #include <drm/drm_crtc_helper.h> 31 #include <drm/amdgpu_drm.h> 32 #include "dm_services.h" 33 #include "amdgpu.h" 34 #include "amdgpu_dm.h" 35 #include "amdgpu_dm_irq.h" 36 #include "amdgpu_pm.h" 37 38 unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, 39 unsigned long long current_time_stamp, 40 unsigned long long last_time_stamp) 41 { 42 return current_time_stamp - last_time_stamp; 43 } 44 45 void dm_perf_trace_timestamp(const char *func_name, unsigned int line) 46 { 47 } 48 49 bool dm_write_persistent_data(struct dc_context *ctx, 50 const struct dc_sink *sink, 51 const char *module_name, 52 const char *key_name, 53 void *params, 54 unsigned int size, 55 struct persistent_data_flag *flag) 56 { 57 /*TODO implement*/ 58 return false; 59 } 60 61 bool dm_read_persistent_data(struct dc_context *ctx, 62 const struct dc_sink *sink, 63 const char *module_name, 64 const char *key_name, 65 void *params, 66 unsigned int size, 67 struct persistent_data_flag *flag) 68 { 69 /*TODO implement*/ 70 return false; 71 } 72 73 /**** power component interfaces ****/ 74 75 bool dm_pp_apply_display_requirements( 76 const struct dc_context *ctx, 77 const struct dm_pp_display_configuration *pp_display_cfg) 78 { 79 struct amdgpu_device *adev = ctx->driver_context; 80 81 if (adev->pm.dpm_enabled) { 82 83 memset(&adev->pm.pm_display_cfg, 0, 84 sizeof(adev->pm.pm_display_cfg)); 85 86 adev->pm.pm_display_cfg.cpu_cc6_disable = 87 pp_display_cfg->cpu_cc6_disable; 88 89 adev->pm.pm_display_cfg.cpu_pstate_disable = 90 pp_display_cfg->cpu_pstate_disable; 91 92 adev->pm.pm_display_cfg.cpu_pstate_separation_time = 93 pp_display_cfg->cpu_pstate_separation_time; 94 95 adev->pm.pm_display_cfg.nb_pstate_switch_disable = 96 pp_display_cfg->nb_pstate_switch_disable; 97 98 adev->pm.pm_display_cfg.num_display = 99 pp_display_cfg->display_count; 100 adev->pm.pm_display_cfg.num_path_including_non_display = 101 pp_display_cfg->display_count; 102 103 adev->pm.pm_display_cfg.min_core_set_clock = 104 pp_display_cfg->min_engine_clock_khz/10; 105 adev->pm.pm_display_cfg.min_core_set_clock_in_sr = 106 pp_display_cfg->min_engine_clock_deep_sleep_khz/10; 107 adev->pm.pm_display_cfg.min_mem_set_clock = 108 pp_display_cfg->min_memory_clock_khz/10; 109 110 adev->pm.pm_display_cfg.multi_monitor_in_sync = 111 pp_display_cfg->all_displays_in_sync; 112 adev->pm.pm_display_cfg.min_vblank_time = 113 pp_display_cfg->avail_mclk_switch_time_us; 114 115 adev->pm.pm_display_cfg.display_clk = 116 pp_display_cfg->disp_clk_khz/10; 117 118 adev->pm.pm_display_cfg.dce_tolerable_mclk_in_active_latency = 119 pp_display_cfg->avail_mclk_switch_time_in_disp_active_us; 120 121 adev->pm.pm_display_cfg.crtc_index = pp_display_cfg->crtc_index; 122 adev->pm.pm_display_cfg.line_time_in_us = 123 pp_display_cfg->line_time_in_us; 124 125 adev->pm.pm_display_cfg.vrefresh = pp_display_cfg->disp_configs[0].v_refresh; 126 adev->pm.pm_display_cfg.crossfire_display_index = -1; 127 adev->pm.pm_display_cfg.min_bus_bandwidth = 0; 128 129 /* TODO: complete implementation of 130 * pp_display_configuration_change(). 131 * Follow example of: 132 * PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c 133 * PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */ 134 if (adev->powerplay.pp_funcs->display_configuration_change) 135 adev->powerplay.pp_funcs->display_configuration_change( 136 adev->powerplay.pp_handle, 137 &adev->pm.pm_display_cfg); 138 139 /* TODO: replace by a separate call to 'apply display cfg'? */ 140 amdgpu_pm_compute_clocks(adev); 141 } 142 143 return true; 144 } 145 146 static void get_default_clock_levels( 147 enum dm_pp_clock_type clk_type, 148 struct dm_pp_clock_levels *clks) 149 { 150 uint32_t disp_clks_in_khz[6] = { 151 300000, 400000, 496560, 626090, 685720, 757900 }; 152 uint32_t sclks_in_khz[6] = { 153 300000, 360000, 423530, 514290, 626090, 720000 }; 154 uint32_t mclks_in_khz[2] = { 333000, 800000 }; 155 156 switch (clk_type) { 157 case DM_PP_CLOCK_TYPE_DISPLAY_CLK: 158 clks->num_levels = 6; 159 memmove(clks->clocks_in_khz, disp_clks_in_khz, 160 sizeof(disp_clks_in_khz)); 161 break; 162 case DM_PP_CLOCK_TYPE_ENGINE_CLK: 163 clks->num_levels = 6; 164 memmove(clks->clocks_in_khz, sclks_in_khz, 165 sizeof(sclks_in_khz)); 166 break; 167 case DM_PP_CLOCK_TYPE_MEMORY_CLK: 168 clks->num_levels = 2; 169 memmove(clks->clocks_in_khz, mclks_in_khz, 170 sizeof(mclks_in_khz)); 171 break; 172 default: 173 clks->num_levels = 0; 174 break; 175 } 176 } 177 178 static enum amd_pp_clock_type dc_to_pp_clock_type( 179 enum dm_pp_clock_type dm_pp_clk_type) 180 { 181 enum amd_pp_clock_type amd_pp_clk_type = 0; 182 183 switch (dm_pp_clk_type) { 184 case DM_PP_CLOCK_TYPE_DISPLAY_CLK: 185 amd_pp_clk_type = amd_pp_disp_clock; 186 break; 187 case DM_PP_CLOCK_TYPE_ENGINE_CLK: 188 amd_pp_clk_type = amd_pp_sys_clock; 189 break; 190 case DM_PP_CLOCK_TYPE_MEMORY_CLK: 191 amd_pp_clk_type = amd_pp_mem_clock; 192 break; 193 default: 194 DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n", 195 dm_pp_clk_type); 196 break; 197 } 198 199 return amd_pp_clk_type; 200 } 201 202 static void pp_to_dc_clock_levels( 203 const struct amd_pp_clocks *pp_clks, 204 struct dm_pp_clock_levels *dc_clks, 205 enum dm_pp_clock_type dc_clk_type) 206 { 207 uint32_t i; 208 209 if (pp_clks->count > DM_PP_MAX_CLOCK_LEVELS) { 210 DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", 211 DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), 212 pp_clks->count, 213 DM_PP_MAX_CLOCK_LEVELS); 214 215 dc_clks->num_levels = DM_PP_MAX_CLOCK_LEVELS; 216 } else 217 dc_clks->num_levels = pp_clks->count; 218 219 DRM_INFO("DM_PPLIB: values for %s clock\n", 220 DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); 221 222 for (i = 0; i < dc_clks->num_levels; i++) { 223 DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->clock[i]); 224 /* translate 10kHz to kHz */ 225 dc_clks->clocks_in_khz[i] = pp_clks->clock[i] * 10; 226 } 227 } 228 229 static void pp_to_dc_clock_levels_with_latency( 230 const struct pp_clock_levels_with_latency *pp_clks, 231 struct dm_pp_clock_levels_with_latency *clk_level_info, 232 enum dm_pp_clock_type dc_clk_type) 233 { 234 uint32_t i; 235 236 if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { 237 DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", 238 DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), 239 pp_clks->num_levels, 240 DM_PP_MAX_CLOCK_LEVELS); 241 242 clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; 243 } else 244 clk_level_info->num_levels = pp_clks->num_levels; 245 246 DRM_DEBUG("DM_PPLIB: values for %s clock\n", 247 DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); 248 249 for (i = 0; i < clk_level_info->num_levels; i++) { 250 DRM_DEBUG("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); 251 clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; 252 clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; 253 } 254 } 255 256 static void pp_to_dc_clock_levels_with_voltage( 257 const struct pp_clock_levels_with_voltage *pp_clks, 258 struct dm_pp_clock_levels_with_voltage *clk_level_info, 259 enum dm_pp_clock_type dc_clk_type) 260 { 261 uint32_t i; 262 263 if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { 264 DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", 265 DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), 266 pp_clks->num_levels, 267 DM_PP_MAX_CLOCK_LEVELS); 268 269 clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; 270 } else 271 clk_level_info->num_levels = pp_clks->num_levels; 272 273 DRM_INFO("DM_PPLIB: values for %s clock\n", 274 DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); 275 276 for (i = 0; i < clk_level_info->num_levels; i++) { 277 DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); 278 clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; 279 clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv; 280 } 281 } 282 283 284 bool dm_pp_get_clock_levels_by_type( 285 const struct dc_context *ctx, 286 enum dm_pp_clock_type clk_type, 287 struct dm_pp_clock_levels *dc_clks) 288 { 289 struct amdgpu_device *adev = ctx->driver_context; 290 void *pp_handle = adev->powerplay.pp_handle; 291 struct amd_pp_clocks pp_clks = { 0 }; 292 struct amd_pp_simple_clock_info validation_clks = { 0 }; 293 uint32_t i; 294 295 if (adev->powerplay.pp_funcs->get_clock_by_type) { 296 if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle, 297 dc_to_pp_clock_type(clk_type), &pp_clks)) { 298 /* Error in pplib. Provide default values. */ 299 get_default_clock_levels(clk_type, dc_clks); 300 return true; 301 } 302 } 303 304 pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type); 305 306 if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) { 307 if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks( 308 pp_handle, &validation_clks)) { 309 /* Error in pplib. Provide default values. */ 310 DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n"); 311 validation_clks.engine_max_clock = 72000; 312 validation_clks.memory_max_clock = 80000; 313 validation_clks.level = 0; 314 } 315 } 316 317 DRM_INFO("DM_PPLIB: Validation clocks:\n"); 318 DRM_INFO("DM_PPLIB: engine_max_clock: %d\n", 319 validation_clks.engine_max_clock); 320 DRM_INFO("DM_PPLIB: memory_max_clock: %d\n", 321 validation_clks.memory_max_clock); 322 DRM_INFO("DM_PPLIB: level : %d\n", 323 validation_clks.level); 324 325 /* Translate 10 kHz to kHz. */ 326 validation_clks.engine_max_clock *= 10; 327 validation_clks.memory_max_clock *= 10; 328 329 /* Determine the highest non-boosted level from the Validation Clocks */ 330 if (clk_type == DM_PP_CLOCK_TYPE_ENGINE_CLK) { 331 for (i = 0; i < dc_clks->num_levels; i++) { 332 if (dc_clks->clocks_in_khz[i] > validation_clks.engine_max_clock) { 333 /* This clock is higher the validation clock. 334 * Than means the previous one is the highest 335 * non-boosted one. */ 336 DRM_INFO("DM_PPLIB: reducing engine clock level from %d to %d\n", 337 dc_clks->num_levels, i); 338 dc_clks->num_levels = i > 0 ? i : 1; 339 break; 340 } 341 } 342 } else if (clk_type == DM_PP_CLOCK_TYPE_MEMORY_CLK) { 343 for (i = 0; i < dc_clks->num_levels; i++) { 344 if (dc_clks->clocks_in_khz[i] > validation_clks.memory_max_clock) { 345 DRM_INFO("DM_PPLIB: reducing memory clock level from %d to %d\n", 346 dc_clks->num_levels, i); 347 dc_clks->num_levels = i > 0 ? i : 1; 348 break; 349 } 350 } 351 } 352 353 return true; 354 } 355 356 bool dm_pp_get_clock_levels_by_type_with_latency( 357 const struct dc_context *ctx, 358 enum dm_pp_clock_type clk_type, 359 struct dm_pp_clock_levels_with_latency *clk_level_info) 360 { 361 struct amdgpu_device *adev = ctx->driver_context; 362 void *pp_handle = adev->powerplay.pp_handle; 363 struct pp_clock_levels_with_latency pp_clks = { 0 }; 364 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; 365 366 if (!pp_funcs || !pp_funcs->get_clock_by_type_with_latency) 367 return false; 368 369 if (pp_funcs->get_clock_by_type_with_latency(pp_handle, 370 dc_to_pp_clock_type(clk_type), 371 &pp_clks)) 372 return false; 373 374 pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type); 375 376 return true; 377 } 378 379 bool dm_pp_get_clock_levels_by_type_with_voltage( 380 const struct dc_context *ctx, 381 enum dm_pp_clock_type clk_type, 382 struct dm_pp_clock_levels_with_voltage *clk_level_info) 383 { 384 struct amdgpu_device *adev = ctx->driver_context; 385 void *pp_handle = adev->powerplay.pp_handle; 386 struct pp_clock_levels_with_voltage pp_clk_info = {0}; 387 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; 388 389 if (pp_funcs->get_clock_by_type_with_voltage(pp_handle, 390 dc_to_pp_clock_type(clk_type), 391 &pp_clk_info)) 392 return false; 393 394 pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type); 395 396 return true; 397 } 398 399 bool dm_pp_notify_wm_clock_changes( 400 const struct dc_context *ctx, 401 struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges) 402 { 403 /* TODO: to be implemented */ 404 return false; 405 } 406 407 bool dm_pp_apply_power_level_change_request( 408 const struct dc_context *ctx, 409 struct dm_pp_power_level_change_request *level_change_req) 410 { 411 /* TODO: to be implemented */ 412 return false; 413 } 414 415 bool dm_pp_apply_clock_for_voltage_request( 416 const struct dc_context *ctx, 417 struct dm_pp_clock_for_voltage_req *clock_for_voltage_req) 418 { 419 struct amdgpu_device *adev = ctx->driver_context; 420 struct pp_display_clock_request *pp_clock_request = {0}; 421 int ret = 0; 422 switch (clock_for_voltage_req->clk_type) { 423 case DM_PP_CLOCK_TYPE_DISPLAY_CLK: 424 pp_clock_request->clock_type = amd_pp_disp_clock; 425 break; 426 427 case DM_PP_CLOCK_TYPE_DCEFCLK: 428 pp_clock_request->clock_type = amd_pp_dcef_clock; 429 break; 430 431 case DM_PP_CLOCK_TYPE_PIXELCLK: 432 pp_clock_request->clock_type = amd_pp_pixel_clock; 433 break; 434 435 default: 436 return false; 437 } 438 439 pp_clock_request->clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz; 440 441 if (adev->powerplay.pp_funcs->display_clock_voltage_request) 442 ret = adev->powerplay.pp_funcs->display_clock_voltage_request( 443 adev->powerplay.pp_handle, 444 pp_clock_request); 445 if (ret) 446 return false; 447 return true; 448 } 449 450 bool dm_pp_get_static_clocks( 451 const struct dc_context *ctx, 452 struct dm_pp_static_clock_info *static_clk_info) 453 { 454 struct amdgpu_device *adev = ctx->driver_context; 455 struct amd_pp_clock_info *pp_clk_info = {0}; 456 int ret = 0; 457 458 if (adev->powerplay.pp_funcs->get_current_clocks) 459 ret = adev->powerplay.pp_funcs->get_current_clocks( 460 adev->powerplay.pp_handle, 461 pp_clk_info); 462 if (ret) 463 return false; 464 465 static_clk_info->max_clocks_state = pp_clk_info->max_clocks_state; 466 static_clk_info->max_mclk_khz = pp_clk_info->max_memory_clock; 467 static_clk_info->max_sclk_khz = pp_clk_info->max_engine_clock; 468 469 return true; 470 } 471 472 void dm_pp_get_funcs_rv( 473 struct dc_context *ctx, 474 struct pp_smu_funcs_rv *funcs) 475 {} 476 477 /**** end of power component interfaces ****/ 478