From: Anson Jacob <Anson.Jacob@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: <Harry.Wentland@amd.com>, <Sunpeng.Li@amd.com>,
<Bhawanpreet.Lakha@amd.com>, <Rodrigo.Siqueira@amd.com>,
<Aurabindo.Pillai@amd.com>, <qingqing.zhuo@amd.com>,
<mikita.lipski@amd.com>, <roman.li@amd.com>,
<Anson.Jacob@amd.com>, <wayne.lin@amd.com>, <stylon.wang@amd.com>,
<solomon.chiu@amd.com>, Michael Strauss <michael.strauss@amd.com>,
Eric Yang <Eric.Yang2@amd.com>
Subject: [PATCH 19/24] drm/amd/display: Defer LUT memory powerdown until LUT bypass latches
Date: Fri, 24 Sep 2021 15:09:29 -0400 [thread overview]
Message-ID: <20210924190934.1193379-20-Anson.Jacob@amd.com> (raw)
In-Reply-To: <20210924190934.1193379-1-Anson.Jacob@amd.com>
From: Michael Strauss <michael.strauss@amd.com>
[WHY]
Blnd, 3dlut, and shaper LUT select registers are double buffered, however
their accompanying LUT memory shutdown registers are not. As a result,
shutting down LUT memory immediately after setting a block to bypass causes
corruption as bypass only happens at next Vupdate.
[HOW]
Re-enable mem low power for CM block
Force optimization on next flip and disable LUT memory during optimization
sequence if LUT select field is then set to bypass
Reviewed-by: Eric Yang <Eric.Yang2@amd.com>
Acked-by: Anson Jacob <Anson.Jacob@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 19 ++++++
.../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c | 59 +++++++++++++++++--
.../drm/amd/display/dc/dcn31/dcn31_resource.c | 2 +-
drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h | 12 ++++
4 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 644005846433..0f0440408a16 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1793,6 +1793,23 @@ static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
return false;
}
+/* Perform updates here which need to be deferred until next vupdate
+ *
+ * i.e. blnd lut, 3dlut, and shaper lut bypass regs are double buffered
+ * but forcing lut memory to shutdown state is immediate. This causes
+ * single frame corruption as lut gets disabled mid-frame unless shutdown
+ * is deferred until after entering bypass.
+ */
+static void process_deferred_updates(struct dc *dc)
+{
+ int i;
+
+ if (dc->debug.enable_mem_low_power.bits.cm)
+ for (i = 0; i < dc->dcn_ip->max_num_dpp; i++)
+ if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update)
+ dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]);
+}
+
void dc_post_update_surfaces_to_stream(struct dc *dc)
{
int i;
@@ -1818,6 +1835,8 @@ void dc_post_update_surfaces_to_stream(struct dc *dc)
dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
}
+ process_deferred_updates(dc);
+
dc->hwss.optimize_bandwidth(dc, context);
dc->optimized_required = false;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
index 23a52d47e61c..ef5f6da5248a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
@@ -488,6 +488,40 @@ void dpp3_cnv_set_bias_scale(
REG_UPDATE(FCNV_FP_SCALE_B, FCNV_FP_SCALE_B, bias_and_scale->scale_blue);
}
+void dpp3_deferred_update(
+ struct dpp *dpp_base)
+{
+ int bypass_state;
+ struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
+
+ if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) {
+ REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state);
+ if (bypass_state == 0) { // only program if bypass was latched
+ REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3);
+ } else
+ ASSERT(0); // LUT select was updated again before vupdate
+ dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false;
+ }
+
+ if (dpp_base->deferred_reg_writes.bits.disable_3dlut) {
+ REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state);
+ if (bypass_state == 0) { // only program if bypass was latched
+ REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3);
+ } else
+ ASSERT(0); // LUT select was updated again before vupdate
+ dpp_base->deferred_reg_writes.bits.disable_3dlut = false;
+ }
+
+ if (dpp_base->deferred_reg_writes.bits.disable_shaper) {
+ REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state);
+ if (bypass_state == 0) { // only program if bypass was latched
+ REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3);
+ } else
+ ASSERT(0); // LUT select was updated again before vupdate
+ dpp_base->deferred_reg_writes.bits.disable_shaper = false;
+ }
+}
+
static void dpp3_power_on_blnd_lut(
struct dpp *dpp_base,
bool power_on)
@@ -495,9 +529,13 @@ static void dpp3_power_on_blnd_lut(
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
- REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, power_on ? 0 : 3);
- if (power_on)
+ if (power_on) {
+ REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0);
REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5);
+ } else {
+ dpp_base->ctx->dc->optimized_required = true;
+ dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true;
+ }
} else {
REG_SET(CM_MEM_PWR_CTRL, 0,
BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);
@@ -511,9 +549,13 @@ static void dpp3_power_on_hdr3dlut(
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
- REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, power_on ? 0 : 3);
- if (power_on)
+ if (power_on) {
+ REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0);
REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5);
+ } else {
+ dpp_base->ctx->dc->optimized_required = true;
+ dpp_base->deferred_reg_writes.bits.disable_3dlut = true;
+ }
}
}
@@ -524,9 +566,13 @@ static void dpp3_power_on_shaper(
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
- REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, power_on ? 0 : 3);
- if (power_on)
+ if (power_on) {
+ REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0);
REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5);
+ } else {
+ dpp_base->ctx->dc->optimized_required = true;
+ dpp_base->deferred_reg_writes.bits.disable_shaper = true;
+ }
}
}
@@ -1400,6 +1446,7 @@ static struct dpp_funcs dcn30_dpp_funcs = {
.dpp_program_blnd_lut = dpp3_program_blnd_lut,
.dpp_program_shaper_lut = dpp3_program_shaper,
.dpp_program_3dlut = dpp3_program_3dlut,
+ .dpp_deferred_update = dpp3_deferred_update,
.dpp_program_bias_and_scale = NULL,
.dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer,
.set_cursor_attributes = dpp3_set_cursor_attributes,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 6f0c788d1904..613d34bde7dd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1013,7 +1013,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.i2c = true,
.dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
.dscl = true,
- .cm = false, // visible flicker on OLED eDPs
+ .cm = true,
.mpc = true,
.optc = true,
.vpg = true,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index 00fc81431b43..9f12792b7e59 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -29,6 +29,15 @@
#include "transform.h"
+union defer_reg_writes {
+ struct {
+ bool disable_blnd_lut:1;
+ bool disable_3dlut:1;
+ bool disable_shaper:1;
+ } bits;
+ uint32_t raw;
+};
+
struct dpp {
const struct dpp_funcs *funcs;
struct dc_context *ctx;
@@ -43,6 +52,7 @@ struct dpp {
struct pwl_params regamma_params;
struct pwl_params degamma_params;
struct dpp_cursor_attributes cur_attr;
+ union defer_reg_writes deferred_reg_writes;
struct pwl_params shaper_params;
bool cm_bypass_mode;
@@ -245,6 +255,8 @@ struct dpp_funcs {
bool dppclk_div,
bool enable);
+ void (*dpp_deferred_update)(
+ struct dpp *dpp);
bool (*dpp_program_blnd_lut)(
struct dpp *dpp,
const struct pwl_params *params);
--
2.25.1
next prev parent reply other threads:[~2021-09-24 19:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-24 19:09 [PATCH 00/24] DC Patches Sep 24, 2021 Anson Jacob
2021-09-24 19:09 ` [PATCH 01/24] drm/amd/display: use correct vpg instance for 128b/132b encoding Anson Jacob
2021-09-24 19:09 ` [PATCH 02/24] drm/amd/display: [FW Promotion] Release 0.0.85 Anson Jacob
2021-09-24 19:09 ` [PATCH 03/24] drm/amd/display: Don't enable AFMT for DP audio stream Anson Jacob
2021-09-24 19:09 ` [PATCH 04/24] drm/amd/display: add vsync notify to dmub for abm pause Anson Jacob
2021-09-24 19:09 ` [PATCH 05/24] drm/amd/display: Add debug support to override the Minimum DRAM Clock Anson Jacob
2021-09-24 19:09 ` [PATCH 06/24] drm/amd/display: update cur_lane_setting to an array one for each lane Anson Jacob
2021-09-24 19:09 ` [PATCH 07/24] drm/amd/display: add function to convert hw to dpcd lane settings Anson Jacob
2021-09-24 19:09 ` [PATCH 08/24] drm/amd/display: implement decide " Anson Jacob
2021-09-24 19:09 ` [PATCH 09/24] drm/amd/display: rename lane_settings to hw_lane_settings Anson Jacob
2021-09-24 19:09 ` [PATCH 10/24] drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings Anson Jacob
2021-09-24 19:09 ` [PATCH 11/24] drm/amd/display: add two lane settings training options Anson Jacob
2021-09-24 19:09 ` [PATCH 12/24] drm/amd/display: Fix for link encoder access for MST Anson Jacob
2021-09-24 19:09 ` [PATCH 13/24] drm/amd/display: Fix MST link encoder availability check Anson Jacob
2021-09-24 19:09 ` [PATCH 14/24] drm/amd/display: Add PPS immediate update flag for DCN2 Anson Jacob
2021-09-24 19:09 ` [PATCH 15/24] drm/amd/display: Add an extra check for dcn10 OPTC data format Anson Jacob
2021-09-24 19:09 ` [PATCH 16/24] drm/amd/display: [FW Promotion] Release 0.0.86 Anson Jacob
2021-09-24 19:09 ` [PATCH 17/24] drm/amd/display: 3.2.155 Anson Jacob
2021-09-24 19:09 ` [PATCH 18/24] drm/amd/display: Replace referral of dal with dc Anson Jacob
2021-09-24 19:09 ` Anson Jacob [this message]
2021-09-24 19:09 ` [PATCH 20/24] drm/amd/display: initialize backlight_ramping_override to false Anson Jacob
2021-09-24 19:09 ` [PATCH 21/24] drm/amd/display: make verified link cap not exceeding max link cap Anson Jacob
2021-09-24 19:09 ` [PATCH 22/24] drm/amd/display: Handle Y carry-over in VCP X.Y calculation Anson Jacob
2021-09-24 19:09 ` [PATCH 23/24] drm/amd/display: Update VCP X.Y logging to improve usefulness Anson Jacob
2021-09-24 19:09 ` [PATCH 24/24] drm/amd/display: Pass PCI deviceid into DC Anson Jacob
2021-09-27 13:21 ` [PATCH 00/24] DC Patches Sep 24, 2021 Wheeler, Daniel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210924190934.1193379-20-Anson.Jacob@amd.com \
--to=anson.jacob@amd.com \
--cc=Aurabindo.Pillai@amd.com \
--cc=Bhawanpreet.Lakha@amd.com \
--cc=Eric.Yang2@amd.com \
--cc=Harry.Wentland@amd.com \
--cc=Rodrigo.Siqueira@amd.com \
--cc=Sunpeng.Li@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=michael.strauss@amd.com \
--cc=mikita.lipski@amd.com \
--cc=qingqing.zhuo@amd.com \
--cc=roman.li@amd.com \
--cc=solomon.chiu@amd.com \
--cc=stylon.wang@amd.com \
--cc=wayne.lin@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).