diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce')
17 files changed, 717 insertions, 584 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index fe92a1222803..29294db1a96b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -26,7 +26,7 @@ #include "dce_abm.h" #include "dm_services.h" #include "reg_helper.h" -#include "fixed32_32.h" +#include "fixed31_32.h" #include "dc.h" #include "atom.h" diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c index 6d5cdcdc8ec9..7f6d724686f1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c @@ -33,8 +33,9 @@ #define CTX \ aud->base.ctx -#define DC_LOGGER \ - aud->base.ctx->logger + +#define DC_LOGGER_INIT() + #define REG(reg)\ (aud->regs->reg) @@ -348,8 +349,8 @@ static void set_audio_latency( void dce_aud_az_enable(struct audio *audio) { - struct dce_audio *aud = DCE_AUD(audio); uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL); + DC_LOGGER_INIT(); set_reg_field_value(value, 1, AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, @@ -371,7 +372,7 @@ void dce_aud_az_enable(struct audio *audio) void dce_aud_az_disable(struct audio *audio) { uint32_t value; - struct dce_audio *aud = DCE_AUD(audio); + DC_LOGGER_INIT(); value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL); set_reg_field_value(value, 1, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index 0aa2cda60890..439dcf3b596c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -41,8 +41,9 @@ #define CTX \ clk_src->base.ctx -#define DC_LOGGER \ - calc_pll_cs->ctx->logger + +#define DC_LOGGER_INIT() + #undef FN #define FN(reg_name, field_name) \ clk_src->cs_shift->field_name, clk_src->cs_mask->field_name @@ -132,7 +133,7 @@ static bool calculate_fb_and_fractional_fb_divider( uint64_t feedback_divider; feedback_divider = - (uint64_t)(target_pix_clk_khz * ref_divider * post_divider); + (uint64_t)target_pix_clk_khz * 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); @@ -144,8 +145,8 @@ static bool calculate_fb_and_fractional_fb_divider( * of fractional feedback decimal point and the fractional FB Divider precision * is 2 then the equation becomes (ullfeedbackDivider + 5*100) / (10*100))*/ - feedback_divider += (uint64_t) - (5 * calc_pll_cs->fract_fb_divider_precision_factor); + feedback_divider += 5ULL * + calc_pll_cs->fract_fb_divider_precision_factor; feedback_divider = div_u64(feedback_divider, calc_pll_cs->fract_fb_divider_precision_factor * 10); @@ -202,8 +203,8 @@ static bool calc_fb_divider_checking_tolerance( &fract_feedback_divider); /*Actual calculated value*/ - actual_calc_clk_khz = (uint64_t)(feedback_divider * - calc_pll_cs->fract_fb_divider_factor) + + actual_calc_clk_khz = (uint64_t)feedback_divider * + calc_pll_cs->fract_fb_divider_factor + fract_feedback_divider; actual_calc_clk_khz *= calc_pll_cs->ref_freq_khz; actual_calc_clk_khz = @@ -467,7 +468,7 @@ static uint32_t dce110_get_pix_clk_dividers_helper ( { uint32_t field = 0; uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; - struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; + DC_LOGGER_INIT(); /* Check if reference clock is external (not pcie/xtalin) * HW Dce80 spec: * 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB @@ -557,8 +558,8 @@ static uint32_t dce110_get_pix_clk_dividers( struct pll_settings *pll_settings) { struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs); - struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; + DC_LOGGER_INIT(); if (pix_clk_params == NULL || pll_settings == NULL || pix_clk_params->requested_pix_clk == 0) { @@ -589,8 +590,9 @@ static uint32_t dce110_get_pix_clk_dividers( pll_settings, pix_clk_params); break; case DCE_VERSION_11_2: + case DCE_VERSION_11_22: case DCE_VERSION_12_0: -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: #endif @@ -655,12 +657,12 @@ static uint32_t dce110_get_d_to_pixel_rate_in_hz( return 0; } - pix_rate = dal_fixed31_32_from_int(clk_src->ref_freq_khz); - pix_rate = dal_fixed31_32_mul_int(pix_rate, 1000); - pix_rate = dal_fixed31_32_mul_int(pix_rate, phase); - pix_rate = dal_fixed31_32_div_int(pix_rate, modulo); + pix_rate = dc_fixpt_from_int(clk_src->ref_freq_khz); + pix_rate = dc_fixpt_mul_int(pix_rate, 1000); + pix_rate = dc_fixpt_mul_int(pix_rate, phase); + pix_rate = dc_fixpt_div_int(pix_rate, modulo); - return dal_fixed31_32_round(pix_rate); + return dc_fixpt_round(pix_rate); } else { return dce110_get_dp_pixel_rate_from_combo_phy_pll(cs, pix_clk_params, pll_settings); } @@ -709,12 +711,12 @@ static bool calculate_ss( const struct spread_spectrum_data *ss_data, struct delta_sigma_data *ds_data) { - struct fixed32_32 fb_div; - struct fixed32_32 ss_amount; - struct fixed32_32 ss_nslip_amount; - struct fixed32_32 ss_ds_frac_amount; - struct fixed32_32 ss_step_size; - struct fixed32_32 modulation_time; + struct fixed31_32 fb_div; + struct fixed31_32 ss_amount; + struct fixed31_32 ss_nslip_amount; + struct fixed31_32 ss_ds_frac_amount; + struct fixed31_32 ss_step_size; + struct fixed31_32 modulation_time; if (ds_data == NULL) return false; @@ -729,42 +731,42 @@ static bool calculate_ss( /* compute SS_AMOUNT_FBDIV & SS_AMOUNT_NFRAC_SLIP & SS_AMOUNT_DSFRAC*/ /* 6 decimal point support in fractional feedback divider */ - fb_div = dal_fixed32_32_from_fraction( + fb_div = dc_fixpt_from_fraction( pll_settings->fract_feedback_divider, 1000000); - fb_div = dal_fixed32_32_add_int(fb_div, pll_settings->feedback_divider); + 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 = dal_fixed32_32_mul( - fb_div, dal_fixed32_32_from_fraction(ss_data->percentage, + ss_amount = dc_fixpt_mul( + fb_div, dc_fixpt_from_fraction(ss_data->percentage, 100 * ss_data->percentage_divider)); - ds_data->feedback_amount = dal_fixed32_32_floor(ss_amount); + ds_data->feedback_amount = dc_fixpt_floor(ss_amount); - ss_nslip_amount = dal_fixed32_32_sub(ss_amount, - dal_fixed32_32_from_int(ds_data->feedback_amount)); - ss_nslip_amount = dal_fixed32_32_mul_int(ss_nslip_amount, 10); - ds_data->nfrac_amount = dal_fixed32_32_floor(ss_nslip_amount); + ss_nslip_amount = dc_fixpt_sub(ss_amount, + dc_fixpt_from_int(ds_data->feedback_amount)); + ss_nslip_amount = dc_fixpt_mul_int(ss_nslip_amount, 10); + ds_data->nfrac_amount = dc_fixpt_floor(ss_nslip_amount); - ss_ds_frac_amount = dal_fixed32_32_sub(ss_nslip_amount, - dal_fixed32_32_from_int(ds_data->nfrac_amount)); - ss_ds_frac_amount = dal_fixed32_32_mul_int(ss_ds_frac_amount, 65536); - ds_data->ds_frac_amount = dal_fixed32_32_floor(ss_ds_frac_amount); + ss_ds_frac_amount = dc_fixpt_sub(ss_nslip_amount, + dc_fixpt_from_int(ds_data->nfrac_amount)); + ss_ds_frac_amount = dc_fixpt_mul_int(ss_ds_frac_amount, 65536); + ds_data->ds_frac_amount = dc_fixpt_floor(ss_ds_frac_amount); /* compute SS_STEP_SIZE_DSFRAC */ - modulation_time = dal_fixed32_32_from_fraction( + modulation_time = dc_fixpt_from_fraction( pll_settings->reference_freq * 1000, pll_settings->reference_divider * ss_data->modulation_freq_hz); if (ss_data->flags.CENTER_SPREAD) - modulation_time = dal_fixed32_32_div_int(modulation_time, 4); + modulation_time = dc_fixpt_div_int(modulation_time, 4); else - modulation_time = dal_fixed32_32_div_int(modulation_time, 2); + modulation_time = dc_fixpt_div_int(modulation_time, 2); - ss_step_size = dal_fixed32_32_div(ss_amount, modulation_time); + ss_step_size = dc_fixpt_div(ss_amount, modulation_time); /* SS_STEP_SIZE_DSFRAC_DEC = Int(SS_STEP_SIZE * 2 ^ 16 * 10)*/ - ss_step_size = dal_fixed32_32_mul_int(ss_step_size, 65536 * 10); - ds_data->ds_frac_size = dal_fixed32_32_floor(ss_step_size); + ss_step_size = dc_fixpt_mul_int(ss_step_size, 65536 * 10); + ds_data->ds_frac_size = dc_fixpt_floor(ss_step_size); return true; } @@ -907,7 +909,7 @@ static bool dce110_program_pix_clk( struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); struct bp_pixel_clock_parameters bp_pc_params = {0}; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) { unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; unsigned dp_dto_ref_kHz = 700000; @@ -978,8 +980,9 @@ static bool dce110_program_pix_clk( break; case DCE_VERSION_11_2: + case DCE_VERSION_11_22: case DCE_VERSION_12_0: -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: #endif @@ -1054,7 +1057,7 @@ static void get_ss_info_from_atombios( struct spread_spectrum_info *ss_info_cur; struct spread_spectrum_data *ss_data_cur; uint32_t i; - struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; + DC_LOGGER_INIT(); if (ss_entries_num == NULL) { DC_LOG_SYNC( "Invalid entry !!!\n"); @@ -1076,13 +1079,15 @@ static void get_ss_info_from_atombios( if (*ss_entries_num == 0) return; - ss_info = kzalloc(sizeof(struct spread_spectrum_info) * (*ss_entries_num), + ss_info = kcalloc(*ss_entries_num, + sizeof(struct spread_spectrum_info), GFP_KERNEL); ss_info_cur = ss_info; if (ss_info == NULL) return; - ss_data = kzalloc(sizeof(struct spread_spectrum_data) * (*ss_entries_num), + ss_data = kcalloc(*ss_entries_num, + sizeof(struct spread_spectrum_data), GFP_KERNEL); if (ss_data == NULL) goto out_free_info; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h index c45e2f76189e..801bb65707b3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h @@ -55,7 +55,7 @@ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, mask_sh) -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #define CS_COMMON_REG_LIST_DCN1_0(index, pllid) \ SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 78e6beb6cf26..8f8a2abac3f3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -26,19 +26,19 @@ #include "dce_clocks.h" #include "dm_services.h" #include "reg_helper.h" -#include "fixed32_32.h" +#include "fixed31_32.h" #include "bios_parser_interface.h" #include "dc.h" #include "dmcu.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "dcn_calcs.h" #endif #include "core_types.h" #include "dc_types.h" - +#include "dal_asic_id.h" #define TO_DCE_CLOCKS(clocks)\ - container_of(clocks, struct dce_disp_clk, base) + container_of(clocks, struct dce_dccg, base) #define REG(reg) \ (clk_dce->regs->reg) @@ -101,99 +101,78 @@ static const struct state_dependent_clocks dce120_max_clks_by_state[] = { /*ClocksStatePerformance*/ { .display_clk_khz = 1133000, .pixel_clk_khz = 600000 } }; -/* Starting point for each divider range.*/ -enum dce_divider_range_start { - DIVIDER_RANGE_01_START = 200, /* 2.00*/ - DIVIDER_RANGE_02_START = 1600, /* 16.00*/ - DIVIDER_RANGE_03_START = 3200, /* 32.00*/ - DIVIDER_RANGE_SCALE_FACTOR = 100 /* Results are scaled up by 100.*/ -}; - -/* Ranges for divider identifiers (Divider ID or DID) - mmDENTIST_DISPCLK_CNTL.DENTIST_DISPCLK_WDIVIDER*/ -enum dce_divider_id_register_setting { - DIVIDER_RANGE_01_BASE_DIVIDER_ID = 0X08, - DIVIDER_RANGE_02_BASE_DIVIDER_ID = 0X40, - DIVIDER_RANGE_03_BASE_DIVIDER_ID = 0X60, - DIVIDER_RANGE_MAX_DIVIDER_ID = 0X80 +/* Starting DID for each range */ +enum dentist_base_divider_id { + DENTIST_BASE_DID_1 = 0x08, + DENTIST_BASE_DID_2 = 0x40, + DENTIST_BASE_DID_3 = 0x60, + DENTIST_MAX_DID = 0x80 }; -/* Step size between each divider within a range. - Incrementing the DENTIST_DISPCLK_WDIVIDER by one - will increment the divider by this much.*/ -enum dce_divider_range_step_size { - DIVIDER_RANGE_01_STEP_SIZE = 25, /* 0.25*/ - DIVIDER_RANGE_02_STEP_SIZE = 50, /* 0.50*/ - DIVIDER_RANGE_03_STEP_SIZE = 100 /* 1.00 */ +/* Starting point and step size for each divider range.*/ +enum dentist_divider_range { + DENTIST_DIVIDER_RANGE_1_START = 8, /* 2.00 */ + DENTIST_DIVIDER_RANGE_1_STEP = 1, /* 0.25 */ + DENTIST_DIVIDER_RANGE_2_START = 64, /* 16.00 */ + DENTIST_DIVIDER_RANGE_2_STEP = 2, /* 0.50 */ + DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */ + DENTIST_DIVIDER_RANGE_3_STEP = 4, /* 1.00 */ + DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4 }; -static bool dce_divider_range_construct( - struct dce_divider_range *div_range, - int range_start, - int range_step, - int did_min, - int did_max) +static int dentist_get_divider_from_did(int did) { - div_range->div_range_start = range_start; - div_range->div_range_step = range_step; - div_range->did_min = did_min; - div_range->did_max = did_max; - - if (div_range->div_range_step == 0) { - div_range->div_range_step = 1; - /*div_range_step cannot be zero*/ - BREAK_TO_DEBUGGER(); + if (did < DENTIST_BASE_DID_1) + did = DENTIST_BASE_DID_1; + if (did > DENTIST_MAX_DID) + did = DENTIST_MAX_DID; + + if (did < DENTIST_BASE_DID_2) { + return DENTIST_DIVIDER_RANGE_1_START + DENTIST_DIVIDER_RANGE_1_STEP + * (did - DENTIST_BASE_DID_1); + } else if (did < DENTIST_BASE_DID_3) { + return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP + * (did - DENTIST_BASE_DID_2); + } else { + return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP + * (did - DENTIST_BASE_DID_3); } - /* Calculate this based on the other inputs.*/ - /* See DividerRange.h for explanation of */ - /* the relationship between divider id (DID) and a divider.*/ - /* Number of Divider IDs = (Maximum Divider ID - Minimum Divider ID)*/ - /* Maximum divider identified in this range = - * (Number of Divider IDs)*Step size between dividers - * + The start of this range.*/ - div_range->div_range_end = (did_max - did_min) * range_step - + range_start; - return true; -} - -static int dce_divider_range_calc_divider( - struct dce_divider_range *div_range, - int did) -{ - /* Is this DID within our range?*/ - if ((did < div_range->did_min) || (did >= div_range->did_max)) - return INVALID_DIVIDER; - - return ((did - div_range->did_min) * div_range->div_range_step) - + div_range->div_range_start; - } -static int dce_divider_range_get_divider( - struct dce_divider_range *div_range, - int ranges_num, - int did) +/* SW will adjust DP REF Clock average value for all purposes + * (DP DTO / DP Audio DTO and DP GTC) + if clock is spread for all cases: + -if SS enabled on DP Ref clock and HW de-spreading enabled with SW + calculations for DS_INCR/DS_MODULO (this is planned to be default case) + -if SS enabled on DP Ref clock and HW de-spreading enabled with HW + calculations (not planned to be used, but average clock should still + be valid) + -if SS enabled on DP Ref clock and HW de-spreading disabled + (should not be case with CIK) then SW should program all rates + generated according to average value (case as with previous ASICs) + */ +static int dccg_adjust_dp_ref_freq_for_ss(struct dce_dccg *clk_dce, int dp_ref_clk_khz) { - int div = INVALID_DIVIDER; - int i; - - for (i = 0; i < ranges_num; i++) { - /* Calculate divider with given divider ID*/ - div = dce_divider_range_calc_divider(&div_range[i], did); - /* Found a valid return divider*/ - if (div != INVALID_DIVIDER) - break; + if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { + struct fixed31_32 ss_percentage = dc_fixpt_div_int( + dc_fixpt_from_fraction(clk_dce->dprefclk_ss_percentage, + clk_dce->dprefclk_ss_divider), 200); + struct fixed31_32 adj_dp_ref_clk_khz; + + ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); + adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); + dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); } - return div; + return dp_ref_clk_khz; } -static int dce_clocks_get_dp_ref_freq(struct display_clock *clk) +static int dce_get_dp_ref_freq_khz(struct dccg *clk) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); int dprefclk_wdivider; int dprefclk_src_sel; int dp_ref_clk_khz = 600000; - int target_div = INVALID_DIVIDER; + int target_div; /* ASSERT DP Reference Clock source is from DFS*/ REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel); @@ -204,80 +183,27 @@ static int dce_clocks_get_dp_ref_freq(struct display_clock *clk) REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ - target_div = dce_divider_range_get_divider( - clk_dce->divider_ranges, - DIVIDER_RANGE_MAX, - dprefclk_wdivider); - - if (target_div != INVALID_DIVIDER) { - /* Calculate the current DFS clock, in kHz.*/ - dp_ref_clk_khz = (DIVIDER_RANGE_SCALE_FACTOR - * clk_dce->dentist_vco_freq_khz) / target_div; - } + target_div = dentist_get_divider_from_did(dprefclk_wdivider); - /* SW will adjust DP REF Clock average value for all purposes - * (DP DTO / DP Audio DTO and DP GTC) - if clock is spread for all cases: - -if SS enabled on DP Ref clock and HW de-spreading enabled with SW - calculations for DS_INCR/DS_MODULO (this is planned to be default case) - -if SS enabled on DP Ref clock and HW de-spreading enabled with HW - calculations (not planned to be used, but average clock should still - be valid) - -if SS enabled on DP Ref clock and HW de-spreading disabled - (should not be case with CIK) then SW should program all rates - generated according to average value (case as with previous ASICs) - */ - if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { - struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( - dal_fixed32_32_from_fraction( - clk_dce->dprefclk_ss_percentage, - clk_dce->dprefclk_ss_divider), 200); - struct fixed32_32 adj_dp_ref_clk_khz; - - ss_percentage = dal_fixed32_32_sub(dal_fixed32_32_one, - ss_percentage); - adj_dp_ref_clk_khz = - dal_fixed32_32_mul_int( - ss_percentage, - dp_ref_clk_khz); - dp_ref_clk_khz = dal_fixed32_32_floor(adj_dp_ref_clk_khz); - } + /* Calculate the current DFS clock, in kHz.*/ + dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR + * clk_dce->dentist_vco_freq_khz) / target_div; - return dp_ref_clk_khz; + return dccg_adjust_dp_ref_freq_for_ss(clk_dce, dp_ref_clk_khz); } -/* TODO: This is DCN DPREFCLK: it could be program by DENTIST by VBIOS - * or CLK0_CLK11 by SMU. For DCE120, it is wlays 600Mhz. Will re-visit - * clock implementation - */ -static int dce_clocks_get_dp_ref_freq_wrkaround(struct display_clock *clk) +static int dce12_get_dp_ref_freq_khz(struct dccg *clk) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); - int dp_ref_clk_khz = 600000; - - if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { - struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( - dal_fixed32_32_from_fraction( - clk_dce->dprefclk_ss_percentage, - clk_dce->dprefclk_ss_divider), 200); - struct fixed32_32 adj_dp_ref_clk_khz; - - ss_percentage = dal_fixed32_32_sub(dal_fixed32_32_one, - ss_percentage); - adj_dp_ref_clk_khz = - dal_fixed32_32_mul_int( - ss_percentage, - dp_ref_clk_khz); - dp_ref_clk_khz = dal_fixed32_32_floor(adj_dp_ref_clk_khz); - } + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); - return dp_ref_clk_khz; + return dccg_adjust_dp_ref_freq_for_ss(clk_dce, 600000); } + static enum dm_pp_clocks_state dce_get_required_clocks_state( - struct display_clock *clk, - struct state_dependent_clocks *req_clocks) + struct dccg *clk, + struct dc_clocks *req_clocks) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); int i; enum dm_pp_clocks_state low_req_clk; @@ -286,53 +212,30 @@ static enum dm_pp_clocks_state dce_get_required_clocks_state( * all required clocks */ for (i = clk->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) - if (req_clocks->display_clk_khz > + if (req_clocks->dispclk_khz > clk_dce->max_clks_by_state[i].display_clk_khz - || req_clocks->pixel_clk_khz > + || req_clocks->phyclk_khz > clk_dce->max_clks_by_state[i].pixel_clk_khz) break; low_req_clk = i + 1; if (low_req_clk > clk->max_clks_state) { - DC_LOG_WARNING("%s: clocks unsupported disp_clk %d pix_clk %d", - __func__, - req_clocks->display_clk_khz, - req_clocks->pixel_clk_khz); - low_req_clk = DM_PP_CLOCKS_STATE_INVALID; + /* set max clock state for high phyclock, invalid on exceeding display clock */ + if (clk_dce->max_clks_by_state[clk->max_clks_state].display_clk_khz + < req_clocks->dispclk_khz) + low_req_clk = DM_PP_CLOCKS_STATE_INVALID; + else + low_req_clk = clk->max_clks_state; } return low_req_clk; } -static bool dce_clock_set_min_clocks_state( - struct display_clock *clk, - enum dm_pp_clocks_state clocks_state) -{ - struct dm_pp_power_level_change_request level_change_req = { - clocks_state }; - - if (clocks_state > clk->max_clks_state) { - /*Requested state exceeds max supported state.*/ - DC_LOG_WARNING("Requested state exceeds max supported state"); - return false; - } else if (clocks_state == clk->cur_min_clks_state) { - /*if we're trying to set the same state, we can just return - * since nothing needs to be done*/ - return true; - } - - /* get max clock state from PPLIB */ - if (dm_pp_apply_power_level_change_request(clk->ctx, &level_change_req)) - clk->cur_min_clks_state = clocks_state; - - return true; -} - static int dce_set_clock( - struct display_clock *clk, + struct dccg *clk, int requested_clk_khz) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); struct bp_pixel_clock_parameters pxl_clk_params = { 0 }; struct dc_bios *bp = clk->ctx->dc_bios; int actual_clock = requested_clk_khz; @@ -364,10 +267,10 @@ static int dce_set_clock( } static int dce_psr_set_clock( - struct display_clock *clk, + struct dccg *clk, int requested_clk_khz) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); struct dc_context *ctx = clk_dce->base.ctx; struct dc *core_dc = ctx->dc; struct dmcu *dmcu = core_dc->res_pool->dmcu; @@ -380,10 +283,10 @@ static int dce_psr_set_clock( } static int dce112_set_clock( - struct display_clock *clk, + struct dccg *clk, int requested_clk_khz) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); struct bp_set_dce_clock_parameters dce_clk_params; struct dc_bios *bp = clk->ctx->dc_bios; struct dc *core_dc = clk->ctx->dc; @@ -413,9 +316,12 @@ static int dce112_set_clock( /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ dce_clk_params.target_clock_frequency = 0; dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; - dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = + if (!ASICREV_IS_VEGA20_P(clk->ctx->asic_id.hw_internal_rev)) + dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = (dce_clk_params.pll_id == CLOCK_SOURCE_COMBO_DISPLAY_PLL0); + else + dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = false; bp->funcs->set_dce_clock(bp, &dce_clk_params); @@ -429,7 +335,7 @@ static int dce112_set_clock( return actual_clock; } -static void dce_clock_read_integrated_info(struct dce_disp_clk *clk_dce) +static void dce_clock_read_integrated_info(struct dce_dccg *clk_dce) { struct dc_debug *debug = &clk_dce->base.ctx->dc->debug; struct dc_bios *bp = clk_dce->base.ctx->dc_bios; @@ -485,11 +391,9 @@ static void dce_clock_read_integrated_info(struct dce_disp_clk *clk_dce) if (!debug->disable_dfs_bypass && bp->integrated_info) if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) clk_dce->dfs_bypass_enabled = true; - - clk_dce->use_max_disp_clk = debug->max_disp_clk; } -static void dce_clock_read_ss_info(struct dce_disp_clk *clk_dce) +static void dce_clock_read_ss_info(struct dce_dccg *clk_dce) { struct dc_bios *bp = clk_dce->base.ctx->dc_bios; int ss_info_num = bp->funcs->get_ss_entry_number( @@ -545,139 +449,263 @@ static void dce_clock_read_ss_info(struct dce_disp_clk *clk_dce) } } -static bool dce_apply_clock_voltage_request( - struct display_clock *clk, - enum dm_pp_clock_type clocks_type, - int clocks_in_khz, - bool pre_mode_set, - bool update_dp_phyclk) +static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) +{ + return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); +} + +static void dce12_update_clocks(struct dccg *dccg, + struct dc_clocks *new_clocks, + bool safe_to_lower) { - bool send_request = false; struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; - switch (clocks_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - case DM_PP_CLOCK_TYPE_PIXELCLK: - case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - break; - default: - BREAK_TO_DEBUGGER(); - return false; + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; + clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; + dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } - clock_voltage_req.clk_type = clocks_type; - clock_voltage_req.clocks_in_khz = clocks_in_khz; - - /* to pplib */ - if (pre_mode_set) { - switch (clocks_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - if (clocks_in_khz > clk->cur_clocks_value.dispclk_in_khz) { - clk->cur_clocks_value.dispclk_notify_pplib_done = true; - send_request = true; - } else - clk->cur_clocks_value.dispclk_notify_pplib_done = false; - /* no matter incrase or decrase clock, update current clock value */ - clk->cur_clocks_value.dispclk_in_khz = clocks_in_khz; - break; - case DM_PP_CLOCK_TYPE_PIXELCLK: - if (clocks_in_khz > clk->cur_clocks_value.max_pixelclk_in_khz) { - clk->cur_clocks_value.pixelclk_notify_pplib_done = true; - send_request = true; - } else - clk->cur_clocks_value.pixelclk_notify_pplib_done = false; - /* no matter incrase or decrase clock, update current clock value */ - clk->cur_clocks_value.max_pixelclk_in_khz = clocks_in_khz; - break; - case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - if (clocks_in_khz > clk->cur_clocks_value.max_non_dp_phyclk_in_khz) { - clk->cur_clocks_value.phyclk_notigy_pplib_done = true; - send_request = true; - } else - clk->cur_clocks_value.phyclk_notigy_pplib_done = false; - /* no matter incrase or decrase clock, update current clock value */ - clk->cur_clocks_value.max_non_dp_phyclk_in_khz = clocks_in_khz; - break; - default: - ASSERT(0); - break; - } + if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; + clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; + dccg->clks.phyclk_khz = new_clocks->phyclk_khz; + + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + } +} + +#ifdef CONFIG_X86 +static int dcn1_determine_dppclk_threshold(struct dccg *dccg, struct dc_clocks *new_clocks) +{ + bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; + bool dispclk_increase = new_clocks->dispclk_khz > dccg->clks.dispclk_khz; + int disp_clk_threshold = new_clocks->max_supported_dppclk_khz; + bool cur_dpp_div = dccg->clks.dispclk_khz > dccg->clks.dppclk_khz; + + /* increase clock, looking for div is 0 for current, request div is 1*/ + if (dispclk_increase) { + /* already divided by 2, no need to reach target clk with 2 steps*/ + if (cur_dpp_div) + return new_clocks->dispclk_khz; + + /* request disp clk is lower than maximum supported dpp clk, + * no need to reach target clk with two steps. + */ + if (new_clocks->dispclk_khz <= disp_clk_threshold) + return new_clocks->dispclk_khz; + + /* target dpp clk not request divided by 2, still within threshold */ + if (!request_dpp_div) + return new_clocks->dispclk_khz; } else { - switch (clocks_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - if (!clk->cur_clocks_value.dispclk_notify_pplib_done) - send_request = true; - break; - case DM_PP_CLOCK_TYPE_PIXELCLK: - if (!clk->cur_clocks_value.pixelclk_notify_pplib_done) - send_request = true; - break; - case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - if (!clk->cur_clocks_value.phyclk_notigy_pplib_done) - send_request = true; - break; - default: - ASSERT(0); - break; - } + /* decrease clock, looking for current dppclk divided by 2, + * request dppclk not divided by 2. + */ + + /* current dpp clk not divided by 2, no need to ramp*/ + if (!cur_dpp_div) + return new_clocks->dispclk_khz; + + /* current disp clk is lower than current maximum dpp clk, + * no need to ramp + */ + if (dccg->clks.dispclk_khz <= disp_clk_threshold) + return new_clocks->dispclk_khz; + + /* request dpp clk need to be divided by 2 */ + if (request_dpp_div) + return new_clocks->dispclk_khz; } - if (send_request) { -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (clk->ctx->dce_version >= DCN_VERSION_1_0) { - struct dc *core_dc = clk->ctx->dc; - /*use dcfclk request voltage*/ - clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; - clock_voltage_req.clocks_in_khz = - dcn_find_dcfclk_suits_all(core_dc, &clk->cur_clocks_value); - } + + return disp_clk_threshold; +} + +static void dcn1_ramp_up_dispclk_with_dpp(struct dccg *dccg, struct dc_clocks *new_clocks) +{ + struct dc *dc = dccg->ctx->dc; + int dispclk_to_dpp_threshold = dcn1_determine_dppclk_threshold(dccg, new_clocks); + bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; + int i; + + /* set disp clk to dpp clk threshold */ + dccg->funcs->set_dispclk(dccg, dispclk_to_dpp_threshold); + + /* update request dpp clk division option */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + + if (!pipe_ctx->plane_state) + continue; + + pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control( + pipe_ctx->plane_res.dpp, + request_dpp_div, + true); + } + + /* If target clk not same as dppclk threshold, set to target clock */ + if (dispclk_to_dpp_threshold != new_clocks->dispclk_khz) + dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + dccg->clks.dppclk_khz = new_clocks->dppclk_khz; + dccg->clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; +} + +static void dcn1_update_clocks(struct dccg *dccg, + struct dc_clocks *new_clocks, + bool safe_to_lower) +{ + struct dc *dc = dccg->ctx->dc; + struct pp_smu_display_requirement_rv *smu_req_cur = + &dc->res_pool->pp_smu_req; + struct pp_smu_display_requirement_rv smu_req = *smu_req_cur; + struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu; + struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; + bool send_request_to_increase = false; + bool send_request_to_lower = false; + + if (new_clocks->phyclk_khz) + smu_req.display_count = 1; + else + smu_req.display_count = 0; + + if (new_clocks->dispclk_khz > dccg->clks.dispclk_khz + || new_clocks->phyclk_khz > dccg->clks.phyclk_khz + || new_clocks->fclk_khz > dccg->clks.fclk_khz + || new_clocks->dcfclk_khz > dccg->clks.dcfclk_khz) + send_request_to_increase = true; + + if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { + dccg->clks.phyclk_khz = new_clocks->phyclk_khz; + + send_request_to_lower = true; + } + + if (should_set_clock(safe_to_lower, new_clocks->fclk_khz, dccg->clks.fclk_khz)) { + dccg->clks.fclk_khz = new_clocks->fclk_khz; + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_FCLK; + clock_voltage_req.clocks_in_khz = new_clocks->fclk_khz; + smu_req.hard_min_fclk_khz = new_clocks->fclk_khz; + + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + send_request_to_lower = true; + } + + if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, dccg->clks.dcfclk_khz)) { + dccg->clks.dcfclk_khz = new_clocks->dcfclk_khz; + smu_req.hard_min_dcefclk_khz = new_clocks->dcfclk_khz; + + send_request_to_lower = true; + } + + if (should_set_clock(safe_to_lower, + new_clocks->dcfclk_deep_sleep_khz, dccg->clks.dcfclk_deep_sleep_khz)) { + dccg->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; + smu_req.min_deep_sleep_dcefclk_mhz = new_clocks->dcfclk_deep_sleep_khz; + + send_request_to_lower = true; + } + + /* make sure dcf clk is before dpp clk to + * make sure we have enough voltage to run dpp clk + */ + if (send_request_to_increase) { + /*use dcfclk to request voltage*/ + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + if (pp_smu->set_display_requirement) + pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); + } + + /* dcn1 dppclk is tied to dispclk */ + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { + dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + + send_request_to_lower = true; + } + + if (!send_request_to_increase && send_request_to_lower) { + /*use dcfclk to request voltage*/ + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + if (pp_smu->set_display_requirement) + pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); + } + + + *smu_req_cur = smu_req; +} #endif - dm_pp_apply_clock_for_voltage_request( - clk->ctx, &clock_voltage_req); + +static void dce_update_clocks(struct dccg *dccg, + struct dc_clocks *new_clocks, + bool safe_to_lower) +{ + struct dm_pp_power_level_change_request level_change_req; + + level_change_req.power_level = dce_get_required_clocks_state(dccg, new_clocks); + /* get max clock state from PPLIB */ + if ((level_change_req.power_level < dccg->cur_min_clks_state && safe_to_lower) + || level_change_req.power_level > dccg->cur_min_clks_state) { + if (dm_pp_apply_power_level_change_request(dccg->ctx, &level_change_req)) + dccg->cur_min_clks_state = level_change_req.power_level; } - if (update_dp_phyclk && (clocks_in_khz > - clk->cur_clocks_value.max_dp_phyclk_in_khz)) - clk->cur_clocks_value.max_dp_phyclk_in_khz = clocks_in_khz; - return true; + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { + dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + } } +#ifdef CONFIG_X86 +static const struct display_clock_funcs dcn1_funcs = { + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .set_dispclk = dce112_set_clock, + .update_clocks = dcn1_update_clocks +}; +#endif static const struct display_clock_funcs dce120_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq_wrkaround, - .apply_clock_voltage_request = dce_apply_clock_voltage_request, - .set_clock = dce112_set_clock + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .set_dispclk = dce112_set_clock, + .update_clocks = dce12_update_clocks }; static const struct display_clock_funcs dce112_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, - .get_required_clocks_state = dce_get_required_clocks_state, - .set_min_clocks_state = dce_clock_set_min_clocks_state, - .set_clock = dce112_set_clock + .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, + .set_dispclk = dce112_set_clock, + .update_clocks = dce_update_clocks }; static const struct display_clock_funcs dce110_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, - .get_required_clocks_state = dce_get_required_clocks_state, - .set_min_clocks_state = dce_clock_set_min_clocks_state, - .set_clock = dce_psr_set_clock + .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, + .set_dispclk = dce_psr_set_clock, + .update_clocks = dce_update_clocks }; static const struct display_clock_funcs dce_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, - .get_required_clocks_state = dce_get_required_clocks_state, - .set_min_clocks_state = dce_clock_set_min_clocks_state, - .set_clock = dce_set_clock + .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, + .set_dispclk = dce_set_clock, + .update_clocks = dce_update_clocks }; -static void dce_disp_clk_construct( - struct dce_disp_clk *clk_dce, +static void dce_dccg_construct( + struct dce_dccg *clk_dce, struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { - struct display_clock *base = &clk_dce->base; + struct dccg *base = &clk_dce->base; base->ctx = ctx; base->funcs = &dce_funcs; @@ -697,34 +725,15 @@ static void dce_disp_clk_construct( dce_clock_read_integrated_info(clk_dce); dce_clock_read_ss_info(clk_dce); - - dce_divider_range_construct( - &clk_dce->divider_ranges[DIVIDER_RANGE_01], - DIVIDER_RANGE_01_START, - DIVIDER_RANGE_01_STEP_SIZE, - DIVIDER_RANGE_01_BASE_DIVIDER_ID, - DIVIDER_RANGE_02_BASE_DIVIDER_ID); - dce_divider_range_construct( - &clk_dce->divider_ranges[DIVIDER_RANGE_02], - DIVIDER_RANGE_02_START, - DIVIDER_RANGE_02_STEP_SIZE, - DIVIDER_RANGE_02_BASE_DIVIDER_ID, - DIVIDER_RANGE_03_BASE_DIVIDER_ID); - dce_divider_range_construct( - &clk_dce->divider_ranges[DIVIDER_RANGE_03], - DIVIDER_RANGE_03_START, - DIVIDER_RANGE_03_STEP_SIZE, - DIVIDER_RANGE_03_BASE_DIVIDER_ID, - DIVIDER_RANGE_MAX_DIVIDER_ID); } -struct display_clock *dce_disp_clk_create( +struct dccg *dce_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -735,19 +744,19 @@ struct display_clock *dce_disp_clk_create( dce80_max_clks_by_state, sizeof(dce80_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, regs, clk_shift, clk_mask); return &clk_dce->base; } -struct display_clock *dce110_disp_clk_create( +struct dccg *dce110_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -758,7 +767,7 @@ struct display_clock *dce110_disp_clk_create( dce110_max_clks_by_state, sizeof(dce110_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, regs, clk_shift, clk_mask); clk_dce->base.funcs = &dce110_funcs; @@ -766,13 +775,13 @@ struct display_clock *dce110_disp_clk_create( return &clk_dce->base; } -struct display_clock *dce112_disp_clk_create( +struct dccg *dce112_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -783,7 +792,7 @@ struct display_clock *dce112_disp_clk_create( dce112_max_clks_by_state, sizeof(dce112_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, regs, clk_shift, clk_mask); clk_dce->base.funcs = &dce112_funcs; @@ -791,10 +800,9 @@ struct display_clock *dce112_disp_clk_create( return &clk_dce->base; } -struct display_clock *dce120_disp_clk_create(struct dc_context *ctx) +struct dccg *dce120_dccg_create(struct dc_context *ctx) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); - struct dm_pp_clock_levels_with_voltage clk_level_info = {0}; + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -805,28 +813,59 @@ struct display_clock *dce120_disp_clk_create(struct dc_context *ctx) dce120_max_clks_by_state, sizeof(dce120_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, NULL, NULL, NULL); clk_dce->base.funcs = &dce120_funcs; - /* new in dce120 */ - if (!ctx->dc->debug.disable_pplib_clock_request && - dm_pp_get_clock_levels_by_type_with_voltage( - ctx, DM_PP_CLOCK_TYPE_DISPLAY_CLK, &clk_level_info) - && clk_level_info.num_levels) - clk_dce->max_displ_clk_in_khz = - clk_level_info.data[clk_level_info.num_levels - 1].clocks_in_khz; - else - clk_dce->max_displ_clk_in_khz = 1133000; + return &clk_dce->base; +} + +#ifdef CONFIG_X86 +struct dccg *dcn1_dccg_create(struct dc_context *ctx) +{ + struct dc_debug *debug = &ctx->dc->debug; + struct dc_bios *bp = ctx->dc_bios; + struct dc_firmware_info fw_info = { { 0 } }; + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + + if (clk_dce == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } + + clk_dce->base.ctx = ctx; + clk_dce->base.funcs = &dcn1_funcs; + + clk_dce->dfs_bypass_disp_clk = 0; + + clk_dce->dprefclk_ss_percentage = 0; + clk_dce->dprefclk_ss_divider = 1000; + clk_dce->ss_on_dprefclk = false; + + if (bp->integrated_info) + clk_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq; + if (clk_dce->dentist_vco_freq_khz == 0) { + bp->funcs->get_firmware_info(bp, &fw_info); + clk_dce->dentist_vco_freq_khz = fw_info.smu_gpu_pll_output_freq; + if (clk_dce->dentist_vco_freq_khz == 0) + clk_dce->dentist_vco_freq_khz = 3600000; + } + + if (!debug->disable_dfs_bypass && bp->integrated_info) + if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) + clk_dce->dfs_bypass_enabled = true; + + dce_clock_read_ss_info(clk_dce); return &clk_dce->base; } +#endif -void dce_disp_clk_destroy(struct display_clock **disp_clk) +void dce_dccg_destroy(struct dccg **dccg) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(*disp_clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(*dccg); kfree(clk_dce); - *disp_clk = NULL; + *dccg = NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index 0e717e0dc8f0..e5e44adc6c27 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -33,6 +33,9 @@ .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ .DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL +#define CLK_COMMON_REG_LIST_DCN_BASE() \ + SR(DENTIST_DISPCLK_CNTL) + #define CLK_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -40,58 +43,37 @@ CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh) +#define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) + #define CLK_REG_FIELD_LIST(type) \ type DPREFCLK_SRC_SEL; \ - type DENTIST_DPREFCLK_WDIVIDER; + type DENTIST_DPREFCLK_WDIVIDER; \ + type DENTIST_DISPCLK_WDIVIDER; \ + type DENTIST_DISPCLK_CHG_DONE; -struct dce_disp_clk_shift { +struct dccg_shift { CLK_REG_FIELD_LIST(uint8_t) }; -struct dce_disp_clk_mask { +struct dccg_mask { CLK_REG_FIELD_LIST(uint32_t) }; -struct dce_disp_clk_registers { +struct dccg_registers { uint32_t DPREFCLK_CNTL; uint32_t DENTIST_DISPCLK_CNTL; }; -/* Array identifiers and count for the divider ranges.*/ -enum dce_divider_range_count { - DIVIDER_RANGE_01 = 0, - DIVIDER_RANGE_02, - DIVIDER_RANGE_03, - DIVIDER_RANGE_MAX /* == 3*/ -}; - -enum dce_divider_error_types { - INVALID_DID = 0, - INVALID_DIVIDER = 1 -}; - -struct dce_divider_range { - int div_range_start; - /* The end of this range of dividers.*/ - int div_range_end; - /* The distance between each divider in this range.*/ - int div_range_step; - /* The divider id for the lowest divider.*/ - int did_min; - /* The divider id for the highest divider.*/ - int did_max; -}; - -struct dce_disp_clk { - struct display_clock base; - const struct dce_disp_clk_registers *regs; - const struct dce_disp_clk_shift *clk_shift; - const struct dce_disp_clk_mask *clk_mask; +struct dce_dccg { + struct dccg base; + const struct dccg_registers *regs; + const struct dccg_shift *clk_shift; + const struct dccg_mask *clk_mask; struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; - struct dce_divider_range divider_ranges[DIVIDER_RANGE_MAX]; - bool use_max_disp_clk; int dentist_vco_freq_khz; /* Cache the status of DFS-bypass feature*/ @@ -106,32 +88,33 @@ struct dce_disp_clk { int dprefclk_ss_percentage; /* DPREFCLK SS percentage Divider (100 or 1000) */ int dprefclk_ss_divider; - - /* max disp_clk from PPLIB for max validation display clock*/ - int max_displ_clk_in_khz; }; -struct display_clock *dce_disp_clk_create( +struct dccg *dce_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask); + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask); -struct display_clock *dce110_disp_clk_create( +struct dccg *dce110_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask); + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask); -struct display_clock *dce112_disp_clk_create( +struct dccg *dce112_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask); + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask); + +struct dccg *dce120_dccg_create(struct dc_context *ctx); -struct display_clock *dce120_disp_clk_create(struct dc_context *ctx); +#ifdef CONFIG_X86 +struct dccg *dcn1_dccg_create(struct dc_context *ctx); +#endif -void dce_disp_clk_destroy(struct display_clock **disp_clk); +void dce_dccg_destroy(struct dccg **dccg); #endif /* _DCE_CLOCKS_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index 2ee3d9bf1062..062a46543887 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -28,7 +28,7 @@ #include "dce_dmcu.h" #include "dm_services.h" #include "reg_helper.h" -#include "fixed32_32.h" +#include "fixed31_32.h" #include "dc.h" #define TO_DCE_DMCU(dmcu)\ @@ -314,7 +314,7 @@ static void dce_get_psr_wait_loop( return; } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 static void dcn10_get_dmcu_state(struct dmcu *dmcu) { struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); @@ -735,7 +735,7 @@ static const struct dmcu_funcs dce_funcs = { .is_dmcu_initialized = dce_is_dmcu_initialized }; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 static const struct dmcu_funcs dcn10_funcs = { .dmcu_init = dcn10_dmcu_init, .load_iram = dcn10_dmcu_load_iram, @@ -787,7 +787,7 @@ struct dmcu *dce_dmcu_create( return &dmcu_dce->base; } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 struct dmcu *dcn10_dmcu_create( struct dc_context *ctx, const struct dce_dmcu_registers *regs, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c index 487724345d9d..0275d6d60da4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c @@ -53,7 +53,8 @@ void dce_pipe_control_lock(struct dc *dc, struct dce_hwseq *hws = dc->hwseq; /* Not lock pipe when blank */ - if (lock && pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg)) + if (lock && pipe->stream_res.tg->funcs->is_blanked && + pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg)) return; val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 057b8afd74bc..64dc75378541 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -147,6 +147,7 @@ SR(DCCG_GATE_DISABLE_CNTL2), \ SR(DCFCLK_CNTL),\ SR(DCFCLK_CNTL), \ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ /* todo: get these from GVM instead of reading registers ourselves */\ MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\ MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\ @@ -249,7 +250,6 @@ struct dce_hwseq_registers { uint32_t DISPCLK_FREQ_CHANGE_CNTL; uint32_t RBBMIF_TIMEOUT_DIS; uint32_t RBBMIF_TIMEOUT_DIS_2; - uint32_t DENTIST_DISPCLK_CNTL; uint32_t DCHUBBUB_CRC_CTRL; uint32_t DPP_TOP0_DPP_CRC_CTRL; uint32_t DPP_TOP0_DPP_CRC_VAL_R_G; @@ -276,6 +276,8 @@ struct dce_hwseq_registers { uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB; uint32_t MC_VM_SYSTEM_APERTURE_LOW_ADDR; uint32_t MC_VM_SYSTEM_APERTURE_HIGH_ADDR; + uint32_t AZALIA_AUDIO_DTO; + uint32_t AZALIA_CONTROLLER_CLOCK_GATING; }; /* set field name */ #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ @@ -362,7 +364,8 @@ struct dce_hwseq_registers { HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh), \ HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ - HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh) + HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh), \ + HWS_SF(, DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh) #define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\ HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ @@ -496,14 +499,13 @@ struct dce_hwseq_registers { type DOMAIN7_PGFSM_PWR_STATUS; \ type DCFCLK_GATE_DIS; \ type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ - type DENTIST_DPPCLK_WDIVIDER; \ - type DENTIST_DISPCLK_WDIVIDER; \ type VGA_TEST_ENABLE; \ type VGA_TEST_RENDER_START; \ type D1VGA_MODE_ENABLE; \ type D2VGA_MODE_ENABLE; \ type D3VGA_MODE_ENABLE; \ - type D4VGA_MODE_ENABLE; + type D4VGA_MODE_ENABLE; \ + type AZALIA_AUDIO_DTO_MODULE; struct dce_hwseq_shift { HWSEQ_REG_FIELD_LIST(uint8_t) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c index d737e911971b..5d9506b3d46b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c @@ -195,13 +195,13 @@ static void dce_ipp_program_input_lut( for (i = 0; i < gamma->num_entries; i++) { REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR, - dal_fixed31_32_round( + dc_fixpt_round( gamma->entries.red[i])); REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR, - dal_fixed31_32_round( + dc_fixpt_round( gamma->entries.green[i])); REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR, - dal_fixed31_32_round( + dc_fixpt_round( gamma->entries.blue[i])); } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 8167cad7bcf7..60e3c6a73d37 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -113,6 +113,7 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, .enable_hpd = dce110_link_encoder_enable_hpd, .disable_hpd = dce110_link_encoder_disable_hpd, + .is_dig_enabled = dce110_is_dig_enabled, .destroy = dce110_link_encoder_destroy }; @@ -535,8 +536,9 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc, DP_SEC_GSP0_PRIORITY, 1); } -static bool is_dig_enabled(const struct dce110_link_encoder *enc110) +bool dce110_is_dig_enabled(struct link_encoder *enc) { + struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); uint32_t value; REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value); @@ -644,6 +646,9 @@ static bool dce110_link_encoder_validate_hdmi_output( if (!enc110->base.features.flags.bits.HDMI_6GB_EN && adjusted_pix_clk_khz >= 300000) return false; + if (enc110->base.ctx->dc->debug.hdmi20_disable && + crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + return false; return true; } @@ -771,6 +776,9 @@ void dce110_link_encoder_construct( __func__, result); } + if (enc110->base.ctx->dc->debug.hdmi20_disable) { + enc110->base.features.flags.bits.HDMI_6GB_EN = 0; + } } bool dce110_link_encoder_validate_output_with_stream( @@ -1031,7 +1039,7 @@ void dce110_link_encoder_disable_output( struct bp_transmitter_control cntl = { 0 }; enum bp_result result; - if (!is_dig_enabled(enc110)) { + if (!dce110_is_dig_enabled(enc)) { /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */ return; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index 0ec3433d34b6..347069461a22 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -263,4 +263,6 @@ void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc, void dce110_psr_program_secondary_packet(struct link_encoder *enc, unsigned int sdp_transmit_line_num_deadline); +bool dce110_is_dig_enabled(struct link_encoder *enc); + #endif /* __DC_LINK_ENCODER__DCE110_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index 0790f25c7b3b..85686d917636 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c @@ -174,6 +174,25 @@ static void program_urgency_watermark( URGENCY_HIGH_WATERMARK, urgency_high_wm); } +static void dce120_program_urgency_watermark( + struct dce_mem_input *dce_mi, + uint32_t wm_select, + uint32_t urgency_low_wm, + uint32_t urgency_high_wm) +{ + REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, + URGENCY_WATERMARK_MASK, wm_select); + + REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0, + URGENCY_LOW_WATERMARK, urgency_low_wm, + URGENCY_HIGH_WATERMARK, urgency_high_wm); + + REG_SET_2(DPG_PIPE_URGENT_LEVEL_CONTROL, 0, + URGENT_LEVEL_LOW_WATERMARK, urgency_low_wm, + URGENT_LEVEL_HIGH_WATERMARK, urgency_high_wm); + +} + static void program_nbp_watermark( struct dce_mem_input *dce_mi, uint32_t wm_select, @@ -206,6 +225,25 @@ static void program_nbp_watermark( } } +static void dce120_program_stutter_watermark( + struct dce_mem_input *dce_mi, + uint32_t wm_select, + uint32_t stutter_mark, + uint32_t stutter_entry) +{ + REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, + STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select); + + if (REG(DPG_PIPE_STUTTER_CONTROL2)) + REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL2, + STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark, + STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry); + else + REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL, + STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark, + STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry); +} + static void program_stutter_watermark( struct dce_mem_input *dce_mi, uint32_t wm_select, @@ -225,7 +263,8 @@ static void program_stutter_watermark( static void dce_mi_program_display_marks( struct mem_input *mi, struct dce_watermarks nbp, - struct dce_watermarks stutter, + struct dce_watermarks stutter_exit, + struct dce_watermarks stutter_enter, struct dce_watermarks urgent, uint32_t total_dest_line_time_ns) { @@ -243,13 +282,14 @@ static void dce_mi_program_display_marks( program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */ program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */ - program_stutter_watermark(dce_mi, 2, stutter.a_mark); /* set a */ - program_stutter_watermark(dce_mi, 1, stutter.d_mark); /* set d */ + program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */ + program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */ } -static void dce120_mi_program_display_marks(struct mem_input *mi, +static void dce112_mi_program_display_marks(struct mem_input *mi, struct dce_watermarks nbp, - struct dce_watermarks stutter, + struct dce_watermarks stutter_exit, + struct dce_watermarks stutter_entry, struct dce_watermarks urgent, uint32_t total_dest_line_time_ns) { @@ -273,10 +313,43 @@ static void dce120_mi_program_display_marks(struct mem_input *mi, program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */ program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */ - program_stutter_watermark(dce_mi, 0, stutter.a_mark); /* set a */ - program_stutter_watermark(dce_mi, 1, stutter.b_mark); /* set b */ - program_stutter_watermark(dce_mi, 2, stutter.c_mark); /* set c */ - program_stutter_watermark(dce_mi, 3, stutter.d_mark); /* set d */ + program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark); /* set a */ + program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark); /* set b */ + program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark); /* set c */ + program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark); /* set d */ +} + +static void dce120_mi_program_display_marks(struct mem_input *mi, + struct dce_watermarks nbp, + struct dce_watermarks stutter_exit, + struct dce_watermarks stutter_entry, + struct dce_watermarks urgent, + uint32_t total_dest_line_time_ns) +{ + struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); + uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1; + + dce120_program_urgency_watermark(dce_mi, 0, /* set a */ + urgent.a_mark, total_dest_line_time_ns); + dce120_program_urgency_watermark(dce_mi, 1, /* set b */ + urgent.b_mark, total_dest_line_time_ns); + dce120_program_urgency_watermark(dce_mi, 2, /* set c */ + urgent.c_mark, total_dest_line_time_ns); + dce120_program_urgency_watermark(dce_mi, 3, /* set d */ + urgent.d_mark, total_dest_line_time_ns); + + REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL, + STUTTER_ENABLE, stutter_en, + STUTTER_IGNORE_FBC, 1); + program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */ + program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */ + program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */ + program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */ + + dce120_program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark, stutter_entry.a_mark); /* set a */ + dce120_program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark, stutter_entry.b_mark); /* set b */ + dce120_program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark, stutter_entry.c_mark); /* set c */ + dce120_program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark, stutter_entry.d_mark); /* set d */ } static void program_tiling( @@ -656,7 +729,7 @@ static bool dce_mi_program_surface_flip_and_addr( return true; } -static struct mem_input_funcs dce_mi_funcs = { +static const struct mem_input_funcs dce_mi_funcs = { .mem_input_program_display_marks = dce_mi_program_display_marks, .allocate_mem_input = dce_mi_allocate_dmif, .free_mem_input = dce_mi_free_dmif, @@ -668,6 +741,29 @@ static struct mem_input_funcs dce_mi_funcs = { .mem_input_is_flip_pending = dce_mi_is_flip_pending }; +static const struct mem_input_funcs dce112_mi_funcs = { + .mem_input_program_display_marks = dce112_mi_program_display_marks, + .allocate_mem_input = dce_mi_allocate_dmif, + .free_mem_input = dce_mi_free_dmif, + .mem_input_program_surface_flip_and_addr = + dce_mi_program_surface_flip_and_addr, + .mem_input_program_pte_vm = dce_mi_program_pte_vm, + .mem_input_program_surface_config = + dce_mi_program_surface_config, + .mem_input_is_flip_pending = dce_mi_is_flip_pending +}; + +static const struct mem_input_funcs dce120_mi_funcs = { + .mem_input_program_display_marks = dce120_mi_program_display_marks, + .allocate_mem_input = dce_mi_allocate_dmif, + .free_mem_input = dce_mi_free_dmif, + .mem_input_program_surface_flip_and_addr = + dce_mi_program_surface_flip_and_addr, + .mem_input_program_pte_vm = dce_mi_program_pte_vm, + .mem_input_program_surface_config = + dce_mi_program_surface_config, + .mem_input_is_flip_pending = dce_mi_is_flip_pending +}; void dce_mem_input_construct( struct dce_mem_input *dce_mi, @@ -696,5 +792,17 @@ void dce112_mem_input_construct( const struct dce_mem_input_mask *mi_mask) { dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); - dce_mi->base.funcs->mem_input_program_display_marks = dce120_mi_program_display_marks; + dce_mi->base.funcs = &dce112_mi_funcs; +} + +void dce120_mem_input_construct( + struct dce_mem_input *dce_mi, + struct dc_context *ctx, + int inst, + const struct dce_mem_input_registers *regs, + const struct dce_mem_input_shift *mi_shift, + const struct dce_mem_input_mask *mi_mask) +{ + dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); + dce_mi->base.funcs = &dce120_mi_funcs; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h index 05d39c0cbe87..d15b0d7f47fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h @@ -106,6 +106,7 @@ struct dce_mem_input_registers { uint32_t DPG_PIPE_ARBITRATION_CONTROL1; uint32_t DPG_WATERMARK_MASK_CONTROL; uint32_t DPG_PIPE_URGENCY_CONTROL; + uint32_t DPG_PIPE_URGENT_LEVEL_CONTROL; uint32_t DPG_PIPE_NB_PSTATE_CHANGE_CONTROL; uint32_t DPG_PIPE_LOW_POWER_CONTROL; uint32_t DPG_PIPE_STUTTER_CONTROL; @@ -213,6 +214,11 @@ struct dce_mem_input_registers { #define MI_DCE12_DMIF_PG_MASK_SH_LIST(mask_sh, blk)\ SFB(blk, DPG_PIPE_STUTTER_CONTROL2, STUTTER_EXIT_SELF_REFRESH_WATERMARK, mask_sh),\ + SFB(blk, DPG_PIPE_STUTTER_CONTROL2, STUTTER_ENTER_SELF_REFRESH_WATERMARK, mask_sh),\ + SFB(blk, DPG_PIPE_URGENT_LEVEL_CONTROL, URGENT_LEVEL_LOW_WATERMARK, mask_sh),\ + SFB(blk, DPG_PIPE_URGENT_LEVEL_CONTROL, URGENT_LEVEL_HIGH_WATERMARK, mask_sh),\ + SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_LOW_WATERMARK, mask_sh),\ + SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_HIGH_WATERMARK, mask_sh),\ SFB(blk, DPG_WATERMARK_MASK_CONTROL, PSTATE_CHANGE_WATERMARK_MASK, mask_sh),\ SFB(blk, DPG_PIPE_LOW_POWER_CONTROL, PSTATE_CHANGE_ENABLE, mask_sh),\ SFB(blk, DPG_PIPE_LOW_POWER_CONTROL, PSTATE_CHANGE_URGENT_DURING_REQUEST, mask_sh),\ @@ -286,6 +292,8 @@ struct dce_mem_input_registers { type STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK; \ type URGENCY_LOW_WATERMARK; \ type URGENCY_HIGH_WATERMARK; \ + type URGENT_LEVEL_LOW_WATERMARK;\ + type URGENT_LEVEL_HIGH_WATERMARK;\ type NB_PSTATE_CHANGE_ENABLE; \ type NB_PSTATE_CHANGE_URGENT_DURING_REQUEST; \ type NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \ @@ -297,6 +305,7 @@ struct dce_mem_input_registers { type STUTTER_ENABLE; \ type STUTTER_IGNORE_FBC; \ type STUTTER_EXIT_SELF_REFRESH_WATERMARK; \ + type STUTTER_ENTER_SELF_REFRESH_WATERMARK; \ type DMIF_BUFFERS_ALLOCATED; \ type DMIF_BUFFERS_ALLOCATION_COMPLETED; \ type ENABLE; /* MC_HUB_RDREQ_DMIF_LIMIT */\ @@ -344,4 +353,12 @@ void dce112_mem_input_construct( const struct dce_mem_input_shift *mi_shift, const struct dce_mem_input_mask *mi_mask); +void dce120_mem_input_construct( + struct dce_mem_input *dce_mi, + struct dc_context *ctx, + int inst, + const struct dce_mem_input_registers *regs, + const struct dce_mem_input_shift *mi_shift, + const struct dce_mem_input_mask *mi_mask); + #endif /*__DCE_MEM_INPUT_H__*/ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c b/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c index 6243450b41b7..48862bebf29e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c @@ -1014,11 +1014,11 @@ static const uint16_t filter_8tap_64p_183[264] = { const uint16_t *get_filter_3tap_16p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_3tap_16p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_3tap_16p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_3tap_16p_150; else return filter_3tap_16p_183; @@ -1026,11 +1026,11 @@ const uint16_t *get_filter_3tap_16p(struct fixed31_32 ratio) const uint16_t *get_filter_3tap_64p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_3tap_64p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_3tap_64p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_3tap_64p_150; else return filter_3tap_64p_183; @@ -1038,11 +1038,11 @@ const uint16_t *get_filter_3tap_64p(struct fixed31_32 ratio) const uint16_t *get_filter_4tap_16p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_4tap_16p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_4tap_16p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_4tap_16p_150; else return filter_4tap_16p_183; @@ -1050,11 +1050,11 @@ const uint16_t *get_filter_4tap_16p(struct fixed31_32 ratio) const uint16_t *get_filter_4tap_64p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_4tap_64p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_4tap_64p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_4tap_64p_150; else return filter_4tap_64p_183; @@ -1062,11 +1062,11 @@ const uint16_t *get_filter_4tap_64p(struct fixed31_32 ratio) const uint16_t *get_filter_5tap_64p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_5tap_64p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_5tap_64p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_5tap_64p_150; else return filter_5tap_64p_183; @@ -1074,11 +1074,11 @@ const uint16_t *get_filter_5tap_64p(struct fixed31_32 ratio) const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_6tap_64p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_6tap_64p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_6tap_64p_150; else return filter_6tap_64p_183; @@ -1086,11 +1086,11 @@ const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio) const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_7tap_64p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_7tap_64p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_7tap_64p_150; else return filter_7tap_64p_183; @@ -1098,11 +1098,11 @@ const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio) const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio) { - if (ratio.value < dal_fixed31_32_one.value) + if (ratio.value < dc_fixpt_one.value) return filter_8tap_64p_upscale; - else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(4, 3).value) return filter_8tap_64p_117; - else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) + else if (ratio.value < dc_fixpt_from_fraction(5, 3).value) return filter_8tap_64p_150; else return filter_8tap_64p_183; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 162f6a6c4208..b139b4017820 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -26,27 +26,10 @@ #include "dc_bios_types.h" #include "dce_stream_encoder.h" #include "reg_helper.h" +#include "hw_shared.h" + #define DC_LOGGER \ enc110->base.ctx->logger -enum DP_PIXEL_ENCODING { -DP_PIXEL_ENCODING_RGB444 = 0x00000000, -DP_PIXEL_ENCODING_YCBCR422 = 0x00000001, -DP_PIXEL_ENCODING_YCBCR444 = 0x00000002, -DP_PIXEL_ENCODING_RGB_WIDE_GAMUT = 0x00000003, -DP_PIXEL_ENCODING_Y_ONLY = 0x00000004, -DP_PIXEL_ENCODING_YCBCR420 = 0x00000005, -DP_PIXEL_ENCODING_RESERVED = 0x00000006, -}; - - -enum DP_COMPONENT_DEPTH { -DP_COMPONENT_DEPTH_6BPC = 0x00000000, -DP_COMPONENT_DEPTH_8BPC = 0x00000001, -DP_COMPONENT_DEPTH_10BPC = 0x00000002, -DP_COMPONENT_DEPTH_12BPC = 0x00000003, -DP_COMPONENT_DEPTH_16BPC = 0x00000004, -DP_COMPONENT_DEPTH_RESERVED = 0x00000005, -}; #define REG(reg)\ @@ -80,7 +63,7 @@ enum { static void dce110_update_generic_info_packet( struct dce110_stream_encoder *enc110, uint32_t packet_index, - const struct encoder_info_packet *info_packet) + const struct dc_info_packet *info_packet) { uint32_t regval; /* TODOFPGA Figure out a proper number for max_retries polling for lock @@ -89,7 +72,8 @@ static void dce110_update_generic_info_packet( uint32_t max_retries = 50; /*we need turn on clock before programming AFMT block*/ - REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); + if (REG(AFMT_CNTL)) + REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); if (REG(AFMT_VBI_PACKET_CONTROL1)) { if (packet_index >= 8) @@ -151,7 +135,7 @@ static void dce110_update_generic_info_packet( AFMT_GENERIC0_UPDATE, (packet_index == 0), AFMT_GENERIC2_UPDATE, (packet_index == 2)); } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (REG(AFMT_VBI_PACKET_CONTROL1)) { switch (packet_index) { case 0: @@ -196,7 +180,7 @@ static void dce110_update_generic_info_packet( static void dce110_update_hdmi_info_packet( struct dce110_stream_encoder *enc110, uint32_t packet_index, - const struct encoder_info_packet *info_packet) + const struct dc_info_packet *info_packet) { uint32_t cont, send, line; @@ -245,7 +229,7 @@ static void dce110_update_hdmi_info_packet( HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case 4: if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, @@ -290,7 +274,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( struct dc_crtc_timing *crtc_timing, enum dc_color_space output_color_space) { -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 uint32_t h_active_start; uint32_t v_active_start; uint32_t misc0 = 0; @@ -305,20 +289,15 @@ static void dce110_stream_encoder_dp_set_stream_attribute( struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (REG(DP_DB_CNTL)) - REG_UPDATE(DP_DB_CNTL, DP_DB_DISABLE, 1); -#endif - /* set pixel encoding */ switch (crtc_timing->pixel_encoding) { case PIXEL_ENCODING_YCBCR422: REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, - DP_PIXEL_ENCODING_YCBCR422); + DP_PIXEL_ENCODING_TYPE_YCBCR422); break; case PIXEL_ENCODING_YCBCR444: REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, - DP_PIXEL_ENCODING_YCBCR444); + DP_PIXEL_ENCODING_TYPE_YCBCR444); if (crtc_timing->flags.Y_ONLY) if (crtc_timing->display_color_depth != COLOR_DEPTH_666) @@ -326,7 +305,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( * Color depth of Y-only could be * 8, 10, 12, 16 bits */ REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, - DP_PIXEL_ENCODING_Y_ONLY); + DP_PIXEL_ENCODING_TYPE_Y_ONLY); /* Note: DP_MSA_MISC1 bit 7 is the indicator * of Y-only mode. * This bit is set in HW if register @@ -334,22 +313,22 @@ static void dce110_stream_encoder_dp_set_stream_attribute( break; case PIXEL_ENCODING_YCBCR420: REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, - DP_PIXEL_ENCODING_YCBCR420); + DP_PIXEL_ENCODING_TYPE_YCBCR420); if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN) REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (enc110->se_mask->DP_VID_N_MUL) REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1); #endif break; default: REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, - DP_PIXEL_ENCODING_RGB444); + DP_PIXEL_ENCODING_TYPE_RGB444); break; } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (REG(DP_MSA_MISC)) misc1 = REG_READ(DP_MSA_MISC); #endif @@ -363,27 +342,27 @@ static void dce110_stream_encoder_dp_set_stream_attribute( break; case COLOR_DEPTH_888: REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, - DP_COMPONENT_DEPTH_8BPC); + DP_COMPONENT_PIXEL_DEPTH_8BPC); break; case COLOR_DEPTH_101010: REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, - DP_COMPONENT_DEPTH_10BPC); + DP_COMPONENT_PIXEL_DEPTH_10BPC); break; case COLOR_DEPTH_121212: REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, - DP_COMPONENT_DEPTH_12BPC); + DP_COMPONENT_PIXEL_DEPTH_12BPC); break; default: REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, - DP_COMPONENT_DEPTH_6BPC); + DP_COMPONENT_PIXEL_DEPTH_6BPC); break; } /* set dynamic range and YCbCr range */ -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 switch (crtc_timing->display_color_depth) { case COLOR_DEPTH_666: colorimetry_bpc = 0; @@ -462,7 +441,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( DP_DYN_RANGE, dynamic_range_rgb, DP_YCBCR_RANGE, dynamic_range_ycbcr); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (REG(DP_MSA_COLORIMETRY)) REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0); @@ -497,7 +476,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( crtc_timing->v_front_porch; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 /* start at begining of left border */ if (REG(DP_MSA_TIMING_PARAM2)) REG_SET_2(DP_MSA_TIMING_PARAM2, 0, @@ -700,11 +679,11 @@ static void dce110_stream_encoder_set_mst_bandwidth( struct fixed31_32 avg_time_slots_per_mtp) { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - uint32_t x = dal_fixed31_32_floor( + uint32_t x = dc_fixpt_floor( avg_time_slots_per_mtp); - uint32_t y = dal_fixed31_32_ceil( - dal_fixed31_32_shl( - dal_fixed31_32_sub_int( + uint32_t y = dc_fixpt_ceil( + dc_fixpt_shl( + dc_fixpt_sub_int( avg_time_slots_per_mtp, x), 26)); @@ -736,7 +715,8 @@ static void dce110_stream_encoder_update_hdmi_info_packets( const uint32_t *content = (const uint32_t *) &info_frame->avi.sb[0]; /*we need turn on clock before programming AFMT block*/ - REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); + if (REG(AFMT_CNTL)) + REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); REG_WRITE(AFMT_AVI_INFO0, content[0]); @@ -771,7 +751,7 @@ static void dce110_stream_encoder_update_hdmi_info_packets( dce110_update_hdmi_info_packet(enc110, 3, &info_frame->hdrsmd); } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (enc110->se_mask->HDMI_DB_DISABLE) { /* for bring up, disable dp double TODO */ if (REG(HDMI_DB_CONTROL)) @@ -809,7 +789,7 @@ static void dce110_stream_encoder_stop_hdmi_info_packets( HDMI_GENERIC1_LINE, 0, HDMI_GENERIC1_SEND, 0); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 /* stop generic packets 2 & 3 on HDMI */ if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0, @@ -836,7 +816,7 @@ static void dce110_stream_encoder_update_dp_info_packets( const struct encoder_info_frame *info_frame) { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - uint32_t value = REG_READ(DP_SEC_CNTL); + uint32_t value = 0; if (info_frame->vsc.valid) dce110_update_generic_info_packet( @@ -870,6 +850,7 @@ static void dce110_stream_encoder_update_dp_info_packets( * Therefore we need to enable master bit * if at least on of the fields is not 0 */ + value = REG_READ(DP_SEC_CNTL); if (value) REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); } @@ -879,7 +860,7 @@ static void dce110_stream_encoder_stop_dp_info_packets( { /* stop generic packets on DP */ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - uint32_t value = REG_READ(DP_SEC_CNTL); + uint32_t value = 0; if (enc110->se_mask->DP_SEC_AVI_ENABLE) { REG_SET_7(DP_SEC_CNTL, 0, @@ -892,25 +873,10 @@ static void dce110_stream_encoder_stop_dp_info_packets( DP_SEC_STREAM_ENABLE, 0); } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (enc110->se_mask->DP_SEC_GSP7_ENABLE) { - REG_SET_10(DP_SEC_CNTL, 0, - DP_SEC_GSP0_ENABLE, 0, - DP_SEC_GSP1_ENABLE, 0, - DP_SEC_GSP2_ENABLE, 0, - DP_SEC_GSP3_ENABLE, 0, - DP_SEC_GSP4_ENABLE, 0, - DP_SEC_GSP5_ENABLE, 0, - DP_SEC_GSP6_ENABLE, 0, - DP_SEC_GSP7_ENABLE, 0, - DP_SEC_MPG_ENABLE, 0, - DP_SEC_STREAM_ENABLE, 0); - } -#endif /* this register shared with audio info frame. * therefore we need to keep master enabled * if at least one of the fields is not 0 */ - + value = REG_READ(DP_SEC_CNTL); if (value) REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); @@ -1513,7 +1479,7 @@ static void dce110_se_disable_dp_audio( struct stream_encoder *enc) { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - uint32_t value = REG_READ(DP_SEC_CNTL); + uint32_t value = 0; /* Disable Audio packets */ REG_UPDATE_5(DP_SEC_CNTL, @@ -1525,6 +1491,7 @@ static void dce110_se_disable_dp_audio( /* This register shared with encoder info frame. Therefore we need to keep master enabled if at least on of the fields is not 0 */ + value = REG_READ(DP_SEC_CNTL); if (value != 0) REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c index 832c5daada35..ab63d0d0304c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c @@ -41,7 +41,7 @@ #define DC_LOGGER \ xfm_dce->base.ctx->logger -#define IDENTITY_RATIO(ratio) (dal_fixed31_32_u2d19(ratio) == (1 << 19)) +#define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19)) #define GAMUT_MATRIX_SIZE 12 #define SCL_PHASES 16 @@ -155,7 +155,7 @@ static void program_overscan( int overscan_bottom = data->v_active - data->recout.y - data->recout.height; - if (xfm_dce->base.ctx->dc->debug.surface_visual_confirm) { + if (xfm_dce->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) { overscan_bottom += 2; overscan_right += 2; } @@ -256,27 +256,27 @@ static void calculate_inits( struct fixed31_32 v_init; inits->h_int_scale_ratio = - dal_fixed31_32_u2d19(data->ratios.horz) << 5; + dc_fixpt_u2d19(data->ratios.horz) << 5; inits->v_int_scale_ratio = - dal_fixed31_32_u2d19(data->ratios.vert) << 5; + dc_fixpt_u2d19(data->ratios.vert) << 5; h_init = - dal_fixed31_32_div_int( - dal_fixed31_32_add( + dc_fixpt_div_int( + dc_fixpt_add( data->ratios.horz, - dal_fixed31_32_from_int(data->taps.h_taps + 1)), + dc_fixpt_from_int(data->taps.h_taps + 1)), 2); - inits->h_init.integer = dal_fixed31_32_floor(h_init); - inits->h_init.fraction = dal_fixed31_32_u0d19(h_init) << 5; + inits->h_init.integer = dc_fixpt_floor(h_init); + inits->h_init.fraction = dc_fixpt_u0d19(h_init) << 5; v_init = - dal_fixed31_32_div_int( - dal_fixed31_32_add( + dc_fixpt_div_int( + dc_fixpt_add( data->ratios.vert, - dal_fixed31_32_from_int(data->taps.v_taps + 1)), + dc_fixpt_from_int(data->taps.v_taps + 1)), 2); - inits->v_init.integer = dal_fixed31_32_floor(v_init); - inits->v_init.fraction = dal_fixed31_32_u0d19(v_init) << 5; + inits->v_init.integer = dc_fixpt_floor(v_init); + inits->v_init.fraction = dc_fixpt_u0d19(v_init) << 5; } static void program_scl_ratios_inits( |