1 /* 2 * Copyright 2012-16 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/slab.h> 27 28 #include "dce_clk_mgr.h" 29 30 #include "reg_helper.h" 31 #include "dmcu.h" 32 #include "core_types.h" 33 #include "dal_asic_id.h" 34 35 #define TO_DCE_CLK_MGR(clocks)\ 36 container_of(clocks, struct dce_clk_mgr, base) 37 38 #define REG(reg) \ 39 (clk_mgr_dce->regs->reg) 40 41 #undef FN 42 #define FN(reg_name, field_name) \ 43 clk_mgr_dce->clk_mgr_shift->field_name, clk_mgr_dce->clk_mgr_mask->field_name 44 45 #define CTX \ 46 clk_mgr_dce->base.ctx 47 #define DC_LOGGER \ 48 clk_mgr->ctx->logger 49 50 /* Max clock values for each state indexed by "enum clocks_state": */ 51 static const struct state_dependent_clocks dce80_max_clks_by_state[] = { 52 /* ClocksStateInvalid - should not be used */ 53 { .display_clk_khz = 0, .pixel_clk_khz = 0 }, 54 /* ClocksStateUltraLow - not expected to be used for DCE 8.0 */ 55 { .display_clk_khz = 0, .pixel_clk_khz = 0 }, 56 /* ClocksStateLow */ 57 { .display_clk_khz = 352000, .pixel_clk_khz = 330000}, 58 /* ClocksStateNominal */ 59 { .display_clk_khz = 600000, .pixel_clk_khz = 400000 }, 60 /* ClocksStatePerformance */ 61 { .display_clk_khz = 600000, .pixel_clk_khz = 400000 } }; 62 63 static const struct state_dependent_clocks dce110_max_clks_by_state[] = { 64 /*ClocksStateInvalid - should not be used*/ 65 { .display_clk_khz = 0, .pixel_clk_khz = 0 }, 66 /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ 67 { .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, 68 /*ClocksStateLow*/ 69 { .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, 70 /*ClocksStateNominal*/ 71 { .display_clk_khz = 467000, .pixel_clk_khz = 400000 }, 72 /*ClocksStatePerformance*/ 73 { .display_clk_khz = 643000, .pixel_clk_khz = 400000 } }; 74 75 static const struct state_dependent_clocks dce112_max_clks_by_state[] = { 76 /*ClocksStateInvalid - should not be used*/ 77 { .display_clk_khz = 0, .pixel_clk_khz = 0 }, 78 /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ 79 { .display_clk_khz = 389189, .pixel_clk_khz = 346672 }, 80 /*ClocksStateLow*/ 81 { .display_clk_khz = 459000, .pixel_clk_khz = 400000 }, 82 /*ClocksStateNominal*/ 83 { .display_clk_khz = 667000, .pixel_clk_khz = 600000 }, 84 /*ClocksStatePerformance*/ 85 { .display_clk_khz = 1132000, .pixel_clk_khz = 600000 } }; 86 87 static const struct state_dependent_clocks dce120_max_clks_by_state[] = { 88 /*ClocksStateInvalid - should not be used*/ 89 { .display_clk_khz = 0, .pixel_clk_khz = 0 }, 90 /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ 91 { .display_clk_khz = 0, .pixel_clk_khz = 0 }, 92 /*ClocksStateLow*/ 93 { .display_clk_khz = 460000, .pixel_clk_khz = 400000 }, 94 /*ClocksStateNominal*/ 95 { .display_clk_khz = 670000, .pixel_clk_khz = 600000 }, 96 /*ClocksStatePerformance*/ 97 { .display_clk_khz = 1133000, .pixel_clk_khz = 600000 } }; 98 99 int dentist_get_divider_from_did(int did) 100 { 101 if (did < DENTIST_BASE_DID_1) 102 did = DENTIST_BASE_DID_1; 103 if (did > DENTIST_MAX_DID) 104 did = DENTIST_MAX_DID; 105 106 if (did < DENTIST_BASE_DID_2) { 107 return DENTIST_DIVIDER_RANGE_1_START + DENTIST_DIVIDER_RANGE_1_STEP 108 * (did - DENTIST_BASE_DID_1); 109 } else if (did < DENTIST_BASE_DID_3) { 110 return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP 111 * (did - DENTIST_BASE_DID_2); 112 } else if (did < DENTIST_BASE_DID_4) { 113 return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP 114 * (did - DENTIST_BASE_DID_3); 115 } else { 116 return DENTIST_DIVIDER_RANGE_4_START + DENTIST_DIVIDER_RANGE_4_STEP 117 * (did - DENTIST_BASE_DID_4); 118 } 119 } 120 121 /* SW will adjust DP REF Clock average value for all purposes 122 * (DP DTO / DP Audio DTO and DP GTC) 123 if clock is spread for all cases: 124 -if SS enabled on DP Ref clock and HW de-spreading enabled with SW 125 calculations for DS_INCR/DS_MODULO (this is planned to be default case) 126 -if SS enabled on DP Ref clock and HW de-spreading enabled with HW 127 calculations (not planned to be used, but average clock should still 128 be valid) 129 -if SS enabled on DP Ref clock and HW de-spreading disabled 130 (should not be case with CIK) then SW should program all rates 131 generated according to average value (case as with previous ASICs) 132 */ 133 static int clk_mgr_adjust_dp_ref_freq_for_ss(struct dce_clk_mgr *clk_mgr_dce, int dp_ref_clk_khz) 134 { 135 if (clk_mgr_dce->ss_on_dprefclk && clk_mgr_dce->dprefclk_ss_divider != 0) { 136 struct fixed31_32 ss_percentage = dc_fixpt_div_int( 137 dc_fixpt_from_fraction(clk_mgr_dce->dprefclk_ss_percentage, 138 clk_mgr_dce->dprefclk_ss_divider), 200); 139 struct fixed31_32 adj_dp_ref_clk_khz; 140 141 ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); 142 adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); 143 dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); 144 } 145 return dp_ref_clk_khz; 146 } 147 148 static int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr) 149 { 150 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 151 int dprefclk_wdivider; 152 int dprefclk_src_sel; 153 int dp_ref_clk_khz = 600000; 154 int target_div; 155 156 /* ASSERT DP Reference Clock source is from DFS*/ 157 REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel); 158 ASSERT(dprefclk_src_sel == 0); 159 160 /* Read the mmDENTIST_DISPCLK_CNTL to get the currently 161 * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ 162 REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); 163 164 /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ 165 target_div = dentist_get_divider_from_did(dprefclk_wdivider); 166 167 /* Calculate the current DFS clock, in kHz.*/ 168 dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR 169 * clk_mgr_dce->dentist_vco_freq_khz) / target_div; 170 171 return clk_mgr_adjust_dp_ref_freq_for_ss(clk_mgr_dce, dp_ref_clk_khz); 172 } 173 174 int dce12_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr) 175 { 176 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 177 178 return clk_mgr_adjust_dp_ref_freq_for_ss(clk_mgr_dce, clk_mgr_dce->dprefclk_khz); 179 } 180 181 /* unit: in_khz before mode set, get pixel clock from context. ASIC register 182 * may not be programmed yet 183 */ 184 static uint32_t get_max_pixel_clock_for_all_paths(struct dc_state *context) 185 { 186 uint32_t max_pix_clk = 0; 187 int i; 188 189 for (i = 0; i < MAX_PIPES; i++) { 190 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 191 192 if (pipe_ctx->stream == NULL) 193 continue; 194 195 /* do not check under lay */ 196 if (pipe_ctx->top_pipe) 197 continue; 198 199 if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10 > max_pix_clk) 200 max_pix_clk = pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10; 201 202 /* raise clock state for HBR3/2 if required. Confirmed with HW DCE/DPCS 203 * logic for HBR3 still needs Nominal (0.8V) on VDDC rail 204 */ 205 if (dc_is_dp_signal(pipe_ctx->stream->signal) && 206 pipe_ctx->stream_res.pix_clk_params.requested_sym_clk > max_pix_clk) 207 max_pix_clk = pipe_ctx->stream_res.pix_clk_params.requested_sym_clk; 208 } 209 210 return max_pix_clk; 211 } 212 213 static enum dm_pp_clocks_state dce_get_required_clocks_state( 214 struct clk_mgr *clk_mgr, 215 struct dc_state *context) 216 { 217 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 218 int i; 219 enum dm_pp_clocks_state low_req_clk; 220 int max_pix_clk = get_max_pixel_clock_for_all_paths(context); 221 222 /* Iterate from highest supported to lowest valid state, and update 223 * lowest RequiredState with the lowest state that satisfies 224 * all required clocks 225 */ 226 for (i = clk_mgr_dce->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) 227 if (context->bw_ctx.bw.dce.dispclk_khz > 228 clk_mgr_dce->max_clks_by_state[i].display_clk_khz 229 || max_pix_clk > 230 clk_mgr_dce->max_clks_by_state[i].pixel_clk_khz) 231 break; 232 233 low_req_clk = i + 1; 234 if (low_req_clk > clk_mgr_dce->max_clks_state) { 235 /* set max clock state for high phyclock, invalid on exceeding display clock */ 236 if (clk_mgr_dce->max_clks_by_state[clk_mgr_dce->max_clks_state].display_clk_khz 237 < context->bw_ctx.bw.dce.dispclk_khz) 238 low_req_clk = DM_PP_CLOCKS_STATE_INVALID; 239 else 240 low_req_clk = clk_mgr_dce->max_clks_state; 241 } 242 243 return low_req_clk; 244 } 245 246 static int dce_set_clock( 247 struct clk_mgr *clk_mgr, 248 int requested_clk_khz) 249 { 250 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 251 struct bp_pixel_clock_parameters pxl_clk_params = { 0 }; 252 struct dc_bios *bp = clk_mgr->ctx->dc_bios; 253 int actual_clock = requested_clk_khz; 254 struct dmcu *dmcu = clk_mgr_dce->base.ctx->dc->res_pool->dmcu; 255 256 /* Make sure requested clock isn't lower than minimum threshold*/ 257 if (requested_clk_khz > 0) 258 requested_clk_khz = max(requested_clk_khz, 259 clk_mgr_dce->dentist_vco_freq_khz / 64); 260 261 /* Prepare to program display clock*/ 262 pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz * 10; 263 pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; 264 265 if (clk_mgr_dce->dfs_bypass_active) 266 pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true; 267 268 bp->funcs->program_display_engine_pll(bp, &pxl_clk_params); 269 270 if (clk_mgr_dce->dfs_bypass_active) { 271 /* Cache the fixed display clock*/ 272 clk_mgr_dce->dfs_bypass_disp_clk = 273 pxl_clk_params.dfs_bypass_display_clock; 274 actual_clock = pxl_clk_params.dfs_bypass_display_clock; 275 } 276 277 /* from power down, we need mark the clock state as ClocksStateNominal 278 * from HWReset, so when resume we will call pplib voltage regulator.*/ 279 if (requested_clk_khz == 0) 280 clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; 281 282 if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) 283 dmcu->funcs->set_psr_wait_loop(dmcu, actual_clock / 1000 / 7); 284 285 return actual_clock; 286 } 287 288 int dce112_set_clock(struct clk_mgr *clk_mgr, int requested_clk_khz) 289 { 290 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 291 struct bp_set_dce_clock_parameters dce_clk_params; 292 struct dc_bios *bp = clk_mgr->ctx->dc_bios; 293 struct dc *core_dc = clk_mgr->ctx->dc; 294 struct dmcu *dmcu = core_dc->res_pool->dmcu; 295 int actual_clock = requested_clk_khz; 296 /* Prepare to program display clock*/ 297 memset(&dce_clk_params, 0, sizeof(dce_clk_params)); 298 299 /* Make sure requested clock isn't lower than minimum threshold*/ 300 if (requested_clk_khz > 0) 301 requested_clk_khz = max(requested_clk_khz, 302 clk_mgr_dce->dentist_vco_freq_khz / 62); 303 304 dce_clk_params.target_clock_frequency = requested_clk_khz; 305 dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; 306 dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK; 307 308 bp->funcs->set_dce_clock(bp, &dce_clk_params); 309 actual_clock = dce_clk_params.target_clock_frequency; 310 311 /* from power down, we need mark the clock state as ClocksStateNominal 312 * from HWReset, so when resume we will call pplib voltage regulator.*/ 313 if (requested_clk_khz == 0) 314 clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; 315 316 /*Program DP ref Clock*/ 317 /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ 318 dce_clk_params.target_clock_frequency = 0; 319 dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; 320 321 if (!((clk_mgr->ctx->asic_id.chip_family == FAMILY_AI) && 322 ASICREV_IS_VEGA20_P(clk_mgr->ctx->asic_id.hw_internal_rev))) 323 dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = 324 (dce_clk_params.pll_id == 325 CLOCK_SOURCE_COMBO_DISPLAY_PLL0); 326 else 327 dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = false; 328 329 bp->funcs->set_dce_clock(bp, &dce_clk_params); 330 331 if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { 332 if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) { 333 if (clk_mgr_dce->dfs_bypass_disp_clk != actual_clock) 334 dmcu->funcs->set_psr_wait_loop(dmcu, 335 actual_clock / 1000 / 7); 336 } 337 } 338 339 clk_mgr_dce->dfs_bypass_disp_clk = actual_clock; 340 return actual_clock; 341 } 342 343 static void dce_clock_read_integrated_info(struct dce_clk_mgr *clk_mgr_dce) 344 { 345 struct dc_debug_options *debug = &clk_mgr_dce->base.ctx->dc->debug; 346 struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios; 347 struct integrated_info info = { { { 0 } } }; 348 struct dc_firmware_info fw_info = { { 0 } }; 349 int i; 350 351 if (bp->integrated_info) 352 info = *bp->integrated_info; 353 354 clk_mgr_dce->dentist_vco_freq_khz = info.dentist_vco_freq; 355 if (clk_mgr_dce->dentist_vco_freq_khz == 0) { 356 bp->funcs->get_firmware_info(bp, &fw_info); 357 clk_mgr_dce->dentist_vco_freq_khz = 358 fw_info.smu_gpu_pll_output_freq; 359 if (clk_mgr_dce->dentist_vco_freq_khz == 0) 360 clk_mgr_dce->dentist_vco_freq_khz = 3600000; 361 } 362 363 /*update the maximum display clock for each power state*/ 364 for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 365 enum dm_pp_clocks_state clk_state = DM_PP_CLOCKS_STATE_INVALID; 366 367 switch (i) { 368 case 0: 369 clk_state = DM_PP_CLOCKS_STATE_ULTRA_LOW; 370 break; 371 372 case 1: 373 clk_state = DM_PP_CLOCKS_STATE_LOW; 374 break; 375 376 case 2: 377 clk_state = DM_PP_CLOCKS_STATE_NOMINAL; 378 break; 379 380 case 3: 381 clk_state = DM_PP_CLOCKS_STATE_PERFORMANCE; 382 break; 383 384 default: 385 clk_state = DM_PP_CLOCKS_STATE_INVALID; 386 break; 387 } 388 389 /*Do not allow bad VBIOS/SBIOS to override with invalid values, 390 * check for > 100MHz*/ 391 if (info.disp_clk_voltage[i].max_supported_clk >= 100000) 392 clk_mgr_dce->max_clks_by_state[clk_state].display_clk_khz = 393 info.disp_clk_voltage[i].max_supported_clk; 394 } 395 396 if (!debug->disable_dfs_bypass && bp->integrated_info) 397 if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) 398 clk_mgr_dce->dfs_bypass_enabled = true; 399 } 400 401 void dce_clock_read_ss_info(struct dce_clk_mgr *clk_mgr_dce) 402 { 403 struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios; 404 int ss_info_num = bp->funcs->get_ss_entry_number( 405 bp, AS_SIGNAL_TYPE_GPU_PLL); 406 407 if (ss_info_num) { 408 struct spread_spectrum_info info = { { 0 } }; 409 enum bp_result result = bp->funcs->get_spread_spectrum_info( 410 bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info); 411 412 /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS 413 * even if SS not enabled and in that case 414 * SSInfo.spreadSpectrumPercentage !=0 would be sign 415 * that SS is enabled 416 */ 417 if (result == BP_RESULT_OK && 418 info.spread_spectrum_percentage != 0) { 419 clk_mgr_dce->ss_on_dprefclk = true; 420 clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider; 421 422 if (info.type.CENTER_MODE == 0) { 423 /* TODO: Currently for DP Reference clock we 424 * need only SS percentage for 425 * downspread */ 426 clk_mgr_dce->dprefclk_ss_percentage = 427 info.spread_spectrum_percentage; 428 } 429 430 return; 431 } 432 433 result = bp->funcs->get_spread_spectrum_info( 434 bp, AS_SIGNAL_TYPE_DISPLAY_PORT, 0, &info); 435 436 /* Based on VBIOS, VBIOS will keep entry for DPREFCLK SS 437 * even if SS not enabled and in that case 438 * SSInfo.spreadSpectrumPercentage !=0 would be sign 439 * that SS is enabled 440 */ 441 if (result == BP_RESULT_OK && 442 info.spread_spectrum_percentage != 0) { 443 clk_mgr_dce->ss_on_dprefclk = true; 444 clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider; 445 446 if (info.type.CENTER_MODE == 0) { 447 /* Currently for DP Reference clock we 448 * need only SS percentage for 449 * downspread */ 450 clk_mgr_dce->dprefclk_ss_percentage = 451 info.spread_spectrum_percentage; 452 } 453 } 454 } 455 } 456 457 /** 458 * dce121_clock_patch_xgmi_ss_info() - Save XGMI spread spectrum info 459 * @clk_mgr: clock manager base structure 460 * 461 * Reads from VBIOS the XGMI spread spectrum info and saves it within 462 * the dce clock manager. This operation will overwrite the existing dprefclk 463 * SS values if the vBIOS query succeeds. Otherwise, it does nothing. It also 464 * sets the ->xgmi_enabled flag. 465 */ 466 void dce121_clock_patch_xgmi_ss_info(struct clk_mgr *clk_mgr) 467 { 468 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 469 enum bp_result result; 470 struct spread_spectrum_info info = { { 0 } }; 471 struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios; 472 473 clk_mgr_dce->xgmi_enabled = false; 474 475 result = bp->funcs->get_spread_spectrum_info(bp, AS_SIGNAL_TYPE_XGMI, 476 0, &info); 477 if (result == BP_RESULT_OK && info.spread_spectrum_percentage != 0) { 478 clk_mgr_dce->xgmi_enabled = true; 479 clk_mgr_dce->ss_on_dprefclk = true; 480 clk_mgr_dce->dprefclk_ss_divider = 481 info.spread_percentage_divider; 482 483 if (info.type.CENTER_MODE == 0) { 484 /* Currently for DP Reference clock we 485 * need only SS percentage for 486 * downspread */ 487 clk_mgr_dce->dprefclk_ss_percentage = 488 info.spread_spectrum_percentage; 489 } 490 } 491 } 492 493 void dce110_fill_display_configs( 494 const struct dc_state *context, 495 struct dm_pp_display_configuration *pp_display_cfg) 496 { 497 int j; 498 int num_cfgs = 0; 499 500 for (j = 0; j < context->stream_count; j++) { 501 int k; 502 503 const struct dc_stream_state *stream = context->streams[j]; 504 struct dm_pp_single_disp_config *cfg = 505 &pp_display_cfg->disp_configs[num_cfgs]; 506 const struct pipe_ctx *pipe_ctx = NULL; 507 508 for (k = 0; k < MAX_PIPES; k++) 509 if (stream == context->res_ctx.pipe_ctx[k].stream) { 510 pipe_ctx = &context->res_ctx.pipe_ctx[k]; 511 break; 512 } 513 514 ASSERT(pipe_ctx != NULL); 515 516 /* only notify active stream */ 517 if (stream->dpms_off) 518 continue; 519 520 num_cfgs++; 521 cfg->signal = pipe_ctx->stream->signal; 522 cfg->pipe_idx = pipe_ctx->stream_res.tg->inst; 523 cfg->src_height = stream->src.height; 524 cfg->src_width = stream->src.width; 525 cfg->ddi_channel_mapping = 526 stream->link->ddi_channel_mapping.raw; 527 cfg->transmitter = 528 stream->link->link_enc->transmitter; 529 cfg->link_settings.lane_count = 530 stream->link->cur_link_settings.lane_count; 531 cfg->link_settings.link_rate = 532 stream->link->cur_link_settings.link_rate; 533 cfg->link_settings.link_spread = 534 stream->link->cur_link_settings.link_spread; 535 cfg->sym_clock = stream->phy_pix_clk; 536 /* Round v_refresh*/ 537 cfg->v_refresh = stream->timing.pix_clk_100hz * 100; 538 cfg->v_refresh /= stream->timing.h_total; 539 cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) 540 / stream->timing.v_total; 541 } 542 543 pp_display_cfg->display_count = num_cfgs; 544 } 545 546 static uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context) 547 { 548 uint8_t j; 549 uint32_t min_vertical_blank_time = -1; 550 551 for (j = 0; j < context->stream_count; j++) { 552 struct dc_stream_state *stream = context->streams[j]; 553 uint32_t vertical_blank_in_pixels = 0; 554 uint32_t vertical_blank_time = 0; 555 556 vertical_blank_in_pixels = stream->timing.h_total * 557 (stream->timing.v_total 558 - stream->timing.v_addressable); 559 560 vertical_blank_time = vertical_blank_in_pixels 561 * 10000 / stream->timing.pix_clk_100hz; 562 563 if (min_vertical_blank_time > vertical_blank_time) 564 min_vertical_blank_time = vertical_blank_time; 565 } 566 567 return min_vertical_blank_time; 568 } 569 570 static int determine_sclk_from_bounding_box( 571 const struct dc *dc, 572 int required_sclk) 573 { 574 int i; 575 576 /* 577 * Some asics do not give us sclk levels, so we just report the actual 578 * required sclk 579 */ 580 if (dc->sclk_lvls.num_levels == 0) 581 return required_sclk; 582 583 for (i = 0; i < dc->sclk_lvls.num_levels; i++) { 584 if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk) 585 return dc->sclk_lvls.clocks_in_khz[i]; 586 } 587 /* 588 * even maximum level could not satisfy requirement, this 589 * is unexpected at this stage, should have been caught at 590 * validation time 591 */ 592 ASSERT(0); 593 return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1]; 594 } 595 596 static void dce_pplib_apply_display_requirements( 597 struct dc *dc, 598 struct dc_state *context) 599 { 600 struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 601 602 pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); 603 604 dce110_fill_display_configs(context, pp_display_cfg); 605 606 if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) 607 dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); 608 } 609 610 static void dce11_pplib_apply_display_requirements( 611 struct dc *dc, 612 struct dc_state *context) 613 { 614 struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 615 616 pp_display_cfg->all_displays_in_sync = 617 context->bw_ctx.bw.dce.all_displays_in_sync; 618 pp_display_cfg->nb_pstate_switch_disable = 619 context->bw_ctx.bw.dce.nbp_state_change_enable == false; 620 pp_display_cfg->cpu_cc6_disable = 621 context->bw_ctx.bw.dce.cpuc_state_change_enable == false; 622 pp_display_cfg->cpu_pstate_disable = 623 context->bw_ctx.bw.dce.cpup_state_change_enable == false; 624 pp_display_cfg->cpu_pstate_separation_time = 625 context->bw_ctx.bw.dce.blackout_recovery_time_us; 626 627 pp_display_cfg->min_memory_clock_khz = context->bw_ctx.bw.dce.yclk_khz 628 / MEMORY_TYPE_MULTIPLIER_CZ; 629 630 pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( 631 dc, 632 context->bw_ctx.bw.dce.sclk_khz); 633 634 /* 635 * As workaround for >4x4K lightup set dcfclock to min_engine_clock value. 636 * This is not required for less than 5 displays, 637 * thus don't request decfclk in dc to avoid impact 638 * on power saving. 639 * 640 */ 641 pp_display_cfg->min_dcfclock_khz = (context->stream_count > 4)? 642 pp_display_cfg->min_engine_clock_khz : 0; 643 644 pp_display_cfg->min_engine_clock_deep_sleep_khz 645 = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; 646 647 pp_display_cfg->avail_mclk_switch_time_us = 648 dce110_get_min_vblank_time_us(context); 649 /* TODO: dce11.2*/ 650 pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; 651 652 pp_display_cfg->disp_clk_khz = dc->res_pool->clk_mgr->clks.dispclk_khz; 653 654 dce110_fill_display_configs(context, pp_display_cfg); 655 656 /* TODO: is this still applicable?*/ 657 if (pp_display_cfg->display_count == 1) { 658 const struct dc_crtc_timing *timing = 659 &context->streams[0]->timing; 660 661 pp_display_cfg->crtc_index = 662 pp_display_cfg->disp_configs[0].pipe_idx; 663 pp_display_cfg->line_time_in_us = timing->h_total * 10000 / timing->pix_clk_100hz; 664 } 665 666 if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) 667 dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); 668 } 669 670 static void dce_update_clocks(struct clk_mgr *clk_mgr, 671 struct dc_state *context, 672 bool safe_to_lower) 673 { 674 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 675 struct dm_pp_power_level_change_request level_change_req; 676 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; 677 678 /*TODO: W/A for dal3 linux, investigate why this works */ 679 if (!clk_mgr_dce->dfs_bypass_active) 680 patched_disp_clk = patched_disp_clk * 115 / 100; 681 682 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); 683 /* get max clock state from PPLIB */ 684 if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower) 685 || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) { 686 if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req)) 687 clk_mgr_dce->cur_min_clks_state = level_change_req.power_level; 688 } 689 690 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) { 691 patched_disp_clk = dce_set_clock(clk_mgr, patched_disp_clk); 692 clk_mgr->clks.dispclk_khz = patched_disp_clk; 693 } 694 dce_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); 695 } 696 697 static void dce11_update_clocks(struct clk_mgr *clk_mgr, 698 struct dc_state *context, 699 bool safe_to_lower) 700 { 701 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 702 struct dm_pp_power_level_change_request level_change_req; 703 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; 704 705 /*TODO: W/A for dal3 linux, investigate why this works */ 706 if (!clk_mgr_dce->dfs_bypass_active) 707 patched_disp_clk = patched_disp_clk * 115 / 100; 708 709 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); 710 /* get max clock state from PPLIB */ 711 if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower) 712 || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) { 713 if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req)) 714 clk_mgr_dce->cur_min_clks_state = level_change_req.power_level; 715 } 716 717 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) { 718 context->bw_ctx.bw.dce.dispclk_khz = dce_set_clock(clk_mgr, patched_disp_clk); 719 clk_mgr->clks.dispclk_khz = patched_disp_clk; 720 } 721 dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); 722 } 723 724 static void dce112_update_clocks(struct clk_mgr *clk_mgr, 725 struct dc_state *context, 726 bool safe_to_lower) 727 { 728 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 729 struct dm_pp_power_level_change_request level_change_req; 730 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; 731 732 /*TODO: W/A for dal3 linux, investigate why this works */ 733 if (!clk_mgr_dce->dfs_bypass_active) 734 patched_disp_clk = patched_disp_clk * 115 / 100; 735 736 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); 737 /* get max clock state from PPLIB */ 738 if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower) 739 || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) { 740 if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req)) 741 clk_mgr_dce->cur_min_clks_state = level_change_req.power_level; 742 } 743 744 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) { 745 patched_disp_clk = dce112_set_clock(clk_mgr, patched_disp_clk); 746 clk_mgr->clks.dispclk_khz = patched_disp_clk; 747 } 748 dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); 749 } 750 751 static void dce12_update_clocks(struct clk_mgr *clk_mgr, 752 struct dc_state *context, 753 bool safe_to_lower) 754 { 755 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); 756 struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; 757 int max_pix_clk = get_max_pixel_clock_for_all_paths(context); 758 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; 759 760 /*TODO: W/A for dal3 linux, investigate why this works */ 761 if (!clk_mgr_dce->dfs_bypass_active) 762 patched_disp_clk = patched_disp_clk * 115 / 100; 763 764 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) { 765 clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; 766 /* 767 * When xGMI is enabled, the display clk needs to be adjusted 768 * with the WAFL link's SS percentage. 769 */ 770 if (clk_mgr_dce->xgmi_enabled) 771 patched_disp_clk = clk_mgr_adjust_dp_ref_freq_for_ss( 772 clk_mgr_dce, patched_disp_clk); 773 clock_voltage_req.clocks_in_khz = patched_disp_clk; 774 clk_mgr->clks.dispclk_khz = dce112_set_clock(clk_mgr, patched_disp_clk); 775 776 dm_pp_apply_clock_for_voltage_request(clk_mgr->ctx, &clock_voltage_req); 777 } 778 779 if (should_set_clock(safe_to_lower, max_pix_clk, clk_mgr->clks.phyclk_khz)) { 780 clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; 781 clock_voltage_req.clocks_in_khz = max_pix_clk; 782 clk_mgr->clks.phyclk_khz = max_pix_clk; 783 784 dm_pp_apply_clock_for_voltage_request(clk_mgr->ctx, &clock_voltage_req); 785 } 786 dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); 787 } 788 789 static const struct clk_mgr_funcs dce120_funcs = { 790 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, 791 .update_clocks = dce12_update_clocks 792 }; 793 794 static const struct clk_mgr_funcs dce112_funcs = { 795 .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, 796 .update_clocks = dce112_update_clocks 797 }; 798 799 static const struct clk_mgr_funcs dce110_funcs = { 800 .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, 801 .update_clocks = dce11_update_clocks, 802 }; 803 804 static const struct clk_mgr_funcs dce_funcs = { 805 .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, 806 .update_clocks = dce_update_clocks 807 }; 808 809 static void dce_clk_mgr_construct( 810 struct dce_clk_mgr *clk_mgr_dce, 811 struct dc_context *ctx, 812 const struct clk_mgr_registers *regs, 813 const struct clk_mgr_shift *clk_shift, 814 const struct clk_mgr_mask *clk_mask) 815 { 816 struct clk_mgr *base = &clk_mgr_dce->base; 817 struct dm_pp_static_clock_info static_clk_info = {0}; 818 819 base->ctx = ctx; 820 base->funcs = &dce_funcs; 821 822 clk_mgr_dce->regs = regs; 823 clk_mgr_dce->clk_mgr_shift = clk_shift; 824 clk_mgr_dce->clk_mgr_mask = clk_mask; 825 826 clk_mgr_dce->dfs_bypass_disp_clk = 0; 827 828 clk_mgr_dce->dprefclk_ss_percentage = 0; 829 clk_mgr_dce->dprefclk_ss_divider = 1000; 830 clk_mgr_dce->ss_on_dprefclk = false; 831 832 833 if (dm_pp_get_static_clocks(ctx, &static_clk_info)) 834 clk_mgr_dce->max_clks_state = static_clk_info.max_clocks_state; 835 else 836 clk_mgr_dce->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; 837 clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID; 838 839 dce_clock_read_integrated_info(clk_mgr_dce); 840 dce_clock_read_ss_info(clk_mgr_dce); 841 } 842 843 struct clk_mgr *dce_clk_mgr_create( 844 struct dc_context *ctx, 845 const struct clk_mgr_registers *regs, 846 const struct clk_mgr_shift *clk_shift, 847 const struct clk_mgr_mask *clk_mask) 848 { 849 struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); 850 851 if (clk_mgr_dce == NULL) { 852 BREAK_TO_DEBUGGER(); 853 return NULL; 854 } 855 856 memcpy(clk_mgr_dce->max_clks_by_state, 857 dce80_max_clks_by_state, 858 sizeof(dce80_max_clks_by_state)); 859 860 dce_clk_mgr_construct( 861 clk_mgr_dce, ctx, regs, clk_shift, clk_mask); 862 863 return &clk_mgr_dce->base; 864 } 865 866 struct clk_mgr *dce110_clk_mgr_create( 867 struct dc_context *ctx, 868 const struct clk_mgr_registers *regs, 869 const struct clk_mgr_shift *clk_shift, 870 const struct clk_mgr_mask *clk_mask) 871 { 872 struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); 873 874 if (clk_mgr_dce == NULL) { 875 BREAK_TO_DEBUGGER(); 876 return NULL; 877 } 878 879 memcpy(clk_mgr_dce->max_clks_by_state, 880 dce110_max_clks_by_state, 881 sizeof(dce110_max_clks_by_state)); 882 883 dce_clk_mgr_construct( 884 clk_mgr_dce, ctx, regs, clk_shift, clk_mask); 885 886 clk_mgr_dce->base.funcs = &dce110_funcs; 887 888 return &clk_mgr_dce->base; 889 } 890 891 struct clk_mgr *dce112_clk_mgr_create( 892 struct dc_context *ctx, 893 const struct clk_mgr_registers *regs, 894 const struct clk_mgr_shift *clk_shift, 895 const struct clk_mgr_mask *clk_mask) 896 { 897 struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); 898 899 if (clk_mgr_dce == NULL) { 900 BREAK_TO_DEBUGGER(); 901 return NULL; 902 } 903 904 memcpy(clk_mgr_dce->max_clks_by_state, 905 dce112_max_clks_by_state, 906 sizeof(dce112_max_clks_by_state)); 907 908 dce_clk_mgr_construct( 909 clk_mgr_dce, ctx, regs, clk_shift, clk_mask); 910 911 clk_mgr_dce->base.funcs = &dce112_funcs; 912 913 return &clk_mgr_dce->base; 914 } 915 916 struct clk_mgr *dce120_clk_mgr_create(struct dc_context *ctx) 917 { 918 struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); 919 920 if (clk_mgr_dce == NULL) { 921 BREAK_TO_DEBUGGER(); 922 return NULL; 923 } 924 925 memcpy(clk_mgr_dce->max_clks_by_state, 926 dce120_max_clks_by_state, 927 sizeof(dce120_max_clks_by_state)); 928 929 dce_clk_mgr_construct( 930 clk_mgr_dce, ctx, NULL, NULL, NULL); 931 932 clk_mgr_dce->dprefclk_khz = 600000; 933 clk_mgr_dce->base.funcs = &dce120_funcs; 934 935 return &clk_mgr_dce->base; 936 } 937 938 struct clk_mgr *dce121_clk_mgr_create(struct dc_context *ctx) 939 { 940 struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), 941 GFP_KERNEL); 942 943 if (clk_mgr_dce == NULL) { 944 BREAK_TO_DEBUGGER(); 945 return NULL; 946 } 947 948 memcpy(clk_mgr_dce->max_clks_by_state, dce120_max_clks_by_state, 949 sizeof(dce120_max_clks_by_state)); 950 951 dce_clk_mgr_construct(clk_mgr_dce, ctx, NULL, NULL, NULL); 952 953 clk_mgr_dce->dprefclk_khz = 625000; 954 clk_mgr_dce->base.funcs = &dce120_funcs; 955 956 return &clk_mgr_dce->base; 957 } 958 959 void dce_clk_mgr_destroy(struct clk_mgr **clk_mgr) 960 { 961 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(*clk_mgr); 962 963 kfree(clk_mgr_dce); 964 *clk_mgr = NULL; 965 } 966