From: Relja Vojvodic <relja.vojvodic(a)amd.com>
[WHY]
Enabling NL SDR blending caused the 1D LUTs to be set/populated in two
different functions. This caused flickering as the LUT was set differently
by the two functions, one of which should only have been modifying the 1D
LUT if 3D LUT was enabled.
[HOW]
Added check to only modify the 1D LUT in populate_mcm if 3D LUT was
enabled.
Added blend_tf function update for non-main planes if the 3D LUT path
was taken.
Reviewed-by: Ilya Bakoulin <ilya.bakoulin(a)amd.co>
Cc: Mario Limonciello <mario.limonciello(a)amd.com>
Cc: Alex Deucher <alexander.deucher(a)amd.com>
Cc: stable(a)vger.kernel.org
Acked-by: Alex Hung <alex.hung(a)amd.com>
Signed-off-by: Relja Vojvodic <relja.vojvodic(a)amd.com>
---
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 5306c8c170c5..b5a02a8fc9d8 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -502,7 +502,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
/* 1D LUT */
- if (mcm_luts.lut1d_func) {
+ if (mcm_luts.lut1d_func && lut3d_xable != MCM_LUT_DISABLE) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
@@ -674,7 +674,7 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
// 1D LUT
- if (!plane_state->mcm_lut1d_enable) {
+ if (plane_state->mcm_shaper_3dlut_setting == DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL) {
if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
lut_params = &plane_state->blend_tf.pwl;
else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
--
2.34.1
From: Alvin Lee <alvin.lee2(a)amd.com>
[WHAT & HOW]
According to register specifications, the CURSOR_DST_X_OFFSET
is relative to the start of the data viewport, not RECOUT space.
In this case we must transform the cursor coordinates passed to
hubp401_cursor_set_position into viewport space to program this
register. This fixes an underflow issue that occurs in scaled
mode with low refresh rate.
Reviewed-by: Nevenko Stupar <nevenko.stupar(a)amd.com>
Cc: Mario Limonciello <mario.limonciello(a)amd.com>
Cc: Alex Deucher <alexander.deucher(a)amd.com>
Cc: stable(a)vger.kernel.org
Acked-by: Alex Hung <alex.hung(a)amd.com>
Signed-off-by: Alvin Lee <alvin.lee2(a)amd.com>
---
.../gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index a893160ae775..3f9ca9b40949 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -656,7 +656,9 @@ void hubp401_cursor_set_position(
int y_pos = pos->y - param->recout.y;
int rec_x_offset = x_pos - pos->x_hotspot;
int rec_y_offset = y_pos - pos->y_hotspot;
- uint32_t dst_x_offset;
+ int dst_x_offset;
+ int x_pos_viewport = x_pos * param->viewport.width / param->recout.width;
+ int x_hot_viewport = pos->x_hotspot * param->viewport.width / param->recout.width;
uint32_t cur_en = pos->enable ? 1 : 0;
hubp->curs_pos = *pos;
@@ -668,7 +670,13 @@ void hubp401_cursor_set_position(
if (hubp->curs_attr.address.quad_part == 0)
return;
- dst_x_offset = (rec_x_offset >= 0) ? rec_x_offset : 0;
+ /* Translate the x position of the cursor from rect
+ * space into viewport space. CURSOR_DST_X_OFFSET
+ * is the offset relative to viewport start position.
+ */
+ dst_x_offset = x_pos_viewport - x_hot_viewport *
+ (1 + hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION);
+ dst_x_offset = (dst_x_offset >= 0) ? dst_x_offset : 0;
dst_x_offset *= param->ref_clk_khz;
dst_x_offset /= param->pixel_clk_khz;
--
2.34.1
From: Daniel Sa <daniel.sa(a)amd.com>
[WHY]
Some monitors are forced to a lower resolution and refresh rate after
system restarts.
[HOW]
Some monitors may give invalid LTTPR information when queried such as
indicating they have one DP lane instead of 4. If given an invalid DPCD
version, skip over getting lttpr link rate and lane counts.
Reviewed-by: Wenjing Liu <wenjing.liu(a)amd.com>
Cc: Mario Limonciello <mario.limonciello(a)amd.com>
Cc: Alex Deucher <alexander.deucher(a)amd.com>
Cc: stable(a)vger.kernel.org
Acked-by: Alex Hung <alex.hung(a)amd.com>
Signed-off-by: Daniel Sa <daniel.sa(a)amd.com>
---
.../dc/link/protocols/link_dp_capability.c | 21 ++++++++++---------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index f1cac74dd7f7..46bb7a855bc2 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -409,9 +409,6 @@ static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link)
case LINK_RATE_HIGH3:
lttpr_max_link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
break;
- default:
- // Assume all LTTPRs support up to HBR3 to improve misbehaving sink interop
- lttpr_max_link_rate = LINK_RATE_HIGH3;
}
if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR20)
@@ -2137,15 +2134,19 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
* notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
*/
if (dp_is_lttpr_present(link)) {
- if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
- max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
- lttpr_max_link_rate = get_lttpr_max_link_rate(link);
- if (lttpr_max_link_rate < max_link_cap.link_rate)
- max_link_cap.link_rate = lttpr_max_link_rate;
+ /* Some LTTPR devices do not report valid DPCD revisions, if so, do not take it's link cap into consideration. */
+ if (link->dpcd_caps.lttpr_caps.revision.raw >= DPCD_REV_14) {
+ if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
+ max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
+ lttpr_max_link_rate = get_lttpr_max_link_rate(link);
- if (!link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5)
- is_uhbr13_5_supported = false;
+ if (lttpr_max_link_rate < max_link_cap.link_rate)
+ max_link_cap.link_rate = lttpr_max_link_rate;
+
+ if (!link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5)
+ is_uhbr13_5_supported = false;
+ }
DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR, max_lane count %d max_link rate %d \n",
__func__,
--
2.34.1