drm/amd/display: Calculate bpc based on max_requested_bpc
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Wed, 21 Aug 2019 15:27:13 +0000 (11:27 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 21 Aug 2019 22:33:32 +0000 (17:33 -0500)
[Why]
The only place where state->max_bpc is updated on the connector is
at the start of atomic check during drm_atomic_connector_check. It
isn't updated when adding the connectors to the atomic state after
the fact. It also doesn't necessarily reflect the right value when
called in amdgpu during mode validation outside of atomic check.

This can cause the wrong bpc to be used even if the max_requested_bpc
is the correct value.

[How]
Don't rely on state->max_bpc reflecting the real bpc value and just
do the min(...) based on display info bpc and max_requested_bpc.

Fixes: 01933ba42d3d ("drm/amd/display: Use current connector state if NULL when checking bpc")
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index 4a29f72..45be7a2 100644 (file)
@@ -3131,13 +3131,25 @@ static enum dc_color_depth
 convert_color_depth_from_display_info(const struct drm_connector *connector,
                                      const struct drm_connector_state *state)
 {
-       uint32_t bpc = connector->display_info.bpc;
+       uint8_t bpc = (uint8_t)connector->display_info.bpc;
+
+       /* Assume 8 bpc by default if no bpc is specified. */
+       bpc = bpc ? bpc : 8;
 
        if (!state)
                state = connector->state;
 
        if (state) {
-               bpc = state->max_bpc;
+               /*
+                * Cap display bpc based on the user requested value.
+                *
+                * The value for state->max_bpc may not correctly updated
+                * depending on when the connector gets added to the state
+                * or if this was called outside of atomic check, so it
+                * can't be used directly.
+                */
+               bpc = min(bpc, state->max_requested_bpc);
+
                /* Round down to the nearest even number. */
                bpc = bpc - (bpc & 1);
        }