| .. | .. |
|---|
| 23 | 23 | * |
|---|
| 24 | 24 | */ |
|---|
| 25 | 25 | |
|---|
| 26 | +#include <linux/slab.h> |
|---|
| 27 | + |
|---|
| 26 | 28 | #include "dm_services.h" |
|---|
| 27 | 29 | |
|---|
| 28 | 30 | |
|---|
| .. | .. |
|---|
| 33 | 35 | #include "include/logger_interface.h" |
|---|
| 34 | 36 | |
|---|
| 35 | 37 | #include "dce_clock_source.h" |
|---|
| 38 | +#include "clk_mgr.h" |
|---|
| 36 | 39 | |
|---|
| 37 | 40 | #include "reg_helper.h" |
|---|
| 38 | 41 | |
|---|
| .. | .. |
|---|
| 51 | 54 | #define FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM 6 |
|---|
| 52 | 55 | #define CALC_PLL_CLK_SRC_ERR_TOLERANCE 1 |
|---|
| 53 | 56 | #define MAX_PLL_CALC_ERROR 0xFFFFFFFF |
|---|
| 57 | + |
|---|
| 58 | +#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) |
|---|
| 54 | 59 | |
|---|
| 55 | 60 | static const struct spread_spectrum_data *get_ss_data_entry( |
|---|
| 56 | 61 | struct dce110_clk_src *clk_src, |
|---|
| .. | .. |
|---|
| 73 | 78 | case SIGNAL_TYPE_HDMI_TYPE_A: |
|---|
| 74 | 79 | ss_parm = clk_src->hdmi_ss_params; |
|---|
| 75 | 80 | entrys_num = clk_src->hdmi_ss_params_cnt; |
|---|
| 81 | + break; |
|---|
| 82 | + |
|---|
| 83 | + case SIGNAL_TYPE_LVDS: |
|---|
| 84 | + ss_parm = clk_src->lvds_ss_params; |
|---|
| 85 | + entrys_num = clk_src->lvds_ss_params_cnt; |
|---|
| 76 | 86 | break; |
|---|
| 77 | 87 | |
|---|
| 78 | 88 | case SIGNAL_TYPE_DISPLAY_PORT: |
|---|
| .. | .. |
|---|
| 103 | 113 | } |
|---|
| 104 | 114 | |
|---|
| 105 | 115 | /** |
|---|
| 106 | | -* Function: calculate_fb_and_fractional_fb_divider |
|---|
| 107 | | -* |
|---|
| 108 | | -* * DESCRIPTION: Calculates feedback and fractional feedback dividers values |
|---|
| 109 | | -* |
|---|
| 110 | | -*PARAMETERS: |
|---|
| 111 | | -* targetPixelClock Desired frequency in 10 KHz |
|---|
| 112 | | -* ref_divider Reference divider (already known) |
|---|
| 113 | | -* postDivider Post Divider (already known) |
|---|
| 114 | | -* feedback_divider_param Pointer where to store |
|---|
| 115 | | -* calculated feedback divider value |
|---|
| 116 | | -* fract_feedback_divider_param Pointer where to store |
|---|
| 117 | | -* calculated fract feedback divider value |
|---|
| 118 | | -* |
|---|
| 119 | | -*RETURNS: |
|---|
| 120 | | -* It fills the locations pointed by feedback_divider_param |
|---|
| 121 | | -* and fract_feedback_divider_param |
|---|
| 122 | | -* It returns - true if feedback divider not 0 |
|---|
| 123 | | -* - false should never happen) |
|---|
| 124 | | -*/ |
|---|
| 116 | + * Function: calculate_fb_and_fractional_fb_divider |
|---|
| 117 | + * |
|---|
| 118 | + * * DESCRIPTION: Calculates feedback and fractional feedback dividers values |
|---|
| 119 | + * |
|---|
| 120 | + *PARAMETERS: |
|---|
| 121 | + * targetPixelClock Desired frequency in 100 Hz |
|---|
| 122 | + * ref_divider Reference divider (already known) |
|---|
| 123 | + * postDivider Post Divider (already known) |
|---|
| 124 | + * feedback_divider_param Pointer where to store |
|---|
| 125 | + * calculated feedback divider value |
|---|
| 126 | + * fract_feedback_divider_param Pointer where to store |
|---|
| 127 | + * calculated fract feedback divider value |
|---|
| 128 | + * |
|---|
| 129 | + *RETURNS: |
|---|
| 130 | + * It fills the locations pointed by feedback_divider_param |
|---|
| 131 | + * and fract_feedback_divider_param |
|---|
| 132 | + * It returns - true if feedback divider not 0 |
|---|
| 133 | + * - false should never happen) |
|---|
| 134 | + */ |
|---|
| 125 | 135 | static bool calculate_fb_and_fractional_fb_divider( |
|---|
| 126 | 136 | struct calc_pll_clock_source *calc_pll_cs, |
|---|
| 127 | | - uint32_t target_pix_clk_khz, |
|---|
| 137 | + uint32_t target_pix_clk_100hz, |
|---|
| 128 | 138 | uint32_t ref_divider, |
|---|
| 129 | 139 | uint32_t post_divider, |
|---|
| 130 | 140 | uint32_t *feedback_divider_param, |
|---|
| .. | .. |
|---|
| 133 | 143 | uint64_t feedback_divider; |
|---|
| 134 | 144 | |
|---|
| 135 | 145 | feedback_divider = |
|---|
| 136 | | - (uint64_t)target_pix_clk_khz * ref_divider * post_divider; |
|---|
| 146 | + (uint64_t)target_pix_clk_100hz * ref_divider * post_divider; |
|---|
| 137 | 147 | feedback_divider *= 10; |
|---|
| 138 | 148 | /* additional factor, since we divide by 10 afterwards */ |
|---|
| 139 | 149 | feedback_divider *= (uint64_t)(calc_pll_cs->fract_fb_divider_factor); |
|---|
| 140 | | - feedback_divider = div_u64(feedback_divider, calc_pll_cs->ref_freq_khz); |
|---|
| 150 | + feedback_divider = div_u64(feedback_divider, calc_pll_cs->ref_freq_khz * 10ull); |
|---|
| 141 | 151 | |
|---|
| 142 | 152 | /*Round to the number of precision |
|---|
| 143 | 153 | * The following code replace the old code (ullfeedbackDivider + 5)/10 |
|---|
| .. | .. |
|---|
| 178 | 188 | *RETURNS: |
|---|
| 179 | 189 | * It fills the PLLSettings structure with PLL Dividers values |
|---|
| 180 | 190 | * if calculated values are within required tolerance |
|---|
| 181 | | -* It returns - true if eror is within tolerance |
|---|
| 182 | | -* - false if eror is not within tolerance |
|---|
| 191 | +* It returns - true if error is within tolerance |
|---|
| 192 | +* - false if error is not within tolerance |
|---|
| 183 | 193 | */ |
|---|
| 184 | 194 | static bool calc_fb_divider_checking_tolerance( |
|---|
| 185 | 195 | struct calc_pll_clock_source *calc_pll_cs, |
|---|
| .. | .. |
|---|
| 190 | 200 | { |
|---|
| 191 | 201 | uint32_t feedback_divider; |
|---|
| 192 | 202 | uint32_t fract_feedback_divider; |
|---|
| 193 | | - uint32_t actual_calculated_clock_khz; |
|---|
| 203 | + uint32_t actual_calculated_clock_100hz; |
|---|
| 194 | 204 | uint32_t abs_err; |
|---|
| 195 | | - uint64_t actual_calc_clk_khz; |
|---|
| 205 | + uint64_t actual_calc_clk_100hz; |
|---|
| 196 | 206 | |
|---|
| 197 | 207 | calculate_fb_and_fractional_fb_divider( |
|---|
| 198 | 208 | calc_pll_cs, |
|---|
| 199 | | - pll_settings->adjusted_pix_clk, |
|---|
| 209 | + pll_settings->adjusted_pix_clk_100hz, |
|---|
| 200 | 210 | ref_divider, |
|---|
| 201 | 211 | post_divider, |
|---|
| 202 | 212 | &feedback_divider, |
|---|
| 203 | 213 | &fract_feedback_divider); |
|---|
| 204 | 214 | |
|---|
| 205 | 215 | /*Actual calculated value*/ |
|---|
| 206 | | - actual_calc_clk_khz = (uint64_t)feedback_divider * |
|---|
| 216 | + actual_calc_clk_100hz = (uint64_t)feedback_divider * |
|---|
| 207 | 217 | calc_pll_cs->fract_fb_divider_factor + |
|---|
| 208 | 218 | fract_feedback_divider; |
|---|
| 209 | | - actual_calc_clk_khz *= calc_pll_cs->ref_freq_khz; |
|---|
| 210 | | - actual_calc_clk_khz = |
|---|
| 211 | | - div_u64(actual_calc_clk_khz, |
|---|
| 219 | + actual_calc_clk_100hz *= calc_pll_cs->ref_freq_khz * 10; |
|---|
| 220 | + actual_calc_clk_100hz = |
|---|
| 221 | + div_u64(actual_calc_clk_100hz, |
|---|
| 212 | 222 | ref_divider * post_divider * |
|---|
| 213 | 223 | calc_pll_cs->fract_fb_divider_factor); |
|---|
| 214 | 224 | |
|---|
| 215 | | - actual_calculated_clock_khz = (uint32_t)(actual_calc_clk_khz); |
|---|
| 225 | + actual_calculated_clock_100hz = (uint32_t)(actual_calc_clk_100hz); |
|---|
| 216 | 226 | |
|---|
| 217 | | - abs_err = (actual_calculated_clock_khz > |
|---|
| 218 | | - pll_settings->adjusted_pix_clk) |
|---|
| 219 | | - ? actual_calculated_clock_khz - |
|---|
| 220 | | - pll_settings->adjusted_pix_clk |
|---|
| 221 | | - : pll_settings->adjusted_pix_clk - |
|---|
| 222 | | - actual_calculated_clock_khz; |
|---|
| 227 | + abs_err = (actual_calculated_clock_100hz > |
|---|
| 228 | + pll_settings->adjusted_pix_clk_100hz) |
|---|
| 229 | + ? actual_calculated_clock_100hz - |
|---|
| 230 | + pll_settings->adjusted_pix_clk_100hz |
|---|
| 231 | + : pll_settings->adjusted_pix_clk_100hz - |
|---|
| 232 | + actual_calculated_clock_100hz; |
|---|
| 223 | 233 | |
|---|
| 224 | 234 | if (abs_err <= tolerance) { |
|---|
| 225 | 235 | /*found good values*/ |
|---|
| .. | .. |
|---|
| 228 | 238 | pll_settings->feedback_divider = feedback_divider; |
|---|
| 229 | 239 | pll_settings->fract_feedback_divider = fract_feedback_divider; |
|---|
| 230 | 240 | pll_settings->pix_clk_post_divider = post_divider; |
|---|
| 231 | | - pll_settings->calculated_pix_clk = |
|---|
| 232 | | - actual_calculated_clock_khz; |
|---|
| 241 | + pll_settings->calculated_pix_clk_100hz = |
|---|
| 242 | + actual_calculated_clock_100hz; |
|---|
| 233 | 243 | pll_settings->vco_freq = |
|---|
| 234 | | - actual_calculated_clock_khz * post_divider; |
|---|
| 244 | + actual_calculated_clock_100hz * post_divider / 10; |
|---|
| 235 | 245 | return true; |
|---|
| 236 | 246 | } |
|---|
| 237 | 247 | return false; |
|---|
| .. | .. |
|---|
| 252 | 262 | |
|---|
| 253 | 263 | /* This is err_tolerance / 10000 = 0.0025 - acceptable error of 0.25% |
|---|
| 254 | 264 | * This is errorTolerance / 10000 = 0.0001 - acceptable error of 0.01%*/ |
|---|
| 255 | | - tolerance = (pll_settings->adjusted_pix_clk * err_tolerance) / |
|---|
| 256 | | - 10000; |
|---|
| 265 | + tolerance = (pll_settings->adjusted_pix_clk_100hz * err_tolerance) / |
|---|
| 266 | + 100000; |
|---|
| 257 | 267 | if (tolerance < CALC_PLL_CLK_SRC_ERR_TOLERANCE) |
|---|
| 258 | 268 | tolerance = CALC_PLL_CLK_SRC_ERR_TOLERANCE; |
|---|
| 259 | 269 | |
|---|
| .. | .. |
|---|
| 289 | 299 | uint32_t min_ref_divider; |
|---|
| 290 | 300 | uint32_t max_ref_divider; |
|---|
| 291 | 301 | |
|---|
| 292 | | - if (pll_settings->adjusted_pix_clk == 0) { |
|---|
| 302 | + if (pll_settings->adjusted_pix_clk_100hz == 0) { |
|---|
| 293 | 303 | DC_LOG_ERROR( |
|---|
| 294 | 304 | "%s Bad requested pixel clock", __func__); |
|---|
| 295 | 305 | return MAX_PLL_CALC_ERROR; |
|---|
| .. | .. |
|---|
| 301 | 311 | max_post_divider = pll_settings->pix_clk_post_divider; |
|---|
| 302 | 312 | } else { |
|---|
| 303 | 313 | min_post_divider = calc_pll_cs->min_pix_clock_pll_post_divider; |
|---|
| 304 | | - if (min_post_divider * pll_settings->adjusted_pix_clk < |
|---|
| 305 | | - calc_pll_cs->min_vco_khz) { |
|---|
| 306 | | - min_post_divider = calc_pll_cs->min_vco_khz / |
|---|
| 307 | | - pll_settings->adjusted_pix_clk; |
|---|
| 314 | + if (min_post_divider * pll_settings->adjusted_pix_clk_100hz < |
|---|
| 315 | + calc_pll_cs->min_vco_khz * 10) { |
|---|
| 316 | + min_post_divider = calc_pll_cs->min_vco_khz * 10 / |
|---|
| 317 | + pll_settings->adjusted_pix_clk_100hz; |
|---|
| 308 | 318 | if ((min_post_divider * |
|---|
| 309 | | - pll_settings->adjusted_pix_clk) < |
|---|
| 310 | | - calc_pll_cs->min_vco_khz) |
|---|
| 319 | + pll_settings->adjusted_pix_clk_100hz) < |
|---|
| 320 | + calc_pll_cs->min_vco_khz * 10) |
|---|
| 311 | 321 | min_post_divider++; |
|---|
| 312 | 322 | } |
|---|
| 313 | 323 | |
|---|
| 314 | 324 | max_post_divider = calc_pll_cs->max_pix_clock_pll_post_divider; |
|---|
| 315 | | - if (max_post_divider * pll_settings->adjusted_pix_clk |
|---|
| 316 | | - > calc_pll_cs->max_vco_khz) |
|---|
| 317 | | - max_post_divider = calc_pll_cs->max_vco_khz / |
|---|
| 318 | | - pll_settings->adjusted_pix_clk; |
|---|
| 325 | + if (max_post_divider * pll_settings->adjusted_pix_clk_100hz |
|---|
| 326 | + > calc_pll_cs->max_vco_khz * 10) |
|---|
| 327 | + max_post_divider = calc_pll_cs->max_vco_khz * 10 / |
|---|
| 328 | + pll_settings->adjusted_pix_clk_100hz; |
|---|
| 319 | 329 | } |
|---|
| 320 | 330 | |
|---|
| 321 | 331 | /* 2) Find Reference divider ranges |
|---|
| .. | .. |
|---|
| 387 | 397 | struct pixel_clk_params *pix_clk_params, |
|---|
| 388 | 398 | struct pll_settings *pll_settings) |
|---|
| 389 | 399 | { |
|---|
| 390 | | - uint32_t actual_pix_clk_khz = 0; |
|---|
| 391 | | - uint32_t requested_clk_khz = 0; |
|---|
| 400 | + uint32_t actual_pix_clk_100hz = 0; |
|---|
| 401 | + uint32_t requested_clk_100hz = 0; |
|---|
| 392 | 402 | struct bp_adjust_pixel_clock_parameters bp_adjust_pixel_clock_params = { |
|---|
| 393 | 403 | 0 }; |
|---|
| 394 | 404 | enum bp_result bp_result; |
|---|
| 395 | 405 | switch (pix_clk_params->signal_type) { |
|---|
| 396 | 406 | case SIGNAL_TYPE_HDMI_TYPE_A: { |
|---|
| 397 | | - requested_clk_khz = pix_clk_params->requested_pix_clk; |
|---|
| 407 | + requested_clk_100hz = pix_clk_params->requested_pix_clk_100hz; |
|---|
| 398 | 408 | if (pix_clk_params->pixel_encoding != PIXEL_ENCODING_YCBCR422) { |
|---|
| 399 | 409 | switch (pix_clk_params->color_depth) { |
|---|
| 400 | 410 | case COLOR_DEPTH_101010: |
|---|
| 401 | | - requested_clk_khz = (requested_clk_khz * 5) >> 2; |
|---|
| 411 | + requested_clk_100hz = (requested_clk_100hz * 5) >> 2; |
|---|
| 402 | 412 | break; /* x1.25*/ |
|---|
| 403 | 413 | case COLOR_DEPTH_121212: |
|---|
| 404 | | - requested_clk_khz = (requested_clk_khz * 6) >> 2; |
|---|
| 414 | + requested_clk_100hz = (requested_clk_100hz * 6) >> 2; |
|---|
| 405 | 415 | break; /* x1.5*/ |
|---|
| 406 | 416 | case COLOR_DEPTH_161616: |
|---|
| 407 | | - requested_clk_khz = requested_clk_khz * 2; |
|---|
| 417 | + requested_clk_100hz = requested_clk_100hz * 2; |
|---|
| 408 | 418 | break; /* x2.0*/ |
|---|
| 409 | 419 | default: |
|---|
| 410 | 420 | break; |
|---|
| 411 | 421 | } |
|---|
| 412 | 422 | } |
|---|
| 413 | | - actual_pix_clk_khz = requested_clk_khz; |
|---|
| 423 | + actual_pix_clk_100hz = requested_clk_100hz; |
|---|
| 414 | 424 | } |
|---|
| 415 | 425 | break; |
|---|
| 416 | 426 | |
|---|
| 417 | 427 | case SIGNAL_TYPE_DISPLAY_PORT: |
|---|
| 418 | 428 | case SIGNAL_TYPE_DISPLAY_PORT_MST: |
|---|
| 419 | 429 | case SIGNAL_TYPE_EDP: |
|---|
| 420 | | - requested_clk_khz = pix_clk_params->requested_sym_clk; |
|---|
| 421 | | - actual_pix_clk_khz = pix_clk_params->requested_pix_clk; |
|---|
| 430 | + requested_clk_100hz = pix_clk_params->requested_sym_clk * 10; |
|---|
| 431 | + actual_pix_clk_100hz = pix_clk_params->requested_pix_clk_100hz; |
|---|
| 422 | 432 | break; |
|---|
| 423 | 433 | |
|---|
| 424 | 434 | default: |
|---|
| 425 | | - requested_clk_khz = pix_clk_params->requested_pix_clk; |
|---|
| 426 | | - actual_pix_clk_khz = pix_clk_params->requested_pix_clk; |
|---|
| 435 | + requested_clk_100hz = pix_clk_params->requested_pix_clk_100hz; |
|---|
| 436 | + actual_pix_clk_100hz = pix_clk_params->requested_pix_clk_100hz; |
|---|
| 427 | 437 | break; |
|---|
| 428 | 438 | } |
|---|
| 429 | 439 | |
|---|
| 430 | | - bp_adjust_pixel_clock_params.pixel_clock = requested_clk_khz; |
|---|
| 440 | + bp_adjust_pixel_clock_params.pixel_clock = requested_clk_100hz / 10; |
|---|
| 431 | 441 | bp_adjust_pixel_clock_params. |
|---|
| 432 | 442 | encoder_object_id = pix_clk_params->encoder_object_id; |
|---|
| 433 | 443 | bp_adjust_pixel_clock_params.signal_type = pix_clk_params->signal_type; |
|---|
| .. | .. |
|---|
| 436 | 446 | bp_result = clk_src->bios->funcs->adjust_pixel_clock( |
|---|
| 437 | 447 | clk_src->bios, &bp_adjust_pixel_clock_params); |
|---|
| 438 | 448 | if (bp_result == BP_RESULT_OK) { |
|---|
| 439 | | - pll_settings->actual_pix_clk = actual_pix_clk_khz; |
|---|
| 440 | | - pll_settings->adjusted_pix_clk = |
|---|
| 441 | | - bp_adjust_pixel_clock_params.adjusted_pixel_clock; |
|---|
| 449 | + pll_settings->actual_pix_clk_100hz = actual_pix_clk_100hz; |
|---|
| 450 | + pll_settings->adjusted_pix_clk_100hz = |
|---|
| 451 | + bp_adjust_pixel_clock_params.adjusted_pixel_clock * 10; |
|---|
| 442 | 452 | pll_settings->reference_divider = |
|---|
| 443 | 453 | bp_adjust_pixel_clock_params.reference_divider; |
|---|
| 444 | 454 | pll_settings->pix_clk_post_divider = |
|---|
| .. | .. |
|---|
| 485 | 495 | const struct spread_spectrum_data *ss_data = get_ss_data_entry( |
|---|
| 486 | 496 | clk_src, |
|---|
| 487 | 497 | pix_clk_params->signal_type, |
|---|
| 488 | | - pll_settings->adjusted_pix_clk); |
|---|
| 498 | + pll_settings->adjusted_pix_clk_100hz / 10); |
|---|
| 489 | 499 | |
|---|
| 490 | 500 | if (NULL != ss_data) |
|---|
| 491 | 501 | pll_settings->ss_percentage = ss_data->percentage; |
|---|
| .. | .. |
|---|
| 497 | 507 | * to continue. */ |
|---|
| 498 | 508 | DC_LOG_ERROR( |
|---|
| 499 | 509 | "%s: Failed to adjust pixel clock!!", __func__); |
|---|
| 500 | | - pll_settings->actual_pix_clk = |
|---|
| 501 | | - pix_clk_params->requested_pix_clk; |
|---|
| 502 | | - pll_settings->adjusted_pix_clk = |
|---|
| 503 | | - pix_clk_params->requested_pix_clk; |
|---|
| 510 | + pll_settings->actual_pix_clk_100hz = |
|---|
| 511 | + pix_clk_params->requested_pix_clk_100hz; |
|---|
| 512 | + pll_settings->adjusted_pix_clk_100hz = |
|---|
| 513 | + pix_clk_params->requested_pix_clk_100hz; |
|---|
| 504 | 514 | |
|---|
| 505 | 515 | if (dc_is_dp_signal(pix_clk_params->signal_type)) |
|---|
| 506 | | - pll_settings->adjusted_pix_clk = 100000; |
|---|
| 516 | + pll_settings->adjusted_pix_clk_100hz = 1000000; |
|---|
| 507 | 517 | } |
|---|
| 508 | 518 | |
|---|
| 509 | 519 | /* Calculate Dividers */ |
|---|
| .. | .. |
|---|
| 528 | 538 | struct pll_settings *pll_settings, |
|---|
| 529 | 539 | struct pixel_clk_params *pix_clk_params) |
|---|
| 530 | 540 | { |
|---|
| 531 | | - uint32_t actualPixelClockInKHz; |
|---|
| 541 | + uint32_t actual_pixel_clock_100hz; |
|---|
| 532 | 542 | |
|---|
| 533 | | - actualPixelClockInKHz = pix_clk_params->requested_pix_clk; |
|---|
| 543 | + actual_pixel_clock_100hz = pix_clk_params->requested_pix_clk_100hz; |
|---|
| 534 | 544 | /* Calculate Dividers */ |
|---|
| 535 | 545 | if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) { |
|---|
| 536 | 546 | switch (pix_clk_params->color_depth) { |
|---|
| 537 | 547 | case COLOR_DEPTH_101010: |
|---|
| 538 | | - actualPixelClockInKHz = (actualPixelClockInKHz * 5) >> 2; |
|---|
| 548 | + actual_pixel_clock_100hz = (actual_pixel_clock_100hz * 5) >> 2; |
|---|
| 549 | + actual_pixel_clock_100hz -= actual_pixel_clock_100hz % 10; |
|---|
| 539 | 550 | break; |
|---|
| 540 | 551 | case COLOR_DEPTH_121212: |
|---|
| 541 | | - actualPixelClockInKHz = (actualPixelClockInKHz * 6) >> 2; |
|---|
| 552 | + actual_pixel_clock_100hz = (actual_pixel_clock_100hz * 6) >> 2; |
|---|
| 553 | + actual_pixel_clock_100hz -= actual_pixel_clock_100hz % 10; |
|---|
| 542 | 554 | break; |
|---|
| 543 | 555 | case COLOR_DEPTH_161616: |
|---|
| 544 | | - actualPixelClockInKHz = actualPixelClockInKHz * 2; |
|---|
| 556 | + actual_pixel_clock_100hz = actual_pixel_clock_100hz * 2; |
|---|
| 545 | 557 | break; |
|---|
| 546 | 558 | default: |
|---|
| 547 | 559 | break; |
|---|
| 548 | 560 | } |
|---|
| 549 | 561 | } |
|---|
| 550 | | - pll_settings->actual_pix_clk = actualPixelClockInKHz; |
|---|
| 551 | | - pll_settings->adjusted_pix_clk = actualPixelClockInKHz; |
|---|
| 552 | | - pll_settings->calculated_pix_clk = pix_clk_params->requested_pix_clk; |
|---|
| 562 | + pll_settings->actual_pix_clk_100hz = actual_pixel_clock_100hz; |
|---|
| 563 | + pll_settings->adjusted_pix_clk_100hz = actual_pixel_clock_100hz; |
|---|
| 564 | + pll_settings->calculated_pix_clk_100hz = pix_clk_params->requested_pix_clk_100hz; |
|---|
| 553 | 565 | } |
|---|
| 554 | 566 | |
|---|
| 555 | 567 | static uint32_t dce110_get_pix_clk_dividers( |
|---|
| .. | .. |
|---|
| 562 | 574 | DC_LOGGER_INIT(); |
|---|
| 563 | 575 | |
|---|
| 564 | 576 | if (pix_clk_params == NULL || pll_settings == NULL |
|---|
| 565 | | - || pix_clk_params->requested_pix_clk == 0) { |
|---|
| 577 | + || pix_clk_params->requested_pix_clk_100hz == 0) { |
|---|
| 566 | 578 | DC_LOG_ERROR( |
|---|
| 567 | 579 | "%s: Invalid parameters!!\n", __func__); |
|---|
| 568 | 580 | return pll_calc_error; |
|---|
| .. | .. |
|---|
| 572 | 584 | |
|---|
| 573 | 585 | if (cs->id == CLOCK_SOURCE_ID_DP_DTO || |
|---|
| 574 | 586 | cs->id == CLOCK_SOURCE_ID_EXTERNAL) { |
|---|
| 575 | | - pll_settings->adjusted_pix_clk = clk_src->ext_clk_khz; |
|---|
| 576 | | - pll_settings->calculated_pix_clk = clk_src->ext_clk_khz; |
|---|
| 577 | | - pll_settings->actual_pix_clk = |
|---|
| 578 | | - pix_clk_params->requested_pix_clk; |
|---|
| 587 | + pll_settings->adjusted_pix_clk_100hz = clk_src->ext_clk_khz * 10; |
|---|
| 588 | + pll_settings->calculated_pix_clk_100hz = clk_src->ext_clk_khz * 10; |
|---|
| 589 | + pll_settings->actual_pix_clk_100hz = |
|---|
| 590 | + pix_clk_params->requested_pix_clk_100hz; |
|---|
| 579 | 591 | return 0; |
|---|
| 580 | 592 | } |
|---|
| 581 | 593 | |
|---|
| 582 | | - switch (cs->ctx->dce_version) { |
|---|
| 583 | | - case DCE_VERSION_8_0: |
|---|
| 584 | | - case DCE_VERSION_8_1: |
|---|
| 585 | | - case DCE_VERSION_8_3: |
|---|
| 586 | | - case DCE_VERSION_10_0: |
|---|
| 587 | | - case DCE_VERSION_11_0: |
|---|
| 588 | | - pll_calc_error = |
|---|
| 589 | | - dce110_get_pix_clk_dividers_helper(clk_src, |
|---|
| 594 | + pll_calc_error = dce110_get_pix_clk_dividers_helper(clk_src, |
|---|
| 590 | 595 | pll_settings, pix_clk_params); |
|---|
| 591 | | - break; |
|---|
| 592 | | - case DCE_VERSION_11_2: |
|---|
| 593 | | - case DCE_VERSION_11_22: |
|---|
| 594 | | - case DCE_VERSION_12_0: |
|---|
| 595 | | -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
|---|
| 596 | | - case DCN_VERSION_1_0: |
|---|
| 597 | | -#endif |
|---|
| 598 | | - |
|---|
| 599 | | - dce112_get_pix_clk_dividers_helper(clk_src, |
|---|
| 600 | | - pll_settings, pix_clk_params); |
|---|
| 601 | | - break; |
|---|
| 602 | | - default: |
|---|
| 603 | | - break; |
|---|
| 604 | | - } |
|---|
| 605 | 596 | |
|---|
| 606 | 597 | return pll_calc_error; |
|---|
| 607 | 598 | } |
|---|
| 608 | 599 | |
|---|
| 609 | | -static uint32_t dce110_get_pll_pixel_rate_in_hz( |
|---|
| 610 | | - struct clock_source *cs, |
|---|
| 611 | | - struct pixel_clk_params *pix_clk_params, |
|---|
| 612 | | - struct pll_settings *pll_settings) |
|---|
| 600 | +static uint32_t dce112_get_pix_clk_dividers( |
|---|
| 601 | + struct clock_source *cs, |
|---|
| 602 | + struct pixel_clk_params *pix_clk_params, |
|---|
| 603 | + struct pll_settings *pll_settings) |
|---|
| 613 | 604 | { |
|---|
| 614 | | - uint32_t inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; |
|---|
| 615 | | - struct dc *dc_core = cs->ctx->dc; |
|---|
| 616 | | - struct dc_state *context = dc_core->current_state; |
|---|
| 617 | | - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[inst]; |
|---|
| 618 | | - |
|---|
| 619 | | - /* This function need separate to different DCE version, before separate, just use pixel clock */ |
|---|
| 620 | | - return pipe_ctx->stream->phy_pix_clk; |
|---|
| 621 | | - |
|---|
| 622 | | -} |
|---|
| 623 | | - |
|---|
| 624 | | -static uint32_t dce110_get_dp_pixel_rate_from_combo_phy_pll( |
|---|
| 625 | | - struct clock_source *cs, |
|---|
| 626 | | - struct pixel_clk_params *pix_clk_params, |
|---|
| 627 | | - struct pll_settings *pll_settings) |
|---|
| 628 | | -{ |
|---|
| 629 | | - uint32_t inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; |
|---|
| 630 | | - struct dc *dc_core = cs->ctx->dc; |
|---|
| 631 | | - struct dc_state *context = dc_core->current_state; |
|---|
| 632 | | - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[inst]; |
|---|
| 633 | | - |
|---|
| 634 | | - /* This function need separate to different DCE version, before separate, just use pixel clock */ |
|---|
| 635 | | - return pipe_ctx->stream->phy_pix_clk; |
|---|
| 636 | | -} |
|---|
| 637 | | - |
|---|
| 638 | | -static uint32_t dce110_get_d_to_pixel_rate_in_hz( |
|---|
| 639 | | - struct clock_source *cs, |
|---|
| 640 | | - struct pixel_clk_params *pix_clk_params, |
|---|
| 641 | | - struct pll_settings *pll_settings) |
|---|
| 642 | | -{ |
|---|
| 643 | | - uint32_t inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; |
|---|
| 644 | 605 | struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs); |
|---|
| 645 | | - int dto_enabled = 0; |
|---|
| 646 | | - struct fixed31_32 pix_rate; |
|---|
| 606 | + DC_LOGGER_INIT(); |
|---|
| 647 | 607 | |
|---|
| 648 | | - REG_GET(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, &dto_enabled); |
|---|
| 649 | | - |
|---|
| 650 | | - if (dto_enabled) { |
|---|
| 651 | | - uint32_t phase = 0; |
|---|
| 652 | | - uint32_t modulo = 0; |
|---|
| 653 | | - REG_GET(PHASE[inst], DP_DTO0_PHASE, &phase); |
|---|
| 654 | | - REG_GET(MODULO[inst], DP_DTO0_MODULO, &modulo); |
|---|
| 655 | | - |
|---|
| 656 | | - if (modulo == 0) { |
|---|
| 657 | | - return 0; |
|---|
| 658 | | - } |
|---|
| 659 | | - |
|---|
| 660 | | - pix_rate = dc_fixpt_from_int(clk_src->ref_freq_khz); |
|---|
| 661 | | - pix_rate = dc_fixpt_mul_int(pix_rate, 1000); |
|---|
| 662 | | - pix_rate = dc_fixpt_mul_int(pix_rate, phase); |
|---|
| 663 | | - pix_rate = dc_fixpt_div_int(pix_rate, modulo); |
|---|
| 664 | | - |
|---|
| 665 | | - return dc_fixpt_round(pix_rate); |
|---|
| 666 | | - } else { |
|---|
| 667 | | - return dce110_get_dp_pixel_rate_from_combo_phy_pll(cs, pix_clk_params, pll_settings); |
|---|
| 668 | | - } |
|---|
| 669 | | -} |
|---|
| 670 | | - |
|---|
| 671 | | -static uint32_t dce110_get_pix_rate_in_hz( |
|---|
| 672 | | - struct clock_source *cs, |
|---|
| 673 | | - struct pixel_clk_params *pix_clk_params, |
|---|
| 674 | | - struct pll_settings *pll_settings) |
|---|
| 675 | | -{ |
|---|
| 676 | | - uint32_t pix_rate = 0; |
|---|
| 677 | | - switch (pix_clk_params->signal_type) { |
|---|
| 678 | | - case SIGNAL_TYPE_DISPLAY_PORT: |
|---|
| 679 | | - case SIGNAL_TYPE_DISPLAY_PORT_MST: |
|---|
| 680 | | - case SIGNAL_TYPE_EDP: |
|---|
| 681 | | - case SIGNAL_TYPE_VIRTUAL: |
|---|
| 682 | | - pix_rate = dce110_get_d_to_pixel_rate_in_hz(cs, pix_clk_params, pll_settings); |
|---|
| 683 | | - break; |
|---|
| 684 | | - case SIGNAL_TYPE_HDMI_TYPE_A: |
|---|
| 685 | | - default: |
|---|
| 686 | | - pix_rate = dce110_get_pll_pixel_rate_in_hz(cs, pix_clk_params, pll_settings); |
|---|
| 687 | | - break; |
|---|
| 608 | + if (pix_clk_params == NULL || pll_settings == NULL |
|---|
| 609 | + || pix_clk_params->requested_pix_clk_100hz == 0) { |
|---|
| 610 | + DC_LOG_ERROR( |
|---|
| 611 | + "%s: Invalid parameters!!\n", __func__); |
|---|
| 612 | + return -1; |
|---|
| 688 | 613 | } |
|---|
| 689 | 614 | |
|---|
| 690 | | - return pix_rate; |
|---|
| 615 | + memset(pll_settings, 0, sizeof(*pll_settings)); |
|---|
| 616 | + |
|---|
| 617 | + if (cs->id == CLOCK_SOURCE_ID_DP_DTO || |
|---|
| 618 | + cs->id == CLOCK_SOURCE_ID_EXTERNAL) { |
|---|
| 619 | + pll_settings->adjusted_pix_clk_100hz = clk_src->ext_clk_khz * 10; |
|---|
| 620 | + pll_settings->calculated_pix_clk_100hz = clk_src->ext_clk_khz * 10; |
|---|
| 621 | + pll_settings->actual_pix_clk_100hz = |
|---|
| 622 | + pix_clk_params->requested_pix_clk_100hz; |
|---|
| 623 | + return -1; |
|---|
| 624 | + } |
|---|
| 625 | + |
|---|
| 626 | + dce112_get_pix_clk_dividers_helper(clk_src, |
|---|
| 627 | + pll_settings, pix_clk_params); |
|---|
| 628 | + |
|---|
| 629 | + return 0; |
|---|
| 691 | 630 | } |
|---|
| 692 | 631 | |
|---|
| 693 | 632 | static bool disable_spread_spectrum(struct dce110_clk_src *clk_src) |
|---|
| .. | .. |
|---|
| 782 | 721 | ss_data = get_ss_data_entry( |
|---|
| 783 | 722 | clk_src, |
|---|
| 784 | 723 | signal, |
|---|
| 785 | | - pll_settings->calculated_pix_clk); |
|---|
| 724 | + pll_settings->calculated_pix_clk_100hz / 10); |
|---|
| 786 | 725 | |
|---|
| 787 | 726 | /* Pixel clock PLL has been programmed to generate desired pixel clock, |
|---|
| 788 | 727 | * now enable SS on pixel clock */ |
|---|
| .. | .. |
|---|
| 909 | 848 | struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); |
|---|
| 910 | 849 | struct bp_pixel_clock_parameters bp_pc_params = {0}; |
|---|
| 911 | 850 | |
|---|
| 912 | | -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
|---|
| 851 | + /* First disable SS |
|---|
| 852 | + * ATOMBIOS will enable by default SS on PLL for DP, |
|---|
| 853 | + * do not disable it here |
|---|
| 854 | + */ |
|---|
| 855 | + if (clock_source->id != CLOCK_SOURCE_ID_EXTERNAL && |
|---|
| 856 | + !dc_is_dp_signal(pix_clk_params->signal_type) && |
|---|
| 857 | + clock_source->ctx->dce_version <= DCE_VERSION_11_0) |
|---|
| 858 | + disable_spread_spectrum(clk_src); |
|---|
| 859 | + |
|---|
| 860 | + /*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/ |
|---|
| 861 | + bp_pc_params.controller_id = pix_clk_params->controller_id; |
|---|
| 862 | + bp_pc_params.pll_id = clock_source->id; |
|---|
| 863 | + bp_pc_params.target_pixel_clock_100hz = pll_settings->actual_pix_clk_100hz; |
|---|
| 864 | + bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id; |
|---|
| 865 | + bp_pc_params.signal_type = pix_clk_params->signal_type; |
|---|
| 866 | + |
|---|
| 867 | + bp_pc_params.reference_divider = pll_settings->reference_divider; |
|---|
| 868 | + bp_pc_params.feedback_divider = pll_settings->feedback_divider; |
|---|
| 869 | + bp_pc_params.fractional_feedback_divider = |
|---|
| 870 | + pll_settings->fract_feedback_divider; |
|---|
| 871 | + bp_pc_params.pixel_clock_post_divider = |
|---|
| 872 | + pll_settings->pix_clk_post_divider; |
|---|
| 873 | + bp_pc_params.flags.SET_EXTERNAL_REF_DIV_SRC = |
|---|
| 874 | + pll_settings->use_external_clk; |
|---|
| 875 | + |
|---|
| 876 | + switch (pix_clk_params->color_depth) { |
|---|
| 877 | + case COLOR_DEPTH_101010: |
|---|
| 878 | + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_30; |
|---|
| 879 | + break; |
|---|
| 880 | + case COLOR_DEPTH_121212: |
|---|
| 881 | + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_36; |
|---|
| 882 | + break; |
|---|
| 883 | + case COLOR_DEPTH_161616: |
|---|
| 884 | + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_48; |
|---|
| 885 | + break; |
|---|
| 886 | + default: |
|---|
| 887 | + break; |
|---|
| 888 | + } |
|---|
| 889 | + |
|---|
| 890 | + if (clk_src->bios->funcs->set_pixel_clock( |
|---|
| 891 | + clk_src->bios, &bp_pc_params) != BP_RESULT_OK) |
|---|
| 892 | + return false; |
|---|
| 893 | + /* Enable SS |
|---|
| 894 | + * ATOMBIOS will enable by default SS for DP on PLL ( DP ID clock), |
|---|
| 895 | + * based on HW display PLL team, SS control settings should be programmed |
|---|
| 896 | + * during PLL Reset, but they do not have effect |
|---|
| 897 | + * until SS_EN is asserted.*/ |
|---|
| 898 | + if (clock_source->id != CLOCK_SOURCE_ID_EXTERNAL |
|---|
| 899 | + && !dc_is_dp_signal(pix_clk_params->signal_type)) { |
|---|
| 900 | + |
|---|
| 901 | + if (pix_clk_params->flags.ENABLE_SS) |
|---|
| 902 | + if (!enable_spread_spectrum(clk_src, |
|---|
| 903 | + pix_clk_params->signal_type, |
|---|
| 904 | + pll_settings)) |
|---|
| 905 | + return false; |
|---|
| 906 | + |
|---|
| 907 | + /* Resync deep color DTO */ |
|---|
| 908 | + dce110_program_pixel_clk_resync(clk_src, |
|---|
| 909 | + pix_clk_params->signal_type, |
|---|
| 910 | + pix_clk_params->color_depth); |
|---|
| 911 | + } |
|---|
| 912 | + |
|---|
| 913 | + return true; |
|---|
| 914 | +} |
|---|
| 915 | + |
|---|
| 916 | +static bool dce112_program_pix_clk( |
|---|
| 917 | + struct clock_source *clock_source, |
|---|
| 918 | + struct pixel_clk_params *pix_clk_params, |
|---|
| 919 | + struct pll_settings *pll_settings) |
|---|
| 920 | +{ |
|---|
| 921 | + struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); |
|---|
| 922 | + struct bp_pixel_clock_parameters bp_pc_params = {0}; |
|---|
| 923 | + |
|---|
| 924 | +#if defined(CONFIG_DRM_AMD_DC_DCN) |
|---|
| 913 | 925 | if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) { |
|---|
| 914 | 926 | unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; |
|---|
| 915 | | - unsigned dp_dto_ref_kHz = 700000; |
|---|
| 916 | | - unsigned clock_kHz = pll_settings->actual_pix_clk; |
|---|
| 927 | + unsigned dp_dto_ref_100hz = 7000000; |
|---|
| 928 | + unsigned clock_100hz = pll_settings->actual_pix_clk_100hz; |
|---|
| 917 | 929 | |
|---|
| 918 | 930 | /* Set DTO values: phase = target clock, modulo = reference clock */ |
|---|
| 919 | | - REG_WRITE(PHASE[inst], clock_kHz); |
|---|
| 920 | | - REG_WRITE(MODULO[inst], dp_dto_ref_kHz); |
|---|
| 931 | + REG_WRITE(PHASE[inst], clock_100hz); |
|---|
| 932 | + REG_WRITE(MODULO[inst], dp_dto_ref_100hz); |
|---|
| 921 | 933 | |
|---|
| 922 | 934 | /* Enable DTO */ |
|---|
| 923 | 935 | REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); |
|---|
| .. | .. |
|---|
| 936 | 948 | /*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/ |
|---|
| 937 | 949 | bp_pc_params.controller_id = pix_clk_params->controller_id; |
|---|
| 938 | 950 | bp_pc_params.pll_id = clock_source->id; |
|---|
| 939 | | - bp_pc_params.target_pixel_clock = pll_settings->actual_pix_clk; |
|---|
| 951 | + bp_pc_params.target_pixel_clock_100hz = pll_settings->actual_pix_clk_100hz; |
|---|
| 940 | 952 | bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id; |
|---|
| 941 | 953 | bp_pc_params.signal_type = pix_clk_params->signal_type; |
|---|
| 942 | 954 | |
|---|
| 943 | | - switch (clock_source->ctx->dce_version) { |
|---|
| 944 | | - case DCE_VERSION_8_0: |
|---|
| 945 | | - case DCE_VERSION_8_1: |
|---|
| 946 | | - case DCE_VERSION_8_3: |
|---|
| 947 | | - case DCE_VERSION_10_0: |
|---|
| 948 | | - case DCE_VERSION_11_0: |
|---|
| 949 | | - bp_pc_params.reference_divider = pll_settings->reference_divider; |
|---|
| 950 | | - bp_pc_params.feedback_divider = pll_settings->feedback_divider; |
|---|
| 951 | | - bp_pc_params.fractional_feedback_divider = |
|---|
| 952 | | - pll_settings->fract_feedback_divider; |
|---|
| 953 | | - bp_pc_params.pixel_clock_post_divider = |
|---|
| 954 | | - pll_settings->pix_clk_post_divider; |
|---|
| 955 | | - bp_pc_params.flags.SET_EXTERNAL_REF_DIV_SRC = |
|---|
| 955 | + if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) { |
|---|
| 956 | + bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC = |
|---|
| 956 | 957 | pll_settings->use_external_clk; |
|---|
| 957 | | - |
|---|
| 958 | | - if (clk_src->bios->funcs->set_pixel_clock( |
|---|
| 959 | | - clk_src->bios, &bp_pc_params) != BP_RESULT_OK) |
|---|
| 960 | | - return false; |
|---|
| 961 | | - /* Enable SS |
|---|
| 962 | | - * ATOMBIOS will enable by default SS for DP on PLL ( DP ID clock), |
|---|
| 963 | | - * based on HW display PLL team, SS control settings should be programmed |
|---|
| 964 | | - * during PLL Reset, but they do not have effect |
|---|
| 965 | | - * until SS_EN is asserted.*/ |
|---|
| 966 | | - if (clock_source->id != CLOCK_SOURCE_ID_EXTERNAL |
|---|
| 967 | | - && !dc_is_dp_signal(pix_clk_params->signal_type)) { |
|---|
| 968 | | - |
|---|
| 969 | | - if (pix_clk_params->flags.ENABLE_SS) |
|---|
| 970 | | - if (!enable_spread_spectrum(clk_src, |
|---|
| 971 | | - pix_clk_params->signal_type, |
|---|
| 972 | | - pll_settings)) |
|---|
| 973 | | - return false; |
|---|
| 974 | | - |
|---|
| 975 | | - /* Resync deep color DTO */ |
|---|
| 976 | | - dce110_program_pixel_clk_resync(clk_src, |
|---|
| 977 | | - pix_clk_params->signal_type, |
|---|
| 978 | | - pix_clk_params->color_depth); |
|---|
| 958 | + bp_pc_params.flags.SET_XTALIN_REF_SRC = |
|---|
| 959 | + !pll_settings->use_external_clk; |
|---|
| 960 | + if (pix_clk_params->flags.SUPPORT_YCBCR420) { |
|---|
| 961 | + bp_pc_params.flags.SUPPORT_YUV_420 = 1; |
|---|
| 979 | 962 | } |
|---|
| 980 | | - |
|---|
| 981 | | - break; |
|---|
| 982 | | - case DCE_VERSION_11_2: |
|---|
| 983 | | - case DCE_VERSION_11_22: |
|---|
| 984 | | - case DCE_VERSION_12_0: |
|---|
| 985 | | -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
|---|
| 986 | | - case DCN_VERSION_1_0: |
|---|
| 987 | | -#endif |
|---|
| 988 | | - |
|---|
| 989 | | - if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) { |
|---|
| 990 | | - bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC = |
|---|
| 991 | | - pll_settings->use_external_clk; |
|---|
| 992 | | - bp_pc_params.flags.SET_XTALIN_REF_SRC = |
|---|
| 993 | | - !pll_settings->use_external_clk; |
|---|
| 994 | | - if (pix_clk_params->flags.SUPPORT_YCBCR420) { |
|---|
| 995 | | - bp_pc_params.flags.SUPPORT_YUV_420 = 1; |
|---|
| 996 | | - } |
|---|
| 997 | | - } |
|---|
| 998 | | - if (clk_src->bios->funcs->set_pixel_clock( |
|---|
| 999 | | - clk_src->bios, &bp_pc_params) != BP_RESULT_OK) |
|---|
| 1000 | | - return false; |
|---|
| 1001 | | - /* Resync deep color DTO */ |
|---|
| 1002 | | - if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) |
|---|
| 1003 | | - dce112_program_pixel_clk_resync(clk_src, |
|---|
| 1004 | | - pix_clk_params->signal_type, |
|---|
| 1005 | | - pix_clk_params->color_depth, |
|---|
| 1006 | | - pix_clk_params->flags.SUPPORT_YCBCR420); |
|---|
| 1007 | | - break; |
|---|
| 1008 | | - default: |
|---|
| 1009 | | - break; |
|---|
| 1010 | 963 | } |
|---|
| 964 | + if (clk_src->bios->funcs->set_pixel_clock( |
|---|
| 965 | + clk_src->bios, &bp_pc_params) != BP_RESULT_OK) |
|---|
| 966 | + return false; |
|---|
| 967 | + /* Resync deep color DTO */ |
|---|
| 968 | + if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) |
|---|
| 969 | + dce112_program_pixel_clk_resync(clk_src, |
|---|
| 970 | + pix_clk_params->signal_type, |
|---|
| 971 | + pix_clk_params->color_depth, |
|---|
| 972 | + pix_clk_params->flags.SUPPORT_YCBCR420); |
|---|
| 1011 | 973 | |
|---|
| 1012 | 974 | return true; |
|---|
| 1013 | 975 | } |
|---|
| 976 | + |
|---|
| 1014 | 977 | |
|---|
| 1015 | 978 | static bool dce110_clock_source_power_down( |
|---|
| 1016 | 979 | struct clock_source *clk_src) |
|---|
| .. | .. |
|---|
| 1035 | 998 | return bp_result == BP_RESULT_OK; |
|---|
| 1036 | 999 | } |
|---|
| 1037 | 1000 | |
|---|
| 1001 | +static bool get_pixel_clk_frequency_100hz( |
|---|
| 1002 | + const struct clock_source *clock_source, |
|---|
| 1003 | + unsigned int inst, |
|---|
| 1004 | + unsigned int *pixel_clk_khz) |
|---|
| 1005 | +{ |
|---|
| 1006 | + struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); |
|---|
| 1007 | + unsigned int clock_hz = 0; |
|---|
| 1008 | + |
|---|
| 1009 | + if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) { |
|---|
| 1010 | + clock_hz = REG_READ(PHASE[inst]); |
|---|
| 1011 | + |
|---|
| 1012 | + /* NOTE: There is agreement with VBIOS here that MODULO is |
|---|
| 1013 | + * programmed equal to DPREFCLK, in which case PHASE will be |
|---|
| 1014 | + * equivalent to pixel clock. |
|---|
| 1015 | + */ |
|---|
| 1016 | + *pixel_clk_khz = clock_hz / 100; |
|---|
| 1017 | + return true; |
|---|
| 1018 | + } |
|---|
| 1019 | + |
|---|
| 1020 | + return false; |
|---|
| 1021 | +} |
|---|
| 1022 | + |
|---|
| 1023 | +#if defined(CONFIG_DRM_AMD_DC_DCN3_0) |
|---|
| 1024 | +/* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ |
|---|
| 1025 | +const struct pixel_rate_range_table_entry video_optimized_pixel_rates[] = { |
|---|
| 1026 | + // /1.001 rates |
|---|
| 1027 | + {25170, 25180, 25200, 1000, 1001}, //25.2MHz -> 25.17 |
|---|
| 1028 | + {59340, 59350, 59400, 1000, 1001}, //59.4Mhz -> 59.340 |
|---|
| 1029 | + {74170, 74180, 74250, 1000, 1001}, //74.25Mhz -> 74.1758 |
|---|
| 1030 | + {125870, 125880, 126000, 1000, 1001}, //126Mhz -> 125.87 |
|---|
| 1031 | + {148350, 148360, 148500, 1000, 1001}, //148.5Mhz -> 148.3516 |
|---|
| 1032 | + {167830, 167840, 168000, 1000, 1001}, //168Mhz -> 167.83 |
|---|
| 1033 | + {222520, 222530, 222750, 1000, 1001}, //222.75Mhz -> 222.527 |
|---|
| 1034 | + {257140, 257150, 257400, 1000, 1001}, //257.4Mhz -> 257.1429 |
|---|
| 1035 | + {296700, 296710, 297000, 1000, 1001}, //297Mhz -> 296.7033 |
|---|
| 1036 | + {342850, 342860, 343200, 1000, 1001}, //343.2Mhz -> 342.857 |
|---|
| 1037 | + {395600, 395610, 396000, 1000, 1001}, //396Mhz -> 395.6 |
|---|
| 1038 | + {409090, 409100, 409500, 1000, 1001}, //409.5Mhz -> 409.091 |
|---|
| 1039 | + {445050, 445060, 445500, 1000, 1001}, //445.5Mhz -> 445.055 |
|---|
| 1040 | + {467530, 467540, 468000, 1000, 1001}, //468Mhz -> 467.5325 |
|---|
| 1041 | + {519230, 519240, 519750, 1000, 1001}, //519.75Mhz -> 519.231 |
|---|
| 1042 | + {525970, 525980, 526500, 1000, 1001}, //526.5Mhz -> 525.974 |
|---|
| 1043 | + {545450, 545460, 546000, 1000, 1001}, //546Mhz -> 545.455 |
|---|
| 1044 | + {593400, 593410, 594000, 1000, 1001}, //594Mhz -> 593.4066 |
|---|
| 1045 | + {623370, 623380, 624000, 1000, 1001}, //624Mhz -> 623.377 |
|---|
| 1046 | + {692300, 692310, 693000, 1000, 1001}, //693Mhz -> 692.308 |
|---|
| 1047 | + {701290, 701300, 702000, 1000, 1001}, //702Mhz -> 701.2987 |
|---|
| 1048 | + {791200, 791210, 792000, 1000, 1001}, //792Mhz -> 791.209 |
|---|
| 1049 | + {890100, 890110, 891000, 1000, 1001}, //891Mhz -> 890.1099 |
|---|
| 1050 | + {1186810, 1186820, 1188000, 1000, 1001},//1188Mhz -> 1186.8131 |
|---|
| 1051 | + |
|---|
| 1052 | + // *1.001 rates |
|---|
| 1053 | + {27020, 27030, 27000, 1001, 1000}, //27Mhz |
|---|
| 1054 | + {54050, 54060, 54000, 1001, 1000}, //54Mhz |
|---|
| 1055 | + {108100, 108110, 108000, 1001, 1000},//108Mhz |
|---|
| 1056 | +}; |
|---|
| 1057 | + |
|---|
| 1058 | +const struct pixel_rate_range_table_entry *look_up_in_video_optimized_rate_tlb( |
|---|
| 1059 | + unsigned int pixel_rate_khz) |
|---|
| 1060 | +{ |
|---|
| 1061 | + int i; |
|---|
| 1062 | + |
|---|
| 1063 | + for (i = 0; i < NUM_ELEMENTS(video_optimized_pixel_rates); i++) { |
|---|
| 1064 | + const struct pixel_rate_range_table_entry *e = &video_optimized_pixel_rates[i]; |
|---|
| 1065 | + |
|---|
| 1066 | + if (e->range_min_khz <= pixel_rate_khz && pixel_rate_khz <= e->range_max_khz) { |
|---|
| 1067 | + return e; |
|---|
| 1068 | + } |
|---|
| 1069 | + } |
|---|
| 1070 | + |
|---|
| 1071 | + return NULL; |
|---|
| 1072 | +} |
|---|
| 1073 | +#endif |
|---|
| 1074 | + |
|---|
| 1075 | +static bool dcn20_program_pix_clk( |
|---|
| 1076 | + struct clock_source *clock_source, |
|---|
| 1077 | + struct pixel_clk_params *pix_clk_params, |
|---|
| 1078 | + struct pll_settings *pll_settings) |
|---|
| 1079 | +{ |
|---|
| 1080 | + dce112_program_pix_clk(clock_source, pix_clk_params, pll_settings); |
|---|
| 1081 | + |
|---|
| 1082 | + return true; |
|---|
| 1083 | +} |
|---|
| 1084 | + |
|---|
| 1085 | +static const struct clock_source_funcs dcn20_clk_src_funcs = { |
|---|
| 1086 | + .cs_power_down = dce110_clock_source_power_down, |
|---|
| 1087 | + .program_pix_clk = dcn20_program_pix_clk, |
|---|
| 1088 | + .get_pix_clk_dividers = dce112_get_pix_clk_dividers, |
|---|
| 1089 | + .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz |
|---|
| 1090 | +}; |
|---|
| 1091 | + |
|---|
| 1092 | +#if defined(CONFIG_DRM_AMD_DC_DCN3_0) |
|---|
| 1093 | +static bool dcn3_program_pix_clk( |
|---|
| 1094 | + struct clock_source *clock_source, |
|---|
| 1095 | + struct pixel_clk_params *pix_clk_params, |
|---|
| 1096 | + struct pll_settings *pll_settings) |
|---|
| 1097 | +{ |
|---|
| 1098 | + struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); |
|---|
| 1099 | + unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; |
|---|
| 1100 | + unsigned int dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dprefclk_khz; |
|---|
| 1101 | + const struct pixel_rate_range_table_entry *e = |
|---|
| 1102 | + look_up_in_video_optimized_rate_tlb(pix_clk_params->requested_pix_clk_100hz / 10); |
|---|
| 1103 | + |
|---|
| 1104 | + // For these signal types Driver to program DP_DTO without calling VBIOS Command table |
|---|
| 1105 | + if (dc_is_dp_signal(pix_clk_params->signal_type)) { |
|---|
| 1106 | + if (e) { |
|---|
| 1107 | + /* Set DTO values: phase = target clock, modulo = reference clock*/ |
|---|
| 1108 | + REG_WRITE(PHASE[inst], e->target_pixel_rate_khz * e->mult_factor); |
|---|
| 1109 | + REG_WRITE(MODULO[inst], dp_dto_ref_khz * e->div_factor); |
|---|
| 1110 | + } else { |
|---|
| 1111 | + /* Set DTO values: phase = target clock, modulo = reference clock*/ |
|---|
| 1112 | + REG_WRITE(PHASE[inst], pll_settings->actual_pix_clk_100hz * 100); |
|---|
| 1113 | + REG_WRITE(MODULO[inst], dp_dto_ref_khz * 1000); |
|---|
| 1114 | + } |
|---|
| 1115 | + REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); |
|---|
| 1116 | + } else |
|---|
| 1117 | + // For other signal types(HDMI_TYPE_A, DVI) Driver still to call VBIOS Command table |
|---|
| 1118 | + dce112_program_pix_clk(clock_source, pix_clk_params, pll_settings); |
|---|
| 1119 | + |
|---|
| 1120 | + return true; |
|---|
| 1121 | +} |
|---|
| 1122 | + |
|---|
| 1123 | +static uint32_t dcn3_get_pix_clk_dividers( |
|---|
| 1124 | + struct clock_source *cs, |
|---|
| 1125 | + struct pixel_clk_params *pix_clk_params, |
|---|
| 1126 | + struct pll_settings *pll_settings) |
|---|
| 1127 | +{ |
|---|
| 1128 | + unsigned long long actual_pix_clk_100Hz = pix_clk_params->requested_pix_clk_100hz; |
|---|
| 1129 | + struct dce110_clk_src *clk_src; |
|---|
| 1130 | + |
|---|
| 1131 | + clk_src = TO_DCE110_CLK_SRC(cs); |
|---|
| 1132 | + DC_LOGGER_INIT(); |
|---|
| 1133 | + |
|---|
| 1134 | + if (pix_clk_params == NULL || pll_settings == NULL |
|---|
| 1135 | + || pix_clk_params->requested_pix_clk_100hz == 0) { |
|---|
| 1136 | + DC_LOG_ERROR( |
|---|
| 1137 | + "%s: Invalid parameters!!\n", __func__); |
|---|
| 1138 | + return -1; |
|---|
| 1139 | + } |
|---|
| 1140 | + |
|---|
| 1141 | + memset(pll_settings, 0, sizeof(*pll_settings)); |
|---|
| 1142 | + /* Adjust for HDMI Type A deep color */ |
|---|
| 1143 | + if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) { |
|---|
| 1144 | + switch (pix_clk_params->color_depth) { |
|---|
| 1145 | + case COLOR_DEPTH_101010: |
|---|
| 1146 | + actual_pix_clk_100Hz = (actual_pix_clk_100Hz * 5) >> 2; |
|---|
| 1147 | + break; |
|---|
| 1148 | + case COLOR_DEPTH_121212: |
|---|
| 1149 | + actual_pix_clk_100Hz = (actual_pix_clk_100Hz * 6) >> 2; |
|---|
| 1150 | + break; |
|---|
| 1151 | + case COLOR_DEPTH_161616: |
|---|
| 1152 | + actual_pix_clk_100Hz = actual_pix_clk_100Hz * 2; |
|---|
| 1153 | + break; |
|---|
| 1154 | + default: |
|---|
| 1155 | + break; |
|---|
| 1156 | + } |
|---|
| 1157 | + } |
|---|
| 1158 | + pll_settings->actual_pix_clk_100hz = (unsigned int) actual_pix_clk_100Hz; |
|---|
| 1159 | + pll_settings->adjusted_pix_clk_100hz = (unsigned int) actual_pix_clk_100Hz; |
|---|
| 1160 | + pll_settings->calculated_pix_clk_100hz = (unsigned int) actual_pix_clk_100Hz; |
|---|
| 1161 | + |
|---|
| 1162 | + return 0; |
|---|
| 1163 | +} |
|---|
| 1164 | + |
|---|
| 1165 | +static const struct clock_source_funcs dcn3_clk_src_funcs = { |
|---|
| 1166 | + .cs_power_down = dce110_clock_source_power_down, |
|---|
| 1167 | + .program_pix_clk = dcn3_program_pix_clk, |
|---|
| 1168 | + .get_pix_clk_dividers = dcn3_get_pix_clk_dividers, |
|---|
| 1169 | + .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz |
|---|
| 1170 | +}; |
|---|
| 1171 | +#endif |
|---|
| 1038 | 1172 | /*****************************************/ |
|---|
| 1039 | 1173 | /* Constructor */ |
|---|
| 1040 | 1174 | /*****************************************/ |
|---|
| 1175 | + |
|---|
| 1176 | +static const struct clock_source_funcs dce112_clk_src_funcs = { |
|---|
| 1177 | + .cs_power_down = dce110_clock_source_power_down, |
|---|
| 1178 | + .program_pix_clk = dce112_program_pix_clk, |
|---|
| 1179 | + .get_pix_clk_dividers = dce112_get_pix_clk_dividers, |
|---|
| 1180 | + .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz |
|---|
| 1181 | +}; |
|---|
| 1041 | 1182 | static const struct clock_source_funcs dce110_clk_src_funcs = { |
|---|
| 1042 | 1183 | .cs_power_down = dce110_clock_source_power_down, |
|---|
| 1043 | 1184 | .program_pix_clk = dce110_program_pix_clk, |
|---|
| 1044 | 1185 | .get_pix_clk_dividers = dce110_get_pix_clk_dividers, |
|---|
| 1045 | | - .get_pix_rate_in_hz = dce110_get_pix_rate_in_hz |
|---|
| 1186 | + .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz |
|---|
| 1046 | 1187 | }; |
|---|
| 1188 | + |
|---|
| 1047 | 1189 | |
|---|
| 1048 | 1190 | static void get_ss_info_from_atombios( |
|---|
| 1049 | 1191 | struct dce110_clk_src *clk_src, |
|---|
| .. | .. |
|---|
| 1184 | 1326 | AS_SIGNAL_TYPE_DVI, |
|---|
| 1185 | 1327 | &clk_src->dvi_ss_params, |
|---|
| 1186 | 1328 | &clk_src->dvi_ss_params_cnt); |
|---|
| 1329 | + get_ss_info_from_atombios( |
|---|
| 1330 | + clk_src, |
|---|
| 1331 | + AS_SIGNAL_TYPE_LVDS, |
|---|
| 1332 | + &clk_src->lvds_ss_params, |
|---|
| 1333 | + &clk_src->lvds_ss_params_cnt); |
|---|
| 1187 | 1334 | } |
|---|
| 1188 | 1335 | |
|---|
| 1189 | 1336 | static bool calc_pll_max_vco_construct( |
|---|
| .. | .. |
|---|
| 1191 | 1338 | struct calc_pll_clock_source_init_data *init_data) |
|---|
| 1192 | 1339 | { |
|---|
| 1193 | 1340 | uint32_t i; |
|---|
| 1194 | | - struct dc_firmware_info fw_info = { { 0 } }; |
|---|
| 1341 | + struct dc_firmware_info *fw_info; |
|---|
| 1195 | 1342 | if (calc_pll_cs == NULL || |
|---|
| 1196 | 1343 | init_data == NULL || |
|---|
| 1197 | 1344 | init_data->bp == NULL) |
|---|
| 1198 | 1345 | return false; |
|---|
| 1199 | 1346 | |
|---|
| 1200 | | - if (init_data->bp->funcs->get_firmware_info( |
|---|
| 1201 | | - init_data->bp, |
|---|
| 1202 | | - &fw_info) != BP_RESULT_OK) |
|---|
| 1347 | + if (!init_data->bp->fw_info_valid) |
|---|
| 1203 | 1348 | return false; |
|---|
| 1204 | 1349 | |
|---|
| 1350 | + fw_info = &init_data->bp->fw_info; |
|---|
| 1205 | 1351 | calc_pll_cs->ctx = init_data->ctx; |
|---|
| 1206 | | - calc_pll_cs->ref_freq_khz = fw_info.pll_info.crystal_frequency; |
|---|
| 1352 | + calc_pll_cs->ref_freq_khz = fw_info->pll_info.crystal_frequency; |
|---|
| 1207 | 1353 | calc_pll_cs->min_vco_khz = |
|---|
| 1208 | | - fw_info.pll_info.min_output_pxl_clk_pll_frequency; |
|---|
| 1354 | + fw_info->pll_info.min_output_pxl_clk_pll_frequency; |
|---|
| 1209 | 1355 | calc_pll_cs->max_vco_khz = |
|---|
| 1210 | | - fw_info.pll_info.max_output_pxl_clk_pll_frequency; |
|---|
| 1356 | + fw_info->pll_info.max_output_pxl_clk_pll_frequency; |
|---|
| 1211 | 1357 | |
|---|
| 1212 | 1358 | if (init_data->max_override_input_pxl_clk_pll_freq_khz != 0) |
|---|
| 1213 | 1359 | calc_pll_cs->max_pll_input_freq_khz = |
|---|
| 1214 | 1360 | init_data->max_override_input_pxl_clk_pll_freq_khz; |
|---|
| 1215 | 1361 | else |
|---|
| 1216 | 1362 | calc_pll_cs->max_pll_input_freq_khz = |
|---|
| 1217 | | - fw_info.pll_info.max_input_pxl_clk_pll_frequency; |
|---|
| 1363 | + fw_info->pll_info.max_input_pxl_clk_pll_frequency; |
|---|
| 1218 | 1364 | |
|---|
| 1219 | 1365 | if (init_data->min_override_input_pxl_clk_pll_freq_khz != 0) |
|---|
| 1220 | 1366 | calc_pll_cs->min_pll_input_freq_khz = |
|---|
| 1221 | 1367 | init_data->min_override_input_pxl_clk_pll_freq_khz; |
|---|
| 1222 | 1368 | else |
|---|
| 1223 | 1369 | calc_pll_cs->min_pll_input_freq_khz = |
|---|
| 1224 | | - fw_info.pll_info.min_input_pxl_clk_pll_frequency; |
|---|
| 1370 | + fw_info->pll_info.min_input_pxl_clk_pll_frequency; |
|---|
| 1225 | 1371 | |
|---|
| 1226 | 1372 | calc_pll_cs->min_pix_clock_pll_post_divider = |
|---|
| 1227 | 1373 | init_data->min_pix_clk_pll_post_divider; |
|---|
| .. | .. |
|---|
| 1273 | 1419 | const struct dce110_clk_src_shift *cs_shift, |
|---|
| 1274 | 1420 | const struct dce110_clk_src_mask *cs_mask) |
|---|
| 1275 | 1421 | { |
|---|
| 1276 | | - struct dc_firmware_info fw_info = { { 0 } }; |
|---|
| 1277 | 1422 | struct calc_pll_clock_source_init_data calc_pll_cs_init_data_hdmi; |
|---|
| 1278 | 1423 | struct calc_pll_clock_source_init_data calc_pll_cs_init_data; |
|---|
| 1279 | 1424 | |
|---|
| .. | .. |
|---|
| 1286 | 1431 | clk_src->cs_shift = cs_shift; |
|---|
| 1287 | 1432 | clk_src->cs_mask = cs_mask; |
|---|
| 1288 | 1433 | |
|---|
| 1289 | | - if (clk_src->bios->funcs->get_firmware_info( |
|---|
| 1290 | | - clk_src->bios, &fw_info) != BP_RESULT_OK) { |
|---|
| 1434 | + if (!clk_src->bios->fw_info_valid) { |
|---|
| 1291 | 1435 | ASSERT_CRITICAL(false); |
|---|
| 1292 | 1436 | goto unexpected_failure; |
|---|
| 1293 | 1437 | } |
|---|
| 1294 | 1438 | |
|---|
| 1295 | | - clk_src->ext_clk_khz = |
|---|
| 1296 | | - fw_info.external_clock_source_frequency_for_dp; |
|---|
| 1439 | + clk_src->ext_clk_khz = clk_src->bios->fw_info.external_clock_source_frequency_for_dp; |
|---|
| 1297 | 1440 | |
|---|
| 1298 | | - switch (clk_src->base.ctx->dce_version) { |
|---|
| 1299 | | - case DCE_VERSION_8_0: |
|---|
| 1300 | | - case DCE_VERSION_8_1: |
|---|
| 1301 | | - case DCE_VERSION_8_3: |
|---|
| 1302 | | - case DCE_VERSION_10_0: |
|---|
| 1303 | | - case DCE_VERSION_11_0: |
|---|
| 1441 | + /* structure normally used with PLL ranges from ATOMBIOS; DS on by default */ |
|---|
| 1442 | + calc_pll_cs_init_data.bp = bios; |
|---|
| 1443 | + calc_pll_cs_init_data.min_pix_clk_pll_post_divider = 1; |
|---|
| 1444 | + calc_pll_cs_init_data.max_pix_clk_pll_post_divider = |
|---|
| 1445 | + clk_src->cs_mask->PLL_POST_DIV_PIXCLK; |
|---|
| 1446 | + calc_pll_cs_init_data.min_pll_ref_divider = 1; |
|---|
| 1447 | + calc_pll_cs_init_data.max_pll_ref_divider = clk_src->cs_mask->PLL_REF_DIV; |
|---|
| 1448 | + /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1449 | + calc_pll_cs_init_data.min_override_input_pxl_clk_pll_freq_khz = 0; |
|---|
| 1450 | + /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1451 | + calc_pll_cs_init_data.max_override_input_pxl_clk_pll_freq_khz = 0; |
|---|
| 1452 | + /*numberOfFractFBDividerDecimalPoints*/ |
|---|
| 1453 | + calc_pll_cs_init_data.num_fract_fb_divider_decimal_point = |
|---|
| 1454 | + FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1455 | + /*number of decimal point to round off for fractional feedback divider value*/ |
|---|
| 1456 | + calc_pll_cs_init_data.num_fract_fb_divider_decimal_point_precision = |
|---|
| 1457 | + FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1458 | + calc_pll_cs_init_data.ctx = ctx; |
|---|
| 1304 | 1459 | |
|---|
| 1305 | | - /* structure normally used with PLL ranges from ATOMBIOS; DS on by default */ |
|---|
| 1306 | | - calc_pll_cs_init_data.bp = bios; |
|---|
| 1307 | | - calc_pll_cs_init_data.min_pix_clk_pll_post_divider = 1; |
|---|
| 1308 | | - calc_pll_cs_init_data.max_pix_clk_pll_post_divider = |
|---|
| 1309 | | - clk_src->cs_mask->PLL_POST_DIV_PIXCLK; |
|---|
| 1310 | | - calc_pll_cs_init_data.min_pll_ref_divider = 1; |
|---|
| 1311 | | - calc_pll_cs_init_data.max_pll_ref_divider = clk_src->cs_mask->PLL_REF_DIV; |
|---|
| 1312 | | - /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1313 | | - calc_pll_cs_init_data.min_override_input_pxl_clk_pll_freq_khz = 0; |
|---|
| 1314 | | - /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1315 | | - calc_pll_cs_init_data.max_override_input_pxl_clk_pll_freq_khz = 0; |
|---|
| 1316 | | - /*numberOfFractFBDividerDecimalPoints*/ |
|---|
| 1317 | | - calc_pll_cs_init_data.num_fract_fb_divider_decimal_point = |
|---|
| 1318 | | - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1319 | | - /*number of decimal point to round off for fractional feedback divider value*/ |
|---|
| 1320 | | - calc_pll_cs_init_data.num_fract_fb_divider_decimal_point_precision = |
|---|
| 1321 | | - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1322 | | - calc_pll_cs_init_data.ctx = ctx; |
|---|
| 1460 | + /*structure for HDMI, no SS or SS% <= 0.06% for 27 MHz Ref clock */ |
|---|
| 1461 | + calc_pll_cs_init_data_hdmi.bp = bios; |
|---|
| 1462 | + calc_pll_cs_init_data_hdmi.min_pix_clk_pll_post_divider = 1; |
|---|
| 1463 | + calc_pll_cs_init_data_hdmi.max_pix_clk_pll_post_divider = |
|---|
| 1464 | + clk_src->cs_mask->PLL_POST_DIV_PIXCLK; |
|---|
| 1465 | + calc_pll_cs_init_data_hdmi.min_pll_ref_divider = 1; |
|---|
| 1466 | + calc_pll_cs_init_data_hdmi.max_pll_ref_divider = clk_src->cs_mask->PLL_REF_DIV; |
|---|
| 1467 | + /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1468 | + calc_pll_cs_init_data_hdmi.min_override_input_pxl_clk_pll_freq_khz = 13500; |
|---|
| 1469 | + /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1470 | + calc_pll_cs_init_data_hdmi.max_override_input_pxl_clk_pll_freq_khz = 27000; |
|---|
| 1471 | + /*numberOfFractFBDividerDecimalPoints*/ |
|---|
| 1472 | + calc_pll_cs_init_data_hdmi.num_fract_fb_divider_decimal_point = |
|---|
| 1473 | + FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1474 | + /*number of decimal point to round off for fractional feedback divider value*/ |
|---|
| 1475 | + calc_pll_cs_init_data_hdmi.num_fract_fb_divider_decimal_point_precision = |
|---|
| 1476 | + FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1477 | + calc_pll_cs_init_data_hdmi.ctx = ctx; |
|---|
| 1323 | 1478 | |
|---|
| 1324 | | - /*structure for HDMI, no SS or SS% <= 0.06% for 27 MHz Ref clock */ |
|---|
| 1325 | | - calc_pll_cs_init_data_hdmi.bp = bios; |
|---|
| 1326 | | - calc_pll_cs_init_data_hdmi.min_pix_clk_pll_post_divider = 1; |
|---|
| 1327 | | - calc_pll_cs_init_data_hdmi.max_pix_clk_pll_post_divider = |
|---|
| 1328 | | - clk_src->cs_mask->PLL_POST_DIV_PIXCLK; |
|---|
| 1329 | | - calc_pll_cs_init_data_hdmi.min_pll_ref_divider = 1; |
|---|
| 1330 | | - calc_pll_cs_init_data_hdmi.max_pll_ref_divider = clk_src->cs_mask->PLL_REF_DIV; |
|---|
| 1331 | | - /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1332 | | - calc_pll_cs_init_data_hdmi.min_override_input_pxl_clk_pll_freq_khz = 13500; |
|---|
| 1333 | | - /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ |
|---|
| 1334 | | - calc_pll_cs_init_data_hdmi.max_override_input_pxl_clk_pll_freq_khz = 27000; |
|---|
| 1335 | | - /*numberOfFractFBDividerDecimalPoints*/ |
|---|
| 1336 | | - calc_pll_cs_init_data_hdmi.num_fract_fb_divider_decimal_point = |
|---|
| 1337 | | - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1338 | | - /*number of decimal point to round off for fractional feedback divider value*/ |
|---|
| 1339 | | - calc_pll_cs_init_data_hdmi.num_fract_fb_divider_decimal_point_precision = |
|---|
| 1340 | | - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; |
|---|
| 1341 | | - calc_pll_cs_init_data_hdmi.ctx = ctx; |
|---|
| 1479 | + clk_src->ref_freq_khz = clk_src->bios->fw_info.pll_info.crystal_frequency; |
|---|
| 1342 | 1480 | |
|---|
| 1343 | | - clk_src->ref_freq_khz = fw_info.pll_info.crystal_frequency; |
|---|
| 1481 | + if (clk_src->base.id == CLOCK_SOURCE_ID_EXTERNAL) |
|---|
| 1482 | + return true; |
|---|
| 1344 | 1483 | |
|---|
| 1345 | | - if (clk_src->base.id == CLOCK_SOURCE_ID_EXTERNAL) |
|---|
| 1346 | | - return true; |
|---|
| 1484 | + /* PLL only from here on */ |
|---|
| 1485 | + ss_info_from_atombios_create(clk_src); |
|---|
| 1347 | 1486 | |
|---|
| 1348 | | - /* PLL only from here on */ |
|---|
| 1349 | | - ss_info_from_atombios_create(clk_src); |
|---|
| 1350 | | - |
|---|
| 1351 | | - if (!calc_pll_max_vco_construct( |
|---|
| 1352 | | - &clk_src->calc_pll, |
|---|
| 1353 | | - &calc_pll_cs_init_data)) { |
|---|
| 1354 | | - ASSERT_CRITICAL(false); |
|---|
| 1355 | | - goto unexpected_failure; |
|---|
| 1356 | | - } |
|---|
| 1487 | + if (!calc_pll_max_vco_construct( |
|---|
| 1488 | + &clk_src->calc_pll, |
|---|
| 1489 | + &calc_pll_cs_init_data)) { |
|---|
| 1490 | + ASSERT_CRITICAL(false); |
|---|
| 1491 | + goto unexpected_failure; |
|---|
| 1492 | + } |
|---|
| 1357 | 1493 | |
|---|
| 1358 | 1494 | |
|---|
| 1359 | | - calc_pll_cs_init_data_hdmi. |
|---|
| 1360 | | - min_override_input_pxl_clk_pll_freq_khz = clk_src->ref_freq_khz/2; |
|---|
| 1361 | | - calc_pll_cs_init_data_hdmi. |
|---|
| 1362 | | - max_override_input_pxl_clk_pll_freq_khz = clk_src->ref_freq_khz; |
|---|
| 1495 | + calc_pll_cs_init_data_hdmi. |
|---|
| 1496 | + min_override_input_pxl_clk_pll_freq_khz = clk_src->ref_freq_khz/2; |
|---|
| 1497 | + calc_pll_cs_init_data_hdmi. |
|---|
| 1498 | + max_override_input_pxl_clk_pll_freq_khz = clk_src->ref_freq_khz; |
|---|
| 1363 | 1499 | |
|---|
| 1364 | 1500 | |
|---|
| 1365 | | - if (!calc_pll_max_vco_construct( |
|---|
| 1366 | | - &clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) { |
|---|
| 1367 | | - ASSERT_CRITICAL(false); |
|---|
| 1368 | | - goto unexpected_failure; |
|---|
| 1369 | | - } |
|---|
| 1370 | | - break; |
|---|
| 1371 | | - default: |
|---|
| 1372 | | - break; |
|---|
| 1501 | + if (!calc_pll_max_vco_construct( |
|---|
| 1502 | + &clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) { |
|---|
| 1503 | + ASSERT_CRITICAL(false); |
|---|
| 1504 | + goto unexpected_failure; |
|---|
| 1373 | 1505 | } |
|---|
| 1374 | 1506 | |
|---|
| 1375 | 1507 | return true; |
|---|
| .. | .. |
|---|
| 1378 | 1510 | return false; |
|---|
| 1379 | 1511 | } |
|---|
| 1380 | 1512 | |
|---|
| 1513 | +bool dce112_clk_src_construct( |
|---|
| 1514 | + struct dce110_clk_src *clk_src, |
|---|
| 1515 | + struct dc_context *ctx, |
|---|
| 1516 | + struct dc_bios *bios, |
|---|
| 1517 | + enum clock_source_id id, |
|---|
| 1518 | + const struct dce110_clk_src_regs *regs, |
|---|
| 1519 | + const struct dce110_clk_src_shift *cs_shift, |
|---|
| 1520 | + const struct dce110_clk_src_mask *cs_mask) |
|---|
| 1521 | +{ |
|---|
| 1522 | + clk_src->base.ctx = ctx; |
|---|
| 1523 | + clk_src->bios = bios; |
|---|
| 1524 | + clk_src->base.id = id; |
|---|
| 1525 | + clk_src->base.funcs = &dce112_clk_src_funcs; |
|---|
| 1526 | + |
|---|
| 1527 | + clk_src->regs = regs; |
|---|
| 1528 | + clk_src->cs_shift = cs_shift; |
|---|
| 1529 | + clk_src->cs_mask = cs_mask; |
|---|
| 1530 | + |
|---|
| 1531 | + if (!clk_src->bios->fw_info_valid) { |
|---|
| 1532 | + ASSERT_CRITICAL(false); |
|---|
| 1533 | + return false; |
|---|
| 1534 | + } |
|---|
| 1535 | + |
|---|
| 1536 | + clk_src->ext_clk_khz = clk_src->bios->fw_info.external_clock_source_frequency_for_dp; |
|---|
| 1537 | + |
|---|
| 1538 | + return true; |
|---|
| 1539 | +} |
|---|
| 1540 | + |
|---|
| 1541 | +bool dcn20_clk_src_construct( |
|---|
| 1542 | + struct dce110_clk_src *clk_src, |
|---|
| 1543 | + struct dc_context *ctx, |
|---|
| 1544 | + struct dc_bios *bios, |
|---|
| 1545 | + enum clock_source_id id, |
|---|
| 1546 | + const struct dce110_clk_src_regs *regs, |
|---|
| 1547 | + const struct dce110_clk_src_shift *cs_shift, |
|---|
| 1548 | + const struct dce110_clk_src_mask *cs_mask) |
|---|
| 1549 | +{ |
|---|
| 1550 | + bool ret = dce112_clk_src_construct(clk_src, ctx, bios, id, regs, cs_shift, cs_mask); |
|---|
| 1551 | + |
|---|
| 1552 | + clk_src->base.funcs = &dcn20_clk_src_funcs; |
|---|
| 1553 | + |
|---|
| 1554 | + return ret; |
|---|
| 1555 | +} |
|---|
| 1556 | + |
|---|
| 1557 | +#if defined(CONFIG_DRM_AMD_DC_DCN3_0) |
|---|
| 1558 | +bool dcn3_clk_src_construct( |
|---|
| 1559 | + struct dce110_clk_src *clk_src, |
|---|
| 1560 | + struct dc_context *ctx, |
|---|
| 1561 | + struct dc_bios *bios, |
|---|
| 1562 | + enum clock_source_id id, |
|---|
| 1563 | + const struct dce110_clk_src_regs *regs, |
|---|
| 1564 | + const struct dce110_clk_src_shift *cs_shift, |
|---|
| 1565 | + const struct dce110_clk_src_mask *cs_mask) |
|---|
| 1566 | +{ |
|---|
| 1567 | + bool ret = dce112_clk_src_construct(clk_src, ctx, bios, id, regs, cs_shift, cs_mask); |
|---|
| 1568 | + |
|---|
| 1569 | + clk_src->base.funcs = &dcn3_clk_src_funcs; |
|---|
| 1570 | + |
|---|
| 1571 | + return ret; |
|---|
| 1572 | +} |
|---|
| 1573 | +#endif |
|---|