From: Zeyu Fan <Zeyu.Fan@xxxxxxx> Change-Id: Ic1b6dc1b70479e30b050659d2231ade0d40e09c9 Signed-off-by: Zeyu Fan <Zeyu.Fan at amd.com> Reviewed-by: Tony Cheng <Tony.Cheng at amd.com> Acked-by: Harry Wentland <Harry.Wentland at amd.com> --- drivers/gpu/drm/amd/dal/dc/dce/Makefile | 3 +- .../dce_clock_source.c} | 455 +++++++++++++-------- .../dce_clock_source.h} | 59 ++- .../gpu/drm/amd/dal/dc/dce100/dce100_resource.c | 53 +-- drivers/gpu/drm/amd/dal/dc/dce110/Makefile | 2 +- .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c | 43 +- drivers/gpu/drm/amd/dal/dc/dce112/Makefile | 2 +- .../drm/amd/dal/dc/dce112/dce112_clock_source.c | 278 ------------- .../drm/amd/dal/dc/dce112/dce112_clock_source.h | 59 --- .../gpu/drm/amd/dal/dc/dce112/dce112_resource.c | 66 +-- drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c | 50 ++- 11 files changed, 467 insertions(+), 603 deletions(-) rename drivers/gpu/drm/amd/dal/dc/{dce110/dce110_clock_source.c => dce/dce_clock_source.c} (76%) rename drivers/gpu/drm/amd/dal/dc/{dce110/dce110_clock_source.h => dce/dce_clock_source.h} (53%) delete mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c delete mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h diff --git a/drivers/gpu/drm/amd/dal/dc/dce/Makefile b/drivers/gpu/drm/amd/dal/dc/dce/Makefile index 87e5f11024ca..cbf73500d361 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce/Makefile +++ b/drivers/gpu/drm/amd/dal/dc/dce/Makefile @@ -6,7 +6,8 @@ # offset/shift/mask stored in dce_hw struct DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \ -dce_mem_input.o dce_scl_filters.o dce_transform.o +dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o + AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE)) diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_clock_source.c b/drivers/gpu/drm/amd/dal/dc/dce/dce_clock_source.c similarity index 76% rename from drivers/gpu/drm/amd/dal/dc/dce110/dce110_clock_source.c rename to drivers/gpu/drm/amd/dal/dc/dce/dce_clock_source.c index 08d3bdacacc3..80ac5d9efa71 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_clock_source.c +++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_clock_source.c @@ -25,9 +25,6 @@ #include "dm_services.h" -/* include DCE11 register header files */ -#include "dce/dce_11_0_d.h" -#include "dce/dce_11_0_sh_mask.h" #include "dc_types.h" #include "core_types.h" @@ -35,7 +32,19 @@ #include "include/grph_object_id.h" #include "include/logger_interface.h" -#include "dce110_clock_source.h" +#include "dce_clock_source.h" + +#include "reg_helper.h" + +#define REG(reg)\ + (clk_src->regs->reg) + +#define CTX \ + clk_src->base.ctx + +#undef FN +#define FN(reg_name, field_name) \ + clk_src->cs_shift->field_name, clk_src->cs_mask->field_name #define FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM 6 #define CALC_PLL_CLK_SRC_ERR_TOLERANCE 1 @@ -450,42 +459,23 @@ static bool pll_adjust_pix_clk( * \return * Calculation error in units of 0.01% */ -static uint32_t dce110_get_pix_clk_dividers( - struct clock_source *cs, - struct pixel_clk_params *pix_clk_params, - struct pll_settings *pll_settings) + +static uint32_t dce110_get_pix_clk_dividers_helper ( + struct dce110_clk_src *clk_src, + struct pll_settings *pll_settings, + struct pixel_clk_params *pix_clk_params) { - struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs); - uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; uint32_t addr = 0; uint32_t value = 0; uint32_t field = 0; - - if (pix_clk_params == NULL || pll_settings == NULL - || pix_clk_params->requested_pix_clk == 0) { - dm_logger_write(clk_src->base.ctx->logger, LOG_ERROR, - "%s: Invalid parameters!!\n", __func__); - return pll_calc_error; - } - - memset(pll_settings, 0, sizeof(*pll_settings)); - - if (cs->id == CLOCK_SOURCE_ID_EXTERNAL) { - pll_settings->adjusted_pix_clk = clk_src->ext_clk_khz; - pll_settings->calculated_pix_clk = clk_src->ext_clk_khz; - pll_settings->actual_pix_clk = - pix_clk_params->requested_pix_clk; - return 0; - } - /* PLL only after this point */ + uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; /* Check if reference clock is external (not pcie/xtalin) * HW Dce80 spec: * 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB * 04 - HSYNCA, 05 - GENLK_CLK, 06 - PCIE_REFCLK, 07 - DVOCLK0 */ - addr = clk_src->offsets.pll_cntl; - value = dm_read_reg(clk_src->base.ctx, addr); - field = get_reg_field_value(value, PLL_CNTL, PLL_REF_DIV_SRC); + value = REG_READ(PLL_CNTL); + REG_GET(PLL_CNTL, PLL_REF_DIV_SRC, &field); pll_settings->use_external_clk = (field > 1); /* VBIOS by default enables DP SS (spread on IDCLK) for DCE 8.0 always @@ -535,6 +525,80 @@ static uint32_t dce110_get_pix_clk_dividers( return pll_calc_error; } +static void dce112_get_pix_clk_dividers_helper ( + struct dce110_clk_src *clk_src, + struct pll_settings *pll_settings, + struct pixel_clk_params *pix_clk_params) +{ + uint32_t actualPixelClockInKHz; + + actualPixelClockInKHz = pix_clk_params->requested_pix_clk; + /* Calculate Dividers */ + if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) { + switch (pix_clk_params->color_depth) { + case COLOR_DEPTH_101010: + actualPixelClockInKHz = (actualPixelClockInKHz * 5) >> 2; + break; + case COLOR_DEPTH_121212: + actualPixelClockInKHz = (actualPixelClockInKHz * 6) >> 2; + break; + case COLOR_DEPTH_161616: + actualPixelClockInKHz = actualPixelClockInKHz * 2; + break; + default: + break; + } + } + pll_settings->actual_pix_clk = actualPixelClockInKHz; + pll_settings->adjusted_pix_clk = actualPixelClockInKHz; + pll_settings->calculated_pix_clk = pix_clk_params->requested_pix_clk; +} + +static uint32_t dce110_get_pix_clk_dividers( + struct clock_source *cs, + struct pixel_clk_params *pix_clk_params, + struct pll_settings *pll_settings) +{ + struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs); + uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; + + if (pix_clk_params == NULL || pll_settings == NULL + || pix_clk_params->requested_pix_clk == 0) { + dm_logger_write(clk_src->base.ctx->logger, LOG_ERROR, + "%s: Invalid parameters!!\n", __func__); + return pll_calc_error; + } + + memset(pll_settings, 0, sizeof(*pll_settings)); + + if (cs->id == CLOCK_SOURCE_ID_DP_DTO || + cs->id == CLOCK_SOURCE_ID_EXTERNAL) { + pll_settings->adjusted_pix_clk = clk_src->ext_clk_khz; + pll_settings->calculated_pix_clk = clk_src->ext_clk_khz; + pll_settings->actual_pix_clk = + pix_clk_params->requested_pix_clk; + return 0; + } + + switch (cs->ctx->dce_version) { + case DCE_VERSION_8_0: + case DCE_VERSION_10_0: + case DCE_VERSION_11_0: + pll_calc_error = + dce110_get_pix_clk_dividers_helper(clk_src, + pll_settings, pix_clk_params); + break; + case DCE_VERSION_11_2: + dce112_get_pix_clk_dividers_helper(clk_src, + pll_settings, pix_clk_params); + break; + default: + break; + } + + return pll_calc_error; +} + static bool disable_spread_spectrum(struct dce110_clk_src *clk_src) { enum bp_result result; @@ -662,21 +726,56 @@ static bool enable_spread_spectrum( return true; } -static void program_pixel_clk_resync( +static void dce110_program_pixel_clk_resync( struct dce110_clk_src *clk_src, enum signal_type signal_type, enum dc_color_depth colordepth) { uint32_t value = 0; - value = dm_read_reg(clk_src->base.ctx, clk_src->offsets.pixclk_resync_cntl); + REG_UPDATE(RESYNC_CNTL, + DCCG_DEEP_COLOR_CNTL1, 0); + /* + 24 bit mode: TMDS clock = 1.0 x pixel clock (1:1) + 30 bit mode: TMDS clock = 1.25 x pixel clock (5:4) + 36 bit mode: TMDS clock = 1.5 x pixel clock (3:2) + 48 bit mode: TMDS clock = 2 x pixel clock (2:1) + */ + if (signal_type != SIGNAL_TYPE_HDMI_TYPE_A) + return; + + switch (colordepth) { + case COLOR_DEPTH_888: + REG_UPDATE(RESYNC_CNTL, + DCCG_DEEP_COLOR_CNTL1, 0); + break; + case COLOR_DEPTH_101010: + REG_UPDATE(RESYNC_CNTL, + DCCG_DEEP_COLOR_CNTL1, 1); + break; + case COLOR_DEPTH_121212: + REG_UPDATE(RESYNC_CNTL, + DCCG_DEEP_COLOR_CNTL1, 2); + break; + case COLOR_DEPTH_161616: + REG_UPDATE(RESYNC_CNTL, + DCCG_DEEP_COLOR_CNTL1, 3); + break; + default: + break; + } +} - set_reg_field_value( - value, - 0, - PIXCLK1_RESYNC_CNTL, - DCCG_DEEP_COLOR_CNTL1); +static void dce112_program_pixel_clk_resync( + struct dce110_clk_src *clk_src, + enum signal_type signal_type, + enum dc_color_depth colordepth, + bool enable_ycbcr420) +{ + uint32_t value = 0; + REG_UPDATE(PIXCLK_RESYNC_CNTL, + PHYPLLA_DCCG_DEEP_COLOR_CNTL, 0); /* 24 bit mode: TMDS clock = 1.0 x pixel clock (1:1) 30 bit mode: TMDS clock = 1.25 x pixel clock (5:4) @@ -688,41 +787,28 @@ static void program_pixel_clk_resync( switch (colordepth) { case COLOR_DEPTH_888: - set_reg_field_value( - value, - 0, - PIXCLK1_RESYNC_CNTL, - DCCG_DEEP_COLOR_CNTL1); + REG_UPDATE_2(PIXCLK_RESYNC_CNTL, + PHYPLLA_DCCG_DEEP_COLOR_CNTL, 0, + PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, enable_ycbcr420); break; case COLOR_DEPTH_101010: - set_reg_field_value( - value, - 1, - PIXCLK1_RESYNC_CNTL, - DCCG_DEEP_COLOR_CNTL1); + REG_UPDATE_2(PIXCLK_RESYNC_CNTL, + PHYPLLA_DCCG_DEEP_COLOR_CNTL, 1, + PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, enable_ycbcr420); break; case COLOR_DEPTH_121212: - set_reg_field_value( - value, - 2, - PIXCLK1_RESYNC_CNTL, - DCCG_DEEP_COLOR_CNTL1); + REG_UPDATE_2(PIXCLK_RESYNC_CNTL, + PHYPLLA_DCCG_DEEP_COLOR_CNTL, 2, + PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, enable_ycbcr420); break; case COLOR_DEPTH_161616: - set_reg_field_value( - value, - 3, - PIXCLK1_RESYNC_CNTL, - DCCG_DEEP_COLOR_CNTL1); + REG_UPDATE_2(PIXCLK_RESYNC_CNTL, + PHYPLLA_DCCG_DEEP_COLOR_CNTL, 3, + PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, enable_ycbcr420); break; default: break; } - - dm_write_reg( - clk_src->base.ctx, - clk_src->offsets.pixclk_resync_cntl, - value); } static bool dce110_program_pix_clk( @@ -738,47 +824,76 @@ static bool dce110_program_pix_clk( * do not disable it here */ if (clk_src->id != CLOCK_SOURCE_ID_EXTERNAL && - !dc_is_dp_signal(pix_clk_params->signal_type)) + !dc_is_dp_signal(pix_clk_params->signal_type) && + clk_src->ctx->dce_version <= DCE_VERSION_11_0) disable_spread_spectrum(dce110_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 = clk_src->id; - bp_pc_params.target_pixel_clock = - pll_settings->actual_pix_clk; - bp_pc_params.reference_divider = pll_settings->reference_divider; - bp_pc_params.feedback_divider = pll_settings->feedback_divider; - bp_pc_params.fractional_feedback_divider = - pll_settings->fract_feedback_divider; - bp_pc_params.pixel_clock_post_divider = - pll_settings->pix_clk_post_divider; + bp_pc_params.target_pixel_clock = pll_settings->actual_pix_clk; bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id; bp_pc_params.signal_type = pix_clk_params->signal_type; - bp_pc_params.flags.SET_EXTERNAL_REF_DIV_SRC = - pll_settings->use_external_clk; - - if (dce110_clk_src->bios->funcs->set_pixel_clock( - dce110_clk_src->bios, &bp_pc_params) != BP_RESULT_OK) - return false; -/* 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 (clk_src->id != CLOCK_SOURCE_ID_EXTERNAL - && pix_clk_params->flags.ENABLE_SS && !dc_is_dp_signal( - pix_clk_params->signal_type)) - if (!enable_spread_spectrum(dce110_clk_src, + switch (clk_src->ctx->dce_version) { + case DCE_VERSION_11_2: + if (clk_src->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.target_pixel_clock = pll_settings->actual_pix_clk / 2; + bp_pc_params.flags.SUPPORT_YUV_420 = 1; + } + } + if (dce110_clk_src->bios->funcs->set_pixel_clock( + dce110_clk_src->bios, &bp_pc_params) != BP_RESULT_OK) + return false; + /* Resync deep color DTO */ + if (clk_src->id != CLOCK_SOURCE_ID_DP_DTO) + dce112_program_pixel_clk_resync(dce110_clk_src, pix_clk_params->signal_type, - pll_settings)) + pix_clk_params->color_depth, + pix_clk_params->flags.SUPPORT_YCBCR420); + break; + case DCE_VERSION_8_0: + case DCE_VERSION_10_0: + case DCE_VERSION_11_0: + bp_pc_params.reference_divider = pll_settings->reference_divider; + bp_pc_params.feedback_divider = pll_settings->feedback_divider; + bp_pc_params.fractional_feedback_divider = + pll_settings->fract_feedback_divider; + bp_pc_params.pixel_clock_post_divider = + pll_settings->pix_clk_post_divider; + bp_pc_params.flags.SET_EXTERNAL_REF_DIV_SRC = + pll_settings->use_external_clk; + + if (dce110_clk_src->bios->funcs->set_pixel_clock( + dce110_clk_src->bios, &bp_pc_params) != BP_RESULT_OK) return false; - -/* Resync deep color DTO */ - if (clk_src->id != CLOCK_SOURCE_ID_EXTERNAL) - program_pixel_clk_resync(dce110_clk_src, - pix_clk_params->signal_type, - pix_clk_params->color_depth); + /* 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 (clk_src->id != CLOCK_SOURCE_ID_EXTERNAL + && pix_clk_params->flags.ENABLE_SS && !dc_is_dp_signal( + pix_clk_params->signal_type)) { + + if (!enable_spread_spectrum(dce110_clk_src, + pix_clk_params->signal_type, + pll_settings)) + return false; + /* Resync deep color DTO */ + dce110_program_pixel_clk_resync(dce110_clk_src, + pix_clk_params->signal_type, + pix_clk_params->color_depth); + } + break; + default: + break; + } return true; } @@ -1035,51 +1150,23 @@ bool dce110_clk_src_construct( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, - const struct dce110_clk_src_reg_offsets *reg_offsets) + const struct dce110_clk_src_regs *regs, + const struct dce110_clk_src_shift *cs_shift, + const struct dce110_clk_src_mask *cs_mask) { struct firmware_info fw_info = { { 0 } }; -/* structure normally used with PLL ranges from ATOMBIOS; DS on by default */ - struct calc_pll_clock_source_init_data calc_pll_cs_init_data = { - bios, - 1, /* minPixelClockPLLPostDivider */ - PLL_POST_DIV__PLL_POST_DIV_PIXCLK_MASK, - /* maxPixelClockPLLPostDivider*/ - 1,/* minPLLRefDivider*/ - PLL_REF_DIV__PLL_REF_DIV_MASK,/* maxPLLRefDivider*/ - 0, -/* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ - 0, -/* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM, -/*numberOfFractFBDividerDecimalPoints*/ - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM, -/*number of decimal point to round off for fractional feedback divider value*/ - ctx - }; -/*structure for HDMI, no SS or SS% <= 0.06% for 27 MHz Ref clock */ - struct calc_pll_clock_source_init_data calc_pll_cs_init_data_hdmi = { - bios, - 1, /* minPixelClockPLLPostDivider */ - PLL_POST_DIV__PLL_POST_DIV_PIXCLK_MASK, - /* maxPixelClockPLLPostDivider*/ - 1,/* minPLLRefDivider*/ - PLL_REF_DIV__PLL_REF_DIV_MASK,/* maxPLLRefDivider*/ - 13500, - /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ - 27000, - /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/ - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM, - /*numberOfFractFBDividerDecimalPoints*/ - FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM, -/*number of decimal point to round off for fractional feedback divider value*/ - ctx - }; + struct calc_pll_clock_source_init_data calc_pll_cs_init_data_hdmi; + struct calc_pll_clock_source_init_data calc_pll_cs_init_data; clk_src->base.ctx = ctx; clk_src->bios = bios; clk_src->base.id = id; clk_src->base.funcs = &dce110_clk_src_funcs; + clk_src->regs = regs; + clk_src->cs_shift = cs_shift; + clk_src->cs_mask = cs_mask; + if (clk_src->bios->funcs->get_firmware_info( clk_src->bios, &fw_info) != BP_RESULT_OK) { ASSERT_CRITICAL(false); @@ -1088,39 +1175,85 @@ bool dce110_clk_src_construct( clk_src->ext_clk_khz = fw_info.external_clock_source_frequency_for_dp; - clk_src->ref_freq_khz = fw_info.pll_info.crystal_frequency; - if (clk_src->base.id == CLOCK_SOURCE_ID_EXTERNAL) - return true; - - clk_src->offsets = *reg_offsets; - - /* PLL only from here on */ - ss_info_from_atombios_create(clk_src); - - if (!calc_pll_max_vco_construct( - &clk_src->calc_pll, - &calc_pll_cs_init_data)) { - ASSERT_CRITICAL(false); - goto unexpected_failure; - } + switch (clk_src->base.ctx->dce_version) { + case DCE_VERSION_8_0: + case DCE_VERSION_10_0: + case DCE_VERSION_11_0: + + /* 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; + + clk_src->ref_freq_khz = fw_info.pll_info.crystal_frequency; + + if (clk_src->base.id == CLOCK_SOURCE_ID_EXTERNAL) + return true; + + /* PLL only from here on */ + ss_info_from_atombios_create(clk_src); + + if (!calc_pll_max_vco_construct( + &clk_src->calc_pll, + &calc_pll_cs_init_data)) { + ASSERT_CRITICAL(false); + goto unexpected_failure; + } - if (clk_src->ref_freq_khz == 48000) { - calc_pll_cs_init_data_hdmi. - min_override_input_pxl_clk_pll_freq_khz = 24000; - calc_pll_cs_init_data_hdmi. - max_override_input_pxl_clk_pll_freq_khz = 48000; - } else if (clk_src->ref_freq_khz == 100000) { - calc_pll_cs_init_data_hdmi. - min_override_input_pxl_clk_pll_freq_khz = 25000; - calc_pll_cs_init_data_hdmi. - max_override_input_pxl_clk_pll_freq_khz = 50000; - } + if (clk_src->ref_freq_khz == 48000) { + calc_pll_cs_init_data_hdmi. + min_override_input_pxl_clk_pll_freq_khz = 24000; + calc_pll_cs_init_data_hdmi. + max_override_input_pxl_clk_pll_freq_khz = 48000; + } else if (clk_src->ref_freq_khz == 100000) { + calc_pll_cs_init_data_hdmi. + min_override_input_pxl_clk_pll_freq_khz = 25000; + calc_pll_cs_init_data_hdmi. + max_override_input_pxl_clk_pll_freq_khz = 50000; + } - if (!calc_pll_max_vco_construct( - &clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) { - ASSERT_CRITICAL(false); - goto unexpected_failure; + if (!calc_pll_max_vco_construct( + &clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) { + ASSERT_CRITICAL(false); + goto unexpected_failure; + } + break; + default: + break; } return true; diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_clock_source.h b/drivers/gpu/drm/amd/dal/dc/dce/dce_clock_source.h similarity index 53% rename from drivers/gpu/drm/amd/dal/dc/dce110/dce110_clock_source.h rename to drivers/gpu/drm/amd/dal/dc/dce/dce_clock_source.h index 4fa82dad271f..067e4ac0e67a 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_clock_source.h +++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_clock_source.h @@ -22,22 +22,65 @@ * */ -#ifndef __DC_CLOCK_SOURCE_DCE110_H__ -#define __DC_CLOCK_SOURCE_DCE110_H__ +#ifndef __DC_CLOCK_SOURCE_DCE_H__ +#define __DC_CLOCK_SOURCE_DCE_H__ #include "../inc/clock_source.h" #define TO_DCE110_CLK_SRC(clk_src)\ container_of(clk_src, struct dce110_clk_src, base) -struct dce110_clk_src_reg_offsets { - uint32_t pll_cntl; - uint32_t pixclk_resync_cntl; +#define CS_COMMON_REG_LIST_DCE_100_110(id) \ + SRI(RESYNC_CNTL, PIXCLK, id), \ + SRI(PLL_CNTL, BPHYC_PLL, id) + +#define CS_COMMON_REG_LIST_DCE_80(id) \ + SRI(RESYNC_CNTL, PIXCLK, id), \ + SRI(PLL_CNTL, DCCG_PLL, id) + +#define CS_COMMON_REG_LIST_DCE_112(id) \ + SRI(PIXCLK_RESYNC_CNTL, PHYPLL, id) + +#define CS_SF(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)\ + CS_SF(PLL_CNTL, PLL_REF_DIV_SRC, mask_sh),\ + CS_SF(PIXCLK1_RESYNC_CNTL, DCCG_DEEP_COLOR_CNTL1, mask_sh),\ + CS_SF(PLL_POST_DIV, PLL_POST_DIV_PIXCLK, mask_sh),\ + CS_SF(PLL_REF_DIV, PLL_REF_DIV, mask_sh),\ + +#define CS_COMMON_MASK_SH_LIST_DCE_112(mask_sh)\ + 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),\ + +#define CS_REG_FIELD_LIST(type) \ + type PLL_REF_DIV_SRC; \ + type DCCG_DEEP_COLOR_CNTL1; \ + type PHYPLLA_DCCG_DEEP_COLOR_CNTL; \ + type PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE; \ + type PLL_POST_DIV_PIXCLK; \ + type PLL_REF_DIV; \ + +struct dce110_clk_src_shift { + CS_REG_FIELD_LIST(uint8_t) +}; + +struct dce110_clk_src_mask{ + CS_REG_FIELD_LIST(uint32_t) +}; + +struct dce110_clk_src_regs { + uint32_t RESYNC_CNTL; + uint32_t PIXCLK_RESYNC_CNTL; + uint32_t PLL_CNTL; }; struct dce110_clk_src { struct clock_source base; - struct dce110_clk_src_reg_offsets offsets; + const struct dce110_clk_src_regs *regs; + const struct dce110_clk_src_mask *cs_mask; + const struct dce110_clk_src_shift *cs_shift; struct dc_bios *bios; struct spread_spectrum_data *dp_ss_params; @@ -59,6 +102,8 @@ bool dce110_clk_src_construct( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id, - const struct dce110_clk_src_reg_offsets *reg_offsets); + const struct dce110_clk_src_regs *regs, + const struct dce110_clk_src_shift *cs_shift, + const struct dce110_clk_src_mask *cs_mask); #endif diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c index fafc976e5209..16595dc875a1 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c @@ -40,7 +40,7 @@ #include "dce110/dce110_ipp.h" #include "dce/dce_transform.h" #include "dce110/dce110_opp.h" -#include "dce110/dce110_clock_source.h" +#include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "dce100/dce100_hw_sequencer.h" @@ -167,20 +167,6 @@ static const struct dce110_mem_input_reg_offsets dce100_mi_reg_offsets[] = { } }; -static const struct dce110_clk_src_reg_offsets dce100_clk_src_reg_offsets[] = { - { - .pll_cntl = mmBPHYC_PLL0_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK0_RESYNC_CNTL - }, - { - .pll_cntl = mmBPHYC_PLL1_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK1_RESYNC_CNTL - }, - { - .pll_cntl = mmBPHYC_PLL2_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK2_RESYNC_CNTL - } -}; static const struct dce110_ipp_reg_offsets dce100_ipp_reg_offsets[] = { { @@ -326,6 +312,26 @@ static const struct dce_aduio_mask audio_mask = { AUD_COMMON_MASK_SH_LIST(_MASK) }; +#define clk_src_regs(id)\ +[id] = {\ + CS_COMMON_REG_LIST_DCE_100_110(id),\ +} + +static const struct dce110_clk_src_regs clk_src_regs[] = { + clk_src_regs(0), + clk_src_regs(1), + clk_src_regs(2) +}; + +static const struct dce110_clk_src_shift cs_shift = { + CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) +}; + +static const struct dce110_clk_src_mask cs_mask = { + CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) +}; + + #define DCFE_MEM_PWR_CTRL_REG_BASE 0x1b03 @@ -642,7 +648,7 @@ struct clock_source *dce100_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, - const struct dce110_clk_src_reg_offsets *offsets, + const struct dce110_clk_src_regs *regs, bool dp_clk_src) { struct dce110_clk_src *clk_src = @@ -651,7 +657,8 @@ struct clock_source *dce100_clock_source_create( if (!clk_src) return NULL; - if (dce110_clk_src_construct(clk_src, ctx, bios, id, offsets)) { + if (dce110_clk_src_construct(clk_src, ctx, bios, id, + regs, &cs_shift, &cs_mask)) { clk_src->base.dp_clk_src = dp_clk_src; return &clk_src->base; } @@ -929,21 +936,21 @@ static bool construct( dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); pool->base.clock_sources[0] = - dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &dce100_clk_src_reg_offsets[0], false); + dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); pool->base.clock_sources[1] = - dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &dce100_clk_src_reg_offsets[1], false); + dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[2] = - dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &dce100_clk_src_reg_offsets[2], false); + dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 3; } else { pool->base.dp_clock_source = - dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &dce100_clk_src_reg_offsets[0], true); + dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); pool->base.clock_sources[0] = - dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &dce100_clk_src_reg_offsets[1], false); + dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[1] = - dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &dce100_clk_src_reg_offsets[2], false); + dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 2; } diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/Makefile b/drivers/gpu/drm/amd/dal/dc/dce110/Makefile index cb6bb24e6298..526fc7f8d395 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/Makefile +++ b/drivers/gpu/drm/amd/dal/dc/dce110/Makefile @@ -6,7 +6,7 @@ DCE110 = dce110_ipp.o dce110_ipp_cursor.o \ dce110_ipp_gamma.o dce110_opp.o dce110_opp_csc.o \ dce110_timing_generator.o dce110_opp_formatter.o dce110_opp_regamma.o \ dce110_compressor.o dce110_mem_input.o dce110_hw_sequencer.o \ -dce110_resource.o dce110_clock_source.o \ +dce110_resource.o \ dce110_opp_regamma_v.o dce110_opp_csc_v.o dce110_timing_generator_v.o \ dce110_mem_input_v.o dce110_opp_v.o dce110_transform_v.o diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c index 9d7fb832dd15..959467fa421e 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c @@ -45,7 +45,7 @@ #include "dce110/dce110_transform_v.h" #include "dce110/dce110_opp.h" #include "dce110/dce110_opp_v.h" -#include "dce110/dce110_clock_source.h" +#include "dce/dce_clock_source.h" #include "dce/dce_hwseq.h" #include "dce110/dce110_hw_sequencer.h" @@ -324,19 +324,23 @@ static const struct dce110_opp_reg_offsets dce110_opp_reg_offsets[] = { } }; -static const struct dce110_clk_src_reg_offsets dce110_clk_src_reg_offsets[] = { - { - .pll_cntl = mmBPHYC_PLL0_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK0_RESYNC_CNTL - }, - { - .pll_cntl = mmBPHYC_PLL1_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK1_RESYNC_CNTL - }, - { - .pll_cntl = mmBPHYC_PLL2_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK2_RESYNC_CNTL - } +#define clk_src_regs(id)\ +[id] = {\ + CS_COMMON_REG_LIST_DCE_100_110(id),\ +} + +static const struct dce110_clk_src_regs clk_src_regs[] = { + clk_src_regs(0), + clk_src_regs(1), + clk_src_regs(2) +}; + +static const struct dce110_clk_src_shift cs_shift = { + CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) +}; + +static const struct dce110_clk_src_mask cs_mask = { + CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; static const struct bios_registers bios_regs = { @@ -609,7 +613,7 @@ struct clock_source *dce110_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, - const struct dce110_clk_src_reg_offsets *offsets, + const struct dce110_clk_src_regs *regs, bool dp_clk_src) { struct dce110_clk_src *clk_src = @@ -618,7 +622,8 @@ struct clock_source *dce110_clock_source_create( if (!clk_src) return NULL; - if (dce110_clk_src_construct(clk_src, ctx, bios, id, offsets)) { + if (dce110_clk_src_construct(clk_src, ctx, bios, id, + regs, &cs_shift, &cs_mask)) { clk_src->base.dp_clk_src = dp_clk_src; return &clk_src->base; } @@ -1270,9 +1275,11 @@ static bool construct( dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); pool->base.clock_sources[0] = - dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &dce110_clk_src_reg_offsets[0], false); + dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, + &clk_src_regs[0], false); pool->base.clock_sources[1] = - dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &dce110_clk_src_reg_offsets[1], false); + dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, + &clk_src_regs[1], false); pool->base.clk_src_count = 2; diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/Makefile b/drivers/gpu/drm/amd/dal/dc/dce112/Makefile index 010e10b48042..5499bcf86cf0 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce112/Makefile +++ b/drivers/gpu/drm/amd/dal/dc/dce112/Makefile @@ -3,7 +3,7 @@ # It provides the control and status of HW CRTC block. DCE112 = dce112_compressor.o dce112_hw_sequencer.o \ -dce112_resource.o dce112_clock_source.o dce112_mem_input.o dce112_opp_formatter.o \ +dce112_resource.o dce112_mem_input.o dce112_opp_formatter.o \ dce112_opp.o AMD_DAL_DCE112 = $(addprefix $(AMDDALPATH)/dc/dce112/,$(DCE112)) diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c deleted file mode 100644 index d9db22607300..000000000000 --- a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * 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 - * - */ - -#include "dm_services.h" - -#include "dce112_clock_source.h" - -/* include DCE11.2 register header files */ -#include "dce/dce_11_2_d.h" -#include "dce/dce_11_2_sh_mask.h" - -#include "dc_types.h" -#include "core_types.h" - -#include "include/grph_object_id.h" -#include "include/logger_interface.h" -#include "dc_bios_types.h" - -/** - * 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% - */ -uint32_t dce112_get_pix_clk_dividers( - struct clock_source *cs, - struct pixel_clk_params *pix_clk_params, - struct pll_settings *pll_settings) -{ - struct dce112_clk_src *clk_src = TO_DCE112_CLK_SRC(cs); - uint32_t actualPixelClockInKHz; - - if (pix_clk_params == NULL || pll_settings == NULL - || pix_clk_params->requested_pix_clk == 0) { - dm_logger_write(cs->ctx->logger, LOG_ERROR, - "%s: Invalid parameters!!\n", __func__); - return 0; - } - - memset(pll_settings, 0, sizeof(*pll_settings)); - - if (clk_src->base.id == CLOCK_SOURCE_ID_DP_DTO) { - pll_settings->adjusted_pix_clk = clk_src->ext_clk_khz; - pll_settings->calculated_pix_clk = clk_src->ext_clk_khz; - pll_settings->actual_pix_clk = - pix_clk_params->requested_pix_clk; - return 0; - } - /* PLL only after this point */ - - actualPixelClockInKHz = pix_clk_params->requested_pix_clk; - - /* Calculate Dividers */ - if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) { - switch (pix_clk_params->color_depth) { - case COLOR_DEPTH_101010: - actualPixelClockInKHz = (actualPixelClockInKHz * 5) >> 2; - break; - case COLOR_DEPTH_121212: - actualPixelClockInKHz = (actualPixelClockInKHz * 6) >> 2; - break; - case COLOR_DEPTH_161616: - actualPixelClockInKHz = actualPixelClockInKHz * 2; - break; - default: - break; - } - } - - pll_settings->actual_pix_clk = actualPixelClockInKHz; - pll_settings->adjusted_pix_clk = actualPixelClockInKHz; - pll_settings->calculated_pix_clk = pix_clk_params->requested_pix_clk; - - return 0; -} - -static void program_pixel_clk_resync( - struct dce112_clk_src *clk_src, - enum signal_type signal_type, - enum dc_color_depth colordepth, - bool enable_ycbcr420) -{ - uint32_t value = 0; - - value = dm_read_reg(clk_src->base.ctx, - clk_src->offsets.pixclk_resync_cntl); - - set_reg_field_value( - value, - 0, - PHYPLLA_PIXCLK_RESYNC_CNTL, - PHYPLLA_DCCG_DEEP_COLOR_CNTL); - - /* - 24 bit mode: TMDS clock = 1.0 x pixel clock (1:1) - 30 bit mode: TMDS clock = 1.25 x pixel clock (5:4) - 36 bit mode: TMDS clock = 1.5 x pixel clock (3:2) - 48 bit mode: TMDS clock = 2 x pixel clock (2:1) - */ - if (signal_type != SIGNAL_TYPE_HDMI_TYPE_A) - return; - - switch (colordepth) { - case COLOR_DEPTH_888: - set_reg_field_value( - value, - 0, - PHYPLLA_PIXCLK_RESYNC_CNTL, - PHYPLLA_DCCG_DEEP_COLOR_CNTL); - break; - case COLOR_DEPTH_101010: - set_reg_field_value( - value, - 1, - PHYPLLA_PIXCLK_RESYNC_CNTL, - PHYPLLA_DCCG_DEEP_COLOR_CNTL); - break; - case COLOR_DEPTH_121212: - set_reg_field_value( - value, - 2, - PHYPLLA_PIXCLK_RESYNC_CNTL, - PHYPLLA_DCCG_DEEP_COLOR_CNTL); - break; - case COLOR_DEPTH_161616: - set_reg_field_value( - value, - 3, - PHYPLLA_PIXCLK_RESYNC_CNTL, - PHYPLLA_DCCG_DEEP_COLOR_CNTL); - break; - default: - break; - } - - set_reg_field_value( - value, - enable_ycbcr420, - PHYPLLA_PIXCLK_RESYNC_CNTL, - PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE); - - dm_write_reg( - clk_src->base.ctx, - clk_src->offsets.pixclk_resync_cntl, - value); -} - -static bool dce112_program_pix_clk( - struct clock_source *clk_src, - struct pixel_clk_params *pix_clk_params, - struct pll_settings *pll_settings) -{ - struct dce112_clk_src *dce112_clk_src = TO_DCE112_CLK_SRC(clk_src); - struct bp_pixel_clock_parameters bp_pc_params = {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 = clk_src->id; - bp_pc_params.target_pixel_clock = pll_settings->actual_pix_clk; - bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id; - bp_pc_params.signal_type = pix_clk_params->signal_type; - - if (clk_src->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.target_pixel_clock = pll_settings->actual_pix_clk / 2; - bp_pc_params.flags.SUPPORT_YUV_420 = 1; - } - - } - - if (dce112_clk_src->bios->funcs->set_pixel_clock( - dce112_clk_src->bios, &bp_pc_params) != BP_RESULT_OK) - return false; - - /* TODO: support YCBCR420 */ - - /* Resync deep color DTO */ - if (clk_src->id != CLOCK_SOURCE_ID_DP_DTO) - program_pixel_clk_resync(dce112_clk_src, - pix_clk_params->signal_type, - pix_clk_params->color_depth, - pix_clk_params->flags.SUPPORT_YCBCR420); - - return true; -} - -bool dce112_clock_source_power_down( - struct clock_source *clk_src) -{ - struct dce112_clk_src *dce112_clk_src = TO_DCE112_CLK_SRC(clk_src); - enum bp_result bp_result; - struct bp_pixel_clock_parameters bp_pixel_clock_params = {0}; - - if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO) - return true; - - /* 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 = dce112_clk_src->bios->funcs->set_pixel_clock( - dce112_clk_src->bios, - &bp_pixel_clock_params); - - return bp_result == BP_RESULT_OK; -} - -/*****************************************/ -/* Constructor */ -/*****************************************/ -static const struct clock_source_funcs dce112_clk_src_funcs = { - .cs_power_down = dce112_clock_source_power_down, - .program_pix_clk = dce112_program_pix_clk, - .get_pix_clk_dividers = dce112_get_pix_clk_dividers -}; - -bool dce112_clk_src_construct( - struct dce112_clk_src *clk_src, - struct dc_context *ctx, - struct dc_bios *bios, - enum clock_source_id id, - const struct dce112_clk_src_reg_offsets *reg_offsets) -{ - struct firmware_info fw_info = { { 0 } }; - - clk_src->base.ctx = ctx; - clk_src->bios = bios; - clk_src->base.id = id; - clk_src->base.funcs = &dce112_clk_src_funcs; - clk_src->offsets = *reg_offsets; - - if (clk_src->bios->funcs->get_firmware_info( - clk_src->bios, &fw_info) != BP_RESULT_OK) { - ASSERT_CRITICAL(false); - goto unexpected_failure; - } - - clk_src->ext_clk_khz = fw_info.external_clock_source_frequency_for_dp; - - return true; - -unexpected_failure: - return false; -} - diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h deleted file mode 100644 index 5667138210b3..000000000000 --- a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 - * - */ - -#ifndef __DC_CLOCK_SOURCE_DCE110_H__ -#define __DC_CLOCK_SOURCE_DCE110_H__ - -#include "clock_source.h" - -#define TO_DCE112_CLK_SRC(clk_src)\ - container_of(clk_src, struct dce112_clk_src, base) - -struct dce112_clk_src_reg_offsets { - uint32_t pixclk_resync_cntl; -}; - -struct dce112_clk_src { - struct clock_source base; - struct dce112_clk_src_reg_offsets offsets; - struct dc_bios *bios; - - uint32_t ext_clk_khz; -}; - -bool dce112_clk_src_construct( - struct dce112_clk_src *clk_src, - struct dc_context *ctx, - struct dc_bios *bios, - enum clock_source_id, - const struct dce112_clk_src_reg_offsets *reg_offsets); - -bool dce112_clock_source_power_down(struct clock_source *clk_src); - -uint32_t dce112_get_pix_clk_dividers( - struct clock_source *cs, - struct pixel_clk_params *pix_clk_params, - struct pll_settings *pll_settings); - -#endif diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c index c0d7ecc89374..bfb2c3fcd2cb 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c @@ -41,7 +41,7 @@ #include "dce/dce_audio.h" #include "dce112/dce112_opp.h" #include "dce110/dce110_ipp.h" -#include "dce112/dce112_clock_source.h" +#include "dce/dce_clock_source.h" #include "dce/dce_hwseq.h" #include "dce112/dce112_hw_sequencer.h" @@ -350,25 +350,26 @@ static const struct dce110_opp_reg_offsets dce112_opp_reg_offsets[] = { } }; -static const struct dce112_clk_src_reg_offsets dce112_clk_src_reg_offsets[] = { - { - .pixclk_resync_cntl = mmPHYPLLA_PIXCLK_RESYNC_CNTL - }, - { - .pixclk_resync_cntl = mmPHYPLLB_PIXCLK_RESYNC_CNTL - }, - { - .pixclk_resync_cntl = mmPHYPLLC_PIXCLK_RESYNC_CNTL - }, - { - .pixclk_resync_cntl = mmPHYPLLD_PIXCLK_RESYNC_CNTL - }, - { - .pixclk_resync_cntl = mmPHYPLLE_PIXCLK_RESYNC_CNTL - }, - { - .pixclk_resync_cntl = mmPHYPLLF_PIXCLK_RESYNC_CNTL - } +#define clk_src_regs(index, id)\ +[index] = {\ + CS_COMMON_REG_LIST_DCE_112(id),\ +} + +static const struct dce110_clk_src_regs clk_src_regs[] = { + clk_src_regs(0, A), + clk_src_regs(1, B), + clk_src_regs(2, C), + clk_src_regs(3, D), + clk_src_regs(4, E), + clk_src_regs(5, F) +}; + +static const struct dce110_clk_src_shift cs_shift = { + CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT) +}; + +static const struct dce110_clk_src_mask cs_mask = { + CS_COMMON_MASK_SH_LIST_DCE_112(_MASK) }; static const struct bios_registers bios_regs = { @@ -662,16 +663,17 @@ struct clock_source *dce112_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, - const struct dce112_clk_src_reg_offsets *offsets, + const struct dce110_clk_src_regs *regs, bool dp_clk_src) { - struct dce112_clk_src *clk_src = - dm_alloc(sizeof(struct dce112_clk_src)); + struct dce110_clk_src *clk_src = + dm_alloc(sizeof(struct dce110_clk_src)); if (!clk_src) return NULL; - if (dce112_clk_src_construct(clk_src, ctx, bios, id, offsets)) { + if (dce110_clk_src_construct(clk_src, ctx, bios, id, + regs, &cs_shift, &cs_mask)) { clk_src->base.dp_clk_src = dp_clk_src; return &clk_src->base; } @@ -682,7 +684,7 @@ struct clock_source *dce112_clock_source_create( void dce112_clock_source_destroy(struct clock_source **clk_src) { - dm_free(TO_DCE112_CLK_SRC(*clk_src)); + dm_free(TO_DCE110_CLK_SRC(*clk_src)); *clk_src = NULL; } @@ -1254,37 +1256,37 @@ static bool construct( dce112_clock_source_create( ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL0, - &dce112_clk_src_reg_offsets[0], false); + &clk_src_regs[0], false); pool->base.clock_sources[DCE112_CLK_SRC_PLL1] = dce112_clock_source_create( ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL1, - &dce112_clk_src_reg_offsets[1], false); + &clk_src_regs[1], false); pool->base.clock_sources[DCE112_CLK_SRC_PLL2] = dce112_clock_source_create( ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL2, - &dce112_clk_src_reg_offsets[2], false); + &clk_src_regs[2], false); pool->base.clock_sources[DCE112_CLK_SRC_PLL3] = dce112_clock_source_create( ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL3, - &dce112_clk_src_reg_offsets[3], false); + &clk_src_regs[3], false); pool->base.clock_sources[DCE112_CLK_SRC_PLL4] = dce112_clock_source_create( ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL4, - &dce112_clk_src_reg_offsets[4], false); + &clk_src_regs[4], false); pool->base.clock_sources[DCE112_CLK_SRC_PLL5] = dce112_clock_source_create( ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL5, - &dce112_clk_src_reg_offsets[5], false); + &clk_src_regs[5], false); pool->base.clk_src_count = DCE112_CLK_SRC_TOTAL; pool->base.dp_clock_source = dce112_clock_source_create( ctx, ctx->dc_bios, - CLOCK_SOURCE_ID_DP_DTO, &dce112_clk_src_reg_offsets[0], true); + CLOCK_SOURCE_ID_DP_DTO, &clk_src_regs[0], true); for (i = 0; i < pool->base.clk_src_count; i++) { diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c index 7dc0e9f6165e..06720407b6fc 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c @@ -45,7 +45,7 @@ #include "dce/dce_transform.h" #include "dce80/dce80_opp.h" #include "dce110/dce110_ipp.h" -#include "dce110/dce110_clock_source.h" +#include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "dce80/dce80_hw_sequencer.h" @@ -326,19 +326,24 @@ static const struct dce_aduio_mask audio_mask = { AUD_COMMON_MASK_SH_LIST(_MASK) }; -static const struct dce110_clk_src_reg_offsets dce80_clk_src_reg_offsets[] = { - { - .pll_cntl = mmDCCG_PLL0_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK0_RESYNC_CNTL - }, - { - .pll_cntl = mmDCCG_PLL1_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK1_RESYNC_CNTL - }, - { - .pll_cntl = mmDCCG_PLL2_PLL_CNTL, - .pixclk_resync_cntl = mmPIXCLK2_RESYNC_CNTL - } +#define clk_src_regs(id)\ +[id] = {\ + CS_COMMON_REG_LIST_DCE_80(id),\ +} + + +static const struct dce110_clk_src_regs clk_src_regs[] = { + clk_src_regs(0), + clk_src_regs(1), + clk_src_regs(2) +}; + +static const struct dce110_clk_src_shift cs_shift = { + CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) +}; + +static const struct dce110_clk_src_mask cs_mask = { + CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; static const struct bios_registers bios_regs = { @@ -581,7 +586,7 @@ struct clock_source *dce80_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, - const struct dce110_clk_src_reg_offsets *offsets, + const struct dce110_clk_src_regs *regs, bool dp_clk_src) { struct dce110_clk_src *clk_src = @@ -590,7 +595,8 @@ struct clock_source *dce80_clock_source_create( if (!clk_src) return NULL; - if (dce110_clk_src_construct(clk_src, ctx, bios, id, offsets)) { + if (dce110_clk_src_construct(clk_src, ctx, bios, id, + regs, &cs_shift, &cs_mask)) { clk_src->base.dp_clk_src = dp_clk_src; return &clk_src->base; } @@ -927,21 +933,21 @@ static bool construct( dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); pool->base.clock_sources[0] = - dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &dce80_clk_src_reg_offsets[0], false); + dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); pool->base.clock_sources[1] = - dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &dce80_clk_src_reg_offsets[1], false); + dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[2] = - dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &dce80_clk_src_reg_offsets[2], false); + dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 3; } else { pool->base.dp_clock_source = - dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &dce80_clk_src_reg_offsets[0], true); + dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); pool->base.clock_sources[0] = - dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &dce80_clk_src_reg_offsets[1], false); + dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[1] = - dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &dce80_clk_src_reg_offsets[2], false); + dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 2; } -- 2.9.3