| 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 */ |
| 40 | enum 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.*/ |
| 49 | enum 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 | |
| 255 | struct 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 | |
| 314 | struct clk_mgr_shift { |
| 315 | CLK_REG_FIELD_LIST(uint8_t) |
| 316 | CLK20_REG_FIELD_LIST(uint8_t) |
| 317 | }; |
| 318 | |
| 319 | struct clk_mgr_mask { |
| 320 | CLK_REG_FIELD_LIST(uint32_t) |
| 321 | CLK20_REG_FIELD_LIST(uint32_t) |
| 322 | }; |
| 323 | |
| 324 | enum 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 | |
| 339 | struct state_dependent_clocks { |
| 340 | int display_clk_khz; |
| 341 | int pixel_clk_khz; |
| 342 | }; |
| 343 | |
| 344 | struct 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 | |
| 424 | struct 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 | |
| 437 | static 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 | |
| 442 | static 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 | |
| 454 | static inline int khz_to_mhz_ceil(int khz) |
| 455 | { |
| 456 | return (khz + 999) / 1000; |
| 457 | } |
| 458 | |
| 459 | static inline int khz_to_mhz_floor(int khz) |
| 460 | { |
| 461 | return khz / 1000; |
| 462 | } |
| 463 | |
| 464 | int clk_mgr_helper_get_active_display_cnt( |
| 465 | struct dc *dc, |
| 466 | struct dc_state *context); |
| 467 | |
| 468 | int 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__ |
| 475 | |