diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0040-drm-amd-display-consolidate-dce8-11.2-display-clock-.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0040-drm-amd-display-consolidate-dce8-11.2-display-clock-.patch | 2394 |
1 files changed, 0 insertions, 2394 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0040-drm-amd-display-consolidate-dce8-11.2-display-clock-.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0040-drm-amd-display-consolidate-dce8-11.2-display-clock-.patch deleted file mode 100644 index 784bf005..00000000 --- a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0040-drm-amd-display-consolidate-dce8-11.2-display-clock-.patch +++ /dev/null @@ -1,2394 +0,0 @@ -From fcb5b31058fdc3bbba78871d8311e7e9c8272c1b Mon Sep 17 00:00:00 2001 -From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> -Date: Thu, 1 Dec 2016 18:13:25 -0500 -Subject: [PATCH 0040/4131] drm/amd/display: consolidate dce8-11.2 display - clock code - -Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> -Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> -Acked-by: Harry Wentland <Harry.Wentland@amd.com> -Signed-off-by: Alex Deucher <alexander.deucher@amd.com> ---- - drivers/gpu/drm/amd/display/dc/dce/Makefile | 3 +- - drivers/gpu/drm/amd/display/dc/dce/dce_audio.c | 4 +- - drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | 519 +++++++++++++++++++++ - drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h | 133 ++++++ - .../drm/amd/display/dc/dce100/dce100_resource.c | 22 +- - .../drm/amd/display/dc/dce110/dce110_resource.c | 24 +- - .../drm/amd/display/dc/dce112/dce112_resource.c | 28 +- - .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 70 +-- - drivers/gpu/drm/amd/display/dc/dm_services_types.h | 18 +- - drivers/gpu/drm/amd/display/dc/gpu/Makefile | 15 - - .../display/dc/gpu/dce110/display_clock_dce110.c | 516 -------------------- - .../display/dc/gpu/dce110/display_clock_dce110.h | 50 -- - .../display/dc/gpu/dce112/display_clock_dce112.c | 152 ------ - .../display/dc/gpu/dce112/display_clock_dce112.h | 14 - - .../amd/display/dc/gpu/dce80/display_clock_dce80.c | 430 ----------------- - .../amd/display/dc/gpu/dce80/display_clock_dce80.h | 54 --- - .../amd/display/include/display_clock_interface.h | 15 +- - 17 files changed, 747 insertions(+), 1320 deletions(-) - create mode 100644 drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c - create mode 100644 drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h - delete mode 100644 drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.c - delete mode 100644 drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.h - delete mode 100644 drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.c - delete mode 100644 drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.h - -diff --git a/drivers/gpu/drm/amd/display/dc/dce/Makefile b/drivers/gpu/drm/amd/display/dc/dce/Makefile -index bfca381..6add597 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce/Makefile -+++ b/drivers/gpu/drm/amd/display/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_clock_source.o dce_scl_filters.o dce_transform.o -+dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \ -+dce_clocks.o - - - AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE)) -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 dc44053..2749c8f 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c -+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c -@@ -888,7 +888,9 @@ static const struct audio_funcs funcs = { - - void dce_aud_destroy(struct audio **audio) - { -- dm_free(*audio); -+ struct dce_audio *aud = DCE_AUD(*audio); -+ -+ dm_free(aud); - *audio = NULL; - } - -diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c -new file mode 100644 -index 0000000..bc1a46b ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c -@@ -0,0 +1,519 @@ -+/* -+ * Copyright 2012-16 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 "dce_clocks.h" -+#include "dm_services.h" -+#include "reg_helper.h" -+#include "fixed32_32.h" -+#include "bios_parser_interface.h" -+#include "dc.h" -+ -+ -+#define REG(reg) \ -+ (clk_dce->regs->reg) -+ -+#undef FN -+#define FN(reg_name, field_name) \ -+ clk_dce->clk_shift->field_name, clk_dce->clk_mask->field_name -+ -+#define CTX \ -+ clk_dce->base.ctx -+ -+/* Starting point for each divider range.*/ -+enum 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 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 -+}; -+ -+/* Step size between each divider within a range. -+ Incrementing the DENTIST_DISPCLK_WDIVIDER by one -+ will increment the divider by this much.*/ -+enum 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 */ -+}; -+ -+ -+static int dce_clocks_get_dp_ref_freq(struct display_clock *clk) -+{ -+ struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); -+ int dprefclk_wdivider; -+ int dprefclk_src_sel; -+ int dp_ref_clk_khz = 600000; -+ int target_div = INVALID_DIVIDER; -+ -+ /* ASSERT DP Reference Clock source is from DFS*/ -+ REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel); -+ ASSERT(dprefclk_src_sel == 0); -+ -+ /* Read the mmDENTIST_DISPCLK_CNTL to get the currently -+ * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ -+ REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); -+ -+ /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ -+ target_div = dal_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; -+ } -+ -+ /* 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_gpu_pll && clk_dce->gpu_pll_ss_divider != 0) { -+ struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( -+ dal_fixed32_32_from_fraction( -+ clk_dce->gpu_pll_ss_percentage, -+ clk_dce->gpu_pll_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); -+ } -+ -+ return dp_ref_clk_khz; -+} -+ -+static enum dm_pp_clocks_state dce_get_required_clocks_state( -+ struct display_clock *clk, -+ struct state_dependent_clocks *req_clocks) -+{ -+ struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); -+ int i; -+ enum dm_pp_clocks_state low_req_clk; -+ -+ /* Iterate from highest supported to lowest valid state, and update -+ * lowest RequiredState with the lowest state that satisfies -+ * all required clocks -+ */ -+ for (i = clk->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) -+ if (req_clocks->display_clk_khz > -+ clk_dce->max_clks_by_state[i].display_clk_khz -+ || req_clocks->pixel_clk_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) { -+ dm_logger_write(clk->ctx->logger, LOG_WARNING, -+ "%s: clocks unsupported", __func__); -+ low_req_clk = DM_PP_CLOCKS_STATE_INVALID; -+ } -+ -+ 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.*/ -+ dm_logger_write(clk->ctx->logger, 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 void dce_set_clock( -+ struct display_clock *clk, -+ uint32_t requested_clk_khz) -+{ -+ struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); -+ struct bp_pixel_clock_parameters pxl_clk_params = { 0 }; -+ struct dc_bios *bp = clk->ctx->dc_bios; -+ -+ /* Make sure requested clock isn't lower than minimum threshold*/ -+ if (requested_clk_khz > 0) -+ requested_clk_khz = dm_max(requested_clk_khz, -+ clk_dce->dentist_vco_freq_khz / 64); -+ -+ /* Prepare to program display clock*/ -+ pxl_clk_params.target_pixel_clock = requested_clk_khz; -+ pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; -+ -+ bp->funcs->program_display_engine_pll(bp, &pxl_clk_params); -+ -+ if (clk_dce->dfs_bypass_enabled) { -+ -+ /* Cache the fixed display clock*/ -+ clk_dce->dfs_bypass_disp_clk = -+ pxl_clk_params.dfs_bypass_display_clock; -+ } -+ -+ /* from power down, we need mark the clock state as ClocksStateNominal -+ * from HWReset, so when resume we will call pplib voltage regulator.*/ -+ if (requested_clk_khz == 0) -+ clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; -+} -+ -+#define PSR_SET_WAITLOOP 0x31 -+ -+union dce110_dmcu_psr_config_data_wait_loop_reg1 { -+ struct { -+ unsigned int wait_loop:16; /* [15:0] */ -+ unsigned int reserved:16; /* [31:16] */ -+ } bits; -+ unsigned int u32; -+}; -+ -+static void dce_psr_wait_loop( -+ struct dce_disp_clk *clk_dce, unsigned int display_clk_khz) -+{ -+ struct dc_context *ctx = clk_dce->base.ctx; -+ union dce110_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1; -+ -+ /* waitDMCUReadyForCmd */ -+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 100); -+ -+ masterCmdData1.u32 = 0; -+ masterCmdData1.bits.wait_loop = display_clk_khz / 1000 / 7; -+ dm_write_reg(ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32); -+ -+ /* setDMCUParam_Cmd */ -+ REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP); -+ -+ /* notifyDMCUMsg */ -+ REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); -+} -+ -+static void dce_psr_set_clock( -+ struct display_clock *clk, -+ uint32_t requested_clk_khz) -+{ -+ struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); -+ -+ dce_set_clock(clk, requested_clk_khz); -+ dce_psr_wait_loop(clk_dce, requested_clk_khz); -+} -+ -+static void polaris_set_clock( -+ struct display_clock *clk, -+ uint32_t requested_clk_khz) -+{ -+ struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); -+ struct bp_set_dce_clock_parameters dce_clk_params; -+ struct dc_bios *bp = clk->ctx->dc_bios; -+ -+ /* Prepare to program display clock*/ -+ memset(&dce_clk_params, 0, sizeof(dce_clk_params)); -+ -+ /* Make sure requested clock isn't lower than minimum threshold*/ -+ if (requested_clk_khz > 0) -+ requested_clk_khz = dm_max(requested_clk_khz, -+ clk_dce->dentist_vco_freq_khz / 64); -+ -+ dce_clk_params.target_clock_frequency = requested_clk_khz; -+ dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; -+ dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK; -+ -+ bp->funcs->set_dce_clock(bp, &dce_clk_params); -+ -+ /* from power down, we need mark the clock state as ClocksStateNominal -+ * from HWReset, so when resume we will call pplib voltage regulator.*/ -+ if (requested_clk_khz == 0) -+ clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; -+ -+ /*Program DP ref 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 = 0; -+ -+ bp->funcs->set_dce_clock(bp, &dce_clk_params); -+} -+ -+static void dce_clock_read_integrated_info(struct dce_disp_clk *clk_dce) -+{ -+ struct dc_debug *debug = &clk_dce->base.ctx->dc->debug; -+ struct dc_bios *bp = clk_dce->base.ctx->dc_bios; -+ struct integrated_info info = { 0 }; -+ struct firmware_info fw_info = { 0 }; -+ int i; -+ -+ if (bp->integrated_info) -+ info = *bp->integrated_info; -+ -+ clk_dce->dentist_vco_freq_khz = 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; -+ } -+ -+ /*update the maximum display clock for each power state*/ -+ for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { -+ enum dm_pp_clocks_state clk_state = DM_PP_CLOCKS_STATE_INVALID; -+ -+ switch (i) { -+ case 0: -+ clk_state = DM_PP_CLOCKS_STATE_ULTRA_LOW; -+ break; -+ -+ case 1: -+ clk_state = DM_PP_CLOCKS_STATE_LOW; -+ break; -+ -+ case 2: -+ clk_state = DM_PP_CLOCKS_STATE_NOMINAL; -+ break; -+ -+ case 3: -+ clk_state = DM_PP_CLOCKS_STATE_PERFORMANCE; -+ break; -+ -+ default: -+ clk_state = DM_PP_CLOCKS_STATE_INVALID; -+ break; -+ } -+ -+ /*Do not allow bad VBIOS/SBIOS to override with invalid values, -+ * check for > 100MHz*/ -+ if (info.disp_clk_voltage[i].max_supported_clk >= 100000) -+ clk_dce->max_clks_by_state[clk_state].display_clk_khz = -+ info.disp_clk_voltage[i].max_supported_clk; -+ } -+ -+ if (!debug->disable_dfs_bypass) -+ 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) -+{ -+ struct dc_bios *bp = clk_dce->base.ctx->dc_bios; -+ int ss_info_num = bp->funcs->get_ss_entry_number( -+ bp, AS_SIGNAL_TYPE_GPU_PLL); -+ -+ if (ss_info_num) { -+ struct spread_spectrum_info info = { 0 }; -+ enum bp_result result = bp->funcs->get_spread_spectrum_info( -+ bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info); -+ -+ /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS -+ * even if SS not enabled and in that case -+ * SSInfo.spreadSpectrumPercentage !=0 would be sign -+ * that SS is enabled -+ */ -+ if (result == BP_RESULT_OK && -+ info.spread_spectrum_percentage != 0) { -+ clk_dce->ss_on_gpu_pll = true; -+ clk_dce->gpu_pll_ss_divider = info.spread_percentage_divider; -+ -+ if (info.type.CENTER_MODE == 0) { -+ /* Currently for DP Reference clock we -+ * need only SS percentage for -+ * downspread */ -+ clk_dce->gpu_pll_ss_percentage = -+ info.spread_spectrum_percentage; -+ } -+ } -+ -+ } -+} -+ -+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 = polaris_set_clock -+}; -+ -+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 -+}; -+ -+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 -+}; -+ -+static void dce_disp_clk_construct( -+ struct dce_disp_clk *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) -+{ -+ struct display_clock *base = &clk_dce->base; -+ -+ base->ctx = ctx; -+ base->funcs = &dce_funcs; -+ -+ clk_dce->regs = regs; -+ clk_dce->clk_shift = clk_shift; -+ clk_dce->clk_mask = clk_mask; -+ -+ clk_dce->dfs_bypass_disp_clk = 0; -+ clk_dce->gpu_pll_ss_percentage = 0; -+ clk_dce->gpu_pll_ss_divider = 1000; -+ clk_dce->ss_on_gpu_pll = false; -+ base->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; -+ base->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID; -+ -+ dce_clock_read_integrated_info(clk_dce); -+ dce_clock_read_ss_info(clk_dce); -+ -+ dal_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); -+ dal_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); -+ dal_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 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) -+{ -+ struct dce_disp_clk *clk_dce = dm_alloc(sizeof(*clk_dce)); -+ -+ if (clk_dce == NULL) { -+ BREAK_TO_DEBUGGER(); -+ return NULL; -+ } -+ -+ dce_disp_clk_construct( -+ clk_dce, ctx, regs, clk_shift, clk_mask); -+ -+ return &clk_dce->base; -+} -+ -+struct display_clock *dce110_disp_clk_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) -+{ -+ struct dce_disp_clk *clk_dce = dm_alloc(sizeof(*clk_dce)); -+ -+ if (clk_dce == NULL) { -+ BREAK_TO_DEBUGGER(); -+ return NULL; -+ } -+ -+ dce_disp_clk_construct( -+ clk_dce, ctx, regs, clk_shift, clk_mask); -+ -+ clk_dce->base.funcs = &dce110_funcs; -+ -+ return &clk_dce->base; -+} -+ -+struct display_clock *dce112_disp_clk_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) -+{ -+ struct dce_disp_clk *clk_dce = dm_alloc(sizeof(*clk_dce)); -+ -+ if (clk_dce == NULL) { -+ BREAK_TO_DEBUGGER(); -+ return NULL; -+ } -+ -+ dce_disp_clk_construct( -+ clk_dce, ctx, regs, clk_shift, clk_mask); -+ -+ clk_dce->base.funcs = &dce112_funcs; -+ -+ return &clk_dce->base; -+} -+ -+void dce_disp_clk_destroy(struct display_clock **disp_clk) -+{ -+ struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(*disp_clk); -+ -+ dm_free(clk_dce); -+ *disp_clk = 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 -new file mode 100644 -index 0000000..e3b2374 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h -@@ -0,0 +1,133 @@ -+/* -+ * Copyright 2012-16 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 _DCE_CLOCKS_H_ -+#define _DCE_CLOCKS_H_ -+ -+#include "display_clock_interface.h" -+#include "../gpu/divider_range.h" -+ -+ -+#define TO_DCE_CLOCKS(clocks)\ -+ container_of(clocks, struct dce_disp_clk, base) -+ -+#define CLK_COMMON_REG_LIST_DCE_BASE() \ -+ .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ -+ .DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL, \ -+ .MASTER_COMM_DATA_REG1 = mmMASTER_COMM_DATA_REG1, \ -+ .MASTER_COMM_CMD_REG = mmMASTER_COMM_CMD_REG, \ -+ .MASTER_COMM_CNTL_REG = mmMASTER_COMM_CNTL_REG -+ -+#define CLK_SF(reg_name, field_name, post_fix)\ -+ .field_name = reg_name ## __ ## field_name ## post_fix -+ -+#define CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \ -+ CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \ -+ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh), \ -+ CLK_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, mask_sh), \ -+ CLK_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh) -+ -+ -+#define CLK_REG_FIELD_LIST(type) \ -+ type DPREFCLK_SRC_SEL; \ -+ type DENTIST_DPREFCLK_WDIVIDER; \ -+ type MASTER_COMM_CMD_REG_BYTE0; \ -+ type MASTER_COMM_INTERRUPT -+ -+struct dce_disp_clk_shift { -+ CLK_REG_FIELD_LIST(uint8_t); -+}; -+ -+struct dce_disp_clk_mask { -+ CLK_REG_FIELD_LIST(uint32_t); -+}; -+ -+struct dce_disp_clk_registers { -+ uint32_t DPREFCLK_CNTL; -+ uint32_t DENTIST_DISPCLK_CNTL; -+ uint32_t MASTER_COMM_DATA_REG1; -+ uint32_t MASTER_COMM_CMD_REG; -+ uint32_t MASTER_COMM_CNTL_REG; -+}; -+ -+/* Array identifiers and count for the divider ranges.*/ -+enum divider_range_count { -+ DIVIDER_RANGE_01 = 0, -+ DIVIDER_RANGE_02, -+ DIVIDER_RANGE_03, -+ DIVIDER_RANGE_MAX /* == 3*/ -+}; -+ -+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 state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; -+ struct divider_range divider_ranges[DIVIDER_RANGE_MAX]; -+ -+ bool use_max_disp_clk; -+ uint32_t dentist_vco_freq_khz; -+ -+ /* Cache the status of DFS-bypass feature*/ -+ bool dfs_bypass_enabled; -+ /* Cache the display clock returned by VBIOS if DFS-bypass is enabled. -+ * This is basically "Crystal Frequency In KHz" (XTALIN) frequency */ -+ uint32_t dfs_bypass_disp_clk; -+ -+ /* Flag for Enabled SS on GPU PLL */ -+ bool ss_on_gpu_pll; -+ /* GPU PLL SS percentage (if down-spread enabled) */ -+ uint32_t gpu_pll_ss_percentage; -+ /* GPU PLL SS percentage Divider (100 or 1000) */ -+ uint32_t gpu_pll_ss_divider; -+ -+ -+}; -+ -+ -+struct display_clock *dce_disp_clk_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); -+ -+struct display_clock *dce110_disp_clk_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); -+ -+struct display_clock *dce112_disp_clk_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); -+ -+void dce_disp_clk_destroy(struct display_clock **disp_clk); -+ -+#endif /* _DCE_CLOCKS_H_ */ -diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c -index 5716ce1..c97416f 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c -@@ -40,6 +40,7 @@ - #include "dce110/dce110_ipp.h" - #include "dce/dce_transform.h" - #include "dce110/dce110_opp.h" -+#include "dce/dce_clocks.h" - #include "dce/dce_clock_source.h" - #include "dce/dce_audio.h" - #include "dce/dce_hwseq.h" -@@ -200,6 +201,18 @@ static const struct dce110_ipp_reg_offsets dce100_ipp_reg_offsets[] = { - .reg_name = mm ## block ## id ## _ ## reg_name - - -+static const struct dce_disp_clk_registers disp_clk_regs = { -+ CLK_COMMON_REG_LIST_DCE_BASE() -+}; -+ -+static const struct dce_disp_clk_shift disp_clk_shift = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -+}; -+ -+static const struct dce_disp_clk_mask disp_clk_mask = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -+}; -+ - #define transform_regs(id)\ - [id] = {\ - XFM_COMMON_REG_LIST_DCE100(id)\ -@@ -717,9 +730,7 @@ static void destruct(struct dce110_resource_pool *pool) - } - - if (pool->base.display_clock != NULL) -- pool->base.display_clock->funcs->destroy( -- &pool->base.display_clock); -- pool->base.display_clock = NULL; -+ dce_disp_clk_destroy(&pool->base.display_clock); - - if (pool->base.irqs != NULL) - dal_irq_service_destroy(&pool->base.irqs); -@@ -970,7 +981,10 @@ static bool construct( - } - } - -- pool->base.display_clock = dal_display_clock_dce110_create(ctx); -+ pool->base.display_clock = dce_disp_clk_create(ctx, -+ &disp_clk_regs, -+ &disp_clk_shift, -+ &disp_clk_mask); - if (pool->base.display_clock == NULL) { - dm_error("DC: failed to create display clock!\n"); - BREAK_TO_DEBUGGER(); -diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c -index 8682c8b..fa601f7 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c -@@ -45,6 +45,7 @@ - #include "dce110/dce110_transform_v.h" - #include "dce110/dce110_opp.h" - #include "dce110/dce110_opp_v.h" -+#include "dce/dce_clocks.h" - #include "dce/dce_clock_source.h" - #include "dce/dce_hwseq.h" - #include "dce110/dce110_hw_sequencer.h" -@@ -187,6 +188,17 @@ static const struct dce110_ipp_reg_offsets dce110_ipp_reg_offsets[] = { - #define SRI(reg_name, block, id)\ - .reg_name = mm ## block ## id ## _ ## reg_name - -+static const struct dce_disp_clk_registers disp_clk_regs = { -+ CLK_COMMON_REG_LIST_DCE_BASE() -+}; -+ -+static const struct dce_disp_clk_shift disp_clk_shift = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -+}; -+ -+static const struct dce_disp_clk_mask disp_clk_mask = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -+}; - - #define transform_regs(id)\ - [id] = {\ -@@ -699,11 +711,8 @@ static void destruct(struct dce110_resource_pool *pool) - } - } - -- if (pool->base.display_clock != NULL) { -- pool->base.display_clock->funcs->destroy( -- &pool->base.display_clock); -- pool->base.display_clock = NULL; -- } -+ if (pool->base.display_clock != NULL) -+ dce_disp_clk_destroy(&pool->base.display_clock); - - if (pool->base.irqs != NULL) { - dal_irq_service_destroy(&pool->base.irqs); -@@ -1261,7 +1270,10 @@ static bool construct( - } - } - -- pool->base.display_clock = dal_display_clock_dce110_create(ctx); -+ pool->base.display_clock = dce110_disp_clk_create(ctx, -+ &disp_clk_regs, -+ &disp_clk_shift, -+ &disp_clk_mask); - if (pool->base.display_clock == NULL) { - dm_error("DC: failed to create display clock!\n"); - BREAK_TO_DEBUGGER(); -diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c -index c50a215..3a47830 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c -@@ -41,6 +41,7 @@ - #include "dce/dce_audio.h" - #include "dce112/dce112_opp.h" - #include "dce110/dce110_ipp.h" -+#include "dce/dce_clocks.h" - #include "dce/dce_clock_source.h" - - #include "dce/dce_hwseq.h" -@@ -204,6 +205,19 @@ static const struct dce110_ipp_reg_offsets ipp_reg_offsets[] = { - #define SRI(reg_name, block, id)\ - .reg_name = mm ## block ## id ## _ ## reg_name - -+ -+static const struct dce_disp_clk_registers disp_clk_regs = { -+ CLK_COMMON_REG_LIST_DCE_BASE() -+}; -+ -+static const struct dce_disp_clk_shift disp_clk_shift = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -+}; -+ -+static const struct dce_disp_clk_mask disp_clk_mask = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -+}; -+ - #define transform_regs(id)\ - [id] = {\ - XFM_COMMON_REG_LIST_DCE110(id)\ -@@ -733,11 +747,8 @@ static void destruct(struct dce110_resource_pool *pool) - } - } - -- if (pool->base.display_clock != NULL) { -- pool->base.display_clock->funcs->destroy( -- &pool->base.display_clock); -- pool->base.display_clock = NULL; -- } -+ if (pool->base.display_clock != NULL) -+ dce_disp_clk_destroy(&pool->base.display_clock); - - if (pool->base.irqs != NULL) { - dal_irq_service_destroy(&pool->base.irqs); -@@ -1299,9 +1310,10 @@ static bool construct( - } - } - -- pool->base.display_clock = dal_display_clock_dce112_create( -- ctx); -- -+ pool->base.display_clock = dce112_disp_clk_create(ctx, -+ &disp_clk_regs, -+ &disp_clk_shift, -+ &disp_clk_mask); - if (pool->base.display_clock == NULL) { - dm_error("DC: failed to create display clock!\n"); - BREAK_TO_DEBUGGER(); -diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c -index 1d2a31e..517d42d 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c -@@ -45,6 +45,7 @@ - #include "dce/dce_transform.h" - #include "dce80/dce80_opp.h" - #include "dce110/dce110_ipp.h" -+#include "dce/dce_clocks.h" - #include "dce/dce_clock_source.h" - #include "dce/dce_audio.h" - #include "dce/dce_hwseq.h" -@@ -215,6 +216,19 @@ static const struct dce110_ipp_reg_offsets ipp_reg_offsets[] = { - #define SRI(reg_name, block, id)\ - .reg_name = mm ## block ## id ## _ ## reg_name - -+ -+static const struct dce_disp_clk_registers disp_clk_regs = { -+ CLK_COMMON_REG_LIST_DCE_BASE() -+}; -+ -+static const struct dce_disp_clk_shift disp_clk_shift = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -+}; -+ -+static const struct dce_disp_clk_mask disp_clk_mask = { -+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -+}; -+ - #define transform_regs(id)\ - [id] = {\ - XFM_COMMON_REG_LIST_DCE_BASE(id)\ -@@ -656,11 +670,8 @@ static void destruct(struct dce110_resource_pool *pool) - } - } - -- if (pool->base.display_clock != NULL) { -- pool->base.display_clock->funcs->destroy( -- &pool->base.display_clock); -- pool->base.display_clock = NULL; -- } -+ if (pool->base.display_clock != NULL) -+ dce_disp_clk_destroy(&pool->base.display_clock); - - if (pool->base.irqs != NULL) { - dal_irq_service_destroy(&pool->base.irqs); -@@ -857,47 +868,6 @@ static const struct resource_funcs dce80_res_pool_funcs = { - .validate_bandwidth = dce80_validate_bandwidth - }; - --static enum dm_pp_clocks_state dce80_resource_convert_clock_state_pp_to_dc( -- enum dm_pp_clocks_state pp_clock_state) --{ -- enum dm_pp_clocks_state dc_clocks_state = DM_PP_CLOCKS_STATE_INVALID; -- -- switch (pp_clock_state) { -- case DM_PP_CLOCKS_STATE_INVALID: -- dc_clocks_state = DM_PP_CLOCKS_STATE_INVALID; -- break; -- case DM_PP_CLOCKS_STATE_ULTRA_LOW: -- dc_clocks_state = DM_PP_CLOCKS_STATE_ULTRA_LOW; -- break; -- case DM_PP_CLOCKS_STATE_LOW: -- dc_clocks_state = DM_PP_CLOCKS_STATE_LOW; -- break; -- case DM_PP_CLOCKS_STATE_NOMINAL: -- dc_clocks_state = DM_PP_CLOCKS_STATE_NOMINAL; -- break; -- case DM_PP_CLOCKS_STATE_PERFORMANCE: -- dc_clocks_state = DM_PP_CLOCKS_STATE_PERFORMANCE; -- break; -- case DM_PP_CLOCKS_DPM_STATE_LEVEL_4: -- dc_clocks_state = DM_PP_CLOCKS_DPM_STATE_LEVEL_4; -- break; -- case DM_PP_CLOCKS_DPM_STATE_LEVEL_5: -- dc_clocks_state = DM_PP_CLOCKS_DPM_STATE_LEVEL_5; -- break; -- case DM_PP_CLOCKS_DPM_STATE_LEVEL_6: -- dc_clocks_state = DM_PP_CLOCKS_DPM_STATE_LEVEL_6; -- break; -- case DM_PP_CLOCKS_DPM_STATE_LEVEL_7: -- dc_clocks_state = DM_PP_CLOCKS_DPM_STATE_LEVEL_7; -- break; -- default: -- dc_clocks_state = DM_PP_CLOCKS_STATE_INVALID; -- break; -- } -- -- return dc_clocks_state; --} -- - static bool construct( - uint8_t num_virtual_links, - struct core_dc *dc, -@@ -967,7 +937,10 @@ static bool construct( - } - } - -- pool->base.display_clock = dal_display_clock_dce80_create(ctx); -+ pool->base.display_clock = dce_disp_clk_create(ctx, -+ &disp_clk_regs, -+ &disp_clk_shift, -+ &disp_clk_mask); - if (pool->base.display_clock == NULL) { - dm_error("DC: failed to create display clock!\n"); - BREAK_TO_DEBUGGER(); -@@ -977,8 +950,7 @@ static bool construct( - - if (dm_pp_get_static_clocks(ctx, &static_clk_info)) - pool->base.display_clock->max_clks_state = -- dce80_resource_convert_clock_state_pp_to_dc( -- static_clk_info.max_clocks_state); -+ static_clk_info.max_clocks_state; - - { - struct irq_service_init_data init_data; -diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h b/drivers/gpu/drm/amd/display/dc/dm_services_types.h -index 44bad17..460971d 100644 ---- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h -+++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h -@@ -43,15 +43,17 @@ enum dm_pp_clocks_state { - - /* Starting from DCE11, Max 8 levels of DPM state supported. */ - DM_PP_CLOCKS_DPM_STATE_LEVEL_INVALID = DM_PP_CLOCKS_STATE_INVALID, -- DM_PP_CLOCKS_DPM_STATE_LEVEL_0 = DM_PP_CLOCKS_STATE_ULTRA_LOW, -- DM_PP_CLOCKS_DPM_STATE_LEVEL_1 = DM_PP_CLOCKS_STATE_LOW, -- DM_PP_CLOCKS_DPM_STATE_LEVEL_2 = DM_PP_CLOCKS_STATE_NOMINAL, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_0, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_1, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_2, - /* to be backward compatible */ -- DM_PP_CLOCKS_DPM_STATE_LEVEL_3 = DM_PP_CLOCKS_STATE_PERFORMANCE, -- DM_PP_CLOCKS_DPM_STATE_LEVEL_4 = DM_PP_CLOCKS_DPM_STATE_LEVEL_3 + 1, -- DM_PP_CLOCKS_DPM_STATE_LEVEL_5 = DM_PP_CLOCKS_DPM_STATE_LEVEL_4 + 1, -- DM_PP_CLOCKS_DPM_STATE_LEVEL_6 = DM_PP_CLOCKS_DPM_STATE_LEVEL_5 + 1, -- DM_PP_CLOCKS_DPM_STATE_LEVEL_7 = DM_PP_CLOCKS_DPM_STATE_LEVEL_6 + 1, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_3, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_4, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_5, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_6, -+ DM_PP_CLOCKS_DPM_STATE_LEVEL_7, -+ -+ DM_PP_CLOCKS_MAX_STATES - }; - - struct dm_pp_gpu_clock_range { -diff --git a/drivers/gpu/drm/amd/display/dc/gpu/Makefile b/drivers/gpu/drm/amd/display/dc/gpu/Makefile -index 0b99a74..6ab4078 100644 ---- a/drivers/gpu/drm/amd/display/dc/gpu/Makefile -+++ b/drivers/gpu/drm/amd/display/dc/gpu/Makefile -@@ -10,23 +10,8 @@ AMD_DAL_GPU = $(addprefix $(AMDDALPATH)/dc/gpu/,$(GPU)) - AMD_DISPLAY_FILES += $(AMD_DAL_GPU) - - ############################################################################### --# DCE 80 family --############################################################################### --GPU_DCE80 = display_clock_dce80.o -- --AMD_DAL_GPU_DCE80 = $(addprefix $(AMDDALPATH)/dc/gpu/dce80/,$(GPU_DCE80)) -- --AMD_DISPLAY_FILES += $(AMD_DAL_GPU_DCE80) -- -- --############################################################################### - # DCE 110 family - ############################################################################### --GPU_DCE110 = display_clock_dce110.o -- --AMD_DAL_GPU_DCE110 = $(addprefix $(AMDDALPATH)/dc/gpu/dce110/,$(GPU_DCE110)) -- --AMD_DISPLAY_FILES += $(AMD_DAL_GPU_DCE110) - - GPU_DCE112 = display_clock_dce112.o - -diff --git a/drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.c b/drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.c -deleted file mode 100644 -index 9dabaac..0000000 ---- a/drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.c -+++ /dev/null -@@ -1,516 +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 "dce/dce_11_0_d.h" --#include "dce/dce_11_0_sh_mask.h" -- --#include "include/bios_parser_interface.h" --#include "include/fixed32_32.h" --#include "include/logger_interface.h" -- --#include "../divider_range.h" -- --#include "display_clock_dce110.h" --#include "dc.h" -- --#define FROM_DISPLAY_CLOCK(base) \ -- container_of(base, struct display_clock_dce110, disp_clk_base) -- --#define PSR_SET_WAITLOOP 0x31 -- --static struct state_dependent_clocks max_clks_by_state[] = { --/*ClocksStateInvalid - should not be used*/ --{ .display_clk_khz = 0, .pixel_clk_khz = 0 }, --/*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ --{ .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, --/*ClocksStateLow*/ --{ .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, --/*ClocksStateNominal*/ --{ .display_clk_khz = 467000, .pixel_clk_khz = 400000 }, --/*ClocksStatePerformance*/ --{ .display_clk_khz = 643000, .pixel_clk_khz = 400000 } }; -- --/* Starting point for each divider range.*/ --enum 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.*/ --}; -- --/* Array identifiers and count for the divider ranges.*/ --enum divider_range_count { -- DIVIDER_RANGE_01 = 0, -- DIVIDER_RANGE_02, -- DIVIDER_RANGE_03, -- DIVIDER_RANGE_MAX /* == 3*/ --}; -- --/* Ranges for divider identifiers (Divider ID or DID) -- mmDENTIST_DISPCLK_CNTL.DENTIST_DISPCLK_WDIVIDER*/ --enum 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 --}; -- --/* Step size between each divider within a range. -- Incrementing the DENTIST_DISPCLK_WDIVIDER by one -- will increment the divider by this much.*/ --enum 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 */ --}; -- --union dce110_dmcu_psr_config_data_wait_loop_reg1 { -- struct { -- unsigned int waitLoop:16; /* [15:0] */ -- unsigned int reserved:16; /* [31:16] */ -- } bits; -- unsigned int u32All; --}; -- --static struct divider_range divider_ranges[DIVIDER_RANGE_MAX]; -- --#define DCE110_DFS_BYPASS_THRESHOLD_KHZ 400000 --/***************************************************************************** -- * static functions -- *****************************************************************************/ -- --static bool dce110_set_min_clocks_state( -- struct display_clock *dc, -- enum dm_pp_clocks_state clocks_state) --{ -- struct dm_pp_power_level_change_request level_change_req = { -- clocks_state }; -- -- if (clocks_state > dc->max_clks_state) { -- /*Requested state exceeds max supported state.*/ -- dm_logger_write(dc->ctx->logger, LOG_WARNING, -- "Requested state exceeds max supported state"); -- return false; -- } else if (clocks_state == dc->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(dc->ctx, &level_change_req)) -- dc->cur_min_clks_state = clocks_state; -- -- return true; --} -- --static uint32_t get_dp_ref_clk_frequency(struct display_clock *dc) --{ -- uint32_t dispclk_cntl_value; -- uint32_t dp_ref_clk_cntl_value; -- uint32_t dp_ref_clk_cntl_src_sel_value; -- uint32_t dp_ref_clk_khz = 600000; -- uint32_t target_div = INVALID_DIVIDER; -- struct display_clock_dce110 *disp_clk = FROM_DISPLAY_CLOCK(dc); -- -- /* ASSERT DP Reference Clock source is from DFS*/ -- dp_ref_clk_cntl_value = dm_read_reg(dc->ctx, -- mmDPREFCLK_CNTL); -- -- dp_ref_clk_cntl_src_sel_value = -- get_reg_field_value( -- dp_ref_clk_cntl_value, -- DPREFCLK_CNTL, DPREFCLK_SRC_SEL); -- -- ASSERT(dp_ref_clk_cntl_src_sel_value == 0); -- -- /* Read the mmDENTIST_DISPCLK_CNTL to get the currently -- * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ -- dispclk_cntl_value = dm_read_reg(dc->ctx, -- mmDENTIST_DISPCLK_CNTL); -- -- /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ -- target_div = dal_divider_range_get_divider( -- divider_ranges, -- DIVIDER_RANGE_MAX, -- get_reg_field_value(dispclk_cntl_value, -- DENTIST_DISPCLK_CNTL, -- DENTIST_DPREFCLK_WDIVIDER)); -- -- if (target_div != INVALID_DIVIDER) { -- /* Calculate the current DFS clock, in kHz.*/ -- dp_ref_clk_khz = (DIVIDER_RANGE_SCALE_FACTOR -- * disp_clk->dentist_vco_freq_khz) / target_div; -- } -- -- /* 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 ((disp_clk->ss_on_gpu_pll) && (disp_clk->gpu_pll_ss_divider != 0)) { -- struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( -- dal_fixed32_32_from_fraction( -- disp_clk->gpu_pll_ss_percentage, -- disp_clk->gpu_pll_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); -- } -- -- return dp_ref_clk_khz; --} -- --static void destroy(struct display_clock **base) --{ -- struct display_clock_dce110 *dc110; -- -- dc110 = DCLCK110_FROM_BASE(*base); -- -- dm_free(dc110); -- -- *base = NULL; --} -- --static bool display_clock_integrated_info_construct( -- struct display_clock_dce110 *disp_clk) --{ -- struct dc_debug *debug = &disp_clk->disp_clk_base.ctx->dc->debug; -- struct dc_bios *bp = disp_clk->disp_clk_base.ctx->dc_bios; -- struct integrated_info info; -- struct firmware_info fw_info; -- uint32_t i; -- struct display_clock *base = &disp_clk->disp_clk_base; -- -- memset(&info, 0, sizeof(struct integrated_info)); -- memset(&fw_info, 0, sizeof(struct firmware_info)); -- -- if (bp->integrated_info) -- info = *bp->integrated_info; -- -- disp_clk->dentist_vco_freq_khz = info.dentist_vco_freq; -- if (disp_clk->dentist_vco_freq_khz == 0) { -- bp->funcs->get_firmware_info(bp, &fw_info); -- disp_clk->dentist_vco_freq_khz = -- fw_info.smu_gpu_pll_output_freq; -- if (disp_clk->dentist_vco_freq_khz == 0) -- disp_clk->dentist_vco_freq_khz = 3600000; -- } -- -- base->min_display_clk_threshold_khz = -- disp_clk->dentist_vco_freq_khz / 64; -- -- if (bp->integrated_info == NULL) -- return false; -- -- /*update the maximum display clock for each power state*/ -- for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { -- enum dm_pp_clocks_state clk_state = DM_PP_CLOCKS_STATE_INVALID; -- -- switch (i) { -- case 0: -- clk_state = DM_PP_CLOCKS_STATE_ULTRA_LOW; -- break; -- -- case 1: -- clk_state = DM_PP_CLOCKS_STATE_LOW; -- break; -- -- case 2: -- clk_state = DM_PP_CLOCKS_STATE_NOMINAL; -- break; -- -- case 3: -- clk_state = DM_PP_CLOCKS_STATE_PERFORMANCE; -- break; -- -- default: -- clk_state = DM_PP_CLOCKS_STATE_INVALID; -- break; -- } -- -- /*Do not allow bad VBIOS/SBIOS to override with invalid values, -- * check for > 100MHz*/ -- if (info.disp_clk_voltage[i].max_supported_clk >= 100000) { -- max_clks_by_state[clk_state].display_clk_khz = -- info.disp_clk_voltage[i].max_supported_clk; -- } -- } -- -- disp_clk->dfs_bypass_enabled = false; -- if (!debug->disable_dfs_bypass) -- if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) -- disp_clk->dfs_bypass_enabled = true; -- -- disp_clk->use_max_disp_clk = debug->max_disp_clk; -- -- return true; --} -- --static enum dm_pp_clocks_state get_required_clocks_state( -- struct display_clock *dc, -- struct state_dependent_clocks *req_clocks) --{ -- int32_t i; -- struct display_clock_dce110 *disp_clk = DCLCK110_FROM_BASE(dc); -- enum dm_pp_clocks_state low_req_clk = dc->max_clks_state; -- -- if (!req_clocks) { -- /* NULL pointer*/ -- dm_logger_write(dc->ctx->logger, LOG_WARNING, -- "%s: Invalid parameter", -- __func__); -- return DM_PP_CLOCKS_STATE_INVALID; -- } -- -- /* Iterate from highest supported to lowest valid state, and update -- * lowest RequiredState with the lowest state that satisfies -- * all required clocks -- */ -- for (i = dc->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; --i) { -- if ((req_clocks->display_clk_khz <= -- max_clks_by_state[i].display_clk_khz) && -- (req_clocks->pixel_clk_khz <= -- max_clks_by_state[i].pixel_clk_khz)) -- low_req_clk = i; -- } -- return low_req_clk; --} -- --static void psr_wait_loop(struct dc_context *ctx, unsigned int display_clk_khz) --{ -- unsigned int dmcu_max_retry_on_wait_reg_ready = 801; -- unsigned int dmcu_wait_reg_ready_interval = 100; -- unsigned int regValue; -- uint32_t masterCmd; -- uint32_t masterComCntl; -- union dce110_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1; -- -- /* waitDMCUReadyForCmd */ -- do { -- dm_delay_in_microseconds(ctx, dmcu_wait_reg_ready_interval); -- regValue = dm_read_reg(ctx, mmMASTER_COMM_CNTL_REG); -- dmcu_max_retry_on_wait_reg_ready--; -- } while -- /* expected value is 0, loop while not 0*/ -- ((MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK & regValue) && -- dmcu_max_retry_on_wait_reg_ready > 0); -- -- masterCmdData1.u32All = 0; -- masterCmdData1.bits.waitLoop = display_clk_khz / 1000 / 7; -- dm_write_reg(ctx, mmMASTER_COMM_DATA_REG1, masterCmdData1.u32All); -- -- /* setDMCUParam_Cmd */ -- masterCmd = dm_read_reg(ctx, mmMASTER_COMM_CMD_REG); -- set_reg_field_value( -- masterCmd, -- PSR_SET_WAITLOOP, -- MASTER_COMM_CMD_REG, -- MASTER_COMM_CMD_REG_BYTE0); -- -- dm_write_reg(ctx, mmMASTER_COMM_CMD_REG, masterCmd); -- -- /* notifyDMCUMsg */ -- masterComCntl = dm_read_reg(ctx, mmMASTER_COMM_CNTL_REG); -- set_reg_field_value( -- masterComCntl, -- 1, -- MASTER_COMM_CNTL_REG, -- MASTER_COMM_INTERRUPT); -- dm_write_reg(ctx, mmMASTER_COMM_CNTL_REG, masterComCntl); --} -- --static void dce110_set_clock( -- struct display_clock *base, -- uint32_t requested_clk_khz) --{ -- struct bp_pixel_clock_parameters pxl_clk_params; -- struct display_clock_dce110 *dc = DCLCK110_FROM_BASE(base); -- struct dc_bios *bp = base->ctx->dc_bios; -- -- /* Prepare to program display clock*/ -- memset(&pxl_clk_params, 0, sizeof(pxl_clk_params)); -- -- /* Make sure requested clock isn't lower than minimum threshold*/ -- if (requested_clk_khz > 0) -- requested_clk_khz = dm_max(requested_clk_khz, -- base->min_display_clk_threshold_khz); -- -- pxl_clk_params.target_pixel_clock = requested_clk_khz; -- pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; -- -- bp->funcs->program_display_engine_pll(bp, &pxl_clk_params); -- -- if (dc->dfs_bypass_enabled) { -- -- /* Cache the fixed display clock*/ -- dc->dfs_bypass_disp_clk = -- pxl_clk_params.dfs_bypass_display_clock; -- } -- -- /* from power down, we need mark the clock state as ClocksStateNominal -- * from HWReset, so when resume we will call pplib voltage regulator.*/ -- if (requested_clk_khz == 0) -- base->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; -- -- psr_wait_loop(base->ctx, requested_clk_khz); --} -- -- --static const struct display_clock_funcs funcs = { -- .destroy = destroy, -- .get_dp_ref_clk_frequency = get_dp_ref_clk_frequency, -- .get_required_clocks_state = get_required_clocks_state, -- .set_clock = dce110_set_clock, -- .set_min_clocks_state = dce110_set_min_clocks_state --}; -- --static bool dal_display_clock_dce110_construct( -- struct display_clock_dce110 *dc110, -- struct dc_context *ctx) --{ -- struct display_clock *dc_base = &dc110->disp_clk_base; -- struct dc_bios *bp = ctx->dc_bios; -- -- dc_base->ctx = ctx; -- dc_base->min_display_clk_threshold_khz = 0; -- -- dc_base->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID; -- -- dc_base->funcs = &funcs; -- -- dc110->dfs_bypass_disp_clk = 0; -- -- if (!display_clock_integrated_info_construct(dc110)) -- dm_logger_write(dc_base->ctx->logger, LOG_WARNING, -- "Cannot obtain VBIOS integrated info\n"); -- -- dc110->gpu_pll_ss_percentage = 0; -- dc110->gpu_pll_ss_divider = 1000; -- dc110->ss_on_gpu_pll = false; -- --/* Initially set max clocks state to nominal. This should be updated by -- * via a pplib call to DAL IRI eventually calling a -- * DisplayEngineClock_Dce110::StoreMaxClocksState(). This call will come in -- * on PPLIB init. This is from DCE5x. in case HW wants to use mixed method.*/ -- dc_base->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; -- -- dal_divider_range_construct( -- ÷r_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); -- dal_divider_range_construct( -- ÷r_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); -- dal_divider_range_construct( -- ÷r_ranges[DIVIDER_RANGE_03], -- DIVIDER_RANGE_03_START, -- DIVIDER_RANGE_03_STEP_SIZE, -- DIVIDER_RANGE_03_BASE_DIVIDER_ID, -- DIVIDER_RANGE_MAX_DIVIDER_ID); -- -- { -- uint32_t ss_info_num = -- bp->funcs->get_ss_entry_number(bp, -- AS_SIGNAL_TYPE_GPU_PLL); -- -- if (ss_info_num) { -- struct spread_spectrum_info info; -- enum bp_result result; -- -- memset(&info, 0, sizeof(info)); -- -- result = bp->funcs->get_spread_spectrum_info(bp, -- AS_SIGNAL_TYPE_GPU_PLL, -- 0, -- &info); -- -- /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS -- * even if SS not enabled and in that case -- * SSInfo.spreadSpectrumPercentage !=0 would be sign -- * that SS is enabled -- */ -- if (result == BP_RESULT_OK && -- info.spread_spectrum_percentage != 0) { -- dc110->ss_on_gpu_pll = true; -- dc110->gpu_pll_ss_divider = -- info.spread_percentage_divider; -- -- if (info.type.CENTER_MODE == 0) { -- /* Currently for DP Reference clock we -- * need only SS percentage for -- * downspread */ -- dc110->gpu_pll_ss_percentage = -- info.spread_spectrum_percentage; -- } -- } -- -- } -- } -- -- return true; --} -- --/***************************************************************************** -- * public functions -- *****************************************************************************/ -- --struct display_clock *dal_display_clock_dce110_create( -- struct dc_context *ctx) --{ -- struct display_clock_dce110 *dc110; -- -- dc110 = dm_alloc(sizeof(struct display_clock_dce110)); -- -- if (dc110 == NULL) -- return NULL; -- -- if (dal_display_clock_dce110_construct(dc110, ctx)) -- return &dc110->disp_clk_base; -- -- dm_free(dc110); -- -- return NULL; --} -diff --git a/drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.h b/drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.h -deleted file mode 100644 -index 50b51c4..0000000 ---- a/drivers/gpu/drm/amd/display/dc/gpu/dce110/display_clock_dce110.h -+++ /dev/null -@@ -1,50 +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 __DAL_DISPLAY_CLOCK_DCE110_H__ --#define __DAL_DISPLAY_CLOCK_DCE110_H__ -- --#include "display_clock_interface.h" -- --struct display_clock_dce110 { -- struct display_clock disp_clk_base; -- bool use_max_disp_clk; -- uint32_t dentist_vco_freq_khz; -- /* Cache the status of DFS-bypass feature*/ -- bool dfs_bypass_enabled; -- /* GPU PLL SS percentage (if down-spread enabled) */ -- uint32_t gpu_pll_ss_percentage; -- /* GPU PLL SS percentage Divider (100 or 1000) */ -- uint32_t gpu_pll_ss_divider; -- /* Flag for Enabled SS on GPU PLL */ -- bool ss_on_gpu_pll; -- /* Cache the display clock returned by VBIOS if DFS-bypass is enabled. -- * This is basically "Crystal Frequency In KHz" (XTALIN) frequency */ -- uint32_t dfs_bypass_disp_clk; --}; -- --#define DCLCK110_FROM_BASE(dc_base) \ -- container_of(dc_base, struct display_clock_dce110, disp_clk_base) -- --#endif /* __DAL_DISPLAY_CLOCK_DCE110_H__ */ -diff --git a/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.c b/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.c -index 930548b..e0d67fb 100644 ---- a/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.c -+++ b/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.c -@@ -71,102 +71,6 @@ enum divider_range_step_size { - - static struct divider_range divider_ranges[DIVIDER_RANGE_MAX]; - --#define dce112_DFS_BYPASS_THRESHOLD_KHZ 400000 -- --static bool dce112_set_min_clocks_state( -- struct display_clock *dc, -- enum dm_pp_clocks_state clocks_state) --{ -- struct dm_pp_power_level_change_request level_change_req = { -- clocks_state }; -- -- if (clocks_state > dc->max_clks_state) { -- /*Requested state exceeds max supported state.*/ -- dm_logger_write(dc->ctx->logger, LOG_WARNING, -- "Requested state exceeds max supported state"); -- return false; -- } else if (clocks_state == dc->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(dc->ctx, &level_change_req)) -- dc->cur_min_clks_state = clocks_state; -- -- return true; --} -- --static uint32_t get_dp_ref_clk_frequency(struct display_clock *dc) --{ -- uint32_t dispclk_cntl_value; -- uint32_t dp_ref_clk_cntl_value; -- uint32_t dp_ref_clk_cntl_src_sel_value; -- uint32_t dp_ref_clk_khz = 600000; -- uint32_t target_div = INVALID_DIVIDER; -- struct display_clock_dce112 *disp_clk = FROM_DISPLAY_CLOCK(dc); -- -- /* ASSERT DP Reference Clock source is from DFS*/ -- dp_ref_clk_cntl_value = dm_read_reg(dc->ctx, -- mmDPREFCLK_CNTL); -- -- dp_ref_clk_cntl_src_sel_value = -- get_reg_field_value( -- dp_ref_clk_cntl_value, -- DPREFCLK_CNTL, DPREFCLK_SRC_SEL); -- -- ASSERT(dp_ref_clk_cntl_src_sel_value == 0); -- -- /* Read the mmDENTIST_DISPCLK_CNTL to get the currently -- * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ -- dispclk_cntl_value = dm_read_reg(dc->ctx, -- mmDENTIST_DISPCLK_CNTL); -- -- /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ -- target_div = dal_divider_range_get_divider( -- divider_ranges, -- DIVIDER_RANGE_MAX, -- get_reg_field_value(dispclk_cntl_value, -- DENTIST_DISPCLK_CNTL, -- DENTIST_DPREFCLK_WDIVIDER)); -- -- if (target_div != INVALID_DIVIDER) { -- /* Calculate the current DFS clock, in kHz.*/ -- dp_ref_clk_khz = (DIVIDER_RANGE_SCALE_FACTOR -- * disp_clk->dentist_vco_freq_khz) / target_div; -- } -- -- /* 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 ((disp_clk->ss_on_gpu_pll) && (disp_clk->gpu_pll_ss_divider != 0)) { -- struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( -- dal_fixed32_32_from_fraction( -- disp_clk->gpu_pll_ss_percentage, -- disp_clk->gpu_pll_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); -- } -- -- return dp_ref_clk_khz; --} - - void dispclk_dce112_destroy(struct display_clock **base) - { -@@ -233,38 +137,6 @@ static bool display_clock_integrated_info_construct( - return true; - } - --enum dm_pp_clocks_state dispclk_dce112_get_required_clocks_state( -- struct display_clock *dc, -- struct state_dependent_clocks *req_clocks) --{ -- int32_t i; -- struct display_clock_dce112 *disp_clk = DCLCK112_FROM_BASE(dc); -- enum dm_pp_clocks_state low_req_clk = dc->max_clks_state; -- -- if (!req_clocks) { -- /* NULL pointer*/ -- dm_logger_write(dc->ctx->logger, LOG_WARNING, -- "%s: Invalid parameter", -- __func__); -- return DM_PP_CLOCKS_STATE_INVALID; -- } -- -- /* Iterate from highest supported to lowest valid state, and update -- * lowest RequiredState with the lowest state that satisfies -- * all required clocks -- */ -- for (i = dc->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; --i) { -- if ((req_clocks->display_clk_khz <= -- (disp_clk->max_clks_by_state + i)-> -- display_clk_khz) && -- (req_clocks->pixel_clk_khz <= -- (disp_clk->max_clks_by_state + i)-> -- pixel_clk_khz)) -- low_req_clk = i; -- } -- return low_req_clk; --} -- - void dce112_set_clock( - struct display_clock *base, - uint32_t requested_clk_khz) -@@ -304,10 +176,7 @@ void dce112_set_clock( - - static const struct display_clock_funcs funcs = { - .destroy = dispclk_dce112_destroy, -- .get_dp_ref_clk_frequency = get_dp_ref_clk_frequency, -- .get_required_clocks_state = dispclk_dce112_get_required_clocks_state, - .set_clock = dce112_set_clock, -- .set_min_clocks_state = dce112_set_min_clocks_state - }; - - bool dal_display_clock_dce112_construct( -@@ -406,24 +275,3 @@ bool dal_display_clock_dce112_construct( - return true; - } - --/***************************************************************************** -- * public functions -- *****************************************************************************/ -- --struct display_clock *dal_display_clock_dce112_create( -- struct dc_context *ctx) --{ -- struct display_clock_dce112 *dc112; -- -- dc112 = dm_alloc(sizeof(struct display_clock_dce112)); -- -- if (dc112 == NULL) -- return NULL; -- -- if (dal_display_clock_dce112_construct(dc112, ctx)) -- return &dc112->disp_clk_base; -- -- dm_free(dc112); -- -- return NULL; --} -diff --git a/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.h b/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.h -index b750bb1..0743c51 100644 ---- a/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.h -+++ b/drivers/gpu/drm/amd/display/dc/gpu/dce112/display_clock_dce112.h -@@ -71,23 +71,9 @@ bool dal_display_clock_dce112_construct( - - void dispclk_dce112_destroy(struct display_clock **base); - --enum dm_pp_clocks_state dispclk_dce112_get_min_clocks_state( -- struct display_clock *base); -- --enum dm_pp_clocks_state dispclk_dce112_get_required_clocks_state( -- struct display_clock *dc, -- struct state_dependent_clocks *req_clocks); -- - void dce112_set_clock( - struct display_clock *base, - uint32_t requested_clk_khz); - --bool dispclk_dce112_set_min_clocks_state( -- struct display_clock *base, -- enum dm_pp_clocks_state clocks_state); -- --void dispclk_dce112_store_max_clocks_state( -- struct display_clock *base, -- enum dm_pp_clocks_state max_clocks_state); - - #endif /* __DAL_DISPLAY_CLOCK_DCE112_H__ */ -diff --git a/drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.c b/drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.c -deleted file mode 100644 -index 9d7cb2c..0000000 ---- a/drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.c -+++ /dev/null -@@ -1,430 +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 "dce/dce_8_0_d.h" --#include "dce/dce_8_0_sh_mask.h" -- --#include "include/bios_parser_interface.h" --#include "include/fixed32_32.h" --#include "include/logger_interface.h" -- --#include "../divider_range.h" --#include "display_clock_dce80.h" --#include "dc.h" -- --#define DCE80_DFS_BYPASS_THRESHOLD_KHZ 100000 -- --/* Max clock values for each state indexed by "enum clocks_state": */ --static struct state_dependent_clocks max_clks_by_state[] = { --/* ClocksStateInvalid - should not be used */ --{ .display_clk_khz = 0, .pixel_clk_khz = 0 }, --/* ClocksStateUltraLow - not expected to be used for DCE 8.0 */ --{ .display_clk_khz = 0, .pixel_clk_khz = 0 }, --/* ClocksStateLow */ --{ .display_clk_khz = 352000, .pixel_clk_khz = 330000}, --/* ClocksStateNominal */ --{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 }, --/* ClocksStatePerformance */ --{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 } }; -- --/* Starting point for each divider range.*/ --enum 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 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 --}; -- --/* Step size between each divider within a range. -- Incrementing the DENTIST_DISPCLK_WDIVIDER by one -- will increment the divider by this much.*/ --enum 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 */ --}; -- --/* Array identifiers and count for the divider ranges.*/ --enum divider_range_count { -- DIVIDER_RANGE_01 = 0, -- DIVIDER_RANGE_02, -- DIVIDER_RANGE_03, -- DIVIDER_RANGE_MAX /* == 3*/ --}; -- --static struct divider_range divider_ranges[DIVIDER_RANGE_MAX]; -- --#define FROM_DISPLAY_CLOCK(base) \ -- container_of(base, struct display_clock_dce80, disp_clk) -- --static void dce80_set_clock( -- struct display_clock *dc, -- uint32_t requested_clk_khz) --{ -- struct bp_pixel_clock_parameters pxl_clk_params; -- struct dc_bios *bp = dc->ctx->dc_bios; -- -- /* Prepare to program display clock*/ -- memset(&pxl_clk_params, 0, sizeof(pxl_clk_params)); -- -- pxl_clk_params.target_pixel_clock = requested_clk_khz; -- pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; -- -- bp->funcs->program_display_engine_pll(bp, &pxl_clk_params); -- -- /* from power down, we need mark the clock state as ClocksStateNominal -- * from HWReset, so when resume we will call pplib voltage regulator.*/ -- if (requested_clk_khz == 0) -- dc->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; --} -- --static enum dm_pp_clocks_state get_required_clocks_state -- (struct display_clock *dc, -- struct state_dependent_clocks *req_clocks) --{ -- int32_t i; -- enum dm_pp_clocks_state low_req_clk = dc->max_clks_state; -- -- if (!req_clocks) { -- /* NULL pointer*/ -- BREAK_TO_DEBUGGER(); -- return DM_PP_CLOCKS_STATE_INVALID; -- } -- -- /* Iterate from highest supported to lowest valid state, and update -- * lowest RequiredState with the lowest state that satisfies -- * all required clocks -- */ -- for (i = dc->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; --i) { -- if ((req_clocks->display_clk_khz <= -- max_clks_by_state[i].display_clk_khz) && -- (req_clocks->pixel_clk_khz <= -- max_clks_by_state[i].pixel_clk_khz)) -- low_req_clk = i; -- } -- return low_req_clk; --} -- --static bool dce80_set_min_clocks_state( -- struct display_clock *dc, -- enum dm_pp_clocks_state clocks_state) --{ -- struct dm_pp_power_level_change_request level_change_req = { -- clocks_state }; -- -- if (clocks_state > dc->max_clks_state) { -- /*Requested state exceeds max supported state.*/ -- dm_logger_write(dc->ctx->logger, LOG_WARNING, -- "Requested state exceeds max supported state"); -- return false; -- } else if (clocks_state == dc->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(dc->ctx, &level_change_req)) -- dc->cur_min_clks_state = clocks_state; -- -- return true; --} -- --static uint32_t get_dp_ref_clk_frequency(struct display_clock *dc) --{ -- uint32_t dispclk_cntl_value; -- uint32_t dp_ref_clk_cntl_value; -- uint32_t dp_ref_clk_cntl_src_sel_value; -- uint32_t dp_ref_clk_khz = 600000; -- uint32_t target_div = INVALID_DIVIDER; -- struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc); -- -- /* ASSERT DP Reference Clock source is from DFS*/ -- dp_ref_clk_cntl_value = dm_read_reg(dc->ctx, -- mmDPREFCLK_CNTL); -- -- dp_ref_clk_cntl_src_sel_value = -- get_reg_field_value( -- dp_ref_clk_cntl_value, -- DPREFCLK_CNTL, DPREFCLK_SRC_SEL); -- -- ASSERT(dp_ref_clk_cntl_src_sel_value == 0); -- -- /* Read the mmDENTIST_DISPCLK_CNTL to get the currently -- * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ -- dispclk_cntl_value = dm_read_reg(dc->ctx, -- mmDENTIST_DISPCLK_CNTL); -- -- /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ -- target_div = dal_divider_range_get_divider( -- divider_ranges, -- DIVIDER_RANGE_MAX, -- get_reg_field_value(dispclk_cntl_value, -- DENTIST_DISPCLK_CNTL, -- DENTIST_DPREFCLK_WDIVIDER)); -- -- if (target_div != INVALID_DIVIDER) { -- /* Calculate the current DFS clock, in kHz.*/ -- dp_ref_clk_khz = (DIVIDER_RANGE_SCALE_FACTOR -- * disp_clk->dentist_vco_freq_khz) / target_div; -- } -- -- /* 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 ((disp_clk->ss_on_gpu_pll) && (disp_clk->gpu_pll_ss_divider != 0)) { -- struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( -- dal_fixed32_32_from_fraction( -- disp_clk->gpu_pll_ss_percentage, -- disp_clk->gpu_pll_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); -- } -- -- return dp_ref_clk_khz; --} -- --static void display_clock_ss_construct( -- struct display_clock_dce80 *disp_clk) --{ -- struct dc_bios *bp = disp_clk->disp_clk.ctx->dc_bios; -- uint32_t ss_entry_num = bp->funcs->get_ss_entry_number(bp, -- AS_SIGNAL_TYPE_GPU_PLL); -- -- /*Read SS Info from VBIOS SS Info table for DP Reference Clock spread.*/ -- if (ss_entry_num > 0) {/* Should be only one entry */ -- struct spread_spectrum_info ss_info; -- enum bp_result res; -- -- memset(&ss_info, 0, sizeof(struct spread_spectrum_info)); -- -- res = bp->funcs->get_spread_spectrum_info(bp, -- AS_SIGNAL_TYPE_GPU_PLL, 0, &ss_info); -- -- /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS even if -- * SS not enabled and in that case -- * SSInfo.spreadSpectrumPercentage !=0 would be -- * sign that SS is enabled*/ -- if (res == BP_RESULT_OK && ss_info.spread_spectrum_percentage != 0) { -- disp_clk->ss_on_gpu_pll = true; -- disp_clk->gpu_pll_ss_divider = -- ss_info.spread_percentage_divider; -- if (ss_info.type.CENTER_MODE == 0) -- /* Currently we need only SS -- * percentage for down-spread*/ -- disp_clk->gpu_pll_ss_percentage = -- ss_info.spread_spectrum_percentage; -- } -- } --} -- --static bool display_clock_integrated_info_construct( -- struct display_clock_dce80 *disp_clk) --{ -- struct dc_debug *debug = &disp_clk->disp_clk.ctx->dc->debug; -- struct dc_bios *bp = disp_clk->disp_clk.ctx->dc_bios; -- struct integrated_info info = { { { 0 } } }; -- struct firmware_info fw_info = { { 0 } }; -- uint32_t i; -- -- if (bp->integrated_info) -- info = *bp->integrated_info; -- -- disp_clk->dentist_vco_freq_khz = info.dentist_vco_freq; -- if (disp_clk->dentist_vco_freq_khz == 0) { -- bp->funcs->get_firmware_info(bp, &fw_info); -- disp_clk->dentist_vco_freq_khz = -- fw_info.smu_gpu_pll_output_freq; -- if (disp_clk->dentist_vco_freq_khz == 0) -- disp_clk->dentist_vco_freq_khz = 3600000; -- } -- disp_clk->disp_clk.min_display_clk_threshold_khz = -- disp_clk->dentist_vco_freq_khz / 64; -- -- /* TODO: initialise disp_clk->dfs_bypass_disp_clk */ -- -- /*update the maximum display clock for each power state*/ -- for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { -- enum dm_pp_clocks_state clk_state = DM_PP_CLOCKS_STATE_INVALID; -- -- switch (i) { -- case 0: -- clk_state = DM_PP_CLOCKS_STATE_ULTRA_LOW; -- break; -- -- case 1: -- clk_state = DM_PP_CLOCKS_STATE_LOW; -- break; -- -- case 2: -- clk_state = DM_PP_CLOCKS_STATE_NOMINAL; -- break; -- -- case 3: -- clk_state = DM_PP_CLOCKS_STATE_PERFORMANCE; -- break; -- -- default: -- clk_state = DM_PP_CLOCKS_STATE_INVALID; -- break; -- } -- -- /*Do not allow bad VBIOS/SBIOS to override with invalid values, -- * check for > 100MHz*/ -- if (info.disp_clk_voltage[i].max_supported_clk >= 100000) { -- max_clks_by_state[clk_state].display_clk_khz = -- info.disp_clk_voltage[i].max_supported_clk; -- } -- } -- -- disp_clk->dfs_bypass_enabled = false; -- if (!debug->disable_dfs_bypass) -- if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) -- disp_clk->dfs_bypass_enabled = true; -- -- disp_clk->use_max_disp_clk = debug->max_disp_clk; -- -- return true; --} -- --static void destroy(struct display_clock **dc) --{ -- struct display_clock_dce80 *disp_clk; -- -- disp_clk = FROM_DISPLAY_CLOCK(*dc); -- dm_free(disp_clk); -- *dc = NULL; --} -- --static const struct display_clock_funcs funcs = { -- .destroy = destroy, -- .get_dp_ref_clk_frequency = get_dp_ref_clk_frequency, -- .get_required_clocks_state = get_required_clocks_state, -- .set_clock = dce80_set_clock, -- .set_min_clocks_state = dce80_set_min_clocks_state --}; -- -- --struct display_clock *dal_display_clock_dce80_create( -- struct dc_context *ctx) --{ -- struct display_clock_dce80 *disp_clk; -- struct display_clock *dc_base; -- -- disp_clk = dm_alloc(sizeof(struct display_clock_dce80)); -- -- if (disp_clk == NULL) -- return NULL; -- -- dc_base = &disp_clk->disp_clk; -- -- dc_base->ctx = ctx; -- dc_base->min_display_clk_threshold_khz = 0; -- -- dc_base->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID; -- -- dc_base->funcs = &funcs; -- /* -- * set_dp_ref_clock_source -- * set_clock_state -- * get_clock_state -- * get_dfs_bypass_threshold -- */ -- -- disp_clk->gpu_pll_ss_percentage = 0; -- disp_clk->gpu_pll_ss_divider = 1000; -- disp_clk->ss_on_gpu_pll = false; -- disp_clk->dfs_bypass_enabled = false; -- disp_clk->dfs_bypass_disp_clk = 0; -- disp_clk->use_max_disp_clk = true;/* false will hang the system! */ -- --/* Initially set max clocks state to nominal. This should be updated by -- * via a pplib call to DAL IRI eventually calling a -- * DisplayEngineClock_Dce50::StoreMaxClocksState(). This call will come in -- * on PPLIB init. This is from DCE5x. in case HW wants to use mixed method.*/ -- dc_base->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; --/* Initially set current min clocks state to invalid since we -- * cannot make any assumption about PPLIB's initial state. This will be updated -- * by HWSS via SetMinClocksState() on first mode set prior to programming -- * state dependent clocks.*/ -- disp_clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID; -- -- display_clock_ss_construct(disp_clk); -- -- if (!display_clock_integrated_info_construct(disp_clk)) { -- dm_logger_write(dc_base->ctx->logger, LOG_WARNING, -- "Cannot obtain VBIOS integrated info"); -- } -- -- dal_divider_range_construct( -- ÷r_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); -- dal_divider_range_construct( -- ÷r_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); -- dal_divider_range_construct( -- ÷r_ranges[DIVIDER_RANGE_03], -- DIVIDER_RANGE_03_START, -- DIVIDER_RANGE_03_STEP_SIZE, -- DIVIDER_RANGE_03_BASE_DIVIDER_ID, -- DIVIDER_RANGE_MAX_DIVIDER_ID); -- -- dm_free(disp_clk); -- return NULL; --} -- -diff --git a/drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.h b/drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.h -deleted file mode 100644 -index c155bb6..0000000 ---- a/drivers/gpu/drm/amd/display/dc/gpu/dce80/display_clock_dce80.h -+++ /dev/null -@@ -1,54 +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 __DAL_DISPLAY_CLOCK_DCE80_H__ --#define __DAL_DISPLAY_CLOCK_DCE80_H__ -- --#include "display_clock_interface.h" -- --struct display_clock_dce80 { -- struct display_clock disp_clk; -- /* DFS input - GPUPLL VCO frequency - from VBIOS Firmware info. */ -- uint32_t dentist_vco_freq_khz; -- /* GPU PLL SS percentage (if down-spread enabled)*/ -- uint32_t gpu_pll_ss_percentage; -- /* GPU PLL SS percentage Divider (100 or 1000)*/ -- uint32_t gpu_pll_ss_divider; -- /* Flag for Enabled SS on GPU PLL*/ -- bool ss_on_gpu_pll; -- /* Current minimum display block clocks state*/ -- enum dm_pp_clocks_state cur_min_clks_state; -- /* DFS-bypass feature variable -- Cache the status of DFS-bypass feature*/ -- bool dfs_bypass_enabled; -- /* Cache the display clock returned by VBIOS if DFS-bypass is enabled. -- * This is basically "Crystal Frequency In KHz" (XTALIN) frequency */ -- uint32_t dfs_bypass_disp_clk; -- bool use_max_disp_clk; --}; -- --struct display_clock *dal_display_clock_dce80_create( -- struct dc_context *ctx); -- --#endif /* __DAL_DISPLAY_CLOCK_DCE80_H__ */ -diff --git a/drivers/gpu/drm/amd/display/include/display_clock_interface.h b/drivers/gpu/drm/amd/display/include/display_clock_interface.h -index 6ba8c09..53a0138 100644 ---- a/drivers/gpu/drm/amd/display/include/display_clock_interface.h -+++ b/drivers/gpu/drm/amd/display/include/display_clock_interface.h -@@ -41,10 +41,9 @@ struct state_dependent_clocks { - struct display_clock { - struct dc_context *ctx; - const struct display_clock_funcs *funcs; -- uint32_t min_display_clk_threshold_khz; -- /* Max display block clocks state*/ -- enum dm_pp_clocks_state max_clks_state; - -+ int min_display_clk_threshold_khz; -+ enum dm_pp_clocks_state max_clks_state; - enum dm_pp_clocks_state cur_min_clks_state; - }; - -@@ -61,15 +60,7 @@ struct display_clock_funcs { - - }; - --struct display_clock *dal_display_clock_dce112_create( -- struct dc_context *ctx); -- --struct display_clock *dal_display_clock_dce110_create( -- struct dc_context *ctx); -- --struct display_clock *dal_display_clock_dce80_create( -- struct dc_context *ctx); -- - void dal_display_clock_destroy(struct display_clock **to_destroy); - -+ - #endif /* __DISPLAY_CLOCK_INTERFACE_H__ */ --- -2.7.4 - |