/* * Copyright 2012-15 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: AMD *
*/
switch (signal) { case SIGNAL_TYPE_DVI_SINGLE_LINK: case SIGNAL_TYPE_DVI_DUAL_LINK:
ss_parm = clk_src->dvi_ss_params;
entrys_num = clk_src->dvi_ss_params_cnt; break;
case SIGNAL_TYPE_HDMI_TYPE_A:
ss_parm = clk_src->hdmi_ss_params;
entrys_num = clk_src->hdmi_ss_params_cnt; break;
case SIGNAL_TYPE_LVDS:
ss_parm = clk_src->lvds_ss_params;
entrys_num = clk_src->lvds_ss_params_cnt; break;
case SIGNAL_TYPE_DISPLAY_PORT: case SIGNAL_TYPE_DISPLAY_PORT_MST: case SIGNAL_TYPE_EDP: case SIGNAL_TYPE_VIRTUAL:
ss_parm = clk_src->dp_ss_params;
entrys_num = clk_src->dp_ss_params_cnt; break;
default:
ss_parm = NULL;
entrys_num = 0; break;
}
if (ss_parm == NULL) return ret;
for (i = 0; i < entrys_num; ++i, ++ss_parm) { if (ss_parm->freq_range_khz >= pix_clk_khz) {
ret = ss_parm; break;
}
}
return ret;
}
/** * calculate_fb_and_fractional_fb_divider - Calculates feedback and fractional * feedback dividers values * * @calc_pll_cs: Pointer to clock source information * @target_pix_clk_100hz: Desired frequency in 100 Hz * @ref_divider: Reference divider (already known) * @post_divider: Post Divider (already known) * @feedback_divider_param: Pointer where to store * calculated feedback divider value * @fract_feedback_divider_param: Pointer where to store * calculated fract feedback divider value * * return: * It fills the locations pointed by feedback_divider_param * and fract_feedback_divider_param * It returns - true if feedback divider not 0 * - false should never happen)
*/ staticbool calculate_fb_and_fractional_fb_divider( struct calc_pll_clock_source *calc_pll_cs,
uint32_t target_pix_clk_100hz,
uint32_t ref_divider,
uint32_t post_divider,
uint32_t *feedback_divider_param,
uint32_t *fract_feedback_divider_param)
{
uint64_t feedback_divider;
feedback_divider =
(uint64_t)target_pix_clk_100hz * ref_divider * post_divider;
feedback_divider *= 10; /* additional factor, since we divide by 10 afterwards */
feedback_divider *= (uint64_t)(calc_pll_cs->fract_fb_divider_factor);
feedback_divider = div_u64(feedback_divider, calc_pll_cs->ref_freq_khz * 10ull);
/*Round to the number of precision * The following code replace the old code (ullfeedbackDivider + 5)/10 * for example if the difference between the number * of fractional feedback decimal point and the fractional FB Divider precision
* is 2 then the equation becomes (ullfeedbackDivider + 5*100) / (10*100))*/
if (*feedback_divider_param != 0) returntrue; returnfalse;
}
/** * calc_fb_divider_checking_tolerance - Calculates Feedback and * Fractional Feedback divider values * for passed Reference and Post divider, * checking for tolerance. * @calc_pll_cs: Pointer to clock source information * @pll_settings: Pointer to PLL settings * @ref_divider: Reference divider (already known) * @post_divider: Post Divider (already known) * @tolerance: Tolerance for Calculated Pixel Clock to be within * * return: * It fills the PLLSettings structure with PLL Dividers values * if calculated values are within required tolerance * It returns - true if error is within tolerance * - false if error is not within tolerance
*/ staticbool calc_fb_divider_checking_tolerance( struct calc_pll_clock_source *calc_pll_cs, struct pll_settings *pll_settings,
uint32_t ref_divider,
uint32_t post_divider,
uint32_t tolerance)
{
uint32_t feedback_divider;
uint32_t fract_feedback_divider;
uint32_t actual_calculated_clock_100hz;
uint32_t abs_err;
uint64_t actual_calc_clk_100hz;
/* 2) Find Reference divider ranges * When SS is enabled, or for Display Port even without SS, * pll_settings->referenceDivider is not zero. * So calculate PPLL FB and fractional FB divider
* using the passed reference divider*/
/* If some parameters are invalid we could have scenario when "min">"max" * which produced endless loop later. * We should investigate why we get the wrong parameters. * But to follow the similar logic when "adjustedPixelClock" is set to be 0 * it is better to return here than cause system hang/watchdog timeout later.
* ## SVS Wed 15 Jul 2009 */
if (min_post_divider > max_post_divider) {
DC_LOG_ERROR( "%s Post divider range is invalid", __func__); return MAX_PLL_CALC_ERROR;
}
if (min_ref_divider > max_ref_divider) {
DC_LOG_ERROR( "%s Reference divider range is invalid", __func__); return MAX_PLL_CALC_ERROR;
}
/* 3) Try to find PLL dividers given ranges * starting with minimal error tolerance.
* Increase error tolerance until PLL dividers found*/
err_tolerance = MAX_PLL_CALC_ERROR;
case SIGNAL_TYPE_DISPLAY_PORT: case SIGNAL_TYPE_DISPLAY_PORT_MST: case SIGNAL_TYPE_EDP:
requested_clk_100hz = pix_clk_params->requested_sym_clk * 10;
actual_pix_clk_100hz = pix_clk_params->requested_pix_clk_100hz; break;
/* * Calculate PLL Dividers for given Clock Value. * First will call VBIOS Adjust Exec table to check if requested Pixel clock * will be Adjusted based on usage. * Then it will calculate PLL Dividers for this Adjusted clock using preferred * method (Maximum VCO frequency). * * \return * Calculation error in units of 0.01%
*/
/* VBIOS by default enables DP SS (spread on IDCLK) for DCE 8.0 always * (we do not care any more from SI for some older DP Sink which
* does not report SS support, no known issues) */ if ((pix_clk_params->flags.ENABLE_SS) ||
(dc_is_dp_signal(pix_clk_params->signal_type))) {
if (NULL != ss_data)
pll_settings->ss_percentage = ss_data->percentage;
}
/* Check VBIOS AdjustPixelClock Exec table */ if (!pll_adjust_pix_clk(clk_src, pix_clk_params, pll_settings)) { /* Should never happen, ASSERT and fill up values to be able
* to continue. */
DC_LOG_ERROR( "%s: Failed to adjust pixel clock!!", __func__);
pll_settings->actual_pix_clk_100hz =
pix_clk_params->requested_pix_clk_100hz;
pll_settings->adjusted_pix_clk_100hz =
pix_clk_params->requested_pix_clk_100hz;
if (dc_is_dp_signal(pix_clk_params->signal_type))
pll_settings->adjusted_pix_clk_100hz = 1000000;
}
/* Calculate Dividers */ if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) /*Calculate Dividers by HDMI object, no SS case or SS case */
pll_calc_error =
calculate_pixel_clock_pll_dividers(
&clk_src->calc_pll_hdmi,
pll_settings); else /*Calculate Dividers by default object, no SS case or SS case */
pll_calc_error =
calculate_pixel_clock_pll_dividers(
&clk_src->calc_pll,
pll_settings);
/*Call ASICControl to process ATOMBIOS Exec table*/
result = clk_src->bios->funcs->enable_spread_spectrum_on_ppll(
clk_src->bios,
&bp_ss_params, false);
/* compute SS_AMOUNT_FBDIV & SS_AMOUNT_NFRAC_SLIP & SS_AMOUNT_DSFRAC*/ /* 6 decimal point support in fractional feedback divider */
fb_div = dc_fixpt_from_fraction(
pll_settings->fract_feedback_divider, 1000000);
fb_div = dc_fixpt_add_int(fb_div, pll_settings->feedback_divider);
ds_data->ds_frac_amount = 0; /*spreadSpectrumPercentage is in the unit of .01%,
* so have to divided by 100 * 100*/
ss_amount = dc_fixpt_mul(
fb_div, dc_fixpt_from_fraction(ss_data->percentage,
100 * (longlong)ss_data->percentage_divider));
ds_data->feedback_amount = dc_fixpt_floor(ss_amount);
/* Pixel clock PLL has been programmed to generate desired pixel clock,
* now enable SS on pixel clock */ /* TODO is it OK to return true not doing anything ??*/ if (ss_data != NULL && pll_settings->ss_percentage != 0) { if (calculate_ss(pll_settings, ss_data, &d_s_data)) {
bp_params.ds.feedback_amount =
d_s_data.feedback_amount;
bp_params.ds.nfrac_amount =
d_s_data.nfrac_amount;
bp_params.ds.ds_frac_size = d_s_data.ds_frac_size;
bp_params.ds_frac_amount =
d_s_data.ds_frac_amount;
bp_params.flags.DS_TYPE = 1;
bp_params.pll_id = clk_src->base.id;
bp_params.percentage = ss_data->percentage; if (ss_data->flags.CENTER_SPREAD)
bp_params.flags.CENTER_SPREAD = 1; if (ss_data->flags.EXTERNAL_SS)
bp_params.flags.EXTERNAL_SS = 1;
/* First disable SS * ATOMBIOS will enable by default SS on PLL for DP, * do not disable it here
*/ if (clock_source->id != CLOCK_SOURCE_ID_EXTERNAL &&
!dc_is_dp_signal(pix_clk_params->signal_type) &&
clock_source->ctx->dce_version <= DCE_VERSION_11_0)
disable_spread_spectrum(clk_src);
/*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
bp_pc_params.controller_id = pix_clk_params->controller_id;
bp_pc_params.pll_id = clock_source->id;
bp_pc_params.target_pixel_clock_100hz = pll_settings->actual_pix_clk_100hz;
bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
bp_pc_params.signal_type = pix_clk_params->signal_type;
switch (pix_clk_params->color_depth) { case COLOR_DEPTH_101010:
bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_30; break; case COLOR_DEPTH_121212:
bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_36; break; case COLOR_DEPTH_161616:
bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_48; break; default: break;
}
if (clk_src->bios->funcs->set_pixel_clock(
clk_src->bios, &bp_pc_params) != BP_RESULT_OK) returnfalse; /* Enable SS * ATOMBIOS will enable by default SS for DP on PLL ( DP ID clock), * based on HW display PLL team, SS control settings should be programmed * during PLL Reset, but they do not have effect
* until SS_EN is asserted.*/ if (clock_source->id != CLOCK_SOURCE_ID_EXTERNAL
&& !dc_is_dp_signal(pix_clk_params->signal_type)) {
if (pix_clk_params->flags.ENABLE_SS) if (!enable_spread_spectrum(clk_src,
pix_clk_params->signal_type,
pll_settings)) returnfalse;
/* Resync deep color DTO */
dce110_program_pixel_clk_resync(clk_src,
pix_clk_params->signal_type,
pix_clk_params->color_depth);
}
/* First disable SS * ATOMBIOS will enable by default SS on PLL for DP, * do not disable it here
*/ if (clock_source->id != CLOCK_SOURCE_ID_EXTERNAL &&
!dc_is_dp_signal(pix_clk_params->signal_type) &&
clock_source->ctx->dce_version <= DCE_VERSION_11_0)
disable_spread_spectrum(clk_src);
/*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
bp_pc_params.controller_id = pix_clk_params->controller_id;
bp_pc_params.pll_id = clock_source->id;
bp_pc_params.target_pixel_clock_100hz = pll_settings->actual_pix_clk_100hz;
bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
bp_pc_params.signal_type = pix_clk_params->signal_type;
if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC =
pll_settings->use_external_clk;
bp_pc_params.flags.SET_XTALIN_REF_SRC =
!pll_settings->use_external_clk; if (pix_clk_params->flags.SUPPORT_YCBCR420) {
bp_pc_params.flags.SUPPORT_YUV_420 = 1;
}
} if (clk_src->bios->funcs->set_pixel_clock(
clk_src->bios, &bp_pc_params) != BP_RESULT_OK) returnfalse; /* Resync deep color DTO */ if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO)
dce112_program_pixel_clk_resync(clk_src,
pix_clk_params->signal_type,
pix_clk_params->color_depth,
pix_clk_params->flags.SUPPORT_YCBCR420);
// Apply ssed(spread spectrum) dpref clock for edp and dp if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0 &&
dc_is_dp_signal(pix_clk_params->signal_type) &&
encoding == DP_8b_10b_ENCODING)
dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
// For these signal types Driver to program DP_DTO without calling VBIOS Command table if (dc_is_dp_signal(pix_clk_params->signal_type) || dc_is_virtual_signal(pix_clk_params->signal_type)) { if (e) { /* Set DTO values: phase = target clock, modulo = reference clock*/
REG_WRITE(PHASE[inst], e->target_pixel_rate_khz * e->mult_factor);
REG_WRITE(MODULO[inst], dp_dto_ref_khz * e->div_factor);
} else { /* Set DTO values: phase = target clock, modulo = reference clock*/
REG_WRITE(PHASE[inst], pll_settings->actual_pix_clk_100hz * 100);
REG_WRITE(MODULO[inst], dp_dto_ref_khz * 1000);
} /* Enable DTO */ if (clk_src->cs_mask->PIPE0_DTO_SRC_SEL) if (encoding == DP_128b_132b_ENCODING)
REG_UPDATE_2(PIXEL_RATE_CNTL[inst],
DP_DTO0_ENABLE, 1,
PIPE0_DTO_SRC_SEL, 2); else
REG_UPDATE_2(PIXEL_RATE_CNTL[inst],
DP_DTO0_ENABLE, 1,
PIPE0_DTO_SRC_SEL, 1); else
REG_UPDATE(PIXEL_RATE_CNTL[inst],
DP_DTO0_ENABLE, 1);
} else {
if (clk_src->cs_mask->PIPE0_DTO_SRC_SEL)
REG_UPDATE(PIXEL_RATE_CNTL[inst],
PIPE0_DTO_SRC_SEL, 0);
/*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
bp_pc_params.controller_id = pix_clk_params->controller_id;
bp_pc_params.pll_id = clock_source->id;
bp_pc_params.target_pixel_clock_100hz = pll_settings->actual_pix_clk_100hz;
bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
bp_pc_params.signal_type = pix_clk_params->signal_type;
// Make sure we send the correct color depth to DMUB for HDMI if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) { switch (pix_clk_params->color_depth) { case COLOR_DEPTH_888:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24; break; case COLOR_DEPTH_101010:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_30; break; case COLOR_DEPTH_121212:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_36; break; case COLOR_DEPTH_161616:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_48; break; default:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24; break;
}
bp_pc_params.color_depth = bp_pc_colour_depth;
}
if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC =
pll_settings->use_external_clk;
bp_pc_params.flags.SET_XTALIN_REF_SRC =
!pll_settings->use_external_clk; if (pix_clk_params->flags.SUPPORT_YCBCR420) {
bp_pc_params.flags.SUPPORT_YUV_420 = 1;
}
} if (clk_src->bios->funcs->set_pixel_clock(
clk_src->bios, &bp_pc_params) != BP_RESULT_OK) returnfalse; /* Resync deep color DTO */ if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO)
dce112_program_pixel_clk_resync(clk_src,
pix_clk_params->signal_type,
pix_clk_params->color_depth,
pix_clk_params->flags.SUPPORT_YCBCR420);
}
// all but TMDS gets Driver to program DP_DTO without calling VBIOS Command table if (!dc_is_tmds_signal(pix_clk_params->signal_type)) { longlong dtbclk_p_src_clk_khz;
} else { if (pll_settings->actual_pix_clk_100hz > 6000000UL) returnfalse;
/* disables DP DTO when provided with TMDS signal type */
clock_source->ctx->dc->res_pool->dccg->funcs->set_dp_dto(
clock_source->ctx->dc->res_pool->dccg,
&dto_params);
/*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
bp_pc_params.controller_id = pix_clk_params->controller_id;
bp_pc_params.pll_id = clock_source->id;
bp_pc_params.target_pixel_clock_100hz = pll_settings->actual_pix_clk_100hz;
bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
bp_pc_params.signal_type = pix_clk_params->signal_type;
// Make sure we send the correct color depth to DMUB for HDMI if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) { switch (pix_clk_params->color_depth) { case COLOR_DEPTH_888:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24; break; case COLOR_DEPTH_101010:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_30; break; case COLOR_DEPTH_121212:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_36; break; case COLOR_DEPTH_161616:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_48; break; default:
bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24; break;
}
bp_pc_params.color_depth = bp_pc_colour_depth;
}
if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC =
pll_settings->use_external_clk;
bp_pc_params.flags.SET_XTALIN_REF_SRC =
!pll_settings->use_external_clk; if (pix_clk_params->flags.SUPPORT_YCBCR420) {
bp_pc_params.flags.SUPPORT_YUV_420 = 1;
}
} if (clk_src->bios->funcs->set_pixel_clock(
clk_src->bios, &bp_pc_params) != BP_RESULT_OK) returnfalse; /* Resync deep color DTO */ if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO)
dce112_program_pixel_clk_resync(clk_src,
pix_clk_params->signal_type,
pix_clk_params->color_depth,
pix_clk_params->flags.SUPPORT_YCBCR420);
}
/* If Pixel Clock is 0 it means Power Down Pll*/
bp_pixel_clock_params.controller_id = CONTROLLER_ID_UNDEFINED;
bp_pixel_clock_params.pll_id = clk_src->id;
bp_pixel_clock_params.flags.FORCE_PROGRAMMING_OF_PLL = 1;
/*Call ASICControl to process ATOMBIOS Exec table*/
bp_result = dce110_clk_src->bios->funcs->set_pixel_clock(
dce110_clk_src->bios,
&bp_pixel_clock_params);
if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) {
clock_hz = REG_READ(PHASE[inst]);
if (clock_source->ctx->dc->hwss.enable_vblanks_synchronization &&
clock_source->ctx->dc->config.vblank_alignment_max_frame_time_diff > 0) { /* NOTE: In case VBLANK syncronization is enabled, MODULO may * not be programmed equal to DPREFCLK
*/
modulo_hz = REG_READ(MODULO[inst]); if (modulo_hz)
*pixel_clk_khz = div_u64((uint64_t)clock_hz*
dp_dto_ref_khz*10,
modulo_hz); else
*pixel_clk_khz = 0;
} else { /* NOTE: There is agreement with VBIOS here that MODULO is * programmed equal to DPREFCLK, in which case PHASE will be * equivalent to pixel clock.
*/
*pixel_clk_khz = clock_hz / 100;
} returntrue;
}
if (clock_source->ctx->dc->hwss.enable_vblanks_synchronization &&
clock_source->ctx->dc->config.vblank_alignment_max_frame_time_diff > 0) { /* NOTE: In case VBLANK syncronization is enabled, * we need to set modulo to default DPREFCLK first * dce112_program_pix_clk does not set default DPREFCLK
*/
REG_WRITE(MODULO[inst],
clock_source->ctx->dc->clk_mgr->dprefclk_khz*1000);
} returntrue;
}
for (i = 0, ss_info_cur = ss_info;
i < (*ss_entries_num);
++i, ++ss_info_cur) {
bp_result = clk_src->bios->funcs->get_spread_spectrum_info(
clk_src->bios,
as_signal,
i,
ss_info_cur);
if (bp_result != BP_RESULT_OK) goto out_free_data;
}
for (i = 0, ss_info_cur = ss_info, ss_data_cur = ss_data;
i < (*ss_entries_num);
++i, ++ss_info_cur, ++ss_data_cur) {
if (ss_info_cur->type.STEP_AND_DELAY_INFO != false) {
DC_LOG_SYNC( "Invalid ATOMBIOS SS Table!!!\n"); goto out_free_data;
}
/* for HDMI check SS percentage,
* if it is > 6 (0.06%), the ATOMBIOS table info is invalid*/ if (as_signal == AS_SIGNAL_TYPE_HDMI
&& ss_info_cur->spread_spectrum_percentage > 6){ /* invalid input, do nothing */
DC_LOG_SYNC( "Invalid SS percentage ");
DC_LOG_SYNC( "for HDMI in ATOMBIOS info Table!!!\n"); continue;
} if (ss_info_cur->spread_percentage_divider == 1000) { /* Keep previous precision from ATOMBIOS for these * in case new precision set by ATOMBIOS for these * (otherwise all code in DCE specific classes * for all previous ASICs would need * to be updated for SS calculations, * Audio SS compensation and DP DTO SS compensation
* which assumes fixed SS percentage Divider = 100)*/
ss_info_cur->spread_spectrum_percentage /= 10;
ss_info_cur->spread_percentage_divider = 100;
}
if (init_data->num_fract_fb_divider_decimal_point == 0 ||
init_data->num_fract_fb_divider_decimal_point_precision >
init_data->num_fract_fb_divider_decimal_point) {
DC_LOG_ERROR( "The dec point num or precision is incorrect!"); returnfalse;
} if (init_data->num_fract_fb_divider_decimal_point_precision == 0) {
DC_LOG_ERROR( "Incorrect fract feedback divider precision num!"); returnfalse;
}
calc_pll_cs->fract_fb_divider_decimal_points_num =
init_data->num_fract_fb_divider_decimal_point;
calc_pll_cs->fract_fb_divider_precision =
init_data->num_fract_fb_divider_decimal_point_precision;
calc_pll_cs->fract_fb_divider_factor = 1; for (i = 0; i < calc_pll_cs->fract_fb_divider_decimal_points_num; ++i)
calc_pll_cs->fract_fb_divider_factor *= 10;
calc_pll_cs->fract_fb_divider_precision_factor = 1; for (
i = 0;
i < (calc_pll_cs->fract_fb_divider_decimal_points_num -
calc_pll_cs->fract_fb_divider_precision);
++i)
calc_pll_cs->fract_fb_divider_precision_factor *= 10;
/* structure normally used with PLL ranges from ATOMBIOS; DS on by default */
calc_pll_cs_init_data.bp = bios;
calc_pll_cs_init_data.min_pix_clk_pll_post_divider = 1;
calc_pll_cs_init_data.max_pix_clk_pll_post_divider =
clk_src->cs_mask->PLL_POST_DIV_PIXCLK;
calc_pll_cs_init_data.min_pll_ref_divider = 1;
calc_pll_cs_init_data.max_pll_ref_divider = clk_src->cs_mask->PLL_REF_DIV; /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
calc_pll_cs_init_data.min_override_input_pxl_clk_pll_freq_khz = 0; /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
calc_pll_cs_init_data.max_override_input_pxl_clk_pll_freq_khz = 0; /*numberOfFractFBDividerDecimalPoints*/
calc_pll_cs_init_data.num_fract_fb_divider_decimal_point =
FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; /*number of decimal point to round off for fractional feedback divider value*/
calc_pll_cs_init_data.num_fract_fb_divider_decimal_point_precision =
FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM;
calc_pll_cs_init_data.ctx = ctx;
/*structure for HDMI, no SS or SS% <= 0.06% for 27 MHz Ref clock */
calc_pll_cs_init_data_hdmi.bp = bios;
calc_pll_cs_init_data_hdmi.min_pix_clk_pll_post_divider = 1;
calc_pll_cs_init_data_hdmi.max_pix_clk_pll_post_divider =
clk_src->cs_mask->PLL_POST_DIV_PIXCLK;
calc_pll_cs_init_data_hdmi.min_pll_ref_divider = 1;
calc_pll_cs_init_data_hdmi.max_pll_ref_divider = clk_src->cs_mask->PLL_REF_DIV; /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
calc_pll_cs_init_data_hdmi.min_override_input_pxl_clk_pll_freq_khz = 13500; /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
calc_pll_cs_init_data_hdmi.max_override_input_pxl_clk_pll_freq_khz = 27000; /*numberOfFractFBDividerDecimalPoints*/
calc_pll_cs_init_data_hdmi.num_fract_fb_divider_decimal_point =
FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM; /*number of decimal point to round off for fractional feedback divider value*/
calc_pll_cs_init_data_hdmi.num_fract_fb_divider_decimal_point_precision =
FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM;
calc_pll_cs_init_data_hdmi.ctx = ctx;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.