hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
....@@ -23,6 +23,8 @@
2323 *
2424 */
2525
26
+#include <linux/slab.h>
27
+
2628 #include "dm_services.h"
2729
2830
....@@ -33,6 +35,7 @@
3335 #include "include/logger_interface.h"
3436
3537 #include "dce_clock_source.h"
38
+#include "clk_mgr.h"
3639
3740 #include "reg_helper.h"
3841
....@@ -51,6 +54,8 @@
5154 #define FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM 6
5255 #define CALC_PLL_CLK_SRC_ERR_TOLERANCE 1
5356 #define MAX_PLL_CALC_ERROR 0xFFFFFFFF
57
+
58
+#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
5459
5560 static const struct spread_spectrum_data *get_ss_data_entry(
5661 struct dce110_clk_src *clk_src,
....@@ -73,6 +78,11 @@
7378 case SIGNAL_TYPE_HDMI_TYPE_A:
7479 ss_parm = clk_src->hdmi_ss_params;
7580 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;
7686 break;
7787
7888 case SIGNAL_TYPE_DISPLAY_PORT:
....@@ -103,28 +113,28 @@
103113 }
104114
105115 /**
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
+ */
125135 static bool calculate_fb_and_fractional_fb_divider(
126136 struct calc_pll_clock_source *calc_pll_cs,
127
- uint32_t target_pix_clk_khz,
137
+ uint32_t target_pix_clk_100hz,
128138 uint32_t ref_divider,
129139 uint32_t post_divider,
130140 uint32_t *feedback_divider_param,
....@@ -133,11 +143,11 @@
133143 uint64_t feedback_divider;
134144
135145 feedback_divider =
136
- (uint64_t)target_pix_clk_khz * ref_divider * post_divider;
146
+ (uint64_t)target_pix_clk_100hz * ref_divider * post_divider;
137147 feedback_divider *= 10;
138148 /* additional factor, since we divide by 10 afterwards */
139149 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);
141151
142152 /*Round to the number of precision
143153 * The following code replace the old code (ullfeedbackDivider + 5)/10
....@@ -178,8 +188,8 @@
178188 *RETURNS:
179189 * It fills the PLLSettings structure with PLL Dividers values
180190 * 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
183193 */
184194 static bool calc_fb_divider_checking_tolerance(
185195 struct calc_pll_clock_source *calc_pll_cs,
....@@ -190,36 +200,36 @@
190200 {
191201 uint32_t feedback_divider;
192202 uint32_t fract_feedback_divider;
193
- uint32_t actual_calculated_clock_khz;
203
+ uint32_t actual_calculated_clock_100hz;
194204 uint32_t abs_err;
195
- uint64_t actual_calc_clk_khz;
205
+ uint64_t actual_calc_clk_100hz;
196206
197207 calculate_fb_and_fractional_fb_divider(
198208 calc_pll_cs,
199
- pll_settings->adjusted_pix_clk,
209
+ pll_settings->adjusted_pix_clk_100hz,
200210 ref_divider,
201211 post_divider,
202212 &feedback_divider,
203213 &fract_feedback_divider);
204214
205215 /*Actual calculated value*/
206
- actual_calc_clk_khz = (uint64_t)feedback_divider *
216
+ actual_calc_clk_100hz = (uint64_t)feedback_divider *
207217 calc_pll_cs->fract_fb_divider_factor +
208218 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,
212222 ref_divider * post_divider *
213223 calc_pll_cs->fract_fb_divider_factor);
214224
215
- actual_calculated_clock_khz = (uint32_t)(actual_calc_clk_khz);
225
+ actual_calculated_clock_100hz = (uint32_t)(actual_calc_clk_100hz);
216226
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;
223233
224234 if (abs_err <= tolerance) {
225235 /*found good values*/
....@@ -228,10 +238,10 @@
228238 pll_settings->feedback_divider = feedback_divider;
229239 pll_settings->fract_feedback_divider = fract_feedback_divider;
230240 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;
233243 pll_settings->vco_freq =
234
- actual_calculated_clock_khz * post_divider;
244
+ actual_calculated_clock_100hz * post_divider / 10;
235245 return true;
236246 }
237247 return false;
....@@ -252,8 +262,8 @@
252262
253263 /* This is err_tolerance / 10000 = 0.0025 - acceptable error of 0.25%
254264 * 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;
257267 if (tolerance < CALC_PLL_CLK_SRC_ERR_TOLERANCE)
258268 tolerance = CALC_PLL_CLK_SRC_ERR_TOLERANCE;
259269
....@@ -289,7 +299,7 @@
289299 uint32_t min_ref_divider;
290300 uint32_t max_ref_divider;
291301
292
- if (pll_settings->adjusted_pix_clk == 0) {
302
+ if (pll_settings->adjusted_pix_clk_100hz == 0) {
293303 DC_LOG_ERROR(
294304 "%s Bad requested pixel clock", __func__);
295305 return MAX_PLL_CALC_ERROR;
....@@ -301,21 +311,21 @@
301311 max_post_divider = pll_settings->pix_clk_post_divider;
302312 } else {
303313 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;
308318 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)
311321 min_post_divider++;
312322 }
313323
314324 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;
319329 }
320330
321331 /* 2) Find Reference divider ranges
....@@ -387,47 +397,47 @@
387397 struct pixel_clk_params *pix_clk_params,
388398 struct pll_settings *pll_settings)
389399 {
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;
392402 struct bp_adjust_pixel_clock_parameters bp_adjust_pixel_clock_params = {
393403 0 };
394404 enum bp_result bp_result;
395405 switch (pix_clk_params->signal_type) {
396406 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;
398408 if (pix_clk_params->pixel_encoding != PIXEL_ENCODING_YCBCR422) {
399409 switch (pix_clk_params->color_depth) {
400410 case COLOR_DEPTH_101010:
401
- requested_clk_khz = (requested_clk_khz * 5) >> 2;
411
+ requested_clk_100hz = (requested_clk_100hz * 5) >> 2;
402412 break; /* x1.25*/
403413 case COLOR_DEPTH_121212:
404
- requested_clk_khz = (requested_clk_khz * 6) >> 2;
414
+ requested_clk_100hz = (requested_clk_100hz * 6) >> 2;
405415 break; /* x1.5*/
406416 case COLOR_DEPTH_161616:
407
- requested_clk_khz = requested_clk_khz * 2;
417
+ requested_clk_100hz = requested_clk_100hz * 2;
408418 break; /* x2.0*/
409419 default:
410420 break;
411421 }
412422 }
413
- actual_pix_clk_khz = requested_clk_khz;
423
+ actual_pix_clk_100hz = requested_clk_100hz;
414424 }
415425 break;
416426
417427 case SIGNAL_TYPE_DISPLAY_PORT:
418428 case SIGNAL_TYPE_DISPLAY_PORT_MST:
419429 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;
422432 break;
423433
424434 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;
427437 break;
428438 }
429439
430
- bp_adjust_pixel_clock_params.pixel_clock = requested_clk_khz;
440
+ bp_adjust_pixel_clock_params.pixel_clock = requested_clk_100hz / 10;
431441 bp_adjust_pixel_clock_params.
432442 encoder_object_id = pix_clk_params->encoder_object_id;
433443 bp_adjust_pixel_clock_params.signal_type = pix_clk_params->signal_type;
....@@ -436,9 +446,9 @@
436446 bp_result = clk_src->bios->funcs->adjust_pixel_clock(
437447 clk_src->bios, &bp_adjust_pixel_clock_params);
438448 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;
442452 pll_settings->reference_divider =
443453 bp_adjust_pixel_clock_params.reference_divider;
444454 pll_settings->pix_clk_post_divider =
....@@ -485,7 +495,7 @@
485495 const struct spread_spectrum_data *ss_data = get_ss_data_entry(
486496 clk_src,
487497 pix_clk_params->signal_type,
488
- pll_settings->adjusted_pix_clk);
498
+ pll_settings->adjusted_pix_clk_100hz / 10);
489499
490500 if (NULL != ss_data)
491501 pll_settings->ss_percentage = ss_data->percentage;
....@@ -497,13 +507,13 @@
497507 * to continue. */
498508 DC_LOG_ERROR(
499509 "%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;
504514
505515 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;
507517 }
508518
509519 /* Calculate Dividers */
....@@ -528,28 +538,30 @@
528538 struct pll_settings *pll_settings,
529539 struct pixel_clk_params *pix_clk_params)
530540 {
531
- uint32_t actualPixelClockInKHz;
541
+ uint32_t actual_pixel_clock_100hz;
532542
533
- actualPixelClockInKHz = pix_clk_params->requested_pix_clk;
543
+ actual_pixel_clock_100hz = pix_clk_params->requested_pix_clk_100hz;
534544 /* Calculate Dividers */
535545 if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) {
536546 switch (pix_clk_params->color_depth) {
537547 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;
539550 break;
540551 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;
542554 break;
543555 case COLOR_DEPTH_161616:
544
- actualPixelClockInKHz = actualPixelClockInKHz * 2;
556
+ actual_pixel_clock_100hz = actual_pixel_clock_100hz * 2;
545557 break;
546558 default:
547559 break;
548560 }
549561 }
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;
553565 }
554566
555567 static uint32_t dce110_get_pix_clk_dividers(
....@@ -562,7 +574,7 @@
562574 DC_LOGGER_INIT();
563575
564576 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) {
566578 DC_LOG_ERROR(
567579 "%s: Invalid parameters!!\n", __func__);
568580 return pll_calc_error;
....@@ -572,122 +584,49 @@
572584
573585 if (cs->id == CLOCK_SOURCE_ID_DP_DTO ||
574586 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;
579591 return 0;
580592 }
581593
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,
590595 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
- }
605596
606597 return pll_calc_error;
607598 }
608599
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)
613604 {
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;
644605 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();
647607
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;
688613 }
689614
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;
691630 }
692631
693632 static bool disable_spread_spectrum(struct dce110_clk_src *clk_src)
....@@ -782,7 +721,7 @@
782721 ss_data = get_ss_data_entry(
783722 clk_src,
784723 signal,
785
- pll_settings->calculated_pix_clk);
724
+ pll_settings->calculated_pix_clk_100hz / 10);
786725
787726 /* Pixel clock PLL has been programmed to generate desired pixel clock,
788727 * now enable SS on pixel clock */
....@@ -909,15 +848,88 @@
909848 struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
910849 struct bp_pixel_clock_parameters bp_pc_params = {0};
911850
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)
913925 if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) {
914926 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;
917929
918930 /* 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);
921933
922934 /* Enable DTO */
923935 REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1);
....@@ -936,81 +948,32 @@
936948 /*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
937949 bp_pc_params.controller_id = pix_clk_params->controller_id;
938950 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;
940952 bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
941953 bp_pc_params.signal_type = pix_clk_params->signal_type;
942954
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 =
956957 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;
979962 }
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;
1010963 }
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);
1011973
1012974 return true;
1013975 }
976
+
1014977
1015978 static bool dce110_clock_source_power_down(
1016979 struct clock_source *clk_src)
....@@ -1035,15 +998,194 @@
1035998 return bp_result == BP_RESULT_OK;
1036999 }
10371000
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
10381172 /*****************************************/
10391173 /* Constructor */
10401174 /*****************************************/
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
+};
10411182 static const struct clock_source_funcs dce110_clk_src_funcs = {
10421183 .cs_power_down = dce110_clock_source_power_down,
10431184 .program_pix_clk = dce110_program_pix_clk,
10441185 .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
10461187 };
1188
+
10471189
10481190 static void get_ss_info_from_atombios(
10491191 struct dce110_clk_src *clk_src,
....@@ -1184,6 +1326,11 @@
11841326 AS_SIGNAL_TYPE_DVI,
11851327 &clk_src->dvi_ss_params,
11861328 &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);
11871334 }
11881335
11891336 static bool calc_pll_max_vco_construct(
....@@ -1191,37 +1338,36 @@
11911338 struct calc_pll_clock_source_init_data *init_data)
11921339 {
11931340 uint32_t i;
1194
- struct dc_firmware_info fw_info = { { 0 } };
1341
+ struct dc_firmware_info *fw_info;
11951342 if (calc_pll_cs == NULL ||
11961343 init_data == NULL ||
11971344 init_data->bp == NULL)
11981345 return false;
11991346
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)
12031348 return false;
12041349
1350
+ fw_info = &init_data->bp->fw_info;
12051351 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;
12071353 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;
12091355 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;
12111357
12121358 if (init_data->max_override_input_pxl_clk_pll_freq_khz != 0)
12131359 calc_pll_cs->max_pll_input_freq_khz =
12141360 init_data->max_override_input_pxl_clk_pll_freq_khz;
12151361 else
12161362 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;
12181364
12191365 if (init_data->min_override_input_pxl_clk_pll_freq_khz != 0)
12201366 calc_pll_cs->min_pll_input_freq_khz =
12211367 init_data->min_override_input_pxl_clk_pll_freq_khz;
12221368 else
12231369 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;
12251371
12261372 calc_pll_cs->min_pix_clock_pll_post_divider =
12271373 init_data->min_pix_clk_pll_post_divider;
....@@ -1273,7 +1419,6 @@
12731419 const struct dce110_clk_src_shift *cs_shift,
12741420 const struct dce110_clk_src_mask *cs_mask)
12751421 {
1276
- struct dc_firmware_info fw_info = { { 0 } };
12771422 struct calc_pll_clock_source_init_data calc_pll_cs_init_data_hdmi;
12781423 struct calc_pll_clock_source_init_data calc_pll_cs_init_data;
12791424
....@@ -1286,90 +1431,77 @@
12861431 clk_src->cs_shift = cs_shift;
12871432 clk_src->cs_mask = cs_mask;
12881433
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) {
12911435 ASSERT_CRITICAL(false);
12921436 goto unexpected_failure;
12931437 }
12941438
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;
12971440
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;
13041459
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;
13231478
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;
13421480
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;
13441483
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);
13471486
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
+ }
13571493
13581494
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;
13631499
13641500
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;
13731505 }
13741506
13751507 return true;
....@@ -1378,3 +1510,64 @@
13781510 return false;
13791511 }
13801512
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