.. | .. |
---|
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 |
---|