FILE
clk_mgr_internal.h
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
1/* 2 * Copyright 2018 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#ifndef __DAL_CLK_MGR_INTERNAL_H__ 27#define __DAL_CLK_MGR_INTERNAL_H__ 28 29#include "clk_mgr.h" 30#include "dc.h" 31 32/* 33 * only thing needed from here is MEMORY_TYPE_MULTIPLIER_CZ, which is also 34 * used in resource, perhaps this should be defined somewhere more common. 35 */ 36#include "resource.h" 37 38 39/* Starting DID for each range */ 40enum dentist_base_divider_id { 41 DENTIST_BASE_DID_1 = 0x08, 42 DENTIST_BASE_DID_2 = 0x40, 43 DENTIST_BASE_DID_3 = 0x60, 44 DENTIST_BASE_DID_4 = 0x7e, 45 DENTIST_MAX_DID = 0x7f 46}; 47 48/* Starting point and step size for each divider range.*/ 49enum dentist_divider_range { 50 DENTIST_DIVIDER_RANGE_1_START = 8, /* 2.00 */ 51 DENTIST_DIVIDER_RANGE_1_STEP = 1, /* 0.25 */ 52 DENTIST_DIVIDER_RANGE_2_START = 64, /* 16.00 */ 53 DENTIST_DIVIDER_RANGE_2_STEP = 2, /* 0.50 */ 54 DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */ 55 DENTIST_DIVIDER_RANGE_3_STEP = 4, /* 1.00 */ 56 DENTIST_DIVIDER_RANGE_4_START = 248, /* 62.00 */ 57 DENTIST_DIVIDER_RANGE_4_STEP = 264, /* 66.00 */ 58 DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4 59}; 60 61/* 62 *************************************************************************************** 63 ****************** Clock Manager Private Macros and Defines *************************** 64 *************************************************************************************** 65 */ 66 67/* Macros */ 68 69#define TO_CLK_MGR_INTERNAL(clk_mgr)\ 70 container_of(clk_mgr, struct clk_mgr_internal, base) 71 72#define CTX \ 73 clk_mgr->base.ctx 74 75#define DC_LOGGER \ 76 dc->ctx->logger 77 78 79 80 81#define CLK_BASE(inst) \ 82 CLK_BASE_INNER(inst) 83 84#define CLK_SRI(reg_name, block, inst)\ 85 .reg_name = CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \ 86 mm ## block ## _ ## inst ## _ ## reg_name 87 88#define CLK_COMMON_REG_LIST_DCE_BASE() \ 89 .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ 90 .DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL 91 92#if defined(CONFIG_DRM_AMD_DC_SI) 93#define CLK_COMMON_REG_LIST_DCE60_BASE() \ 94 SR(DENTIST_DISPCLK_CNTL) 95#endif 96 97#define CLK_COMMON_REG_LIST_DCN_BASE() \ 98 SR(DENTIST_DISPCLK_CNTL) 99 100#define CLK_COMMON_REG_LIST_DCN_201() \ 101 SR(DENTIST_DISPCLK_CNTL), \ 102 CLK_SRI(CLK4_CLK_PLL_REQ, CLK4, 0), \ 103 CLK_SRI(CLK4_CLK2_CURRENT_CNT, CLK4, 0) 104 105#define CLK_REG_LIST_NV10() \ 106 SR(DENTIST_DISPCLK_CNTL), \ 107 CLK_SRI(CLK3_CLK_PLL_REQ, CLK3, 0), \ 108 CLK_SRI(CLK3_CLK2_DFS_CNTL, CLK3, 0) 109 110#define CLK_REG_LIST_DCN3() \ 111 SR(DENTIST_DISPCLK_CNTL), \ 112 CLK_SRI(CLK0_CLK_PLL_REQ, CLK02, 0), \ 113 CLK_SRI(CLK0_CLK2_DFS_CNTL, CLK02, 0) 114 115#define CLK_SF(reg_name, field_name, post_fix)\ 116 .field_name = reg_name ## __ ## field_name ## post_fix 117 118#define CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \ 119 CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \ 120 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh) 121 122#if defined(CONFIG_DRM_AMD_DC_SI) 123#define CLK_COMMON_MASK_SH_LIST_DCE60_COMMON_BASE(mask_sh) \ 124 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ 125 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) 126#endif 127 128#define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \ 129 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ 130 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) 131 132#define CLK_MASK_SH_LIST_RV1(mask_sh) \ 133 CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ 134 CLK_SF(MP1_SMN_C2PMSG_67, CONTENT, mask_sh),\ 135 CLK_SF(MP1_SMN_C2PMSG_83, CONTENT, mask_sh),\ 136 CLK_SF(MP1_SMN_C2PMSG_91, CONTENT, mask_sh), 137 138#define CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh) \ 139 CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ 140 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ 141 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh) 142 143#define CLK_MASK_SH_LIST_NV10(mask_sh) \ 144 CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\ 145 CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_int, mask_sh),\ 146 CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_frac, mask_sh) 147 148#define CLK_COMMON_MASK_SH_LIST_DCN201_BASE(mask_sh) \ 149 CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ 150 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ 151 CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh),\ 152 CLK_SF(CLK4_0_CLK4_CLK_PLL_REQ, FbMult_int, mask_sh) 153 154#define CLK_REG_LIST_DCN32() \ 155 SR(DENTIST_DISPCLK_CNTL), \ 156 CLK_SR_DCN32(CLK1_CLK_PLL_REQ), \ 157 CLK_SR_DCN32(CLK1_CLK0_DFS_CNTL), \ 158 CLK_SR_DCN32(CLK1_CLK1_DFS_CNTL), \ 159 CLK_SR_DCN32(CLK1_CLK2_DFS_CNTL), \ 160 CLK_SR_DCN32(CLK1_CLK3_DFS_CNTL), \ 161 CLK_SR_DCN32(CLK1_CLK4_DFS_CNTL), \ 162 CLK_SR_DCN32(CLK1_CLK0_CURRENT_CNT), \ 163 CLK_SR_DCN32(CLK1_CLK1_CURRENT_CNT), \ 164 CLK_SR_DCN32(CLK1_CLK2_CURRENT_CNT), \ 165 CLK_SR_DCN32(CLK1_CLK3_CURRENT_CNT), \ 166 CLK_SR_DCN32(CLK1_CLK4_CURRENT_CNT), \ 167 CLK_SR_DCN32(CLK4_CLK0_CURRENT_CNT) 168 169#define CLK_REG_LIST_DCN35() \ 170 CLK_SR_DCN35(CLK1_CLK_PLL_REQ), \ 171 CLK_SR_DCN35(CLK1_CLK0_DFS_CNTL), \ 172 CLK_SR_DCN35(CLK1_CLK1_DFS_CNTL), \ 173 CLK_SR_DCN35(CLK1_CLK2_DFS_CNTL), \ 174 CLK_SR_DCN35(CLK1_CLK3_DFS_CNTL), \ 175 CLK_SR_DCN35(CLK1_CLK4_DFS_CNTL), \ 176 CLK_SR_DCN35(CLK1_CLK5_DFS_CNTL), \ 177 CLK_SR_DCN35(CLK1_CLK0_CURRENT_CNT), \ 178 CLK_SR_DCN35(CLK1_CLK1_CURRENT_CNT), \ 179 CLK_SR_DCN35(CLK1_CLK2_CURRENT_CNT), \ 180 CLK_SR_DCN35(CLK1_CLK3_CURRENT_CNT), \ 181 CLK_SR_DCN35(CLK1_CLK4_CURRENT_CNT), \ 182 CLK_SR_DCN35(CLK1_CLK5_CURRENT_CNT), \ 183 CLK_SR_DCN35(CLK1_CLK0_BYPASS_CNTL), \ 184 CLK_SR_DCN35(CLK1_CLK1_BYPASS_CNTL), \ 185 CLK_SR_DCN35(CLK1_CLK2_BYPASS_CNTL), \ 186 CLK_SR_DCN35(CLK1_CLK3_BYPASS_CNTL), \ 187 CLK_SR_DCN35(CLK1_CLK4_BYPASS_CNTL),\ 188 CLK_SR_DCN35(CLK1_CLK5_BYPASS_CNTL), \ 189 CLK_SR_DCN35(CLK1_CLK0_DS_CNTL), \ 190 CLK_SR_DCN35(CLK1_CLK1_DS_CNTL), \ 191 CLK_SR_DCN35(CLK1_CLK2_DS_CNTL), \ 192 CLK_SR_DCN35(CLK1_CLK3_DS_CNTL), \ 193 CLK_SR_DCN35(CLK1_CLK4_DS_CNTL), \ 194 CLK_SR_DCN35(CLK1_CLK5_DS_CNTL), \ 195 CLK_SR_DCN35(CLK1_CLK0_ALLOW_DS), \ 196 CLK_SR_DCN35(CLK1_CLK1_ALLOW_DS), \ 197 CLK_SR_DCN35(CLK1_CLK2_ALLOW_DS), \ 198 CLK_SR_DCN35(CLK1_CLK3_ALLOW_DS), \ 199 CLK_SR_DCN35(CLK1_CLK4_ALLOW_DS), \ 200 CLK_SR_DCN35(CLK1_CLK5_ALLOW_DS), \ 201 CLK_SR_DCN35(CLK5_spll_field_8), \ 202 CLK_SR_DCN35(CLK6_spll_field_8), \ 203 SR(DENTIST_DISPCLK_CNTL), \ 204 205#define CLK_COMMON_MASK_SH_LIST_DCN32(mask_sh) \ 206 CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\ 207 CLK_SF(CLK1_CLK_PLL_REQ, FbMult_int, mask_sh),\ 208 CLK_SF(CLK1_CLK_PLL_REQ, FbMult_frac, mask_sh) 209 210#define CLK_REG_LIST_DCN321() \ 211 SR(DENTIST_DISPCLK_CNTL), \ 212 CLK_SR_DCN321(CLK0_CLK_PLL_REQ, CLK01, 0), \ 213 CLK_SR_DCN321(CLK0_CLK0_DFS_CNTL, CLK01, 0), \ 214 CLK_SR_DCN321(CLK0_CLK1_DFS_CNTL, CLK01, 0), \ 215 CLK_SR_DCN321(CLK0_CLK2_DFS_CNTL, CLK01, 0), \ 216 CLK_SR_DCN321(CLK0_CLK3_DFS_CNTL, CLK01, 0), \ 217 CLK_SR_DCN321(CLK0_CLK4_DFS_CNTL, CLK01, 0) 218 219#define CLK_COMMON_MASK_SH_LIST_DCN321(mask_sh) \ 220 CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\ 221 CLK_SF(CLK0_CLK_PLL_REQ, FbMult_int, mask_sh),\ 222 CLK_SF(CLK0_CLK_PLL_REQ, FbMult_frac, mask_sh) 223 224#define CLK_REG_LIST_DCN401() \ 225 SR(DENTIST_DISPCLK_CNTL), \ 226 CLK_SR_DCN401(CLK0_CLK_PLL_REQ, CLK01, 0), \ 227 CLK_SR_DCN401(CLK0_CLK0_DFS_CNTL, CLK01, 0), \ 228 CLK_SR_DCN401(CLK0_CLK1_DFS_CNTL, CLK01, 0), \ 229 CLK_SR_DCN401(CLK0_CLK2_DFS_CNTL, CLK01, 0), \ 230 CLK_SR_DCN401(CLK0_CLK3_DFS_CNTL, CLK01, 0), \ 231 CLK_SR_DCN401(CLK0_CLK4_DFS_CNTL, CLK01, 0), \ 232 CLK_SR_DCN401(CLK2_CLK2_DFS_CNTL, CLK20, 0) 233 234#define CLK_COMMON_MASK_SH_LIST_DCN401(mask_sh) \ 235 CLK_COMMON_MASK_SH_LIST_DCN321(mask_sh) 236 237#define CLK_REG_FIELD_LIST(type) \ 238 type DPREFCLK_SRC_SEL; \ 239 type DENTIST_DPREFCLK_WDIVIDER; \ 240 type DENTIST_DISPCLK_WDIVIDER; \ 241 type DENTIST_DISPCLK_CHG_DONE; 242 243#define CLK20_REG_FIELD_LIST(type) \ 244 type DENTIST_DPPCLK_WDIVIDER; \ 245 type DENTIST_DPPCLK_CHG_DONE; \ 246 type FbMult_int; \ 247 type FbMult_frac; 248 249/* 250 *************************************************************************************** 251 ****************** Clock Manager Private Structures *********************************** 252 *************************************************************************************** 253 */ 254 255struct clk_mgr_registers { 256 uint32_t DPREFCLK_CNTL; 257 uint32_t DENTIST_DISPCLK_CNTL; 258 259 uint32_t CLK4_CLK2_CURRENT_CNT; 260 uint32_t CLK4_CLK_PLL_REQ; 261 262 uint32_t CLK4_CLK0_CURRENT_CNT; 263 264 uint32_t CLK3_CLK2_DFS_CNTL; 265 uint32_t CLK3_CLK_PLL_REQ; 266 267 uint32_t CLK0_CLK2_DFS_CNTL; 268 uint32_t CLK0_CLK_PLL_REQ; 269 270 uint32_t CLK1_CLK_PLL_REQ; 271 uint32_t CLK1_CLK0_DFS_CNTL; 272 uint32_t CLK1_CLK1_DFS_CNTL; 273 uint32_t CLK1_CLK2_DFS_CNTL; 274 uint32_t CLK1_CLK3_DFS_CNTL; 275 uint32_t CLK1_CLK4_DFS_CNTL; 276 uint32_t CLK1_CLK5_DFS_CNTL; 277 uint32_t CLK2_CLK2_DFS_CNTL; 278 279 uint32_t CLK1_CLK0_CURRENT_CNT; 280 uint32_t CLK1_CLK1_CURRENT_CNT; 281 uint32_t CLK1_CLK2_CURRENT_CNT; 282 uint32_t CLK1_CLK3_CURRENT_CNT; 283 uint32_t CLK1_CLK4_CURRENT_CNT; 284 uint32_t CLK1_CLK5_CURRENT_CNT; 285 286 uint32_t CLK0_CLK0_DFS_CNTL; 287 uint32_t CLK0_CLK1_DFS_CNTL; 288 uint32_t CLK0_CLK3_DFS_CNTL; 289 uint32_t CLK0_CLK4_DFS_CNTL; 290 uint32_t CLK1_CLK0_BYPASS_CNTL; 291 uint32_t CLK1_CLK1_BYPASS_CNTL; 292 uint32_t CLK1_CLK2_BYPASS_CNTL; 293 uint32_t CLK1_CLK3_BYPASS_CNTL; 294 uint32_t CLK1_CLK4_BYPASS_CNTL; 295 uint32_t CLK1_CLK5_BYPASS_CNTL; 296 297 uint32_t CLK1_CLK0_DS_CNTL; 298 uint32_t CLK1_CLK1_DS_CNTL; 299 uint32_t CLK1_CLK2_DS_CNTL; 300 uint32_t CLK1_CLK3_DS_CNTL; 301 uint32_t CLK1_CLK4_DS_CNTL; 302 uint32_t CLK1_CLK5_DS_CNTL; 303 304 uint32_t CLK1_CLK0_ALLOW_DS; 305 uint32_t CLK1_CLK1_ALLOW_DS; 306 uint32_t CLK1_CLK2_ALLOW_DS; 307 uint32_t CLK1_CLK3_ALLOW_DS; 308 uint32_t CLK1_CLK4_ALLOW_DS; 309 uint32_t CLK1_CLK5_ALLOW_DS; 310 uint32_t CLK5_spll_field_8; 311 uint32_t CLK6_spll_field_8; 312}; 313 314struct clk_mgr_shift { 315 CLK_REG_FIELD_LIST(uint8_t) 316 CLK20_REG_FIELD_LIST(uint8_t) 317}; 318 319struct clk_mgr_mask { 320 CLK_REG_FIELD_LIST(uint32_t) 321 CLK20_REG_FIELD_LIST(uint32_t) 322}; 323 324enum clock_type { 325 clock_type_dispclk = 1, 326 clock_type_dcfclk, 327 clock_type_socclk, 328 clock_type_pixelclk, 329 clock_type_phyclk, 330 clock_type_dppclk, 331 clock_type_fclk, 332 clock_type_dcfdsclk, 333 clock_type_dscclk, 334 clock_type_uclk, 335 clock_type_dramclk, 336}; 337 338 339struct state_dependent_clocks { 340 int display_clk_khz; 341 int pixel_clk_khz; 342}; 343 344struct clk_mgr_internal { 345 struct clk_mgr base; 346 int smu_ver; 347 struct pp_smu_funcs *pp_smu; 348 struct clk_mgr_internal_funcs *funcs; 349 350 struct dccg *dccg; 351 352 /* 353 * For backwards compatbility with previous implementation 354 * TODO: remove these after everything transitions to new pattern 355 * Rationale is that clk registers change a lot across DCE versions 356 * and a shared data structure doesn't really make sense. 357 */ 358 const struct clk_mgr_registers *regs; 359 const struct clk_mgr_shift *clk_mgr_shift; 360 const struct clk_mgr_mask *clk_mgr_mask; 361 362 struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; 363 364 /*TODO: figure out which of the below fields should be here vs in asic specific portion */ 365 /* Cache the status of DFS-bypass feature*/ 366 bool dfs_bypass_enabled; 367 /* True if the DFS-bypass feature is enabled and active. */ 368 bool dfs_bypass_active; 369 370 uint32_t dfs_ref_freq_khz; 371 /* 372 * Cache the display clock returned by VBIOS if DFS-bypass is enabled. 373 * This is basically "Crystal Frequency In KHz" (XTALIN) frequency 374 */ 375 int dfs_bypass_disp_clk; 376 377 /** 378 * @ss_on_dprefclk: 379 * 380 * True if spread spectrum is enabled on the DP ref clock. 381 */ 382 bool ss_on_dprefclk; 383 384 /** 385 * @xgmi_enabled: 386 * 387 * True if xGMI is enabled. On VG20, both audio and display clocks need 388 * to be adjusted with the WAFL link's SS info if xGMI is enabled. 389 */ 390 bool xgmi_enabled; 391 392 /** 393 * @dprefclk_ss_percentage: 394 * 395 * DPREFCLK SS percentage (if down-spread enabled). 396 * 397 * Note that if XGMI is enabled, the SS info (percentage and divider) 398 * from the WAFL link is used instead. This is decided during 399 * dce_clk_mgr initialization. 400 */ 401 int dprefclk_ss_percentage; 402 403 /** 404 * @dprefclk_ss_divider: 405 * 406 * DPREFCLK SS percentage Divider (100 or 1000). 407 */ 408 int dprefclk_ss_divider; 409 410 enum dm_pp_clocks_state max_clks_state; 411 enum dm_pp_clocks_state cur_min_clks_state; 412 bool periodic_retraining_disabled; 413 414 unsigned int cur_phyclk_req_table[MAX_LINKS]; 415 416 bool smu_present; 417 void *wm_range_table; 418 long long wm_range_table_addr; 419 420 bool dpm_present; 421 bool pme_trigger_pending; 422}; 423 424struct clk_mgr_internal_funcs { 425 int (*set_dispclk)(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz); 426 int (*set_dprefclk)(struct clk_mgr_internal *clk_mgr); 427}; 428 429 430/* 431 *************************************************************************************** 432 ****************** Clock Manager Level Helper functions ******************************* 433 *************************************************************************************** 434 */ 435 436 437static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) 438{ 439 return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); 440} 441 442static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support) 443{ 444 if (cur_support != calc_support) { 445 if (calc_support && safe_to_lower) 446 return true; 447 else if (!calc_support && !safe_to_lower) 448 return true; 449 } 450 451 return false; 452} 453 454static inline int khz_to_mhz_ceil(int khz) 455{ 456 return (khz + 999) / 1000; 457} 458 459static inline int khz_to_mhz_floor(int khz) 460{ 461 return khz / 1000; 462} 463 464int clk_mgr_helper_get_active_display_cnt( 465 struct dc *dc, 466 struct dc_state *context); 467 468int clk_mgr_helper_get_active_plane_cnt( 469 struct dc *dc, 470 struct dc_state *context); 471 472 473 474#endif //__DAL_CLK_MGR_INTERNAL_H__
~/
Read-only file preview.