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 "dal_asic_id.h" 27 #include "dc_types.h" 28 #include "dccg.h" 29 #include "clk_mgr_internal.h" 30 #include "dc_state_priv.h" 31 #include "link_service.h" 32 33 #include "dce100/dce_clk_mgr.h" 34 #include "dce110/dce110_clk_mgr.h" 35 #include "dce112/dce112_clk_mgr.h" 36 #include "dce120/dce120_clk_mgr.h" 37 #include "dcn10/rv1_clk_mgr.h" 38 #include "dcn10/rv2_clk_mgr.h" 39 #include "dcn20/dcn20_clk_mgr.h" 40 #include "dcn21/rn_clk_mgr.h" 41 #include "dcn201/dcn201_clk_mgr.h" 42 #include "dcn30/dcn30_clk_mgr.h" 43 #include "dcn301/vg_clk_mgr.h" 44 #include "dcn31/dcn31_clk_mgr.h" 45 #include "dcn314/dcn314_clk_mgr.h" 46 #include "dcn315/dcn315_clk_mgr.h" 47 #include "dcn316/dcn316_clk_mgr.h" 48 #include "dcn32/dcn32_clk_mgr.h" 49 #include "dcn35/dcn35_clk_mgr.h" 50 #include "dcn401/dcn401_clk_mgr.h" 51 #include "dcn42/dcn42_clk_mgr.h" 52 #include "dcn42b/dcn42b_clk_mgr.h" 53 54 int clk_mgr_helper_get_active_display_cnt( 55 struct dc *dc, 56 struct dc_state *context) 57 { 58 int i, display_count; 59 60 display_count = 0; 61 for (i = 0; i < context->stream_count; i++) { 62 const struct dc_stream_state *stream = context->streams[i]; 63 const struct dc_stream_status *stream_status = &context->stream_status[i]; 64 65 /* Don't count SubVP phantom pipes as part of active 66 * display count 67 */ 68 if (dc_state_get_stream_subvp_type(context, stream) == SUBVP_PHANTOM) 69 continue; 70 71 if (!stream->dpms_off || dc->is_switch_in_progress_dest || (stream_status && stream_status->plane_count)) 72 display_count++; 73 } 74 75 return display_count; 76 } 77 78 int clk_mgr_helper_get_active_plane_cnt( 79 struct dc *dc, 80 struct dc_state *context) 81 { 82 (void)dc; 83 int i, total_plane_count; 84 85 total_plane_count = 0; 86 for (i = 0; i < context->stream_count; i++) { 87 const struct dc_stream_status stream_status = context->stream_status[i]; 88 89 /* 90 * Sum up plane_count for all streams ( active and virtual ). 91 */ 92 total_plane_count += stream_status.plane_count; 93 } 94 95 return total_plane_count; 96 } 97 98 void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) 99 { 100 struct dc_link *edp_links[MAX_NUM_EDP]; 101 struct dc_link *edp_link = NULL; 102 unsigned int edp_num; 103 unsigned int panel_inst; 104 105 dc_get_edp_links(dc, edp_links, &edp_num); 106 if (dc->hwss.exit_optimized_pwr_state) 107 dc->hwss.exit_optimized_pwr_state(dc, dc->current_state); 108 109 if (edp_num) { 110 for (panel_inst = 0; panel_inst < edp_num; panel_inst++) { 111 bool allow_active = false; 112 113 edp_link = edp_links[panel_inst]; 114 if (!edp_link->psr_settings.psr_feature_enabled) 115 continue; 116 clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active; 117 dc->link_srv->edp_set_psr_allow_active(edp_link, &allow_active, false, false, NULL); 118 dc->link_srv->edp_set_replay_allow_active(edp_link, &allow_active, false, false, NULL); 119 } 120 } 121 122 } 123 124 void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) 125 { 126 struct dc_link *edp_links[MAX_NUM_EDP]; 127 struct dc_link *edp_link = NULL; 128 unsigned int edp_num; 129 unsigned int panel_inst; 130 131 dc_get_edp_links(dc, edp_links, &edp_num); 132 if (edp_num) { 133 for (panel_inst = 0; panel_inst < edp_num; panel_inst++) { 134 edp_link = edp_links[panel_inst]; 135 if (!edp_link->psr_settings.psr_feature_enabled) 136 continue; 137 dc->link_srv->edp_set_psr_allow_active(edp_link, 138 &clk_mgr->psr_allow_active_cache, false, false, NULL); 139 dc->link_srv->edp_set_replay_allow_active(edp_link, 140 &clk_mgr->psr_allow_active_cache, false, false, NULL); 141 } 142 } 143 144 if (dc->hwss.optimize_pwr_state) 145 dc->hwss.optimize_pwr_state(dc, dc->current_state); 146 147 } 148 149 struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg) 150 { 151 struct hw_asic_id asic_id = ctx->asic_id; 152 153 switch (asic_id.chip_family) { 154 case FAMILY_SI: 155 case FAMILY_CI: 156 case FAMILY_KV: { 157 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); 158 159 if (clk_mgr == NULL) { 160 BREAK_TO_DEBUGGER(); 161 return NULL; 162 } 163 dce_clk_mgr_construct(ctx, clk_mgr); 164 return &clk_mgr->base; 165 } 166 case FAMILY_CZ: { 167 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); 168 169 if (clk_mgr == NULL) { 170 BREAK_TO_DEBUGGER(); 171 return NULL; 172 } 173 dce110_clk_mgr_construct(ctx, clk_mgr); 174 return &clk_mgr->base; 175 } 176 case FAMILY_VI: { 177 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); 178 179 if (clk_mgr == NULL) { 180 BREAK_TO_DEBUGGER(); 181 return NULL; 182 } 183 if (ASIC_REV_IS_TONGA_P(asic_id.hw_internal_rev) || 184 ASIC_REV_IS_FIJI_P(asic_id.hw_internal_rev)) { 185 dce_clk_mgr_construct(ctx, clk_mgr); 186 return &clk_mgr->base; 187 } 188 if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev) || 189 ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev) || 190 ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev)) { 191 dce112_clk_mgr_construct(ctx, clk_mgr); 192 return &clk_mgr->base; 193 } 194 if (ASIC_REV_IS_VEGAM(asic_id.hw_internal_rev)) { 195 dce112_clk_mgr_construct(ctx, clk_mgr); 196 return &clk_mgr->base; 197 } 198 return &clk_mgr->base; 199 } 200 case FAMILY_AI: { 201 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); 202 203 if (clk_mgr == NULL) { 204 BREAK_TO_DEBUGGER(); 205 return NULL; 206 } 207 if (ASICREV_IS_VEGA20_P(asic_id.hw_internal_rev)) 208 dce121_clk_mgr_construct(ctx, clk_mgr); 209 else 210 dce120_clk_mgr_construct(ctx, clk_mgr); 211 return &clk_mgr->base; 212 } 213 #if defined(CONFIG_DRM_AMD_DC_FP) 214 case FAMILY_RV: { 215 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); 216 217 if (clk_mgr == NULL) { 218 BREAK_TO_DEBUGGER(); 219 return NULL; 220 } 221 222 if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) { 223 rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 224 return &clk_mgr->base; 225 } 226 227 if (ASICREV_IS_GREEN_SARDINE(asic_id.hw_internal_rev)) { 228 rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 229 return &clk_mgr->base; 230 } 231 if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) { 232 rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu); 233 return &clk_mgr->base; 234 } 235 if (ASICREV_IS_RAVEN(asic_id.hw_internal_rev) || 236 ASICREV_IS_PICASSO(asic_id.hw_internal_rev)) { 237 rv1_clk_mgr_construct(ctx, clk_mgr, pp_smu); 238 return &clk_mgr->base; 239 } 240 return &clk_mgr->base; 241 } 242 case FAMILY_NV: { 243 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); 244 245 if (clk_mgr == NULL) { 246 BREAK_TO_DEBUGGER(); 247 return NULL; 248 } 249 if (ctx->dce_version == DCN_VERSION_2_01) { 250 dcn201_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 251 return &clk_mgr->base; 252 } 253 if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) { 254 dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 255 return &clk_mgr->base; 256 } 257 if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) { 258 dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 259 return &clk_mgr->base; 260 } 261 if (ASICREV_IS_BEIGE_GOBY_P(asic_id.hw_internal_rev)) { 262 dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 263 return &clk_mgr->base; 264 } 265 dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 266 return &clk_mgr->base; 267 } 268 case FAMILY_VGH: 269 if (ASICREV_IS_VANGOGH(asic_id.hw_internal_rev)) { 270 struct clk_mgr_vgh *clk_mgr = kzalloc_obj(*clk_mgr); 271 272 if (clk_mgr == NULL) { 273 BREAK_TO_DEBUGGER(); 274 return NULL; 275 } 276 vg_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 277 return &clk_mgr->base.base; 278 } 279 break; 280 281 case FAMILY_YELLOW_CARP: { 282 struct clk_mgr_dcn31 *clk_mgr = kzalloc_obj(*clk_mgr); 283 284 if (clk_mgr == NULL) { 285 BREAK_TO_DEBUGGER(); 286 return NULL; 287 } 288 289 dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 290 return &clk_mgr->base.base; 291 } 292 break; 293 case AMDGPU_FAMILY_GC_10_3_6: { 294 struct clk_mgr_dcn315 *clk_mgr = kzalloc_obj(*clk_mgr); 295 296 if (clk_mgr == NULL) { 297 BREAK_TO_DEBUGGER(); 298 return NULL; 299 } 300 301 dcn315_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 302 return &clk_mgr->base.base; 303 } 304 break; 305 case AMDGPU_FAMILY_GC_10_3_7: { 306 struct clk_mgr_dcn316 *clk_mgr = kzalloc_obj(*clk_mgr); 307 308 if (clk_mgr == NULL) { 309 BREAK_TO_DEBUGGER(); 310 return NULL; 311 } 312 313 dcn316_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 314 return &clk_mgr->base.base; 315 } 316 break; 317 case AMDGPU_FAMILY_GC_11_0_0: { 318 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); 319 320 if (clk_mgr == NULL) { 321 BREAK_TO_DEBUGGER(); 322 return NULL; 323 } 324 dcn32_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 325 return &clk_mgr->base; 326 } 327 328 case AMDGPU_FAMILY_GC_11_0_1: { 329 struct clk_mgr_dcn314 *clk_mgr = kzalloc_obj(*clk_mgr); 330 331 if (clk_mgr == NULL) { 332 BREAK_TO_DEBUGGER(); 333 return NULL; 334 } 335 336 dcn314_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 337 return &clk_mgr->base.base; 338 } 339 break; 340 341 case AMDGPU_FAMILY_GC_11_5_0: { 342 if (ctx->dce_version == DCN_VERSION_4_2B) { 343 struct clk_mgr_dcn42 *clk_mgr = kzalloc_obj(*clk_mgr); 344 345 if (clk_mgr == NULL) { 346 BREAK_TO_DEBUGGER(); 347 return NULL; 348 } 349 dcn42b_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 350 return &clk_mgr->base.base; 351 } 352 struct clk_mgr_dcn35 *clk_mgr = kzalloc_obj(*clk_mgr); 353 354 if (clk_mgr == NULL) { 355 BREAK_TO_DEBUGGER(); 356 return NULL; 357 } 358 if (ctx->dce_version == DCN_VERSION_3_51) 359 dcn351_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 360 else 361 dcn35_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 362 363 return &clk_mgr->base.base; 364 } 365 break; 366 367 case AMDGPU_FAMILY_GC_12_0_0: { 368 struct clk_mgr_internal *clk_mgr = dcn401_clk_mgr_construct(ctx, dccg); 369 370 if (clk_mgr == NULL) { 371 BREAK_TO_DEBUGGER(); 372 return NULL; 373 } 374 375 return &clk_mgr->base; 376 } 377 break; 378 case AMDGPU_FAMILY_GC_11_5_4: { 379 struct clk_mgr_dcn42 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); 380 381 if (clk_mgr == NULL) { 382 BREAK_TO_DEBUGGER(); 383 return NULL; 384 } 385 386 dcn42_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 387 return &clk_mgr->base.base; 388 } 389 break; 390 #endif /* CONFIG_DRM_AMD_DC_FP */ 391 default: 392 ASSERT(0); /* Unknown Asic */ 393 break; 394 } 395 396 return NULL; 397 } 398 399 void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) 400 { 401 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 402 403 #ifdef CONFIG_DRM_AMD_DC_FP 404 switch (clk_mgr_base->ctx->asic_id.chip_family) { 405 case FAMILY_NV: 406 if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { 407 dcn3_clk_mgr_destroy(clk_mgr); 408 } else if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { 409 dcn3_clk_mgr_destroy(clk_mgr); 410 } 411 if (ASICREV_IS_BEIGE_GOBY_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { 412 dcn3_clk_mgr_destroy(clk_mgr); 413 } 414 break; 415 416 case FAMILY_VGH: 417 if (ASICREV_IS_VANGOGH(clk_mgr_base->ctx->asic_id.hw_internal_rev)) 418 vg_clk_mgr_destroy(clk_mgr); 419 break; 420 421 case FAMILY_YELLOW_CARP: 422 dcn31_clk_mgr_destroy(clk_mgr); 423 break; 424 425 case AMDGPU_FAMILY_GC_10_3_6: 426 dcn315_clk_mgr_destroy(clk_mgr); 427 break; 428 429 case AMDGPU_FAMILY_GC_10_3_7: 430 dcn316_clk_mgr_destroy(clk_mgr); 431 break; 432 433 case AMDGPU_FAMILY_GC_11_0_0: 434 dcn32_clk_mgr_destroy(clk_mgr); 435 break; 436 437 case AMDGPU_FAMILY_GC_11_0_1: 438 dcn314_clk_mgr_destroy(clk_mgr); 439 break; 440 441 case AMDGPU_FAMILY_GC_11_5_0: 442 if (clk_mgr_base->ctx->dce_version == DCN_VERSION_4_2B) { 443 dcn42_clk_mgr_destroy(clk_mgr); 444 break; 445 } 446 dcn35_clk_mgr_destroy(clk_mgr); 447 break; 448 case AMDGPU_FAMILY_GC_12_0_0: 449 dcn401_clk_mgr_destroy(clk_mgr); 450 break; 451 case AMDGPU_FAMILY_GC_11_5_4: 452 dcn42_clk_mgr_destroy(clk_mgr); 453 break; 454 455 default: 456 break; 457 } 458 #endif /* CONFIG_DRM_AMD_DC_FP */ 459 460 kfree(clk_mgr); 461 } 462 463