aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/5070-drm-amd-display-Add-support-for-toggling-DFS-bypass.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5070-drm-amd-display-Add-support-for-toggling-DFS-bypass.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/5070-drm-amd-display-Add-support-for-toggling-DFS-bypass.patch190
1 files changed, 190 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5070-drm-amd-display-Add-support-for-toggling-DFS-bypass.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5070-drm-amd-display-Add-support-for-toggling-DFS-bypass.patch
new file mode 100644
index 00000000..4635e5be
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5070-drm-amd-display-Add-support-for-toggling-DFS-bypass.patch
@@ -0,0 +1,190 @@
+From c9b18e8580a988a80be3ba87c157b8afdc5d3d63 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Thu, 26 Jul 2018 09:32:48 -0400
+Subject: [PATCH 5070/5725] drm/amd/display: Add support for toggling DFS
+ bypass
+
+[Why]
+
+If the hardware supports DFS bypass it will always be enabled after
+creation of the DCCG. DFS bypass should only be enabled when
+the current stream consists of a single embedded panel and the
+minimum display clock is below the DFS bypass threshold.
+
+[How]
+
+Add a function to the DCCG table that updates the DFS bypass state
+when setting the bandwidth. If the DFS bypass state is changed, the
+clock needs to be reprogrammed to reflect this before the DPREFCLK
+is updated for audio endpoints. The existing display clock value
+is used as the target display clock value when reprogramming since the
+resulting change will be equal or larger to the current value.
+
+These changes only specifically target dce110 but do offer a framework
+for support on other applicable targets.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: David Francis <David.Francis@amd.com>
+Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | 63 ++++++++++++++++++++--
+ drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h | 2 +
+ .../amd/display/dc/dce110/dce110_hw_sequencer.c | 12 ++++-
+ .../gpu/drm/amd/display/dc/inc/hw/display_clock.h | 5 ++
+ 4 files changed, 76 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
+index 10bb8095..51ceb99 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
+@@ -249,13 +249,12 @@ static int dce_set_clock(
+ pxl_clk_params.target_pixel_clock = requested_clk_khz;
+ pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
+
+- if (clk_dce->dfs_bypass_enabled)
++ if (clk_dce->dfs_bypass_active)
+ pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true;
+
+ bp->funcs->program_display_engine_pll(bp, &pxl_clk_params);
+
+- if (clk_dce->dfs_bypass_enabled) {
+-
++ if (clk_dce->dfs_bypass_active) {
+ /* Cache the fixed display clock*/
+ clk_dce->dfs_bypass_disp_clk =
+ pxl_clk_params.dfs_bypass_display_clock;
+@@ -671,6 +670,61 @@ static void dce_update_clocks(struct dccg *dccg,
+ }
+ }
+
++static bool dce_update_dfs_bypass(
++ struct dccg *dccg,
++ struct dc *dc,
++ struct dc_state *context,
++ int requested_clock_khz)
++{
++ struct dce_dccg *clk_dce = TO_DCE_CLOCKS(dccg);
++ struct resource_context *res_ctx = &context->res_ctx;
++ enum signal_type signal_type = SIGNAL_TYPE_NONE;
++ bool was_active = clk_dce->dfs_bypass_active;
++ int i;
++
++ /* Disable DFS bypass by default. */
++ clk_dce->dfs_bypass_active = false;
++
++ /* Check that DFS bypass is available. */
++ if (!clk_dce->dfs_bypass_enabled)
++ goto update;
++
++ /* Check if the requested display clock is below the threshold. */
++ if (requested_clock_khz >= 400000)
++ goto update;
++
++ /* DFS-bypass should only be enabled on single stream setups */
++ if (context->stream_count != 1)
++ goto update;
++
++ /* Check that the stream's signal type is an embedded panel */
++ for (i = 0; i < dc->res_pool->pipe_count; i++) {
++ if (res_ctx->pipe_ctx[i].stream) {
++ struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
++
++ signal_type = pipe_ctx->stream->sink->link->connector_signal;
++ break;
++ }
++ }
++
++ if (signal_type == SIGNAL_TYPE_EDP ||
++ signal_type == SIGNAL_TYPE_LVDS)
++ clk_dce->dfs_bypass_active = true;
++
++update:
++ /* Update the clock state. We don't need to respect safe_to_lower
++ * because DFS bypass should always be greater than the current
++ * display clock frequency.
++ */
++ if (was_active != clk_dce->dfs_bypass_active) {
++ dccg->clks.dispclk_khz =
++ dccg->funcs->set_dispclk(dccg, dccg->clks.dispclk_khz);
++ return true;
++ }
++
++ return false;
++}
++
+ #ifdef CONFIG_X86
+ static const struct display_clock_funcs dcn1_funcs = {
+ .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+@@ -694,7 +748,8 @@ static const struct display_clock_funcs dce112_funcs = {
+ static const struct display_clock_funcs dce110_funcs = {
+ .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz,
+ .set_dispclk = dce_psr_set_clock,
+- .update_clocks = dce_update_clocks
++ .update_clocks = dce_update_clocks,
++ .update_dfs_bypass = dce_update_dfs_bypass
+ };
+
+ static const struct display_clock_funcs dce_funcs = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h
+index e5e44ad..8be68eb 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h
+@@ -78,6 +78,8 @@ struct dce_dccg {
+
+ /* Cache the status of DFS-bypass feature*/
+ bool dfs_bypass_enabled;
++ /* True if the DFS-bypass feature is enabled and active. */
++ bool dfs_bypass_active;
+ /* Cache the display clock returned by VBIOS if DFS-bypass is enabled.
+ * This is basically "Crystal Frequency In KHz" (XTALIN) frequency */
+ int dfs_bypass_disp_clk;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+index afd1743..3b4a9f9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+@@ -2539,6 +2539,7 @@ void dce110_set_bandwidth(
+ bool decrease_allowed)
+ {
+ struct dc_clocks req_clks;
++ struct dccg *dccg = dc->res_pool->dccg;
+
+ req_clks.dispclk_khz = context->bw.dce.dispclk_khz;
+ req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context);
+@@ -2548,8 +2549,15 @@ void dce110_set_bandwidth(
+ else
+ dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
+
+- dc->res_pool->dccg->funcs->update_clocks(
+- dc->res_pool->dccg,
++ if (dccg->funcs->update_dfs_bypass)
++ dccg->funcs->update_dfs_bypass(
++ dccg,
++ dc,
++ context,
++ req_clks.dispclk_khz);
++
++ dccg->funcs->update_clocks(
++ dccg,
+ &req_clks,
+ decrease_allowed);
+ pplib_apply_display_requirements(dc, context);
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h
+index 3c7ccb6..689faa1 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h
+@@ -53,6 +53,11 @@ struct display_clock_funcs {
+ int requested_clock_khz);
+
+ int (*get_dp_ref_clk_frequency)(struct dccg *dccg);
++
++ bool (*update_dfs_bypass)(struct dccg *dccg,
++ struct dc *dc,
++ struct dc_state *context,
++ int requested_clock_khz);
+ };
+
+ #endif /* __DISPLAY_CLOCK_H__ */
+--
+2.7.4
+